--- a/.hgtags Fri Nov 30 12:39:37 2012 +0000
+++ b/.hgtags Fri Nov 30 17:09:05 2012 -0800
@@ -185,3 +185,5 @@
cdaa6122185f9bf512dcd6600f56bfccc4824e8c jdk8-b61
8d9d430b4244b95f5cf1ebe719f834a1ac5d6cd5 jdk8-b62
21ee1dd7b809639284900a128b9b656a592ebc7a jdk8-b63
+70fa4b11f26522e69b51fd652215f60ce350bac3 jdk8-b64
+a2cf4d4a484378caea2e827ed604b2bbae58bdba jdk8-b65
--- a/.hgtags-top-repo Fri Nov 30 12:39:37 2012 +0000
+++ b/.hgtags-top-repo Fri Nov 30 17:09:05 2012 -0800
@@ -185,3 +185,5 @@
20ff117b509075c3aec4ee3a57990ecd5db5df9c jdk8-b61
8a3fe0ae06a8cc21347da5a18384b0aa6c2349f5 jdk8-b62
3229597524cab4239325bc3602df6c486397a511 jdk8-b63
+1c8370a55b305d35353346202bde042ba9e8a9fd jdk8-b64
+b772de306dc24c17f7bd1398531ddeb58723b804 jdk8-b65
--- a/common/autoconf/basics.m4 Fri Nov 30 12:39:37 2012 +0000
+++ b/common/autoconf/basics.m4 Fri Nov 30 17:09:05 2012 -0800
@@ -345,7 +345,13 @@
[ CONF_NAME=${with_conf_name} ])
# Test from where we are running configure, in or outside of src root.
-if test "x$CURDIR" = "x$SRC_ROOT" || test "x$CURDIR" = "x$SRC_ROOT/common" || test "x$CURDIR" = "x$SRC_ROOT/common/autoconf" || test "x$CURDIR" = "x$SRC_ROOT/common/makefiles" ; then
+# To enable comparison of directories, CURDIR needs to be symlink free
+# just like SRC_ROOT already is
+NOSYM_CURDIR="$CURDIR"
+BASIC_REMOVE_SYMBOLIC_LINKS(NOSYM_CURDIR)
+if test "x$NOSYM_CURDIR" = "x$SRC_ROOT" || test "x$NOSYM_CURDIR" = "x$SRC_ROOT/common" \
+ || test "x$NOSYM_CURDIR" = "x$SRC_ROOT/common/autoconf" \
+ || test "x$NOSYM_CURDIR" = "x$SRC_ROOT/common/makefiles" ; then
# We are running configure from the src root.
# Create a default ./build/target-variant-debuglevel output root.
if test "x${CONF_NAME}" = x; then
--- a/common/autoconf/build-performance.m4 Fri Nov 30 12:39:37 2012 +0000
+++ b/common/autoconf/build-performance.m4 Fri Nov 30 17:09:05 2012 -0800
@@ -204,7 +204,7 @@
#
AC_ARG_ENABLE([precompiled-headers], [AS_HELP_STRING([--disable-precompiled-headers],
[disable using precompiled headers when compiling C++ @<:@enabled@:>@])],
- [ENABLE_PRECOMPH=${enable_precompiled-headers}], [ENABLE_PRECOMPH=yes])
+ [ENABLE_PRECOMPH=${enable_precompiled_headers}], [ENABLE_PRECOMPH=yes])
USE_PRECOMPILED_HEADER=1
if test "x$ENABLE_PRECOMPH" = xno; then
@@ -214,17 +214,16 @@
if test "x$ENABLE_PRECOMPH" = xyes; then
# Check that the compiler actually supports precomp headers.
if test "x$GCC" = xyes; then
- AC_MSG_CHECKING([that precompiled headers work])
+ AC_MSG_CHECKING([that precompiled headers work])
echo "int alfa();" > conftest.h
- $CXX -x c++-header conftest.h -o conftest.hpp.gch
+ $CXX -x c++-header conftest.h -o conftest.hpp.gch 2>&AS_MESSAGE_LOG_FD >&AS_MESSAGE_LOG_FD
if test ! -f conftest.hpp.gch; then
- echo Precompiled header is not working!
USE_PRECOMPILED_HEADER=0
AC_MSG_RESULT([no])
else
AC_MSG_RESULT([yes])
fi
- rm -f conftest.h
+ rm -f conftest.h conftest.hpp.gch
fi
fi
--- a/common/autoconf/generated-configure.sh Fri Nov 30 12:39:37 2012 +0000
+++ b/common/autoconf/generated-configure.sh Fri Nov 30 17:09:05 2012 -0800
@@ -730,6 +730,8 @@
LD_OUT_OPTION
EXE_OUT_OPTION
CC_OUT_OPTION
+BUILD_HOTSPOT
+HOTSPOT_DIST
BUILD_OUTPUT
OVERRIDE_SRC_ROOT
ADD_SRC_ROOT
@@ -975,6 +977,7 @@
with_override_jaxws
with_override_hotspot
with_override_jdk
+with_import_hotspot
with_msvcr_dll
with_extra_cflags
with_extra_cxxflags
@@ -990,7 +993,7 @@
with_alsa_include
with_alsa_lib
with_zlib
-enable_static_link_stdc__
+with_stdc__lib
with_num_cores
with_memory_size
with_sjavac_server_java
@@ -1657,9 +1660,6 @@
--disable-macosx-runtime-support
disable the use of MacOSX Java runtime support
framework [enabled]
- --disable-static-link-stdc++
- disable static linking of the C++ runtime on Linux
- [enabled]
--enable-sjavac use sjavac to do fast incremental compiles
[disabled]
--disable-precompiled-headers
@@ -1719,6 +1719,9 @@
--with-override-jaxws use this jaxws dir for the build
--with-override-hotspot use this hotspot dir for the build
--with-override-jdk use this jdk dir for the build
+ --with-import-hotspot import hotspot binaries from this jdk image or
+ hotspot build dist dir instead of building from
+ source
--with-msvcr-dll copy this msvcr100.dll into the built JDK (Windows
only) [probed]
--with-extra-cflags extra flags to be used when compiling jdk c-files
@@ -1738,6 +1741,10 @@
--with-alsa-lib specify directory for the alsa library
--with-zlib use zlib from build system or OpenJDK source
(system, bundled) [bundled]
+ --with-stdc++lib=<static>,<dynamic>,<default>
+ force linking of the C++ runtime on Linux to either
+ static or dynamic, default is static with dynamic as
+ fallback
--with-num-cores number of cores in the build system, e.g.
--with-num-cores=8 [probed]
--with-memory-size memory (in MB) available in the build system, e.g.
@@ -3665,7 +3672,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1351854415
+DATE_WHEN_GENERATED=1354106772
###############################################################################
#
@@ -7575,7 +7582,56 @@
# Test from where we are running configure, in or outside of src root.
-if test "x$CURDIR" = "x$SRC_ROOT" || test "x$CURDIR" = "x$SRC_ROOT/common" || test "x$CURDIR" = "x$SRC_ROOT/common/autoconf" || test "x$CURDIR" = "x$SRC_ROOT/common/makefiles" ; then
+# To enable comparison of directories, CURDIR needs to be symlink free
+# just like SRC_ROOT already is
+NOSYM_CURDIR="$CURDIR"
+
+ if test "x$OPENJDK_BUILD_OS" != xwindows; then
+ # Follow a chain of symbolic links. Use readlink
+ # where it exists, else fall back to horribly
+ # complicated shell code.
+ if test "x$READLINK_TESTED" != yes; then
+ # On MacOSX there is a readlink tool with a different
+ # purpose than the GNU readlink tool. Check the found readlink.
+ ISGNU=`$READLINK --help 2>&1 | $GREP GNU`
+ if test "x$ISGNU" = x; then
+ # A readlink that we do not know how to use.
+ # Are there other non-GNU readlinks out there?
+ READLINK_TESTED=yes
+ READLINK=
+ fi
+ fi
+
+ if test "x$READLINK" != x; then
+ NOSYM_CURDIR=`$READLINK -f $NOSYM_CURDIR`
+ else
+ STARTDIR=$PWD
+ COUNTER=0
+ sym_link_dir=`$DIRNAME $NOSYM_CURDIR`
+ sym_link_file=`$BASENAME $NOSYM_CURDIR`
+ while test $COUNTER -lt 20; do
+ ISLINK=`$LS -l $sym_link_dir/$sym_link_file | $GREP '\->' | $SED -e 's/.*-> \(.*\)/\1/'`
+ if test "x$ISLINK" == x; then
+ # This is not a symbolic link! We are done!
+ break
+ fi
+ # The link might be relative! We have to use cd to travel safely.
+ cd $sym_link_dir
+ # ... and we must get the to the absolute path, not one using symbolic links.
+ cd `pwd -P`
+ cd `$DIRNAME $ISLINK`
+ sym_link_dir=`$THEPWDCMD`
+ sym_link_file=`$BASENAME $ISLINK`
+ let COUNTER=COUNTER+1
+ done
+ cd $STARTDIR
+ NOSYM_CURDIR=$sym_link_dir/$sym_link_file
+ fi
+ fi
+
+if test "x$NOSYM_CURDIR" = "x$SRC_ROOT" || test "x$NOSYM_CURDIR" = "x$SRC_ROOT/common" \
+ || test "x$NOSYM_CURDIR" = "x$SRC_ROOT/common/autoconf" \
+ || test "x$NOSYM_CURDIR" = "x$SRC_ROOT/common/makefiles" ; then
# We are running configure from the src root.
# Create a default ./build/target-variant-debuglevel output root.
if test "x${CONF_NAME}" = x; then
@@ -15582,6 +15638,31 @@
BUILD_OUTPUT="$OUTPUT_ROOT"
+HOTSPOT_DIST="$OUTPUT_ROOT/hotspot/dist"
+BUILD_HOTSPOT=true
+
+
+
+# Check whether --with-import-hotspot was given.
+if test "${with_import_hotspot+set}" = set; then :
+ withval=$with_import_hotspot;
+fi
+
+if test "x$with_import_hotspot" != x; then
+ CURDIR="$PWD"
+ cd "$with_import_hotspot"
+ HOTSPOT_DIST="`pwd`"
+ cd "$CURDIR"
+ if ! (test -d $HOTSPOT_DIST/lib && test -d $HOTSPOT_DIST/jre/lib); then
+ as_fn_error $? "You have to import hotspot from a full jdk image or hotspot build dist dir!" "$LINENO" 5
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if hotspot should be imported" >&5
+$as_echo_n "checking if hotspot should be imported... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes from $HOTSPOT_DIST" >&5
+$as_echo "yes from $HOTSPOT_DIST" >&6; }
+ BUILD_HOTSPOT=false
+fi
+
JDK_OUTPUTDIR="$OUTPUT_ROOT/jdk"
@@ -25583,6 +25664,8 @@
fi
fi
+ # Only call fixup if objcopy was found.
+ if test -n "$OBJCOPY"; then
if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
@@ -25838,6 +25921,7 @@
$as_echo "$as_me: Rewriting OBJCOPY to \"$new_complete\"" >&6;}
fi
+ fi
fi
if test -n "$ac_tool_prefix"; then
@@ -27498,10 +27582,19 @@
fi
fi
LDFLAGS_JDKLIB="${LDFLAGS_JDK} $SHARED_LIBRARY_FLAGS \
- -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/server \
- -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/client \
-L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}"
+ # On some platforms (mac) the linker warns about non existing -L dirs.
+ # Add server first if available. Linking aginst client does not always produce the same results.
+ # Only add client dir if client is being built. Default to server for other variants.
+ if test "x$JVM_VARIANT_SERVER" = xtrue; then
+ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/server"
+ elif test "x$JVM_VARIANT_CLIENT" = xtrue; then
+ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/client"
+ else
+ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/server"
+ fi
+
LDFLAGS_JDKLIB_SUFFIX="-ljava -ljvm"
if test "x$COMPILER_NAME" = xossc; then
LDFLAGS_JDKLIB_SUFFIX="$LDFLAGS_JDKLIB_SUFFIX -lc"
@@ -30159,12 +30252,17 @@
# statically link libstdc++ before C++ ABI is stablized on Linux unless
# dynamic build is configured on command line.
#
-# Check whether --enable-static-link-stdc++ was given.
-if test "${enable_static_link_stdc__+set}" = set; then :
- enableval=$enable_static_link_stdc__;
-else
-
- enable_static_link_stdc__=yes
+
+# Check whether --with-stdc++lib was given.
+if test "${with_stdc__lib+set}" = set; then :
+ withval=$with_stdc__lib;
+ if test "x$with_stdc__lib" != xdynamic && test "x$with_stdc__lib" != xstatic \
+ && test "x$with_stdc__lib" != xdefault; then
+ as_fn_error $? "Bad parameter value --with-stdc++lib=$with_stdc__lib!" "$LINENO" 5
+ fi
+
+else
+ with_stdc__lib=default
fi
@@ -30252,36 +30350,34 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_static_libstdcxx" >&5
$as_echo "$has_static_libstdcxx" >&6; }
- if test "x$has_static_libcxx" = xno && test "x$has_dynamic_libcxx" = xno; then
- as_fn_error $? "I cannot link to stdc++! Neither dynamically nor statically." "$LINENO" 5
- fi
-
- if test "x$enable_static_link_stdc__" = xyes && test "x$has_static_libstdcxx" = xno; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: Static linking of libstdc++ was not possible reverting to dynamic linking." >&5
-$as_echo "$as_me: Static linking of libstdc++ was not possible reverting to dynamic linking." >&6;}
- enable_static_link_stdc__=no
- fi
-
- if test "x$enable_static_link_stdc__" = xno && test "x$has_dynamic_libstdcxx" = xno; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: Dynamic linking of libstdc++ was not possible reverting to static linking." >&5
-$as_echo "$as_me: Dynamic linking of libstdc++ was not possible reverting to static linking." >&6;}
- enable_static_link_stdc__=yes
+ if test "x$has_static_libstdcxx" = xno && test "x$has_dynamic_libstdcxx" = xno; then
+ as_fn_error $? "Cannot link to stdc++, neither dynamically nor statically!" "$LINENO" 5
+ fi
+
+ if test "x$with_stdc__lib" = xstatic && test "x$has_static_libstdcxx" = xno; then
+ as_fn_error $? "Static linking of libstdc++ was not possible!" "$LINENO" 5
+ fi
+
+ if test "x$with_stdc__lib" = xdynamic && test "x$has_dynamic_libstdcxx" = xno; then
+ as_fn_error $? "Dynamic linking of libstdc++ was not possible!" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libstdc++" >&5
$as_echo_n "checking how to link with libstdc++... " >&6; }
- if test "x$enable_static_link_stdc__" = xyes; then
+ # If dynamic was requested, it's available since it would fail above otherwise.
+ # If dynamic wasn't requested, go with static unless it isn't available.
+ if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno; then
+ LIBCXX="$LIBCXX -lstdc++"
+ LDCXX="$CXX"
+ STATIC_CXX_SETTING="STATIC_CXX=false"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: dynamic" >&5
+$as_echo "dynamic" >&6; }
+ else
LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
LDCXX="$CC"
STATIC_CXX_SETTING="STATIC_CXX=true"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
$as_echo "static" >&6; }
- else
- LIBCXX="$LIBCXX -lstdc++"
- LDCXX="$CXX"
- STATIC_CXX_SETTING="STATIC_CXX=false"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: dynamic" >&5
-$as_echo "dynamic" >&6; }
fi
fi
@@ -30733,7 +30829,7 @@
#
# Check whether --enable-precompiled-headers was given.
if test "${enable_precompiled_headers+set}" = set; then :
- enableval=$enable_precompiled_headers; ENABLE_PRECOMPH=${enable_precompiled-headers}
+ enableval=$enable_precompiled_headers; ENABLE_PRECOMPH=${enable_precompiled_headers}
else
ENABLE_PRECOMPH=yes
fi
@@ -30750,9 +30846,8 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that precompiled headers work" >&5
$as_echo_n "checking that precompiled headers work... " >&6; }
echo "int alfa();" > conftest.h
- $CXX -x c++-header conftest.h -o conftest.hpp.gch
+ $CXX -x c++-header conftest.h -o conftest.hpp.gch 2>&5 >&5
if test ! -f conftest.hpp.gch; then
- echo Precompiled header is not working!
USE_PRECOMPILED_HEADER=0
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
@@ -30760,7 +30855,7 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
fi
- rm -f conftest.h
+ rm -f conftest.h conftest.hpp.gch
fi
fi
--- a/common/autoconf/hotspot-spec.gmk.in Fri Nov 30 12:39:37 2012 +0000
+++ b/common/autoconf/hotspot-spec.gmk.in Fri Nov 30 17:09:05 2012 -0800
@@ -95,6 +95,8 @@
EXTRA_CXXFLAGS=@LEGACY_EXTRA_CXXFLAGS@
EXTRA_LDFLAGS=@LEGACY_EXTRA_LDFLAGS@
+USE_PRECOMPILED_HEADER=@USE_PRECOMPILED_HEADER@
+
# Sneak this in via the spec.gmk file, since we don't want to mess around too much with the Hotspot make files.
# This is needed to get the LOG setting to work properly.
include $(SRC_ROOT)/common/makefiles/MakeBase.gmk
--- a/common/autoconf/libraries.m4 Fri Nov 30 12:39:37 2012 +0000
+++ b/common/autoconf/libraries.m4 Fri Nov 30 17:09:05 2012 -0800
@@ -601,11 +601,16 @@
# statically link libstdc++ before C++ ABI is stablized on Linux unless
# dynamic build is configured on command line.
#
-AC_ARG_ENABLE([static-link-stdc++], [AS_HELP_STRING([--disable-static-link-stdc++],
- [disable static linking of the C++ runtime on Linux @<:@enabled@:>@])],,
- [
- enable_static_link_stdc__=yes
- ])
+AC_ARG_WITH([stdc++lib], [AS_HELP_STRING([--with-stdc++lib=<static>,<dynamic>,<default>],
+ [force linking of the C++ runtime on Linux to either static or dynamic, default is static with dynamic as fallback])],
+ [
+ if test "x$with_stdc__lib" != xdynamic && test "x$with_stdc__lib" != xstatic \
+ && test "x$with_stdc__lib" != xdefault; then
+ AC_MSG_ERROR([Bad parameter value --with-stdc++lib=$with_stdc__lib!])
+ fi
+ ],
+ [with_stdc__lib=default]
+)
if test "x$OPENJDK_TARGET_OS" = xlinux; then
# Test if -lstdc++ works.
@@ -636,31 +641,31 @@
AC_LANG_POP(C++)
AC_MSG_RESULT([$has_static_libstdcxx])
- if test "x$has_static_libcxx" = xno && test "x$has_dynamic_libcxx" = xno; then
- AC_MSG_ERROR([I cannot link to stdc++! Neither dynamically nor statically.])
+ if test "x$has_static_libstdcxx" = xno && test "x$has_dynamic_libstdcxx" = xno; then
+ AC_MSG_ERROR([Cannot link to stdc++, neither dynamically nor statically!])
fi
- if test "x$enable_static_link_stdc__" = xyes && test "x$has_static_libstdcxx" = xno; then
- AC_MSG_NOTICE([Static linking of libstdc++ was not possible reverting to dynamic linking.])
- enable_static_link_stdc__=no
+ if test "x$with_stdc__lib" = xstatic && test "x$has_static_libstdcxx" = xno; then
+ AC_MSG_ERROR([Static linking of libstdc++ was not possible!])
fi
- if test "x$enable_static_link_stdc__" = xno && test "x$has_dynamic_libstdcxx" = xno; then
- AC_MSG_NOTICE([Dynamic linking of libstdc++ was not possible reverting to static linking.])
- enable_static_link_stdc__=yes
+ if test "x$with_stdc__lib" = xdynamic && test "x$has_dynamic_libstdcxx" = xno; then
+ AC_MSG_ERROR([Dynamic linking of libstdc++ was not possible!])
fi
AC_MSG_CHECKING([how to link with libstdc++])
- if test "x$enable_static_link_stdc__" = xyes; then
+ # If dynamic was requested, it's available since it would fail above otherwise.
+ # If dynamic wasn't requested, go with static unless it isn't available.
+ if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno; then
+ LIBCXX="$LIBCXX -lstdc++"
+ LDCXX="$CXX"
+ STATIC_CXX_SETTING="STATIC_CXX=false"
+ AC_MSG_RESULT([dynamic])
+ else
LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
LDCXX="$CC"
STATIC_CXX_SETTING="STATIC_CXX=true"
AC_MSG_RESULT([static])
- else
- LIBCXX="$LIBCXX -lstdc++"
- LDCXX="$CXX"
- STATIC_CXX_SETTING="STATIC_CXX=false"
- AC_MSG_RESULT([dynamic])
fi
fi
AC_SUBST(STATIC_CXX_SETTING)
--- a/common/autoconf/source-dirs.m4 Fri Nov 30 12:39:37 2012 +0000
+++ b/common/autoconf/source-dirs.m4 Fri Nov 30 17:09:05 2012 -0800
@@ -253,5 +253,24 @@
BUILD_OUTPUT="$OUTPUT_ROOT"
AC_SUBST(BUILD_OUTPUT)
+HOTSPOT_DIST="$OUTPUT_ROOT/hotspot/dist"
+BUILD_HOTSPOT=true
+AC_SUBST(HOTSPOT_DIST)
+AC_SUBST(BUILD_HOTSPOT)
+AC_ARG_WITH(import-hotspot, [AS_HELP_STRING([--with-import-hotspot],
+ [import hotspot binaries from this jdk image or hotspot build dist dir instead of building from source])])
+if test "x$with_import_hotspot" != x; then
+ CURDIR="$PWD"
+ cd "$with_import_hotspot"
+ HOTSPOT_DIST="`pwd`"
+ cd "$CURDIR"
+ if ! (test -d $HOTSPOT_DIST/lib && test -d $HOTSPOT_DIST/jre/lib); then
+ AC_MSG_ERROR([You have to import hotspot from a full jdk image or hotspot build dist dir!])
+ fi
+ AC_MSG_CHECKING([if hotspot should be imported])
+ AC_MSG_RESULT([yes from $HOTSPOT_DIST])
+ BUILD_HOTSPOT=false
+fi
+
JDK_OUTPUTDIR="$OUTPUT_ROOT/jdk"
])
--- a/common/autoconf/spec.gmk.in Fri Nov 30 12:39:37 2012 +0000
+++ b/common/autoconf/spec.gmk.in Fri Nov 30 17:09:05 2012 -0800
@@ -224,7 +224,9 @@
CORBA_DIST=$(CORBA_OUTPUTDIR)/dist
JAXP_DIST=$(JAXP_OUTPUTDIR)/dist
JAXWS_DIST=$(JAXWS_OUTPUTDIR)/dist
-HOTSPOT_DIST=$(HOTSPOT_OUTPUTDIR)/dist
+HOTSPOT_DIST=@HOTSPOT_DIST@
+
+BUILD_HOTSPOT=@BUILD_HOTSPOT@
# The boot jdk to use
BOOT_JDK:=@BOOT_JDK@
@@ -244,12 +246,6 @@
# Store sjavac server synchronization files here, and
# the sjavac server log files.
SJAVAC_SERVER_DIR:=@SJAVAC_SERVER_DIR@
-# We can block the Javac server to never use more cores than this.
-# This is not for performance reasons, but for memory usage, since each
-# core requires its own JavaCompiler. We might have 64 cores and 4GB
-# of memory, 64 JavaCompilers will currently not fit in a 3GB heap.
-# Since there is no sharing of data between the JavaCompilers.
-SJAVAC_SERVER_CORES:=@SJAVAC_SERVER_CORES@
# The OpenJDK makefiles should be changed to using the standard
# configure output ..._CFLAGS and ..._LIBS. In the meantime we
@@ -494,7 +490,14 @@
# Where the build output is stored for your convenience.
BUILD_LOG:=@BUILD_LOG@
BUILD_LOG_PREVIOUS:=@BUILD_LOG_PREVIOUS@
-BUILD_LOG_WRAPPER:=@BUILD_LOG_WRAPPER@
+# Disable the build log wrapper on sjavac+winapi until
+# we have solved how to prevent the log wrapper to wait
+# for the background sjavac server process.
+ifeq (@ENABLE_SJAVAC@X@OPENJDK_BUILD_OS_API@,yesXwinapi)
+ BUILD_LOG_WRAPPER:=
+else
+ BUILD_LOG_WRAPPER:=@BUILD_LOG_WRAPPER@
+endif
# Build setup
ENABLE_JFR=@ENABLE_JFR@
--- a/common/autoconf/toolchain.m4 Fri Nov 30 12:39:37 2012 +0000
+++ b/common/autoconf/toolchain.m4 Fri Nov 30 17:09:05 2012 -0800
@@ -437,7 +437,10 @@
# full debug symbols are enabled.
if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; then
AC_CHECK_TOOLS(OBJCOPY, [gobjcopy objcopy])
- BASIC_FIXUP_EXECUTABLE(OBJCOPY)
+ # Only call fixup if objcopy was found.
+ if test -n "$OBJCOPY"; then
+ BASIC_FIXUP_EXECUTABLE(OBJCOPY)
+ fi
fi
AC_CHECK_TOOLS(OBJDUMP, [gobjdump objdump])
@@ -935,10 +938,19 @@
fi
fi
LDFLAGS_JDKLIB="${LDFLAGS_JDK} $SHARED_LIBRARY_FLAGS \
- -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/server \
- -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/client \
-L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}"
+ # On some platforms (mac) the linker warns about non existing -L dirs.
+ # Add server first if available. Linking aginst client does not always produce the same results.
+ # Only add client dir if client is being built. Default to server for other variants.
+ if test "x$JVM_VARIANT_SERVER" = xtrue; then
+ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/server"
+ elif test "x$JVM_VARIANT_CLIENT" = xtrue; then
+ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/client"
+ else
+ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} -L${JDK_OUTPUTDIR}/lib${OPENJDK_TARGET_CPU_LIBDIR}/server"
+ fi
+
LDFLAGS_JDKLIB_SUFFIX="-ljava -ljvm"
if test "x$COMPILER_NAME" = xossc; then
LDFLAGS_JDKLIB_SUFFIX="$LDFLAGS_JDKLIB_SUFFIX -lc"
--- a/common/bin/compare.sh Fri Nov 30 12:39:37 2012 +0000
+++ b/common/bin/compare.sh Fri Nov 30 17:09:05 2012 -0800
@@ -283,13 +283,14 @@
! -name "*.debuginfo" ! -name "*.dylib" ! -name "jexec" \
! -name "ct.sym" ! -name "*.diz" ! -name "*.dll" \
! -name "*.pdb" ! -name "*.exp" ! -name "*.ilk" \
- ! -name "*.lib" ! -name "*.war" \
+ ! -name "*.lib" ! -name "*.war" ! -name "JavaControlPanel" \
| $GREP -v "./bin/" | $SORT | $FILTER)
echo General files...
for f in $GENERAL_FILES
do
if [ -e $OTHER_DIR/$f ]; then
+ SUFFIX="${f##*.}"
if [ "$(basename $f)" = "release" ]; then
# Ignore differences in change numbers in release file.
OTHER_FILE=$WORK_DIR/$f.other
@@ -298,6 +299,22 @@
$MKDIR -p $(dirname $THIS_FILE)
$CAT $OTHER_DIR/$f | $SED 's/\:[0-9a-f]\{12,12\}/:CHANGE/g' > $OTHER_FILE
$CAT $THIS_DIR/$f | $SED 's/\:[0-9a-f]\{12,12\}/:CHANGE/g' > $THIS_FILE
+ elif [ "x$SUFFIX" = "xhtml" ]; then
+ # Ignore time stamps in docs files
+ OTHER_FILE=$WORK_DIR/$f.other
+ THIS_FILE=$WORK_DIR/$f.this
+ $MKDIR -p $(dirname $OTHER_FILE)
+ $MKDIR -p $(dirname $THIS_FILE)
+ $CAT $OTHER_DIR/$f | $SED -e 's/\(-- Generated by javadoc \).*\( --\)/\1(removed)\2/' \
+ -e 's/\(<meta name="date" content="\).*\(">\)/\1(removed)\2/' \
+ -e 's/\(Monday\|Tuesday\|Wednesday\|Thursday\|Friday\|Saturday\|Sunday\), [A-Z][a-z]* [0-9][0-9]*, [12][0-9]* [0-9][0-9:]* \(AM\|PM\) [A-Z][A-Z]*/(removed)/' \
+ -e 's/^\( from \).*\(\.idl\)$/\1(removed)\2/' \
+ > $OTHER_FILE
+ $CAT $THIS_DIR/$f | $SED -e 's/\(-- Generated by javadoc \).*\( --\)/\1(removed)\2/' \
+ -e 's/\(<meta name="date" content="\).*\(">\)/\1(removed)\2/' \
+ -e 's/\(Monday\|Tuesday\|Wednesday\|Thursday\|Friday\|Saturday\|Sunday\), [A-Z][a-z]* [0-9][0-9]*, [12][0-9]* [0-9][0-9:]* \(AM\|PM\) [A-Z][A-Z]*/(removed)/' \
+ -e 's/^\( from \).*\(\.idl\)$/\1(removed)\2/' \
+ > $THIS_FILE
else
OTHER_FILE=$OTHER_DIR/$f
THIS_FILE=$THIS_DIR/$f
@@ -611,10 +628,19 @@
DIFF_SIZE_NUM=$($EXPR $THIS_SIZE - $OTHER_SIZE)
DIFF_SIZE_REL=$($EXPR $THIS_SIZE \* 100 / $OTHER_SIZE)
SIZE_MSG=$($PRINTF "%3d%% %4d" $DIFF_SIZE_REL $DIFF_SIZE_NUM)
- if [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] && [ "$DIFF_SIZE_REL" -gt 98 ] && [ "$DIFF_SIZE_REL" -lt 102 ]; then
+ if [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] && [ "$DIFF_SIZE_REL" -gt 98 ] \
+ && [ "$DIFF_SIZE_REL" -lt 102 ]; then
SIZE_MSG="($SIZE_MSG)"
DIFF_SIZE=
- elif [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] && [ "$DIFF_SIZE_NUM" = 512 ]; then
+ elif [ "$OPENJDK_TARGET_OS" = "windows" ] \
+ && [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] \
+ && [ "$DIFF_SIZE_NUM" = 512 ]; then
+ # On windows, size of binaries increase in 512 increments.
+ SIZE_MSG="($SIZE_MSG)"
+ DIFF_SIZE=
+ elif [ "$OPENJDK_TARGET_OS" = "windows" ] \
+ && [[ "$ACCEPTED_SMALL_SIZE_DIFF" = *"$BIN_FILE"* ]] \
+ && [ "$DIFF_SIZE_NUM" = -512 ]; then
# On windows, size of binaries increase in 512 increments.
SIZE_MSG="($SIZE_MSG)"
DIFF_SIZE=
@@ -840,7 +866,7 @@
OTHER_DIR=$2
WORK_DIR=$3
- LIBS=$(cd $THIS_DIR && $FIND . -type f \( -name 'lib*.so' -o -name '*.dylib' -o -name '*.dll' \) | $SORT | $FILTER)
+ LIBS=$(cd $THIS_DIR && $FIND . -type f \( -name 'lib*.so' -o -name '*.dylib' -o -name '*.dll' -o -name 'JavaControlPanel' \) | $SORT | $FILTER)
if [ -n "$LIBS" ]; then
echo Libraries...
@@ -1102,6 +1128,22 @@
echo "Skipping bundle compare!"
fi
+if [ -d "$THIS/docs" ]; then
+ THIS_DOCS="$THIS/docs"
+fi
+
+if [ -d "$OTHER/docs" ]; then
+ OTHER_DOCS="$OTHER/docs"
+fi
+
+if [ -z "$THIS_DOCS" ]; then
+ echo "WARNING! Docs haven't been built and won't be compared."
+fi
+
+if [ -z "$OTHER_DOCS" ]; then
+ echo "WARNING! Other build doesn't contain docs, skipping doc compare."
+fi
+
##########################################################################################
# Do the work
@@ -1139,6 +1181,12 @@
echo -n "J2RE Bundle "
compare_files $THIS_J2RE_BUNDLE $OTHER_J2RE_BUNDLE $COMPARE_ROOT/j2re-bundle
fi
+ if [ -n "$THIS_DOCS" ] && [ -n "$OTHER_DOCS" ]; then
+ echo -n "Docs "
+ compare_dirs $THIS_DOCS $OTHER_DOCS $COMPARE_ROOT/docs
+ echo -n "Docs "
+ compare_files $THIS_DOCS $OTHER_DOCS $COMPARE_ROOT/docs
+ fi
fi
if [ "$CMP_PERMS" = "true" ]; then
@@ -1202,6 +1250,10 @@
echo -n "J2RE Bundle "
compare_general_files $THIS_J2RE_BUNDLE $OTHER_J2RE_BUNDLE $COMPARE_ROOT/j2re-bundle
fi
+ if [ -n "$THIS_DOCS" ] && [ -n "$OTHER_DOCS" ]; then
+ echo -n "Docs "
+ compare_general_files $THIS_DOCS $OTHER_DOCS $COMPARE_ROOT/docs
+ fi
fi
if [ "$CMP_ZIPS" = "true" ]; then
@@ -1218,7 +1270,12 @@
if [ "$CMP_LIBS" = "true" ]; then
if [ -n "$THIS_J2SDK" ] && [ -n "$OTHER_J2SDK" ]; then
+ echo -n "J2SDK "
compare_all_libs $THIS_J2SDK $OTHER_J2SDK $COMPARE_ROOT/j2sdk
+ if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
+ echo -n "J2RE "
+ compare_all_libs $THIS_J2RE $OTHER_J2RE $COMPARE_ROOT/j2re
+ fi
fi
if [ -n "$THIS_J2SDK_OVERLAY" ] && [ -n "$OTHER_J2SDK_OVERLAY" ]; then
echo -n "Bundle "
--- a/common/bin/compare_exceptions.sh.incl Fri Nov 30 12:39:37 2012 +0000
+++ b/common/bin/compare_exceptions.sh.incl Fri Nov 30 17:09:05 2012 -0800
@@ -291,6 +291,14 @@
./jre/plugin/i386/ns4/libjavaplugin.so
./jre/plugin/i386/ns7/libjavaplugin_oji.so
./jre/lib/i386/server/libjvm.so
+./jre/lib/i386/client/64/libjvm_db.so
+./jre/lib/i386/client/64/libjvm_dtrace.so
+./jre/lib/i386/client/libjvm_db.so
+./jre/lib/i386/client/libjvm_dtrace.so
+./jre/lib/i386/server/64/libjvm_db.so
+./jre/lib/i386/server/64/libjvm_dtrace.so
+./jre/lib/i386/server/libjvm_db.so
+./jre/lib/i386/server/libjvm_dtrace.so
./bin/appletviewer
./bin/extcheck
./bin/idlj
@@ -348,7 +356,9 @@
SKIP_FULLDUMP_DIFF="true"
# Filter random C++ symbol strings.
-DIS_DIFF_FILTER="$SED -e s/\.[a-zA-Z0-9_\$]\{15,15\}/<SYM>/g"
+# Some numbers differ randomly.
+# Can't use space in these expressions as the shell will mess with them.
+DIS_DIFF_FILTER="$SED -e s/\.[a-zA-Z0-9_\$]\{15,15\}/<SYM>/g -e s/\([0-9a-f][0-9a-f].\)\{2,8\}[0-9a-f][0-9a-f]/<NUMS>/g -e s/\(0x\)[0-9a-f]*\([,(>]\)/\1<HEX>\2/g -e s/\(0x\)[0-9a-f]*$/\1<HEX>/g -e s/\(\#.\)[0-9a-f]*\(.<\)/\1<HEX>\2/g -e s/[\.A-Za-z0-9%]\{16,16\}$/<BIN>/g"
fi
@@ -426,6 +436,9 @@
./jre/lib/amd64/libzip.so
./jre/lib/amd64/server/64/libjvm_db.so
./jre/lib/amd64/server/64/libjvm_dtrace.so
+./jre/lib/amd64/server/libjvm.so
+./jre/lib/amd64/server/libjvm_db.so
+./jre/lib/amd64/server/libjvm_dtrace.so
./bin/amd64/appletviewer
./bin/amd64/extcheck
./bin/amd64/idlj
@@ -480,7 +493,9 @@
SKIP_FULLDUMP_DIFF="true"
# Filter random C++ symbol strings.
-DIS_DIFF_FILTER="$SED -e s/\.[a-zA-Z0-9_\$]\{15,15\}/<SYM>/g"
+# Some numbers differ randomly.
+# Can't use space in these expressions as the shell will mess with them.
+DIS_DIFF_FILTER="$SED -e s/\.[a-zA-Z0-9_\$]\{15,15\}/<SYM>/g -e s/\([0-9a-f][0-9a-f].\)\{2,8\}[0-9a-f][0-9a-f]/<NUMS>/g -e s/\(0x\)[0-9a-f]*\([,(>]\)/\1<HEX>\2/g -e s/\(0x\)[0-9a-f]*$/\1<HEX>/g -e s/\(\#.\)[0-9a-f]*\(.<\)/\1<HEX>\2/g -e s/[\.A-Za-z0-9%]\{16,16\}$/<BIN>/g"
fi
@@ -881,6 +896,7 @@
KNOWN_BIN_DIFF="
./jre/lib/libJObjC.dylib
+./lib/libJObjC.dylib
"
ACCEPTED_BIN_DIFF="
@@ -932,26 +948,34 @@
./jre/bin/tnameserv
./jre/lib/libsaproc.dylib
./jre/lib/server/libjvm.dylib
+./lib/libsaproc.dylib
+./lib/server/libjvm.dylib
+./lib/deploy/JavaControlPanel.prefPane/Contents/MacOS/JavaControlPanel
"
KNOWN_SIZE_DIFF="
./jre/lib/libJObjC.dylib
+./lib/libJObjC.dylib
"
SORT_SYMBOLS="
./jre/lib/libJObjC.dylib
+./lib/libJObjC.dylib
"
KNOWN_SYM_DIFF="
./jre/lib/libJObjC.dylib
+./lib/libJObjC.dylib
"
KNOWN_ELF_DIFF="
./jre/lib/libJObjC.dylib
+./lib/libJObjC.dylib
"
KNOWN_DIS_DIFF="
./jre/lib/libJObjC.dylib
+./lib/libJObjC.dylib
"
fi
--- a/common/makefiles/JavaCompilation.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/common/makefiles/JavaCompilation.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -111,7 +111,7 @@
ifeq ($$(word 20,$$($1_GREP_INCLUDE_PATTERNS)),)
$1_GREP_INCLUDES:=| $(GREP) $$(patsubst %,$(SPACE)-e$(SPACE)$(DQUOTE)%$(DQUOTE),$$($1_GREP_INCLUDE_PATTERNS))
else
- $$(shell $(RM) $$($1_BIN)/_the.$$($1_JARNAME)_include)
+ $$(shell $(MKDIR) -p $$($1_BIN) && $(RM) $$($1_BIN)/_the.$$($1_JARNAME)_include)
$$(eval $$(call ListPathsSafelyNow,$1_GREP_INCLUDE_PATTERNS,\n, \
>> $$($1_BIN)/_the.$$($1_JARNAME)_include))
$1_GREP_INCLUDES:=| $(GREP) -f $$($1_BIN)/_the.$$($1_JARNAME)_include
@@ -124,7 +124,7 @@
ifeq ($$(word 20,$$($1_GREP_EXCLUDE_PATTERNS)),)
$1_GREP_EXCLUDES:=| $(GREP) -v $$(patsubst %,$(SPACE)-e$(SPACE)$(DQUOTE)%$(DQUOTE),$$($1_GREP_EXCLUDE_PATTERNS))
else
- $$(shell $(RM) $$($1_BIN)/_the.$$($1_JARNAME)_exclude)
+ $$(shell $(MKDIR) -p $$($1_BIN) && $(RM) $$($1_BIN)/_the.$$($1_JARNAME)_exclude)
$$(eval $$(call ListPathsSafelyNow,$1_GREP_EXCLUDE_PATTERNS,\n, \
>> $$($1_BIN)/_the.$$($1_JARNAME)_exclude))
$1_GREP_EXCLUDES:=| $(GREP) -v -f $$($1_BIN)/_the.$$($1_JARNAME)_exclude
@@ -170,9 +170,10 @@
# tells us what to remove from the jar-file.
$1_CAPTURE_DELETES=$$(foreach src,$$($1_SRCS),($(FIND) $$(src) -name _the.package.deleted -newer $$@ -exec $(SED) 's|$$(src)||g' \{\} >> $$($1_DELETES_FILE) \;) $$(NEWLINE))
# The update contents macro updates the jar file with the previously capture contents.
+ # xargs is used to trim the whitespace from the contents file, to see if it is empty.
$1_UPDATE_CONTENTS=$$(foreach src,$$($1_SRCS),\
(cd $$(src) && \
- if [ -s _the.$$($1_JARNAME)_contents ]; then \
+ if [ -n "`$(CAT) _the.$$($1_JARNAME)_contents | $(XARGS)`" ]; then \
$(ECHO) " updating" `$(WC) -l _the.$$($1_JARNAME)_contents | $(AWK) '{ print $$$$1 }'` files && \
$(JAR) $$($1_JAR_UPDATE_OPTIONS) $$@ @_the.$$($1_JARNAME)_contents; \
fi) $$(NEWLINE))
--- a/common/makefiles/Main.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/common/makefiles/Main.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -94,11 +94,13 @@
@($(CD) $(JAXWS_TOPDIR)/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f BuildJaxws.gmk)
@$(call TargetExit)
+ifeq ($(BUILD_HOTSPOT),true)
hotspot: hotspot-only
hotspot-only: start-make
@$(call TargetEnter)
@($(CD) $(SRC_ROOT)/common/makefiles && $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) -f HotspotWrapper.gmk)
@$(call TargetExit)
+endif
jdk: langtools hotspot corba jaxp jaxws jdk-only
jdk-only: start-make
@@ -163,7 +165,7 @@
# Remove everything, except the output from configure.
-clean: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-images clean-overlay-images clean-bootcycle-build
+clean: clean-langtools clean-corba clean-jaxp clean-jaxws clean-hotspot clean-jdk clean-images clean-overlay-images clean-bootcycle-build clean-docs
@($(CD) $(OUTPUT_ROOT) && $(RM) -r tmp source_tips build.log* build-trace*.log*)
@$(ECHO) Cleaned all build artifacts.
@@ -199,6 +201,9 @@
$(call CleanComponent,overlay-images)
clean-bootcycle-build:
$(call CleanComponent,bootcycle-build)
+clean-docs:
+ $(call CleanComponent,docs)
+ $(call CleanComponent,docstemp)
.PHONY: langtools corba jaxp jaxws hotspot jdk images overlay-images install
.PHONY: langtools-only corba-only jaxp-only jaxws-only hotspot-only jdk-only images-only overlay-images-only install-only
--- a/common/makefiles/MakeHelpers.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/common/makefiles/MakeHelpers.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -142,7 +142,7 @@
define TargetExit
$(call RecordEndTime,$(patsubst %-only,%,$@))
$(BUILD_LOG_WRAPPER) $(PRINTF) "## Finished $(patsubst %-only,%,$@) (build time %s)\n\n" \
- "`$(CAT) $(BUILDTIMESDIR)/build_time_diff_$(patsubst %-only,%,$@) | $(CUT) -f 1 -d " "`"
+ "`$(CAT) $(BUILDTIMESDIR)/build_time_diff_$(patsubst %-only,%,$@) | $(CUT) -f 1 -d ' '`"
$(call CheckIfMakeAtEnd)
endef
@@ -157,7 +157,7 @@
# Hook to be called as the very last thing for targets that are "top level" targets
define AtMakeEnd
- $(if $(SJAVAC_SERVER_DIR),@$(RM) -rf $(SJAVAC_SERVER_DIR)/*.port)
+ [ -f $(SJAVAC_SERVER_DIR)/server.port ] && echo Stopping sjavac server && $(TOUCH) $(SJAVAC_SERVER_DIR)/server.port.stop; true
$(call StopGlobalTimer)
$(call ReportBuildTimes)
@$(PRINTF) "Finished building $(PRODUCT_NAME) for target '$(call GetRealTarget)'\n"
@@ -174,8 +174,8 @@
define ParseLogLevel
ifeq ($$(origin VERBOSE),undefined)
# Setup logging according to LOG (but only if VERBOSE is not given)
-
- # If the "nofile" argument is given, act on it and strip it away
+
+ # If the "nofile" argument is given, act on it and strip it away
ifneq ($$(findstring nofile,$$(LOG)),)
# Reset the build log wrapper, regardless of other values
override BUILD_LOG_WRAPPER=
--- a/common/makefiles/javadoc/Javadoc.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/common/makefiles/javadoc/Javadoc.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -50,17 +50,12 @@
BOOT_JAVA_CMD=$(JAVA)
-# Langtools
-JAVAC_JAR = $(LANGTOOLS_DIST)/bootstrap/lib/javac.jar
JAVADOC_JAR = $(LANGTOOLS_DIST)/bootstrap/lib/javadoc.jar
-DOCLETS_JAR = $(LANGTOOLS_DIST)/bootstrap/lib/doclets.jar
JAVADOC_CMD = $(BOOT_JAVA_CMD) \
-Xmx1024m \
-Djava.awt.headless=true \
- "-Xbootclasspath/p:$(JAVADOC_JAR)$(CLASSPATH_SEPARATOR)$(JAVAC_JAR)$(CLASSPATH_SEPARATOR)$(DOCLETS_JAR)" \
- -jar $(JAVADOC_JAR)
-
-JAVADOC_CMD = javadoc
+ "-Xbootclasspath/p:$(JAVADOC_JAR)" \
+ -jar $(JAVADOC_JAR) -bootclasspath $(JDK_OUTPUTDIR)/classes
# Copyright year for beginning of Java and some of the apis
# (Needed when creating the javadocs)
@@ -113,7 +108,8 @@
# Url to copyright html file
COPYRIGHT_URL-7 = $(DOCSDIR_URL)/legal/cpyr.html
-COPYRIGHT_URL-8 = $(DOCSDIR_URL)/legal/cpyr.html
+# This isn't added in old build yet.
+#COPYRIGHT_URL-8 = $(DOCSDIR_URL)/legal/cpyr.html
COPYRIGHT_URL = $(COPYRIGHT_URL-$(JDK_MINOR_VERSION))
# Url to bug filing site
@@ -125,7 +121,8 @@
# Url to devdocs page
# Was: http://java.sun.com/javase/6/webnotes/devdocs-vs-specs.html
DEV_DOCS_URL-7 = http://download.oracle.com/javase/7/docs/index.html
-DEV_DOCS_URL-8 = http://download.oracle.com/javase/7/docs/index.html
+# This isn't added in old build yet.
+#DEV_DOCS_URL-8 = http://download.oracle.com/javase/7/docs/index.html
DEV_DOCS_URL = $(DEV_DOCS_URL-$(JDK_MINOR_VERSION))
DOCS_BASE_URL = http://download.oracle.com/javase/7/docs
@@ -142,9 +139,10 @@
# Otherwise, you get "No packages or classes specified." due
# to $(CLASSPATH_SEPARATOR) being interpreted as an end of
# command (newline or shell ; character)
-ALL_SOURCE_DIRS = $(JDK_IMPSRC) \
+ALL_SOURCE_DIRS = $(JDK_SHARE_CLASSES) \
+ $(JDK_IMPSRC) \
$(JDK_GENSRC) \
- $(JDK_SHARE_CLASSES) \
+ $(JDK_OUTPUTDIR)/gendocsrc_rmic \
$(JDK_TOPDIR)/src/solaris/classes \
$(JDK_TOPDIR)/src/windows/classes \
$(JDK_SHARE_SRC)/doc/stub
@@ -440,7 +438,7 @@
$(DOCLETAPI_INDEX_FILE): GET2DOCSDIR=$(DOCLETAPI2COREAPI)/..
# Run javadoc if the index file is out of date or missing
-$(DOCLETAPI_INDEX_FILE): $(DOCLETAPI_OPTIONS_FILE) $(DOCLETAPI_PACKAGES_FILE)
+$(DOCLETAPI_INDEX_FILE): $(DOCLETAPI_OPTIONS_FILE) $(DOCLETAPI_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(DOCLETAPI_OPTIONS_FILE),$(DOCLETAPI_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@@ -481,7 +479,7 @@
TAGLETAPI_TEMPDIR = $(DOCSTMPDIR)/taglets_temp
# The index.html, options, and packages files
-TAGLETAPI_INDEX_FILE = $(TAGLETAPI_DOCDIR)/com/sun/tools/doclets/Taglet.html
+TAGLETAPI_INDEX_FILE = $(TAGLETAPI_DOCDIR)/index.html
TAGLETAPI_OPTIONS_FILE = $(DOCSTMPDIR)/tagletapi.options
TAGLETAPI_PACKAGES_FILE = $(DOCSTMPDIR)/tagletapi.packages
@@ -491,7 +489,7 @@
$(TAGLETAPI_INDEX_FILE): GET2DOCSDIR=$(TAGLETAPI2COREAPI)/..
# Run javadoc if the index file is out of date or missing
-$(TAGLETAPI_INDEX_FILE): $(TAGLETAPI_OPTIONS_FILE) $(TAGLETAPI_PACKAGES_FILE)
+$(TAGLETAPI_INDEX_FILE): $(TAGLETAPI_OPTIONS_FILE) $(TAGLETAPI_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(RM) -r $(TAGLETAPI_TEMPDIR)
$(MKDIR) -p $(TAGLETAPI_TEMPDIR)
@@ -517,9 +515,7 @@
# Create a file with the package names in it
$(TAGLETAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(TAGLETAPI_PKGS))
$(prep-target)
- $(call PackageFilter,$(TAGLETAPI_PKGS))
- $(GREP) "$(TAGLETAPI_FILE)" $@ > $@.tmp
- $(MV) $@.tmp $@
+ @($(ECHO) "$(JDK_IMPSRC)/$(TAGLETAPI_FILE)" ) > $@
#############################################################
#
@@ -549,7 +545,7 @@
$(DOMAPI_INDEX_FILE): GET2DOCSDIR=$(DOMAPI2COREAPI)/..
# Run javadoc if the index file is out of date or missing
-$(DOMAPI_INDEX_FILE): $(DOMAPI_OPTIONS_FILE) $(DOMAPI_PACKAGES_FILE)
+$(DOMAPI_INDEX_FILE): $(DOMAPI_OPTIONS_FILE) $(DOMAPI_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(DOMAPI_OPTIONS_FILE),$(DOMAPI_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@@ -611,7 +607,7 @@
$(JDI_INDEX_FILE): GET2DOCSDIR=$(JDI2COREAPI)/..
# Run javadoc if the index file is out of date or missing
-$(JDI_INDEX_FILE): $(JDI_OPTIONS_FILE) $(JDI_PACKAGES_FILE)
+$(JDI_INDEX_FILE): $(JDI_OPTIONS_FILE) $(JDI_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(JDI_OPTIONS_FILE),$(JDI_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@@ -698,7 +694,7 @@
$(JAAS_INDEX_FILE): GET2DOCSDIR=$(JAAS2COREAPI)/..
# Run javadoc if the index file is out of date or missing
-$(JAAS_INDEX_FILE): $(JAAS_OPTIONS_FILE) $(JAAS_PACKAGES_FILE)
+$(JAAS_INDEX_FILE): $(JAAS_OPTIONS_FILE) $(JAAS_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(JAAS_OPTIONS_FILE),$(JAAS_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@@ -750,7 +746,7 @@
$(JGSS_INDEX_FILE): GET2DOCSDIR=$(JGSS2COREAPI)/..
# Run javadoc if the index file is out of date or missing
-$(JGSS_INDEX_FILE): $(JGSS_OPTIONS_FILE) $(JGSS_PACKAGES_FILE)
+$(JGSS_INDEX_FILE): $(JGSS_OPTIONS_FILE) $(JGSS_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(JGSS_OPTIONS_FILE),$(JGSS_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@@ -802,7 +798,7 @@
$(SMARTCARDIO_INDEX_FILE): GET2DOCSDIR=$(SMARTCARDIO2COREAPI)/..
# Run javadoc if the index file is out of date or missing
-$(SMARTCARDIO_INDEX_FILE): $(SMARTCARDIO_OPTIONS_FILE) $(SMARTCARDIO_PACKAGES_FILE)
+$(SMARTCARDIO_INDEX_FILE): $(SMARTCARDIO_OPTIONS_FILE) $(SMARTCARDIO_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(SMARTCARDIO_OPTIONS_FILE),$(SMARTCARDIO_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@@ -852,7 +848,7 @@
$(HTTPSERVER_INDEX_HTML): GET2DOCSDIR=$(HTTPSERVER2COREAPI)/..
# Run javadoc if the index file is out of date or missing
-$(HTTPSERVER_INDEX_HTML): $(HTTPSERVER_OPTIONS_FILE) $(HTTPSERVER_PACKAGES_FILE)
+$(HTTPSERVER_INDEX_HTML): $(HTTPSERVER_OPTIONS_FILE) $(HTTPSERVER_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(HTTPSERVER_OPTIONS_FILE),$(HTTPSERVER_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@@ -887,7 +883,7 @@
MGMT_DOCDIR := $(JRE_API_DOCSDIR)/management/extension
MGMT2COREAPI := ../../$(JDKJRE2COREAPI)
JVM_MIB_NAME := JVM-MANAGEMENT-MIB.mib
-JVM_MIB_SRC := $(CLOSED_SRC)/share/classes/sun/management/snmp/$(JVM_MIB_NAME)
+JVM_MIB_SRC := $(JDK_TOPDIR)/src/closed/share/classes/sun/management/snmp/$(JVM_MIB_NAME)
MGMT_DOCTITLE := Monitoring and Management Interface for the Java$(TRADEMARK) Platform
MGMT_WINDOWTITLE := Monitoring and Management Interface for the Java Platform
MGMT_HEADER := <strong>Monitoring and Management Interface for the Java Platform</strong>
@@ -906,7 +902,7 @@
$(MGMT_INDEX_FILE): GET2DOCSDIR=$(MGMT2COREAPI)/..
# Run javadoc if the index file is out of date or missing
-$(MGMT_INDEX_FILE): $(MGMT_OPTIONS_FILE) $(MGMT_PACKAGES_FILE)
+$(MGMT_INDEX_FILE): $(MGMT_OPTIONS_FILE) $(MGMT_PACKAGES_FILE) coredocs
$(prep-javadoc)
@if [ -f $(JVM_MIB_SRC) ] ; then \
$(ECHO) "$(CP) $(JVM_MIB_SRC) $(@D)/.."; \
@@ -963,7 +959,7 @@
$(ATTACH_INDEX_HTML): GET2DOCSDIR=$(ATTACH2COREAPI)/..
# Run javadoc if the index file is out of date or missing
-$(ATTACH_INDEX_HTML): $(ATTACH_OPTIONS_FILE) $(ATTACH_PACKAGES_FILE)
+$(ATTACH_INDEX_HTML): $(ATTACH_OPTIONS_FILE) $(ATTACH_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(ATTACH_OPTIONS_FILE),$(ATTACH_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@@ -1013,7 +1009,7 @@
$(JCONSOLE_INDEX_HTML): GET2DOCSDIR=$(JCONSOLE2COREAPI)/..
# Run javadoc if the index file is out of date or missing
-$(JCONSOLE_INDEX_HTML): $(JCONSOLE_OPTIONS_FILE) $(JCONSOLE_PACKAGES_FILE)
+$(JCONSOLE_INDEX_HTML): $(JCONSOLE_OPTIONS_FILE) $(JCONSOLE_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(JCONSOLE_OPTIONS_FILE),$(JCONSOLE_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@@ -1065,7 +1061,7 @@
$(TREEAPI_INDEX_HTML): GET2DOCSDIR=$(TREEAPI2COREAPI)/..
# Run javadoc if the index file is out of date or missing
-$(TREEAPI_INDEX_HTML): $(TREEAPI_OPTIONS_FILE) $(TREEAPI_PACKAGES_FILE)
+$(TREEAPI_INDEX_HTML): $(TREEAPI_OPTIONS_FILE) $(TREEAPI_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(TREEAPI_OPTIONS_FILE),$(TREEAPI_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
@@ -1116,7 +1112,7 @@
$(SCTPAPI_INDEX_HTML): GET2DOCSDIR=$(SCTPAPI2COREAPI)/..
# Run javadoc if the index file is out of date or missing
-$(SCTPAPI_INDEX_HTML): $(SCTPAPI_OPTIONS_FILE) $(SCTPAPI_PACKAGES_FILE)
+$(SCTPAPI_INDEX_HTML): $(SCTPAPI_OPTIONS_FILE) $(SCTPAPI_PACKAGES_FILE) coredocs
$(prep-javadoc)
$(call JavadocSummary,$(SCTPAPI_OPTIONS_FILE),$(SCTPAPI_PACKAGES_FILE))
$(JAVADOC_CMD) -d $(@D) \
--- a/corba/.hgtags Fri Nov 30 12:39:37 2012 +0000
+++ b/corba/.hgtags Fri Nov 30 17:09:05 2012 -0800
@@ -185,3 +185,5 @@
0e08ba7648fb3faa0986cb217887d7c4990977f3 jdk8-b61
08afb9c6f44f11c3595b01fd0985db64b29834dd jdk8-b62
6ccbf67b68bfed1ab9c44ab8748a5bdc7df33506 jdk8-b63
+54d599a5b4aad83c235d590652fc81f41c2824fb jdk8-b64
+5132f7900a8f0c30c3ca7f7a32f9433f4fee7745 jdk8-b65
--- a/hotspot/.hgtags Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/.hgtags Fri Nov 30 17:09:05 2012 -0800
@@ -291,3 +291,7 @@
dc16fe422c535ecd4e9f80fb814a1bb9704da6f5 hs25-b07
acabb5c282f59be7e3238920b2ea06b684ab68f7 jdk8-b63
8cb93eadfb6dcab88d91b8e2cd3e0e07d0ac4048 hs25-b08
+5920f72e799c8133d1066c4a62fa1fafcb729966 jdk8-b64
+b4ee7b773144a88af8b6b92e4384dea82cb948d8 hs25-b09
+0f7290a03b24bd562583fa325d3566c21c51fb94 jdk8-b65
+cfc5309f03b7bd6c1567618b63cf1fc74c0f2a8f hs25-b10
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/doc/c2replay.html Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,41 @@
+<html>
+<head>
+<title>
+C2 Replay
+</title>
+</head>
+<body>
+
+<h1>C2 compiler replay</h1>
+<p>
+The C2 compiler replay is a function to repeat the compiling process from a crashed java process in compiled method<br>
+This function only exists in debug version of VM
+</p>
+<h2>Usage</h2>
+<pre>
+First, use SA to attach to the core file, if suceeded, do
+ clhsdb>dumpreplaydata <address> | -a | <thread_id> [> replay.txt]
+ create file replay.txt, address is address of Method, or nmethod(CodeBlob)
+ clhsdb>buildreplayjars [all | boot | app]
+ create files:
+ all:
+ app.jar, boot.jar
+ boot:
+ boot.jar
+ app:
+ app.jar
+ exit SA now.
+Second, use the obtained replay text file, replay.txt and jar files, app.jar and boot.jar, using debug version of java
+ java -Xbootclasspath/p:boot.jar -cp app.jar -XX:ReplayDataFile=<datafile> -XX:+ReplayCompiles ....
+ This will replay the compiling process.
+
+ With ReplayCompiles, the replay will recompile all the methods in app.jar, and in boot.jar to emulate the process in java app.
+
+notes:
+ 1) Most time, we don't need the boot.jar which is the classes loaded from JDK. It will be only modified when an agent(JVMDI) is running and modifies the classes.
+ 2) If encounter error as "<flag>" not found, that means the SA is using a VMStructs which is different from the one with corefile. In this case, SA has a utility tool vmstructsdump which is located at agent/src/os/<os>/proc/<os_platform>
+
+ Use this tool to dump VM type library:
+ vmstructsdump libjvm.so > <type_name>.db
+
+ set env SA_TYPEDB=<type_name>.db (refer different shell for set envs)
--- a/hotspot/agent/doc/clhsdb.html Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/doc/clhsdb.html Fri Nov 30 17:09:05 2012 -0800
@@ -37,12 +37,19 @@
Available commands:
assert true | false <font color="red">turn on/off asserts in SA code</font>
attach pid | exec core <font color="red">attach SA to a process or core</font>
+ buildreplayjars [all | boot | app] <font color="red">build jars for replay, boot.jar for bootclasses, app.jar for application classes</font>
class name <font color="red">find a Java class from debuggee and print oop</font>
classes <font color="red">print all loaded Java classes with Klass*</font>
detach <font color="red">detach SA from current target</font>
dis address [ length ] <font color="red">disassemble (sparc/x86) specified number of instructions from given address</font>
+ dissemble address <font color="red">disassemble nmethod</font>
+ dumpcfg -a | id <font color="red">Dump the PhaseCFG for every compiler thread that has one live</font>
dumpclass { address | name } [ directory ] <font color="red">dump .class file for given Klass* or class name</font>
+ dumpcodecache <font color="red">dump codecache contents</font>
dumpheap [ file ] <font color="red">dump heap in hprof binary format</font>
+ dumpideal -a | id <font color="red">dump ideal graph like debug flag -XX:+PrintIdeal</font>
+ dumpilt -a | id <font color="red">dump inline tree for C2 compilation</font>
+ dumpreplaydata <address> | -a | <thread_id> [>replay.txt] <font color="red">dump replay data into a file</font>
echo [ true | false ] <font color="red">turn on/off command echo mode</font>
examine [ address/count ] | [ address,address] <font color="red">show contents of memory from given address</font>
field [ type [ name fieldtype isStatic offset address ] ] <font color="red">print info about a field of HotSpot type</font>
@@ -51,29 +58,35 @@
help [ command ] <font color="red">print help message for all commands or just given command</font>
history <font color="red">show command history. usual !command-number syntax works.</font>
inspect expression <font color="red">inspect a given oop</font>
+ intConstant [ name [ value ] ] <font color="red">print out hotspot integer constant(s)</font>
jdis address <font color="red">show bytecode disassembly of a given Method*</font>
jhisto <font color="red">show Java heap histogram</font>
jseval script <font color="red">evaluate a given string as JavaScript code</font>
jsload file <font color="red">load and evaluate a JavaScript file</font>
jstack [-v] <font color="red">show Java stack trace of all Java threads. -v is verbose mode</font>
livenmethods <font color="red">show all live nmethods</font>
+ longConstant [ name [ value ] ] <font color="red">print out hotspot long constant(s)s</font>
mem address [ length ] <font color="red">show contents of memory -- also shows closest ELF/COFF symbol if found</font>
pmap <font color="red">show Solaris pmap-like output</font>
print expression <font color="red">print given Klass*, Method* or arbitrary address</font>
printas type expression <font color="red">print given address as given HotSpot type. eg. print JavaThread <address></font>
+ printmdo -a | expression <font color="red">print method data oop</font>
printstatics [ type ] <font color="red">print static fields of given HotSpot type (or all types if none specified)</font>
pstack [-v] <font color="red">show mixed mode stack trace for all Java, non-Java threads. -v is verbose mode</font>
quit <font color="red">quit CLHSDB tool</font>
reattach <font color="red">detach and re-attach SA to current target</font>
+ revptrs <font color="red">find liveness of oops</font>
scanoops start end [ type ] <font color="red">scan a Oop from given start to end address</font>
search [ heap | codecache | threads ] value <font color="red">search a value in heap or codecache or threads</font>
source filename <font color="red">load and execute CLHSDB commands from given file</font>
symbol name <font color="red">show address of a given ELF/COFF symbol</font>
sysprops <font color="red">show all Java System properties</font>
+ thread id <font color="red">show thread of id</font>
threads <font color="red">show all Java threads</font>
tokenize ...
type [ type [ name super isOop isInteger isUnsigned size ] ] <font color="red">show info. on HotSpot type</font>
universe <font color="red">print gc universe</font>
+ vmstructsdump <font color="red">dump hotspot type library in text</font>
verbose true | false <font color="red">turn on/off verbose mode</font>
versioncheck [ true | false ] <font color="red">turn on/off debuggee VM version check</font>
whatis address <font color="red">print info about any arbitrary address</font>
@@ -114,5 +127,11 @@
</code>
</pre>
+<h3>C2 Compilation Replay</h3>
+<p>
+When a java process crashes in compiled method, usually a core file is saved.
+The C2 replay function can reproduce the compiling process in the core.
+<a href="c2replay.html">c2replay.html</a>
+
</body>
</html>
--- a/hotspot/agent/doc/index.html Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/doc/index.html Fri Nov 30 17:09:05 2012 -0800
@@ -220,6 +220,12 @@
</tr>
</table>
+<h3>C2 Compilation Replay</h3>
+<p>
+When a java process crashes in compiled method, usually a core file is saved.
+The C2 replay function can reproduce the compiling process in the core.
+<a href="c2replay.html">c2replay.html</a>
+
<h3>Debugging transported core dumps</h3>
<p>
When a core dump is moved from the machine where it was produced to a
--- a/hotspot/agent/make/Makefile Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/make/Makefile Fri Nov 30 17:09:05 2012 -0800
@@ -58,10 +58,8 @@
sun.jvm.hotspot.debugger.cdbg.basic.amd64 \
sun.jvm.hotspot.debugger.cdbg.basic.x86 \
sun.jvm.hotspot.debugger.dummy \
-sun.jvm.hotspot.debugger.ia64 \
sun.jvm.hotspot.debugger.linux \
sun.jvm.hotspot.debugger.linux.amd64 \
-sun.jvm.hotspot.debugger.linux.ia64 \
sun.jvm.hotspot.debugger.linux.x86 \
sun.jvm.hotspot.debugger.posix \
sun.jvm.hotspot.debugger.posix.elf \
@@ -77,7 +75,6 @@
sun.jvm.hotspot.debugger.win32.coff \
sun.jvm.hotspot.debugger.windbg \
sun.jvm.hotspot.debugger.windbg.amd64 \
-sun.jvm.hotspot.debugger.windbg.ia64 \
sun.jvm.hotspot.debugger.windbg.x86 \
sun.jvm.hotspot.debugger.x86 \
sun.jvm.hotspot.gc_implementation \
@@ -97,10 +94,8 @@
sun.jvm.hotspot.runtime.bsd \
sun.jvm.hotspot.runtime.bsd_amd64 \
sun.jvm.hotspot.runtime.bsd_x86 \
-sun.jvm.hotspot.runtime.ia64 \
sun.jvm.hotspot.runtime.linux \
sun.jvm.hotspot.runtime.linux_amd64 \
-sun.jvm.hotspot.runtime.linux_ia64 \
sun.jvm.hotspot.runtime.linux_sparc \
sun.jvm.hotspot.runtime.linux_x86 \
sun.jvm.hotspot.runtime.posix \
@@ -109,7 +104,6 @@
sun.jvm.hotspot.runtime.solaris_x86 \
sun.jvm.hotspot.runtime.sparc \
sun.jvm.hotspot.runtime.win32_amd64 \
-sun.jvm.hotspot.runtime.win32_ia64 \
sun.jvm.hotspot.runtime.win32_x86 \
sun.jvm.hotspot.runtime.x86 \
sun.jvm.hotspot.tools \
@@ -152,7 +146,6 @@
sun/jvm/hotspot/debugger/cdbg/basic/amd64/*.java \
sun/jvm/hotspot/debugger/cdbg/basic/x86/*.java \
sun/jvm/hotspot/debugger/dummy/*.java \
-sun/jvm/hotspot/debugger/ia64/*.java \
sun/jvm/hotspot/debugger/linux/*.java \
sun/jvm/hotspot/debugger/linux/x86/*.java \
sun/jvm/hotspot/debugger/posix/*.java \
@@ -168,7 +161,6 @@
sun/jvm/hotspot/debugger/sparc/*.java \
sun/jvm/hotspot/debugger/win32/coff/*.java \
sun/jvm/hotspot/debugger/windbg/*.java \
-sun/jvm/hotspot/debugger/windbg/ia64/*.java \
sun/jvm/hotspot/debugger/windbg/x86/*.java \
sun/jvm/hotspot/debugger/x86/*.java \
sun/jvm/hotspot/gc_implementation/g1/*.java \
@@ -186,10 +178,8 @@
sun/jvm/hotspot/runtime/bsd/*.java \
sun/jvm/hotspot/runtime/bsd_amd64/*.java \
sun/jvm/hotspot/runtime/bsd_x86/*.java \
-sun/jvm/hotspot/runtime/ia64/*.java \
sun/jvm/hotspot/runtime/linux/*.java \
sun/jvm/hotspot/runtime/linux_amd64/*.java \
-sun/jvm/hotspot/runtime/linux_ia64/*.java \
sun/jvm/hotspot/runtime/linux_sparc/*.java \
sun/jvm/hotspot/runtime/linux_x86/*.java \
sun/jvm/hotspot/runtime/posix/*.java \
@@ -198,7 +188,6 @@
sun/jvm/hotspot/runtime/solaris_x86/*.java \
sun/jvm/hotspot/runtime/sparc/*.java \
sun/jvm/hotspot/runtime/win32_amd64/*.java \
-sun/jvm/hotspot/runtime/win32_ia64/*.java \
sun/jvm/hotspot/runtime/win32_x86/*.java \
sun/jvm/hotspot/runtime/x86/*.java \
sun/jvm/hotspot/tools/*.java \
@@ -258,6 +247,7 @@
SA_PROPERTIES = $(OUTPUT_DIR)/sa.properties
JAVAC = $(JDK_HOME)/bin/javac
+JAVA = $(JDK_HOME)/bin/java
JAVADOC = $(JDK_HOME)/bin/javadoc
RMIC = $(JDK_HOME)/bin/rmic
@@ -298,7 +288,7 @@
.PHONY: natives
natives:
- cd ../src/os/`java -classpath $(OUTPUT_DIR) sun.jvm.hotspot.utilities.PlatformInfo`; $(MAKE) all
+ cd ../src/os/`$(JAVA) -classpath $(OUTPUT_DIR) sun.jvm.hotspot.utilities.PlatformInfo`; $(MAKE) all
.PHONY: sa-jdi.jar
sa-jdi.jar:
@@ -323,5 +313,5 @@
clean::
rm -rf filelist
- cd ../src/os/`java -classpath $(OUTPUT_DIR) sun.jvm.hotspot.utilities.PlatformInfo`; $(MAKE) clean
+ cd ../src/os/`$(JAVA) -classpath $(OUTPUT_DIR) sun.jvm.hotspot.utilities.PlatformInfo`; $(MAKE) clean
rm -rf $(BUILD_DIR)/*
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Fri Nov 30 17:09:05 2012 -0800
@@ -33,6 +33,7 @@
import sun.jvm.hotspot.types.Field;
import sun.jvm.hotspot.HotSpotTypeDataBase;
import sun.jvm.hotspot.types.basic.BasicType;
+import sun.jvm.hotspot.types.basic.BasicTypeDataBase;
import sun.jvm.hotspot.types.CIntegerType;
import sun.jvm.hotspot.code.*;
import sun.jvm.hotspot.compiler.*;
@@ -448,6 +449,112 @@
}
}
},
+ new Command("dumpreplaydata", "dumpreplaydata { <address > | -a | <thread_id> }", false) {
+ // This is used to dump replay data from ciInstanceKlass, ciMethodData etc
+ // default file name is replay.txt, also if java crashes in compiler
+ // thread, this file will be dumped in error processing.
+ public void doit(Tokens t) {
+ if (t.countTokens() != 1) {
+ usage();
+ return;
+ }
+ String name = t.nextToken();
+ Address a = null;
+ try {
+ a = VM.getVM().getDebugger().parseAddress(name);
+ } catch (NumberFormatException e) { }
+ if (a != null) {
+ // only nmethod, Method, MethodData and InstanceKlass needed to
+ // dump replay data
+
+ CodeBlob cb = VM.getVM().getCodeCache().findBlob(a);
+ if (cb != null && (cb instanceof NMethod)) {
+ ((NMethod)cb).dumpReplayData(out);
+ return;
+ }
+ // assume it is Metadata
+ Metadata meta = Metadata.instantiateWrapperFor(a);
+ if (meta != null) {
+ meta.dumpReplayData(out);
+ } else {
+ usage();
+ return;
+ }
+ }
+ // Not an address
+ boolean all = name.equals("-a");
+ Threads threads = VM.getVM().getThreads();
+ for (JavaThread thread = threads.first(); thread != null; thread = thread.next()) {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ thread.printThreadIDOn(new PrintStream(bos));
+ if (all || bos.toString().equals(name)) {
+ if (thread instanceof CompilerThread) {
+ CompilerThread ct = (CompilerThread)thread;
+ ciEnv env = ct.env();
+ if (env != null) {
+ env.dumpReplayData(out);
+ }
+ }
+ }
+ }
+ }
+ },
+ new Command("buildreplayjars", "buildreplayjars [ all | app | boot ] | [ prefix ]", false) {
+ // This is used to dump jar files of all the classes
+ // loaded in the core. Everything on the bootclasspath
+ // will go in boot.jar and everything else will go in
+ // app.jar. Then the classes can be loaded by the replay
+ // jvm using -Xbootclasspath/p:boot.jar -cp app.jar. boot.jar usually
+ // not needed, unless changed by jvmti.
+ public void doit(Tokens t) {
+ int tcount = t.countTokens();
+ if (tcount > 2) {
+ usage();
+ return;
+ }
+ try {
+ String prefix = "";
+ String option = "all"; // default
+ switch(tcount) {
+ case 0:
+ break;
+ case 1:
+ option = t.nextToken();
+ if (!option.equalsIgnoreCase("all") && !option.equalsIgnoreCase("app") &&
+ !option.equalsIgnoreCase("root")) {
+ prefix = option;
+ option = "all";
+ }
+ break;
+ case 2:
+ option = t.nextToken();
+ prefix = t.nextToken();
+ break;
+ default:
+ usage();
+ return;
+ }
+ if (!option.equalsIgnoreCase("all") && !option.equalsIgnoreCase("app") &&
+ !option.equalsIgnoreCase("boot")) {
+ usage();
+ return;
+ }
+ ClassDump cd = new ClassDump();
+ if (option.equalsIgnoreCase("all") || option.equalsIgnoreCase("boot")) {
+ cd.setClassFilter(new BootFilter());
+ cd.setJarOutput(prefix + "boot.jar");
+ cd.run();
+ }
+ if (option.equalsIgnoreCase("all") || option.equalsIgnoreCase("app")) {
+ cd.setClassFilter(new NonBootFilter());
+ cd.setJarOutput(prefix + "app.jar");
+ cd.run();
+ }
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+ },
new Command("findpc", "findpc address", false) {
public void doit(Tokens t) {
if (t.countTokens() != 1) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciBaseObject.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciBaseObject.java Fri Nov 30 17:09:05 2012 -0800
@@ -16,9 +16,9 @@
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * 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.
*
*/
@@ -50,4 +50,8 @@
public ciBaseObject(Address addr) {
super(addr);
}
+
+ public void dumpReplayData(PrintStream out) {
+ out.println("# Unknown ci type " + getAddress().getAddressAt(0));
+ }
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciConstant.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciConstant.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -16,9 +16,9 @@
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * 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.
*
*/
@@ -60,4 +60,8 @@
public ciConstant(Address addr) {
super(addr);
}
+
+ public void dumpReplayData(PrintStream out) {
+ // Nothing to be done
+ }
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciEnv.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciEnv.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -16,9 +16,9 @@
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * 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.
*
*/
@@ -74,4 +74,29 @@
public CompileTask task() {
return new CompileTask(taskField.getValue(this.getAddress()));
}
+
+ public void dumpReplayData(PrintStream out) {
+ out.println("JvmtiExport can_access_local_variables " +
+ (JvmtiExport.canAccessLocalVariables() ? '1' : '0'));
+ out.println("JvmtiExport can_hotswap_or_post_breakpoint " +
+ (JvmtiExport.canHotswapOrPostBreakpoint() ? '1' : '0'));
+ out.println("JvmtiExport can_post_on_exceptions " +
+ (JvmtiExport.canPostOnExceptions() ? '1' : '0'));
+
+ GrowableArray<ciMetadata> objects = factory().objects();
+ out.println("# " + objects.length() + " ciObject found");
+ for (int i = 0; i < objects.length(); i++) {
+ ciMetadata o = objects.at(i);
+ out.println("# ciMetadata" + i + " @ " + o);
+ o.dumpReplayData(out);
+ }
+ CompileTask task = task();
+ Method method = task.method();
+ int entryBci = task.osrBci();
+ Klass holder = method.getMethodHolder();
+ out.println("compile " + holder.getName().asString() + " " +
+ OopUtilities.escapeString(method.getName().asString()) + " " +
+ method.getSignature().asString() + " " +
+ entryBci);
+ }
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciInstanceKlass.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciInstanceKlass.java Fri Nov 30 17:09:05 2012 -0800
@@ -16,9 +16,9 @@
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * 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.
*
*/
@@ -80,4 +80,84 @@
public boolean isInitialized() {
return initState() == CLASS_STATE_FULLY_INITIALIZED;
}
+
+ public void dumpReplayData(PrintStream out) {
+ InstanceKlass ik = (InstanceKlass)getMetadata();
+ ConstantPool cp = ik.getConstants();
+
+ // Try to record related loaded classes
+ Klass sub = ik.getSubklassKlass();
+ while (sub != null) {
+ if (sub instanceof InstanceKlass) {
+ out.println("instanceKlass " + sub.getName().asString());
+ }
+ sub = sub.getNextSiblingKlass();
+ }
+
+ final int length = (int) cp.getLength();
+ out.print("ciInstanceKlass " + name() + " " + (isLinked() ? 1 : 0) + " " + (isInitialized() ? 1 : 0) + " " + length);
+ for (int index = 1; index < length; index++) {
+ out.print(" " + cp.getTags().at(index));
+ }
+ out.println();
+ if (isInitialized()) {
+ Field[] staticFields = ik.getStaticFields();
+ for (int i = 0; i < staticFields.length; i++) {
+ Field f = staticFields[i];
+ Oop mirror = ik.getJavaMirror();
+ if (f.isFinal() && !f.hasInitialValue()) {
+ out.print("staticfield " + name() + " " +
+ OopUtilities.escapeString(f.getID().getName()) + " " +
+ f.getFieldType().getSignature().asString() + " ");
+ if (f instanceof ByteField) {
+ ByteField bf = (ByteField)f;
+ out.println(bf.getValue(mirror));
+ } else if (f instanceof BooleanField) {
+ BooleanField bf = (BooleanField)f;
+ out.println(bf.getValue(mirror) ? 1 : 0);
+ } else if (f instanceof ShortField) {
+ ShortField bf = (ShortField)f;
+ out.println(bf.getValue(mirror));
+ } else if (f instanceof CharField) {
+ CharField bf = (CharField)f;
+ out.println(bf.getValue(mirror) & 0xffff);
+ } else if (f instanceof IntField) {
+ IntField bf = (IntField)f;
+ out.println(bf.getValue(mirror));
+ } else if (f instanceof LongField) {
+ LongField bf = (LongField)f;
+ out.println(bf.getValue(mirror));
+ } else if (f instanceof FloatField) {
+ FloatField bf = (FloatField)f;
+ out.println(Float.floatToRawIntBits(bf.getValue(mirror)));
+ } else if (f instanceof DoubleField) {
+ DoubleField bf = (DoubleField)f;
+ out.println(Double.doubleToRawLongBits(bf.getValue(mirror)));
+ } else if (f instanceof OopField) {
+ OopField bf = (OopField)f;
+ Oop value = bf.getValue(mirror);
+ if (value == null) {
+ out.println("null");
+ } else if (value.isInstance()) {
+ Instance inst = (Instance)value;
+ if (inst.isA(SystemDictionary.getStringKlass())) {
+ out.println("\"" + OopUtilities.stringOopToEscapedString(inst) + "\"");
+ } else {
+ out.println(inst.getKlass().getName().asString());
+ }
+ } else if (value.isObjArray()) {
+ ObjArray oa = (ObjArray)value;
+ Klass ek = (ObjArrayKlass)oa.getKlass();
+ out.println(oa.getLength() + " " + ek.getName().asString());
+ } else if (value.isTypeArray()) {
+ TypeArray ta = (TypeArray)value;
+ out.println(ta.getLength());
+ } else {
+ out.println(value);
+ }
+ }
+ }
+ }
+ }
+ }
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethod.java Fri Nov 30 17:09:05 2012 -0800
@@ -16,9 +16,9 @@
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * 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.
*
*/
@@ -88,4 +88,19 @@
st.printf(" %s::%s", method.getMethodHolder().getName().asString().replace('/', '.'),
method.getName().asString());
}
+
+ public void dumpReplayData(PrintStream out) {
+ Method method = (Method)getMetadata();
+ NMethod nm = method.getNativeMethod();
+ Klass holder = method.getMethodHolder();
+ out.println("ciMethod " +
+ holder.getName().asString() + " " +
+ OopUtilities.escapeString(method.getName().asString()) + " " +
+ method.getSignature().asString() + " " +
+ method.getInvocationCounter() + " " +
+ method.getBackedgeCounter() + " " +
+ interpreterInvocationCount() + " " +
+ interpreterThrowoutCount() + " " +
+ instructionsSize());
+ }
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethodData.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ci/ciMethodData.java Fri Nov 30 17:09:05 2012 -0800
@@ -16,9 +16,9 @@
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * 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.
*
*/
@@ -174,4 +174,52 @@
}
}
+ public void dumpReplayData(PrintStream out) {
+ MethodData mdo = (MethodData)getMetadata();
+ Method method = mdo.getMethod();
+ Klass holder = method.getMethodHolder();
+ out.print("ciMethodData " +
+ holder.getName().asString() + " " +
+ OopUtilities.escapeString(method.getName().asString()) + " " +
+ method.getSignature().asString() + " " +
+ state() + " " + currentMileage());
+ byte[] orig = orig();
+ out.print(" orig " + orig.length);
+ for (int i = 0; i < orig.length; i++) {
+ out.print(" " + (orig[i] & 0xff));
+ }
+
+ long[] data = data();
+ out.print(" data " + data.length);
+ for (int i = 0; i < data.length; i++) {
+ out.print(" 0x" + Long.toHexString(data[i]));
+ }
+ int count = 0;
+ for (int round = 0; round < 2; round++) {
+ if (round == 1) out.print(" oops " + count);
+ ProfileData pdata = firstData();
+ for ( ; isValid(pdata); pdata = nextData(pdata)) {
+ if (pdata instanceof ciReceiverTypeData) {
+ ciReceiverTypeData vdata = (ciReceiverTypeData)pdata;
+ for (int i = 0; i < vdata.rowLimit(); i++) {
+ ciKlass k = vdata.receiverAt(i);
+ if (k != null) {
+ if (round == 0) count++;
+ else out.print(" " + ((vdata.dp() + vdata.cellOffset(vdata.receiverCellIndex(i))) / MethodData.cellSize) + " " + k.name());
+ }
+ }
+ } else if (pdata instanceof ciVirtualCallData) {
+ ciVirtualCallData vdata = (ciVirtualCallData)pdata;
+ for (int i = 0; i < vdata.rowLimit(); i++) {
+ ciKlass k = vdata.receiverAt(i);
+ if (k != null) {
+ if (round == 0) count++;
+ else out.print(" " + ((vdata.dp() + vdata.cellOffset(vdata.receiverCellIndex(i))) / MethodData.cellSize + " " + k.name()));
+ }
+ }
+ }
+ }
+ }
+ out.println();
+ }
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java Fri Nov 30 17:09:05 2012 -0800
@@ -498,6 +498,42 @@
method.getSignature().asString();
}
+ public void dumpReplayData(PrintStream out) {
+ HashMap h = new HashMap();
+ for (int i = 1; i < getMetadataLength(); i++) {
+ Metadata meta = Metadata.instantiateWrapperFor(getMetadataAt(i));
+ System.err.println(meta);
+ if (h.get(meta) != null) continue;
+ h.put(meta, meta);
+ if (meta instanceof InstanceKlass) {
+ ((InstanceKlass)meta).dumpReplayData(out);
+ } else if (meta instanceof Method) {
+ ((Method)meta).dumpReplayData(out);
+ MethodData mdo = ((Method)meta).getMethodData();
+ if (mdo != null) {
+ mdo.dumpReplayData(out);
+ }
+ }
+ }
+ Method method = getMethod();
+ if (h.get(method) == null) {
+ method.dumpReplayData(out);
+ MethodData mdo = method.getMethodData();
+ if (mdo != null) {
+ mdo.dumpReplayData(out);
+ }
+ }
+ if (h.get(method.getMethodHolder()) == null) {
+ ((InstanceKlass)method.getMethodHolder()).dumpReplayData(out);
+ }
+ Klass holder = method.getMethodHolder();
+ out.println("compile " + holder.getName().asString() + " " +
+ OopUtilities.escapeString(method.getName().asString()) + " " +
+ method.getSignature().asString() + " " +
+ getEntryBCI());
+
+ }
+
//--------------------------------------------------------------------------------
// Internals only below this point
//
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/CompileTask.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/compiler/CompileTask.java Fri Nov 30 17:09:05 2012 -0800
@@ -56,7 +56,7 @@
}
public Method method() {
- Address oh = methodField.getValue(getAddress()).getAddressAt(0);
+ Address oh = methodField.getValue(getAddress());
return (Method)Metadata.instantiateWrapperFor(oh);
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Fri Nov 30 17:09:05 2012 -0800
@@ -121,7 +121,7 @@
Address addr = cache.getValue(getAddress());
return (ConstantPoolCache) VMObjectFactory.newObject(ConstantPoolCache.class, addr);
}
- public Klass getPoolHolder() { return (Klass) poolHolder.getValue(this); }
+ public InstanceKlass getPoolHolder() { return (InstanceKlass)poolHolder.getValue(this); }
public int getLength() { return (int)length.getValue(getAddress()); }
public Oop getResolvedReferences() {
Address handle = resolvedReferences.getValue(getAddress());
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java Fri Nov 30 17:09:05 2012 -0800
@@ -86,7 +86,7 @@
public void printValueOn(PrintStream tty) {
- tty.print("ConstantPoolCache for " + getConstants().getPoolHolder().getName().asString());
+ tty.print("ConstantPoolCache for " + getConstants().getPoolHolder().getName().asString() + " address = " + getAddress() + " offset = " + baseOffset);
}
public int getLength() {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Field.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Field.java Fri Nov 30 17:09:05 2012 -0800
@@ -110,6 +110,8 @@
public Symbol getSignature() { return signature; }
public Symbol getGenericSignature() { return genericSignature; }
+ public boolean hasInitialValue() { return holder.getFieldInitialValueIndex(fieldIndex) != 0; }
+
//
// Following acccessors are for named, non-VM fields only
//
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Fri Nov 30 17:09:05 2012 -0800
@@ -278,7 +278,7 @@
}
public short getFieldGenericSignatureIndex(int index) {
- int len = getFields().length();
+ // int len = getFields().length();
int allFieldsCount = getAllFieldsCount();
int generic_signature_slot = allFieldsCount * FIELD_SLOTS;
for (int i = 0; i < allFieldsCount; i++) {
@@ -325,7 +325,7 @@
public KlassArray getTransitiveInterfaces() { return new KlassArray(transitiveInterfaces.getValue(getAddress())); }
public int getJavaFieldsCount() { return (int) javaFieldsCount.getValue(this); }
public int getAllFieldsCount() {
- int len = getFields().length();
+ int len = getFields().length();
int allFieldsCount = 0;
for (; allFieldsCount*FIELD_SLOTS < len; allFieldsCount++) {
short flags = getFieldAccessFlags(allFieldsCount);
@@ -581,6 +581,19 @@
}
}
+ public Field[] getStaticFields() {
+ U2Array fields = getFields();
+ int length = getJavaFieldsCount();
+ ArrayList result = new ArrayList();
+ for (int index = 0; index < length; index++) {
+ Field f = newField(index);
+ if (f.isStatic()) {
+ result.add(f);
+ }
+ }
+ return (Field[])result.toArray(new Field[result.size()]);
+ }
+
public void iterateNonStaticFields(OopVisitor visitor, Oop obj) {
if (getSuper() != null) {
((InstanceKlass) getSuper()).iterateNonStaticFields(visitor, obj);
@@ -979,4 +992,84 @@
}
return -1;
}
+
+ public void dumpReplayData(PrintStream out) {
+ ConstantPool cp = getConstants();
+
+ // Try to record related loaded classes
+ Klass sub = getSubklassKlass();
+ while (sub != null) {
+ if (sub instanceof InstanceKlass) {
+ out.println("instanceKlass " + sub.getName().asString());
+ }
+ sub = sub.getNextSiblingKlass();
+ }
+
+ final int length = (int) cp.getLength();
+ out.print("ciInstanceKlass " + getName().asString() + " " + (isLinked() ? 1 : 0) + " " + (isInitialized() ? 1 : 0) + " " + length);
+ for (int index = 1; index < length; index++) {
+ out.print(" " + cp.getTags().at(index));
+ }
+ out.println();
+ if (isInitialized()) {
+ Field[] staticFields = getStaticFields();
+ for (int i = 0; i < staticFields.length; i++) {
+ Field f = staticFields[i];
+ Oop mirror = getJavaMirror();
+ if (f.isFinal() && !f.hasInitialValue()) {
+ out.print("staticfield " + getName().asString() + " " +
+ OopUtilities.escapeString(f.getID().getName()) + " " +
+ f.getFieldType().getSignature().asString() + " ");
+ if (f instanceof ByteField) {
+ ByteField bf = (ByteField)f;
+ out.println(bf.getValue(mirror));
+ } else if (f instanceof BooleanField) {
+ BooleanField bf = (BooleanField)f;
+ out.println(bf.getValue(mirror) ? 1 : 0);
+ } else if (f instanceof ShortField) {
+ ShortField bf = (ShortField)f;
+ out.println(bf.getValue(mirror));
+ } else if (f instanceof CharField) {
+ CharField bf = (CharField)f;
+ out.println(bf.getValue(mirror) & 0xffff);
+ } else if (f instanceof IntField) {
+ IntField bf = (IntField)f;
+ out.println(bf.getValue(mirror));
+ } else if (f instanceof LongField) {
+ LongField bf = (LongField)f;
+ out.println(bf.getValue(mirror));
+ } else if (f instanceof FloatField) {
+ FloatField bf = (FloatField)f;
+ out.println(Float.floatToRawIntBits(bf.getValue(mirror)));
+ } else if (f instanceof DoubleField) {
+ DoubleField bf = (DoubleField)f;
+ out.println(Double.doubleToRawLongBits(bf.getValue(mirror)));
+ } else if (f instanceof OopField) {
+ OopField bf = (OopField)f;
+
+ Oop value = bf.getValue(mirror);
+ if (value == null) {
+ out.println("null");
+ } else if (value.isInstance()) {
+ Instance inst = (Instance)value;
+ if (inst.isA(SystemDictionary.getStringKlass())) {
+ out.println("\"" + OopUtilities.stringOopToEscapedString(inst) + "\"");
+ } else {
+ out.println(inst.getKlass().getName().asString());
+ }
+ } else if (value.isObjArray()) {
+ ObjArray oa = (ObjArray)value;
+ Klass ek = (ObjArrayKlass)oa.getKlass();
+ out.println(oa.getLength() + " " + ek.getName().asString());
+ } else if (value.isTypeArray()) {
+ TypeArray ta = (TypeArray)value;
+ out.println(ta.getLength());
+ } else {
+ out.println(value);
+ }
+ }
+ }
+ }
+ }
+ }
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Metadata.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Metadata.java Fri Nov 30 17:09:05 2012 -0800
@@ -79,4 +79,7 @@
}
abstract public void printValueOn(PrintStream tty);
+ public void dumpReplayData(PrintStream out) {
+ out.println("# Unknown Metadata");
+ }
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Fri Nov 30 17:09:05 2012 -0800
@@ -177,7 +177,7 @@
bci. It is required that there is currently a bytecode at this
bci. */
public int getOrigBytecodeAt(int bci) {
- BreakpointInfo bp = ((InstanceKlass) getMethodHolder()).getBreakpoints();
+ BreakpointInfo bp = getMethodHolder().getBreakpoints();
for (; bp != null; bp = bp.getNext()) {
if (bp.match(this, bci)) {
return bp.getOrigBytecode();
@@ -238,7 +238,7 @@
}
// Method holder (the Klass holding this method)
- public Klass getMethodHolder() { return getConstants().getPoolHolder(); }
+ public InstanceKlass getMethodHolder() { return getConstants().getPoolHolder(); }
// Access flags
public boolean isPublic() { return getAccessFlagsObj().isPublic(); }
@@ -358,6 +358,25 @@
buf.append(")");
return buf.toString().replace('/', '.');
}
+
+ public void dumpReplayData(PrintStream out) {
+ NMethod nm = getNativeMethod();
+ int code_size = 0;
+ if (nm != null) {
+ code_size = (int)nm.codeEnd().minus(nm.getVerifiedEntryPoint());
+ }
+ Klass holder = getMethodHolder();
+ out.println("ciMethod " +
+ holder.getName().asString() + " " +
+ OopUtilities.escapeString(getName().asString()) + " " +
+ getSignature().asString() + " " +
+ getInvocationCounter() + " " +
+ getBackedgeCounter() + " " +
+ interpreterInvocationCount() + " " +
+ interpreterThrowoutCount() + " " +
+ code_size);
+ }
+
public int interpreterThrowoutCount() {
return (int) interpreterThrowoutCountField.getValue(this);
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java Fri Nov 30 17:09:05 2012 -0800
@@ -332,4 +332,59 @@
public int currentMileage() {
return 20000;
}
+
+ public void dumpReplayData(PrintStream out) {
+ Method method = getMethod();
+ Klass holder = method.getMethodHolder();
+ out.print("ciMethodData " +
+ holder.getName().asString() + " " +
+ OopUtilities.escapeString(method.getName().asString()) + " " +
+ method.getSignature().asString() + " " +
+ "2" + " " +
+ currentMileage());
+ byte[] orig = orig();
+ out.print(" orig " + orig.length);
+ for (int i = 0; i < orig.length; i++) {
+ out.print(" " + (orig[i] & 0xff));
+ }
+
+ long[] data = data();
+ out.print(" data " + data.length);
+ for (int i = 0; i < data.length; i++) {
+ out.print(" 0x" + Long.toHexString(data[i]));
+ }
+ int count = 0;
+ for (int round = 0; round < 2; round++) {
+ if (round == 1) out.print(" oops " + count);
+ ProfileData pdata = firstData();
+ for ( ; isValid(pdata); pdata = nextData(pdata)) {
+ if (pdata instanceof ReceiverTypeData) {
+ ReceiverTypeData vdata = (ReceiverTypeData)pdata;
+ for (int i = 0; i < vdata.rowLimit(); i++) {
+ Klass k = vdata.receiver(i);
+ if (k != null) {
+ if (round == 0) count++;
+ else out.print(" " +
+ (dpToDi(vdata.dp() +
+ vdata.cellOffset(vdata.receiverCellIndex(i))) / cellSize) + " " +
+ k.getName().asString());
+ }
+ }
+ } else if (pdata instanceof VirtualCallData) {
+ VirtualCallData vdata = (VirtualCallData)pdata;
+ for (int i = 0; i < vdata.rowLimit(); i++) {
+ Klass k = vdata.receiver(i);
+ if (k != null) {
+ if (round == 0) count++;
+ else out.print(" " +
+ (dpToDi(vdata.dp() +
+ vdata.cellOffset(vdata.receiverCellIndex(i))) / cellSize) + " " +
+ k.getName().asString());
+ }
+ }
+ }
+ }
+ }
+ out.println();
+ }
}
--- a/hotspot/make/hotspot_version Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/make/hotspot_version Fri Nov 30 17:09:05 2012 -0800
@@ -35,7 +35,7 @@
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=08
+HS_BUILD_NUMBER=10
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
--- a/hotspot/make/linux/makefiles/defs.make Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/make/linux/makefiles/defs.make Fri Nov 30 17:09:05 2012 -0800
@@ -170,68 +170,70 @@
# overridden in some situations, e.g., a BUILD_FLAVOR != product
# build.
- ifeq ($(BUILD_FLAVOR), product)
- FULL_DEBUG_SYMBOLS ?= 1
- ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
- else
- # debug variants always get Full Debug Symbols (if available)
- ENABLE_FULL_DEBUG_SYMBOLS = 1
- endif
- _JUNK_ := $(shell \
- echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
- # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
+ # Due to the multiple sub-make processes that occur this logic gets
+ # executed multiple times. We reduce the noise by at least checking that
+ # BUILD_FLAVOR has been set.
+ ifneq ($(BUILD_FLAVOR),)
+ ifeq ($(BUILD_FLAVOR), product)
+ FULL_DEBUG_SYMBOLS ?= 1
+ ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
+ else
+ # debug variants always get Full Debug Symbols (if available)
+ ENABLE_FULL_DEBUG_SYMBOLS = 1
+ endif
+ _JUNK_ := $(shell \
+ echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
+ # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
- ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
- # Default OBJCOPY comes from GNU Binutils on Linux:
- DEF_OBJCOPY=/usr/bin/objcopy
- ifdef CROSS_COMPILE_ARCH
- # don't try to generate .debuginfo files when cross compiling
- _JUNK_ := $(shell \
- echo >&2 "INFO: cross compiling for ARCH $(CROSS_COMPILE_ARCH)," \
- "skipping .debuginfo generation.")
- OBJCOPY=
- else
+ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+ # Default OBJCOPY comes from GNU Binutils on Linux
+ ifeq ($(CROSS_COMPILE_ARCH),)
+ DEF_OBJCOPY=/usr/bin/objcopy
+ else
+ # Assume objcopy is part of the cross-compilation toolset
+ ifneq ($(ALT_COMPILER_PATH),)
+ DEF_OBJCOPY=$(ALT_COMPILER_PATH)/objcopy
+ endif
+ endif
OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
ifneq ($(ALT_OBJCOPY),)
_JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
endif
- endif
- else
- OBJCOPY=
- endif
- ifeq ($(OBJCOPY),)
- _JUNK_ := $(shell \
- echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.")
- ENABLE_FULL_DEBUG_SYMBOLS=0
- _JUNK_ := $(shell \
- echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
- else
- _JUNK_ := $(shell \
- echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.")
+ ifeq ($(OBJCOPY),)
+ _JUNK_ := $(shell \
+ echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files. You may need to set ALT_OBJCOPY.")
+ ENABLE_FULL_DEBUG_SYMBOLS=0
+ _JUNK_ := $(shell \
+ echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
+ else
+ _JUNK_ := $(shell \
+ echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.")
- # Library stripping policies for .debuginfo configs:
- # all_strip - strips everything from the library
- # min_strip - strips most stuff from the library; leaves minimum symbols
- # no_strip - does not strip the library at all
- #
- # Oracle security policy requires "all_strip". A waiver was granted on
- # 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE.
- #
- # Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled.
- #
- STRIP_POLICY ?= min_strip
+ # Library stripping policies for .debuginfo configs:
+ # all_strip - strips everything from the library
+ # min_strip - strips most stuff from the library; leaves minimum symbols
+ # no_strip - does not strip the library at all
+ #
+ # Oracle security policy requires "all_strip". A waiver was granted on
+ # 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE.
+ #
+ # Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled.
+ #
+ STRIP_POLICY ?= min_strip
- _JUNK_ := $(shell \
- echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)")
+ _JUNK_ := $(shell \
+ echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)")
- ZIP_DEBUGINFO_FILES ?= 1
+ ZIP_DEBUGINFO_FILES ?= 1
- _JUNK_ := $(shell \
- echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)")
- endif
-endif
+ _JUNK_ := $(shell \
+ echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)")
+ endif
+ endif # ENABLE_FULL_DEBUG_SYMBOLS=1
+ endif # BUILD_FLAVOR
+endif # JDK_6_OR_EARLIER
JDK_INCLUDE_SUBDIR=linux
--- a/hotspot/make/linux/makefiles/vm.make Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/make/linux/makefiles/vm.make Fri Nov 30 17:09:05 2012 -0800
@@ -336,24 +336,23 @@
fi \
fi \
}
-ifeq ($(CROSS_COMPILE_ARCH),)
- ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+
+ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DEBUGINFO)
$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@
- ifeq ($(STRIP_POLICY),all_strip)
+ ifeq ($(STRIP_POLICY),all_strip)
$(QUIETLY) $(STRIP) $@
- else
- ifeq ($(STRIP_POLICY),min_strip)
+ else
+ ifeq ($(STRIP_POLICY),min_strip)
$(QUIETLY) $(STRIP) -g $@
- # implied else here is no stripping at all
- endif
+ # implied else here is no stripping at all
endif
+ endif
$(QUIETLY) [ -f $(LIBJVM_G_DEBUGINFO) ] || ln -s $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO)
- ifeq ($(ZIP_DEBUGINFO_FILES),1)
+ ifeq ($(ZIP_DEBUGINFO_FILES),1)
$(ZIPEXE) -q -y $(LIBJVM_DIZ) $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO)
$(RM) $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO)
[ -f $(LIBJVM_G_DIZ) ] || { ln -s $(LIBJVM_DIZ) $(LIBJVM_G_DIZ); }
- endif
endif
endif
--- a/hotspot/make/solaris/makefiles/defs.make Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/make/solaris/makefiles/defs.make Fri Nov 30 17:09:05 2012 -0800
@@ -109,60 +109,63 @@
# overridden in some situations, e.g., a BUILD_FLAVOR != product
# build.
- ifeq ($(BUILD_FLAVOR), product)
- FULL_DEBUG_SYMBOLS ?= 1
- ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
- else
- # debug variants always get Full Debug Symbols (if available)
- ENABLE_FULL_DEBUG_SYMBOLS = 1
- endif
- _JUNK_ := $(shell \
- echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
- # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
-
- ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
- # Default OBJCOPY comes from the SUNWbinutils package:
- DEF_OBJCOPY=/usr/sfw/bin/gobjcopy
- OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
- ifneq ($(ALT_OBJCOPY),)
- _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
- OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
+ # Due to the multiple sub-make processes that occur this logic gets
+ # executed multiple times. We reduce the noise by at least checking that
+ # BUILD_FLAVOR has been set.
+ ifneq ($(BUILD_FLAVOR),)
+ ifeq ($(BUILD_FLAVOR), product)
+ FULL_DEBUG_SYMBOLS ?= 1
+ ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
+ else
+ # debug variants always get Full Debug Symbols (if available)
+ ENABLE_FULL_DEBUG_SYMBOLS = 1
endif
- else
- OBJCOPY=
- endif
-
- ifeq ($(OBJCOPY),)
- _JUNK_ := $(shell \
- echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.")
- ENABLE_FULL_DEBUG_SYMBOLS=0
_JUNK_ := $(shell \
echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
- else
- _JUNK_ := $(shell \
- echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.")
+ # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
+
+ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+ # Default OBJCOPY comes from the SUNWbinutils package:
+ DEF_OBJCOPY=/usr/sfw/bin/gobjcopy
+ OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
+ ifneq ($(ALT_OBJCOPY),)
+ _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
+ OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
+ endif
+
+ ifeq ($(OBJCOPY),)
+ _JUNK_ := $(shell \
+ echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.")
+ ENABLE_FULL_DEBUG_SYMBOLS=0
+ _JUNK_ := $(shell \
+ echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
+ else
+ _JUNK_ := $(shell \
+ echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.")
- # Library stripping policies for .debuginfo configs:
- # all_strip - strips everything from the library
- # min_strip - strips most stuff from the library; leaves minimum symbols
- # no_strip - does not strip the library at all
- #
- # Oracle security policy requires "all_strip". A waiver was granted on
- # 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE.
- #
- # Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled.
- #
- STRIP_POLICY ?= min_strip
+ # Library stripping policies for .debuginfo configs:
+ # all_strip - strips everything from the library
+ # min_strip - strips most stuff from the library; leaves minimum symbols
+ # no_strip - does not strip the library at all
+ #
+ # Oracle security policy requires "all_strip". A waiver was granted on
+ # 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE.
+ #
+ # Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled.
+ #
+ STRIP_POLICY ?= min_strip
- _JUNK_ := $(shell \
- echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)")
+ _JUNK_ := $(shell \
+ echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)")
- ZIP_DEBUGINFO_FILES ?= 1
+ ZIP_DEBUGINFO_FILES ?= 1
- _JUNK_ := $(shell \
- echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)")
- endif
-endif
+ _JUNK_ := $(shell \
+ echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)")
+ endif
+ endif # ENABLE_FULL_DEBUG_SYMBOLS=1
+ endif # BUILD_FLAVOR
+endif # JDK_6_OR_EARLIER
JDK_INCLUDE_SUBDIR=solaris
--- a/hotspot/make/windows/makefiles/defs.make Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/make/windows/makefiles/defs.make Fri Nov 30 17:09:05 2012 -0800
@@ -131,23 +131,29 @@
# overridden in some situations, e.g., a BUILD_FLAVOR != product
# build.
-ifeq ($(BUILD_FLAVOR), product)
- FULL_DEBUG_SYMBOLS ?= 1
- ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
-else
- # debug variants always get Full Debug Symbols (if available)
- ENABLE_FULL_DEBUG_SYMBOLS = 1
+# Due to the multiple sub-make processes that occur this logic gets
+# executed multiple times. We reduce the noise by at least checking that
+# BUILD_FLAVOR has been set.
+ifneq ($(BUILD_FLAVOR),)
+ ifeq ($(BUILD_FLAVOR), product)
+ FULL_DEBUG_SYMBOLS ?= 1
+ ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
+ else
+ # debug variants always get Full Debug Symbols (if available)
+ ENABLE_FULL_DEBUG_SYMBOLS = 1
+ endif
+ _JUNK_ := $(shell \
+ echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
+ MAKE_ARGS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)
+
+ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+ ZIP_DEBUGINFO_FILES ?= 1
+ else
+ ZIP_DEBUGINFO_FILES=0
+ endif
+ MAKE_ARGS += ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)
endif
-_JUNK_ := $(shell \
- echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
-MAKE_ARGS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)
-ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
- ZIP_DEBUGINFO_FILES ?= 1
-else
- ZIP_DEBUGINFO_FILES=0
-endif
-MAKE_ARGS += ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)
MAKE_ARGS += RM="$(RM)"
MAKE_ARGS += ZIPEXE=$(ZIPEXE)
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -2322,7 +2322,7 @@
// Pre-load a static method's oop into O1. Used both by locking code and
// the normal JNI call code.
if (method->is_static() && !is_critical_native) {
- __ set_oop_constant(JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror()), O1);
+ __ set_oop_constant(JNIHandles::make_local(method->method_holder()->java_mirror()), O1);
// Now handlize the static class mirror in O1. It's known not-null.
__ st_ptr(O1, SP, klass_offset + STACK_BIAS);
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1936,7 +1936,7 @@
if (method->is_static() && !is_critical_native) {
// load opp into a register
- __ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror()));
+ __ movoop(oop_handle_reg, JNIHandles::make_local(method->method_holder()->java_mirror()));
// Now handlize the static class mirror it's known not-null.
__ movptr(Address(rsp, klass_offset), oop_handle_reg);
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -2179,7 +2179,7 @@
if (method->is_static() && !is_critical_native) {
// load oop into a register
- __ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror()));
+ __ movoop(oop_handle_reg, JNIHandles::make_local(method->method_holder()->java_mirror()));
// Now handlize the static class mirror it's known not-null.
__ movptr(Address(rsp, klass_offset), oop_handle_reg);
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -488,8 +488,8 @@
}
// The AES intrinsic stubs require AES instruction support (of course)
- // but also require AVX mode for misaligned SSE access
- if (UseAES && (UseAVX > 0)) {
+ // but also require AVX and sse3 modes for instructions it use.
+ if (UseAES && (UseAVX > 0) && (UseSSE > 2)) {
if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
UseAESIntrinsics = true;
}
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1198,19 +1198,20 @@
return os::stat(filename, &statbuf) == 0;
}
-void os::dll_build_name(char* buffer, size_t buflen,
+bool os::dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
+ bool retval = false;
// Copied from libhpi
const size_t pnamelen = pname ? strlen(pname) : 0;
- // Quietly truncate on buffer overflow. Should be an error.
+ // Return error on buffer overflow.
if (pnamelen + strlen(fname) + strlen(JNI_LIB_PREFIX) + strlen(JNI_LIB_SUFFIX) + 2 > buflen) {
- *buffer = '\0';
- return;
+ return retval;
}
if (pnamelen == 0) {
snprintf(buffer, buflen, JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, fname);
+ retval = true;
} else if (strchr(pname, *os::path_separator()) != NULL) {
int n;
char** pelements = split_path(pname, &n);
@@ -1222,6 +1223,7 @@
snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX,
pelements[i], fname);
if (file_exists(buffer)) {
+ retval = true;
break;
}
}
@@ -1236,7 +1238,9 @@
}
} else {
snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, pname, fname);
+ retval = true;
}
+ return retval;
}
const char* os::get_current_directory(char *buf, int buflen) {
--- a/hotspot/src/os/linux/vm/os_linux.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1650,19 +1650,20 @@
return os::stat(filename, &statbuf) == 0;
}
-void os::dll_build_name(char* buffer, size_t buflen,
+bool os::dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
+ bool retval = false;
// Copied from libhpi
const size_t pnamelen = pname ? strlen(pname) : 0;
- // Quietly truncate on buffer overflow. Should be an error.
+ // Return error on buffer overflow.
if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
- *buffer = '\0';
- return;
+ return retval;
}
if (pnamelen == 0) {
snprintf(buffer, buflen, "lib%s.so", fname);
+ retval = true;
} else if (strchr(pname, *os::path_separator()) != NULL) {
int n;
char** pelements = split_path(pname, &n);
@@ -1673,6 +1674,7 @@
}
snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname);
if (file_exists(buffer)) {
+ retval = true;
break;
}
}
@@ -1687,7 +1689,9 @@
}
} else {
snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
- }
+ retval = true;
+ }
+ return retval;
}
const char* os::get_current_directory(char *buf, int buflen) {
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1894,18 +1894,19 @@
return os::stat(filename, &statbuf) == 0;
}
-void os::dll_build_name(char* buffer, size_t buflen,
+bool os::dll_build_name(char* buffer, size_t buflen,
const char* pname, const char* fname) {
+ bool retval = false;
const size_t pnamelen = pname ? strlen(pname) : 0;
- // Quietly truncate on buffer overflow. Should be an error.
+ // Return error on buffer overflow.
if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
- *buffer = '\0';
- return;
+ return retval;
}
if (pnamelen == 0) {
snprintf(buffer, buflen, "lib%s.so", fname);
+ retval = true;
} else if (strchr(pname, *os::path_separator()) != NULL) {
int n;
char** pelements = split_path(pname, &n);
@@ -1916,6 +1917,7 @@
}
snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname);
if (file_exists(buffer)) {
+ retval = true;
break;
}
}
@@ -1930,7 +1932,9 @@
}
} else {
snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
- }
+ retval = true;
+ }
+ return retval;
}
const char* os::get_current_directory(char *buf, int buflen) {
--- a/hotspot/src/os/windows/vm/os_windows.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1132,21 +1132,23 @@
return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES;
}
-void os::dll_build_name(char *buffer, size_t buflen,
+bool os::dll_build_name(char *buffer, size_t buflen,
const char* pname, const char* fname) {
+ bool retval = false;
const size_t pnamelen = pname ? strlen(pname) : 0;
const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0;
- // Quietly truncates on buffer overflow. Should be an error.
+ // Return error on buffer overflow.
if (pnamelen + strlen(fname) + 10 > buflen) {
- *buffer = '\0';
- return;
+ return retval;
}
if (pnamelen == 0) {
jio_snprintf(buffer, buflen, "%s.dll", fname);
+ retval = true;
} else if (c == ':' || c == '\\') {
jio_snprintf(buffer, buflen, "%s%s.dll", pname, fname);
+ retval = true;
} else if (strchr(pname, *os::path_separator()) != NULL) {
int n;
char** pelements = split_path(pname, &n);
@@ -1164,6 +1166,7 @@
jio_snprintf(buffer, buflen, "%s\\%s.dll", path, fname);
}
if (file_exists(buffer)) {
+ retval = true;
break;
}
}
@@ -1178,7 +1181,9 @@
}
} else {
jio_snprintf(buffer, buflen, "%s\\%s.dll", pname, fname);
- }
+ retval = true;
+ }
+ return retval;
}
// Needs to be in os specific directory because windows requires another
--- a/hotspot/src/share/tools/hsdis/hsdis-demo.c Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/tools/hsdis/hsdis-demo.c Fri Nov 30 17:09:05 2012 -0800
@@ -85,9 +85,11 @@
#include "dlfcn.h"
-#define DECODE_INSTRUCTIONS_NAME "decode_instructions_virtual"
+#define DECODE_INSTRUCTIONS_VIRTUAL_NAME "decode_instructions_virtual"
+#define DECODE_INSTRUCTIONS_NAME "decode_instructions"
#define HSDIS_NAME "hsdis"
static void* decode_instructions_pv = 0;
+static void* decode_instructions_sv = 0;
static const char* hsdis_path[] = {
HSDIS_NAME"-"LIBARCH LIB_EXT,
"./" HSDIS_NAME"-"LIBARCH LIB_EXT,
@@ -101,11 +103,12 @@
void* dllib = NULL;
const char* *next_in_path = hsdis_path;
while (1) {
- decode_instructions_pv = dlsym(dllib, DECODE_INSTRUCTIONS_NAME);
- if (decode_instructions_pv != NULL)
+ decode_instructions_pv = dlsym(dllib, DECODE_INSTRUCTIONS_VIRTUAL_NAME);
+ decode_instructions_sv = dlsym(dllib, DECODE_INSTRUCTIONS_NAME);
+ if (decode_instructions_pv != NULL || decode_instructions_sv != NULL)
return NULL;
if (dllib != NULL)
- return "plugin does not defined "DECODE_INSTRUCTIONS_NAME;
+ return "plugin does not defined "DECODE_INSTRUCTIONS_VIRTUAL_NAME" and "DECODE_INSTRUCTIONS_NAME;
for (dllib = NULL; dllib == NULL; ) {
const char* next_lib = (*next_in_path++);
if (next_lib == NULL)
@@ -213,20 +216,44 @@
printf("%s: %s\n", err, dlerror());
exit(1);
}
- printf("Decoding from %p to %p...\n", from, to);
- decode_instructions_ftype decode_instructions
- = (decode_instructions_ftype) decode_instructions_pv;
+ decode_func_vtype decode_instructions_v
+ = (decode_func_vtype) decode_instructions_pv;
+ decode_func_stype decode_instructions_s
+ = (decode_func_stype) decode_instructions_sv;
void* res;
- if (raw && xml) {
- res = (*decode_instructions)(from, to, (unsigned char*)from, to - from, simple_handle_event, stdout, NULL, stdout, options);
- } else if (raw) {
- res = (*decode_instructions)(from, to, (unsigned char*)from, to - from, simple_handle_event, stdout, NULL, stdout, options);
- } else {
- res = (*decode_instructions)(from, to, (unsigned char*)from, to - from,
- handle_event, (void*) event_cookie,
- fprintf_callback, stdout,
- options);
+ if (decode_instructions_pv != NULL) {
+ printf("\nDecoding from %p to %p...with %s\n", from, to, DECODE_INSTRUCTIONS_VIRTUAL_NAME);
+ if (raw) {
+ res = (*decode_instructions_v)(from, to,
+ (unsigned char*)from, to - from,
+ simple_handle_event, stdout,
+ NULL, stdout,
+ options, 0);
+ } else {
+ res = (*decode_instructions_v)(from, to,
+ (unsigned char*)from, to - from,
+ handle_event, (void*) event_cookie,
+ fprintf_callback, stdout,
+ options, 0);
+ }
+ if (res != (void*)to)
+ printf("*** Result was %p!\n", res);
}
- if (res != (void*)to)
- printf("*** Result was %p!\n", res);
+ void* sres;
+ if (decode_instructions_sv != NULL) {
+ printf("\nDecoding from %p to %p...with old decode_instructions\n", from, to, DECODE_INSTRUCTIONS_NAME);
+ if (raw) {
+ sres = (*decode_instructions_s)(from, to,
+ simple_handle_event, stdout,
+ NULL, stdout,
+ options);
+ } else {
+ sres = (*decode_instructions_s)(from, to,
+ handle_event, (void*) event_cookie,
+ fprintf_callback, stdout,
+ options);
+ }
+ if (sres != (void *)to)
+ printf("*** Result of decode_instructions %p!\n", sres);
+ }
}
--- a/hotspot/src/share/tools/hsdis/hsdis.c Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/tools/hsdis/hsdis.c Fri Nov 30 17:09:05 2012 -0800
@@ -99,7 +99,7 @@
unsigned char* buffer, uintptr_t length,
event_callback_t event_callback_arg, void* event_stream_arg,
printf_callback_t printf_callback_arg, void* printf_stream_arg,
- const char* options) {
+ const char* options, int newline) {
struct hsdis_app_data app_data;
memset(&app_data, 0, sizeof(app_data));
app_data.start_va = start_va;
@@ -110,7 +110,7 @@
app_data.event_stream = event_stream_arg;
app_data.printf_callback = printf_callback_arg;
app_data.printf_stream = printf_stream_arg;
- app_data.do_newline = false;
+ app_data.do_newline = newline == 0 ? false : true;
return decode(&app_data, options);
}
@@ -132,7 +132,7 @@
event_stream_arg,
printf_callback_arg,
printf_stream_arg,
- options);
+ options, false);
}
static void* decode(struct hsdis_app_data* app_data, const char* options) {
@@ -173,7 +173,7 @@
if (!app_data->losing) {
const char* insn_close = format_insn_close("/insn", &app_data->dinfo,
buf, sizeof(buf));
- (*event_callback)(event_stream, insn_close, (void*) p) != NULL;
+ (*event_callback)(event_stream, insn_close, (void*) p);
if (app_data->do_newline) {
/* follow each complete insn by a nice newline */
@@ -182,13 +182,14 @@
}
}
- (*event_callback)(event_stream, "/insns", (void*) p);
+ if (app_data->losing) (*event_callback)(event_stream, "/insns", (void*) p);
return (void*) p;
}
}
/* take the address of the function, for luck, and also test the typedef: */
-const decode_instructions_ftype decode_instructions_address = &decode_instructions_virtual;
+const decode_func_vtype decode_func_virtual_address = &decode_instructions_virtual;
+const decode_func_stype decode_func_address = &decode_instructions;
static const char* format_insn_close(const char* close,
disassemble_info* dinfo,
--- a/hotspot/src/share/tools/hsdis/hsdis.h Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/tools/hsdis/hsdis.h Fri Nov 30 17:09:05 2012 -0800
@@ -47,6 +47,9 @@
where tag is a simple identifier, signifying (as in XML) a element start,
element end, and standalone element. (To render as XML, add angle brackets.)
*/
+#ifndef SHARED_TOOLS_HSDIS_H
+#define SHARED_TOOLS_HSDIS_H
+
extern
#ifdef DLL_EXPORT
DLL_EXPORT
@@ -57,16 +60,37 @@
void* event_stream,
int (*printf_callback)(void*, const char*, ...),
void* printf_stream,
- const char* options);
+ const char* options,
+ int newline /* bool value for nice new line */);
+
+/* This is the compatability interface for older versions of hotspot */
+extern
+#ifdef DLL_ENTRY
+ DLL_ENTRY
+#endif
+void* decode_instructions(void* start_pv, void* end_pv,
+ void* (*event_callback)(void*, const char*, void*),
+ void* event_stream,
+ int (*printf_callback)(void*, const char*, ...),
+ void* printf_stream,
+ const char* options);
/* convenience typedefs */
typedef void* (*decode_instructions_event_callback_ftype) (void*, const char*, void*);
typedef int (*decode_instructions_printf_callback_ftype) (void*, const char*, ...);
-typedef void* (*decode_instructions_ftype) (uintptr_t start_va, uintptr_t end_va,
- unsigned char* buffer, uintptr_t length,
- decode_instructions_event_callback_ftype event_callback,
- void* event_stream,
- decode_instructions_printf_callback_ftype printf_callback,
- void* printf_stream,
- const char* options);
+typedef void* (*decode_func_vtype) (uintptr_t start_va, uintptr_t end_va,
+ unsigned char* buffer, uintptr_t length,
+ decode_instructions_event_callback_ftype event_callback,
+ void* event_stream,
+ decode_instructions_printf_callback_ftype printf_callback,
+ void* printf_stream,
+ const char* options,
+ int newline);
+typedef void* (*decode_func_stype) (void* start_pv, void* end_pv,
+ decode_instructions_event_callback_ftype event_callback,
+ void* event_stream,
+ decode_instructions_printf_callback_ftype printf_callback,
+ void* printf_stream,
+ const char* options);
+#endif /* SHARED_TOOLS_HSDIS_H */
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1836,7 +1836,7 @@
// check if we could do inlining
if (!PatchALot && Inline && klass->is_loaded() &&
(klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
- && target->will_link(klass, callee_holder, code)) {
+ && target->is_loaded()) {
// callee is known => check if we have static binding
assert(target->is_loaded(), "callee must be known");
if (code == Bytecodes::_invokestatic ||
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -374,7 +374,7 @@
JRT_ENTRY(void, Runtime1::throw_array_store_exception(JavaThread* thread, oopDesc* obj))
ResourceMark rm(thread);
- const char* klass_name = Klass::cast(obj->klass())->external_name();
+ const char* klass_name = obj->klass()->external_name();
SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArrayStoreException(), klass_name);
JRT_END
@@ -631,7 +631,7 @@
NOT_PRODUCT(_throw_class_cast_exception_count++;)
ResourceMark rm(thread);
char* message = SharedRuntime::generate_class_cast_message(
- thread, Klass::cast(object->klass())->external_name());
+ thread, object->klass()->external_name());
SharedRuntime::throw_and_post_jvmti_exception(
thread, vmSymbols::java_lang_ClassCastException(), message);
JRT_END
@@ -876,7 +876,7 @@
case Bytecodes::_anewarray:
{ Bytecode_anewarray anew(caller_method(), caller_method->bcp_from(bci));
Klass* ek = caller_method->constants()->klass_at(anew.index(), CHECK);
- k = Klass::cast(ek)->array_klass(CHECK);
+ k = ek->array_klass(CHECK);
}
break;
case Bytecodes::_ldc:
@@ -1236,7 +1236,7 @@
} else {
Klass* bound = ObjArrayKlass::cast(dst->klass())->element_klass();
Klass* stype = ObjArrayKlass::cast(src->klass())->element_klass();
- if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) {
+ if (stype == bound || stype->is_subtype_of(bound)) {
// Elements are guaranteed to be subtypes, so no check necessary
bs->write_ref_array_pre(dst_addr, length);
Copy::conjoint_oops_atomic(src_addr, dst_addr, length);
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -282,7 +282,7 @@
ciMethod* inline_target = NULL;
if (target->is_loaded() && klass->is_loaded()
&& (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
- && target->will_link(klass, callee_holder, code)) {
+ && target->is_loaded()) {
if (code == Bytecodes::_invokestatic
|| code == Bytecodes::_invokespecial
|| code == Bytecodes::_invokevirtual && target->is_final_method()) {
--- a/hotspot/src/share/vm/ci/ciClassList.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciClassList.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -106,6 +106,7 @@
friend class ciArray; \
friend class ciObjArray; \
friend class ciMetadata; \
+friend class ciReplay; \
friend class ciTypeArray; \
friend class ciType; \
friend class ciReturnAddress; \
--- a/hotspot/src/share/vm/ci/ciEnv.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -30,6 +30,7 @@
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciMethod.hpp"
#include "ci/ciNullObject.hpp"
+#include "ci/ciReplay.hpp"
#include "ci/ciUtilities.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
@@ -426,7 +427,7 @@
for (int i = cpool->length() - 1; i >= 1; i--) {
if (cpool->tag_at(i).is_klass()) {
Klass* kls = cpool->resolved_klass_at(i);
- if (Klass::cast(kls)->name() == sym) {
+ if (kls->name() == sym) {
found_klass = KlassHandle(THREAD, kls);
break;
}
@@ -768,10 +769,15 @@
Method* m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc);
if (m != NULL &&
(bc == Bytecodes::_invokestatic
- ? InstanceKlass::cast(m->method_holder())->is_not_initialized()
- : !InstanceKlass::cast(m->method_holder())->is_loaded())) {
+ ? m->method_holder()->is_not_initialized()
+ : !m->method_holder()->is_loaded())) {
m = NULL;
}
+#ifdef ASSERT
+ if (m != NULL && ReplayCompiles && !ciReplay::is_loaded(m)) {
+ m = NULL;
+ }
+#endif
if (m != NULL) {
// We found the method.
return get_method(m);
@@ -1056,7 +1062,7 @@
method_name,
entry_bci);
}
- InstanceKlass::cast(method->method_holder())->add_osr_nmethod(nm);
+ method->method_holder()->add_osr_nmethod(nm);
}
}
@@ -1144,3 +1150,43 @@
// If memory is low, we stop compiling methods.
record_method_not_compilable("out of memory");
}
+
+fileStream* ciEnv::_replay_data_stream = NULL;
+
+void ciEnv::dump_replay_data() {
+ VM_ENTRY_MARK;
+ MutexLocker ml(Compile_lock);
+ if (_replay_data_stream == NULL) {
+ _replay_data_stream = new (ResourceObj::C_HEAP, mtCompiler) fileStream(ReplayDataFile);
+ if (_replay_data_stream == NULL) {
+ fatal(err_msg("Can't open %s for replay data", ReplayDataFile));
+ }
+ }
+ dump_replay_data(_replay_data_stream);
+}
+
+
+void ciEnv::dump_replay_data(outputStream* out) {
+ ASSERT_IN_VM;
+
+#if INCLUDE_JVMTI
+ out->print_cr("JvmtiExport can_access_local_variables %d", _jvmti_can_access_local_variables);
+ out->print_cr("JvmtiExport can_hotswap_or_post_breakpoint %d", _jvmti_can_hotswap_or_post_breakpoint);
+ out->print_cr("JvmtiExport can_post_on_exceptions %d", _jvmti_can_post_on_exceptions);
+#endif // INCLUDE_JVMTI
+
+ GrowableArray<ciMetadata*>* objects = _factory->get_ci_metadata();
+ out->print_cr("# %d ciObject found", objects->length());
+ for (int i = 0; i < objects->length(); i++) {
+ objects->at(i)->dump_replay_data(out);
+ }
+ Method* method = task()->method();
+ int entry_bci = task()->osr_bci();
+ // Klass holder = method->method_holder();
+ out->print_cr("compile %s %s %s %d",
+ method->klass_name()->as_quoted_ascii(),
+ method->name()->as_quoted_ascii(),
+ method->signature()->as_quoted_ascii(),
+ entry_bci);
+ out->flush();
+}
--- a/hotspot/src/share/vm/ci/ciEnv.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciEnv.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -46,6 +46,8 @@
friend class CompileBroker;
friend class Dependencies; // for get_object, during logging
+ static fileStream* _replay_data_stream;
+
private:
Arena* _arena; // Alias for _ciEnv_arena except in init_shared_objects()
Arena _ciEnv_arena;
@@ -448,6 +450,13 @@
// RedefineClasses support
void metadata_do(void f(Metadata*)) { _factory->metadata_do(f); }
+
+ // Dump the compilation replay data for this ciEnv to
+ // ReplayDataFile, creating the file if needed.
+ void dump_replay_data();
+
+ // Dump the compilation replay data for the ciEnv to the stream.
+ void dump_replay_data(outputStream* out);
};
#endif // SHARE_VM_CI_CIENV_HPP
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -561,3 +561,114 @@
}
return impl;
}
+
+// Utility class for printing of the contents of the static fields for
+// use by compilation replay. It only prints out the information that
+// could be consumed by the compiler, so for primitive types it prints
+// out the actual value. For Strings it's the actual string value.
+// For array types it it's first level array size since that's the
+// only value which statically unchangeable. For all other reference
+// types it simply prints out the dynamic type.
+
+class StaticFinalFieldPrinter : public FieldClosure {
+ outputStream* _out;
+ const char* _holder;
+ public:
+ StaticFinalFieldPrinter(outputStream* out, const char* holder) :
+ _out(out),
+ _holder(holder) {
+ }
+ void do_field(fieldDescriptor* fd) {
+ if (fd->is_final() && !fd->has_initial_value()) {
+ oop mirror = fd->field_holder()->java_mirror();
+ _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii());
+ switch (fd->field_type()) {
+ case T_BYTE: _out->print_cr("%d", mirror->byte_field(fd->offset())); break;
+ case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset())); break;
+ case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break;
+ case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break;
+ case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break;
+ case T_LONG: _out->print_cr(INT64_FORMAT, mirror->long_field(fd->offset())); break;
+ case T_FLOAT: {
+ float f = mirror->float_field(fd->offset());
+ _out->print_cr("%d", *(int*)&f);
+ break;
+ }
+ case T_DOUBLE: {
+ double d = mirror->double_field(fd->offset());
+ _out->print_cr(INT64_FORMAT, *(jlong*)&d);
+ break;
+ }
+ case T_ARRAY: {
+ oop value = mirror->obj_field_acquire(fd->offset());
+ if (value == NULL) {
+ _out->print_cr("null");
+ } else {
+ typeArrayOop ta = (typeArrayOop)value;
+ _out->print("%d", ta->length());
+ if (value->is_objArray()) {
+ objArrayOop oa = (objArrayOop)value;
+ const char* klass_name = value->klass()->name()->as_quoted_ascii();
+ _out->print(" %s", klass_name);
+ }
+ _out->cr();
+ }
+ break;
+ }
+ case T_OBJECT: {
+ oop value = mirror->obj_field_acquire(fd->offset());
+ if (value == NULL) {
+ _out->print_cr("null");
+ } else if (value->is_instance()) {
+ if (value->is_a(SystemDictionary::String_klass())) {
+ _out->print("\"");
+ _out->print_raw(java_lang_String::as_quoted_ascii(value));
+ _out->print_cr("\"");
+ } else {
+ const char* klass_name = value->klass()->name()->as_quoted_ascii();
+ _out->print_cr(klass_name);
+ }
+ } else {
+ ShouldNotReachHere();
+ }
+ break;
+ }
+ default:
+ ShouldNotReachHere();
+ }
+ }
+ }
+};
+
+
+void ciInstanceKlass::dump_replay_data(outputStream* out) {
+ ASSERT_IN_VM;
+ InstanceKlass* ik = get_instanceKlass();
+ ConstantPool* cp = ik->constants();
+
+ // Try to record related loaded classes
+ Klass* sub = ik->subklass();
+ while (sub != NULL) {
+ if (sub->oop_is_instance()) {
+ out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii());
+ }
+ sub = sub->next_sibling();
+ }
+
+ // Dump out the state of the constant pool tags. During replay the
+ // tags will be validated for things which shouldn't change and
+ // classes will be resolved if the tags indicate that they were
+ // resolved at compile time.
+ out->print("ciInstanceKlass %s %d %d %d", ik->name()->as_quoted_ascii(),
+ is_linked(), is_initialized(), cp->length());
+ for (int index = 1; index < cp->length(); index++) {
+ out->print(" %d", cp->tags()->at(index));
+ }
+ out->cr();
+ if (is_initialized()) {
+ // Dump out the static final fields in case the compilation relies
+ // on their value for correct replay.
+ StaticFinalFieldPrinter sffp(out, ik->name()->as_quoted_ascii());
+ ik->do_local_static_fields(&sffp);
+ }
+}
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -230,6 +230,9 @@
// What kind of ciObject is this?
bool is_instance_klass() const { return true; }
bool is_java_klass() const { return true; }
+
+ // Dump the current state of this klass for compilation replay.
+ virtual void dump_replay_data(outputStream* out);
};
#endif // SHARE_VM_CI_CIINSTANCEKLASS_HPP
--- a/hotspot/src/share/vm/ci/ciMetadata.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciMetadata.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -61,6 +61,7 @@
virtual bool is_array_klass() const { return false; }
virtual bool is_obj_array_klass() const { return false; }
virtual bool is_type_array_klass() const { return false; }
+ virtual void dump_replay_data(outputStream* st) { /* do nothing */ }
ciMethod* as_method() {
assert(is_method(), "bad cast");
--- a/hotspot/src/share/vm/ci/ciMethod.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -31,6 +31,7 @@
#include "ci/ciMethodData.hpp"
#include "ci/ciStreams.hpp"
#include "ci/ciSymbol.hpp"
+#include "ci/ciReplay.hpp"
#include "ci/ciUtilities.hpp"
#include "classfile/systemDictionary.hpp"
#include "compiler/abstractCompiler.hpp"
@@ -105,7 +106,7 @@
CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
}
- if (InstanceKlass::cast(h_m()->method_holder())->is_linked()) {
+ if (h_m()->method_holder()->is_linked()) {
_can_be_statically_bound = h_m()->can_be_statically_bound();
} else {
// Have to use a conservative value in this case.
@@ -139,6 +140,12 @@
}
if (_interpreter_invocation_count == 0)
_interpreter_invocation_count = 1;
+ _instructions_size = -1;
+#ifdef ASSERT
+ if (ReplayCompiles) {
+ ciReplay::initialize(this);
+ }
+#endif
}
@@ -161,7 +168,8 @@
#if defined(COMPILER2) || defined(SHARK)
,
_flow( NULL),
- _bcea( NULL)
+ _bcea( NULL),
+ _instructions_size(-1)
#endif // COMPILER2 || SHARK
{
// Usually holder and accessor are the same type but in some cases
@@ -188,7 +196,7 @@
// Revert any breakpoint bytecodes in ci's copy
if (me->number_of_breakpoints() > 0) {
- BreakpointInfo* bp = InstanceKlass::cast(me->method_holder())->breakpoints();
+ BreakpointInfo* bp = me->method_holder()->breakpoints();
for (; bp != NULL; bp = bp->next()) {
if (bp->match(me)) {
code_at_put(bp->bci(), bp->orig_bytecode());
@@ -868,25 +876,6 @@
}
// ------------------------------------------------------------------
-// ciMethod::will_link
-//
-// Will this method link in a specific calling context?
-bool ciMethod::will_link(ciKlass* accessing_klass,
- ciKlass* declared_method_holder,
- Bytecodes::Code bc) {
- if (!is_loaded()) {
- // Method lookup failed.
- return false;
- }
-
- // The link checks have been front-loaded into the get_method
- // call. This method (ciMethod::will_link()) will be removed
- // in the future.
-
- return true;
-}
-
-// ------------------------------------------------------------------
// ciMethod::should_exclude
//
// Should this method be excluded from compilation?
@@ -1000,8 +989,7 @@
// ------------------------------------------------------------------
// ciMethod::has_compiled_code
bool ciMethod::has_compiled_code() {
- VM_ENTRY_MARK;
- return get_Method()->code() != NULL;
+ return instructions_size() > 0;
}
int ciMethod::comp_level() {
@@ -1039,14 +1027,18 @@
// junk like exception handler, stubs, and constant table, which are
// not highly relevant to an inlined method. So we use the more
// specific accessor nmethod::insts_size.
-int ciMethod::instructions_size(int comp_level) {
- GUARDED_VM_ENTRY(
- nmethod* code = get_Method()->code();
- if (code != NULL && (comp_level == CompLevel_any || comp_level == code->comp_level())) {
- return code->insts_end() - code->verified_entry_point();
- }
- return 0;
- )
+int ciMethod::instructions_size() {
+ if (_instructions_size == -1) {
+ GUARDED_VM_ENTRY(
+ nmethod* code = get_Method()->code();
+ if (code != NULL && (code->comp_level() == CompLevel_full_optimization)) {
+ _instructions_size = code->insts_end() - code->verified_entry_point();
+ } else {
+ _instructions_size = 0;
+ }
+ );
+ }
+ return _instructions_size;
}
// ------------------------------------------------------------------
@@ -1166,6 +1158,20 @@
#undef FETCH_FLAG_FROM_VM
+void ciMethod::dump_replay_data(outputStream* st) {
+ ASSERT_IN_VM;
+ Method* method = get_Method();
+ Klass* holder = method->method_holder();
+ st->print_cr("ciMethod %s %s %s %d %d %d %d %d",
+ holder->name()->as_quoted_ascii(),
+ method->name()->as_quoted_ascii(),
+ method->signature()->as_quoted_ascii(),
+ method->invocation_counter()->raw_counter(),
+ method->backedge_counter()->raw_counter(),
+ interpreter_invocation_count(),
+ interpreter_throwout_count(),
+ _instructions_size);
+}
// ------------------------------------------------------------------
// ciMethod::print_codes
--- a/hotspot/src/share/vm/ci/ciMethod.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -51,6 +51,7 @@
friend class ciExceptionHandlerStream;
friend class ciBytecodeStream;
friend class ciMethodHandle;
+ friend class ciReplay;
private:
// General method information.
@@ -69,6 +70,7 @@
int _handler_count;
int _interpreter_invocation_count;
int _interpreter_throwout_count;
+ int _instructions_size;
bool _uses_monitors;
bool _balanced_monitors;
@@ -239,9 +241,6 @@
int resolve_vtable_index(ciKlass* caller, ciKlass* receiver);
// Compilation directives
- bool will_link(ciKlass* accessing_klass,
- ciKlass* declared_method_holder,
- Bytecodes::Code bc);
bool should_exclude();
bool should_inline();
bool should_not_inline();
@@ -252,7 +251,6 @@
bool can_be_osr_compiled(int entry_bci);
void set_not_compilable();
bool has_compiled_code();
- int instructions_size(int comp_level = CompLevel_any);
void log_nmethod_identity(xmlStream* log);
bool is_not_reached(int bci);
bool was_executed_more_than(int times);
@@ -260,6 +258,7 @@
bool is_klass_loaded(int refinfo_index, bool must_be_resolved) const;
bool check_call(int refinfo_index, bool is_static) const;
bool ensure_method_data(); // make sure it exists in the VM also
+ int instructions_size();
int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC
// JSR 292 support
@@ -291,6 +290,7 @@
bool is_accessor () const;
bool is_initializer () const;
bool can_be_statically_bound() const { return _can_be_statically_bound; }
+ void dump_replay_data(outputStream* st);
// Print the bytecodes of this method.
void print_codes_on(outputStream* st);
--- a/hotspot/src/share/vm/ci/ciMethodData.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciMethodData.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "ci/ciMetadata.hpp"
#include "ci/ciMethodData.hpp"
+#include "ci/ciReplay.hpp"
#include "ci/ciUtilities.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
@@ -115,6 +116,11 @@
_arg_local = mdo->arg_local();
_arg_stack = mdo->arg_stack();
_arg_returned = mdo->arg_returned();
+#ifndef PRODUCT
+ if (ReplayCompiles) {
+ ciReplay::initialize(this);
+ }
+#endif
}
void ciReceiverTypeData::translate_receiver_data_from(ProfileData* data) {
@@ -366,6 +372,79 @@
ciMetadata::print_impl(st);
}
+void ciMethodData::dump_replay_data(outputStream* out) {
+ ASSERT_IN_VM;
+ MethodData* mdo = get_MethodData();
+ Method* method = mdo->method();
+ Klass* holder = method->method_holder();
+ out->print("ciMethodData %s %s %s %d %d",
+ holder->name()->as_quoted_ascii(),
+ method->name()->as_quoted_ascii(),
+ method->signature()->as_quoted_ascii(),
+ _state,
+ current_mileage());
+
+ // dump the contents of the MDO header as raw data
+ unsigned char* orig = (unsigned char*)&_orig;
+ int length = sizeof(_orig);
+ out->print(" orig %d", length);
+ for (int i = 0; i < length; i++) {
+ out->print(" %d", orig[i]);
+ }
+
+ // dump the MDO data as raw data
+ int elements = data_size() / sizeof(intptr_t);
+ out->print(" data %d", elements);
+ for (int i = 0; i < elements; i++) {
+ // We could use INTPTR_FORMAT here but that's a zero justified
+ // which makes comparing it with the SA version of this output
+ // harder.
+#ifdef _LP64
+ out->print(" 0x%" FORMAT64_MODIFIER "x", data()[i]);
+#else
+ out->print(" 0x%x", data()[i]);
+#endif
+ }
+
+ // The MDO contained oop references as ciObjects, so scan for those
+ // and emit pairs of offset and klass name so that they can be
+ // reconstructed at runtime. The first round counts the number of
+ // oop references and the second actually emits them.
+ int count = 0;
+ for (int round = 0; round < 2; round++) {
+ if (round == 1) out->print(" oops %d", count);
+ ProfileData* pdata = first_data();
+ for ( ; is_valid(pdata); pdata = next_data(pdata)) {
+ if (pdata->is_ReceiverTypeData()) {
+ ciReceiverTypeData* vdata = (ciReceiverTypeData*)pdata;
+ for (uint i = 0; i < vdata->row_limit(); i++) {
+ ciKlass* k = vdata->receiver(i);
+ if (k != NULL) {
+ if (round == 0) {
+ count++;
+ } else {
+ out->print(" %d %s", dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t), k->name()->as_quoted_ascii());
+ }
+ }
+ }
+ } else if (pdata->is_VirtualCallData()) {
+ ciVirtualCallData* vdata = (ciVirtualCallData*)pdata;
+ for (uint i = 0; i < vdata->row_limit(); i++) {
+ ciKlass* k = vdata->receiver(i);
+ if (k != NULL) {
+ if (round == 0) {
+ count++;
+ } else {
+ out->print(" %d %s", dp_to_di(vdata->dp() + in_bytes(vdata->receiver_offset(i))) / sizeof(intptr_t), k->name()->as_quoted_ascii());
+ }
+ }
+ }
+ }
+ }
+ }
+ out->cr();
+}
+
#ifndef PRODUCT
void ciMethodData::print() {
print_data_on(tty);
--- a/hotspot/src/share/vm/ci/ciMethodData.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciMethodData.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -144,6 +144,7 @@
class ciMethodData : public ciMetadata {
CI_PACKAGE_ACCESS
+ friend class ciReplay;
private:
// Size in bytes
@@ -320,6 +321,7 @@
void print();
void print_data_on(outputStream* st);
#endif
+ void dump_replay_data(outputStream* out);
};
#endif // SHARE_VM_CI_CIMETHODDATA_HPP
--- a/hotspot/src/share/vm/ci/ciObject.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciObject.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -131,6 +131,7 @@
// Is this a type or value which has no associated class?
// It is true of primitive types and null objects.
virtual bool is_classless() const { return false; }
+ virtual void dump_replay_data(outputStream* st) { /* do nothing */ }
// Note: some ciObjects refer to oops which have yet to be created.
// We refer to these as "unloaded". Specifically, there are
--- a/hotspot/src/share/vm/ci/ciObjectFactory.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciObjectFactory.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -137,6 +137,7 @@
ciReturnAddress* get_return_address(int bci);
+ GrowableArray<ciMetadata*>* get_ci_metadata() const { return _ci_metadata; }
// RedefineClasses support
void metadata_do(void f(Metadata*));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,942 @@
+/* Copyright (c) 2012, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "ci/ciMethodData.hpp"
+#include "ci/ciReplay.hpp"
+#include "ci/ciUtilities.hpp"
+#include "compiler/compileBroker.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/oopFactory.hpp"
+#include "memory/resourceArea.hpp"
+#include "utilities/copy.hpp"
+
+#ifdef ASSERT
+
+// ciReplay
+
+typedef struct _ciMethodDataRecord {
+ const char* klass;
+ const char* method;
+ const char* signature;
+ int state;
+ int current_mileage;
+ intptr_t* data;
+ int data_length;
+ char* orig_data;
+ int orig_data_length;
+ int oops_length;
+ jobject* oops_handles;
+ int* oops_offsets;
+} ciMethodDataRecord;
+
+typedef struct _ciMethodRecord {
+ const char* klass;
+ const char* method;
+ const char* signature;
+ int instructions_size;
+ int interpreter_invocation_count;
+ int interpreter_throwout_count;
+ int invocation_counter;
+ int backedge_counter;
+} ciMethodRecord;
+
+class CompileReplay;
+static CompileReplay* replay_state;
+
+class CompileReplay : public StackObj {
+ private:
+ FILE* stream;
+ Thread* thread;
+ Handle protection_domain;
+ Handle loader;
+
+ GrowableArray<ciMethodRecord*> ci_method_records;
+ GrowableArray<ciMethodDataRecord*> ci_method_data_records;
+
+ const char* _error_message;
+
+ char* bufptr;
+ char* buffer;
+ int buffer_length;
+ int buffer_end;
+ int line_no;
+
+ public:
+ CompileReplay(const char* filename, TRAPS) {
+ thread = THREAD;
+ loader = Handle(thread, SystemDictionary::java_system_loader());
+ stream = fopen(filename, "rt");
+ if (stream == NULL) {
+ fprintf(stderr, "Can't open replay file %s\n", filename);
+ }
+ buffer_length = 32;
+ buffer = NEW_RESOURCE_ARRAY(char, buffer_length);
+ _error_message = NULL;
+
+ test();
+ }
+
+ ~CompileReplay() {
+ if (stream != NULL) fclose(stream);
+ }
+
+ void test() {
+ strcpy(buffer, "1 2 foo 4 bar 0x9 \"this is it\"");
+ bufptr = buffer;
+ assert(parse_int("test") == 1, "what");
+ assert(parse_int("test") == 2, "what");
+ assert(strcmp(parse_string(), "foo") == 0, "what");
+ assert(parse_int("test") == 4, "what");
+ assert(strcmp(parse_string(), "bar") == 0, "what");
+ assert(parse_intptr_t("test") == 9, "what");
+ assert(strcmp(parse_quoted_string(), "this is it") == 0, "what");
+ }
+
+ bool had_error() {
+ return _error_message != NULL || thread->has_pending_exception();
+ }
+
+ bool can_replay() {
+ return !(stream == NULL || had_error());
+ }
+
+ void report_error(const char* msg) {
+ _error_message = msg;
+ // Restore the buffer contents for error reporting
+ for (int i = 0; i < buffer_end; i++) {
+ if (buffer[i] == '\0') buffer[i] = ' ';
+ }
+ }
+
+ int parse_int(const char* label) {
+ if (had_error()) {
+ return 0;
+ }
+
+ int v = 0;
+ int read;
+ if (sscanf(bufptr, "%i%n", &v, &read) != 1) {
+ report_error(label);
+ } else {
+ bufptr += read;
+ }
+ return v;
+ }
+
+ intptr_t parse_intptr_t(const char* label) {
+ if (had_error()) {
+ return 0;
+ }
+
+ intptr_t v = 0;
+ int read;
+ if (sscanf(bufptr, INTPTR_FORMAT "%n", &v, &read) != 1) {
+ report_error(label);
+ } else {
+ bufptr += read;
+ }
+ return v;
+ }
+
+ void skip_ws() {
+ // Skip any leading whitespace
+ while (*bufptr == ' ' || *bufptr == '\t') {
+ bufptr++;
+ }
+ }
+
+
+ char* scan_and_terminate(char delim) {
+ char* str = bufptr;
+ while (*bufptr != delim && *bufptr != '\0') {
+ bufptr++;
+ }
+ if (*bufptr != '\0') {
+ *bufptr++ = '\0';
+ }
+ if (bufptr == str) {
+ // nothing here
+ return NULL;
+ }
+ return str;
+ }
+
+ char* parse_string() {
+ if (had_error()) return NULL;
+
+ skip_ws();
+ return scan_and_terminate(' ');
+ }
+
+ char* parse_quoted_string() {
+ if (had_error()) return NULL;
+
+ skip_ws();
+
+ if (*bufptr == '"') {
+ bufptr++;
+ return scan_and_terminate('"');
+ } else {
+ return scan_and_terminate(' ');
+ }
+ }
+
+ const char* parse_escaped_string() {
+ char* result = parse_quoted_string();
+ if (result != NULL) {
+ unescape_string(result);
+ }
+ return result;
+ }
+
+ // Look for the tag 'tag' followed by an
+ bool parse_tag_and_count(const char* tag, int& length) {
+ const char* t = parse_string();
+ if (t == NULL) {
+ return false;
+ }
+
+ if (strcmp(tag, t) != 0) {
+ report_error(tag);
+ return false;
+ }
+ length = parse_int("parse_tag_and_count");
+ return !had_error();
+ }
+
+ // Parse a sequence of raw data encoded as bytes and return the
+ // resulting data.
+ char* parse_data(const char* tag, int& length) {
+ if (!parse_tag_and_count(tag, length)) {
+ return NULL;
+ }
+
+ char * result = NEW_RESOURCE_ARRAY(char, length);
+ for (int i = 0; i < length; i++) {
+ int val = parse_int("data");
+ result[i] = val;
+ }
+ return result;
+ }
+
+ // Parse a standard chunk of data emitted as:
+ // 'tag' <length> # # ...
+ // Where each # is an intptr_t item
+ intptr_t* parse_intptr_data(const char* tag, int& length) {
+ if (!parse_tag_and_count(tag, length)) {
+ return NULL;
+ }
+
+ intptr_t* result = NEW_RESOURCE_ARRAY(intptr_t, length);
+ for (int i = 0; i < length; i++) {
+ skip_ws();
+ intptr_t val = parse_intptr_t("data");
+ result[i] = val;
+ }
+ return result;
+ }
+
+ // Parse a possibly quoted version of a symbol into a symbolOop
+ Symbol* parse_symbol(TRAPS) {
+ const char* str = parse_escaped_string();
+ if (str != NULL) {
+ Symbol* sym = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL);
+ return sym;
+ }
+ return NULL;
+ }
+
+ // Parse a valid klass name and look it up
+ Klass* parse_klass(TRAPS) {
+ const char* str = parse_escaped_string();
+ Symbol* klass_name = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL);
+ if (klass_name != NULL) {
+ Klass* k = SystemDictionary::resolve_or_fail(klass_name, loader, protection_domain, true, THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ oop throwable = PENDING_EXCEPTION;
+ java_lang_Throwable::print(throwable, tty);
+ tty->cr();
+ report_error(str);
+ return NULL;
+ }
+ return k;
+ }
+ return NULL;
+ }
+
+ // Lookup a klass
+ Klass* resolve_klass(const char* klass, TRAPS) {
+ Symbol* klass_name = SymbolTable::lookup(klass, (int)strlen(klass), CHECK_NULL);
+ return SystemDictionary::resolve_or_fail(klass_name, loader, protection_domain, true, CHECK_NULL);
+ }
+
+ // Parse the standard tuple of <klass> <name> <signature>
+ Method* parse_method(TRAPS) {
+ InstanceKlass* k = (InstanceKlass*)parse_klass(CHECK_NULL);
+ Symbol* method_name = parse_symbol(CHECK_NULL);
+ Symbol* method_signature = parse_symbol(CHECK_NULL);
+ Method* m = k->find_method(method_name, method_signature);
+ if (m == NULL) {
+ report_error("can't find method");
+ }
+ return m;
+ }
+
+ // Process each line of the replay file executing each command until
+ // the file ends.
+ void process(TRAPS) {
+ line_no = 1;
+ int pos = 0;
+ int c = getc(stream);
+ while(c != EOF) {
+ if (pos + 1 >= buffer_length) {
+ int newl = buffer_length * 2;
+ char* newb = NEW_RESOURCE_ARRAY(char, newl);
+ memcpy(newb, buffer, pos);
+ buffer = newb;
+ buffer_length = newl;
+ }
+ if (c == '\n') {
+ // null terminate it, reset the pointer and process the line
+ buffer[pos] = '\0';
+ buffer_end = pos++;
+ bufptr = buffer;
+ process_command(CHECK);
+ if (had_error()) {
+ tty->print_cr("Error while parsing line %d: %s\n", line_no, _error_message);
+ tty->print_cr("%s", buffer);
+ assert(false, "error");
+ return;
+ }
+ pos = 0;
+ buffer_end = 0;
+ line_no++;
+ } else if (c == '\r') {
+ // skip LF
+ } else {
+ buffer[pos++] = c;
+ }
+ c = getc(stream);
+ }
+ }
+
+ void process_command(TRAPS) {
+ char* cmd = parse_string();
+ if (cmd == NULL) {
+ return;
+ }
+ if (strcmp("#", cmd) == 0) {
+ // ignore
+ } else if (strcmp("compile", cmd) == 0) {
+ process_compile(CHECK);
+ } else if (strcmp("ciMethod", cmd) == 0) {
+ process_ciMethod(CHECK);
+ } else if (strcmp("ciMethodData", cmd) == 0) {
+ process_ciMethodData(CHECK);
+ } else if (strcmp("staticfield", cmd) == 0) {
+ process_staticfield(CHECK);
+ } else if (strcmp("ciInstanceKlass", cmd) == 0) {
+ process_ciInstanceKlass(CHECK);
+ } else if (strcmp("instanceKlass", cmd) == 0) {
+ process_instanceKlass(CHECK);
+#if INCLUDE_JVMTI
+ } else if (strcmp("JvmtiExport", cmd) == 0) {
+ process_JvmtiExport(CHECK);
+#endif // INCLUDE_JVMTI
+ } else {
+ report_error("unknown command");
+ }
+ }
+
+ // compile <klass> <name> <signature> <entry_bci>
+ void process_compile(TRAPS) {
+ // methodHandle method;
+ Method* method = parse_method(CHECK);
+ int entry_bci = parse_int("entry_bci");
+ Klass* k = method->method_holder();
+ ((InstanceKlass*)k)->initialize(THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ oop throwable = PENDING_EXCEPTION;
+ java_lang_Throwable::print(throwable, tty);
+ tty->cr();
+ if (ReplayIgnoreInitErrors) {
+ CLEAR_PENDING_EXCEPTION;
+ ((InstanceKlass*)k)->set_init_state(InstanceKlass::fully_initialized);
+ } else {
+ return;
+ }
+ }
+ // Make sure the existence of a prior compile doesn't stop this one
+ nmethod* nm = (entry_bci != InvocationEntryBci) ? method->lookup_osr_nmethod_for(entry_bci, CompLevel_full_optimization, true) : method->code();
+ if (nm != NULL) {
+ nm->make_not_entrant();
+ }
+ replay_state = this;
+ CompileBroker::compile_method(method, entry_bci, CompLevel_full_optimization,
+ methodHandle(), 0, "replay", THREAD);
+ replay_state = NULL;
+ reset();
+ }
+
+ // ciMethod <klass> <name> <signature> <invocation_counter> <backedge_counter> <interpreter_invocation_count> <interpreter_throwout_count> <instructions_size>
+ //
+ //
+ void process_ciMethod(TRAPS) {
+ Method* method = parse_method(CHECK);
+ ciMethodRecord* rec = new_ciMethod(method);
+ rec->invocation_counter = parse_int("invocation_counter");
+ rec->backedge_counter = parse_int("backedge_counter");
+ rec->interpreter_invocation_count = parse_int("interpreter_invocation_count");
+ rec->interpreter_throwout_count = parse_int("interpreter_throwout_count");
+ rec->instructions_size = parse_int("instructions_size");
+ }
+
+ // ciMethodData <klass> <name> <signature> <state> <current mileage> orig <length> # # ... data <length> # # ... oops <length>
+ void process_ciMethodData(TRAPS) {
+ Method* method = parse_method(CHECK);
+ /* jsut copied from Method, to build interpret data*/
+ if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
+ return;
+ }
+ // methodOopDesc::build_interpreter_method_data(method, CHECK);
+ {
+ // Grab a lock here to prevent multiple
+ // MethodData*s from being created.
+ MutexLocker ml(MethodData_lock, THREAD);
+ if (method->method_data() == NULL) {
+ ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
+ MethodData* method_data = MethodData::allocate(loader_data, method, CHECK);
+ method->set_method_data(method_data);
+ }
+ }
+
+ // collect and record all the needed information for later
+ ciMethodDataRecord* rec = new_ciMethodData(method);
+ rec->state = parse_int("state");
+ rec->current_mileage = parse_int("current_mileage");
+
+ rec->orig_data = parse_data("orig", rec->orig_data_length);
+ if (rec->orig_data == NULL) {
+ return;
+ }
+ rec->data = parse_intptr_data("data", rec->data_length);
+ if (rec->data == NULL) {
+ return;
+ }
+ if (!parse_tag_and_count("oops", rec->oops_length)) {
+ return;
+ }
+ rec->oops_handles = NEW_RESOURCE_ARRAY(jobject, rec->oops_length);
+ rec->oops_offsets = NEW_RESOURCE_ARRAY(int, rec->oops_length);
+ for (int i = 0; i < rec->oops_length; i++) {
+ int offset = parse_int("offset");
+ if (had_error()) {
+ return;
+ }
+ Klass* k = parse_klass(CHECK);
+ rec->oops_offsets[i] = offset;
+ rec->oops_handles[i] = (jobject)(new KlassHandle(THREAD, k));
+ }
+ }
+
+ // instanceKlass <name>
+ //
+ // Loads and initializes the klass 'name'. This can be used to
+ // create particular class loading environments
+ void process_instanceKlass(TRAPS) {
+ // just load the referenced class
+ Klass* k = parse_klass(CHECK);
+ }
+
+ // ciInstanceKlass <name> <is_linked> <is_initialized> <length> tag # # # ...
+ //
+ // Load the klass 'name' and link or initialize it. Verify that the
+ // constant pool is the same length as 'length' and make sure the
+ // constant pool tags are in the same state.
+ void process_ciInstanceKlass(TRAPS) {
+ InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
+ int is_linked = parse_int("is_linked");
+ int is_initialized = parse_int("is_initialized");
+ int length = parse_int("length");
+ if (is_initialized) {
+ k->initialize(THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ oop throwable = PENDING_EXCEPTION;
+ java_lang_Throwable::print(throwable, tty);
+ tty->cr();
+ if (ReplayIgnoreInitErrors) {
+ CLEAR_PENDING_EXCEPTION;
+ k->set_init_state(InstanceKlass::fully_initialized);
+ } else {
+ return;
+ }
+ }
+ } else if (is_linked) {
+ k->link_class(CHECK);
+ }
+ ConstantPool* cp = k->constants();
+ if (length != cp->length()) {
+ report_error("constant pool length mismatch: wrong class files?");
+ return;
+ }
+
+ int parsed_two_word = 0;
+ for (int i = 1; i < length; i++) {
+ int tag = parse_int("tag");
+ if (had_error()) {
+ return;
+ }
+ switch (cp->tag_at(i).value()) {
+ case JVM_CONSTANT_UnresolvedClass: {
+ if (tag == JVM_CONSTANT_Class) {
+ tty->print_cr("Resolving klass %s at %d", cp->unresolved_klass_at(i)->as_utf8(), i);
+ Klass* k = cp->klass_at(i, CHECK);
+ }
+ break;
+ }
+ case JVM_CONSTANT_Long:
+ case JVM_CONSTANT_Double:
+ parsed_two_word = i + 1;
+
+ case JVM_CONSTANT_ClassIndex:
+ case JVM_CONSTANT_StringIndex:
+ case JVM_CONSTANT_String:
+ case JVM_CONSTANT_UnresolvedClassInError:
+ case JVM_CONSTANT_Fieldref:
+ case JVM_CONSTANT_Methodref:
+ case JVM_CONSTANT_InterfaceMethodref:
+ case JVM_CONSTANT_NameAndType:
+ case JVM_CONSTANT_Utf8:
+ case JVM_CONSTANT_Integer:
+ case JVM_CONSTANT_Float:
+ if (tag != cp->tag_at(i).value()) {
+ report_error("tag mismatch: wrong class files?");
+ return;
+ }
+ break;
+
+ case JVM_CONSTANT_Class:
+ if (tag == JVM_CONSTANT_Class) {
+ } else if (tag == JVM_CONSTANT_UnresolvedClass) {
+ tty->print_cr("Warning: entry was unresolved in the replay data");
+ } else {
+ report_error("Unexpected tag");
+ return;
+ }
+ break;
+
+ case 0:
+ if (parsed_two_word == i) continue;
+
+ default:
+ ShouldNotReachHere();
+ break;
+ }
+
+ }
+ }
+
+ // Initialize a class and fill in the value for a static field.
+ // This is useful when the compile was dependent on the value of
+ // static fields but it's impossible to properly rerun the static
+ // initiailizer.
+ void process_staticfield(TRAPS) {
+ InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
+
+ if (ReplaySuppressInitializers == 0 ||
+ ReplaySuppressInitializers == 2 && k->class_loader() == NULL) {
+ return;
+ }
+
+ assert(k->is_initialized(), "must be");
+
+ const char* field_name = parse_escaped_string();;
+ const char* field_signature = parse_string();
+ fieldDescriptor fd;
+ Symbol* name = SymbolTable::lookup(field_name, (int)strlen(field_name), CHECK);
+ Symbol* sig = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK);
+ if (!k->find_local_field(name, sig, &fd) ||
+ !fd.is_static() ||
+ fd.has_initial_value()) {
+ report_error(field_name);
+ return;
+ }
+
+ oop java_mirror = k->java_mirror();
+ if (field_signature[0] == '[') {
+ int length = parse_int("array length");
+ oop value = NULL;
+
+ if (field_signature[1] == '[') {
+ // multi dimensional array
+ ArrayKlass* kelem = (ArrayKlass *)parse_klass(CHECK);
+ int rank = 0;
+ while (field_signature[rank] == '[') {
+ rank++;
+ }
+ int* dims = NEW_RESOURCE_ARRAY(int, rank);
+ dims[0] = length;
+ for (int i = 1; i < rank; i++) {
+ dims[i] = 1; // These aren't relevant to the compiler
+ }
+ value = kelem->multi_allocate(rank, dims, CHECK);
+ } else {
+ if (strcmp(field_signature, "[B") == 0) {
+ value = oopFactory::new_byteArray(length, CHECK);
+ } else if (strcmp(field_signature, "[Z") == 0) {
+ value = oopFactory::new_boolArray(length, CHECK);
+ } else if (strcmp(field_signature, "[C") == 0) {
+ value = oopFactory::new_charArray(length, CHECK);
+ } else if (strcmp(field_signature, "[S") == 0) {
+ value = oopFactory::new_shortArray(length, CHECK);
+ } else if (strcmp(field_signature, "[F") == 0) {
+ value = oopFactory::new_singleArray(length, CHECK);
+ } else if (strcmp(field_signature, "[D") == 0) {
+ value = oopFactory::new_doubleArray(length, CHECK);
+ } else if (strcmp(field_signature, "[I") == 0) {
+ value = oopFactory::new_intArray(length, CHECK);
+ } else if (strcmp(field_signature, "[J") == 0) {
+ value = oopFactory::new_longArray(length, CHECK);
+ } else if (field_signature[0] == '[' && field_signature[1] == 'L') {
+ KlassHandle kelem = resolve_klass(field_signature + 1, CHECK);
+ value = oopFactory::new_objArray(kelem(), length, CHECK);
+ } else {
+ report_error("unhandled array staticfield");
+ }
+ }
+ java_mirror->obj_field_put(fd.offset(), value);
+ } else {
+ const char* string_value = parse_escaped_string();
+ if (strcmp(field_signature, "I") == 0) {
+ int value = atoi(string_value);
+ java_mirror->int_field_put(fd.offset(), value);
+ } else if (strcmp(field_signature, "B") == 0) {
+ int value = atoi(string_value);
+ java_mirror->byte_field_put(fd.offset(), value);
+ } else if (strcmp(field_signature, "C") == 0) {
+ int value = atoi(string_value);
+ java_mirror->char_field_put(fd.offset(), value);
+ } else if (strcmp(field_signature, "S") == 0) {
+ int value = atoi(string_value);
+ java_mirror->short_field_put(fd.offset(), value);
+ } else if (strcmp(field_signature, "Z") == 0) {
+ int value = atol(string_value);
+ java_mirror->bool_field_put(fd.offset(), value);
+ } else if (strcmp(field_signature, "J") == 0) {
+ jlong value;
+ if (sscanf(string_value, INT64_FORMAT, &value) != 1) {
+ fprintf(stderr, "Error parsing long: %s\n", string_value);
+ return;
+ }
+ java_mirror->long_field_put(fd.offset(), value);
+ } else if (strcmp(field_signature, "F") == 0) {
+ float value = atof(string_value);
+ java_mirror->float_field_put(fd.offset(), value);
+ } else if (strcmp(field_signature, "D") == 0) {
+ double value = atof(string_value);
+ java_mirror->double_field_put(fd.offset(), value);
+ } else if (strcmp(field_signature, "Ljava/lang/String;") == 0) {
+ Handle value = java_lang_String::create_from_str(string_value, CHECK);
+ java_mirror->obj_field_put(fd.offset(), value());
+ } else if (field_signature[0] == 'L') {
+ Symbol* klass_name = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK);
+ KlassHandle kelem = resolve_klass(field_signature, CHECK);
+ oop value = ((InstanceKlass*)kelem())->allocate_instance(CHECK);
+ java_mirror->obj_field_put(fd.offset(), value);
+ } else {
+ report_error("unhandled staticfield");
+ }
+ }
+ }
+
+#if INCLUDE_JVMTI
+ void process_JvmtiExport(TRAPS) {
+ const char* field = parse_string();
+ bool value = parse_int("JvmtiExport flag") != 0;
+ if (strcmp(field, "can_access_local_variables") == 0) {
+ JvmtiExport::set_can_access_local_variables(value);
+ } else if (strcmp(field, "can_hotswap_or_post_breakpoint") == 0) {
+ JvmtiExport::set_can_hotswap_or_post_breakpoint(value);
+ } else if (strcmp(field, "can_post_on_exceptions") == 0) {
+ JvmtiExport::set_can_post_on_exceptions(value);
+ } else {
+ report_error("Unrecognized JvmtiExport directive");
+ }
+ }
+#endif // INCLUDE_JVMTI
+
+ // Create and initialize a record for a ciMethod
+ ciMethodRecord* new_ciMethod(Method* method) {
+ ciMethodRecord* rec = NEW_RESOURCE_OBJ(ciMethodRecord);
+ rec->klass = method->method_holder()->name()->as_utf8();
+ rec->method = method->name()->as_utf8();
+ rec->signature = method->signature()->as_utf8();
+ ci_method_records.append(rec);
+ return rec;
+ }
+
+ // Lookup data for a ciMethod
+ ciMethodRecord* find_ciMethodRecord(Method* method) {
+ const char* klass_name = method->method_holder()->name()->as_utf8();
+ const char* method_name = method->name()->as_utf8();
+ const char* signature = method->signature()->as_utf8();
+ for (int i = 0; i < ci_method_records.length(); i++) {
+ ciMethodRecord* rec = ci_method_records.at(i);
+ if (strcmp(rec->klass, klass_name) == 0 &&
+ strcmp(rec->method, method_name) == 0 &&
+ strcmp(rec->signature, signature) == 0) {
+ return rec;
+ }
+ }
+ return NULL;
+ }
+
+ // Create and initialize a record for a ciMethodData
+ ciMethodDataRecord* new_ciMethodData(Method* method) {
+ ciMethodDataRecord* rec = NEW_RESOURCE_OBJ(ciMethodDataRecord);
+ rec->klass = method->method_holder()->name()->as_utf8();
+ rec->method = method->name()->as_utf8();
+ rec->signature = method->signature()->as_utf8();
+ ci_method_data_records.append(rec);
+ return rec;
+ }
+
+ // Lookup data for a ciMethodData
+ ciMethodDataRecord* find_ciMethodDataRecord(Method* method) {
+ const char* klass_name = method->method_holder()->name()->as_utf8();
+ const char* method_name = method->name()->as_utf8();
+ const char* signature = method->signature()->as_utf8();
+ for (int i = 0; i < ci_method_data_records.length(); i++) {
+ ciMethodDataRecord* rec = ci_method_data_records.at(i);
+ if (strcmp(rec->klass, klass_name) == 0 &&
+ strcmp(rec->method, method_name) == 0 &&
+ strcmp(rec->signature, signature) == 0) {
+ return rec;
+ }
+ }
+ return NULL;
+ }
+
+ const char* error_message() {
+ return _error_message;
+ }
+
+ void reset() {
+ _error_message = NULL;
+ ci_method_records.clear();
+ ci_method_data_records.clear();
+ }
+
+ // Take an ascii string contain \u#### escapes and convert it to utf8
+ // in place.
+ static void unescape_string(char* value) {
+ char* from = value;
+ char* to = value;
+ while (*from != '\0') {
+ if (*from != '\\') {
+ *from++ = *to++;
+ } else {
+ switch (from[1]) {
+ case 'u': {
+ from += 2;
+ jchar value=0;
+ for (int i=0; i<4; i++) {
+ char c = *from++;
+ switch (c) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ value = (value << 4) + c - '0';
+ break;
+ case 'a': case 'b': case 'c':
+ case 'd': case 'e': case 'f':
+ value = (value << 4) + 10 + c - 'a';
+ break;
+ case 'A': case 'B': case 'C':
+ case 'D': case 'E': case 'F':
+ value = (value << 4) + 10 + c - 'A';
+ break;
+ default:
+ ShouldNotReachHere();
+ }
+ }
+ UNICODE::convert_to_utf8(&value, 1, to);
+ to++;
+ break;
+ }
+ case 't': *to++ = '\t'; from += 2; break;
+ case 'n': *to++ = '\n'; from += 2; break;
+ case 'r': *to++ = '\r'; from += 2; break;
+ case 'f': *to++ = '\f'; from += 2; break;
+ default:
+ ShouldNotReachHere();
+ }
+ }
+ }
+ *from = *to;
+ }
+};
+
+void ciReplay::replay(TRAPS) {
+ int exit_code = replay_impl(THREAD);
+
+ Threads::destroy_vm();
+
+ vm_exit(exit_code);
+}
+
+int ciReplay::replay_impl(TRAPS) {
+ HandleMark hm;
+ ResourceMark rm;
+ // Make sure we don't run with background compilation
+ BackgroundCompilation = false;
+
+ if (ReplaySuppressInitializers > 2) {
+ // ReplaySuppressInitializers > 2 means that we want to allow
+ // normal VM bootstrap but once we get into the replay itself
+ // don't allow any intializers to be run.
+ ReplaySuppressInitializers = 1;
+ }
+
+ // Load and parse the replay data
+ CompileReplay rp(ReplayDataFile, THREAD);
+ int exit_code = 0;
+ if (rp.can_replay()) {
+ rp.process(THREAD);
+ } else {
+ exit_code = 1;
+ return exit_code;
+ }
+
+ if (HAS_PENDING_EXCEPTION) {
+ oop throwable = PENDING_EXCEPTION;
+ CLEAR_PENDING_EXCEPTION;
+ java_lang_Throwable::print(throwable, tty);
+ tty->cr();
+ java_lang_Throwable::print_stack_trace(throwable, tty);
+ tty->cr();
+ exit_code = 2;
+ }
+
+ if (rp.had_error()) {
+ tty->print_cr("Failed on %s", rp.error_message());
+ exit_code = 1;
+ }
+ return exit_code;
+}
+
+
+void ciReplay::initialize(ciMethodData* m) {
+ if (replay_state == NULL) {
+ return;
+ }
+
+ ASSERT_IN_VM;
+ ResourceMark rm;
+
+ Method* method = m->get_MethodData()->method();
+ ciMethodDataRecord* rec = replay_state->find_ciMethodDataRecord(method);
+ if (rec == NULL) {
+ // This indicates some mismatch with the original environment and
+ // the replay environment though it's not always enough to
+ // interfere with reproducing a bug
+ tty->print_cr("Warning: requesting ciMethodData record for method with no data: ");
+ method->print_name(tty);
+ tty->cr();
+ } else {
+ m->_state = rec->state;
+ m->_current_mileage = rec->current_mileage;
+ if (rec->data_length != 0) {
+ assert(m->_data_size == rec->data_length * (int)sizeof(rec->data[0]), "must agree");
+
+ // Write the correct ciObjects back into the profile data
+ ciEnv* env = ciEnv::current();
+ for (int i = 0; i < rec->oops_length; i++) {
+ KlassHandle *h = (KlassHandle *)rec->oops_handles[i];
+ *(ciMetadata**)(rec->data + rec->oops_offsets[i]) =
+ env->get_metadata((*h)());
+ }
+ // Copy the updated profile data into place as intptr_ts
+#ifdef _LP64
+ Copy::conjoint_jlongs_atomic((jlong *)rec->data, (jlong *)m->_data, rec->data_length);
+#else
+ Copy::conjoint_jints_atomic((jint *)rec->data, (jint *)m->_data, rec->data_length);
+#endif
+ }
+
+ // copy in the original header
+ Copy::conjoint_jbytes(rec->orig_data, (char*)&m->_orig, rec->orig_data_length);
+ }
+}
+
+
+bool ciReplay::should_not_inline(ciMethod* method) {
+ if (replay_state == NULL) {
+ return false;
+ }
+
+ VM_ENTRY_MARK;
+ // ciMethod without a record shouldn't be inlined.
+ return replay_state->find_ciMethodRecord(method->get_Method()) == NULL;
+}
+
+
+void ciReplay::initialize(ciMethod* m) {
+ if (replay_state == NULL) {
+ return;
+ }
+
+ ASSERT_IN_VM;
+ ResourceMark rm;
+
+ Method* method = m->get_Method();
+ ciMethodRecord* rec = replay_state->find_ciMethodRecord(method);
+ if (rec == NULL) {
+ // This indicates some mismatch with the original environment and
+ // the replay environment though it's not always enough to
+ // interfere with reproducing a bug
+ tty->print_cr("Warning: requesting ciMethod record for method with no data: ");
+ method->print_name(tty);
+ tty->cr();
+ } else {
+ // m->_instructions_size = rec->instructions_size;
+ m->_instructions_size = -1;
+ m->_interpreter_invocation_count = rec->interpreter_invocation_count;
+ m->_interpreter_throwout_count = rec->interpreter_throwout_count;
+ method->invocation_counter()->_counter = rec->invocation_counter;
+ method->backedge_counter()->_counter = rec->backedge_counter;
+ }
+}
+
+bool ciReplay::is_loaded(Method* method) {
+ if (replay_state == NULL) {
+ return true;
+ }
+
+ ASSERT_IN_VM;
+ ResourceMark rm;
+
+ ciMethodRecord* rec = replay_state->find_ciMethodRecord(method);
+ return rec != NULL;
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/ci/ciReplay.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_CI_CIREPLAY_HPP
+#define SHARE_VM_CI_CIREPLAY_HPP
+
+#include "ci/ciMethod.hpp"
+
+// ciReplay
+
+class ciReplay {
+ CI_PACKAGE_ACCESS
+
+#ifdef ASSERT
+ private:
+ static int replay_impl(TRAPS);
+
+ public:
+ static void replay(TRAPS);
+
+ // These are used by the CI to fill in the cached data from the
+ // replay file when replaying compiles.
+ static void initialize(ciMethodData* method);
+ static void initialize(ciMethod* method);
+
+ static bool is_loaded(Method* method);
+ static bool is_loaded(Klass* klass);
+
+ static bool should_not_inline(ciMethod* method);
+
+#endif
+};
+
+#endif // SHARE_VM_CI_CIREPLAY_HPP
--- a/hotspot/src/share/vm/ci/ciSymbol.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciSymbol.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -63,6 +63,11 @@
return s->as_utf8();
}
+// The text of the symbol as a null-terminated C string.
+const char* ciSymbol::as_quoted_ascii() {
+ GUARDED_VM_QUICK_ENTRY(return get_symbol()->as_quoted_ascii();)
+}
+
// ------------------------------------------------------------------
// ciSymbol::base
const jbyte* ciSymbol::base() {
--- a/hotspot/src/share/vm/ci/ciSymbol.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciSymbol.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -73,6 +73,9 @@
const char* as_utf8();
int utf8_length();
+ // The text of the symbol as ascii with all non-printable characters quoted as \u####
+ const char* as_quoted_ascii();
+
// Return the i-th utf8 byte, where i < utf8_length
int byte_at(int i);
--- a/hotspot/src/share/vm/ci/ciType.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciType.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -45,7 +45,7 @@
}
ciType::ciType(KlassHandle k) : ciMetadata(k()) {
- _basic_type = Klass::cast(k())->oop_is_array() ? T_ARRAY : T_OBJECT;
+ _basic_type = k()->oop_is_array() ? T_ARRAY : T_OBJECT;
}
--- a/hotspot/src/share/vm/ci/ciUtilities.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/ci/ciUtilities.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -80,6 +80,9 @@
#define GUARDED_VM_ENTRY(action) \
{if (IS_IN_VM) { action } else { VM_ENTRY_MARK; { action }}}
+#define GUARDED_VM_QUICK_ENTRY(action) \
+ {if (IS_IN_VM) { action } else { VM_QUICK_ENTRY_MARK; { action }}}
+
// Redefine this later.
#define KILL_COMPILE_ON_FATAL_(result) \
THREAD); \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/bytecodeAssembler.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "classfile/bytecodeAssembler.hpp"
+#include "interpreter/bytecodes.hpp"
+#include "memory/oopFactory.hpp"
+#include "oops/constantPool.hpp"
+
+#ifdef TARGET_ARCH_x86
+# include "bytes_x86.hpp"
+#endif
+#ifdef TARGET_ARCH_sparc
+# include "bytes_sparc.hpp"
+#endif
+#ifdef TARGET_ARCH_zero
+# include "bytes_zero.hpp"
+#endif
+#ifdef TARGET_ARCH_arm
+# include "bytes_arm.hpp"
+#endif
+#ifdef TARGET_ARCH_ppc
+# include "bytes_ppc.hpp"
+#endif
+
+u2 BytecodeConstantPool::find_or_add(BytecodeCPEntry const& bcpe) {
+ u2 index;
+ u2* probe = _indices.get(bcpe);
+ if (probe == NULL) {
+ index = _entries.length();
+ _entries.append(bcpe);
+ _indices.put(bcpe, index);
+ } else {
+ index = *probe;
+ }
+ return index + _orig->length();
+}
+
+ConstantPool* BytecodeConstantPool::create_constant_pool(TRAPS) const {
+ if (_entries.length() == 0) {
+ return _orig;
+ }
+
+ ConstantPool* cp = ConstantPool::allocate(
+ _orig->pool_holder()->class_loader_data(),
+ _orig->length() + _entries.length(), CHECK_NULL);
+
+ cp->set_pool_holder(_orig->pool_holder());
+ _orig->copy_cp_to(1, _orig->length() - 1, cp, 1, CHECK_NULL);
+
+ for (int i = 0; i < _entries.length(); ++i) {
+ BytecodeCPEntry entry = _entries.at(i);
+ int idx = i + _orig->length();
+ switch (entry._tag) {
+ case BytecodeCPEntry::UTF8:
+ cp->symbol_at_put(idx, entry._u.utf8);
+ entry._u.utf8->increment_refcount();
+ break;
+ case BytecodeCPEntry::KLASS:
+ cp->unresolved_klass_at_put(
+ idx, cp->symbol_at(entry._u.klass));
+ break;
+ case BytecodeCPEntry::STRING:
+ cp->unresolved_string_at_put(
+ idx, cp->symbol_at(entry._u.string));
+ break;
+ case BytecodeCPEntry::NAME_AND_TYPE:
+ cp->name_and_type_at_put(idx,
+ entry._u.name_and_type.name_index,
+ entry._u.name_and_type.type_index);
+ break;
+ case BytecodeCPEntry::METHODREF:
+ cp->method_at_put(idx,
+ entry._u.methodref.class_index,
+ entry._u.methodref.name_and_type_index);
+ break;
+ default:
+ ShouldNotReachHere();
+ }
+ }
+ return cp;
+}
+
+void BytecodeAssembler::append(u1 imm_u1) {
+ _code->append(imm_u1);
+}
+
+void BytecodeAssembler::append(u2 imm_u2) {
+ _code->append(0);
+ _code->append(0);
+ Bytes::put_Java_u2(_code->adr_at(_code->length() - 2), imm_u2);
+}
+
+void BytecodeAssembler::append(u4 imm_u4) {
+ _code->append(0);
+ _code->append(0);
+ _code->append(0);
+ _code->append(0);
+ Bytes::put_Java_u4(_code->adr_at(_code->length() - 4), imm_u4);
+}
+
+void BytecodeAssembler::xload(u4 index, u1 onebyteop, u1 twobyteop) {
+ if (index < 4) {
+ _code->append(onebyteop + index);
+ } else {
+ _code->append(twobyteop);
+ _code->append((u2)index);
+ }
+}
+
+void BytecodeAssembler::dup() {
+ _code->append(Bytecodes::_dup);
+}
+
+void BytecodeAssembler::_new(Symbol* sym) {
+ u2 cpool_index = _cp->klass(sym);
+ _code->append(Bytecodes::_new);
+ append(cpool_index);
+}
+
+void BytecodeAssembler::load_string(Symbol* sym) {
+ u2 cpool_index = _cp->string(sym);
+ if (cpool_index < 0x100) {
+ ldc(cpool_index);
+ } else {
+ ldc_w(cpool_index);
+ }
+}
+
+void BytecodeAssembler::ldc(u1 index) {
+ _code->append(Bytecodes::_ldc);
+ append(index);
+}
+
+void BytecodeAssembler::ldc_w(u2 index) {
+ _code->append(Bytecodes::_ldc_w);
+ append(index);
+}
+
+void BytecodeAssembler::athrow() {
+ _code->append(Bytecodes::_athrow);
+}
+
+void BytecodeAssembler::iload(u4 index) {
+ xload(index, Bytecodes::_iload_0, Bytecodes::_iload);
+}
+
+void BytecodeAssembler::lload(u4 index) {
+ xload(index, Bytecodes::_lload_0, Bytecodes::_lload);
+}
+
+void BytecodeAssembler::fload(u4 index) {
+ xload(index, Bytecodes::_fload_0, Bytecodes::_fload);
+}
+
+void BytecodeAssembler::dload(u4 index) {
+ xload(index, Bytecodes::_dload_0, Bytecodes::_dload);
+}
+
+void BytecodeAssembler::aload(u4 index) {
+ xload(index, Bytecodes::_aload_0, Bytecodes::_aload);
+}
+
+void BytecodeAssembler::load(BasicType bt, u4 index) {
+ switch (bt) {
+ case T_BOOLEAN:
+ case T_CHAR:
+ case T_BYTE:
+ case T_SHORT:
+ case T_INT: iload(index); break;
+ case T_FLOAT: fload(index); break;
+ case T_DOUBLE: dload(index); break;
+ case T_LONG: lload(index); break;
+ case T_OBJECT:
+ case T_ARRAY: aload(index); break;
+ default:
+ ShouldNotReachHere();
+ }
+}
+
+void BytecodeAssembler::checkcast(Symbol* sym) {
+ u2 cpool_index = _cp->klass(sym);
+ _code->append(Bytecodes::_checkcast);
+ append(cpool_index);
+}
+
+void BytecodeAssembler::invokespecial(Method* method) {
+ invokespecial(method->klass_name(), method->name(), method->signature());
+}
+
+void BytecodeAssembler::invokespecial(Symbol* klss, Symbol* name, Symbol* sig) {
+ u2 methodref_index = _cp->methodref(klss, name, sig);
+ _code->append(Bytecodes::_invokespecial);
+ append(methodref_index);
+}
+
+void BytecodeAssembler::invokevirtual(Method* method) {
+ invokevirtual(method->klass_name(), method->name(), method->signature());
+}
+
+void BytecodeAssembler::invokevirtual(Symbol* klss, Symbol* name, Symbol* sig) {
+ u2 methodref_index = _cp->methodref(klss, name, sig);
+ _code->append(Bytecodes::_invokevirtual);
+ append(methodref_index);
+}
+
+void BytecodeAssembler::ireturn() {
+ _code->append(Bytecodes::_ireturn);
+}
+
+void BytecodeAssembler::lreturn() {
+ _code->append(Bytecodes::_lreturn);
+}
+
+void BytecodeAssembler::freturn() {
+ _code->append(Bytecodes::_freturn);
+}
+
+void BytecodeAssembler::dreturn() {
+ _code->append(Bytecodes::_dreturn);
+}
+
+void BytecodeAssembler::areturn() {
+ _code->append(Bytecodes::_areturn);
+}
+
+void BytecodeAssembler::_return() {
+ _code->append(Bytecodes::_return);
+}
+
+void BytecodeAssembler::_return(BasicType bt) {
+ switch (bt) {
+ case T_BOOLEAN:
+ case T_CHAR:
+ case T_BYTE:
+ case T_SHORT:
+ case T_INT: ireturn(); break;
+ case T_FLOAT: freturn(); break;
+ case T_DOUBLE: dreturn(); break;
+ case T_LONG: lreturn(); break;
+ case T_OBJECT:
+ case T_ARRAY: areturn(); break;
+ case T_VOID: _return(); break;
+ default:
+ ShouldNotReachHere();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/bytecodeAssembler.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP
+#define SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP
+
+#include "memory/allocation.hpp"
+#include "oops/method.hpp"
+#include "oops/symbol.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/growableArray.hpp"
+#include "utilities/resourceHash.hpp"
+
+
+/**
+ * Bytecode Assembler
+ *
+ * These classes are used to synthesize code for creating new methods from
+ * within the VM. This is only a partial implementation of an assembler;
+ * only the bytecodes that are needed by clients are implemented at this time.
+ * This is used during default method analysis to create overpass methods
+ * and add them to a call during parsing. Other uses (such as creating
+ * bridges) may come later. Any missing bytecodes can be implemented on an
+ * as-need basis.
+ */
+
+class BytecodeBuffer : public GrowableArray<u1> {
+ public:
+ BytecodeBuffer() : GrowableArray<u1>(20) {}
+};
+
+// Entries in a yet-to-be-created constant pool. Limited types for now.
+class BytecodeCPEntry VALUE_OBJ_CLASS_SPEC {
+ public:
+ enum tag {
+ ERROR_TAG,
+ UTF8,
+ KLASS,
+ STRING,
+ NAME_AND_TYPE,
+ METHODREF
+ };
+
+ u1 _tag;
+ union {
+ Symbol* utf8;
+ u2 klass;
+ u2 string;
+ struct {
+ u2 name_index;
+ u2 type_index;
+ } name_and_type;
+ struct {
+ u2 class_index;
+ u2 name_and_type_index;
+ } methodref;
+ uintptr_t hash;
+ } _u;
+
+ BytecodeCPEntry() : _tag(ERROR_TAG) { _u.hash = 0; }
+ BytecodeCPEntry(u1 tag) : _tag(tag) { _u.hash = 0; }
+
+ static BytecodeCPEntry utf8(Symbol* symbol) {
+ BytecodeCPEntry bcpe(UTF8);
+ bcpe._u.utf8 = symbol;
+ return bcpe;
+ }
+
+ static BytecodeCPEntry klass(u2 index) {
+ BytecodeCPEntry bcpe(KLASS);
+ bcpe._u.klass = index;
+ return bcpe;
+ }
+
+ static BytecodeCPEntry string(u2 index) {
+ BytecodeCPEntry bcpe(STRING);
+ bcpe._u.string = index;
+ return bcpe;
+ }
+
+ static BytecodeCPEntry name_and_type(u2 name, u2 type) {
+ BytecodeCPEntry bcpe(NAME_AND_TYPE);
+ bcpe._u.name_and_type.name_index = name;
+ bcpe._u.name_and_type.type_index = type;
+ return bcpe;
+ }
+
+ static BytecodeCPEntry methodref(u2 class_index, u2 nat) {
+ BytecodeCPEntry bcpe(METHODREF);
+ bcpe._u.methodref.class_index = class_index;
+ bcpe._u.methodref.name_and_type_index = nat;
+ return bcpe;
+ }
+
+ static bool equals(BytecodeCPEntry const& e0, BytecodeCPEntry const& e1) {
+ return e0._tag == e1._tag && e0._u.hash == e1._u.hash;
+ }
+
+ static unsigned hash(BytecodeCPEntry const& e0) {
+ return (unsigned)(e0._tag ^ e0._u.hash);
+ }
+};
+
+class BytecodeConstantPool : ResourceObj {
+ private:
+ typedef ResourceHashtable<BytecodeCPEntry, u2,
+ &BytecodeCPEntry::hash, &BytecodeCPEntry::equals> IndexHash;
+
+ ConstantPool* _orig;
+ GrowableArray<BytecodeCPEntry> _entries;
+ IndexHash _indices;
+
+ u2 find_or_add(BytecodeCPEntry const& bcpe);
+
+ public:
+
+ BytecodeConstantPool(ConstantPool* orig) : _orig(orig) {}
+
+ BytecodeCPEntry const& at(u2 index) const { return _entries.at(index); }
+
+ InstanceKlass* pool_holder() const {
+ return InstanceKlass::cast(_orig->pool_holder());
+ }
+
+ u2 utf8(Symbol* sym) {
+ return find_or_add(BytecodeCPEntry::utf8(sym));
+ }
+
+ u2 klass(Symbol* class_name) {
+ return find_or_add(BytecodeCPEntry::klass(utf8(class_name)));
+ }
+
+ u2 string(Symbol* str) {
+ return find_or_add(BytecodeCPEntry::string(utf8(str)));
+ }
+
+ u2 name_and_type(Symbol* name, Symbol* sig) {
+ return find_or_add(BytecodeCPEntry::name_and_type(utf8(name), utf8(sig)));
+ }
+
+ u2 methodref(Symbol* class_name, Symbol* name, Symbol* sig) {
+ return find_or_add(BytecodeCPEntry::methodref(
+ klass(class_name), name_and_type(name, sig)));
+ }
+
+ ConstantPool* create_constant_pool(TRAPS) const;
+};
+
+// Partial bytecode assembler - only what we need for creating
+// overpass methods for default methods is implemented
+class BytecodeAssembler : StackObj {
+ private:
+ BytecodeBuffer* _code;
+ BytecodeConstantPool* _cp;
+
+ void append(u1 imm_u1);
+ void append(u2 imm_u2);
+ void append(u4 imm_u4);
+
+ void xload(u4 index, u1 quick, u1 twobyte);
+
+ public:
+ BytecodeAssembler(BytecodeBuffer* buffer, BytecodeConstantPool* cp)
+ : _code(buffer), _cp(cp) {}
+
+ void aload(u4 index);
+ void areturn();
+ void athrow();
+ void checkcast(Symbol* sym);
+ void dload(u4 index);
+ void dreturn();
+ void dup();
+ void fload(u4 index);
+ void freturn();
+ void iload(u4 index);
+ void invokespecial(Method* method);
+ void invokespecial(Symbol* cls, Symbol* name, Symbol* sig);
+ void invokevirtual(Method* method);
+ void invokevirtual(Symbol* cls, Symbol* name, Symbol* sig);
+ void ireturn();
+ void ldc(u1 index);
+ void ldc_w(u2 index);
+ void lload(u4 index);
+ void lreturn();
+ void _new(Symbol* sym);
+ void _return();
+
+ void load_string(Symbol* sym);
+ void load(BasicType bt, u4 index);
+ void _return(BasicType bt);
+};
+
+#endif // SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -27,6 +27,8 @@
#include "classfile/classLoader.hpp"
#include "classfile/classLoaderData.hpp"
#include "classfile/classLoaderData.inline.hpp"
+#include "classfile/defaultMethods.hpp"
+#include "classfile/genericSignatures.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
@@ -84,6 +86,9 @@
// - to check NameAndType_info signatures more aggressively
#define JAVA_7_VERSION 51
+// Extension method support.
+#define JAVA_8_VERSION 52
+
void ClassFileParser::parse_constant_pool_entries(ClassLoaderData* loader_data, constantPoolHandle cp, int length, TRAPS) {
// Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
@@ -785,6 +790,7 @@
ClassLoaderData* loader_data,
Handle protection_domain,
Symbol* class_name,
+ bool* has_default_methods,
TRAPS) {
ClassFileStream* cfs = stream();
assert(length > 0, "only called for length>0");
@@ -818,9 +824,12 @@
interf = KlassHandle(THREAD, k);
}
- if (!Klass::cast(interf())->is_interface()) {
+ if (!interf()->is_interface()) {
THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", NULL);
}
+ if (InstanceKlass::cast(interf())->has_default_methods()) {
+ *has_default_methods = true;
+ }
interfaces->at_put(index, interf());
}
@@ -1928,7 +1937,8 @@
if (method_attribute_name == vmSymbols::tag_code()) {
// Parse Code attribute
if (_need_verify) {
- guarantee_property(!access_flags.is_native() && !access_flags.is_abstract(),
+ guarantee_property(
+ !access_flags.is_native() && !access_flags.is_abstract(),
"Code attribute in native or abstract methods in class file %s",
CHECK_(nullHandle));
}
@@ -2125,7 +2135,9 @@
runtime_visible_annotations_length = method_attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations");
- parse_annotations(runtime_visible_annotations, runtime_visible_annotations_length, cp, &parsed_annotations, CHECK_(nullHandle));
+ parse_annotations(runtime_visible_annotations,
+ runtime_visible_annotations_length, cp, &parsed_annotations,
+ CHECK_(nullHandle));
cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle));
} else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
runtime_invisible_annotations_length = method_attribute_length;
@@ -2169,12 +2181,10 @@
}
// All sizing information for a Method* is finally available, now create it
- Method* m = Method::allocate(loader_data, code_length, access_flags,
- linenumber_table_length,
- total_lvt_length,
- exception_table_length,
- checked_exceptions_length,
- CHECK_(nullHandle));
+ Method* m = Method::allocate(
+ loader_data, code_length, access_flags, linenumber_table_length,
+ total_lvt_length, exception_table_length, checked_exceptions_length,
+ ConstMethod::NORMAL, CHECK_(nullHandle));
ClassLoadingService::add_class_method_size(m->size()*HeapWordSize);
@@ -2204,7 +2214,6 @@
// Fill in code attribute information
m->set_max_stack(max_stack);
m->set_max_locals(max_locals);
-
m->constMethod()->set_stackmap_data(stackmap_data);
// Copy byte codes
@@ -2356,6 +2365,7 @@
Array<AnnotationArray*>** methods_annotations,
Array<AnnotationArray*>** methods_parameter_annotations,
Array<AnnotationArray*>** methods_default_annotations,
+ bool* has_default_methods,
TRAPS) {
ClassFileStream* cfs = stream();
AnnotationArray* method_annotations = NULL;
@@ -2382,6 +2392,10 @@
if (method->is_final()) {
*has_final_method = true;
}
+ if (is_interface && !method->is_abstract() && !method->is_static()) {
+ // default method
+ *has_default_methods = true;
+ }
methods->at_put(index, method());
if (*methods_annotations == NULL) {
*methods_annotations =
@@ -2907,6 +2921,34 @@
}
+#ifndef PRODUCT
+static void parseAndPrintGenericSignatures(
+ instanceKlassHandle this_klass, TRAPS) {
+ assert(ParseAllGenericSignatures == true, "Shouldn't call otherwise");
+ ResourceMark rm;
+
+ if (this_klass->generic_signature() != NULL) {
+ using namespace generic;
+ ClassDescriptor* spec = ClassDescriptor::parse_generic_signature(this_klass(), CHECK);
+
+ tty->print_cr("Parsing %s", this_klass->generic_signature()->as_C_string());
+ spec->print_on(tty);
+
+ for (int i = 0; i < this_klass->methods()->length(); ++i) {
+ Method* m = this_klass->methods()->at(i);
+ MethodDescriptor* method_spec = MethodDescriptor::parse_generic_signature(m, spec);
+ Symbol* sig = m->generic_signature();
+ if (sig == NULL) {
+ sig = m->signature();
+ }
+ tty->print_cr("Parsing %s", sig->as_C_string());
+ method_spec->print_on(tty);
+ }
+ }
+}
+#endif // ndef PRODUCT
+
+
instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
Handle class_loader,
Handle protection_domain,
@@ -2923,6 +2965,8 @@
unsigned char *cached_class_file_bytes = NULL;
jint cached_class_file_length;
ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
+ bool has_default_methods = false;
+ ResourceMark rm(THREAD);
ClassFileStream* cfs = stream();
// Timing
@@ -3138,7 +3182,9 @@
if (itfs_len == 0) {
local_interfaces = Universe::the_empty_klass_array();
} else {
- local_interfaces = parse_interfaces(cp, itfs_len, loader_data, protection_domain, _class_name, CHECK_(nullHandle));
+ local_interfaces = parse_interfaces(
+ cp, itfs_len, loader_data, protection_domain, _class_name,
+ &has_default_methods, CHECK_(nullHandle));
}
u2 java_fields_count = 0;
@@ -3164,6 +3210,7 @@
&methods_annotations,
&methods_parameter_annotations,
&methods_default_annotations,
+ &has_default_methods,
CHECK_(nullHandle));
// Additional attributes
@@ -3193,6 +3240,11 @@
super_klass = instanceKlassHandle(THREAD, kh());
}
if (super_klass.not_null()) {
+
+ if (super_klass->has_default_methods()) {
+ has_default_methods = true;
+ }
+
if (super_klass->is_interface()) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
@@ -3229,14 +3281,11 @@
int itable_size = 0;
int num_miranda_methods = 0;
- klassVtable::compute_vtable_size_and_num_mirandas(vtable_size,
- num_miranda_methods,
- super_klass(),
- methods,
- access_flags,
- class_loader,
- class_name,
- local_interfaces,
+ GrowableArray<Method*> all_mirandas(20);
+
+ klassVtable::compute_vtable_size_and_num_mirandas(
+ &vtable_size, &num_miranda_methods, &all_mirandas, super_klass(), methods,
+ access_flags, class_loader, class_name, local_interfaces,
CHECK_(nullHandle));
// Size of Java itable (in words)
@@ -3656,6 +3705,7 @@
this_klass->set_minor_version(minor_version);
this_klass->set_major_version(major_version);
+ this_klass->set_has_default_methods(has_default_methods);
// Set up Method*::intrinsic_id as soon as we know the names of methods.
// (We used to do this lazily, but now we query it in Rewriter,
@@ -3673,6 +3723,16 @@
cached_class_file_length);
}
+ // Fill in field values obtained by parse_classfile_attributes
+ if (parsed_annotations.has_any_annotations())
+ parsed_annotations.apply_to(this_klass);
+ // Create annotations
+ if (_annotations != NULL && this_klass->annotations() == NULL) {
+ Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL);
+ this_klass->set_annotations(anno);
+ }
+ apply_parsed_class_attributes(this_klass);
+
// Miranda methods
if ((num_miranda_methods > 0) ||
// if this class introduced new miranda methods or
@@ -3682,18 +3742,6 @@
this_klass->set_has_miranda_methods(); // then set a flag
}
- // Fill in field values obtained by parse_classfile_attributes
- if (parsed_annotations.has_any_annotations()) {
- parsed_annotations.apply_to(this_klass);
- }
- // Create annotations
- if (_annotations != NULL && this_klass->annotations() == NULL) {
- Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL);
- this_klass->set_annotations(anno);
- }
- apply_parsed_class_attributes(this_klass);
-
- // Compute transitive closure of interfaces this class implements
this_klass->set_transitive_interfaces(transitive_interfaces);
// Fill in information needed to compute superclasses.
@@ -3702,6 +3750,7 @@
// Initialize itable offset tables
klassItable::setup_itable_offset_table(this_klass);
+ // Compute transitive closure of interfaces this class implements
// Do final class setup
fill_oop_maps(this_klass, nonstatic_oop_map_count, nonstatic_oop_offsets, nonstatic_oop_counts);
@@ -3726,6 +3775,21 @@
check_illegal_static_method(this_klass, CHECK_(nullHandle));
}
+
+#ifdef ASSERT
+ if (ParseAllGenericSignatures) {
+ parseAndPrintGenericSignatures(this_klass, CHECK_(nullHandle));
+ }
+#endif
+
+ // Generate any default methods - default methods are interface methods
+ // that have a default implementation. This is new with Lambda project.
+ if (has_default_methods && !access_flags.is_interface() &&
+ local_interfaces->length() > 0) {
+ DefaultMethods::generate_default_methods(
+ this_klass(), &all_mirandas, CHECK_(nullHandle));
+ }
+
// Allocate mirror and initialize static fields
java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));
@@ -3744,6 +3808,7 @@
false /* not shared class */);
if (TraceClassLoading) {
+ ResourceMark rm;
// print in a single call to reduce interleaving of output
if (cfs->source() != NULL) {
tty->print("[Loaded %s from %s]\n", this_klass->external_name(),
@@ -3758,15 +3823,15 @@
tty->print("[Loaded %s]\n", this_klass->external_name());
}
} else {
- ResourceMark rm;
tty->print("[Loaded %s from %s]\n", this_klass->external_name(),
InstanceKlass::cast(class_loader->klass())->external_name());
}
}
if (TraceClassResolution) {
+ ResourceMark rm;
// print out the superclass.
- const char * from = Klass::cast(this_klass())->external_name();
+ const char * from = this_klass()->external_name();
if (this_klass->java_super() != NULL) {
tty->print("RESOLVE %s %s (super)\n", from, InstanceKlass::cast(this_klass->java_super())->external_name());
}
@@ -3785,6 +3850,7 @@
#ifndef PRODUCT
if( PrintCompactFieldsSavings ) {
+ ResourceMark rm;
if( nonstatic_field_size < orig_nonstatic_field_size ) {
tty->print("[Saved %d of %d bytes in %s]\n",
(orig_nonstatic_field_size - nonstatic_field_size)*heapOopSize,
@@ -3811,7 +3877,6 @@
return this_klass;
}
-
unsigned int
ClassFileParser::compute_oop_map_count(instanceKlassHandle super,
unsigned int nonstatic_oop_map_count,
@@ -3917,13 +3982,13 @@
// java.lang.Object has empty default constructor
k->set_has_vanilla_constructor();
} else {
- if (Klass::cast(super)->has_vanilla_constructor() &&
+ if (super->has_vanilla_constructor() &&
_has_vanilla_constructor) {
k->set_has_vanilla_constructor();
}
#ifdef ASSERT
bool v = false;
- if (Klass::cast(super)->has_vanilla_constructor()) {
+ if (super->has_vanilla_constructor()) {
Method* constructor = k->find_method(vmSymbols::object_initializer_name(
), vmSymbols::void_method_signature());
if (constructor != NULL && constructor->is_vanilla_constructor()) {
@@ -4065,7 +4130,7 @@
int lng = local_interfaces->length();
for (int i = lng - 1; i >= 0; i--) {
Klass* k = local_interfaces->at(i);
- assert (k != NULL && Klass::cast(k)->is_interface(), "invalid interface");
+ assert (k != NULL && k->is_interface(), "invalid interface");
if (!Reflection::verify_class_access(this_klass(), k, false)) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
@@ -4128,7 +4193,7 @@
}
// continue to look from super_m's holder's super.
- k = InstanceKlass::cast(super_m->method_holder())->super();
+ k = super_m->method_holder()->super();
continue;
}
@@ -4263,13 +4328,16 @@
const bool is_strict = (flags & JVM_ACC_STRICT) != 0;
const bool is_synchronized = (flags & JVM_ACC_SYNCHRONIZED) != 0;
const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION;
+ const bool major_gte_8 = _major_version >= JAVA_8_VERSION;
const bool is_initializer = (name == vmSymbols::object_initializer_name());
bool is_illegal = false;
if (is_interface) {
- if (!is_abstract || !is_public || is_static || is_final ||
- is_native || (major_gte_15 && (is_synchronized || is_strict))) {
+ if (!is_public || is_static || is_final || is_native ||
+ ((is_synchronized || is_strict) && major_gte_15 &&
+ (!major_gte_8 || is_abstract)) ||
+ (!major_gte_8 && !is_abstract)) {
is_illegal = true;
}
} else { // not interface
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -151,6 +151,7 @@
ClassLoaderData* loader_data,
Handle protection_domain,
Symbol* class_name,
+ bool* has_default_methods,
TRAPS);
void record_defined_class_dependencies(instanceKlassHandle defined_klass, TRAPS);
@@ -188,6 +189,7 @@
Array<AnnotationArray*>** methods_annotations,
Array<AnnotationArray*>** methods_parameter_annotations,
Array<AnnotationArray*>** methods_default_annotations,
+ bool* has_default_method,
TRAPS);
Array<int>* sort_methods(ClassLoaderData* loader_data,
Array<Method*>* methods,
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -605,8 +605,10 @@
// Load zip library
char path[JVM_MAXPATHLEN];
char ebuf[1024];
- os::dll_build_name(path, sizeof(path), Arguments::get_dll_dir(), "zip");
- void* handle = os::dll_load(path, ebuf, sizeof ebuf);
+ void* handle = NULL;
+ if (os::dll_build_name(path, sizeof(path), Arguments::get_dll_dir(), "zip")) {
+ handle = os::dll_load(path, ebuf, sizeof ebuf);
+ }
if (handle == NULL) {
vm_exit_during_initialization("Unable to load ZIP library", path);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,1387 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "classfile/bytecodeAssembler.hpp"
+#include "classfile/defaultMethods.hpp"
+#include "classfile/genericSignatures.hpp"
+#include "classfile/symbolTable.hpp"
+#include "memory/allocation.hpp"
+#include "memory/metadataFactory.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/signature.hpp"
+#include "runtime/thread.hpp"
+#include "oops/instanceKlass.hpp"
+#include "oops/klass.hpp"
+#include "oops/method.hpp"
+#include "utilities/accessFlags.hpp"
+#include "utilities/exceptions.hpp"
+#include "utilities/ostream.hpp"
+#include "utilities/pair.hpp"
+#include "utilities/resourceHash.hpp"
+
+typedef enum { QUALIFIED, DISQUALIFIED } QualifiedState;
+
+// Because we use an iterative algorithm when iterating over the type
+// hierarchy, we can't use traditional scoped objects which automatically do
+// cleanup in the destructor when the scope is exited. PseudoScope (and
+// PseudoScopeMark) provides a similar functionality, but for when you want a
+// scoped object in non-stack memory (such as in resource memory, as we do
+// here). You've just got to remember to call 'destroy()' on the scope when
+// leaving it (and marks have to be explicitly added).
+class PseudoScopeMark : public ResourceObj {
+ public:
+ virtual void destroy() = 0;
+};
+
+class PseudoScope : public ResourceObj {
+ private:
+ GrowableArray<PseudoScopeMark*> _marks;
+ public:
+
+ static PseudoScope* cast(void* data) {
+ return static_cast<PseudoScope*>(data);
+ }
+
+ void add_mark(PseudoScopeMark* psm) {
+ _marks.append(psm);
+ }
+
+ void destroy() {
+ for (int i = 0; i < _marks.length(); ++i) {
+ _marks.at(i)->destroy();
+ }
+ }
+};
+
+class ContextMark : public PseudoScopeMark {
+ private:
+ generic::Context::Mark _mark;
+ public:
+ ContextMark(const generic::Context::Mark& cm) : _mark(cm) {}
+ virtual void destroy() { _mark.destroy(); }
+};
+
+#ifndef PRODUCT
+static void print_slot(outputStream* str, Symbol* name, Symbol* signature) {
+ ResourceMark rm;
+ str->print("%s%s", name->as_C_string(), signature->as_C_string());
+}
+
+static void print_method(outputStream* str, Method* mo, bool with_class=true) {
+ ResourceMark rm;
+ if (with_class) {
+ str->print("%s.", mo->klass_name()->as_C_string());
+ }
+ print_slot(str, mo->name(), mo->signature());
+}
+#endif // ndef PRODUCT
+
+/**
+ * Perform a depth-first iteration over the class hierarchy, applying
+ * algorithmic logic as it goes.
+ *
+ * This class is one half of the inheritance hierarchy analysis mechanism.
+ * It is meant to be used in conjunction with another class, the algorithm,
+ * which is indicated by the ALGO template parameter. This class can be
+ * paired with any algorithm class that provides the required methods.
+ *
+ * This class contains all the mechanics for iterating over the class hierarchy
+ * starting at a particular root, without recursing (thus limiting stack growth
+ * from this point). It visits each superclass (if present) and superinterface
+ * in a depth-first manner, with callbacks to the ALGO class as each class is
+ * encountered (visit()), The algorithm can cut-off further exploration of a
+ * particular branch by returning 'false' from a visit() call.
+ *
+ * The ALGO class, must provide a visit() method, which each of which will be
+ * called once for each node in the inheritance tree during the iteration. In
+ * addition, it can provide a memory block via new_node_data(InstanceKlass*),
+ * which it can use for node-specific storage (and access via the
+ * current_data() and data_at_depth(int) methods).
+ *
+ * Bare minimum needed to be an ALGO class:
+ * class Algo : public HierarchyVisitor<Algo> {
+ * void* new_node_data(InstanceKlass* cls) { return NULL; }
+ * void free_node_data(void* data) { return; }
+ * bool visit() { return true; }
+ * };
+ */
+template <class ALGO>
+class HierarchyVisitor : StackObj {
+ private:
+
+ class Node : public ResourceObj {
+ public:
+ InstanceKlass* _class;
+ bool _super_was_visited;
+ int _interface_index;
+ void* _algorithm_data;
+
+ Node(InstanceKlass* cls, void* data, bool visit_super)
+ : _class(cls), _super_was_visited(!visit_super),
+ _interface_index(0), _algorithm_data(data) {}
+
+ int number_of_interfaces() { return _class->local_interfaces()->length(); }
+ int interface_index() { return _interface_index; }
+ void set_super_visited() { _super_was_visited = true; }
+ void increment_visited_interface() { ++_interface_index; }
+ void set_all_interfaces_visited() {
+ _interface_index = number_of_interfaces();
+ }
+ bool has_visited_super() { return _super_was_visited; }
+ bool has_visited_all_interfaces() {
+ return interface_index() >= number_of_interfaces();
+ }
+ InstanceKlass* interface_at(int index) {
+ return InstanceKlass::cast(_class->local_interfaces()->at(index));
+ }
+ InstanceKlass* next_super() { return _class->java_super(); }
+ InstanceKlass* next_interface() {
+ return interface_at(interface_index());
+ }
+ };
+
+ bool _cancelled;
+ GrowableArray<Node*> _path;
+
+ Node* current_top() const { return _path.top(); }
+ bool has_more_nodes() const { return !_path.is_empty(); }
+ void push(InstanceKlass* cls, void* data) {
+ assert(cls != NULL, "Requires a valid instance class");
+ Node* node = new Node(cls, data, has_super(cls));
+ _path.push(node);
+ }
+ void pop() { _path.pop(); }
+
+ void reset_iteration() {
+ _cancelled = false;
+ _path.clear();
+ }
+ bool is_cancelled() const { return _cancelled; }
+
+ static bool has_super(InstanceKlass* cls) {
+ return cls->super() != NULL && !cls->is_interface();
+ }
+
+ Node* node_at_depth(int i) const {
+ return (i >= _path.length()) ? NULL : _path.at(_path.length() - i - 1);
+ }
+
+ protected:
+
+ // Accessors available to the algorithm
+ int current_depth() const { return _path.length() - 1; }
+
+ InstanceKlass* class_at_depth(int i) {
+ Node* n = node_at_depth(i);
+ return n == NULL ? NULL : n->_class;
+ }
+ InstanceKlass* current_class() { return class_at_depth(0); }
+
+ void* data_at_depth(int i) {
+ Node* n = node_at_depth(i);
+ return n == NULL ? NULL : n->_algorithm_data;
+ }
+ void* current_data() { return data_at_depth(0); }
+
+ void cancel_iteration() { _cancelled = true; }
+
+ public:
+
+ void run(InstanceKlass* root) {
+ ALGO* algo = static_cast<ALGO*>(this);
+
+ reset_iteration();
+
+ void* algo_data = algo->new_node_data(root);
+ push(root, algo_data);
+ bool top_needs_visit = true;
+
+ do {
+ Node* top = current_top();
+ if (top_needs_visit) {
+ if (algo->visit() == false) {
+ // algorithm does not want to continue along this path. Arrange
+ // it so that this state is immediately popped off the stack
+ top->set_super_visited();
+ top->set_all_interfaces_visited();
+ }
+ top_needs_visit = false;
+ }
+
+ if (top->has_visited_super() && top->has_visited_all_interfaces()) {
+ algo->free_node_data(top->_algorithm_data);
+ pop();
+ } else {
+ InstanceKlass* next = NULL;
+ if (top->has_visited_super() == false) {
+ next = top->next_super();
+ top->set_super_visited();
+ } else {
+ next = top->next_interface();
+ top->increment_visited_interface();
+ }
+ assert(next != NULL, "Otherwise we shouldn't be here");
+ algo_data = algo->new_node_data(next);
+ push(next, algo_data);
+ top_needs_visit = true;
+ }
+ } while (!is_cancelled() && has_more_nodes());
+ }
+};
+
+#ifndef PRODUCT
+class PrintHierarchy : public HierarchyVisitor<PrintHierarchy> {
+ public:
+
+ bool visit() {
+ InstanceKlass* cls = current_class();
+ streamIndentor si(tty, current_depth() * 2);
+ tty->indent().print_cr("%s", cls->name()->as_C_string());
+ return true;
+ }
+
+ void* new_node_data(InstanceKlass* cls) { return NULL; }
+ void free_node_data(void* data) { return; }
+};
+#endif // ndef PRODUCT
+
+// Used to register InstanceKlass objects and all related metadata structures
+// (Methods, ConstantPools) as "in-use" by the current thread so that they can't
+// be deallocated by class redefinition while we're using them. The classes are
+// de-registered when this goes out of scope.
+//
+// Once a class is registered, we need not bother with methodHandles or
+// constantPoolHandles for it's associated metadata.
+class KeepAliveRegistrar : public StackObj {
+ private:
+ Thread* _thread;
+ GrowableArray<ConstantPool*> _keep_alive;
+
+ public:
+ KeepAliveRegistrar(Thread* thread) : _thread(thread), _keep_alive(20) {
+ assert(thread == Thread::current(), "Must be current thread");
+ }
+
+ ~KeepAliveRegistrar() {
+ for (int i = _keep_alive.length() - 1; i >= 0; --i) {
+ ConstantPool* cp = _keep_alive.at(i);
+ int idx = _thread->metadata_handles()->find_from_end(cp);
+ assert(idx > 0, "Must be in the list");
+ _thread->metadata_handles()->remove_at(idx);
+ }
+ }
+
+ // Register a class as 'in-use' by the thread. It's fine to register a class
+ // multiple times (though perhaps inefficient)
+ void register_class(InstanceKlass* ik) {
+ ConstantPool* cp = ik->constants();
+ _keep_alive.push(cp);
+ _thread->metadata_handles()->push(cp);
+ }
+};
+
+class KeepAliveVisitor : public HierarchyVisitor<KeepAliveVisitor> {
+ private:
+ KeepAliveRegistrar* _registrar;
+
+ public:
+ KeepAliveVisitor(KeepAliveRegistrar* registrar) : _registrar(registrar) {}
+
+ void* new_node_data(InstanceKlass* cls) { return NULL; }
+ void free_node_data(void* data) { return; }
+
+ bool visit() {
+ _registrar->register_class(current_class());
+ return true;
+ }
+};
+
+// A method family contains a set of all methods that implement a single
+// language-level method. Because of erasure, these methods may have different
+// signatures. As members of the set are collected while walking over the
+// hierarchy, they are tagged with a qualification state. The qualification
+// state for an erased method is set to disqualified if there exists a path
+// from the root of hierarchy to the method that contains an interleaving
+// language-equivalent method defined in an interface.
+class MethodFamily : public ResourceObj {
+ private:
+
+ generic::MethodDescriptor* _descriptor; // language-level description
+ GrowableArray<Pair<Method*,QualifiedState> > _members;
+ ResourceHashtable<Method*, int> _member_index;
+
+ Method* _selected_target; // Filled in later, if a unique target exists
+ Symbol* _exception_message; // If no unique target is found
+
+ bool contains_method(Method* method) {
+ int* lookup = _member_index.get(method);
+ return lookup != NULL;
+ }
+
+ void add_method(Method* method, QualifiedState state) {
+ Pair<Method*,QualifiedState> entry(method, state);
+ _member_index.put(method, _members.length());
+ _members.append(entry);
+ }
+
+ void disqualify_method(Method* method) {
+ int* index = _member_index.get(method);
+ assert(index != NULL && *index >= 0 && *index < _members.length(), "bad index");
+ _members.at(*index).second = DISQUALIFIED;
+ }
+
+ Symbol* generate_no_defaults_message(TRAPS) const;
+ Symbol* generate_abstract_method_message(Method* method, TRAPS) const;
+ Symbol* generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const;
+
+ public:
+
+ MethodFamily(generic::MethodDescriptor* canonical_desc)
+ : _descriptor(canonical_desc), _selected_target(NULL),
+ _exception_message(NULL) {}
+
+ generic::MethodDescriptor* descriptor() const { return _descriptor; }
+
+ bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) {
+ return descriptor()->covariant_match(md, ctx);
+ }
+
+ void set_target_if_empty(Method* m) {
+ if (_selected_target == NULL && !m->is_overpass()) {
+ _selected_target = m;
+ }
+ }
+
+ void record_qualified_method(Method* m) {
+ // If the method already exists in the set as qualified, this operation is
+ // redundant. If it already exists as disqualified, then we leave it as
+ // disqualfied. Thus we only add to the set if it's not already in the
+ // set.
+ if (!contains_method(m)) {
+ add_method(m, QUALIFIED);
+ }
+ }
+
+ void record_disqualified_method(Method* m) {
+ // If not in the set, add it as disqualified. If it's already in the set,
+ // then set the state to disqualified no matter what the previous state was.
+ if (!contains_method(m)) {
+ add_method(m, DISQUALIFIED);
+ } else {
+ disqualify_method(m);
+ }
+ }
+
+ bool has_target() const { return _selected_target != NULL; }
+ bool throws_exception() { return _exception_message != NULL; }
+
+ Method* get_selected_target() { return _selected_target; }
+ Symbol* get_exception_message() { return _exception_message; }
+
+ // Either sets the target or the exception error message
+ void determine_target(InstanceKlass* root, TRAPS) {
+ if (has_target() || throws_exception()) {
+ return;
+ }
+
+ GrowableArray<Method*> qualified_methods;
+ for (int i = 0; i < _members.length(); ++i) {
+ Pair<Method*,QualifiedState> entry = _members.at(i);
+ if (entry.second == QUALIFIED) {
+ qualified_methods.append(entry.first);
+ }
+ }
+
+ if (qualified_methods.length() == 0) {
+ _exception_message = generate_no_defaults_message(CHECK);
+ } else if (qualified_methods.length() == 1) {
+ Method* method = qualified_methods.at(0);
+ if (method->is_abstract()) {
+ _exception_message = generate_abstract_method_message(method, CHECK);
+ } else {
+ _selected_target = qualified_methods.at(0);
+ }
+ } else {
+ _exception_message = generate_conflicts_message(&qualified_methods,CHECK);
+ }
+
+ assert((has_target() ^ throws_exception()) == 1,
+ "One and only one must be true");
+ }
+
+ bool contains_signature(Symbol* query) {
+ for (int i = 0; i < _members.length(); ++i) {
+ if (query == _members.at(i).first->signature()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+#ifndef PRODUCT
+ void print_on(outputStream* str) const {
+ print_on(str, 0);
+ }
+
+ void print_on(outputStream* str, int indent) const {
+ streamIndentor si(str, indent * 2);
+
+ generic::Context ctx(NULL); // empty, as _descriptor already canonicalized
+ TempNewSymbol family = descriptor()->reify_signature(&ctx, Thread::current());
+ str->indent().print_cr("Logical Method %s:", family->as_C_string());
+
+ streamIndentor si2(str);
+ for (int i = 0; i < _members.length(); ++i) {
+ str->indent();
+ print_method(str, _members.at(i).first);
+ if (_members.at(i).second == DISQUALIFIED) {
+ str->print(" (disqualified)");
+ }
+ str->print_cr("");
+ }
+
+ if (_selected_target != NULL) {
+ print_selected(str, 1);
+ }
+ }
+
+ void print_selected(outputStream* str, int indent) const {
+ assert(has_target(), "Should be called otherwise");
+ streamIndentor si(str, indent * 2);
+ str->indent().print("Selected method: ");
+ print_method(str, _selected_target);
+ str->print_cr("");
+ }
+
+ void print_exception(outputStream* str, int indent) {
+ assert(throws_exception(), "Should be called otherwise");
+ streamIndentor si(str, indent * 2);
+ str->indent().print_cr("%s", _exception_message->as_C_string());
+ }
+#endif // ndef PRODUCT
+};
+
+Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const {
+ return SymbolTable::new_symbol("No qualifying defaults found", CHECK_NULL);
+}
+
+Symbol* MethodFamily::generate_abstract_method_message(Method* method, TRAPS) const {
+ Symbol* klass = method->klass_name();
+ Symbol* name = method->name();
+ Symbol* sig = method->signature();
+ stringStream ss;
+ ss.print("Method ");
+ ss.write((const char*)klass->bytes(), klass->utf8_length());
+ ss.print(".");
+ ss.write((const char*)name->bytes(), name->utf8_length());
+ ss.write((const char*)sig->bytes(), sig->utf8_length());
+ ss.print(" is abstract");
+ return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL);
+}
+
+Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const {
+ stringStream ss;
+ ss.print("Conflicting default methods:");
+ for (int i = 0; i < methods->length(); ++i) {
+ Method* method = methods->at(i);
+ Symbol* klass = method->klass_name();
+ Symbol* name = method->name();
+ ss.print(" ");
+ ss.write((const char*)klass->bytes(), klass->utf8_length());
+ ss.print(".");
+ ss.write((const char*)name->bytes(), name->utf8_length());
+ }
+ return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL);
+}
+
+class StateRestorer;
+
+// StatefulMethodFamily is a wrapper around MethodFamily that maintains the
+// qualification state during hierarchy visitation, and applies that state
+// when adding members to the MethodFamily.
+class StatefulMethodFamily : public ResourceObj {
+ friend class StateRestorer;
+ private:
+ MethodFamily* _method;
+ QualifiedState _qualification_state;
+
+ void set_qualification_state(QualifiedState state) {
+ _qualification_state = state;
+ }
+
+ public:
+ StatefulMethodFamily(generic::MethodDescriptor* md, generic::Context* ctx) {
+ _method = new MethodFamily(md->canonicalize(ctx));
+ _qualification_state = QUALIFIED;
+ }
+
+ void set_target_if_empty(Method* m) { _method->set_target_if_empty(m); }
+
+ MethodFamily* get_method_family() { return _method; }
+
+ bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) {
+ return _method->descriptor_matches(md, ctx);
+ }
+
+ StateRestorer* record_method_and_dq_further(Method* mo);
+};
+
+class StateRestorer : public PseudoScopeMark {
+ private:
+ StatefulMethodFamily* _method;
+ QualifiedState _state_to_restore;
+ public:
+ StateRestorer(StatefulMethodFamily* dm, QualifiedState state)
+ : _method(dm), _state_to_restore(state) {}
+ ~StateRestorer() { destroy(); }
+ void restore_state() { _method->set_qualification_state(_state_to_restore); }
+ virtual void destroy() { restore_state(); }
+};
+
+StateRestorer* StatefulMethodFamily::record_method_and_dq_further(Method* mo) {
+ StateRestorer* mark = new StateRestorer(this, _qualification_state);
+ if (_qualification_state == QUALIFIED) {
+ _method->record_qualified_method(mo);
+ } else {
+ _method->record_disqualified_method(mo);
+ }
+ // Everything found "above"??? this method in the hierarchy walk is set to
+ // disqualified
+ set_qualification_state(DISQUALIFIED);
+ return mark;
+}
+
+class StatefulMethodFamilies : public ResourceObj {
+ private:
+ GrowableArray<StatefulMethodFamily*> _methods;
+
+ public:
+ StatefulMethodFamily* find_matching(
+ generic::MethodDescriptor* md, generic::Context* ctx) {
+ for (int i = 0; i < _methods.length(); ++i) {
+ StatefulMethodFamily* existing = _methods.at(i);
+ if (existing->descriptor_matches(md, ctx)) {
+ return existing;
+ }
+ }
+ return NULL;
+ }
+
+ StatefulMethodFamily* find_matching_or_create(
+ generic::MethodDescriptor* md, generic::Context* ctx) {
+ StatefulMethodFamily* method = find_matching(md, ctx);
+ if (method == NULL) {
+ method = new StatefulMethodFamily(md, ctx);
+ _methods.append(method);
+ }
+ return method;
+ }
+
+ void extract_families_into(GrowableArray<MethodFamily*>* array) {
+ for (int i = 0; i < _methods.length(); ++i) {
+ array->append(_methods.at(i)->get_method_family());
+ }
+ }
+};
+
+// Represents a location corresponding to a vtable slot for methods that
+// neither the class nor any of it's ancestors provide an implementaion.
+// Default methods may be present to fill this slot.
+class EmptyVtableSlot : public ResourceObj {
+ private:
+ Symbol* _name;
+ Symbol* _signature;
+ int _size_of_parameters;
+ MethodFamily* _binding;
+
+ public:
+ EmptyVtableSlot(Method* method)
+ : _name(method->name()), _signature(method->signature()),
+ _size_of_parameters(method->size_of_parameters()), _binding(NULL) {}
+
+ Symbol* name() const { return _name; }
+ Symbol* signature() const { return _signature; }
+ int size_of_parameters() const { return _size_of_parameters; }
+
+ void bind_family(MethodFamily* lm) { _binding = lm; }
+ bool is_bound() { return _binding != NULL; }
+ MethodFamily* get_binding() { return _binding; }
+
+#ifndef PRODUCT
+ void print_on(outputStream* str) const {
+ print_slot(str, name(), signature());
+ }
+#endif // ndef PRODUCT
+};
+
+static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots(
+ InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS) {
+
+ assert(klass != NULL, "Must be valid class");
+
+ GrowableArray<EmptyVtableSlot*>* slots = new GrowableArray<EmptyVtableSlot*>();
+
+ // All miranda methods are obvious candidates
+ for (int i = 0; i < mirandas->length(); ++i) {
+ EmptyVtableSlot* slot = new EmptyVtableSlot(mirandas->at(i));
+ slots->append(slot);
+ }
+
+ // Also any overpasses in our superclasses, that we haven't implemented.
+ // (can't use the vtable because it is not guaranteed to be initialized yet)
+ InstanceKlass* super = klass->java_super();
+ while (super != NULL) {
+ for (int i = 0; i < super->methods()->length(); ++i) {
+ Method* m = super->methods()->at(i);
+ if (m->is_overpass()) {
+ // m is a method that would have been a miranda if not for the
+ // default method processing that occurred on behalf of our superclass,
+ // so it's a method we want to re-examine in this new context. That is,
+ // unless we have a real implementation of it in the current class.
+ Method* impl = klass->lookup_method(m->name(), m->signature());
+ if (impl == NULL || impl->is_overpass()) {
+ slots->append(new EmptyVtableSlot(m));
+ }
+ }
+ }
+ super = super->java_super();
+ }
+
+#ifndef PRODUCT
+ if (TraceDefaultMethods) {
+ tty->print_cr("Slots that need filling:");
+ streamIndentor si(tty);
+ for (int i = 0; i < slots->length(); ++i) {
+ tty->indent();
+ slots->at(i)->print_on(tty);
+ tty->print_cr("");
+ }
+ }
+#endif // ndef PRODUCT
+ return slots;
+}
+
+// Iterates over the type hierarchy looking for all methods with a specific
+// method name. The result of this is a set of method families each of
+// which is populated with a set of methods that implement the same
+// language-level signature.
+class FindMethodsByName : public HierarchyVisitor<FindMethodsByName> {
+ private:
+ // Context data
+ Thread* THREAD;
+ generic::DescriptorCache* _cache;
+ Symbol* _method_name;
+ generic::Context* _ctx;
+ StatefulMethodFamilies _families;
+
+ public:
+
+ FindMethodsByName(generic::DescriptorCache* cache, Symbol* name,
+ generic::Context* ctx, Thread* thread) :
+ _cache(cache), _method_name(name), _ctx(ctx), THREAD(thread) {}
+
+ void get_discovered_families(GrowableArray<MethodFamily*>* methods) {
+ _families.extract_families_into(methods);
+ }
+
+ void* new_node_data(InstanceKlass* cls) { return new PseudoScope(); }
+ void free_node_data(void* node_data) {
+ PseudoScope::cast(node_data)->destroy();
+ }
+
+ bool visit() {
+ PseudoScope* scope = PseudoScope::cast(current_data());
+ InstanceKlass* klass = current_class();
+ InstanceKlass* sub = current_depth() > 0 ? class_at_depth(1) : NULL;
+
+ ContextMark* cm = new ContextMark(_ctx->mark());
+ scope->add_mark(cm); // will restore context when scope is freed
+
+ _ctx->apply_type_arguments(sub, klass, THREAD);
+
+ int start, end = 0;
+ start = klass->find_method_by_name(_method_name, &end);
+ if (start != -1) {
+ for (int i = start; i < end; ++i) {
+ Method* m = klass->methods()->at(i);
+ // This gets the method's parameter list with its generic type
+ // parameters resolved
+ generic::MethodDescriptor* md = _cache->descriptor_for(m, THREAD);
+
+ // Find all methods on this hierarchy that match this method
+ // (name, signature). This class collects other families of this
+ // method name.
+ StatefulMethodFamily* family =
+ _families.find_matching_or_create(md, _ctx);
+
+ if (klass->is_interface()) {
+ // ???
+ StateRestorer* restorer = family->record_method_and_dq_further(m);
+ scope->add_mark(restorer);
+ } else {
+ // This is the rule that methods in classes "win" (bad word) over
+ // methods in interfaces. This works because of single inheritance
+ family->set_target_if_empty(m);
+ }
+ }
+ }
+ return true;
+ }
+};
+
+#ifndef PRODUCT
+static void print_families(
+ GrowableArray<MethodFamily*>* methods, Symbol* match) {
+ streamIndentor si(tty, 4);
+ if (methods->length() == 0) {
+ tty->indent();
+ tty->print_cr("No Logical Method found");
+ }
+ for (int i = 0; i < methods->length(); ++i) {
+ tty->indent();
+ MethodFamily* lm = methods->at(i);
+ if (lm->contains_signature(match)) {
+ tty->print_cr("<Matching>");
+ } else {
+ tty->print_cr("<Non-Matching>");
+ }
+ lm->print_on(tty, 1);
+ }
+}
+#endif // ndef PRODUCT
+
+static void merge_in_new_methods(InstanceKlass* klass,
+ GrowableArray<Method*>* new_methods, TRAPS);
+static void create_overpasses(
+ GrowableArray<EmptyVtableSlot*>* slots, InstanceKlass* klass, TRAPS);
+
+// This is the guts of the default methods implementation. This is called just
+// after the classfile has been parsed if some ancestor has default methods.
+//
+// First if finds any name/signature slots that need any implementation (either
+// because they are miranda or a superclass's implementation is an overpass
+// itself). For each slot, iterate over the hierarchy, using generic signature
+// information to partition any methods that match the name into method families
+// where each family contains methods whose signatures are equivalent at the
+// language level (i.e., their reified parameters match and return values are
+// covariant). Check those sets to see if they contain a signature that matches
+// the slot we're looking at (if we're lucky, there might be other empty slots
+// that we can fill using the same analysis).
+//
+// For each slot filled, we generate an overpass method that either calls the
+// unique default method candidate using invokespecial, or throws an exception
+// (in the case of no default method candidates, or more than one valid
+// candidate). These methods are then added to the class's method list. If
+// the method set we're using contains methods (qualified or not) with a
+// different runtime signature than the method we're creating, then we have to
+// create bridges with those signatures too.
+void DefaultMethods::generate_default_methods(
+ InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS) {
+
+ // This resource mark is the bound for all memory allocation that takes
+ // place during default method processing. After this goes out of scope,
+ // all (Resource) objects' memory will be reclaimed. Be careful if adding an
+ // embedded resource mark under here as that memory can't be used outside
+ // whatever scope it's in.
+ ResourceMark rm(THREAD);
+
+ generic::DescriptorCache cache;
+
+ // Keep entire hierarchy alive for the duration of the computation
+ KeepAliveRegistrar keepAlive(THREAD);
+ KeepAliveVisitor loadKeepAlive(&keepAlive);
+ loadKeepAlive.run(klass);
+
+#ifndef PRODUCT
+ if (TraceDefaultMethods) {
+ ResourceMark rm; // be careful with these!
+ tty->print_cr("Class %s requires default method processing",
+ klass->name()->as_klass_external_name());
+ PrintHierarchy printer;
+ printer.run(klass);
+ }
+#endif // ndef PRODUCT
+
+ GrowableArray<EmptyVtableSlot*>* empty_slots =
+ find_empty_vtable_slots(klass, mirandas, CHECK);
+
+ for (int i = 0; i < empty_slots->length(); ++i) {
+ EmptyVtableSlot* slot = empty_slots->at(i);
+#ifndef PRODUCT
+ if (TraceDefaultMethods) {
+ streamIndentor si(tty, 2);
+ tty->indent().print("Looking for default methods for slot ");
+ slot->print_on(tty);
+ tty->print_cr("");
+ }
+#endif // ndef PRODUCT
+ if (slot->is_bound()) {
+#ifndef PRODUCT
+ if (TraceDefaultMethods) {
+ streamIndentor si(tty, 4);
+ tty->indent().print_cr("Already bound to logical method:");
+ slot->get_binding()->print_on(tty, 1);
+ }
+#endif // ndef PRODUCT
+ continue; // covered by previous processing
+ }
+
+ generic::Context ctx(&cache);
+ FindMethodsByName visitor(&cache, slot->name(), &ctx, CHECK);
+ visitor.run(klass);
+
+ GrowableArray<MethodFamily*> discovered_families;
+ visitor.get_discovered_families(&discovered_families);
+
+#ifndef PRODUCT
+ if (TraceDefaultMethods) {
+ print_families(&discovered_families, slot->signature());
+ }
+#endif // ndef PRODUCT
+
+ // Find and populate any other slots that match the discovered families
+ for (int j = i; j < empty_slots->length(); ++j) {
+ EmptyVtableSlot* open_slot = empty_slots->at(j);
+
+ if (slot->name() == open_slot->name()) {
+ for (int k = 0; k < discovered_families.length(); ++k) {
+ MethodFamily* lm = discovered_families.at(k);
+
+ if (lm->contains_signature(open_slot->signature())) {
+ lm->determine_target(klass, CHECK);
+ open_slot->bind_family(lm);
+ }
+ }
+ }
+ }
+ }
+
+#ifndef PRODUCT
+ if (TraceDefaultMethods) {
+ tty->print_cr("Creating overpasses...");
+ }
+#endif // ndef PRODUCT
+
+ create_overpasses(empty_slots, klass, CHECK);
+
+#ifndef PRODUCT
+ if (TraceDefaultMethods) {
+ tty->print_cr("Default method processing complete");
+ }
+#endif // ndef PRODUCT
+}
+
+
+/**
+ * Generic analysis was used upon interface '_target' and found a unique
+ * default method candidate with generic signature '_method_desc'. This
+ * method is only viable if it would also be in the set of default method
+ * candidates if we ran a full analysis on the current class.
+ *
+ * The only reason that the method would not be in the set of candidates for
+ * the current class is if that there's another covariantly matching method
+ * which is "more specific" than the found method -- i.e., one could find a
+ * path in the interface hierarchy in which the matching method appears
+ * before we get to '_target'.
+ *
+ * In order to determine this, we examine all of the implemented
+ * interfaces. If we find path that leads to the '_target' interface, then
+ * we examine that path to see if there are any methods that would shadow
+ * the selected method along that path.
+ */
+class ShadowChecker : public HierarchyVisitor<ShadowChecker> {
+ private:
+ generic::DescriptorCache* _cache;
+ Thread* THREAD;
+
+ InstanceKlass* _target;
+
+ Symbol* _method_name;
+ InstanceKlass* _method_holder;
+ generic::MethodDescriptor* _method_desc;
+ bool _found_shadow;
+
+ bool path_has_shadow() {
+ generic::Context ctx(_cache);
+
+ for (int i = current_depth() - 1; i > 0; --i) {
+ InstanceKlass* ik = class_at_depth(i);
+ InstanceKlass* sub = class_at_depth(i + 1);
+ ctx.apply_type_arguments(sub, ik, THREAD);
+
+ if (ik->is_interface()) {
+ int end;
+ int start = ik->find_method_by_name(_method_name, &end);
+ if (start != -1) {
+ for (int j = start; j < end; ++j) {
+ Method* mo = ik->methods()->at(j);
+ generic::MethodDescriptor* md = _cache->descriptor_for(mo, THREAD);
+ if (_method_desc->covariant_match(md, &ctx)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public:
+
+ ShadowChecker(generic::DescriptorCache* cache, Thread* thread,
+ Symbol* name, InstanceKlass* holder, generic::MethodDescriptor* desc,
+ InstanceKlass* target)
+ : _cache(cache), THREAD(thread), _method_name(name), _method_holder(holder),
+ _method_desc(desc), _target(target), _found_shadow(false) {}
+
+ void* new_node_data(InstanceKlass* cls) { return NULL; }
+ void free_node_data(void* data) { return; }
+
+ bool visit() {
+ InstanceKlass* ik = current_class();
+ if (ik == _target && current_depth() == 1) {
+ return false; // This was the specified super -- no need to search it
+ }
+ if (ik == _method_holder || ik == _target) {
+ // We found a path that should be examined to see if it shadows _method
+ if (path_has_shadow()) {
+ _found_shadow = true;
+ cancel_iteration();
+ }
+ return false; // no need to continue up hierarchy
+ }
+ return true;
+ }
+
+ bool found_shadow() { return _found_shadow; }
+};
+
+// This is called during linktime when we find an invokespecial call that
+// refers to a direct superinterface. It indicates that we should find the
+// default method in the hierarchy of that superinterface, and if that method
+// would have been a candidate from the point of view of 'this' class, then we
+// return that method.
+Method* DefaultMethods::find_super_default(
+ Klass* cls, Klass* super, Symbol* method_name, Symbol* sig, TRAPS) {
+
+ ResourceMark rm(THREAD);
+
+ assert(cls != NULL && super != NULL, "Need real classes");
+
+ InstanceKlass* current_class = InstanceKlass::cast(cls);
+ InstanceKlass* direction = InstanceKlass::cast(super);
+
+ // Keep entire hierarchy alive for the duration of the computation
+ KeepAliveRegistrar keepAlive(THREAD);
+ KeepAliveVisitor loadKeepAlive(&keepAlive);
+ loadKeepAlive.run(current_class);
+
+#ifndef PRODUCT
+ if (TraceDefaultMethods) {
+ tty->print_cr("Finding super default method %s.%s%s from %s",
+ direction->name()->as_C_string(),
+ method_name->as_C_string(), sig->as_C_string(),
+ current_class->name()->as_C_string());
+ }
+#endif // ndef PRODUCT
+
+ if (!direction->is_interface()) {
+ // We should not be here
+ return NULL;
+ }
+
+ generic::DescriptorCache cache;
+ generic::Context ctx(&cache);
+
+ // Prime the initial generic context for current -> direction
+ ctx.apply_type_arguments(current_class, direction, CHECK_NULL);
+
+ FindMethodsByName visitor(&cache, method_name, &ctx, CHECK_NULL);
+ visitor.run(direction);
+
+ GrowableArray<MethodFamily*> families;
+ visitor.get_discovered_families(&families);
+
+#ifndef PRODUCT
+ if (TraceDefaultMethods) {
+ print_families(&families, sig);
+ }
+#endif // ndef PRODUCT
+
+ MethodFamily* selected_family = NULL;
+
+ for (int i = 0; i < families.length(); ++i) {
+ MethodFamily* lm = families.at(i);
+ if (lm->contains_signature(sig)) {
+ lm->determine_target(current_class, CHECK_NULL);
+ selected_family = lm;
+ }
+ }
+
+ if (selected_family->has_target()) {
+ Method* target = selected_family->get_selected_target();
+ InstanceKlass* holder = InstanceKlass::cast(target->method_holder());
+
+ // Verify that the identified method is valid from the context of
+ // the current class
+ ShadowChecker checker(&cache, THREAD, target->name(),
+ holder, selected_family->descriptor(), direction);
+ checker.run(current_class);
+
+ if (checker.found_shadow()) {
+#ifndef PRODUCT
+ if (TraceDefaultMethods) {
+ tty->print_cr(" Only candidate found was shadowed.");
+ }
+#endif // ndef PRODUCT
+ THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(),
+ "Accessible default method not found", NULL);
+ } else {
+#ifndef PRODUCT
+ if (TraceDefaultMethods) {
+ tty->print(" Returning ");
+ print_method(tty, target, true);
+ tty->print_cr("");
+ }
+#endif // ndef PRODUCT
+ return target;
+ }
+ } else {
+ assert(selected_family->throws_exception(), "must have target or throw");
+ THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(),
+ selected_family->get_exception_message()->as_C_string(), NULL);
+ }
+}
+
+
+static int assemble_redirect(
+ BytecodeConstantPool* cp, BytecodeBuffer* buffer,
+ Symbol* incoming, Method* target, TRAPS) {
+
+ BytecodeAssembler assem(buffer, cp);
+
+ SignatureStream in(incoming, true);
+ SignatureStream out(target->signature(), true);
+ u2 parameter_count = 0;
+
+ assem.aload(parameter_count++); // load 'this'
+
+ while (!in.at_return_type()) {
+ assert(!out.at_return_type(), "Parameter counts do not match");
+ BasicType bt = in.type();
+ assert(out.type() == bt, "Parameter types are not compatible");
+ assem.load(bt, parameter_count);
+ if (in.is_object() && in.as_symbol(THREAD) != out.as_symbol(THREAD)) {
+ assem.checkcast(out.as_symbol(THREAD));
+ } else if (bt == T_LONG || bt == T_DOUBLE) {
+ ++parameter_count; // longs and doubles use two slots
+ }
+ ++parameter_count;
+ in.next();
+ out.next();
+ }
+ assert(out.at_return_type(), "Parameter counts do not match");
+ assert(in.type() == out.type(), "Return types are not compatible");
+
+ if (parameter_count == 1 && (in.type() == T_LONG || in.type() == T_DOUBLE)) {
+ ++parameter_count; // need room for return value
+ }
+ if (target->method_holder()->is_interface()) {
+ assem.invokespecial(target);
+ } else {
+ assem.invokevirtual(target);
+ }
+
+ if (in.is_object() && in.as_symbol(THREAD) != out.as_symbol(THREAD)) {
+ assem.checkcast(in.as_symbol(THREAD));
+ }
+ assem._return(in.type());
+ return parameter_count;
+}
+
+static int assemble_abstract_method_error(
+ BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* message, TRAPS) {
+
+ Symbol* errorName = vmSymbols::java_lang_AbstractMethodError();
+ Symbol* init = vmSymbols::object_initializer_name();
+ Symbol* sig = vmSymbols::string_void_signature();
+
+ BytecodeAssembler assem(buffer, cp);
+
+ assem._new(errorName);
+ assem.dup();
+ assem.load_string(message);
+ assem.invokespecial(errorName, init, sig);
+ assem.athrow();
+
+ return 3; // max stack size: [ exception, exception, string ]
+}
+
+static Method* new_method(
+ BytecodeConstantPool* cp, BytecodeBuffer* bytecodes, Symbol* name,
+ Symbol* sig, AccessFlags flags, int max_stack, int params,
+ ConstMethod::MethodType mt, TRAPS) {
+
+ address code_start = static_cast<address>(bytecodes->adr_at(0));
+ int code_length = bytecodes->length();
+
+ Method* m = Method::allocate(cp->pool_holder()->class_loader_data(),
+ code_length, flags, 0, 0, 0, 0, mt, CHECK_NULL);
+
+ m->set_constants(NULL); // This will get filled in later
+ m->set_name_index(cp->utf8(name));
+ m->set_signature_index(cp->utf8(sig));
+ m->set_generic_signature_index(0);
+#ifdef CC_INTERP
+ ResultTypeFinder rtf(sig);
+ m->set_result_index(rtf.type());
+#endif
+ m->set_size_of_parameters(params);
+ m->set_max_stack(max_stack);
+ m->set_max_locals(params);
+ m->constMethod()->set_stackmap_data(NULL);
+ m->set_code(code_start);
+ m->set_force_inline(true);
+
+ return m;
+}
+
+static void switchover_constant_pool(BytecodeConstantPool* bpool,
+ InstanceKlass* klass, GrowableArray<Method*>* new_methods, TRAPS) {
+
+ if (new_methods->length() > 0) {
+ ConstantPool* cp = bpool->create_constant_pool(CHECK);
+ if (cp != klass->constants()) {
+ klass->class_loader_data()->add_to_deallocate_list(klass->constants());
+ klass->set_constants(cp);
+ cp->set_pool_holder(klass);
+
+ for (int i = 0; i < new_methods->length(); ++i) {
+ new_methods->at(i)->set_constants(cp);
+ }
+ for (int i = 0; i < klass->methods()->length(); ++i) {
+ Method* mo = klass->methods()->at(i);
+ mo->set_constants(cp);
+ }
+ }
+ }
+}
+
+// A "bridge" is a method created by javac to bridge the gap between
+// an implementation and a generically-compatible, but different, signature.
+// Bridges have actual bytecode implementation in classfiles.
+// An "overpass", on the other hand, performs the same function as a bridge
+// but does not occur in a classfile; the VM creates overpass itself,
+// when it needs a path to get from a call site to an default method, and
+// a bridge doesn't exist.
+static void create_overpasses(
+ GrowableArray<EmptyVtableSlot*>* slots,
+ InstanceKlass* klass, TRAPS) {
+
+ GrowableArray<Method*> overpasses;
+ BytecodeConstantPool bpool(klass->constants());
+
+ for (int i = 0; i < slots->length(); ++i) {
+ EmptyVtableSlot* slot = slots->at(i);
+
+ if (slot->is_bound()) {
+ MethodFamily* method = slot->get_binding();
+ int max_stack = 0;
+ BytecodeBuffer buffer;
+
+#ifndef PRODUCT
+ if (TraceDefaultMethods) {
+ tty->print("for slot: ");
+ slot->print_on(tty);
+ tty->print_cr("");
+ if (method->has_target()) {
+ method->print_selected(tty, 1);
+ } else {
+ method->print_exception(tty, 1);
+ }
+ }
+#endif // ndef PRODUCT
+ if (method->has_target()) {
+ Method* selected = method->get_selected_target();
+ max_stack = assemble_redirect(
+ &bpool, &buffer, slot->signature(), selected, CHECK);
+ } else if (method->throws_exception()) {
+ max_stack = assemble_abstract_method_error(
+ &bpool, &buffer, method->get_exception_message(), CHECK);
+ }
+ AccessFlags flags = accessFlags_from(
+ JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE);
+ Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(),
+ flags, max_stack, slot->size_of_parameters(),
+ ConstMethod::OVERPASS, CHECK);
+ if (m != NULL) {
+ overpasses.push(m);
+ }
+ }
+ }
+
+#ifndef PRODUCT
+ if (TraceDefaultMethods) {
+ tty->print_cr("Created %d overpass methods", overpasses.length());
+ }
+#endif // ndef PRODUCT
+
+ switchover_constant_pool(&bpool, klass, &overpasses, CHECK);
+ merge_in_new_methods(klass, &overpasses, CHECK);
+}
+
+static void sort_methods(GrowableArray<Method*>* methods) {
+ // Note that this must sort using the same key as is used for sorting
+ // methods in InstanceKlass.
+ bool sorted = true;
+ for (int i = methods->length() - 1; i > 0; --i) {
+ for (int j = 0; j < i; ++j) {
+ Method* m1 = methods->at(j);
+ Method* m2 = methods->at(j + 1);
+ if ((uintptr_t)m1->name() > (uintptr_t)m2->name()) {
+ methods->at_put(j, m2);
+ methods->at_put(j + 1, m1);
+ sorted = false;
+ }
+ }
+ if (sorted) break;
+ sorted = true;
+ }
+#ifdef ASSERT
+ uintptr_t prev = 0;
+ for (int i = 0; i < methods->length(); ++i) {
+ Method* mh = methods->at(i);
+ uintptr_t nv = (uintptr_t)mh->name();
+ assert(nv >= prev, "Incorrect overpass method ordering");
+ prev = nv;
+ }
+#endif
+}
+
+static void merge_in_new_methods(InstanceKlass* klass,
+ GrowableArray<Method*>* new_methods, TRAPS) {
+
+ enum { ANNOTATIONS, PARAMETERS, DEFAULTS, NUM_ARRAYS };
+
+ Array<AnnotationArray*>* original_annots[NUM_ARRAYS];
+
+ Array<Method*>* original_methods = klass->methods();
+ Annotations* annots = klass->annotations();
+ original_annots[ANNOTATIONS] = annots->methods_annotations();
+ original_annots[PARAMETERS] = annots->methods_parameter_annotations();
+ original_annots[DEFAULTS] = annots->methods_default_annotations();
+
+ Array<int>* original_ordering = klass->method_ordering();
+ Array<int>* merged_ordering = Universe::the_empty_int_array();
+
+ int new_size = klass->methods()->length() + new_methods->length();
+
+ Array<AnnotationArray*>* merged_annots[NUM_ARRAYS];
+
+ Array<Method*>* merged_methods = MetadataFactory::new_array<Method*>(
+ klass->class_loader_data(), new_size, NULL, CHECK);
+ for (int i = 0; i < NUM_ARRAYS; ++i) {
+ if (original_annots[i] != NULL) {
+ merged_annots[i] = MetadataFactory::new_array<AnnotationArray*>(
+ klass->class_loader_data(), new_size, CHECK);
+ } else {
+ merged_annots[i] = NULL;
+ }
+ }
+ if (original_ordering != NULL && original_ordering->length() > 0) {
+ merged_ordering = MetadataFactory::new_array<int>(
+ klass->class_loader_data(), new_size, CHECK);
+ }
+ int method_order_index = klass->methods()->length();
+
+ sort_methods(new_methods);
+
+ // Perform grand merge of existing methods and new methods
+ int orig_idx = 0;
+ int new_idx = 0;
+
+ for (int i = 0; i < new_size; ++i) {
+ Method* orig_method = NULL;
+ Method* new_method = NULL;
+ if (orig_idx < original_methods->length()) {
+ orig_method = original_methods->at(orig_idx);
+ }
+ if (new_idx < new_methods->length()) {
+ new_method = new_methods->at(new_idx);
+ }
+
+ if (orig_method != NULL &&
+ (new_method == NULL || orig_method->name() < new_method->name())) {
+ merged_methods->at_put(i, orig_method);
+ original_methods->at_put(orig_idx, NULL);
+ for (int j = 0; j < NUM_ARRAYS; ++j) {
+ if (merged_annots[j] != NULL) {
+ merged_annots[j]->at_put(i, original_annots[j]->at(orig_idx));
+ original_annots[j]->at_put(orig_idx, NULL);
+ }
+ }
+ if (merged_ordering->length() > 0) {
+ merged_ordering->at_put(i, original_ordering->at(orig_idx));
+ }
+ ++orig_idx;
+ } else {
+ merged_methods->at_put(i, new_method);
+ if (merged_ordering->length() > 0) {
+ merged_ordering->at_put(i, method_order_index++);
+ }
+ ++new_idx;
+ }
+ // update idnum for new location
+ merged_methods->at(i)->set_method_idnum(i);
+ }
+
+ // Verify correct order
+#ifdef ASSERT
+ uintptr_t prev = 0;
+ for (int i = 0; i < merged_methods->length(); ++i) {
+ Method* mo = merged_methods->at(i);
+ uintptr_t nv = (uintptr_t)mo->name();
+ assert(nv >= prev, "Incorrect method ordering");
+ prev = nv;
+ }
+#endif
+
+ // Replace klass methods with new merged lists
+ klass->set_methods(merged_methods);
+ annots->set_methods_annotations(merged_annots[ANNOTATIONS]);
+ annots->set_methods_parameter_annotations(merged_annots[PARAMETERS]);
+ annots->set_methods_default_annotations(merged_annots[DEFAULTS]);
+
+ ClassLoaderData* cld = klass->class_loader_data();
+ MetadataFactory::free_array(cld, original_methods);
+ for (int i = 0; i < NUM_ARRAYS; ++i) {
+ MetadataFactory::free_array(cld, original_annots[i]);
+ }
+ if (original_ordering->length() > 0) {
+ klass->set_method_ordering(merged_ordering);
+ MetadataFactory::free_array(cld, original_ordering);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/defaultMethods.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP
+#define SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP
+
+#include "runtime/handles.hpp"
+#include "utilities/growableArray.hpp"
+#include "utilities/exceptions.hpp"
+
+class InstanceKlass;
+class Symbol;
+class Method;
+
+class DefaultMethods : AllStatic {
+ public:
+
+ // Analyzes class and determines which default methods are inherited
+ // from interfaces (and has no other implementation). For each method
+ // (and each different signature the method could have), create an
+ // "overpass" method that is an instance method that redirects to the
+ // default method. Overpass methods are added to the methods lists for
+ // the class.
+ static void generate_default_methods(
+ InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS);
+
+
+ // Called during linking when an invokespecial to an direct interface
+ // method is found. Selects and returns a method if there is a unique
+ // default method in the 'super_iface' part of the hierarchy which is
+ // also a candidate default for 'this_klass'. Otherwise throws an AME.
+ static Method* find_super_default(
+ Klass* this_klass, Klass* super_iface,
+ Symbol* method_name, Symbol* method_sig, TRAPS);
+};
+
+#endif // SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP
--- a/hotspot/src/share/vm/classfile/dictionary.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -346,7 +346,7 @@
KlassHandle obj) {
assert_locked_or_safepoint(SystemDictionary_lock);
assert(obj() != NULL, "adding NULL obj");
- assert(Klass::cast(obj())->name() == class_name, "sanity check on name");
+ assert(obj()->name() == class_name, "sanity check on name");
unsigned int hash = compute_hash(class_name, loader_data);
int index = hash_to_index(hash);
@@ -553,7 +553,7 @@
bool is_defining_class =
(loader_data == InstanceKlass::cast(e)->class_loader_data());
tty->print("%s%s", is_defining_class ? " " : "^",
- Klass::cast(e)->external_name());
+ e->external_name());
tty->print(", loader ");
loader_data->print_value();
@@ -575,7 +575,7 @@
probe = probe->next()) {
Klass* e = probe->klass();
ClassLoaderData* loader_data = probe->loader_data();
- guarantee(Klass::cast(e)->oop_is_instance(),
+ guarantee(e->oop_is_instance(),
"Verify of system dictionary failed");
// class loader must be present; a null class loader is the
// boostrap loader
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/genericSignatures.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,1272 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "classfile/genericSignatures.hpp"
+#include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "memory/resourceArea.hpp"
+
+namespace generic {
+
+// Helper class for parsing the generic signature Symbol in klass and methods
+class DescriptorStream : public ResourceObj {
+ private:
+ Symbol* _symbol;
+ int _offset;
+ int _mark;
+ const char* _parse_error;
+
+ void set_parse_error(const char* error) {
+ assert(error != NULL, "Can't set NULL error string");
+ _parse_error = error;
+ }
+
+ public:
+ DescriptorStream(Symbol* sym)
+ : _symbol(sym), _offset(0), _mark(-1), _parse_error(NULL) {}
+
+ const char* parse_error() const {
+ return _parse_error;
+ }
+
+ bool at_end() { return _offset >= _symbol->utf8_length(); }
+
+ char peek() {
+ if (at_end()) {
+ set_parse_error("Peeking past end of signature");
+ return '\0';
+ } else {
+ return _symbol->byte_at(_offset);
+ }
+ }
+
+ char read() {
+ if (at_end()) {
+ set_parse_error("Reading past end of signature");
+ return '\0';
+ } else {
+ return _symbol->byte_at(_offset++);
+ }
+ }
+
+ void read(char expected) {
+ char c = read();
+ assert_char(c, expected, 0);
+ }
+
+ void assert_char(char c, char expected, int pos = -1) {
+ if (c != expected) {
+ const char* fmt = "Parse error at %d: expected %c but got %c";
+ size_t len = strlen(fmt) + 5;
+ char* buffer = NEW_RESOURCE_ARRAY(char, len);
+ jio_snprintf(buffer, len, fmt, _offset + pos, expected, c);
+ set_parse_error(buffer);
+ }
+ }
+
+ void push(char c) {
+ assert(c == _symbol->byte_at(_offset - 1), "Pushing back wrong value");
+ --_offset;
+ }
+
+ void expect_end() {
+ if (!at_end()) {
+ set_parse_error("Unexpected data trailing signature");
+ }
+ }
+
+ bool has_mark() { return _mark != -1; }
+
+ void set_mark() {
+ _mark = _offset;
+ }
+
+ Identifier* identifier_from_mark() {
+ assert(has_mark(), "Mark should be set");
+ if (!has_mark()) {
+ set_parse_error("Expected mark to be set");
+ return NULL;
+ } else {
+ Identifier* id = new Identifier(_symbol, _mark, _offset - 1);
+ _mark = -1;
+ return id;
+ }
+ }
+};
+
+
+#define CHECK_FOR_PARSE_ERROR() \
+ if (STREAM->parse_error() != NULL) { \
+ if (VerifyGenericSignatures) { \
+ fatal(STREAM->parse_error()); \
+ } \
+ return NULL; \
+ } 0
+
+#define READ() STREAM->read(); CHECK_FOR_PARSE_ERROR()
+#define PEEK() STREAM->peek(); CHECK_FOR_PARSE_ERROR()
+#define PUSH(c) STREAM->push(c)
+#define EXPECT(c) STREAM->read(c); CHECK_FOR_PARSE_ERROR()
+#define EXPECTED(c, ch) STREAM->assert_char(c, ch); CHECK_FOR_PARSE_ERROR()
+#define EXPECT_END() STREAM->expect_end(); CHECK_FOR_PARSE_ERROR()
+
+#define CHECK_STREAM STREAM); CHECK_FOR_PARSE_ERROR(); (0
+
+#ifndef PRODUCT
+void Identifier::print_on(outputStream* str) const {
+ for (int i = _begin; i < _end; ++i) {
+ str->print("%c", (char)_sym->byte_at(i));
+ }
+}
+#endif // ndef PRODUCT
+
+bool Identifier::equals(Identifier* other) {
+ if (_sym == other->_sym && _begin == other->_begin && _end == other->_end) {
+ return true;
+ } else if (_end - _begin != other->_end - other->_begin) {
+ return false;
+ } else {
+ size_t len = _end - _begin;
+ char* addr = ((char*)_sym->bytes()) + _begin;
+ char* oaddr = ((char*)other->_sym->bytes()) + other->_begin;
+ return strncmp(addr, oaddr, len) == 0;
+ }
+}
+
+bool Identifier::equals(Symbol* sym) {
+ Identifier id(sym, 0, sym->utf8_length());
+ return equals(&id);
+}
+
+/**
+ * A formal type parameter may be found in the the enclosing class, but it could
+ * also come from an enclosing method or outer class, in the case of inner-outer
+ * classes or anonymous classes. For example:
+ *
+ * class Outer<T,V> {
+ * class Inner<W> {
+ * void m(T t, V v, W w);
+ * }
+ * }
+ *
+ * In this case, the type variables in m()'s signature are not all found in the
+ * immediate enclosing class (Inner). class Inner has only type parameter W,
+ * but it's outer_class field will reference Outer's descriptor which contains
+ * T & V (no outer_method in this case).
+ *
+ * If you have an anonymous class, it has both an enclosing method *and* an
+ * enclosing class where type parameters can be declared:
+ *
+ * class MOuter<T> {
+ * <V> void bar(V v) {
+ * Runnable r = new Runnable() {
+ * public void run() {}
+ * public void foo(T t, V v) { ... }
+ * };
+ * }
+ * }
+ *
+ * In this case, foo will be a member of some class, Runnable$1, which has no
+ * formal parameters itself, but has an outer_method (bar()) which provides
+ * type parameter V, and an outer class MOuter with type parameter T.
+ *
+ * It is also possible that the outer class is itself an inner class to some
+ * other class (or an anonymous class with an enclosing method), so we need to
+ * follow the outer_class/outer_method chain to it's end when looking for a
+ * type parameter.
+ */
+TypeParameter* Descriptor::find_type_parameter(Identifier* id, int* depth) {
+
+ int current_depth = 0;
+
+ MethodDescriptor* outer_method = as_method_signature();
+ ClassDescriptor* outer_class = as_class_signature();
+
+ if (outer_class == NULL) { // 'this' is a method signature; use the holder
+ outer_class = outer_method->outer_class();
+ }
+
+ while (outer_method != NULL || outer_class != NULL) {
+ if (outer_method != NULL) {
+ for (int i = 0; i < outer_method->type_parameters().length(); ++i) {
+ TypeParameter* p = outer_method->type_parameters().at(i);
+ if (p->identifier()->equals(id)) {
+ *depth = -1; // indicates this this is a method parameter
+ return p;
+ }
+ }
+ }
+ if (outer_class != NULL) {
+ for (int i = 0; i < outer_class->type_parameters().length(); ++i) {
+ TypeParameter* p = outer_class->type_parameters().at(i);
+ if (p->identifier()->equals(id)) {
+ *depth = current_depth;
+ return p;
+ }
+ }
+ outer_method = outer_class->outer_method();
+ outer_class = outer_class->outer_class();
+ ++current_depth;
+ }
+ }
+
+ if (VerifyGenericSignatures) {
+ fatal("Could not resolve identifier");
+ }
+
+ return NULL;
+}
+
+ClassDescriptor* ClassDescriptor::parse_generic_signature(Klass* klass, TRAPS) {
+ return parse_generic_signature(klass, NULL, CHECK_NULL);
+}
+
+ClassDescriptor* ClassDescriptor::parse_generic_signature(
+ Klass* klass, Symbol* original_name, TRAPS) {
+
+ InstanceKlass* ik = InstanceKlass::cast(klass);
+ Symbol* sym = ik->generic_signature();
+
+ ClassDescriptor* spec;
+
+ if (sym == NULL || (spec = ClassDescriptor::parse_generic_signature(sym)) == NULL) {
+ spec = ClassDescriptor::placeholder(ik);
+ }
+
+ u2 outer_index = get_outer_class_index(ik, CHECK_NULL);
+ if (outer_index != 0) {
+ if (original_name == NULL) {
+ original_name = ik->name();
+ }
+ Handle class_loader = Handle(THREAD, ik->class_loader());
+ Handle protection_domain = Handle(THREAD, ik->protection_domain());
+
+ Symbol* outer_name = ik->constants()->klass_name_at(outer_index);
+ Klass* outer = SystemDictionary::find(
+ outer_name, class_loader, protection_domain, CHECK_NULL);
+ if (outer == NULL && !THREAD->is_Compiler_thread()) {
+ outer = SystemDictionary::resolve_super_or_fail(original_name,
+ outer_name, class_loader, protection_domain, false, CHECK_NULL);
+ }
+
+ InstanceKlass* outer_ik;
+ ClassDescriptor* outer_spec = NULL;
+ if (outer == NULL) {
+ outer_spec = ClassDescriptor::placeholder(ik);
+ assert(false, "Outer class not loaded and not loadable from here");
+ } else {
+ outer_ik = InstanceKlass::cast(outer);
+ outer_spec = parse_generic_signature(outer, original_name, CHECK_NULL);
+ }
+ spec->set_outer_class(outer_spec);
+
+ u2 encl_method_idx = ik->enclosing_method_method_index();
+ if (encl_method_idx != 0 && outer_ik != NULL) {
+ ConstantPool* cp = ik->constants();
+ u2 name_index = cp->name_ref_index_at(encl_method_idx);
+ u2 sig_index = cp->signature_ref_index_at(encl_method_idx);
+ Symbol* name = cp->symbol_at(name_index);
+ Symbol* sig = cp->symbol_at(sig_index);
+ Method* m = outer_ik->find_method(name, sig);
+ if (m != NULL) {
+ Symbol* gsig = m->generic_signature();
+ if (gsig != NULL) {
+ MethodDescriptor* gms = MethodDescriptor::parse_generic_signature(gsig, outer_spec);
+ spec->set_outer_method(gms);
+ }
+ } else if (VerifyGenericSignatures) {
+ ResourceMark rm;
+ stringStream ss;
+ ss.print("Could not find method %s %s in class %s",
+ name->as_C_string(), sig->as_C_string(), outer_name->as_C_string());
+ fatal(ss.as_string());
+ }
+ }
+ }
+
+ spec->bind_variables_to_parameters();
+ return spec;
+}
+
+ClassDescriptor* ClassDescriptor::placeholder(InstanceKlass* klass) {
+ GrowableArray<TypeParameter*> formals;
+ GrowableArray<ClassType*> interfaces;
+ ClassType* super_type = NULL;
+
+ Klass* super_klass = klass->super();
+ if (super_klass != NULL) {
+ InstanceKlass* super = InstanceKlass::cast(super_klass);
+ super_type = ClassType::from_symbol(super->name());
+ }
+
+ for (int i = 0; i < klass->local_interfaces()->length(); ++i) {
+ InstanceKlass* iface = InstanceKlass::cast(klass->local_interfaces()->at(i));
+ interfaces.append(ClassType::from_symbol(iface->name()));
+ }
+ return new ClassDescriptor(formals, super_type, interfaces);
+}
+
+ClassDescriptor* ClassDescriptor::parse_generic_signature(Symbol* sym) {
+
+ DescriptorStream ds(sym);
+ DescriptorStream* STREAM = &ds;
+
+ GrowableArray<TypeParameter*> parameters(8);
+ char c = READ();
+ if (c == '<') {
+ c = READ();
+ while (c != '>') {
+ PUSH(c);
+ TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM);
+ parameters.append(ftp);
+ c = READ();
+ }
+ } else {
+ PUSH(c);
+ }
+
+ EXPECT('L');
+ ClassType* super = ClassType::parse_generic_signature(CHECK_STREAM);
+
+ GrowableArray<ClassType*> signatures(2);
+ while (!STREAM->at_end()) {
+ EXPECT('L');
+ ClassType* iface = ClassType::parse_generic_signature(CHECK_STREAM);
+ signatures.append(iface);
+ }
+
+ EXPECT_END();
+
+ return new ClassDescriptor(parameters, super, signatures);
+}
+
+#ifndef PRODUCT
+void ClassDescriptor::print_on(outputStream* str) const {
+ str->indent().print_cr("ClassDescriptor {");
+ {
+ streamIndentor si(str);
+ if (_type_parameters.length() > 0) {
+ str->indent().print_cr("Formals {");
+ {
+ streamIndentor si(str);
+ for (int i = 0; i < _type_parameters.length(); ++i) {
+ _type_parameters.at(i)->print_on(str);
+ }
+ }
+ str->indent().print_cr("}");
+ }
+ if (_super != NULL) {
+ str->indent().print_cr("Superclass: ");
+ {
+ streamIndentor si(str);
+ _super->print_on(str);
+ }
+ }
+ if (_interfaces.length() > 0) {
+ str->indent().print_cr("SuperInterfaces: {");
+ {
+ streamIndentor si(str);
+ for (int i = 0; i < _interfaces.length(); ++i) {
+ _interfaces.at(i)->print_on(str);
+ }
+ }
+ str->indent().print_cr("}");
+ }
+ if (_outer_method != NULL) {
+ str->indent().print_cr("Outer Method: {");
+ {
+ streamIndentor si(str);
+ _outer_method->print_on(str);
+ }
+ str->indent().print_cr("}");
+ }
+ if (_outer_class != NULL) {
+ str->indent().print_cr("Outer Class: {");
+ {
+ streamIndentor si(str);
+ _outer_class->print_on(str);
+ }
+ str->indent().print_cr("}");
+ }
+ }
+ str->indent().print_cr("}");
+}
+#endif // ndef PRODUCT
+
+ClassType* ClassDescriptor::interface_desc(Symbol* sym) {
+ for (int i = 0; i < _interfaces.length(); ++i) {
+ if (_interfaces.at(i)->identifier()->equals(sym)) {
+ return _interfaces.at(i);
+ }
+ }
+ if (VerifyGenericSignatures) {
+ fatal("Did not find expected interface");
+ }
+ return NULL;
+}
+
+void ClassDescriptor::bind_variables_to_parameters() {
+ if (_outer_class != NULL) {
+ _outer_class->bind_variables_to_parameters();
+ }
+ if (_outer_method != NULL) {
+ _outer_method->bind_variables_to_parameters();
+ }
+ for (int i = 0; i < _type_parameters.length(); ++i) {
+ _type_parameters.at(i)->bind_variables_to_parameters(this, i);
+ }
+ if (_super != NULL) {
+ _super->bind_variables_to_parameters(this);
+ }
+ for (int i = 0; i < _interfaces.length(); ++i) {
+ _interfaces.at(i)->bind_variables_to_parameters(this);
+ }
+}
+
+ClassDescriptor* ClassDescriptor::canonicalize(Context* ctx) {
+
+ GrowableArray<TypeParameter*> type_params(_type_parameters.length());
+ for (int i = 0; i < _type_parameters.length(); ++i) {
+ type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0));
+ }
+
+ ClassDescriptor* outer = _outer_class == NULL ? NULL :
+ _outer_class->canonicalize(ctx);
+
+ ClassType* super = _super == NULL ? NULL : _super->canonicalize(ctx, 0);
+
+ GrowableArray<ClassType*> interfaces(_interfaces.length());
+ for (int i = 0; i < _interfaces.length(); ++i) {
+ interfaces.append(_interfaces.at(i)->canonicalize(ctx, 0));
+ }
+
+ MethodDescriptor* md = _outer_method == NULL ? NULL :
+ _outer_method->canonicalize(ctx);
+
+ return new ClassDescriptor(type_params, super, interfaces, outer, md);
+}
+
+u2 ClassDescriptor::get_outer_class_index(InstanceKlass* klass, TRAPS) {
+ int inner_index = InstanceKlass::inner_class_inner_class_info_offset;
+ int outer_index = InstanceKlass::inner_class_outer_class_info_offset;
+ int name_offset = InstanceKlass::inner_class_inner_name_offset;
+ int next_offset = InstanceKlass::inner_class_next_offset;
+
+ if (klass->inner_classes() == NULL || klass->inner_classes()->length() == 0) {
+ // No inner class info => no declaring class
+ return 0;
+ }
+
+ Array<u2>* i_icls = klass->inner_classes();
+ ConstantPool* i_cp = klass->constants();
+ int i_length = i_icls->length();
+
+ // Find inner_klass attribute
+ for (int i = 0; i + next_offset < i_length; i += next_offset) {
+ u2 ioff = i_icls->at(i + inner_index);
+ u2 ooff = i_icls->at(i + outer_index);
+ u2 noff = i_icls->at(i + name_offset);
+ if (ioff != 0) {
+ // Check to see if the name matches the class we're looking for
+ // before attempting to find the class.
+ if (i_cp->klass_name_at_matches(klass, ioff) && ooff != 0) {
+ return ooff;
+ }
+ }
+ }
+
+ // It may be anonymous; try for that.
+ u2 encl_method_class_idx = klass->enclosing_method_class_index();
+ if (encl_method_class_idx != 0) {
+ return encl_method_class_idx;
+ }
+
+ return 0;
+}
+
+MethodDescriptor* MethodDescriptor::parse_generic_signature(Method* m, ClassDescriptor* outer) {
+ Symbol* generic_sig = m->generic_signature();
+ MethodDescriptor* md = NULL;
+ if (generic_sig == NULL || (md = parse_generic_signature(generic_sig, outer)) == NULL) {
+ md = parse_generic_signature(m->signature(), outer);
+ }
+ assert(md != NULL, "Could not parse method signature");
+ md->bind_variables_to_parameters();
+ return md;
+}
+
+MethodDescriptor* MethodDescriptor::parse_generic_signature(Symbol* sym, ClassDescriptor* outer) {
+
+ DescriptorStream ds(sym);
+ DescriptorStream* STREAM = &ds;
+
+ GrowableArray<TypeParameter*> params(8);
+ char c = READ();
+ if (c == '<') {
+ c = READ();
+ while (c != '>') {
+ PUSH(c);
+ TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM);
+ params.append(ftp);
+ c = READ();
+ }
+ } else {
+ PUSH(c);
+ }
+
+ EXPECT('(');
+
+ GrowableArray<Type*> parameters(8);
+ c = READ();
+ while (c != ')') {
+ PUSH(c);
+ Type* arg = Type::parse_generic_signature(CHECK_STREAM);
+ parameters.append(arg);
+ c = READ();
+ }
+
+ Type* rt = Type::parse_generic_signature(CHECK_STREAM);
+
+ GrowableArray<Type*> throws;
+ while (!STREAM->at_end()) {
+ EXPECT('^');
+ Type* spec = Type::parse_generic_signature(CHECK_STREAM);
+ throws.append(spec);
+ }
+
+ return new MethodDescriptor(params, outer, parameters, rt, throws);
+}
+
+void MethodDescriptor::bind_variables_to_parameters() {
+ for (int i = 0; i < _type_parameters.length(); ++i) {
+ _type_parameters.at(i)->bind_variables_to_parameters(this, i);
+ }
+ for (int i = 0; i < _parameters.length(); ++i) {
+ _parameters.at(i)->bind_variables_to_parameters(this);
+ }
+ _return_type->bind_variables_to_parameters(this);
+ for (int i = 0; i < _throws.length(); ++i) {
+ _throws.at(i)->bind_variables_to_parameters(this);
+ }
+}
+
+bool MethodDescriptor::covariant_match(MethodDescriptor* other, Context* ctx) {
+
+ if (_parameters.length() == other->_parameters.length()) {
+ for (int i = 0; i < _parameters.length(); ++i) {
+ if (!_parameters.at(i)->covariant_match(other->_parameters.at(i), ctx)) {
+ return false;
+ }
+ }
+
+ if (_return_type->as_primitive() != NULL) {
+ return _return_type->covariant_match(other->_return_type, ctx);
+ } else {
+ // return type is a reference
+ return other->_return_type->as_class() != NULL ||
+ other->_return_type->as_variable() != NULL ||
+ other->_return_type->as_array() != NULL;
+ }
+ } else {
+ return false;
+ }
+}
+
+MethodDescriptor* MethodDescriptor::canonicalize(Context* ctx) {
+
+ GrowableArray<TypeParameter*> type_params(_type_parameters.length());
+ for (int i = 0; i < _type_parameters.length(); ++i) {
+ type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0));
+ }
+
+ ClassDescriptor* outer = _outer_class == NULL ? NULL :
+ _outer_class->canonicalize(ctx);
+
+ GrowableArray<Type*> params(_parameters.length());
+ for (int i = 0; i < _parameters.length(); ++i) {
+ params.append(_parameters.at(i)->canonicalize(ctx, 0));
+ }
+
+ Type* rt = _return_type->canonicalize(ctx, 0);
+
+ GrowableArray<Type*> throws(_throws.length());
+ for (int i = 0; i < _throws.length(); ++i) {
+ throws.append(_throws.at(i)->canonicalize(ctx, 0));
+ }
+
+ return new MethodDescriptor(type_params, outer, params, rt, throws);
+}
+
+#ifndef PRODUCT
+TempNewSymbol MethodDescriptor::reify_signature(Context* ctx, TRAPS) {
+ stringStream ss(256);
+
+ ss.print("(");
+ for (int i = 0; i < _parameters.length(); ++i) {
+ _parameters.at(i)->reify_signature(&ss, ctx);
+ }
+ ss.print(")");
+ _return_type->reify_signature(&ss, ctx);
+ return SymbolTable::new_symbol(ss.base(), (int)ss.size(), THREAD);
+}
+
+void MethodDescriptor::print_on(outputStream* str) const {
+ str->indent().print_cr("MethodDescriptor {");
+ {
+ streamIndentor si(str);
+ if (_type_parameters.length() > 0) {
+ str->indent().print_cr("Formals: {");
+ {
+ streamIndentor si(str);
+ for (int i = 0; i < _type_parameters.length(); ++i) {
+ _type_parameters.at(i)->print_on(str);
+ }
+ }
+ str->indent().print_cr("}");
+ }
+ str->indent().print_cr("Parameters: {");
+ {
+ streamIndentor si(str);
+ for (int i = 0; i < _parameters.length(); ++i) {
+ _parameters.at(i)->print_on(str);
+ }
+ }
+ str->indent().print_cr("}");
+ str->indent().print_cr("Return Type: ");
+ {
+ streamIndentor si(str);
+ _return_type->print_on(str);
+ }
+
+ if (_throws.length() > 0) {
+ str->indent().print_cr("Throws: {");
+ {
+ streamIndentor si(str);
+ for (int i = 0; i < _throws.length(); ++i) {
+ _throws.at(i)->print_on(str);
+ }
+ }
+ str->indent().print_cr("}");
+ }
+ }
+ str->indent().print_cr("}");
+}
+#endif // ndef PRODUCT
+
+TypeParameter* TypeParameter::parse_generic_signature(DescriptorStream* STREAM) {
+ STREAM->set_mark();
+ char c = READ();
+ while (c != ':') {
+ c = READ();
+ }
+
+ Identifier* id = STREAM->identifier_from_mark();
+
+ ClassType* class_bound = NULL;
+ GrowableArray<ClassType*> interface_bounds(8);
+
+ c = READ();
+ if (c != '>') {
+ if (c != ':') {
+ EXPECTED(c, 'L');
+ class_bound = ClassType::parse_generic_signature(CHECK_STREAM);
+ c = READ();
+ }
+
+ while (c == ':') {
+ EXPECT('L');
+ ClassType* fts = ClassType::parse_generic_signature(CHECK_STREAM);
+ interface_bounds.append(fts);
+ c = READ();
+ }
+ }
+ PUSH(c);
+
+ return new TypeParameter(id, class_bound, interface_bounds);
+}
+
+void TypeParameter::bind_variables_to_parameters(Descriptor* sig, int position) {
+ if (_class_bound != NULL) {
+ _class_bound->bind_variables_to_parameters(sig);
+ }
+ for (int i = 0; i < _interface_bounds.length(); ++i) {
+ _interface_bounds.at(i)->bind_variables_to_parameters(sig);
+ }
+ _position = position;
+}
+
+Type* TypeParameter::resolve(
+ Context* ctx, int inner_depth, int ctx_depth) {
+
+ if (inner_depth == -1) {
+ // This indicates that the parameter is a method type parameter, which
+ // isn't resolveable using the class hierarchy context
+ return bound();
+ }
+
+ ClassType* provider = ctx->at_depth(ctx_depth);
+ if (provider != NULL) {
+ for (int i = 0; i < inner_depth && provider != NULL; ++i) {
+ provider = provider->outer_class();
+ }
+ if (provider != NULL) {
+ TypeArgument* arg = provider->type_argument_at(_position);
+ if (arg != NULL) {
+ Type* value = arg->lower_bound();
+ return value->canonicalize(ctx, ctx_depth + 1);
+ }
+ }
+ }
+
+ return bound();
+}
+
+TypeParameter* TypeParameter::canonicalize(Context* ctx, int ctx_depth) {
+ ClassType* bound = _class_bound == NULL ? NULL :
+ _class_bound->canonicalize(ctx, ctx_depth);
+
+ GrowableArray<ClassType*> ifaces(_interface_bounds.length());
+ for (int i = 0; i < _interface_bounds.length(); ++i) {
+ ifaces.append(_interface_bounds.at(i)->canonicalize(ctx, ctx_depth));
+ }
+
+ TypeParameter* ret = new TypeParameter(_identifier, bound, ifaces);
+ ret->_position = _position;
+ return ret;
+}
+
+ClassType* TypeParameter::bound() {
+ if (_class_bound != NULL) {
+ return _class_bound;
+ }
+
+ if (_interface_bounds.length() == 1) {
+ return _interface_bounds.at(0);
+ }
+
+ return ClassType::java_lang_Object(); // TODO: investigate this case
+}
+
+#ifndef PRODUCT
+void TypeParameter::print_on(outputStream* str) const {
+ str->indent().print_cr("Formal: {");
+ {
+ streamIndentor si(str);
+
+ str->indent().print("Identifier: ");
+ _identifier->print_on(str);
+ str->print_cr("");
+ if (_class_bound != NULL) {
+ str->indent().print_cr("Class Bound: ");
+ streamIndentor si(str);
+ _class_bound->print_on(str);
+ }
+ if (_interface_bounds.length() > 0) {
+ str->indent().print_cr("Interface Bounds: {");
+ {
+ streamIndentor si(str);
+ for (int i = 0; i < _interface_bounds.length(); ++i) {
+ _interface_bounds.at(i)->print_on(str);
+ }
+ }
+ str->indent().print_cr("}");
+ }
+ str->indent().print_cr("Ordinal Position: %d", _position);
+ }
+ str->indent().print_cr("}");
+}
+#endif // ndef PRODUCT
+
+Type* Type::parse_generic_signature(DescriptorStream* STREAM) {
+ char c = READ();
+ switch (c) {
+ case 'L':
+ return ClassType::parse_generic_signature(CHECK_STREAM);
+ case 'T':
+ return TypeVariable::parse_generic_signature(CHECK_STREAM);
+ case '[':
+ return ArrayType::parse_generic_signature(CHECK_STREAM);
+ default:
+ return new PrimitiveType(c);
+ }
+}
+
+Identifier* ClassType::parse_generic_signature_simple(GrowableArray<TypeArgument*>* args,
+ bool* has_inner, DescriptorStream* STREAM) {
+ STREAM->set_mark();
+
+ char c = READ();
+ while (c != ';' && c != '.' && c != '<') { c = READ(); }
+ Identifier* id = STREAM->identifier_from_mark();
+
+ if (c == '<') {
+ c = READ();
+ while (c != '>') {
+ PUSH(c);
+ TypeArgument* arg = TypeArgument::parse_generic_signature(CHECK_STREAM);
+ args->append(arg);
+ c = READ();
+ }
+ c = READ();
+ }
+
+ *has_inner = (c == '.');
+ if (!(*has_inner)) {
+ EXPECTED(c, ';');
+ }
+
+ return id;
+}
+
+ClassType* ClassType::parse_generic_signature(DescriptorStream* STREAM) {
+ return parse_generic_signature(NULL, CHECK_STREAM);
+}
+
+ClassType* ClassType::parse_generic_signature(ClassType* outer, DescriptorStream* STREAM) {
+ GrowableArray<TypeArgument*> args;
+ ClassType* gct = NULL;
+ bool has_inner = false;
+
+ Identifier* id = parse_generic_signature_simple(&args, &has_inner, STREAM);
+ if (id != NULL) {
+ gct = new ClassType(id, args, outer);
+
+ if (has_inner) {
+ gct = parse_generic_signature(gct, CHECK_STREAM);
+ }
+ }
+ return gct;
+}
+
+ClassType* ClassType::from_symbol(Symbol* sym) {
+ assert(sym != NULL, "Must not be null");
+ GrowableArray<TypeArgument*> args;
+ Identifier* id = new Identifier(sym, 0, sym->utf8_length());
+ return new ClassType(id, args, NULL);
+}
+
+ClassType* ClassType::java_lang_Object() {
+ return from_symbol(vmSymbols::java_lang_Object());
+}
+
+void ClassType::bind_variables_to_parameters(Descriptor* sig) {
+ for (int i = 0; i < _type_arguments.length(); ++i) {
+ _type_arguments.at(i)->bind_variables_to_parameters(sig);
+ }
+ if (_outer_class != NULL) {
+ _outer_class->bind_variables_to_parameters(sig);
+ }
+}
+
+TypeArgument* ClassType::type_argument_at(int i) {
+ if (i >= 0 && i < _type_arguments.length()) {
+ return _type_arguments.at(i);
+ } else {
+ return NULL;
+ }
+}
+
+#ifndef PRODUCT
+void ClassType::reify_signature(stringStream* ss, Context* ctx) {
+ ss->print("L");
+ _identifier->print_on(ss);
+ ss->print(";");
+}
+
+void ClassType::print_on(outputStream* str) const {
+ str->indent().print_cr("Class {");
+ {
+ streamIndentor si(str);
+ str->indent().print("Name: ");
+ _identifier->print_on(str);
+ str->print_cr("");
+ if (_type_arguments.length() != 0) {
+ str->indent().print_cr("Type Arguments: {");
+ {
+ streamIndentor si(str);
+ for (int j = 0; j < _type_arguments.length(); ++j) {
+ _type_arguments.at(j)->print_on(str);
+ }
+ }
+ str->indent().print_cr("}");
+ }
+ if (_outer_class != NULL) {
+ str->indent().print_cr("Outer Class: ");
+ streamIndentor sir(str);
+ _outer_class->print_on(str);
+ }
+ }
+ str->indent().print_cr("}");
+}
+#endif // ndef PRODUCT
+
+bool ClassType::covariant_match(Type* other, Context* ctx) {
+
+ if (other == this) {
+ return true;
+ }
+
+ TypeVariable* variable = other->as_variable();
+ if (variable != NULL) {
+ other = variable->resolve(ctx, 0);
+ }
+
+ ClassType* outer = outer_class();
+ ClassType* other_class = other->as_class();
+
+ if (other_class == NULL ||
+ (outer == NULL) != (other_class->outer_class() == NULL)) {
+ return false;
+ }
+
+ if (!_identifier->equals(other_class->_identifier)) {
+ return false;
+ }
+
+ if (outer != NULL && !outer->covariant_match(other_class->outer_class(), ctx)) {
+ return false;
+ }
+
+ return true;
+}
+
+ClassType* ClassType::canonicalize(Context* ctx, int ctx_depth) {
+
+ GrowableArray<TypeArgument*> args(_type_arguments.length());
+ for (int i = 0; i < _type_arguments.length(); ++i) {
+ args.append(_type_arguments.at(i)->canonicalize(ctx, ctx_depth));
+ }
+
+ ClassType* outer = _outer_class == NULL ? NULL :
+ _outer_class->canonicalize(ctx, ctx_depth);
+
+ return new ClassType(_identifier, args, outer);
+}
+
+TypeVariable* TypeVariable::parse_generic_signature(DescriptorStream* STREAM) {
+ STREAM->set_mark();
+ char c = READ();
+ while (c != ';') {
+ c = READ();
+ }
+ Identifier* id = STREAM->identifier_from_mark();
+
+ return new TypeVariable(id);
+}
+
+void TypeVariable::bind_variables_to_parameters(Descriptor* sig) {
+ _parameter = sig->find_type_parameter(_id, &_inner_depth);
+ if (VerifyGenericSignatures && _parameter == NULL) {
+ fatal("Could not find formal parameter");
+ }
+}
+
+Type* TypeVariable::resolve(Context* ctx, int ctx_depth) {
+ if (parameter() != NULL) {
+ return parameter()->resolve(ctx, inner_depth(), ctx_depth);
+ } else {
+ if (VerifyGenericSignatures) {
+ fatal("Type variable matches no parameter");
+ }
+ return NULL;
+ }
+}
+
+bool TypeVariable::covariant_match(Type* other, Context* ctx) {
+
+ if (other == this) {
+ return true;
+ }
+
+ Context my_context(NULL); // empty, results in erasure
+ Type* my_type = resolve(&my_context, 0);
+ if (my_type == NULL) {
+ return false;
+ }
+
+ return my_type->covariant_match(other, ctx);
+}
+
+Type* TypeVariable::canonicalize(Context* ctx, int ctx_depth) {
+ return resolve(ctx, ctx_depth);
+}
+
+#ifndef PRODUCT
+void TypeVariable::reify_signature(stringStream* ss, Context* ctx) {
+ Type* type = resolve(ctx, 0);
+ if (type != NULL) {
+ type->reify_signature(ss, ctx);
+ }
+}
+
+void TypeVariable::print_on(outputStream* str) const {
+ str->indent().print_cr("Type Variable {");
+ {
+ streamIndentor si(str);
+ str->indent().print("Name: ");
+ _id->print_on(str);
+ str->print_cr("");
+ str->indent().print_cr("Inner depth: %d", _inner_depth);
+ }
+ str->indent().print_cr("}");
+}
+#endif // ndef PRODUCT
+
+ArrayType* ArrayType::parse_generic_signature(DescriptorStream* STREAM) {
+ Type* base = Type::parse_generic_signature(CHECK_STREAM);
+ return new ArrayType(base);
+}
+
+void ArrayType::bind_variables_to_parameters(Descriptor* sig) {
+ assert(_base != NULL, "Invalid base");
+ _base->bind_variables_to_parameters(sig);
+}
+
+bool ArrayType::covariant_match(Type* other, Context* ctx) {
+ assert(_base != NULL, "Invalid base");
+
+ if (other == this) {
+ return true;
+ }
+
+ ArrayType* other_array = other->as_array();
+ return (other_array != NULL && _base->covariant_match(other_array->_base, ctx));
+}
+
+ArrayType* ArrayType::canonicalize(Context* ctx, int ctx_depth) {
+ assert(_base != NULL, "Invalid base");
+ return new ArrayType(_base->canonicalize(ctx, ctx_depth));
+}
+
+#ifndef PRODUCT
+void ArrayType::reify_signature(stringStream* ss, Context* ctx) {
+ assert(_base != NULL, "Invalid base");
+ ss->print("[");
+ _base->reify_signature(ss, ctx);
+}
+
+void ArrayType::print_on(outputStream* str) const {
+ str->indent().print_cr("Array {");
+ {
+ streamIndentor si(str);
+ _base->print_on(str);
+ }
+ str->indent().print_cr("}");
+}
+#endif // ndef PRODUCT
+
+bool PrimitiveType::covariant_match(Type* other, Context* ctx) {
+
+ PrimitiveType* other_prim = other->as_primitive();
+ return (other_prim != NULL && _type == other_prim->_type);
+}
+
+PrimitiveType* PrimitiveType::canonicalize(Context* ctx, int ctxd) {
+ return this;
+}
+
+#ifndef PRODUCT
+void PrimitiveType::reify_signature(stringStream* ss, Context* ctx) {
+ ss->print("%c", _type);
+}
+
+void PrimitiveType::print_on(outputStream* str) const {
+ str->indent().print_cr("Primitive: '%c'", _type);
+}
+#endif // ndef PRODUCT
+
+void PrimitiveType::bind_variables_to_parameters(Descriptor* sig) {
+}
+
+TypeArgument* TypeArgument::parse_generic_signature(DescriptorStream* STREAM) {
+ char c = READ();
+ Type* type = NULL;
+
+ switch (c) {
+ case '*':
+ return new TypeArgument(ClassType::java_lang_Object(), NULL);
+ break;
+ default:
+ PUSH(c);
+ // fall-through
+ case '+':
+ case '-':
+ type = Type::parse_generic_signature(CHECK_STREAM);
+ if (c == '+') {
+ return new TypeArgument(type, NULL);
+ } else if (c == '-') {
+ return new TypeArgument(ClassType::java_lang_Object(), type);
+ } else {
+ return new TypeArgument(type, type);
+ }
+ }
+}
+
+void TypeArgument::bind_variables_to_parameters(Descriptor* sig) {
+ assert(_lower_bound != NULL, "Invalid lower bound");
+ _lower_bound->bind_variables_to_parameters(sig);
+ if (_upper_bound != NULL && _upper_bound != _lower_bound) {
+ _upper_bound->bind_variables_to_parameters(sig);
+ }
+}
+
+bool TypeArgument::covariant_match(TypeArgument* other, Context* ctx) {
+ assert(_lower_bound != NULL, "Invalid lower bound");
+
+ if (other == this) {
+ return true;
+ }
+
+ if (!_lower_bound->covariant_match(other->lower_bound(), ctx)) {
+ return false;
+ }
+ return true;
+}
+
+TypeArgument* TypeArgument::canonicalize(Context* ctx, int ctx_depth) {
+ assert(_lower_bound != NULL, "Invalid lower bound");
+ Type* lower = _lower_bound->canonicalize(ctx, ctx_depth);
+ Type* upper = NULL;
+
+ if (_upper_bound == _lower_bound) {
+ upper = lower;
+ } else if (_upper_bound != NULL) {
+ upper = _upper_bound->canonicalize(ctx, ctx_depth);
+ }
+
+ return new TypeArgument(lower, upper);
+}
+
+#ifndef PRODUCT
+void TypeArgument::print_on(outputStream* str) const {
+ str->indent().print_cr("TypeArgument {");
+ {
+ streamIndentor si(str);
+ if (_lower_bound != NULL) {
+ str->indent().print("Lower bound: ");
+ _lower_bound->print_on(str);
+ }
+ if (_upper_bound != NULL) {
+ str->indent().print("Upper bound: ");
+ _upper_bound->print_on(str);
+ }
+ }
+ str->indent().print_cr("}");
+}
+#endif // ndef PRODUCT
+
+void Context::Mark::destroy() {
+ if (is_active()) {
+ _context->reset_to_mark(_marked_size);
+ }
+ deactivate();
+}
+
+void Context::apply_type_arguments(
+ InstanceKlass* current, InstanceKlass* super, TRAPS) {
+ assert(_cache != NULL, "Cannot use an empty context");
+ ClassType* spec = NULL;
+ if (current != NULL) {
+ ClassDescriptor* descriptor = _cache->descriptor_for(current, CHECK);
+ if (super == current->super()) {
+ spec = descriptor->super();
+ } else {
+ spec = descriptor->interface_desc(super->name());
+ }
+ if (spec != NULL) {
+ _type_arguments.push(spec);
+ }
+ }
+}
+
+void Context::reset_to_mark(int size) {
+ _type_arguments.trunc_to(size);
+}
+
+ClassType* Context::at_depth(int i) const {
+ if (i < _type_arguments.length()) {
+ return _type_arguments.at(_type_arguments.length() - 1 - i);
+ }
+ return NULL;
+}
+
+#ifndef PRODUCT
+void Context::print_on(outputStream* str) const {
+ str->indent().print_cr("Context {");
+ for (int i = 0; i < _type_arguments.length(); ++i) {
+ streamIndentor si(str);
+ str->indent().print("leval %d: ", i);
+ ClassType* ct = at_depth(i);
+ if (ct == NULL) {
+ str->print_cr("<empty>");
+ continue;
+ } else {
+ str->print_cr("{");
+ }
+
+ for (int j = 0; j < ct->type_arguments_length(); ++j) {
+ streamIndentor si(str);
+ TypeArgument* ta = ct->type_argument_at(j);
+ Type* bound = ta->lower_bound();
+ bound->print_on(str);
+ }
+ str->indent().print_cr("}");
+ }
+ str->indent().print_cr("}");
+}
+#endif // ndef PRODUCT
+
+ClassDescriptor* DescriptorCache::descriptor_for(InstanceKlass* ik, TRAPS) {
+
+ ClassDescriptor** existing = _class_descriptors.get(ik);
+ if (existing == NULL) {
+ ClassDescriptor* cd = ClassDescriptor::parse_generic_signature(ik, CHECK_NULL);
+ _class_descriptors.put(ik, cd);
+ return cd;
+ } else {
+ return *existing;
+ }
+}
+
+MethodDescriptor* DescriptorCache::descriptor_for(
+ Method* mh, ClassDescriptor* cd, TRAPS) {
+ assert(mh != NULL && cd != NULL, "Should not be NULL");
+ MethodDescriptor** existing = _method_descriptors.get(mh);
+ if (existing == NULL) {
+ MethodDescriptor* md = MethodDescriptor::parse_generic_signature(mh, cd);
+ _method_descriptors.put(mh, md);
+ return md;
+ } else {
+ return *existing;
+ }
+}
+MethodDescriptor* DescriptorCache::descriptor_for(Method* mh, TRAPS) {
+ ClassDescriptor* cd = descriptor_for(
+ InstanceKlass::cast(mh->method_holder()), CHECK_NULL);
+ return descriptor_for(mh, cd, THREAD);
+}
+
+} // namespace generic
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/classfile/genericSignatures.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
+#define SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
+
+#include "classfile/symbolTable.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/signature.hpp"
+#include "utilities/growableArray.hpp"
+#include "utilities/resourceHash.hpp"
+
+class stringStream;
+
+namespace generic {
+
+class Identifier;
+class ClassDescriptor;
+class MethodDescriptor;
+
+class TypeParameter; // a formal type parameter declared in generic signatures
+class TypeArgument; // The "type value" passed to fill parameters in supertypes
+class TypeVariable; // A usage of a type parameter as a value
+/**
+ * Example:
+ *
+ * <T, V> class Foo extends Bar<String> { int m(V v) {} }
+ * ^^^^^^ ^^^^^^ ^^
+ * type parameters type argument type variable
+ *
+ * Note that a type variable could be passed as an argument too:
+ * <T, V> class Foo extends Bar<T> { int m(V v) {} }
+ * ^^^
+ * type argument's value is a type variable
+ */
+
+
+class Type;
+class ClassType;
+class ArrayType;
+class PrimitiveType;
+class Context;
+class DescriptorCache;
+
+class DescriptorStream;
+
+class Identifier : public ResourceObj {
+ private:
+ Symbol* _sym;
+ int _begin;
+ int _end;
+
+ public:
+ Identifier(Symbol* sym, int begin, int end) :
+ _sym(sym), _begin(begin), _end(end) {}
+
+ bool equals(Identifier* other);
+ bool equals(Symbol* sym);
+
+#ifndef PRODUCT
+ void print_on(outputStream* str) const;
+#endif // ndef PRODUCT
+};
+
+class Descriptor : public ResourceObj {
+ protected:
+ GrowableArray<TypeParameter*> _type_parameters;
+ ClassDescriptor* _outer_class;
+
+ Descriptor(GrowableArray<TypeParameter*>& params,
+ ClassDescriptor* outer)
+ : _type_parameters(params), _outer_class(outer) {}
+
+ public:
+
+ ClassDescriptor* outer_class() { return _outer_class; }
+ void set_outer_class(ClassDescriptor* sig) { _outer_class = sig; }
+
+ virtual ClassDescriptor* as_class_signature() { return NULL; }
+ virtual MethodDescriptor* as_method_signature() { return NULL; }
+
+ bool is_class_signature() { return as_class_signature() != NULL; }
+ bool is_method_signature() { return as_method_signature() != NULL; }
+
+ GrowableArray<TypeParameter*>& type_parameters() {
+ return _type_parameters;
+ }
+
+ TypeParameter* find_type_parameter(Identifier* id, int* param_depth);
+
+ virtual void bind_variables_to_parameters() = 0;
+
+#ifndef PRODUCT
+ virtual void print_on(outputStream* str) const = 0;
+#endif
+};
+
+class ClassDescriptor : public Descriptor {
+ private:
+ ClassType* _super;
+ GrowableArray<ClassType*> _interfaces;
+ MethodDescriptor* _outer_method;
+
+ ClassDescriptor(GrowableArray<TypeParameter*>& ftp, ClassType* scs,
+ GrowableArray<ClassType*>& sis, ClassDescriptor* outer_class = NULL,
+ MethodDescriptor* outer_method = NULL)
+ : Descriptor(ftp, outer_class), _super(scs), _interfaces(sis),
+ _outer_method(outer_method) {}
+
+ static u2 get_outer_class_index(InstanceKlass* k, TRAPS);
+ static ClassDescriptor* parse_generic_signature(Klass* k, Symbol* original_name, TRAPS);
+
+ public:
+
+ virtual ClassDescriptor* as_class_signature() { return this; }
+
+ MethodDescriptor* outer_method() { return _outer_method; }
+ void set_outer_method(MethodDescriptor* m) { _outer_method = m; }
+
+ ClassType* super() { return _super; }
+ ClassType* interface_desc(Symbol* sym);
+
+ static ClassDescriptor* parse_generic_signature(Klass* k, TRAPS);
+ static ClassDescriptor* parse_generic_signature(Symbol* sym);
+
+ // For use in superclass chains in positions where this is no generic info
+ static ClassDescriptor* placeholder(InstanceKlass* klass);
+
+#ifndef PRODUCT
+ void print_on(outputStream* str) const;
+#endif
+
+ ClassDescriptor* canonicalize(Context* ctx);
+
+ // Linking sets the position index in any contained TypeVariable type
+ // to correspond to the location of that identifier in the formal type
+ // parameters.
+ void bind_variables_to_parameters();
+};
+
+class MethodDescriptor : public Descriptor {
+ private:
+ GrowableArray<Type*> _parameters;
+ Type* _return_type;
+ GrowableArray<Type*> _throws;
+
+ MethodDescriptor(GrowableArray<TypeParameter*>& ftp, ClassDescriptor* outer,
+ GrowableArray<Type*>& sigs, Type* rt, GrowableArray<Type*>& throws)
+ : Descriptor(ftp, outer), _parameters(sigs), _return_type(rt),
+ _throws(throws) {}
+
+ public:
+
+ static MethodDescriptor* parse_generic_signature(Method* m, ClassDescriptor* outer);
+ static MethodDescriptor* parse_generic_signature(Symbol* sym, ClassDescriptor* outer);
+
+ MethodDescriptor* as_method_signature() { return this; }
+
+ // Performs generic analysis on the method parameters to determine
+ // if both methods refer to the same argument types.
+ bool covariant_match(MethodDescriptor* other, Context* ctx);
+
+ // Returns a new method descriptor with all generic variables
+ // removed and replaced with whatever is indicated using the Context.
+ MethodDescriptor* canonicalize(Context* ctx);
+
+ void bind_variables_to_parameters();
+
+#ifndef PRODUCT
+ TempNewSymbol reify_signature(Context* ctx, TRAPS);
+ void print_on(outputStream* str) const;
+#endif
+};
+
+class TypeParameter : public ResourceObj {
+ private:
+ Identifier* _identifier;
+ ClassType* _class_bound;
+ GrowableArray<ClassType*> _interface_bounds;
+
+ // The position is the ordinal location of the parameter within the
+ // formal parameter list (excluding outer classes). It is only set for
+ // formal type parameters that are associated with a class -- method
+ // type parameters are left as -1. When resolving a generic variable to
+ // find the actual type, this index is used to access the generic type
+ // argument in the provided context object.
+ int _position; // Assigned during variable linking
+
+ TypeParameter(Identifier* id, ClassType* class_bound,
+ GrowableArray<ClassType*>& interface_bounds) :
+ _identifier(id), _class_bound(class_bound),
+ _interface_bounds(interface_bounds), _position(-1) {}
+
+ public:
+ static TypeParameter* parse_generic_signature(DescriptorStream* str);
+
+ ClassType* bound();
+ int position() { return _position; }
+
+ void bind_variables_to_parameters(Descriptor* sig, int position);
+ Identifier* identifier() { return _identifier; }
+
+ Type* resolve(Context* ctx, int inner_depth, int ctx_depth);
+ TypeParameter* canonicalize(Context* ctx, int ctx_depth);
+
+#ifndef PRODUCT
+ void print_on(outputStream* str) const;
+#endif
+};
+
+class Type : public ResourceObj {
+ public:
+ static Type* parse_generic_signature(DescriptorStream* str);
+
+ virtual ClassType* as_class() { return NULL; }
+ virtual TypeVariable* as_variable() { return NULL; }
+ virtual ArrayType* as_array() { return NULL; }
+ virtual PrimitiveType* as_primitive() { return NULL; }
+
+ virtual bool covariant_match(Type* gt, Context* ctx) = 0;
+ virtual Type* canonicalize(Context* ctx, int ctx_depth) = 0;
+
+ virtual void bind_variables_to_parameters(Descriptor* sig) = 0;
+
+#ifndef PRODUCT
+ virtual void reify_signature(stringStream* ss, Context* ctx) = 0;
+ virtual void print_on(outputStream* str) const = 0;
+#endif
+};
+
+class ClassType : public Type {
+ friend class ClassDescriptor;
+ protected:
+ Identifier* _identifier;
+ GrowableArray<TypeArgument*> _type_arguments;
+ ClassType* _outer_class;
+
+ ClassType(Identifier* identifier,
+ GrowableArray<TypeArgument*>& args,
+ ClassType* outer)
+ : _identifier(identifier), _type_arguments(args), _outer_class(outer) {}
+
+ // Returns true if there are inner classes to read
+ static Identifier* parse_generic_signature_simple(
+ GrowableArray<TypeArgument*>* args,
+ bool* has_inner, DescriptorStream* str);
+
+ static ClassType* parse_generic_signature(ClassType* outer,
+ DescriptorStream* str);
+ static ClassType* from_symbol(Symbol* sym);
+
+ public:
+ ClassType* as_class() { return this; }
+
+ static ClassType* parse_generic_signature(DescriptorStream* str);
+ static ClassType* java_lang_Object();
+
+ Identifier* identifier() { return _identifier; }
+ int type_arguments_length() { return _type_arguments.length(); }
+ TypeArgument* type_argument_at(int i);
+
+ virtual ClassType* outer_class() { return _outer_class; }
+
+ bool covariant_match(Type* gt, Context* ctx);
+ ClassType* canonicalize(Context* ctx, int context_depth);
+
+ void bind_variables_to_parameters(Descriptor* sig);
+
+#ifndef PRODUCT
+ void reify_signature(stringStream* ss, Context* ctx);
+ void print_on(outputStream* str) const;
+#endif
+};
+
+class TypeVariable : public Type {
+ private:
+ Identifier* _id;
+ TypeParameter* _parameter; // assigned during linking
+
+ // how many steps "out" from inner classes, -1 if method
+ int _inner_depth;
+
+ TypeVariable(Identifier* id)
+ : _id(id), _parameter(NULL), _inner_depth(0) {}
+
+ public:
+ TypeVariable* as_variable() { return this; }
+
+ static TypeVariable* parse_generic_signature(DescriptorStream* str);
+
+ Identifier* identifier() { return _id; }
+ TypeParameter* parameter() { return _parameter; }
+ int inner_depth() { return _inner_depth; }
+
+ void bind_variables_to_parameters(Descriptor* sig);
+
+ Type* resolve(Context* ctx, int ctx_depth);
+ bool covariant_match(Type* gt, Context* ctx);
+ Type* canonicalize(Context* ctx, int ctx_depth);
+
+#ifndef PRODUCT
+ void reify_signature(stringStream* ss, Context* ctx);
+ void print_on(outputStream* str) const;
+#endif
+};
+
+class ArrayType : public Type {
+ private:
+ Type* _base;
+
+ ArrayType(Type* base) : _base(base) {}
+
+ public:
+ ArrayType* as_array() { return this; }
+
+ static ArrayType* parse_generic_signature(DescriptorStream* str);
+
+ bool covariant_match(Type* gt, Context* ctx);
+ ArrayType* canonicalize(Context* ctx, int ctx_depth);
+
+ void bind_variables_to_parameters(Descriptor* sig);
+
+#ifndef PRODUCT
+ void reify_signature(stringStream* ss, Context* ctx);
+ void print_on(outputStream* str) const;
+#endif
+};
+
+class PrimitiveType : public Type {
+ friend class Type;
+ private:
+ char _type; // includes V for void
+
+ PrimitiveType(char& type) : _type(type) {}
+
+ public:
+ PrimitiveType* as_primitive() { return this; }
+
+ bool covariant_match(Type* gt, Context* ctx);
+ PrimitiveType* canonicalize(Context* ctx, int ctx_depth);
+
+ void bind_variables_to_parameters(Descriptor* sig);
+
+#ifndef PRODUCT
+ void reify_signature(stringStream* ss, Context* ctx);
+ void print_on(outputStream* str) const;
+#endif
+};
+
+class TypeArgument : public ResourceObj {
+ private:
+ Type* _lower_bound;
+ Type* _upper_bound; // may be null or == _lower_bound
+
+ TypeArgument(Type* lower_bound, Type* upper_bound)
+ : _lower_bound(lower_bound), _upper_bound(upper_bound) {}
+
+ public:
+
+ static TypeArgument* parse_generic_signature(DescriptorStream* str);
+
+ Type* lower_bound() { return _lower_bound; }
+ Type* upper_bound() { return _upper_bound; }
+
+ void bind_variables_to_parameters(Descriptor* sig);
+ TypeArgument* canonicalize(Context* ctx, int ctx_depth);
+
+ bool covariant_match(TypeArgument* a, Context* ctx);
+
+#ifndef PRODUCT
+ void print_on(outputStream* str) const;
+#endif
+};
+
+
+class Context : public ResourceObj {
+ private:
+ DescriptorCache* _cache;
+ GrowableArray<ClassType*> _type_arguments;
+
+ void reset_to_mark(int size);
+
+ public:
+ // When this object goes out of scope or 'destroy' is
+ // called, then the application of the type to the
+ // context is wound-back (unless it's been deactivated).
+ class Mark : public StackObj {
+ private:
+ mutable Context* _context;
+ int _marked_size;
+
+ bool is_active() const { return _context != NULL; }
+ void deactivate() const { _context = NULL; }
+
+ public:
+ Mark() : _context(NULL), _marked_size(0) {}
+ Mark(Context* ctx, int sz) : _context(ctx), _marked_size(sz) {}
+ Mark(const Mark& m) : _context(m._context), _marked_size(m._marked_size) {
+ m.deactivate(); // Ownership is transferred
+ }
+
+ Mark& operator=(const Mark& cm) {
+ destroy();
+ _context = cm._context;
+ _marked_size = cm._marked_size;
+ cm.deactivate();
+ return *this;
+ }
+
+ void destroy();
+ ~Mark() { destroy(); }
+ };
+
+ Context(DescriptorCache* cache) : _cache(cache) {}
+
+ Mark mark() { return Mark(this, _type_arguments.length()); }
+ void apply_type_arguments(InstanceKlass* current, InstanceKlass* super,TRAPS);
+
+ ClassType* at_depth(int i) const;
+
+#ifndef PRODUCT
+ void print_on(outputStream* str) const;
+#endif
+};
+
+/**
+ * Contains a cache of descriptors for classes and methods so they can be
+ * looked-up instead of reparsing each time they are needed.
+ */
+class DescriptorCache : public ResourceObj {
+ private:
+ ResourceHashtable<InstanceKlass*, ClassDescriptor*> _class_descriptors;
+ ResourceHashtable<Method*, MethodDescriptor*> _method_descriptors;
+
+ public:
+ ClassDescriptor* descriptor_for(InstanceKlass* ikh, TRAPS);
+
+ MethodDescriptor* descriptor_for(Method* mh, ClassDescriptor* cd, TRAPS);
+ // Class descriptor derived from method holder
+ MethodDescriptor* descriptor_for(Method* mh, TRAPS);
+};
+
+} // namespace generic
+
+#endif // SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP
+
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -348,6 +348,22 @@
return java_lang_String::to_hash(value->char_at_addr(offset), length);
}
+char* java_lang_String::as_quoted_ascii(oop java_string) {
+ typeArrayOop value = java_lang_String::value(java_string);
+ int offset = java_lang_String::offset(java_string);
+ int length = java_lang_String::length(java_string);
+
+ jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
+ if (base == NULL) return NULL;
+
+ int result_length = UNICODE::quoted_ascii_length(base, length) + 1;
+ char* result = NEW_RESOURCE_ARRAY(char, result_length);
+ UNICODE::as_quoted_ascii(base, length, result, result_length);
+ assert(result_length >= length + 1, "must not be shorter");
+ assert(result_length == (int)strlen(result) + 1, "must match");
+ return result;
+}
+
unsigned int java_lang_String::hash_string(oop java_string) {
int length = java_lang_String::length(java_string);
// Zero length string doesn't hash necessarily hash to zero.
@@ -545,7 +561,7 @@
assert(k->oop_is_objArray(), "Must be");
Klass* element_klass = ObjArrayKlass::cast(k())->element_klass();
assert(element_klass != NULL, "Must have an element klass");
- comp_mirror = Klass::cast(element_klass)->java_mirror();
+ comp_mirror = element_klass->java_mirror();
}
assert(comp_mirror.not_null(), "must have a mirror");
@@ -628,8 +644,8 @@
name = vmSymbols::type_signature(primitive_type(java_class));
} else {
Klass* k = as_Klass(java_class);
- is_instance = Klass::cast(k)->oop_is_instance();
- name = Klass::cast(k)->name();
+ is_instance = k->oop_is_instance();
+ name = k->name();
}
if (name == NULL) {
st->print("<null>");
@@ -651,12 +667,12 @@
name->increment_refcount();
} else {
Klass* k = as_Klass(java_class);
- if (!Klass::cast(k)->oop_is_instance()) {
- name = Klass::cast(k)->name();
+ if (!k->oop_is_instance()) {
+ name = k->name();
name->increment_refcount();
} else {
ResourceMark rm;
- const char* sigstr = Klass::cast(k)->signature_name();
+ const char* sigstr = k->signature_name();
int siglen = (int) strlen(sigstr);
if (!intern_if_not_found) {
name = SymbolTable::probe(sigstr, siglen);
@@ -671,13 +687,13 @@
Klass* java_lang_Class::array_klass(oop java_class) {
Klass* k = ((Klass*)java_class->metadata_field(_array_klass_offset));
- assert(k == NULL || k->is_klass() && Klass::cast(k)->oop_is_array(), "should be array klass");
+ assert(k == NULL || k->is_klass() && k->oop_is_array(), "should be array klass");
return k;
}
void java_lang_Class::set_array_klass(oop java_class, Klass* klass) {
- assert(klass->is_klass() && Klass::cast(klass)->oop_is_array(), "should be array klass");
+ assert(klass->is_klass() && klass->oop_is_array(), "should be array klass");
java_class->metadata_field_put(_array_klass_offset, klass);
}
@@ -1156,7 +1172,7 @@
// Print stack trace element to resource allocated buffer
char* java_lang_Throwable::print_stack_element_to_buffer(Method* method, int bci) {
// Get strings and string lengths
- InstanceKlass* klass = InstanceKlass::cast(method->method_holder());
+ InstanceKlass* klass = method->method_holder();
const char* klass_name = klass->external_name();
int buf_len = (int)strlen(klass_name);
char* source_file_name;
@@ -1747,14 +1763,14 @@
Handle element = ik->allocate_instance_handle(CHECK_0);
// Fill in class name
ResourceMark rm(THREAD);
- const char* str = InstanceKlass::cast(method->method_holder())->external_name();
+ const char* str = method->method_holder()->external_name();
oop classname = StringTable::intern((char*) str, CHECK_0);
java_lang_StackTraceElement::set_declaringClass(element(), classname);
// Fill in method name
oop methodname = StringTable::intern(method->name(), CHECK_0);
java_lang_StackTraceElement::set_methodName(element(), methodname);
// Fill in source file name
- Symbol* source = InstanceKlass::cast(method->method_holder())->source_file_name();
+ Symbol* source = method->method_holder()->source_file_name();
if (ShowHiddenFrames && source == NULL)
source = vmSymbols::unknown_class_name();
oop filename = StringTable::intern(source, CHECK_0);
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -154,6 +154,8 @@
static char* as_utf8_string(oop java_string, int start, int len);
static char* as_platform_dependent_str(Handle java_string, TRAPS);
static jchar* as_unicode_string(oop java_string, int& length);
+ // produce an ascii string with all other values quoted using \u####
+ static char* as_quoted_ascii(oop java_string);
// Compute the hash value for a java.lang.String object which would
// contain the characters passed in.
@@ -912,7 +914,7 @@
// Testers
static bool is_subclass(Klass* klass) {
- return Klass::cast(klass)->is_subclass_of(SystemDictionary::MethodHandle_klass());
+ return klass->is_subclass_of(SystemDictionary::MethodHandle_klass());
}
static bool is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
@@ -942,7 +944,7 @@
// Testers
static bool is_subclass(Klass* klass) {
return SystemDictionary::LambdaForm_klass() != NULL &&
- Klass::cast(klass)->is_subclass_of(SystemDictionary::LambdaForm_klass());
+ klass->is_subclass_of(SystemDictionary::LambdaForm_klass());
}
static bool is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
@@ -1004,7 +1006,7 @@
// Testers
static bool is_subclass(Klass* klass) {
- return Klass::cast(klass)->is_subclass_of(SystemDictionary::MemberName_klass());
+ return klass->is_subclass_of(SystemDictionary::MemberName_klass());
}
static bool is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
@@ -1090,7 +1092,7 @@
// Testers
static bool is_subclass(Klass* klass) {
- return Klass::cast(klass)->is_subclass_of(SystemDictionary::CallSite_klass());
+ return klass->is_subclass_of(SystemDictionary::CallSite_klass());
}
static bool is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
@@ -1160,7 +1162,7 @@
// Testers
static bool is_subclass(Klass* klass) {
- return Klass::cast(klass)->is_subclass_of(SystemDictionary::ClassLoader_klass());
+ return klass->is_subclass_of(SystemDictionary::ClassLoader_klass());
}
static bool is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
--- a/hotspot/src/share/vm/classfile/loaderConstraints.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/loaderConstraints.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -320,7 +320,7 @@
Handle loader) {
LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
if (p != NULL && p->klass() != NULL) {
- if (Klass::cast(p->klass())->oop_is_instance() && !InstanceKlass::cast(p->klass())->is_loaded()) {
+ if (p->klass()->oop_is_instance() && !InstanceKlass::cast(p->klass())->is_loaded()) {
// Only return fully loaded classes. Classes found through the
// constraints might still be in the process of loading.
return NULL;
--- a/hotspot/src/share/vm/classfile/placeholders.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/placeholders.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -45,7 +45,7 @@
entry->set_loadInstanceThreadQ(NULL);
entry->set_defineThreadQ(NULL);
entry->set_definer(NULL);
- entry->set_instanceKlass(NULL);
+ entry->set_instance_klass(NULL);
return entry;
}
@@ -188,7 +188,7 @@
void PlaceholderEntry::classes_do(KlassClosure* closure) {
assert(klassname() != NULL, "should have a non-null klass");
if (_instanceKlass != NULL) {
- closure->do_klass(InstanceKlass());
+ closure->do_klass(instance_klass());
}
}
@@ -220,9 +220,9 @@
tty->print(", definer ");
definer()->print_value();
}
- if (InstanceKlass() != NULL) {
+ if (instance_klass() != NULL) {
tty->print(", InstanceKlass ");
- InstanceKlass()->print_value();
+ instance_klass()->print_value();
}
tty->print("\n");
tty->print("loadInstanceThreadQ threads:");
@@ -241,9 +241,9 @@
guarantee(loader_data() != NULL, "Must have been setup.");
guarantee(loader_data()->class_loader() == NULL || loader_data()->class_loader()->is_instance(),
"checking type of _loader");
- guarantee(InstanceKlass() == NULL
- || Klass::cast(InstanceKlass())->oop_is_instance(),
- "checking type of InstanceKlass result");
+ guarantee(instance_klass() == NULL
+ || instance_klass()->oop_is_instance(),
+ "checking type of instance_klass result");
}
void PlaceholderTable::verify() {
--- a/hotspot/src/share/vm/classfile/placeholders.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/placeholders.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -191,8 +191,8 @@
Thread* definer() const {return _definer; }
void set_definer(Thread* definer) { _definer = definer; }
- Klass* InstanceKlass() const {return _instanceKlass; }
- void set_instanceKlass(Klass* InstanceKlass) { _instanceKlass = InstanceKlass; }
+ Klass* instance_klass() const {return _instanceKlass; }
+ void set_instance_klass(Klass* ik) { _instanceKlass = ik; }
SeenThread* superThreadQ() const { return _superThreadQ; }
void set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; }
--- a/hotspot/src/share/vm/classfile/symbolTable.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/symbolTable.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -262,19 +262,14 @@
// The string table
static StringTable* the_table() { return _the_table; }
+ // Size of one bucket in the string table. Used when checking for rollover.
+ static uint bucket_size() { return sizeof(HashtableBucket<mtSymbol>); }
+
static void create_table() {
assert(_the_table == NULL, "One string table allowed.");
_the_table = new StringTable();
}
- static void create_table(HashtableBucket<mtSymbol>* t, int length,
- int number_of_entries) {
- assert(_the_table == NULL, "One string table allowed.");
- assert((size_t)length == StringTableSize * sizeof(HashtableBucket<mtSymbol>),
- "bad shared string size.");
- _the_table = new StringTable(t, number_of_entries);
- }
-
// GC support
// Delete pointers to otherwise-unreachable objects.
static void unlink(BoolObjectClosure* cl);
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -240,7 +240,7 @@
protection_domain,
CHECK_NULL);
if (k != NULL) {
- k = Klass::cast(k)->array_klass(fd.dimension(), CHECK_NULL);
+ k = k->array_klass(fd.dimension(), CHECK_NULL);
}
} else {
k = Universe::typeArrayKlassObj(t);
@@ -328,8 +328,8 @@
if ((childk != NULL ) && (is_superclass) &&
((quicksuperk = InstanceKlass::cast(childk)->super()) != NULL) &&
- ((Klass::cast(quicksuperk)->name() == class_name) &&
- (Klass::cast(quicksuperk)->class_loader() == class_loader()))) {
+ ((quicksuperk->name() == class_name) &&
+ (quicksuperk->class_loader() == class_loader()))) {
return quicksuperk;
} else {
PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, child_name, loader_data);
@@ -928,7 +928,7 @@
k = SystemDictionary::find(fd.object_key(), class_loader, protection_domain, THREAD);
}
if (k != NULL) {
- k = Klass::cast(k)->array_klass_or_null(fd.dimension());
+ k = k->array_klass_or_null(fd.dimension());
}
} else {
k = find(class_name, class_loader, protection_domain, THREAD);
@@ -1537,7 +1537,7 @@
// Only special cases allow parallel defines and can use other thread's results
// Other cases fall through, and may run into duplicate defines
// caught by finding an entry in the SystemDictionary
- if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->InstanceKlass() != NULL)) {
+ if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) {
probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, THREAD);
SystemDictionary_lock->notify_all();
@@ -1545,7 +1545,7 @@
Klass* check = find_class(d_index, d_hash, name_h, loader_data);
assert(check != NULL, "definer missed recording success");
#endif
- return(instanceKlassHandle(THREAD, probe->InstanceKlass()));
+ return(instanceKlassHandle(THREAD, probe->instance_klass()));
} else {
// This thread will define the class (even if earlier thread tried and had an error)
probe->set_definer(THREAD);
@@ -1566,7 +1566,7 @@
linkage_exception = Handle(THREAD,PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
} else {
- probe->set_instanceKlass(k());
+ probe->set_instance_klass(k());
}
probe->set_definer(NULL);
probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
@@ -2149,7 +2149,7 @@
}
// If element class already loaded, allocate array klass
if (klass != NULL) {
- klass = Klass::cast(klass)->array_klass_or_null(fd.dimension());
+ klass = klass->array_klass_or_null(fd.dimension());
}
} else {
MutexLocker mu(SystemDictionary_lock, THREAD);
@@ -2466,9 +2466,9 @@
Klass* sel_klass = java_lang_Class::as_Klass(mirror);
mirror = NULL; // safety
// Emulate ConstantPool::verify_constant_pool_resolve.
- if (Klass::cast(sel_klass)->oop_is_objArray())
+ if (sel_klass->oop_is_objArray())
sel_klass = ObjArrayKlass::cast(sel_klass)->bottom_klass();
- if (Klass::cast(sel_klass)->oop_is_instance()) {
+ if (sel_klass->oop_is_instance()) {
KlassHandle sel_kh(THREAD, sel_klass);
LinkResolver::check_klass_accessability(accessing_klass, sel_kh, CHECK_(empty));
}
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -137,6 +137,7 @@
/* NOTE: needed too early in bootstrapping process to have checks based on JDK version */ \
/* Universe::is_gte_jdk14x_version() is not set up by this point. */ \
/* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \
+ do_klass(lambda_MagicLambdaImpl_klass, java_lang_invoke_MagicLambdaImpl, Opt ) \
do_klass(reflect_MagicAccessorImpl_klass, sun_reflect_MagicAccessorImpl, Opt ) \
do_klass(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \
do_klass(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \
--- a/hotspot/src/share/vm/classfile/verifier.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -446,7 +446,7 @@
bytecode_name = "<illegal>";
}
}
- InstanceKlass* ik = InstanceKlass::cast(method->method_holder());
+ InstanceKlass* ik = method->method_holder();
ss->indent().print_cr("Location:");
streamIndentor si2(ss);
ss->indent().print_cr("%s.%s%s @%d: %s",
@@ -555,9 +555,10 @@
if (was_recursively_verified()) return;
Method* m = methods->at(index);
- if (m->is_native() || m->is_abstract()) {
+ if (m->is_native() || m->is_abstract() || m->is_overpass()) {
// If m is native or abstract, skip it. It is checked in class file
- // parser that methods do not override a final method.
+ // parser that methods do not override a final method. Overpass methods
+ // are trusted since the VM generates them.
continue;
}
verify_method(methodHandle(THREAD, m), CHECK_VERIFY(this));
@@ -1849,7 +1850,7 @@
if ((index <= 0) || (index >= nconstants)) {
verify_error(ErrorContext::bad_cp_index(bci, index),
"Illegal constant pool index %d in class %s",
- index, InstanceKlass::cast(cp->pool_holder())->external_name());
+ index, cp->pool_holder()->external_name());
return;
}
}
@@ -1868,7 +1869,7 @@
if ((types & (1 << tag)) == 0) {
verify_error(ErrorContext::bad_cp_index(bci, index),
"Illegal type at constant pool entry %d in class %s",
- index, InstanceKlass::cast(cp->pool_holder())->external_name());
+ index, cp->pool_holder()->external_name());
return;
}
}
@@ -1880,7 +1881,7 @@
if (!tag.is_klass() && !tag.is_unresolved_klass()) {
verify_error(ErrorContext::bad_cp_index(bci, index),
"Illegal type at constant pool entry %d in class %s",
- index, InstanceKlass::cast(cp->pool_holder())->external_name());
+ index, cp->pool_holder()->external_name());
return;
}
}
@@ -2304,11 +2305,21 @@
// Make sure the constant pool item is the right type
u2 index = bcs->get_index_u2();
Bytecodes::Code opcode = bcs->raw_code();
- unsigned int types = (opcode == Bytecodes::_invokeinterface
- ? 1 << JVM_CONSTANT_InterfaceMethodref
- : opcode == Bytecodes::_invokedynamic
- ? 1 << JVM_CONSTANT_InvokeDynamic
- : 1 << JVM_CONSTANT_Methodref);
+ unsigned int types;
+ switch (opcode) {
+ case Bytecodes::_invokeinterface:
+ types = 1 << JVM_CONSTANT_InterfaceMethodref;
+ break;
+ case Bytecodes::_invokedynamic:
+ types = 1 << JVM_CONSTANT_InvokeDynamic;
+ break;
+ case Bytecodes::_invokespecial:
+ types = (1 << JVM_CONSTANT_InterfaceMethodref) |
+ (1 << JVM_CONSTANT_Methodref);
+ break;
+ default:
+ types = 1 << JVM_CONSTANT_Methodref;
+ }
verify_cp_type(bcs->bci(), index, cp, types, CHECK_VERIFY(this));
// Get method name and signature
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -507,7 +507,7 @@
}
void vmIntrinsics::verify_method(ID actual_id, Method* m) {
- Symbol* mk = Klass::cast(m->method_holder())->name();
+ Symbol* mk = m->method_holder()->name();
ID declared_id = match_method_with_klass(m, mk);
if (declared_id == actual_id) return; // success
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -259,6 +259,7 @@
template(java_lang_invoke_DontInline_signature, "Ljava/lang/invoke/DontInline;") \
template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \
+ template(java_lang_invoke_MagicLambdaImpl, "java/lang/invoke/MagicLambdaImpl") \
/* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */ \
template(findMethodHandleType_name, "findMethodHandleType") \
template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \
--- a/hotspot/src/share/vm/code/compiledIC.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/code/compiledIC.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -191,8 +191,8 @@
int index = klassItable::compute_itable_index(call_info->resolved_method()());
entry = VtableStubs::create_stub(false, index, method());
assert(entry != NULL, "entry not computed");
- Klass* k = call_info->resolved_method()->method_holder();
- assert(Klass::cast(k)->is_interface(), "sanity check");
+ InstanceKlass* k = call_info->resolved_method()->method_holder();
+ assert(k->is_interface(), "sanity check");
InlineCacheBuffer::create_transition_stub(this, k, entry);
} else {
// Can be different than method->vtable_index(), due to package-private etc.
--- a/hotspot/src/share/vm/code/dependencies.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/code/dependencies.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -552,7 +552,7 @@
}
tty->print(" %s = %s", what, (put_star? "*": ""));
if (arg.is_klass())
- tty->print("%s", Klass::cast((Klass*)arg.metadata_value())->external_name());
+ tty->print("%s", ((Klass*)arg.metadata_value())->external_name());
else if (arg.is_method())
((Method*)arg.metadata_value())->print_value();
else
@@ -563,12 +563,13 @@
bool put_star = !Dependencies::is_concrete_klass(witness);
tty->print_cr(" witness = %s%s",
(put_star? "*": ""),
- Klass::cast(witness)->external_name());
+ witness->external_name());
}
}
void Dependencies::DepStream::log_dependency(Klass* witness) {
if (_deps == NULL && xtty == NULL) return; // fast cutout for runtime
+ ResourceMark rm;
int nargs = argument_count();
DepArgument args[max_arg_count];
for (int j = 0; j < nargs; j++) {
@@ -808,7 +809,7 @@
if (!(m->is_public() || m->is_protected()))
// The override story is complex when packages get involved.
return true; // Must punt the assertion to true.
- Klass* k = Klass::cast(ctxk);
+ Klass* k = ctxk;
Method* lm = k->lookup_method(m->name(), m->signature());
if (lm == NULL && k->oop_is_instance()) {
// It might be an abstract interface method, devoid of mirandas.
@@ -829,13 +830,13 @@
}
if ( !Dependencies::is_concrete_method(lm)
&& !Dependencies::is_concrete_method(m)
- && Klass::cast(lm->method_holder())->is_subtype_of(m->method_holder()))
+ && lm->method_holder()->is_subtype_of(m->method_holder()))
// Method m is overridden by lm, but both are non-concrete.
return true;
}
ResourceMark rm;
tty->print_cr("Dependency method not found in the associated context:");
- tty->print_cr(" context = %s", Klass::cast(ctxk)->external_name());
+ tty->print_cr(" context = %s", ctxk->external_name());
tty->print( " method = "); m->print_short_name(tty); tty->cr();
if (lm != NULL) {
tty->print( " found = "); lm->print_short_name(tty); tty->cr();
@@ -1010,7 +1011,7 @@
for (int i = 0; i < num_participants(); i++) {
Klass* part = participant(i);
if (part == NULL) continue;
- assert(changes.involves_context(part) == Klass::cast(new_type)->is_subtype_of(part),
+ assert(changes.involves_context(part) == new_type->is_subtype_of(part),
"correct marking of participants, b/c new_type is unique");
if (changes.involves_context(part)) {
// new guy is protected from this check by previous participant
@@ -1146,7 +1147,7 @@
bool Dependencies::is_concrete_klass(Klass* k) {
- if (Klass::cast(k)->is_abstract()) return false;
+ if (k->is_abstract()) return false;
// %%% We could treat classes which are concrete but
// have not yet been instantiated as virtually abstract.
// This would require a deoptimization barrier on first instantiation.
@@ -1160,7 +1161,11 @@
// We could also return false if m does not yet appear to be
// executed, if the VM version supports this distinction also.
- return !m->is_abstract();
+ return !m->is_abstract() &&
+ !InstanceKlass::cast(m->method_holder())->is_interface();
+ // TODO: investigate whether default methods should be
+ // considered as "concrete" in this situation. For now they
+ // are not.
}
@@ -1701,12 +1706,12 @@
}
bool KlassDepChange::involves_context(Klass* k) {
- if (k == NULL || !Klass::cast(k)->oop_is_instance()) {
+ if (k == NULL || !k->oop_is_instance()) {
return false;
}
InstanceKlass* ik = InstanceKlass::cast(k);
bool is_contained = ik->is_marked_dependent();
- assert(is_contained == Klass::cast(new_type())->is_subtype_of(k),
+ assert(is_contained == new_type()->is_subtype_of(k),
"correct marking of potential context types");
return is_contained;
}
--- a/hotspot/src/share/vm/code/nmethod.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/code/nmethod.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1263,7 +1263,7 @@
assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod");
// Remove from list of active nmethods
if (method() != NULL)
- InstanceKlass::cast(method()->method_holder())->remove_osr_nmethod(this);
+ method()->method_holder()->remove_osr_nmethod(this);
// Set entry as invalid
_entry_bci = InvalidOSREntryBci;
}
@@ -2568,9 +2568,8 @@
deps.print_dependency();
Klass* ctxk = deps.context_type();
if (ctxk != NULL) {
- Klass* k = Klass::cast(ctxk);
- if (k->oop_is_instance() && ((InstanceKlass*)k)->is_dependent_nmethod(this)) {
- tty->print_cr(" [nmethod<=klass]%s", k->external_name());
+ if (ctxk->oop_is_instance() && ((InstanceKlass*)ctxk)->is_dependent_nmethod(this)) {
+ tty->print_cr(" [nmethod<=klass]%s", ctxk->external_name());
}
}
deps.log_dependency(); // put it into the xml log also
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1051,7 +1051,7 @@
guarantee(!method->is_abstract(), "cannot compile abstract methods");
assert(method->method_holder()->oop_is_instance(),
"sanity check");
- assert(!InstanceKlass::cast(method->method_holder())->is_not_initialized(),
+ assert(!method->method_holder()->is_not_initialized(),
"method holder must be initialized");
assert(!method->is_method_handle_intrinsic(), "do not enqueue these guys");
@@ -1206,7 +1206,7 @@
assert(method->method_holder()->oop_is_instance(), "not an instance method");
assert(osr_bci == InvocationEntryBci || (0 <= osr_bci && osr_bci < method->code_size()), "bci out of range");
assert(!method->is_abstract() && (osr_bci == InvocationEntryBci || !method->is_native()), "cannot compile abstract/native methods");
- assert(!InstanceKlass::cast(method->method_holder())->is_not_initialized(), "method holder must be initialized");
+ assert(!method->method_holder()->is_not_initialized(), "method holder must be initialized");
if (!TieredCompilation) {
comp_level = CompLevel_highest_tier;
--- a/hotspot/src/share/vm/compiler/compilerOracle.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -67,7 +67,7 @@
// utility method
MethodMatcher* find(methodHandle method) {
- Symbol* class_name = Klass::cast(method->method_holder())->name();
+ Symbol* class_name = method->method_holder()->name();
Symbol* method_name = method->name();
for (MethodMatcher* current = this; current != NULL; current = current->_next) {
if (match(class_name, current->class_name(), current->_class_mode) &&
@@ -624,7 +624,7 @@
assert(has_command_file(), "command file must be specified");
fileStream stream(fopen(cc_file(), "at"));
stream.print("exclude ");
- Klass::cast(method->method_holder())->name()->print_symbol_on(&stream);
+ method->method_holder()->name()->print_symbol_on(&stream);
stream.print(".");
method->name()->print_symbol_on(&stream);
method->signature()->print_symbol_on(&stream);
--- a/hotspot/src/share/vm/compiler/disassembler.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -55,16 +55,18 @@
bool Disassembler::_tried_to_load_library = false;
// This routine is in the shared library:
+Disassembler::decode_func_virtual Disassembler::_decode_instructions_virtual = NULL;
Disassembler::decode_func Disassembler::_decode_instructions = NULL;
static const char hsdis_library_name[] = "hsdis-"HOTSPOT_LIB_ARCH;
-static const char decode_instructions_name[] = "decode_instructions_virtual";
-
+static const char decode_instructions_virtual_name[] = "decode_instructions_virtual";
+static const char decode_instructions_name[] = "decode_instructions";
+static bool use_new_version = true;
#define COMMENT_COLUMN 40 LP64_ONLY(+8) /*could be an option*/
#define BYTES_COMMENT ";..." /* funky byte display comment */
bool Disassembler::load_library() {
- if (_decode_instructions != NULL) {
+ if (_decode_instructions_virtual != NULL || _decode_instructions != NULL) {
// Already succeeded.
return true;
}
@@ -123,11 +125,19 @@
_library = os::dll_load(buf, ebuf, sizeof ebuf);
}
if (_library != NULL) {
+ _decode_instructions_virtual = CAST_TO_FN_PTR(Disassembler::decode_func_virtual,
+ os::dll_lookup(_library, decode_instructions_virtual_name));
+ }
+ if (_decode_instructions_virtual == NULL) {
+ // could not spot in new version, try old version
_decode_instructions = CAST_TO_FN_PTR(Disassembler::decode_func,
os::dll_lookup(_library, decode_instructions_name));
+ use_new_version = false;
+ } else {
+ use_new_version = true;
}
_tried_to_load_library = true;
- if (_decode_instructions == NULL) {
+ if (_decode_instructions_virtual == NULL && _decode_instructions == NULL) {
tty->print_cr("Could not load %s; %s; %s", buf,
((_library != NULL)
? "entry point is missing"
@@ -343,7 +353,7 @@
obj->print_value_on(st);
if (st->count() == c) {
// No output. (Can happen in product builds.)
- st->print("(a %s)", Klass::cast(obj->klass())->external_name());
+ st->print("(a %s)", obj->klass()->external_name());
}
return;
}
@@ -450,17 +460,31 @@
// This is mainly for debugging the library itself.
FILE* out = stdout;
FILE* xmlout = (_print_raw > 1 ? out : NULL);
- return (address)
- (*Disassembler::_decode_instructions)((uintptr_t)start, (uintptr_t)end,
- start, end - start,
+ return use_new_version ?
+ (address)
+ (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end,
+ start, end - start,
+ NULL, (void*) xmlout,
+ NULL, (void*) out,
+ options(), 0/*nice new line*/)
+ :
+ (address)
+ (*Disassembler::_decode_instructions)(start, end,
NULL, (void*) xmlout,
NULL, (void*) out,
options());
}
- return (address)
- (*Disassembler::_decode_instructions)((uintptr_t)start, (uintptr_t)end,
- start, end - start,
+ return use_new_version ?
+ (address)
+ (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end,
+ start, end - start,
+ &event_to_env, (void*) this,
+ &printf_to_env, (void*) this,
+ options(), 0/*nice new line*/)
+ :
+ (address)
+ (*Disassembler::_decode_instructions)(start, end,
&event_to_env, (void*) this,
&printf_to_env, (void*) this,
options());
--- a/hotspot/src/share/vm/compiler/disassembler.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/compiler/disassembler.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -49,18 +49,27 @@
friend class decode_env;
private:
// this is the type of the dll entry point:
- typedef void* (*decode_func)(uintptr_t start_va, uintptr_t end_va,
+ typedef void* (*decode_func_virtual)(uintptr_t start_va, uintptr_t end_va,
unsigned char* buffer, uintptr_t length,
void* (*event_callback)(void*, const char*, void*),
void* event_stream,
int (*printf_callback)(void*, const char*, ...),
void* printf_stream,
+ const char* options,
+ int newline);
+ // this is the type of the dll entry point for old version:
+ typedef void* (*decode_func)(void* start_va, void* end_va,
+ void* (*event_callback)(void*, const char*, void*),
+ void* event_stream,
+ int (*printf_callback)(void*, const char*, ...),
+ void* printf_stream,
const char* options);
// points to the library.
static void* _library;
// bailout
static bool _tried_to_load_library;
// points to the decode function.
+ static decode_func_virtual _decode_instructions_virtual;
static decode_func _decode_instructions;
// tries to load library and return whether it succedded.
static bool load_library();
@@ -85,7 +94,9 @@
public:
static bool can_decode() {
- return (_decode_instructions != NULL) || load_library();
+ return (_decode_instructions_virtual != NULL) ||
+ (_decode_instructions != NULL) ||
+ load_library();
}
static void decode(CodeBlob *cb, outputStream* st = NULL);
static void decode(nmethod* nm, outputStream* st = NULL);
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -2043,8 +2043,8 @@
if (objKlassOop != klassOf &&
!objKlassOop->is_subtype_of(klassOf)) {
ResourceMark rm(THREAD);
- const char* objName = Klass::cast(objKlassOop)->external_name();
- const char* klassName = Klass::cast(klassOf)->external_name();
+ const char* objName = objKlassOop->external_name();
+ const char* klassName = klassOf->external_name();
char* message = SharedRuntime::generate_class_cast_message(
objName, klassName);
VM_JAVA_ERROR(vmSymbols::java_lang_ClassCastException(), message);
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -312,7 +312,7 @@
IRT_ENTRY(void, InterpreterRuntime::create_klass_exception(JavaThread* thread, char* name, oopDesc* obj))
ResourceMark rm(thread);
- const char* klass_name = Klass::cast(obj->klass())->external_name();
+ const char* klass_name = obj->klass()->external_name();
// lookup exception klass
TempNewSymbol s = SymbolTable::new_symbol(name, CHECK);
if (ProfileTraps) {
@@ -341,7 +341,7 @@
ResourceMark rm(thread);
char* message = SharedRuntime::generate_class_cast_message(
- thread, Klass::cast(obj->klass())->external_name());
+ thread, obj->klass()->external_name());
if (ProfileTraps) {
note_trap(thread, Deoptimization::Reason_class_check, CHECK);
@@ -733,12 +733,7 @@
get_index_u2_cpcache(thread, bytecode), bytecode, CHECK);
} // end JvmtiHideSingleStepping
- cache_entry(thread)->set_method_handle(
- pool,
- info.resolved_method(),
- info.resolved_appendix(),
- info.resolved_method_type(),
- pool->resolved_references());
+ cache_entry(thread)->set_method_handle(pool, info);
}
IRT_END
@@ -762,12 +757,7 @@
} // end JvmtiHideSingleStepping
ConstantPoolCacheEntry* cp_cache_entry = pool->invokedynamic_cp_cache_entry_at(index);
- cp_cache_entry->set_dynamic_call(
- pool,
- info.resolved_method(),
- info.resolved_appendix(),
- info.resolved_method_type(),
- pool->resolved_references());
+ cp_cache_entry->set_dynamic_call(pool, info);
}
IRT_END
--- a/hotspot/src/share/vm/interpreter/invocationCounter.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/interpreter/invocationCounter.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -40,6 +40,7 @@
class InvocationCounter VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
+ friend class ciReplay;
private: // bit no: |31 3| 2 | 1 0 |
unsigned int _counter; // format: [count|carry|state]
@@ -85,6 +86,8 @@
void set_carry(); // set the sticky carry bit
void set_carry_flag() { _counter |= carry_mask; }
+ int raw_counter() { return _counter; }
+
// Accessors
State state() const { return (State)(_counter & state_mask); }
bool carry() const { return (_counter & carry_mask) != 0; }
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "classfile/defaultMethods.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "compiler/compileBroker.hpp"
@@ -132,7 +133,7 @@
// don't force compilation, resolve was on behalf of compiler
return;
}
- if (InstanceKlass::cast(selected_method->method_holder())->is_not_initialized()) {
+ if (selected_method->method_holder()->is_not_initialized()) {
// 'is_not_initialized' means not only '!is_initialized', but also that
// initialization has not been started yet ('!being_initialized')
// Do not force compilation of methods in uninitialized classes.
@@ -202,7 +203,7 @@
Method* result_oop = klass->uncached_lookup_method(name, signature);
result = methodHandle(THREAD, result_oop);
while (!result.is_null() && result->is_static()) {
- klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super());
+ klass = KlassHandle(THREAD, result->method_holder()->super());
result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature));
}
}
@@ -404,21 +405,13 @@
Symbol* method_name, Symbol* method_signature,
KlassHandle current_klass, bool check_access, TRAPS) {
- // 1. check if klass is not interface
- if (resolved_klass->is_interface()) {
- ResourceMark rm(THREAD);
- char buf[200];
- jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", Klass::cast(resolved_klass())->external_name());
- THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
- }
-
Handle nested_exception;
- // 2. lookup method in resolved klass and its super klasses
+ // 1. lookup method in resolved klass and its super klasses
lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
if (resolved_method.is_null()) { // not found in the class hierarchy
- // 3. lookup method in all the interfaces implemented by the resolved klass
+ // 2. lookup method in all the interfaces implemented by the resolved klass
lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
if (resolved_method.is_null()) {
@@ -432,21 +425,30 @@
}
if (resolved_method.is_null()) {
- // 4. method lookup failed
+ // 3. method lookup failed
ResourceMark rm(THREAD);
THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
- Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
+ Method::name_and_sig_as_C_string(resolved_klass(),
method_name,
method_signature),
nested_exception);
}
}
+ // 4. check if klass is not interface
+ if (resolved_klass->is_interface() && resolved_method->is_abstract()) {
+ ResourceMark rm(THREAD);
+ char buf[200];
+ jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
+ resolved_klass()->external_name());
+ THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
+ }
+
// 5. check if method is concrete
if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
- Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
+ Method::name_and_sig_as_C_string(resolved_klass(),
method_name,
method_signature));
}
@@ -464,7 +466,7 @@
// check loader constraints
Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
- Handle class_loader (THREAD, InstanceKlass::cast(resolved_method->method_holder())->class_loader());
+ Handle class_loader (THREAD, resolved_method->method_holder()->class_loader());
{
ResourceMark rm(THREAD);
char* failed_type_name =
@@ -475,7 +477,7 @@
" \"%s\" the class loader (instance of %s) of the current class, %s,"
" and the class loader (instance of %s) for resolved class, %s, have"
" different Class objects for the type %s used in the signature";
- char* sig = Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature);
+ char* sig = Method::name_and_sig_as_C_string(resolved_klass(),method_name,method_signature);
const char* loader1 = SystemDictionary::loader_name(loader());
char* current = InstanceKlass::cast(current_klass())->name()->as_C_string();
const char* loader2 = SystemDictionary::loader_name(class_loader());
@@ -503,7 +505,7 @@
if (!resolved_klass->is_interface()) {
ResourceMark rm(THREAD);
char buf[200];
- jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", Klass::cast(resolved_klass())->external_name());
+ jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
@@ -517,7 +519,7 @@
// no method found
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
- Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
+ Method::name_and_sig_as_C_string(resolved_klass(),
method_name,
method_signature));
}
@@ -526,7 +528,7 @@
if (check_access) {
HandleMark hm(THREAD);
Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
- Handle class_loader (THREAD, InstanceKlass::cast(resolved_method->method_holder())->class_loader());
+ Handle class_loader (THREAD, resolved_method->method_holder()->class_loader());
{
ResourceMark rm(THREAD);
char* failed_type_name =
@@ -538,7 +540,7 @@
"current class, %s, and the class loader (instance of %s) for "
"resolved class, %s, have different Class objects for the type %s "
"used in the signature";
- char* sig = Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature);
+ char* sig = Method::name_and_sig_as_C_string(resolved_klass(),method_name,method_signature);
const char* loader1 = SystemDictionary::loader_name(loader());
char* current = InstanceKlass::cast(current_klass())->name()->as_C_string();
const char* loader2 = SystemDictionary::loader_name(class_loader());
@@ -625,7 +627,7 @@
if (is_static != fd.is_static()) {
ResourceMark rm(THREAD);
char msg[200];
- jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", Klass::cast(resolved_klass())->external_name(), fd.name()->as_C_string());
+ jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string());
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
}
@@ -699,7 +701,7 @@
bool check_access, bool initialize_class, TRAPS) {
methodHandle resolved_method;
linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
- resolved_klass = KlassHandle(THREAD, Klass::cast(resolved_method->method_holder()));
+ resolved_klass = KlassHandle(THREAD, resolved_method->method_holder());
// Initialize klass (this should only happen if everything is ok)
if (initialize_class && resolved_klass->should_be_initialized()) {
@@ -723,7 +725,7 @@
if (!resolved_method->is_static()) {
ResourceMark rm(THREAD);
char buf[200];
- jio_snprintf(buf, sizeof(buf), "Expected static method %s", Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
+ jio_snprintf(buf, sizeof(buf), "Expected static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
resolved_method->name(),
resolved_method->signature()));
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
@@ -743,6 +745,27 @@
Symbol* method_name, Symbol* method_signature,
KlassHandle current_klass, bool check_access, TRAPS) {
+ if (resolved_klass->is_interface() && current_klass() != NULL) {
+ // If the target class is a direct interface, treat this as a "super"
+ // default call.
+ //
+ // If the current method is an overpass that happens to call a direct
+ // super-interface's method, then we'll end up rerunning the default method
+ // analysis even though we don't need to, but that's ok since it will end
+ // up with the same answer.
+ InstanceKlass* ik = InstanceKlass::cast(current_klass());
+ Array<Klass*>* interfaces = ik->local_interfaces();
+ int num_interfaces = interfaces->length();
+ for (int index = 0; index < num_interfaces; index++) {
+ if (interfaces->at(index) == resolved_klass()) {
+ Method* method = DefaultMethods::find_super_default(current_klass(),
+ resolved_klass(), method_name, method_signature, CHECK);
+ resolved_method = methodHandle(THREAD, method);
+ return;
+ }
+ }
+ }
+
resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
// check if method name is <init>, that it is found in same klass as static type
@@ -766,7 +789,7 @@
char buf[200];
jio_snprintf(buf, sizeof(buf),
"Expecting non-static method %s",
- Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
+ Method::name_and_sig_as_C_string(resolved_klass(),
resolved_method->name(),
resolved_method->signature()));
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
@@ -784,11 +807,17 @@
{ KlassHandle method_klass = KlassHandle(THREAD,
resolved_method->method_holder());
- if (check_access &&
+ const bool direct_calling_default_method =
+ resolved_klass() != NULL && resolved_method() != NULL &&
+ resolved_klass->is_interface() && !resolved_method->is_abstract();
+
+ if (!direct_calling_default_method &&
+ check_access &&
// a) check if ACC_SUPER flag is set for the current class
current_klass->is_super() &&
// b) check if the method class is a superclass of the current class (superclass relation is not reflexive!)
- current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() &&
+ current_klass->is_subtype_of(method_klass()) &&
+ current_klass() != method_klass() &&
// c) check if the method is not <init>
resolved_method->name() != vmSymbols::object_initializer_name()) {
// Lookup super method
@@ -800,7 +829,7 @@
if (sel_method.is_null()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
- Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
+ Method::name_and_sig_as_C_string(resolved_klass(),
resolved_method->name(),
resolved_method->signature()));
}
@@ -811,7 +840,7 @@
if (sel_method->is_static()) {
ResourceMark rm(THREAD);
char buf[200];
- jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
+ jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
resolved_method->name(),
resolved_method->signature()));
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
@@ -821,7 +850,7 @@
if (sel_method->is_abstract()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
- Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
+ Method::name_and_sig_as_C_string(resolved_klass(),
sel_method->name(),
sel_method->signature()));
}
@@ -852,7 +881,7 @@
if (resolved_method->is_static()) {
ResourceMark rm(THREAD);
char buf[200];
- jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
+ jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
resolved_method->name(),
resolved_method->signature()));
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
@@ -881,12 +910,12 @@
// Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s
// has not been rewritten, and the vtable initialized.
- assert(InstanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked");
+ assert(resolved_method->method_holder()->is_linked(), "must be linked");
// Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s
// has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since
// a missing receiver might result in a bogus lookup.
- assert(InstanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked");
+ assert(resolved_method->method_holder()->is_linked(), "must be linked");
// do lookup based on receiver klass using the vtable index
if (resolved_method->method_holder()->is_interface()) { // miranda method
@@ -921,7 +950,7 @@
if (selected_method.is_null()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
- Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
+ Method::name_and_sig_as_C_string(resolved_klass(),
resolved_method->name(),
resolved_method->signature()));
}
@@ -930,7 +959,7 @@
if (check_null_and_abstract && selected_method->is_abstract()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
- Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
+ Method::name_and_sig_as_C_string(resolved_klass(),
selected_method->name(),
selected_method->signature()));
}
@@ -970,8 +999,8 @@
ResourceMark rm(THREAD);
char buf[200];
jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
- (Klass::cast(recv_klass()))->external_name(),
- (Klass::cast(resolved_klass()))->external_name());
+ recv_klass()->external_name(),
+ resolved_klass()->external_name());
THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
}
// do lookup based on receiver klass
@@ -983,7 +1012,7 @@
if (sel_method.is_null()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
- Method::name_and_sig_as_C_string(Klass::cast(recv_klass()),
+ Method::name_and_sig_as_C_string(recv_klass(),
resolved_method->name(),
resolved_method->signature()));
}
@@ -991,7 +1020,7 @@
if (!sel_method->is_public()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
- Method::name_and_sig_as_C_string(Klass::cast(recv_klass()),
+ Method::name_and_sig_as_C_string(recv_klass(),
sel_method->name(),
sel_method->signature()));
}
@@ -999,7 +1028,7 @@
if (check_null_and_abstract && sel_method->is_abstract()) {
ResourceMark rm(THREAD);
THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
- Method::name_and_sig_as_C_string(Klass::cast(recv_klass()),
+ Method::name_and_sig_as_C_string(recv_klass(),
sel_method->name(),
sel_method->signature()));
}
--- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -239,7 +239,7 @@
} else {
if (nextTC == NULL) {
// Removing chunk at tail of list
- link_tail(prevFC);
+ this->link_tail(prevFC);
}
// Chunk is interior to the list
prevFC->link_after(nextTC);
@@ -296,7 +296,7 @@
Chunk_t* fc = tail();
fc->link_after(chunk);
- link_tail(chunk);
+ this->link_tail(chunk);
assert(!tail() || size() == tail()->size(), "Wrong sized chunk in list");
FreeList_t<Chunk_t>::increment_count();
@@ -323,7 +323,7 @@
chunk->link_after(fc);
} else {
assert(tail() == NULL, "List is inconsistent");
- link_tail(chunk);
+ this->link_tail(chunk);
}
head()->link_after(chunk);
assert(!head() || size() == head()->size(), "Wrong sized chunk in list");
@@ -940,7 +940,7 @@
void do_tree(TreeList<Chunk_t, FreeList_t>* tl) {
if (tl != NULL) {
do_tree(tl->left());
- do_list(tl);
+ this->do_list(tl);
do_tree(tl->right());
}
}
@@ -952,7 +952,7 @@
void do_tree(TreeList<Chunk_t, FreeList_t>* tl) {
if (tl != NULL) {
do_tree(tl->right());
- do_list(tl);
+ this->do_list(tl);
do_tree(tl->left());
}
}
@@ -1022,7 +1022,7 @@
bool do_tree(TreeList<Chunk_t, FreeList_t>* tl) {
if (tl != NULL) {
if (do_tree(tl->right())) return true;
- if (do_list(tl)) return true;
+ if (this->do_list(tl)) return true;
if (do_tree(tl->left())) return true;
}
return false;
--- a/hotspot/src/share/vm/memory/metaspace.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/memory/metaspace.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -42,6 +42,10 @@
typedef BinaryTreeDictionary<Metablock, FreeList> BlockTreeDictionary;
typedef BinaryTreeDictionary<Metachunk, FreeList> ChunkTreeDictionary;
+// Define this macro to enable slow integrity checking of
+// the free chunk lists
+const bool metaspace_slow_verify = false;
+
// Parameters for stress mode testing
const uint metadata_deallocate_a_lot_block = 10;
@@ -161,7 +165,17 @@
size_t sum_free_chunks_count();
void locked_verify_free_chunks_total();
+ void slow_locked_verify_free_chunks_total() {
+ if (metaspace_slow_verify) {
+ locked_verify_free_chunks_total();
+ }
+ }
void locked_verify_free_chunks_count();
+ void slow_locked_verify_free_chunks_count() {
+ if (metaspace_slow_verify) {
+ locked_verify_free_chunks_count();
+ }
+ }
void verify_free_chunks_count();
public:
@@ -201,7 +215,17 @@
// Debug support
void verify();
+ void slow_verify() {
+ if (metaspace_slow_verify) {
+ verify();
+ }
+ }
void locked_verify();
+ void slow_locked_verify() {
+ if (metaspace_slow_verify) {
+ locked_verify();
+ }
+ }
void verify_free_chunks_total();
void locked_print_free_chunks(outputStream* st);
@@ -1507,7 +1531,7 @@
if (!UseConcMarkSweepGC && !SpaceManager::expand_lock()->is_locked()) {
MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
- locked_verify_free_chunks_total();
+ slow_locked_verify_free_chunks_total();
}
#endif
return _free_chunks_total;
@@ -1524,10 +1548,10 @@
Mutex::_no_safepoint_check_flag);
// This lock is only needed in debug because the verification
// of the _free_chunks_totals walks the list of free chunks
- locked_verify_free_chunks_count();
+ slow_locked_verify_free_chunks_count();
}
#endif
- return _free_chunks_count;
+ return _free_chunks_count;
}
void ChunkManager::locked_verify_free_chunks_total() {
@@ -1561,14 +1585,9 @@
}
void ChunkManager::verify() {
-#ifdef ASSERT
- if (!UseConcMarkSweepGC) {
- MutexLockerEx cl(SpaceManager::expand_lock(),
- Mutex::_no_safepoint_check_flag);
- locked_verify_free_chunks_total();
- locked_verify_free_chunks_count();
- }
-#endif
+ MutexLockerEx cl(SpaceManager::expand_lock(),
+ Mutex::_no_safepoint_check_flag);
+ locked_verify();
}
void ChunkManager::locked_verify() {
@@ -1642,7 +1661,7 @@
free_list->set_head(chunk);
// chunk is being returned to the chunk free list
inc_free_chunks_total(chunk->capacity_word_size());
- locked_verify();
+ slow_locked_verify();
}
void ChunkManager::chunk_freelist_deallocate(Metachunk* chunk) {
@@ -1650,8 +1669,8 @@
// manangement code for a Metaspace and does not hold the
// lock.
assert(chunk != NULL, "Deallocating NULL");
- // MutexLockerEx fcl(SpaceManager::expand_lock(), Mutex::_no_safepoint_check_flag);
- locked_verify();
+ assert_lock_strong(SpaceManager::expand_lock());
+ slow_locked_verify();
if (TraceMetadataChunkAllocation) {
tty->print_cr("ChunkManager::chunk_freelist_deallocate: chunk "
PTR_FORMAT " size " SIZE_FORMAT,
@@ -1663,7 +1682,7 @@
Metachunk* ChunkManager::free_chunks_get(size_t word_size) {
assert_lock_strong(SpaceManager::expand_lock());
- locked_verify();
+ slow_locked_verify();
Metachunk* chunk = NULL;
if (!SpaceManager::is_humongous(word_size)) {
@@ -1708,13 +1727,13 @@
#endif
}
}
- locked_verify();
+ slow_locked_verify();
return chunk;
}
Metachunk* ChunkManager::chunk_freelist_allocate(size_t word_size) {
assert_lock_strong(SpaceManager::expand_lock());
- locked_verify();
+ slow_locked_verify();
// Take from the beginning of the list
Metachunk* chunk = free_chunks_get(word_size);
@@ -1959,7 +1978,7 @@
ChunkManager* chunk_manager = vs_list()->chunk_manager();
- chunk_manager->locked_verify();
+ chunk_manager->slow_locked_verify();
if (TraceMetadataChunkAllocation && Verbose) {
gclog_or_tty->print_cr("~SpaceManager(): " PTR_FORMAT, this);
@@ -2015,7 +2034,7 @@
humongous_chunks = next_humongous_chunks;
}
set_chunks_in_use(HumongousIndex, NULL);
- chunk_manager->locked_verify();
+ chunk_manager->slow_locked_verify();
}
void SpaceManager::deallocate(MetaWord* p, size_t word_size) {
@@ -2330,8 +2349,7 @@
ChunkManager* chunk = (mdtype == Metaspace::ClassType) ?
Metaspace::class_space_list()->chunk_manager() :
Metaspace::space_list()->chunk_manager();
-
- chunk->verify_free_chunks_total();
+ chunk->slow_verify();
return chunk->free_chunks_total();
}
@@ -2435,6 +2453,11 @@
print_waste(out);
}
+void MetaspaceAux::verify_free_chunks() {
+ Metaspace::space_list()->chunk_manager()->verify();
+ Metaspace::class_space_list()->chunk_manager()->verify();
+}
+
// Metaspace methods
size_t Metaspace::_first_chunk_word_size = 0;
--- a/hotspot/src/share/vm/memory/metaspace.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/memory/metaspace.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -189,6 +189,7 @@
static void print_waste(outputStream* out);
static void dump(outputStream* out);
+ static void verify_free_chunks();
};
// Metaspace are deallocated when their class loader are GC'ed.
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -431,7 +431,7 @@
}
static void link_shared_classes(Klass* obj, TRAPS) {
- Klass* k = Klass::cast(obj);
+ Klass* k = obj;
if (k->oop_is_instance()) {
InstanceKlass* ik = (InstanceKlass*) k;
// Link the class to cause the bytecodes to be rewritten and the
--- a/hotspot/src/share/vm/memory/universe.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/memory/universe.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -346,7 +346,7 @@
// ---
// New
// Have already been initialized.
- Klass::cast(_objectArrayKlassObj)->append_to_sibling_list();
+ _objectArrayKlassObj->append_to_sibling_list();
// Compute is_jdk version flags.
// Only 1.3 or later has the java.lang.Shutdown class.
@@ -1304,6 +1304,8 @@
if (!silent) gclog_or_tty->print("cldg ");
ClassLoaderDataGraph::verify();
#endif
+ if (!silent) gclog_or_tty->print("metaspace chunks ");
+ MetaspaceAux::verify_free_chunks();
if (!silent) gclog_or_tty->print("hand ");
JNIHandles::verify();
if (!silent) gclog_or_tty->print("C-heap ");
--- a/hotspot/src/share/vm/oops/arrayKlass.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/arrayKlass.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -67,7 +67,7 @@
Method* ArrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const {
// There are no methods in an array klass but the super class (Object) has some
assert(super(), "super klass must be present");
- return Klass::cast(super())->uncached_lookup_method(name, signature);
+ return super()->uncached_lookup_method(name, signature);
}
ArrayKlass::ArrayKlass(Symbol* name) {
--- a/hotspot/src/share/vm/oops/constMethod.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/constMethod.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -34,29 +34,30 @@
const u2 ConstMethod::UNSET_IDNUM = 0xFFFF;
ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data,
- int byte_code_size,
- int compressed_line_number_size,
- int localvariable_table_length,
- int exception_table_length,
- int checked_exceptions_length,
- TRAPS) {
+ int byte_code_size,
+ int compressed_line_number_size,
+ int localvariable_table_length,
+ int exception_table_length,
+ int checked_exceptions_length,
+ MethodType method_type,
+ TRAPS) {
int size = ConstMethod::size(byte_code_size,
compressed_line_number_size,
localvariable_table_length,
exception_table_length,
checked_exceptions_length);
return new (loader_data, size, true, THREAD) ConstMethod(
- byte_code_size, compressed_line_number_size,
- localvariable_table_length, exception_table_length,
- checked_exceptions_length, size);
+ byte_code_size, compressed_line_number_size, localvariable_table_length,
+ exception_table_length, checked_exceptions_length, method_type, size);
}
ConstMethod::ConstMethod(int byte_code_size,
- int compressed_line_number_size,
- int localvariable_table_length,
- int exception_table_length,
- int checked_exceptions_length,
- int size) {
+ int compressed_line_number_size,
+ int localvariable_table_length,
+ int exception_table_length,
+ int checked_exceptions_length,
+ MethodType method_type,
+ int size) {
No_Safepoint_Verifier no_safepoint;
set_interpreter_kind(Interpreter::invalid);
@@ -69,6 +70,7 @@
compressed_line_number_size,
localvariable_table_length,
exception_table_length);
+ set_method_type(method_type);
assert(this->size() == size, "wrong size for object");
}
@@ -111,8 +113,7 @@
}
Method* ConstMethod::method() const {
- return InstanceKlass::cast(_constants->pool_holder())->method_with_idnum(
- _method_idnum);
+ return _constants->pool_holder()->method_with_idnum(_method_idnum);
}
// linenumber table - note that length is unknown until decompression,
--- a/hotspot/src/share/vm/oops/constMethod.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/constMethod.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -108,12 +108,17 @@
class ConstMethod : public MetaspaceObj {
friend class VMStructs;
+
+public:
+ typedef enum { NORMAL, OVERPASS } MethodType;
+
private:
enum {
_has_linenumber_table = 1,
_has_checked_exceptions = 2,
_has_localvariable_table = 4,
- _has_exception_table = 8
+ _has_exception_table = 8,
+ _is_overpass = 16
};
// Bit vector of signature
@@ -145,19 +150,22 @@
// Constructor
ConstMethod(int byte_code_size,
- int compressed_line_number_size,
- int localvariable_table_length,
- int exception_table_length,
- int checked_exceptions_length,
- int size);
+ int compressed_line_number_size,
+ int localvariable_table_length,
+ int exception_table_length,
+ int checked_exceptions_length,
+ MethodType is_overpass,
+ int size);
public:
+
static ConstMethod* allocate(ClassLoaderData* loader_data,
- int byte_code_size,
- int compressed_line_number_size,
- int localvariable_table_length,
- int exception_table_length,
- int checked_exceptions_length,
- TRAPS);
+ int byte_code_size,
+ int compressed_line_number_size,
+ int localvariable_table_length,
+ int exception_table_length,
+ int checked_exceptions_length,
+ MethodType mt,
+ TRAPS);
bool is_constMethod() const { return true; }
@@ -179,6 +187,19 @@
bool has_exception_handler() const
{ return (_flags & _has_exception_table) != 0; }
+ MethodType method_type() const {
+ return ((_flags & _is_overpass) == 0) ? NORMAL : OVERPASS;
+ }
+
+ void set_method_type(MethodType mt) {
+ if (mt == NORMAL) {
+ _flags &= ~(_is_overpass);
+ } else {
+ _flags |= _is_overpass;
+ }
+ }
+
+
void set_interpreter_kind(int kind) { _interpreter_kind = kind; }
int interpreter_kind(void) const { return _interpreter_kind; }
--- a/hotspot/src/share/vm/oops/constantPool.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -228,7 +228,7 @@
} else {
do_resolve = true;
name = this_oop->unresolved_klass_at(which);
- loader = Handle(THREAD, InstanceKlass::cast(this_oop->pool_holder())->class_loader());
+ loader = Handle(THREAD, this_oop->pool_holder()->class_loader());
}
}
} // unlocking constantPool
@@ -247,7 +247,7 @@
if (do_resolve) {
// this_oop must be unlocked during resolve_or_fail
- oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain();
+ oop protection_domain = this_oop->pool_holder()->protection_domain();
Handle h_prot (THREAD, protection_domain);
Klass* k_oop = SystemDictionary::resolve_or_fail(name, loader, h_prot, true, THREAD);
KlassHandle k;
@@ -315,7 +315,7 @@
vframeStream vfst(JavaThread::current());
if (!vfst.at_end()) {
line_number = vfst.method()->line_number_from_bci(vfst.bci());
- Symbol* s = InstanceKlass::cast(vfst.method()->method_holder())->source_file_name();
+ Symbol* s = vfst.method()->method_holder()->source_file_name();
if (s != NULL) {
source_file = s->as_C_string();
}
@@ -325,11 +325,11 @@
// only print something if the classes are different
if (source_file != NULL) {
tty->print("RESOLVE %s %s %s:%d\n",
- InstanceKlass::cast(this_oop->pool_holder())->external_name(),
+ this_oop->pool_holder()->external_name(),
InstanceKlass::cast(k())->external_name(), source_file, line_number);
} else {
tty->print("RESOLVE %s %s\n",
- InstanceKlass::cast(this_oop->pool_holder())->external_name(),
+ this_oop->pool_holder()->external_name(),
InstanceKlass::cast(k())->external_name());
}
}
@@ -339,7 +339,7 @@
// Only updated constant pool - if it is resolved.
do_resolve = this_oop->tag_at(which).is_unresolved_klass();
if (do_resolve) {
- ClassLoaderData* this_key = InstanceKlass::cast(this_oop->pool_holder())->class_loader_data();
+ ClassLoaderData* this_key = this_oop->pool_holder()->class_loader_data();
if (!this_key->is_the_null_class_loader_data()) {
this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM
}
@@ -367,8 +367,8 @@
assert(entry.is_unresolved(), "must be either symbol or klass");
Thread *thread = Thread::current();
Symbol* name = entry.get_symbol();
- oop loader = InstanceKlass::cast(this_oop->pool_holder())->class_loader();
- oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain();
+ oop loader = this_oop->pool_holder()->class_loader();
+ oop protection_domain = this_oop->pool_holder()->protection_domain();
Handle h_prot (thread, protection_domain);
Handle h_loader (thread, loader);
Klass* k = SystemDictionary::find(name, h_loader, h_prot, thread);
@@ -409,8 +409,8 @@
} else {
assert(entry.is_unresolved(), "must be either symbol or klass");
Symbol* name = entry.get_symbol();
- oop loader = InstanceKlass::cast(this_oop->pool_holder())->class_loader();
- oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain();
+ oop loader = this_oop->pool_holder()->class_loader();
+ oop protection_domain = this_oop->pool_holder()->protection_domain();
Handle h_loader(THREAD, loader);
Handle h_prot (THREAD, protection_domain);
KlassHandle k(THREAD, SystemDictionary::find(name, h_loader, h_prot, THREAD));
@@ -1143,16 +1143,21 @@
int from_oplen = operand_array_length(from_cp->operands());
int old_oplen = operand_array_length(to_cp->operands());
if (from_oplen != 0) {
+ ClassLoaderData* loader_data = to_cp->pool_holder()->class_loader_data();
// append my operands to the target's operands array
if (old_oplen == 0) {
- to_cp->set_operands(from_cp->operands()); // reuse; do not merge
+ // Can't just reuse from_cp's operand list because of deallocation issues
+ int len = from_cp->operands()->length();
+ Array<u2>* new_ops = MetadataFactory::new_array<u2>(loader_data, len, CHECK);
+ Copy::conjoint_memory_atomic(
+ from_cp->operands()->adr_at(0), new_ops->adr_at(0), len * sizeof(u2));
+ to_cp->set_operands(new_ops);
} else {
int old_len = to_cp->operands()->length();
int from_len = from_cp->operands()->length();
int old_off = old_oplen * sizeof(u2);
int from_off = from_oplen * sizeof(u2);
// Use the metaspace for the destination constant pool
- ClassLoaderData* loader_data = to_cp->pool_holder()->class_loader_data();
Array<u2>* new_operands = MetadataFactory::new_array<u2>(loader_data, old_len + from_len, CHECK);
int fillp = 0, len = 0;
// first part of dest
@@ -1785,7 +1790,7 @@
assert(cp_patches->at(index).is_null(),
err_msg("Unused constant pool patch at %d in class file %s",
index,
- InstanceKlass::cast(pool_holder())->external_name()));
+ pool_holder()->external_name()));
}
#endif // ASSERT
}
@@ -1943,7 +1948,7 @@
st->print(" for ");
pool_holder()->print_value_on(st);
if (pool_holder() != NULL) {
- bool extra = (InstanceKlass::cast(pool_holder())->constants() != this);
+ bool extra = (pool_holder()->constants() != this);
if (extra) st->print(" (extra)");
}
if (cache() != NULL) {
--- a/hotspot/src/share/vm/oops/constantPool.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/constantPool.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -86,8 +86,8 @@
friend class Universe; // For null constructor
private:
Array<u1>* _tags; // the tag array describing the constant pool's contents
- ConstantPoolCache* _cache; // the cache holding interpreter runtime information
- Klass* _pool_holder; // the corresponding class
+ ConstantPoolCache* _cache; // the cache holding interpreter runtime information
+ InstanceKlass* _pool_holder; // the corresponding class
Array<u2>* _operands; // for variable-sized (InvokeDynamic) nodes, usually empty
// Array of resolved objects from the constant pool and map from resolved
@@ -193,9 +193,9 @@
void set_on_stack(const bool value);
// Klass holding pool
- Klass* pool_holder() const { return _pool_holder; }
- void set_pool_holder(Klass* k) { _pool_holder = k; }
- Klass** pool_holder_addr() { return &_pool_holder; }
+ InstanceKlass* pool_holder() const { return _pool_holder; }
+ void set_pool_holder(InstanceKlass* k) { _pool_holder = k; }
+ InstanceKlass** pool_holder_addr() { return &_pool_holder; }
// Interpreter runtime support
ConstantPoolCache* cache() const { return _cache; }
--- a/hotspot/src/share/vm/oops/cpCache.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/cpCache.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -231,8 +231,8 @@
void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index) {
- Klass* interf = method->method_holder();
- assert(InstanceKlass::cast(interf)->is_interface(), "must be an interface");
+ InstanceKlass* interf = method->method_holder();
+ assert(interf->is_interface(), "must be an interface");
assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here");
set_f1(interf);
set_f2(index);
@@ -243,25 +243,17 @@
}
-void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool,
- methodHandle adapter,
- Handle appendix, Handle method_type,
- objArrayHandle resolved_references) {
- set_method_handle_common(cpool, Bytecodes::_invokehandle, adapter, appendix, method_type, resolved_references);
+void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool, const CallInfo &call_info) {
+ set_method_handle_common(cpool, Bytecodes::_invokehandle, call_info);
}
-void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool,
- methodHandle adapter,
- Handle appendix, Handle method_type,
- objArrayHandle resolved_references) {
- set_method_handle_common(cpool, Bytecodes::_invokedynamic, adapter, appendix, method_type, resolved_references);
+void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool, const CallInfo &call_info) {
+ set_method_handle_common(cpool, Bytecodes::_invokedynamic, call_info);
}
void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
Bytecodes::Code invoke_code,
- methodHandle adapter,
- Handle appendix, Handle method_type,
- objArrayHandle resolved_references) {
+ const CallInfo &call_info) {
// NOTE: This CPCE can be the subject of data races.
// There are three words to update: flags, refs[f2], f1 (in that order).
// Writers must store all other values before f1.
@@ -276,6 +268,9 @@
return;
}
+ const methodHandle adapter = call_info.resolved_method();
+ const Handle appendix = call_info.resolved_appendix();
+ const Handle method_type = call_info.resolved_method_type();
const bool has_appendix = appendix.not_null();
const bool has_method_type = method_type.not_null();
@@ -315,6 +310,7 @@
// This allows us to create fewer method oops, while keeping type safety.
//
+ objArrayHandle resolved_references = cpool->resolved_references();
// Store appendix, if any.
if (has_appendix) {
const int appendix_index = f2_as_index() + _indy_resolved_references_appendix_offset;
@@ -375,7 +371,7 @@
int holder_index = cpool->uncached_klass_ref_index_at(constant_pool_index());
if (cpool->tag_at(holder_index).is_klass()) {
Klass* klass = cpool->resolved_klass_at(holder_index);
- if (!Klass::cast(klass)->oop_is_instance())
+ if (!klass->oop_is_instance())
klass = SystemDictionary::Object_klass();
return InstanceKlass::cast(klass)->method_at_vtable(f2_as_index());
}
@@ -421,7 +417,7 @@
if (!(*trace_name_printed)) {
// RC_TRACE_MESG macro has an embedded ResourceMark
RC_TRACE_MESG(("adjust: name=%s",
- Klass::cast(old_method->method_holder())->external_name()));
+ old_method->method_holder()->external_name()));
*trace_name_printed = true;
}
// RC_TRACE macro has an embedded ResourceMark
@@ -449,7 +445,7 @@
if (!(*trace_name_printed)) {
// RC_TRACE_MESG macro has an embedded ResourceMark
RC_TRACE_MESG(("adjust: name=%s",
- Klass::cast(old_method->method_holder())->external_name()));
+ old_method->method_holder()->external_name()));
*trace_name_printed = true;
}
// RC_TRACE macro has an embedded ResourceMark
--- a/hotspot/src/share/vm/oops/cpCache.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/cpCache.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -117,6 +117,8 @@
// The fields are volatile so that they are stored in the order written in the
// source code. The _indices field with the bytecode must be written last.
+class CallInfo;
+
class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
friend class constantPoolCacheKlass;
@@ -223,18 +225,12 @@
void set_method_handle(
constantPoolHandle cpool, // holding constant pool (required for locking)
- methodHandle method, // adapter for invokeExact, etc.
- Handle appendix, // stored in refs[f2+0]; could be a java.lang.invoke.MethodType
- Handle method_type, // stored in refs[f2+1]; is a java.lang.invoke.MethodType
- objArrayHandle resolved_references
+ const CallInfo &call_info // Call link information
);
void set_dynamic_call(
constantPoolHandle cpool, // holding constant pool (required for locking)
- methodHandle method, // adapter for this call site
- Handle appendix, // stored in refs[f2+0]; could be a java.lang.invoke.CallSite
- Handle method_type, // stored in refs[f2+1]; is a java.lang.invoke.MethodType
- objArrayHandle resolved_references
+ const CallInfo &call_info // Call link information
);
// Common code for invokedynamic and MH invocations.
@@ -255,10 +251,7 @@
void set_method_handle_common(
constantPoolHandle cpool, // holding constant pool (required for locking)
Bytecodes::Code invoke_code, // _invokehandle or _invokedynamic
- methodHandle adapter, // invoker method (f1)
- Handle appendix, // appendix such as CallSite, MethodType, etc. (refs[f2+0])
- Handle method_type, // MethodType (refs[f2+1])
- objArrayHandle resolved_references
+ const CallInfo &call_info // Call link information
);
// invokedynamic and invokehandle call sites have two entries in the
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -727,8 +727,8 @@
// Step 7
Klass* super_klass = this_oop->super();
- if (super_klass != NULL && !this_oop->is_interface() && Klass::cast(super_klass)->should_be_initialized()) {
- Klass::cast(super_klass)->initialize(THREAD);
+ if (super_klass != NULL && !this_oop->is_interface() && super_klass->should_be_initialized()) {
+ super_klass->initialize(THREAD);
if (HAS_PENDING_EXCEPTION) {
Handle e(THREAD, PENDING_EXCEPTION);
@@ -743,6 +743,35 @@
}
}
+ if (this_oop->has_default_methods()) {
+ // Step 7.5: initialize any interfaces which have default methods
+ for (int i = 0; i < this_oop->local_interfaces()->length(); ++i) {
+ Klass* iface = this_oop->local_interfaces()->at(i);
+ InstanceKlass* ik = InstanceKlass::cast(iface);
+ if (ik->has_default_methods() && ik->should_be_initialized()) {
+ ik->initialize(THREAD);
+
+ if (HAS_PENDING_EXCEPTION) {
+ Handle e(THREAD, PENDING_EXCEPTION);
+ CLEAR_PENDING_EXCEPTION;
+ {
+ EXCEPTION_MARK;
+ // Locks object, set state, and notify all waiting threads
+ this_oop->set_initialization_state_and_notify(
+ initialization_error, THREAD);
+
+ // ignore any exception thrown, superclass initialization error is
+ // thrown below
+ CLEAR_PENDING_EXCEPTION;
+ }
+ DTRACE_CLASSINIT_PROBE_WAIT(
+ super__failed, InstanceKlass::cast(this_oop()), -1, wait);
+ THROW_OOP(e());
+ }
+ }
+ }
+ }
+
// Step 8
{
assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl");
@@ -895,7 +924,7 @@
}
bool InstanceKlass::compute_is_subtype_of(Klass* k) {
- if (Klass::cast(k)->is_interface()) {
+ if (k->is_interface()) {
return implements_interface(k);
} else {
return Klass::compute_is_subtype_of(k);
@@ -904,7 +933,7 @@
bool InstanceKlass::implements_interface(Klass* k) const {
if (this == k) return true;
- assert(Klass::cast(k)->is_interface(), "should be an interface class");
+ assert(k->is_interface(), "should be an interface class");
for (int i = 0; i < transitive_interfaces()->length(); i++) {
if (transitive_interfaces()->at(i) == k) {
return true;
@@ -1023,6 +1052,13 @@
}
void InstanceKlass::call_class_initializer_impl(instanceKlassHandle this_oop, TRAPS) {
+ if (ReplayCompiles &&
+ (ReplaySuppressInitializers == 1 ||
+ ReplaySuppressInitializers >= 2 && this_oop->class_loader() != NULL)) {
+ // Hide the existence of the initializer for the purpose of replaying the compile
+ return;
+ }
+
methodHandle h_method(THREAD, this_oop->class_initializer());
assert(!this_oop->is_initialized(), "we cannot initialize twice");
if (TraceClassInitialization) {
@@ -1071,7 +1107,7 @@
const int n = local_interfaces()->length();
for (int i = 0; i < n; i++) {
Klass* intf1 = local_interfaces()->at(i);
- assert(Klass::cast(intf1)->is_interface(), "just checking type");
+ assert(intf1->is_interface(), "just checking type");
// search for field in current interface
if (InstanceKlass::cast(intf1)->find_local_field(name, sig, fd)) {
assert(fd->is_static(), "interface field must be static");
@@ -1142,7 +1178,7 @@
if (InstanceKlass::cast(klass)->find_local_field_from_offset(offset, is_static, fd)) {
return true;
}
- klass = Klass::cast(klass)->super();
+ klass = klass->super();
}
return false;
}
@@ -1252,11 +1288,7 @@
}
#endif
-Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const {
- return InstanceKlass::find_method(methods(), name, signature);
-}
-
-Method* InstanceKlass::find_method(Array<Method*>* methods, Symbol* name, Symbol* signature) {
+static int binary_search(Array<Method*>* methods, Symbol* name) {
int len = methods->length();
// methods are sorted, so do binary search
int l = 0;
@@ -1267,43 +1299,70 @@
assert(m->is_method(), "must be method");
int res = m->name()->fast_compare(name);
if (res == 0) {
- // found matching name; do linear search to find matching signature
- // first, quick check for common case
- if (m->signature() == signature) return m;
- // search downwards through overloaded methods
- int i;
- for (i = mid - 1; i >= l; i--) {
- Method* m = methods->at(i);
- assert(m->is_method(), "must be method");
- if (m->name() != name) break;
- if (m->signature() == signature) return m;
- }
- // search upwards
- for (i = mid + 1; i <= h; i++) {
- Method* m = methods->at(i);
- assert(m->is_method(), "must be method");
- if (m->name() != name) break;
- if (m->signature() == signature) return m;
- }
- // not found
-#ifdef ASSERT
- int index = linear_search(methods, name, signature);
- assert(index == -1, err_msg("binary search should have found entry %d", index));
-#endif
- return NULL;
+ return mid;
} else if (res < 0) {
l = mid + 1;
} else {
h = mid - 1;
}
}
+ return -1;
+}
+
+Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const {
+ return InstanceKlass::find_method(methods(), name, signature);
+}
+
+Method* InstanceKlass::find_method(
+ Array<Method*>* methods, Symbol* name, Symbol* signature) {
+ int hit = binary_search(methods, name);
+ if (hit != -1) {
+ Method* m = methods->at(hit);
+ // Do linear search to find matching signature. First, quick check
+ // for common case
+ if (m->signature() == signature) return m;
+ // search downwards through overloaded methods
+ int i;
+ for (i = hit - 1; i >= 0; --i) {
+ Method* m = methods->at(i);
+ assert(m->is_method(), "must be method");
+ if (m->name() != name) break;
+ if (m->signature() == signature) return m;
+ }
+ // search upwards
+ for (i = hit + 1; i < methods->length(); ++i) {
+ Method* m = methods->at(i);
+ assert(m->is_method(), "must be method");
+ if (m->name() != name) break;
+ if (m->signature() == signature) return m;
+ }
+ // not found
#ifdef ASSERT
- int index = linear_search(methods, name, signature);
- assert(index == -1, err_msg("binary search should have found entry %d", index));
+ int index = linear_search(methods, name, signature);
+ assert(index == -1, err_msg("binary search should have found entry %d", index));
#endif
+ }
return NULL;
}
+int InstanceKlass::find_method_by_name(Symbol* name, int* end) {
+ return find_method_by_name(methods(), name, end);
+}
+
+int InstanceKlass::find_method_by_name(
+ Array<Method*>* methods, Symbol* name, int* end_ptr) {
+ assert(end_ptr != NULL, "just checking");
+ int start = binary_search(methods, name);
+ int end = start + 1;
+ if (start != -1) {
+ while (start - 1 >= 0 && (methods->at(start - 1))->name() == name) --start;
+ while (end < methods->length() && (methods->at(end))->name() == name) ++end;
+ *end_ptr = end;
+ return start;
+ }
+ return -1;
+}
+
Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const {
Klass* klass = const_cast<InstanceKlass*>(this);
while (klass != NULL) {
@@ -2307,19 +2366,19 @@
bool InstanceKlass::is_same_class_package(Klass* class2) {
Klass* class1 = this;
oop classloader1 = InstanceKlass::cast(class1)->class_loader();
- Symbol* classname1 = Klass::cast(class1)->name();
-
- if (Klass::cast(class2)->oop_is_objArray()) {
+ Symbol* classname1 = class1->name();
+
+ if (class2->oop_is_objArray()) {
class2 = ObjArrayKlass::cast(class2)->bottom_klass();
}
oop classloader2;
- if (Klass::cast(class2)->oop_is_instance()) {
+ if (class2->oop_is_instance()) {
classloader2 = InstanceKlass::cast(class2)->class_loader();
} else {
- assert(Klass::cast(class2)->oop_is_typeArray(), "should be type array");
+ assert(class2->oop_is_typeArray(), "should be type array");
classloader2 = NULL;
}
- Symbol* classname2 = Klass::cast(class2)->name();
+ Symbol* classname2 = class2->name();
return InstanceKlass::is_same_class_package(classloader1, classname1,
classloader2, classname2);
@@ -2328,7 +2387,7 @@
bool InstanceKlass::is_same_class_package(oop classloader2, Symbol* classname2) {
Klass* class1 = this;
oop classloader1 = InstanceKlass::cast(class1)->class_loader();
- Symbol* classname1 = Klass::cast(class1)->name();
+ Symbol* classname1 = class1->name();
return InstanceKlass::is_same_class_package(classloader1, classname1,
classloader2, classname2);
@@ -2419,7 +2478,7 @@
bool InstanceKlass::is_same_package_member_impl(instanceKlassHandle class1,
Klass* class2_oop, TRAPS) {
if (class2_oop == class1()) return true;
- if (!Klass::cast(class2_oop)->oop_is_instance()) return false;
+ if (!class2_oop->oop_is_instance()) return false;
instanceKlassHandle class2(THREAD, class2_oop);
// must be in same package before we try anything else
@@ -2952,7 +3011,7 @@
if (im != NULL) {
guarantee(is_interface(), "only interfaces should have implementor set");
guarantee(im->is_klass(), "should be klass");
- guarantee(!Klass::cast(im)->is_interface() || im == this,
+ guarantee(!im->is_interface() || im == this,
"implementors cannot be interfaces");
}
@@ -2961,7 +3020,7 @@
Array<Klass*>* local_interfaces = this->local_interfaces();
for (int j = 0; j < local_interfaces->length(); j++) {
Klass* e = local_interfaces->at(j);
- guarantee(e->is_klass() && Klass::cast(e)->is_interface(), "invalid local interface");
+ guarantee(e->is_klass() && e->is_interface(), "invalid local interface");
}
}
@@ -2970,7 +3029,7 @@
Array<Klass*>* transitive_interfaces = this->transitive_interfaces();
for (int j = 0; j < transitive_interfaces->length(); j++) {
Klass* e = transitive_interfaces->at(j);
- guarantee(e->is_klass() && Klass::cast(e)->is_interface(), "invalid transitive interface");
+ guarantee(e->is_klass() && e->is_interface(), "invalid transitive interface");
}
}
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -133,6 +133,7 @@
class InstanceKlass: public Klass {
friend class VMStructs;
friend class ClassFileParser;
+ friend class CompileReplay;
protected:
// Constructor
@@ -245,6 +246,10 @@
unsigned char * _cached_class_file_bytes; // JVMTI: cached class file, before retransformable agent modified it in CFLH
jint _cached_class_file_len; // JVMTI: length of above
JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration
+
+ // true if class, superclass, or implemented interfaces have default methods
+ bool _has_default_methods;
+
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
// Method array.
Array<Method*>* _methods;
@@ -492,6 +497,13 @@
// (returns NULL if not found)
Method* lookup_method_in_all_interfaces(Symbol* name, Symbol* signature) const;
+ // Find method indices by name. If a method with the specified name is
+ // found the index to the first method is returned, and 'end' is filled in
+ // with the index of first non-name-matching method. If no method is found
+ // -1 is returned.
+ int find_method_by_name(Symbol* name, int* end);
+ static int find_method_by_name(Array<Method*>* methods, Symbol* name, int* end);
+
// constant pool
ConstantPool* constants() const { return _constants; }
void set_constants(ConstantPool* c) { _constants = c; }
@@ -592,6 +604,9 @@
return _jvmti_cached_class_field_map;
}
+ bool has_default_methods() const { return _has_default_methods; }
+ void set_has_default_methods(bool b) { _has_default_methods = b; }
+
// for adding methods, ConstMethod::UNSET_IDNUM means no more ids available
inline u2 next_method_idnum();
void set_initial_method_idnum(u2 value) { _idnum_allocated_count = value; }
@@ -728,7 +743,6 @@
GrowableArray<Klass*>* compute_secondary_supers(int num_extra_slots);
bool compute_is_subtype_of(Klass* k);
bool can_be_primary_super_slow() const;
- Klass* java_super() const { return super(); }
int oop_size(oop obj) const { return size_helper(); }
bool oop_is_instance_slow() const { return true; }
@@ -750,6 +764,10 @@
return (InstanceKlass*) k;
}
+ InstanceKlass* java_super() const {
+ return (super() == NULL) ? NULL : cast(super());
+ }
+
// Sizing (in words)
static int header_size() { return align_object_offset(sizeof(InstanceKlass)/HeapWordSize); }
static int size(int vtable_length, int itable_length,
--- a/hotspot/src/share/vm/oops/klass.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/klass.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -56,7 +56,7 @@
while (t != NULL) {
if (t == k) return true;
- t = Klass::cast(t)->super();
+ t = t->super();
}
return false;
}
@@ -243,16 +243,16 @@
juint j = super_depth();
assert(j == my_depth, "computed accessor gets right answer");
Klass* t = this;
- while (!Klass::cast(t)->can_be_primary_super()) {
- t = Klass::cast(t)->super();
- j = Klass::cast(t)->super_depth();
+ while (!t->can_be_primary_super()) {
+ t = t->super();
+ j = t->super_depth();
}
for (juint j1 = j+1; j1 < primary_super_limit(); j1++) {
assert(primary_super_of_depth(j1) == NULL, "super list padding");
}
while (t != NULL) {
assert(primary_super_of_depth(j) == t, "super list initialization");
- t = Klass::cast(t)->super();
+ t = t->super();
--j;
}
assert(j == (juint)-1, "correct depth count");
@@ -333,7 +333,7 @@
Klass* Klass::subklass() const {
- return _subklass == NULL ? NULL : Klass::cast(_subklass);
+ return _subklass == NULL ? NULL : _subklass;
}
InstanceKlass* Klass::superklass() const {
@@ -342,7 +342,7 @@
}
Klass* Klass::next_sibling() const {
- return _next_sibling == NULL ? NULL : Klass::cast(_next_sibling);
+ return _next_sibling == NULL ? NULL : _next_sibling;
}
void Klass::set_subklass(Klass* s) {
--- a/hotspot/src/share/vm/oops/klass.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/klass.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -422,12 +422,6 @@
// if not, throw either an Error or an Exception.
virtual void check_valid_for_instantiation(bool throwError, TRAPS);
- // Casting
- static Klass* cast(Klass* k) {
- assert(k->is_klass(), "cast to Klass");
- return k;
- }
-
// array copying
virtual void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
--- a/hotspot/src/share/vm/oops/klassVtable.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -54,22 +54,16 @@
// the same name and signature as m), then m is a Miranda method which is
// entered as a public abstract method in C's vtable. From then on it should
// treated as any other public method in C for method over-ride purposes.
-void klassVtable::compute_vtable_size_and_num_mirandas(int &vtable_length,
- int &num_miranda_methods,
- Klass* super,
- Array<Method*>* methods,
- AccessFlags class_flags,
- Handle classloader,
- Symbol* classname,
- Array<Klass*>* local_interfaces,
- TRAPS
- ) {
-
+void klassVtable::compute_vtable_size_and_num_mirandas(
+ int* vtable_length_ret, int* num_new_mirandas,
+ GrowableArray<Method*>* all_mirandas, Klass* super,
+ Array<Method*>* methods, AccessFlags class_flags,
+ Handle classloader, Symbol* classname, Array<Klass*>* local_interfaces,
+ TRAPS) {
No_Safepoint_Verifier nsv;
// set up default result values
- vtable_length = 0;
- num_miranda_methods = 0;
+ int vtable_length = 0;
// start off with super's vtable length
InstanceKlass* sk = (InstanceKlass*)super;
@@ -86,9 +80,12 @@
}
}
+ GrowableArray<Method*> new_mirandas(20);
// compute the number of mirandas methods that must be added to the end
- num_miranda_methods = get_num_mirandas(super, methods, local_interfaces);
- vtable_length += (num_miranda_methods * vtableEntry::size());
+ get_mirandas(&new_mirandas, all_mirandas, super, methods, local_interfaces);
+ *num_new_mirandas = new_mirandas.length();
+
+ vtable_length += *num_new_mirandas * vtableEntry::size();
if (Universe::is_bootstrapping() && vtable_length == 0) {
// array classes don't have their superclass set correctly during
@@ -109,6 +106,8 @@
"bad vtable size for class Object");
assert(vtable_length % vtableEntry::size() == 0, "bad vtable length");
assert(vtable_length >= Universe::base_vtable_size(), "vtable too small");
+
+ *vtable_length_ret = vtable_length;
}
int klassVtable::index_of(Method* m, int len) const {
@@ -191,7 +190,7 @@
}
// add miranda methods; it will also update the value of initialized
- fill_in_mirandas(initialized);
+ fill_in_mirandas(&initialized);
// In class hierarchies where the accessibility is not increasing (i.e., going from private ->
// package_private -> publicprotected), the vtable might actually be smaller than our initial
@@ -249,6 +248,11 @@
return superk;
}
+// Methods that are "effectively" final don't need vtable entries.
+bool method_is_effectively_final(
+ AccessFlags klass_flags, methodHandle target) {
+ return target->is_final() || klass_flags.is_final() && !target->is_overpass();
+}
// Update child's copy of super vtable for overrides
// OR return true if a new vtable entry is required
@@ -269,7 +273,7 @@
return false;
}
- if (klass->is_final() || target_method()->is_final()) {
+ if (method_is_effectively_final(klass->access_flags(), target_method)) {
// a final method never needs a new entry; final methods can be statically
// resolved and they have to be present in the vtable only if they override
// a super's method, in which case they re-use its entry
@@ -303,7 +307,7 @@
if (super_method->name() == name && super_method->signature() == signature) {
// get super_klass for method_holder for the found method
- InstanceKlass* super_klass = InstanceKlass::cast(super_method->method_holder());
+ InstanceKlass* super_klass = super_method->method_holder();
if ((super_klass->is_override(super_method, target_loader, target_classname, THREAD)) ||
((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION)
@@ -406,7 +410,8 @@
Symbol* classname,
AccessFlags class_flags,
TRAPS) {
- if ((class_flags.is_final() || target_method()->is_final()) ||
+
+ if (method_is_effectively_final(class_flags, target_method) ||
// a final method never needs a new entry; final methods can be statically
// resolved and they have to be present in the vtable only if they override
// a super's method, in which case they re-use its entry
@@ -447,7 +452,7 @@
}
// get the class holding the matching method
// make sure you use that class for is_override
- InstanceKlass* superk = InstanceKlass::cast(super_method->method_holder());
+ InstanceKlass* superk = super_method->method_holder();
// we want only instance method matches
// pretend private methods are not in the super vtable
// since we do override around them: e.g. a.m pub/b.m private/c.m pub,
@@ -502,7 +507,7 @@
// miranda methods are interface methods in a class's vtable
if (mhk->is_interface()) {
- assert(m->is_public() && m->is_abstract(), "should be public and abstract");
+ assert(m->is_public(), "should be public");
assert(ik()->implements_interface(method_holder) , "this class should implement the interface");
assert(is_miranda(m, ik()->methods(), ik()->super()), "should be a miranda_method");
return true;
@@ -532,19 +537,19 @@
return false;
}
-void klassVtable::add_new_mirandas_to_list(GrowableArray<Method*>* list_of_current_mirandas,
- Array<Method*>* current_interface_methods,
- Array<Method*>* class_methods,
- Klass* super) {
+void klassVtable::add_new_mirandas_to_lists(
+ GrowableArray<Method*>* new_mirandas, GrowableArray<Method*>* all_mirandas,
+ Array<Method*>* current_interface_methods, Array<Method*>* class_methods,
+ Klass* super) {
// iterate thru the current interface's method to see if it a miranda
int num_methods = current_interface_methods->length();
for (int i = 0; i < num_methods; i++) {
Method* im = current_interface_methods->at(i);
bool is_duplicate = false;
- int num_of_current_mirandas = list_of_current_mirandas->length();
+ int num_of_current_mirandas = new_mirandas->length();
// check for duplicate mirandas in different interfaces we implement
for (int j = 0; j < num_of_current_mirandas; j++) {
- Method* miranda = list_of_current_mirandas->at(j);
+ Method* miranda = new_mirandas->at(j);
if ((im->name() == miranda->name()) &&
(im->signature() == miranda->signature())) {
is_duplicate = true;
@@ -557,51 +562,47 @@
InstanceKlass *sk = InstanceKlass::cast(super);
// check if it is a duplicate of a super's miranda
if (sk->lookup_method_in_all_interfaces(im->name(), im->signature()) == NULL) {
- list_of_current_mirandas->append(im);
+ new_mirandas->append(im);
+ }
+ if (all_mirandas != NULL) {
+ all_mirandas->append(im);
}
}
}
}
}
-void klassVtable::get_mirandas(GrowableArray<Method*>* mirandas,
+void klassVtable::get_mirandas(GrowableArray<Method*>* new_mirandas,
+ GrowableArray<Method*>* all_mirandas,
Klass* super, Array<Method*>* class_methods,
Array<Klass*>* local_interfaces) {
- assert((mirandas->length() == 0) , "current mirandas must be 0");
+ assert((new_mirandas->length() == 0) , "current mirandas must be 0");
// iterate thru the local interfaces looking for a miranda
int num_local_ifs = local_interfaces->length();
for (int i = 0; i < num_local_ifs; i++) {
InstanceKlass *ik = InstanceKlass::cast(local_interfaces->at(i));
- add_new_mirandas_to_list(mirandas, ik->methods(), class_methods, super);
+ add_new_mirandas_to_lists(new_mirandas, all_mirandas,
+ ik->methods(), class_methods, super);
// iterate thru each local's super interfaces
Array<Klass*>* super_ifs = ik->transitive_interfaces();
int num_super_ifs = super_ifs->length();
for (int j = 0; j < num_super_ifs; j++) {
InstanceKlass *sik = InstanceKlass::cast(super_ifs->at(j));
- add_new_mirandas_to_list(mirandas, sik->methods(), class_methods, super);
+ add_new_mirandas_to_lists(new_mirandas, all_mirandas,
+ sik->methods(), class_methods, super);
}
}
}
-// get number of mirandas
-int klassVtable::get_num_mirandas(Klass* super, Array<Method*>* class_methods, Array<Klass*>* local_interfaces) {
- ResourceMark rm;
- GrowableArray<Method*>* mirandas = new GrowableArray<Method*>(20);
- get_mirandas(mirandas, super, class_methods, local_interfaces);
- return mirandas->length();
-}
-
// fill in mirandas
-void klassVtable::fill_in_mirandas(int& initialized) {
- ResourceMark rm;
- GrowableArray<Method*>* mirandas = new GrowableArray<Method*>(20);
- InstanceKlass *this_ik = ik();
- get_mirandas(mirandas, this_ik->super(), this_ik->methods(), this_ik->local_interfaces());
- int num_mirandas = mirandas->length();
- for (int i = 0; i < num_mirandas; i++) {
- put_method_at(mirandas->at(i), initialized);
- initialized++;
+void klassVtable::fill_in_mirandas(int* initialized) {
+ GrowableArray<Method*> mirandas(20);
+ get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(),
+ ik()->local_interfaces());
+ for (int i = 0; i < mirandas.length(); i++) {
+ put_method_at(mirandas.at(i), *initialized);
+ ++(*initialized);
}
}
@@ -629,7 +630,7 @@
if (!(*trace_name_printed)) {
// RC_TRACE_MESG macro has an embedded ResourceMark
RC_TRACE_MESG(("adjust: name=%s",
- Klass::cast(old_method->method_holder())->external_name()));
+ old_method->method_holder()->external_name()));
*trace_name_printed = true;
}
// RC_TRACE macro has an embedded ResourceMark
@@ -744,8 +745,8 @@
Method* target = klass->uncached_lookup_method(method_name, method_signature);
while (target != NULL && target->is_static()) {
// continue with recursive lookup through the superclass
- Klass* super = Klass::cast(target->method_holder())->super();
- target = (super == NULL) ? (Method*)NULL : Klass::cast(super)->uncached_lookup_method(method_name, method_signature);
+ Klass* super = target->method_holder()->super();
+ target = (super == NULL) ? (Method*)NULL : super->uncached_lookup_method(method_name, method_signature);
}
if (target == NULL || !target->is_public() || target->is_abstract()) {
// Entry do not resolve. Leave it empty
@@ -754,7 +755,7 @@
// if checkconstraints requested
methodHandle target_h (THREAD, target); // preserve across gc
if (checkconstraints) {
- Handle method_holder_loader (THREAD, InstanceKlass::cast(target->method_holder())->class_loader());
+ Handle method_holder_loader (THREAD, target->method_holder()->class_loader());
if (method_holder_loader() != interface_loader()) {
ResourceMark rm(THREAD);
char* failed_type_name =
@@ -824,7 +825,7 @@
if (!(*trace_name_printed)) {
// RC_TRACE_MESG macro has an embedded ResourceMark
RC_TRACE_MESG(("adjust: name=%s",
- Klass::cast(old_method->method_holder())->external_name()));
+ old_method->method_holder()->external_name()));
*trace_name_printed = true;
}
// RC_TRACE macro has an embedded ResourceMark
@@ -851,7 +852,7 @@
// Handle array argument
for(int i = 0; i < transitive_intf->length(); i++) {
Klass* intf = transitive_intf->at(i);
- assert(Klass::cast(intf)->is_interface(), "sanity check");
+ assert(intf->is_interface(), "sanity check");
// Find no. of methods excluding a <clinit>
int method_count = InstanceKlass::cast(intf)->methods()->length();
@@ -959,9 +960,9 @@
// m must be a method in an interface
int klassItable::compute_itable_index(Method* m) {
- Klass* intf = m->method_holder();
- assert(InstanceKlass::cast(intf)->is_interface(), "sanity check");
- Array<Method*>* methods = InstanceKlass::cast(intf)->methods();
+ InstanceKlass* intf = m->method_holder();
+ assert(intf->is_interface(), "sanity check");
+ Array<Method*>* methods = intf->methods();
int index = 0;
while(methods->at(index) != m) {
index++;
--- a/hotspot/src/share/vm/oops/klassVtable.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/klassVtable.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -84,11 +84,11 @@
bool is_initialized();
// computes vtable length (in words) and the number of miranda methods
- static void compute_vtable_size_and_num_mirandas(int &vtable_length, int &num_miranda_methods,
- Klass* super, Array<Method*>* methods,
- AccessFlags class_flags, Handle classloader,
- Symbol* classname, Array<Klass*>* local_interfaces,
- TRAPS);
+ static void compute_vtable_size_and_num_mirandas(
+ int* vtable_length, int* num_new_mirandas,
+ GrowableArray<Method*>* all_mirandas, Klass* super,
+ Array<Method*>* methods, AccessFlags class_flags, Handle classloader,
+ Symbol* classname, Array<Klass*>* local_interfaces, TRAPS);
// RedefineClasses() API support:
// If any entry of this vtable points to any of old_methods,
@@ -125,12 +125,17 @@
// support for miranda methods
bool is_miranda_entry_at(int i);
- void fill_in_mirandas(int& initialized);
+ void fill_in_mirandas(int* initialized);
static bool is_miranda(Method* m, Array<Method*>* class_methods, Klass* super);
- static void add_new_mirandas_to_list(GrowableArray<Method*>* list_of_current_mirandas, Array<Method*>* current_interface_methods, Array<Method*>* class_methods, Klass* super);
- static void get_mirandas(GrowableArray<Method*>* mirandas, Klass* super, Array<Method*>* class_methods, Array<Klass*>* local_interfaces);
- static int get_num_mirandas(Klass* super, Array<Method*>* class_methods, Array<Klass*>* local_interfaces);
-
+ static void add_new_mirandas_to_lists(
+ GrowableArray<Method*>* new_mirandas,
+ GrowableArray<Method*>* all_mirandas,
+ Array<Method*>* current_interface_methods, Array<Method*>* class_methods,
+ Klass* super);
+ static void get_mirandas(
+ GrowableArray<Method*>* new_mirandas,
+ GrowableArray<Method*>* all_mirandas, Klass* super,
+ Array<Method*>* class_methods, Array<Klass*>* local_interfaces);
void verify_against(outputStream* st, klassVtable* vt, int index);
inline InstanceKlass* ik() const;
--- a/hotspot/src/share/vm/oops/method.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/method.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -35,6 +35,7 @@
#include "memory/generation.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
+#include "oops/constMethod.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
@@ -57,22 +58,24 @@
// Implementation of Method
Method* Method::allocate(ClassLoaderData* loader_data,
- int byte_code_size,
- AccessFlags access_flags,
- int compressed_line_number_size,
- int localvariable_table_length,
- int exception_table_length,
- int checked_exceptions_length,
- TRAPS) {
+ int byte_code_size,
+ AccessFlags access_flags,
+ int compressed_line_number_size,
+ int localvariable_table_length,
+ int exception_table_length,
+ int checked_exceptions_length,
+ ConstMethod::MethodType method_type,
+ TRAPS) {
assert(!access_flags.is_native() || byte_code_size == 0,
"native methods should not contain byte codes");
ConstMethod* cm = ConstMethod::allocate(loader_data,
- byte_code_size,
- compressed_line_number_size,
- localvariable_table_length,
- exception_table_length,
- checked_exceptions_length,
- CHECK_NULL);
+ byte_code_size,
+ compressed_line_number_size,
+ localvariable_table_length,
+ exception_table_length,
+ checked_exceptions_length,
+ method_type,
+ CHECK_NULL);
int size = Method::size(access_flags.is_native());
@@ -149,11 +152,11 @@
}
char* Method::name_and_sig_as_C_string() const {
- return name_and_sig_as_C_string(Klass::cast(constants()->pool_holder()), name(), signature());
+ return name_and_sig_as_C_string(constants()->pool_holder(), name(), signature());
}
char* Method::name_and_sig_as_C_string(char* buf, int size) const {
- return name_and_sig_as_C_string(Klass::cast(constants()->pool_holder()), name(), signature(), buf, size);
+ return name_and_sig_as_C_string(constants()->pool_holder(), name(), signature(), buf, size);
}
char* Method::name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature) {
@@ -240,12 +243,12 @@
warning("oopmap should only be accessed by the "
"VM, GC task or CMS threads (or during debugging)");
InterpreterOopMap local_mask;
- InstanceKlass::cast(method_holder())->mask_for(h_this, bci, &local_mask);
+ method_holder()->mask_for(h_this, bci, &local_mask);
local_mask.print();
}
}
#endif
- InstanceKlass::cast(method_holder())->mask_for(h_this, bci, mask);
+ method_holder()->mask_for(h_this, bci, mask);
return;
}
@@ -520,7 +523,7 @@
bool Method::is_final_method() const {
// %%% Should return true for private methods also,
// since there is no way to override them.
- return is_final() || Klass::cast(method_holder())->is_final();
+ return is_final() || method_holder()->is_final();
}
@@ -552,7 +555,7 @@
bool Method::has_valid_initializer_flags() const {
return (is_static() ||
- InstanceKlass::cast(method_holder())->major_version() < 51);
+ method_holder()->major_version() < 51);
}
bool Method::is_static_initializer() const {
@@ -575,8 +578,8 @@
for (int i = 0; i < length; i++) {
CheckedExceptionElement* table = h_this->checked_exceptions_start(); // recompute on each iteration, not gc safe
Klass* k = h_this->constants()->klass_at(table[i].class_cp_index, CHECK_(objArrayHandle()));
- assert(Klass::cast(k)->is_subclass_of(SystemDictionary::Throwable_klass()), "invalid exception class");
- mirrors->obj_at_put(i, Klass::cast(k)->java_mirror());
+ assert(k->is_subclass_of(SystemDictionary::Throwable_klass()), "invalid exception class");
+ mirrors->obj_at_put(i, k->java_mirror());
}
return mirrors;
}
@@ -614,8 +617,8 @@
if( constants()->tag_at(klass_index).is_unresolved_klass() ) {
Thread *thread = Thread::current();
Symbol* klass_name = constants()->klass_name_at(klass_index);
- Handle loader(thread, InstanceKlass::cast(method_holder())->class_loader());
- Handle prot (thread, Klass::cast(method_holder())->protection_domain());
+ Handle loader(thread, method_holder()->class_loader());
+ Handle prot (thread, method_holder()->protection_domain());
return SystemDictionary::find(klass_name, loader, prot, thread) != NULL;
} else {
return true;
@@ -932,7 +935,7 @@
// If method is an interface, we skip it - except if it
// is a miranda method
- if (InstanceKlass::cast(method_holder())->is_interface()) {
+ if (method_holder()->is_interface()) {
// Check that method is not a miranda method
if (ik->lookup_method(name(), signature()) == NULL) {
// No implementation exist - so miranda method
@@ -1017,7 +1020,7 @@
ConstantPool* cp_oop = ConstantPool::allocate(loader_data, cp_length, CHECK_(empty));
cp = constantPoolHandle(THREAD, cp_oop);
}
- cp->set_pool_holder(holder());
+ cp->set_pool_holder(InstanceKlass::cast(holder()));
cp->symbol_at_put(_imcp_invoke_name, name);
cp->symbol_at_put(_imcp_invoke_signature, signature);
cp->set_preresolution();
@@ -1031,7 +1034,7 @@
methodHandle m;
{
Method* m_oop = Method::allocate(loader_data, 0, accessFlags_from(flags_bits),
- 0, 0, 0, 0, CHECK_(empty));
+ 0, 0, 0, 0, ConstMethod::NORMAL, CHECK_(empty));
m = methodHandle(THREAD, m_oop);
}
m->set_constants(cp());
@@ -1064,8 +1067,8 @@
}
Klass* Method::check_non_bcp_klass(Klass* klass) {
- if (klass != NULL && Klass::cast(klass)->class_loader() != NULL) {
- if (Klass::cast(klass)->oop_is_objArray())
+ if (klass != NULL && klass->class_loader() != NULL) {
+ if (klass->oop_is_objArray())
klass = ObjArrayKlass::cast(klass)->bottom_klass();
return klass;
}
@@ -1083,15 +1086,16 @@
int localvariable_len = m->localvariable_table_length();
int exception_table_len = m->exception_table_length();
- ClassLoaderData* loader_data = m()->method_holder()->class_loader_data();
+ ClassLoaderData* loader_data = m->method_holder()->class_loader_data();
Method* newm_oop = Method::allocate(loader_data,
- new_code_length,
- flags,
- new_compressed_linenumber_size,
- localvariable_len,
- exception_table_len,
- checked_exceptions_len,
- CHECK_(methodHandle()));
+ new_code_length,
+ flags,
+ new_compressed_linenumber_size,
+ localvariable_len,
+ exception_table_len,
+ checked_exceptions_len,
+ m->method_type(),
+ CHECK_(methodHandle()));
methodHandle newm (THREAD, newm_oop);
int new_method_size = newm->method_size();
@@ -1233,8 +1237,8 @@
return false;
}
bool sig_is_loaded = true;
- Handle class_loader(THREAD, InstanceKlass::cast(m->method_holder())->class_loader());
- Handle protection_domain(THREAD, Klass::cast(m->method_holder())->protection_domain());
+ Handle class_loader(THREAD, m->method_holder()->class_loader());
+ Handle protection_domain(THREAD, m->method_holder()->protection_domain());
ResourceMark rm(THREAD);
Symbol* signature = m->signature();
for(SignatureStream ss(signature); !ss.is_done(); ss.next()) {
@@ -1260,8 +1264,8 @@
}
bool Method::has_unloaded_classes_in_signature(methodHandle m, TRAPS) {
- Handle class_loader(THREAD, InstanceKlass::cast(m->method_holder())->class_loader());
- Handle protection_domain(THREAD, Klass::cast(m->method_holder())->protection_domain());
+ Handle class_loader(THREAD, m->method_holder()->class_loader());
+ Handle protection_domain(THREAD, m->method_holder()->protection_domain());
ResourceMark rm(THREAD);
Symbol* signature = m->signature();
for(SignatureStream ss(signature); !ss.is_done(); ss.next()) {
@@ -1468,7 +1472,7 @@
Bytecodes::Code Method::orig_bytecode_at(int bci) const {
- BreakpointInfo* bp = InstanceKlass::cast(method_holder())->breakpoints();
+ BreakpointInfo* bp = method_holder()->breakpoints();
for (; bp != NULL; bp = bp->next()) {
if (bp->match(this, bci)) {
return bp->orig_bytecode();
@@ -1480,7 +1484,7 @@
void Method::set_orig_bytecode_at(int bci, Bytecodes::Code code) {
assert(code != Bytecodes::_breakpoint, "cannot patch breakpoints this way");
- BreakpointInfo* bp = InstanceKlass::cast(method_holder())->breakpoints();
+ BreakpointInfo* bp = method_holder()->breakpoints();
for (; bp != NULL; bp = bp->next()) {
if (bp->match(this, bci)) {
bp->set_orig_bytecode(code);
@@ -1490,7 +1494,7 @@
}
void Method::set_breakpoint(int bci) {
- InstanceKlass* ik = InstanceKlass::cast(method_holder());
+ InstanceKlass* ik = method_holder();
BreakpointInfo *bp = new BreakpointInfo(this, bci);
bp->set_next(ik->breakpoints());
ik->set_breakpoints(bp);
@@ -1499,7 +1503,7 @@
}
static void clear_matches(Method* m, int bci) {
- InstanceKlass* ik = InstanceKlass::cast(m->method_holder());
+ InstanceKlass* ik = m->method_holder();
BreakpointInfo* prev_bp = NULL;
BreakpointInfo* next_bp;
for (BreakpointInfo* bp = ik->breakpoints(); bp != NULL; bp = next_bp) {
@@ -1782,7 +1786,7 @@
bool Method::is_method_id(jmethodID mid) {
Method* m = resolve_jmethod_id(mid);
assert(m != NULL, "should be called with non-null method");
- InstanceKlass* ik = InstanceKlass::cast(m->method_holder());
+ InstanceKlass* ik = m->method_holder();
ClassLoaderData* cld = ik->class_loader_data();
if (cld->jmethod_ids() == NULL) return false;
return (cld->jmethod_ids()->contains((Method**)mid));
--- a/hotspot/src/share/vm/oops/method.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/method.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -30,7 +30,6 @@
#include "compiler/oopMap.hpp"
#include "interpreter/invocationCounter.hpp"
#include "oops/annotations.hpp"
-#include "oops/constMethod.hpp"
#include "oops/constantPool.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/oop.hpp"
@@ -104,6 +103,7 @@
class LocalVariableTableElement;
class AdapterHandlerEntry;
class MethodData;
+class ConstMethod;
class Method : public Metadata {
friend class VMStructs;
@@ -158,14 +158,16 @@
// Constructor
Method(ConstMethod* xconst, AccessFlags access_flags, int size);
public:
+
static Method* allocate(ClassLoaderData* loader_data,
- int byte_code_size,
- AccessFlags access_flags,
- int compressed_line_number_size,
- int localvariable_table_length,
- int exception_table_length,
- int checked_exceptions_length,
- TRAPS);
+ int byte_code_size,
+ AccessFlags access_flags,
+ int compressed_line_number_size,
+ int localvariable_table_length,
+ int exception_table_length,
+ int checked_exceptions_length,
+ ConstMethod::MethodType method_type,
+ TRAPS);
Method() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
@@ -207,21 +209,21 @@
// annotations support
AnnotationArray* annotations() const {
- InstanceKlass* ik = InstanceKlass::cast(method_holder());
+ InstanceKlass* ik = method_holder();
if (ik->annotations() == NULL) {
return NULL;
}
return ik->annotations()->get_method_annotations_of(method_idnum());
}
AnnotationArray* parameter_annotations() const {
- InstanceKlass* ik = InstanceKlass::cast(method_holder());
+ InstanceKlass* ik = method_holder();
if (ik->annotations() == NULL) {
return NULL;
}
return ik->annotations()->get_method_parameter_annotations_of(method_idnum());
}
AnnotationArray* annotation_default() const {
- InstanceKlass* ik = InstanceKlass::cast(method_holder());
+ InstanceKlass* ik = method_holder();
if (ik->annotations() == NULL) {
return NULL;
}
@@ -494,7 +496,7 @@
{ return constMethod()->compressed_linenumber_table(); }
// method holder (the Klass* holding this method)
- Klass* method_holder() const { return constants()->pool_holder(); }
+ InstanceKlass* method_holder() const { return constants()->pool_holder(); }
void compute_size_of_parameters(Thread *thread); // word size of parameters (receiver if any + arguments)
Symbol* klass_name() const; // returns the name of the method holder
@@ -695,18 +697,18 @@
// Get this method's jmethodID -- allocate if it doesn't exist
jmethodID jmethod_id() { methodHandle this_h(this);
- return InstanceKlass::get_jmethod_id(InstanceKlass::cast(method_holder()), this_h); }
+ return InstanceKlass::get_jmethod_id(method_holder(), this_h); }
// Lookup the jmethodID for this method. Return NULL if not found.
// NOTE that this function can be called from a signal handler
// (see AsyncGetCallTrace support for Forte Analyzer) and this
// needs to be async-safe. No allocation should be done and
// so handles are not used to avoid deadlock.
- jmethodID find_jmethod_id_or_null() { return InstanceKlass::cast(method_holder())->jmethod_id_or_null(this); }
+ jmethodID find_jmethod_id_or_null() { return method_holder()->jmethod_id_or_null(this); }
// JNI static invoke cached itable index accessors
- int cached_itable_index() { return InstanceKlass::cast(method_holder())->cached_itable_index(method_idnum()); }
- void set_cached_itable_index(int index) { InstanceKlass::cast(method_holder())->set_cached_itable_index(method_idnum(), index); }
+ int cached_itable_index() { return method_holder()->cached_itable_index(method_idnum()); }
+ void set_cached_itable_index(int index) { method_holder()->set_cached_itable_index(method_idnum(), index); }
// Support for inlining of intrinsic methods
vmIntrinsics::ID intrinsic_id() const { return (vmIntrinsics::ID) _intrinsic_id; }
@@ -725,14 +727,18 @@
void set_dont_inline(bool x) { _dont_inline = x; }
bool is_hidden() { return _hidden; }
void set_hidden(bool x) { _hidden = x; }
+ ConstMethod::MethodType method_type() const {
+ return _constMethod->method_type();
+ }
+ bool is_overpass() const { return method_type() == ConstMethod::OVERPASS; }
// On-stack replacement support
bool has_osr_nmethod(int level, bool match_level) {
- return InstanceKlass::cast(method_holder())->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL;
+ return method_holder()->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL;
}
nmethod* lookup_osr_nmethod_for(int bci, int level, bool match_level) {
- return InstanceKlass::cast(method_holder())->lookup_osr_nmethod(this, bci, level, match_level);
+ return method_holder()->lookup_osr_nmethod(this, bci, level, match_level);
}
// Inline cache support
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -81,7 +81,7 @@
Array<Klass*>* element_supers = element_klass->secondary_supers();
for( int i = element_supers->length()-1; i >= 0; i-- ) {
Klass* elem_super = element_supers->at(i);
- if (Klass::cast(elem_super)->array_klass_or_null() == NULL) {
+ if (elem_super->array_klass_or_null() == NULL) {
supers_exist = false;
break;
}
@@ -172,7 +172,7 @@
} else {
bk = element_klass();
}
- assert(bk != NULL && (Klass::cast(bk)->oop_is_instance() || Klass::cast(bk)->oop_is_typeArray()), "invalid bottom klass");
+ assert(bk != NULL && (bk->oop_is_instance() || bk->oop_is_typeArray()), "invalid bottom klass");
this->set_bottom_klass(bk);
this->set_class_loader_data(bk->class_loader_data());
@@ -254,7 +254,7 @@
// We have to make sure all elements conform to the destination array
Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
Klass* stype = ObjArrayKlass::cast(s->klass())->element_klass();
- if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) {
+ if (stype == bound || stype->is_subtype_of(bound)) {
// elements are guaranteed to be subtypes, so no check necessary
bs->write_ref_array_pre(dst, length);
Copy::conjoint_oops_atomic(src, dst, length);
@@ -271,7 +271,7 @@
oop new_val = element_is_null ? oop(NULL)
: oopDesc::decode_heap_oop_not_null(element);
if (element_is_null ||
- Klass::cast((new_val->klass()))->is_subtype_of(bound)) {
+ (new_val->klass())->is_subtype_of(bound)) {
bs->write_ref_field_pre(p, new_val);
*p = *from;
} else {
@@ -381,7 +381,7 @@
GrowableArray<Klass*>* ObjArrayKlass::compute_secondary_supers(int num_extra_slots) {
// interfaces = { cloneable_klass, serializable_klass, elemSuper[], ... };
- Array<Klass*>* elem_supers = Klass::cast(element_klass())->secondary_supers();
+ Array<Klass*>* elem_supers = element_klass()->secondary_supers();
int num_elem_supers = elem_supers == NULL ? 0 : elem_supers->length();
int num_secondaries = num_extra_slots + 2 + num_elem_supers;
if (num_secondaries == 2) {
@@ -411,7 +411,7 @@
}
void ObjArrayKlass::initialize(TRAPS) {
- Klass::cast(bottom_klass())->initialize(THREAD); // dispatches to either InstanceKlass or TypeArrayKlass
+ bottom_klass()->initialize(THREAD); // dispatches to either InstanceKlass or TypeArrayKlass
}
#define ObjArrayKlass_SPECIALIZED_OOP_ITERATE(T, a, p, do_oop) \
@@ -607,7 +607,7 @@
return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC;
}
// Return the flags of the bottom element type.
- jint element_flags = Klass::cast(bottom_klass())->compute_modifier_flags(CHECK_0);
+ jint element_flags = bottom_klass()->compute_modifier_flags(CHECK_0);
return (element_flags & (JVM_ACC_PUBLIC | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED))
| (JVM_ACC_ABSTRACT | JVM_ACC_FINAL);
@@ -686,7 +686,7 @@
guarantee(element_klass()->is_klass(), "should be klass");
guarantee(bottom_klass()->is_metadata(), "should be in metaspace");
guarantee(bottom_klass()->is_klass(), "should be klass");
- Klass* bk = Klass::cast(bottom_klass());
+ Klass* bk = bottom_klass();
guarantee(bk->oop_is_instance() || bk->oop_is_typeArray(), "invalid bottom klass");
}
--- a/hotspot/src/share/vm/oops/objArrayKlass.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/objArrayKlass.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -74,7 +74,7 @@
void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
// Compute protection domain
- oop protection_domain() { return Klass::cast(bottom_klass())->protection_domain(); }
+ oop protection_domain() { return bottom_klass()->protection_domain(); }
private:
// Either oop or narrowOop depending on UseCompressedOops.
--- a/hotspot/src/share/vm/oops/symbol.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/symbol.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -153,17 +153,15 @@
void Symbol::print_symbol_on(outputStream* st) const {
st = st ? st : tty;
- int length = UTF8::unicode_length((const char*)bytes(), utf8_length());
- const char *ptr = (const char *)bytes();
- jchar value;
- for (int index = 0; index < length; index++) {
- ptr = UTF8::next(ptr, &value);
- if (value >= 32 && value < 127 || value == '\'' || value == '\\') {
- st->put(value);
- } else {
- st->print("\\u%04x", value);
- }
- }
+ st->print("%s", as_quoted_ascii());
+}
+
+char* Symbol::as_quoted_ascii() const {
+ const char *ptr = (const char *)&_body[0];
+ int quoted_length = UTF8::quoted_ascii_length(ptr, utf8_length());
+ char* result = NEW_RESOURCE_ARRAY(char, quoted_length + 1);
+ UTF8::as_quoted_ascii(ptr, result, quoted_length + 1);
+ return result;
}
jchar* Symbol::as_unicode(int& length) const {
--- a/hotspot/src/share/vm/oops/symbol.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/oops/symbol.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -189,6 +189,8 @@
// Use buf if needed buffer length is <= size.
char* as_C_string_flexible_buffer(Thread* t, char* buf, int size) const;
+ // Returns an escaped form of a Java string.
+ char* as_quoted_ascii() const;
// Returns a null terminated utf8 string in a resource array
char* as_utf8() const { return as_C_string(); }
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "ci/ciReplay.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "compiler/compileBroker.hpp"
@@ -150,7 +151,7 @@
} else {
// Not hot. Check for medium-sized pre-existing nmethod at cold sites.
if (callee_method->has_compiled_code() &&
- callee_method->instructions_size(CompLevel_full_optimization) > inline_small_code_size)
+ callee_method->instructions_size() > inline_small_code_size)
return "already compiled into a medium method";
}
if (size > max_inline_size) {
@@ -192,7 +193,7 @@
}
if (callee_method->has_compiled_code() &&
- callee_method->instructions_size(CompLevel_full_optimization) > InlineSmallCode) {
+ callee_method->instructions_size() > InlineSmallCode) {
wci_result->set_profit(wci_result->profit() * 0.1);
// %%% adjust wci_result->size()?
}
@@ -216,7 +217,7 @@
// Now perform checks which are heuristic
if (callee_method->has_compiled_code() &&
- callee_method->instructions_size(CompLevel_full_optimization) > InlineSmallCode) {
+ callee_method->instructions_size() > InlineSmallCode) {
return "already compiled into a big method";
}
@@ -235,6 +236,12 @@
return "disallowed by CompilerOracle";
}
+#ifndef PRODUCT
+ if (ciReplay::should_not_inline(callee_method)) {
+ return "disallowed by ciReplay";
+ }
+#endif
+
if (UseStringCache) {
// Do not inline StringCache::profile() method used only at the beginning.
if (callee_method->name() == ciSymbol::profile_name() &&
--- a/hotspot/src/share/vm/opto/doCall.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/opto/doCall.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -334,7 +334,7 @@
return true;
}
- assert(dest_method->will_link(method()->holder(), klass, bc()), "dest_method: typeflow responsibility");
+ assert(dest_method->is_loaded(), "dest_method: typeflow responsibility");
return false;
}
--- a/hotspot/src/share/vm/opto/escape.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/opto/escape.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1386,12 +1386,12 @@
// Non-escaped allocation returned from Java or runtime call have
// unknown values in fields.
for (EdgeIterator i(pta); i.has_next(); i.next()) {
- PointsToNode* ptn = i.get();
- if (ptn->is_Field() && ptn->as_Field()->is_oop()) {
- if (add_edge(ptn, phantom_obj)) {
+ PointsToNode* field = i.get();
+ if (field->is_Field() && field->as_Field()->is_oop()) {
+ if (add_edge(field, phantom_obj)) {
// New edge was added
new_edges++;
- add_field_uses_to_worklist(ptn->as_Field());
+ add_field_uses_to_worklist(field->as_Field());
}
}
}
@@ -1413,30 +1413,30 @@
// captured by Initialize node.
//
for (EdgeIterator i(pta); i.has_next(); i.next()) {
- PointsToNode* ptn = i.get(); // Field (AddP)
- if (!ptn->is_Field() || !ptn->as_Field()->is_oop())
+ PointsToNode* field = i.get(); // Field (AddP)
+ if (!field->is_Field() || !field->as_Field()->is_oop())
continue; // Not oop field
- int offset = ptn->as_Field()->offset();
+ int offset = field->as_Field()->offset();
if (offset == Type::OffsetBot) {
if (!visited_bottom_offset) {
// OffsetBot is used to reference array's element,
// always add reference to NULL to all Field nodes since we don't
// known which element is referenced.
- if (add_edge(ptn, null_obj)) {
+ if (add_edge(field, null_obj)) {
// New edge was added
new_edges++;
- add_field_uses_to_worklist(ptn->as_Field());
+ add_field_uses_to_worklist(field->as_Field());
visited_bottom_offset = true;
}
}
} else {
// Check only oop fields.
- const Type* adr_type = ptn->ideal_node()->as_AddP()->bottom_type();
+ const Type* adr_type = field->ideal_node()->as_AddP()->bottom_type();
if (adr_type->isa_rawptr()) {
#ifdef ASSERT
// Raw pointers are used for initializing stores so skip it
// since it should be recorded already
- Node* base = get_addp_base(ptn->ideal_node());
+ Node* base = get_addp_base(field->ideal_node());
assert(adr_type->isa_rawptr() && base->is_Proj() &&
(base->in(0) == alloc),"unexpected pointer type");
#endif
@@ -1446,10 +1446,54 @@
offsets_worklist.append(offset);
Node* value = NULL;
if (ini != NULL) {
- BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT;
- Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase);
- if (store != NULL && store->is_Store()) {
+ // StoreP::memory_type() == T_ADDRESS
+ BasicType ft = UseCompressedOops ? T_NARROWOOP : T_ADDRESS;
+ Node* store = ini->find_captured_store(offset, type2aelembytes(ft, true), phase);
+ // Make sure initializing store has the same type as this AddP.
+ // This AddP may reference non existing field because it is on a
+ // dead branch of bimorphic call which is not eliminated yet.
+ if (store != NULL && store->is_Store() &&
+ store->as_Store()->memory_type() == ft) {
value = store->in(MemNode::ValueIn);
+#ifdef ASSERT
+ if (VerifyConnectionGraph) {
+ // Verify that AddP already points to all objects the value points to.
+ PointsToNode* val = ptnode_adr(value->_idx);
+ assert((val != NULL), "should be processed already");
+ PointsToNode* missed_obj = NULL;
+ if (val->is_JavaObject()) {
+ if (!field->points_to(val->as_JavaObject())) {
+ missed_obj = val;
+ }
+ } else {
+ if (!val->is_LocalVar() || (val->edge_count() == 0)) {
+ tty->print_cr("----------init store has invalid value -----");
+ store->dump();
+ val->dump();
+ assert(val->is_LocalVar() && (val->edge_count() > 0), "should be processed already");
+ }
+ for (EdgeIterator j(val); j.has_next(); j.next()) {
+ PointsToNode* obj = j.get();
+ if (obj->is_JavaObject()) {
+ if (!field->points_to(obj->as_JavaObject())) {
+ missed_obj = obj;
+ break;
+ }
+ }
+ }
+ }
+ if (missed_obj != NULL) {
+ tty->print_cr("----------field---------------------------------");
+ field->dump();
+ tty->print_cr("----------missed referernce to object-----------");
+ missed_obj->dump();
+ tty->print_cr("----------object referernced by init store -----");
+ store->dump();
+ val->dump();
+ assert(!field->points_to(missed_obj->as_JavaObject()), "missed JavaObject reference");
+ }
+ }
+#endif
} else {
// There could be initializing stores which follow allocation.
// For example, a volatile field store is not collected
@@ -1462,10 +1506,10 @@
}
if (value == NULL) {
// A field's initializing value was not recorded. Add NULL.
- if (add_edge(ptn, null_obj)) {
+ if (add_edge(field, null_obj)) {
// New edge was added
new_edges++;
- add_field_uses_to_worklist(ptn->as_Field());
+ add_field_uses_to_worklist(field->as_Field());
}
}
}
@@ -1607,7 +1651,26 @@
}
// Verify that all fields have initializing values.
if (field->edge_count() == 0) {
+ tty->print_cr("----------field does not have references----------");
field->dump();
+ for (BaseIterator i(field); i.has_next(); i.next()) {
+ PointsToNode* base = i.get();
+ tty->print_cr("----------field has next base---------------------");
+ base->dump();
+ if (base->is_JavaObject() && (base != phantom_obj) && (base != null_obj)) {
+ tty->print_cr("----------base has fields-------------------------");
+ for (EdgeIterator j(base); j.has_next(); j.next()) {
+ j.get()->dump();
+ }
+ tty->print_cr("----------base has references---------------------");
+ for (UseIterator j(base); j.has_next(); j.next()) {
+ j.get()->dump();
+ }
+ }
+ }
+ for (UseIterator i(field); i.has_next(); i.next()) {
+ i.get()->dump();
+ }
assert(field->edge_count() > 0, "sanity");
}
}
@@ -1967,7 +2030,7 @@
if (is_JavaObject()) {
return (this == ptn);
}
- assert(is_LocalVar(), "sanity");
+ assert(is_LocalVar() || is_Field(), "sanity");
for (EdgeIterator i(this); i.has_next(); i.next()) {
if (i.get() == ptn)
return true;
@@ -3127,10 +3190,14 @@
EscapeState fields_es = fields_escape_state();
tty->print("%s(%s) ", esc_names[(int)es], esc_names[(int)fields_es]);
if (nt == PointsToNode::JavaObject && !this->scalar_replaceable())
- tty->print("NSR");
+ tty->print("NSR ");
}
if (is_Field()) {
FieldNode* f = (FieldNode*)this;
+ if (f->is_oop())
+ tty->print("oop ");
+ if (f->offset() > 0)
+ tty->print("+%d ", f->offset());
tty->print("(");
for (BaseIterator i(f); i.has_next(); i.next()) {
PointsToNode* b = i.get();
--- a/hotspot/src/share/vm/opto/runtime.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/opto/runtime.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -236,7 +236,7 @@
assert(check_compiled_frame(thread), "incorrect caller");
// These checks are cheap to make and support reflective allocation.
- int lh = Klass::cast(klass)->layout_helper();
+ int lh = klass->layout_helper();
if (Klass::layout_helper_needs_slow_path(lh)
|| !InstanceKlass::cast(klass)->is_initialized()) {
KlassHandle kh(THREAD, klass);
@@ -283,7 +283,7 @@
// Scavenge and allocate an instance.
oop result;
- if (Klass::cast(array_type)->oop_is_typeArray()) {
+ if (array_type->oop_is_typeArray()) {
// The oopFactory likes to work with the element type.
// (We could bypass the oopFactory, since it doesn't add much value.)
BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
@@ -321,7 +321,7 @@
// Scavenge and allocate an instance.
oop result;
- assert(Klass::cast(array_type)->oop_is_typeArray(), "should be called only for type array");
+ assert(array_type->oop_is_typeArray(), "should be called only for type array");
// The oopFactory likes to work with the element type.
BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
result = oopFactory::new_typeArray_nozero(elem_type, len, THREAD);
--- a/hotspot/src/share/vm/prims/jni.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/jni.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -24,6 +24,7 @@
*/
#include "precompiled.hpp"
+#include "ci/ciReplay.hpp"
#include "classfile/altHashing.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/javaClasses.hpp"
@@ -233,13 +234,13 @@
intptr_t jfieldIDWorkaround::encode_klass_hash(Klass* k, intptr_t offset) {
if (offset <= small_offset_mask) {
Klass* field_klass = k;
- Klass* super_klass = Klass::cast(field_klass)->super();
+ Klass* super_klass = field_klass->super();
// With compressed oops the most super class with nonstatic fields would
// be the owner of fields embedded in the header.
while (InstanceKlass::cast(super_klass)->has_nonstatic_fields() &&
InstanceKlass::cast(super_klass)->contains_field_offset(offset)) {
field_klass = super_klass; // super contains the field also
- super_klass = Klass::cast(field_klass)->super();
+ super_klass = field_klass->super();
}
debug_only(No_Safepoint_Verifier nosafepoint;)
uintptr_t klass_hash = field_klass->identity_hash();
@@ -249,7 +250,7 @@
#ifndef PRODUCT
{
ResourceMark rm;
- warning("VerifyJNIFields: long offset %d in %s", offset, Klass::cast(k)->external_name());
+ warning("VerifyJNIFields: long offset %d in %s", offset, k->external_name());
}
#endif
#endif
@@ -265,7 +266,7 @@
// Could use a non-blocking query for identity_hash here...
if ((k->identity_hash() & klass_mask) == klass_hash)
return true;
- k = Klass::cast(k)->super();
+ k = k->super();
} while (k != NULL);
return false;
}
@@ -283,7 +284,7 @@
#ifndef PRODUCT
if (Verbose) {
ResourceMark rm;
- warning("VerifyJNIFields: unverified offset %d for %s", offset, Klass::cast(k)->external_name());
+ warning("VerifyJNIFields: unverified offset %d for %s", offset, k->external_name());
}
#endif
#endif
@@ -415,7 +416,7 @@
}
cls = (jclass)JNIHandles::make_local(
- env, Klass::cast(k)->java_mirror());
+ env, k->java_mirror());
return cls;
JNI_END
@@ -536,7 +537,7 @@
KlassHandle k1(THREAD, k);
// Make sure class is initialized before handing id's out to methods
- Klass::cast(k1())->initialize(CHECK_NULL);
+ k1()->initialize(CHECK_NULL);
Method* m = InstanceKlass::cast(k1())->method_with_idnum(slot);
ret = m==NULL? NULL : m->jmethod_id(); // return NULL if reflected method deleted
return ret;
@@ -569,7 +570,7 @@
KlassHandle k1(THREAD, k);
// Make sure class is initialized before handing id's out to fields
- Klass::cast(k1())->initialize(CHECK_NULL);
+ k1()->initialize(CHECK_NULL);
// First check if this is a static field
if (modifiers & JVM_ACC_STATIC) {
@@ -648,17 +649,17 @@
// interfaces return NULL
// proper classes return Klass::super()
Klass* k = java_lang_Class::as_Klass(mirror);
- if (Klass::cast(k)->is_interface()) return NULL;
+ if (k->is_interface()) return NULL;
// return mirror for superclass
- Klass* super = Klass::cast(k)->java_super();
+ Klass* super = k->java_super();
// super2 is the value computed by the compiler's getSuperClass intrinsic:
- debug_only(Klass* super2 = ( Klass::cast(k)->oop_is_array()
+ debug_only(Klass* super2 = ( k->oop_is_array()
? SystemDictionary::Object_klass()
- : Klass::cast(k)->super() ) );
+ : k->super() ) );
assert(super == super2,
"java_super computation depends on interface, array, other super");
- obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(Klass::cast(super)->java_mirror());
+ obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(super->java_mirror());
return obj;
JNI_END
@@ -686,7 +687,7 @@
Klass* sub_klass = java_lang_Class::as_Klass(sub_mirror);
Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
- jboolean ret = Klass::cast(sub_klass)->is_subtype_of(super_klass) ?
+ jboolean ret = sub_klass->is_subtype_of(super_klass) ?
JNI_TRUE : JNI_FALSE;
#ifndef USDT2
DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret);
@@ -820,7 +821,7 @@
ResourceMark rm(THREAD);
jio_fprintf(defaultStream::error_stream(),
". Uncaught exception of type %s.",
- Klass::cast(ex->klass())->external_name());
+ ex->klass()->external_name());
}
}
}
@@ -1358,7 +1359,7 @@
Method* m = Method::resolve_jmethod_id(method_id);
number_of_parameters = m->size_of_parameters();
Klass* holder = m->method_holder();
- if (!(Klass::cast(holder))->is_interface()) {
+ if (!(holder)->is_interface()) {
// non-interface call -- for that little speed boost, don't handlize
debug_only(No_Safepoint_Verifier nosafepoint;)
if (call_type == JNI_VIRTUAL) {
@@ -1423,7 +1424,7 @@
static instanceOop alloc_object(jclass clazz, TRAPS) {
KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
- Klass::cast(k())->check_valid_for_instantiation(false, CHECK_NULL);
+ k()->check_valid_for_instantiation(false, CHECK_NULL);
InstanceKlass::cast(k())->initialize(CHECK_NULL);
instanceOop ih = InstanceKlass::cast(k())->allocate_instance(THREAD);
return ih;
@@ -1545,7 +1546,7 @@
#endif /* USDT2 */
Klass* k = JNIHandles::resolve_non_null(obj)->klass();
jclass ret =
- (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror());
+ (jclass) JNIHandles::make_local(env, k->java_mirror());
#ifndef USDT2
DTRACE_PROBE1(hotspot_jni, GetObjectClass__return, ret);
#else /* USDT2 */
@@ -1610,7 +1611,7 @@
// Make sure class is linked and initialized before handing id's out to
// Method*s.
- Klass::cast(klass())->initialize(CHECK_NULL);
+ klass()->initialize(CHECK_NULL);
Method* m;
if (name == vmSymbols::object_initializer_name() ||
@@ -2426,7 +2427,7 @@
JNI_ArgumentPusherVaArg ap(methodID, args); \
/* Make sure class is initialized before trying to invoke its method */ \
KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls))); \
- Klass::cast(k())->initialize(CHECK_0); \
+ k()->initialize(CHECK_0); \
jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
va_end(args); \
ret = jvalue.get_##ResultType(); \
@@ -2611,10 +2612,10 @@
KlassHandle k(THREAD,
java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
// Make sure class is initialized before handing id's out to fields
- Klass::cast(k())->initialize(CHECK_NULL);
+ k()->initialize(CHECK_NULL);
fieldDescriptor fd;
- if (!Klass::cast(k())->oop_is_instance() ||
+ if (!k()->oop_is_instance() ||
!InstanceKlass::cast(k())->find_field(fieldname, signame, false, &fd)) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
}
@@ -2976,16 +2977,16 @@
KlassHandle k(THREAD,
java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
// Make sure class is initialized before handing id's out to static fields
- Klass::cast(k())->initialize(CHECK_NULL);
+ k()->initialize(CHECK_NULL);
fieldDescriptor fd;
- if (!Klass::cast(k())->oop_is_instance() ||
+ if (!k()->oop_is_instance() ||
!InstanceKlass::cast(k())->find_field(fieldname, signame, true, &fd)) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
}
// A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
- JNIid* id = InstanceKlass::cast(fd.field_holder())->jni_id_for(fd.offset());
+ JNIid* id = fd.field_holder()->jni_id_for(fd.offset());
debug_only(id->set_is_static_field_id();)
debug_only(id->verify(fd.field_holder()));
@@ -3439,7 +3440,7 @@
jobjectArray ret = NULL;
DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret);
KlassHandle ek(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass)));
- Klass* ako = Klass::cast(ek())->array_klass(CHECK_NULL);
+ Klass* ako = ek()->array_klass(CHECK_NULL);
KlassHandle ak = KlassHandle(THREAD, ako);
ObjArrayKlass::cast(ak())->initialize(CHECK_NULL);
objArrayOop result = ObjArrayKlass::cast(ak())->allocate(length, CHECK_NULL);
@@ -3970,7 +3971,7 @@
if (trial_name == NULL) {
continue; // no such symbol, so this prefix wasn't used, try the next prefix
}
- method = Klass::cast(k())->lookup_method(trial_name, signature);
+ method = k()->lookup_method(trial_name, signature);
if (method == NULL) {
continue; // signature doesn't match, try the next prefix
}
@@ -3987,12 +3988,12 @@
}
static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, address entry, TRAPS) {
- Method* method = Klass::cast(k())->lookup_method(name, signature);
+ Method* method = k()->lookup_method(name, signature);
if (method == NULL) {
ResourceMark rm;
stringStream st;
st.print("Method %s name or signature does not match",
- Method::name_and_sig_as_C_string(Klass::cast(k()), name, signature));
+ Method::name_and_sig_as_C_string(k(), name, signature));
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
}
if (!method->is_native()) {
@@ -4002,7 +4003,7 @@
ResourceMark rm;
stringStream st;
st.print("Method %s is not declared as native",
- Method::name_and_sig_as_C_string(Klass::cast(k()), name, signature));
+ Method::name_and_sig_as_C_string(k(), name, signature));
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
}
}
@@ -4016,7 +4017,7 @@
if (PrintJNIResolving) {
ResourceMark rm(THREAD);
tty->print_cr("[Registering JNI native method %s.%s]",
- Klass::cast(method->method_holder())->external_name(),
+ method->method_holder()->external_name(),
method->name()->as_C_string());
}
return true;
@@ -4058,7 +4059,7 @@
if (name == NULL || signature == NULL) {
ResourceMark rm;
stringStream st;
- st.print("Method %s.%s%s not found", Klass::cast(h_k())->external_name(), meth_name, meth_sig);
+ st.print("Method %s.%s%s not found", h_k()->external_name(), meth_name, meth_sig);
// Must return negative value on failure
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);
}
@@ -4084,7 +4085,7 @@
#endif /* USDT2 */
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
//%note jni_2
- if (Klass::cast(k)->oop_is_instance()) {
+ if (k->oop_is_instance()) {
for (int index = 0; index < InstanceKlass::cast(k)->methods()->length(); index++) {
Method* m = InstanceKlass::cast(k)->methods()->at(index);
if (m->is_native()) {
@@ -5151,6 +5152,7 @@
// Check if we should compile all classes on bootclasspath
NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();)
+ NOT_PRODUCT(if (ReplayCompiles) ciReplay::replay(thread);)
// Since this is not a JVM_ENTRY we have to set the thread state manually before leaving.
ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
} else {
--- a/hotspot/src/share/vm/prims/jniCheck.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -383,7 +383,7 @@
ASSERT_OOPS_ALLOWED;
assert(klass != NULL, "klass argument must have a value");
- if (!Klass::cast(klass)->oop_is_instance() ||
+ if (!klass->oop_is_instance() ||
!InstanceKlass::cast(klass)->is_subclass_of(SystemDictionary::Throwable_klass())) {
ReportJNIFatalError(thr, fatal_class_not_a_throwable_class);
}
--- a/hotspot/src/share/vm/prims/jvm.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/jvm.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -125,7 +125,7 @@
int line_number = -1;
const char * source_file = NULL;
const char * trace = "explicit";
- Klass* caller = NULL;
+ InstanceKlass* caller = NULL;
JavaThread* jthread = JavaThread::current();
if (jthread->has_last_Java_frame()) {
vframeStream vfst(jthread);
@@ -153,17 +153,17 @@
// that caller, otherwise keep quiet since this should be picked up elsewhere.
bool found_it = false;
if (!vfst.at_end() &&
- InstanceKlass::cast(vfst.method()->method_holder())->name() == vmSymbols::java_lang_Class() &&
+ vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class() &&
vfst.method()->name() == vmSymbols::forName0_name()) {
vfst.next();
if (!vfst.at_end() &&
- InstanceKlass::cast(vfst.method()->method_holder())->name() == vmSymbols::java_lang_Class() &&
+ vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class() &&
vfst.method()->name() == vmSymbols::forName_name()) {
vfst.next();
found_it = true;
}
} else if (last_caller != NULL &&
- InstanceKlass::cast(last_caller->method_holder())->name() ==
+ last_caller->method_holder()->name() ==
vmSymbols::java_lang_ClassLoader() &&
(last_caller->name() == vmSymbols::loadClassInternal_name() ||
last_caller->name() == vmSymbols::loadClass_name())) {
@@ -182,7 +182,7 @@
// show method name if it's a native method
trace = vfst.method()->name_and_sig_as_C_string();
}
- Symbol* s = InstanceKlass::cast(caller)->source_file_name();
+ Symbol* s = caller->source_file_name();
if (s != NULL) {
source_file = s->as_C_string();
}
@@ -190,8 +190,8 @@
}
if (caller != NULL) {
if (to_class != caller) {
- const char * from = Klass::cast(caller)->external_name();
- const char * to = Klass::cast(to_class)->external_name();
+ const char * from = caller->external_name();
+ const char * to = to_class->external_name();
// print in a single call to reduce interleaving between threads
if (source_file != NULL) {
tty->print("RESOLVE %s %s %s:%d (%s)\n", from, to, source_file, line_number, trace);
@@ -305,7 +305,7 @@
assert(s->is_oop(), "JVM_ArrayCopy: src not an oop");
assert(d->is_oop(), "JVM_ArrayCopy: dst not an oop");
// Do copy
- Klass::cast(s->klass())->copy_array(s, src_pos, d, dst_pos, length, thread);
+ s->klass()->copy_array(s, src_pos, d, dst_pos, length, thread);
JVM_END
@@ -675,7 +675,7 @@
JVM_ENTRY(jclass, JVM_GetCallerClass(JNIEnv* env, int depth))
JVMWrapper("JVM_GetCallerClass");
Klass* k = thread->security_get_caller_class(depth);
- return (k == NULL) ? NULL : (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror());
+ return (k == NULL) ? NULL : (jclass) JNIHandles::make_local(env, k->java_mirror());
JVM_END
@@ -739,7 +739,7 @@
if (TraceClassResolution) {
trace_class_resolution(k);
}
- return (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror());
+ return (jclass) JNIHandles::make_local(env, k->java_mirror());
JVM_END
JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,
@@ -785,8 +785,8 @@
oop class_loader = NULL;
oop protection_domain = NULL;
if (from_class != NULL) {
- class_loader = Klass::cast(from_class)->class_loader();
- protection_domain = Klass::cast(from_class)->protection_domain();
+ class_loader = from_class->class_loader();
+ protection_domain = from_class->protection_domain();
}
Handle h_loader(THREAD, class_loader);
Handle h_prot (THREAD, protection_domain);
@@ -798,11 +798,11 @@
ResourceMark rm;
oop from_mirror = JNIHandles::resolve_non_null(from);
Klass* from_class = java_lang_Class::as_Klass(from_mirror);
- const char * from_name = Klass::cast(from_class)->external_name();
+ const char * from_name = from_class->external_name();
oop mirror = JNIHandles::resolve_non_null(result);
Klass* to_class = java_lang_Class::as_Klass(mirror);
- const char * to = Klass::cast(to_class)->external_name();
+ const char * to = to_class->external_name();
tty->print("RESOLVE %s %s (verification)\n", from_name, to);
}
@@ -875,7 +875,7 @@
trace_class_resolution(k);
}
- return (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror());
+ return (jclass) JNIHandles::make_local(env, k->java_mirror());
}
@@ -936,7 +936,7 @@
CHECK_NULL);
return (k == NULL) ? NULL :
- (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror());
+ (jclass) JNIHandles::make_local(env, k->java_mirror());
JVM_END
@@ -954,7 +954,7 @@
// Consider caching interned string in Klass
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
assert(k->is_klass(), "just checking");
- name = Klass::cast(k)->external_name();
+ name = k->external_name();
}
oop result = StringTable::intern((char*) name, CHECK_NULL);
return (jstring) JNIHandles::make_local(env, result);
@@ -991,12 +991,12 @@
// Regular instance klass, fill in all local interfaces
for (int index = 0; index < size; index++) {
Klass* k = InstanceKlass::cast(klass())->local_interfaces()->at(index);
- result->obj_at_put(index, Klass::cast(k)->java_mirror());
+ result->obj_at_put(index, k->java_mirror());
}
} else {
// All arrays implement java.lang.Cloneable and java.io.Serializable
- result->obj_at_put(0, Klass::cast(SystemDictionary::Cloneable_klass())->java_mirror());
- result->obj_at_put(1, Klass::cast(SystemDictionary::Serializable_klass())->java_mirror());
+ result->obj_at_put(0, SystemDictionary::Cloneable_klass()->java_mirror());
+ result->obj_at_put(1, SystemDictionary::Serializable_klass()->java_mirror());
}
return (jobjectArray) JNIHandles::make_local(env, result());
JVM_END
@@ -1008,7 +1008,7 @@
return NULL;
}
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
- oop loader = Klass::cast(k)->class_loader();
+ oop loader = k->class_loader();
return JNIHandles::make_local(env, loader);
JVM_END
@@ -1020,8 +1020,8 @@
return JNI_FALSE;
}
Klass* k = java_lang_Class::as_Klass(mirror);
- jboolean result = Klass::cast(k)->is_interface();
- assert(!result || Klass::cast(k)->oop_is_instance(),
+ jboolean result = k->is_interface();
+ assert(!result || k->oop_is_instance(),
"all interfaces are instance types");
// The compiler intrinsic for isInterface tests the
// Klass::_access_flags bits in the same way.
@@ -1039,7 +1039,7 @@
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
objArrayOop signers = NULL;
- if (Klass::cast(k)->oop_is_instance()) {
+ if (k->oop_is_instance()) {
signers = InstanceKlass::cast(k)->signers();
}
@@ -1066,7 +1066,7 @@
// Signers are only set once, ClassLoader.java, and thus shouldn't
// be called with an array. Only the bootstrap loader creates arrays.
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
- if (Klass::cast(k)->oop_is_instance()) {
+ if (k->oop_is_instance()) {
InstanceKlass::cast(k)->set_signers(objArrayOop(JNIHandles::resolve(signers)));
}
}
@@ -1085,7 +1085,7 @@
}
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
- return (jobject) JNIHandles::make_local(env, Klass::cast(k)->protection_domain());
+ return (jobject) JNIHandles::make_local(env, k->protection_domain());
JVM_END
@@ -1101,7 +1101,7 @@
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
// cls won't be an array, as this called only from ClassLoader.defineClass
- if (Klass::cast(k)->oop_is_instance()) {
+ if (k->oop_is_instance()) {
oop pd = JNIHandles::resolve(protection_domain);
assert(pd == NULL || pd->is_oop(), "just checking");
InstanceKlass::cast(k)->set_protection_domain(pd);
@@ -1124,7 +1124,7 @@
Handle object (THREAD, JNIHandles::resolve(action));
// get run() method
- Method* m_oop = Klass::cast(object->klass())->uncached_lookup_method(
+ Method* m_oop = object->klass()->uncached_lookup_method(
vmSymbols::run_method_name(),
vmSymbols::void_object_signature());
methodHandle m (THREAD, m_oop);
@@ -1228,7 +1228,7 @@
privileged_context = Handle(thread, thread->privileged_stack_top()->privileged_context());
protection_domain = thread->privileged_stack_top()->protection_domain();
} else {
- protection_domain = InstanceKlass::cast(method->method_holder())->protection_domain();
+ protection_domain = method->method_holder()->protection_domain();
}
if ((previous_protection_domain != protection_domain) && (protection_domain != NULL)) {
@@ -1267,7 +1267,7 @@
JVM_QUICK_ENTRY(jboolean, JVM_IsArrayClass(JNIEnv *env, jclass cls))
JVMWrapper("JVM_IsArrayClass");
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
- return (k != NULL) && Klass::cast(k)->oop_is_array() ? true : false;
+ return (k != NULL) && k->oop_is_array() ? true : false;
JVM_END
@@ -1293,7 +1293,7 @@
return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC;
}
- Klass* k = Klass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)));
+ Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
debug_only(int computed_modifiers = k->compute_modifier_flags(CHECK_0));
assert(k->modifier_flags() == computed_modifiers, "modifiers cache is OK");
return k->modifier_flags();
@@ -1308,7 +1308,7 @@
// of an InstanceKlass
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||
- ! Klass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)))->oop_is_instance()) {
+ ! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_instance()) {
oop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL);
return (jobjectArray)JNIHandles::make_local(env, result);
}
@@ -1372,7 +1372,7 @@
{
// ofClass is a reference to a java_lang_Class object.
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||
- ! Klass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)))->oop_is_instance()) {
+ ! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_instance()) {
return NULL;
}
@@ -1382,7 +1382,7 @@
)->compute_enclosing_class(&inner_is_member, CHECK_NULL);
if (outer_klass == NULL) return NULL; // already a top-level class
if (!inner_is_member) return NULL; // an anonymous class (inside a method)
- return (jclass) JNIHandles::make_local(env, Klass::cast(outer_klass)->java_mirror());
+ return (jclass) JNIHandles::make_local(env, outer_klass->java_mirror());
}
JVM_END
@@ -1452,7 +1452,7 @@
// Return null for arrays and primatives
if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
- if (Klass::cast(k)->oop_is_instance()) {
+ if (k->oop_is_instance()) {
Symbol* sym = InstanceKlass::cast(k)->generic_signature();
if (sym == NULL) return NULL;
Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);
@@ -1470,7 +1470,7 @@
// Return null for arrays and primitives
if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
- if (Klass::cast(k)->oop_is_instance()) {
+ if (k->oop_is_instance()) {
typeArrayOop a = Annotations::make_java_array(InstanceKlass::cast(k)->class_annotations(), CHECK_NULL);
return (jbyteArray) JNIHandles::make_local(env, a);
}
@@ -1583,7 +1583,7 @@
// Exclude primitive types and array types
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||
- Klass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)))->oop_is_array()) {
+ java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) {
// Return empty array
oop res = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), 0, CHECK_NULL);
return (jobjectArray) JNIHandles::make_local(env, res);
@@ -1646,7 +1646,7 @@
// Exclude primitive types and array types
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass))
- || Klass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)))->oop_is_array()) {
+ || java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) {
// Return empty array
oop res = oopFactory::new_objArray(SystemDictionary::reflect_Method_klass(), 0, CHECK_NULL);
return (jobjectArray) JNIHandles::make_local(env, res);
@@ -1698,7 +1698,7 @@
// Exclude primitive types and array types
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass))
- || Klass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)))->oop_is_array()) {
+ || java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) {
// Return empty array
oop res = oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), 0 , CHECK_NULL);
return (jobjectArray) JNIHandles::make_local(env, res);
@@ -1751,7 +1751,7 @@
return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC;
}
- Klass* k = Klass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)));
+ Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
return k->access_flags().as_int() & JVM_ACC_WRITTEN_FLAGS;
}
JVM_END
@@ -1767,7 +1767,7 @@
// Return null for primitives and arrays
if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
- if (Klass::cast(k)->oop_is_instance()) {
+ if (k->oop_is_instance()) {
instanceKlassHandle k_h(THREAD, k);
Handle jcp = sun_reflect_ConstantPool::create(CHECK_NULL);
sun_reflect_ConstantPool::set_cp(jcp(), k_h->constants());
@@ -2043,12 +2043,12 @@
if (java_lang_Class::is_primitive(r)) return false;
Klass* k = java_lang_Class::as_Klass(r);
- assert(Klass::cast(k)->oop_is_instance(), "must be an instance klass");
- if (! Klass::cast(k)->oop_is_instance()) return false;
+ assert(k->oop_is_instance(), "must be an instance klass");
+ if (! k->oop_is_instance()) return false;
ResourceMark rm(THREAD);
- const char* name = Klass::cast(k)->name()->as_C_string();
- bool system_class = Klass::cast(k)->class_loader() == NULL;
+ const char* name = k->name()->as_C_string();
+ bool system_class = k->class_loader() == NULL;
return JavaAssertions::enabled(name, system_class);
JVM_END
@@ -2079,7 +2079,7 @@
JVMWrapper("JVM_GetClassNameUTF");
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
- return Klass::cast(k)->name()->as_utf8();
+ return k->name()->as_utf8();
JVM_END
@@ -2089,7 +2089,7 @@
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
// types will have length zero if this is not an InstanceKlass
// (length is determined by call to JVM_GetClassCPEntriesCount)
- if (Klass::cast(k)->oop_is_instance()) {
+ if (k->oop_is_instance()) {
ConstantPool* cp = InstanceKlass::cast(k)->constants();
for (int index = cp->length() - 1; index >= 0; index--) {
constantTag tag = cp->tag_at(index);
@@ -2103,7 +2103,7 @@
JVMWrapper("JVM_GetClassCPEntriesCount");
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
- if (!Klass::cast(k)->oop_is_instance())
+ if (!k->oop_is_instance())
return 0;
return InstanceKlass::cast(k)->constants()->length();
JVM_END
@@ -2113,7 +2113,7 @@
JVMWrapper("JVM_GetClassFieldsCount");
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
- if (!Klass::cast(k)->oop_is_instance())
+ if (!k->oop_is_instance())
return 0;
return InstanceKlass::cast(k)->java_fields_count();
JVM_END
@@ -2123,7 +2123,7 @@
JVMWrapper("JVM_GetClassMethodsCount");
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
- if (!Klass::cast(k)->oop_is_instance())
+ if (!k->oop_is_instance())
return 0;
return InstanceKlass::cast(k)->methods()->length();
JVM_END
@@ -3048,10 +3048,10 @@
Method* m = vfst.method();
if (!m->is_native()) {
- Klass* holder = m->method_holder();
- oop loader = InstanceKlass::cast(holder)->class_loader();
+ InstanceKlass* holder = m->method_holder();
+ oop loader = holder->class_loader();
if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) {
- return (jclass) JNIHandles::make_local(env, Klass::cast(holder)->java_mirror());
+ return (jclass) JNIHandles::make_local(env, holder->java_mirror());
}
}
}
@@ -3071,9 +3071,9 @@
Method* m = vfst.method();
if (!m->is_native()) {
- Klass* holder = m->method_holder();
+ InstanceKlass* holder = m->method_holder();
assert(holder->is_klass(), "just checking");
- oop loader = InstanceKlass::cast(holder)->class_loader();
+ oop loader = holder->class_loader();
if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) {
return JNIHandles::make_local(env, loader);
}
@@ -3123,7 +3123,7 @@
// Fill in mirrors corresponding to method holders
int index = 0;
while (first != NULL) {
- result->obj_at_put(index++, Klass::cast(first->klass())->java_mirror());
+ result->obj_at_put(index++, first->klass()->java_mirror());
first = first->next;
}
assert(index == depth, "just checking");
@@ -3148,9 +3148,9 @@
for(vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
if (!vfst.method()->is_native()) {
- Klass* holder = vfst.method()->method_holder();
+ InstanceKlass* holder = vfst.method()->method_holder();
assert(holder->is_klass(), "just checking");
- if (InstanceKlass::cast(holder)->name() == class_name_sym) {
+ if (holder->name() == class_name_sym) {
return depth;
}
depth++;
@@ -3171,9 +3171,9 @@
Method* m = vfst.method();
if (!m->is_native()) {
- Klass* holder = m->method_holder();
+ InstanceKlass* holder = m->method_holder();
assert(holder->is_klass(), "just checking");
- oop loader = InstanceKlass::cast(holder)->class_loader();
+ oop loader = holder->class_loader();
if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) {
return depth;
}
@@ -3217,7 +3217,7 @@
if (access.is_protected()) {
// See if current_class is a subclass of field_class
- if (Klass::cast(current_class)->is_subclass_of(field_class)) {
+ if (current_class->is_subclass_of(field_class)) {
return true;
}
}
@@ -3241,8 +3241,8 @@
}
// Arrays not allowed here, must use JVM_AllocateNewArray
- if (Klass::cast(java_lang_Class::as_Klass(curr_mirror))->oop_is_array() ||
- Klass::cast(java_lang_Class::as_Klass(init_mirror))->oop_is_array()) {
+ if (java_lang_Class::as_Klass(curr_mirror)->oop_is_array() ||
+ java_lang_Class::as_Klass(init_mirror)->oop_is_array()) {
ResourceMark rm(THREAD);
THROW_0(vmSymbols::java_lang_InvalidClassException());
}
@@ -3264,7 +3264,7 @@
if (m.is_null()) {
ResourceMark rm(THREAD);
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(),
- Method::name_and_sig_as_C_string(Klass::cast(init_klass()),
+ Method::name_and_sig_as_C_string(init_klass(),
vmSymbols::object_initializer_name(),
vmSymbols::void_method_signature()));
}
@@ -3322,8 +3322,7 @@
for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
// UseNewReflection
vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection
- Klass* holder = vfst.method()->method_holder();
- oop loader = InstanceKlass::cast(holder)->class_loader();
+ oop loader = vfst.method()->method_holder()->class_loader();
if (loader != NULL) {
return JNIHandles::make_local(env, loader);
}
@@ -3365,9 +3364,9 @@
!vfst.at_end() && loader == NULL;
vfst.next()) {
if (!vfst.method()->is_native()) {
- Klass* holder = vfst.method()->method_holder();
- loader = InstanceKlass::cast(holder)->class_loader();
- protection_domain = InstanceKlass::cast(holder)->protection_domain();
+ InstanceKlass* holder = vfst.method()->method_holder();
+ loader = holder->class_loader();
+ protection_domain = holder->protection_domain();
}
}
} else {
@@ -4246,7 +4245,7 @@
return NULL;
}
Klass* k = java_lang_Class::as_Klass(mirror());
- if (!Klass::cast(k)->oop_is_instance()) {
+ if (!k->oop_is_instance()) {
return NULL;
}
instanceKlassHandle ik_h(THREAD, k);
@@ -4257,7 +4256,7 @@
objArrayOop dest_o = oopFactory::new_objArray(SystemDictionary::Object_klass(), 3, CHECK_NULL);
objArrayHandle dest(THREAD, dest_o);
Klass* enc_k = ik_h->constants()->klass_at(encl_method_class_idx, CHECK_NULL);
- dest->obj_at_put(0, Klass::cast(enc_k)->java_mirror());
+ dest->obj_at_put(0, enc_k->java_mirror());
int encl_method_method_idx = ik_h->enclosing_method_method_index();
if (encl_method_method_idx != 0) {
Symbol* sym = ik_h->constants()->symbol_at(
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -228,7 +228,7 @@
write_attribute_name_index("Code");
write_u4(size);
- write_u2(method->max_stack());
+ write_u2(method->verifier_max_stack());
write_u2(method->max_locals());
write_u4(code_size);
copy_bytecodes(method, (unsigned char*)writeable_address(code_size));
@@ -753,7 +753,7 @@
unsigned char* p = bytecodes;
Bytecodes::Code code;
- bool is_rewritten = InstanceKlass::cast(mh->method_holder())->is_rewritten();
+ bool is_rewritten = mh->method_holder()->is_rewritten();
while ((code = bs.next()) >= 0) {
assert(Bytecodes::is_java_code(code), "sanity check");
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -2116,7 +2116,7 @@
result[0] = tchar;
result[1] = '\0';
} else {
- const char* class_sig = Klass::cast(k)->signature_name();
+ const char* class_sig = k->signature_name();
result = (char *) jvmtiMalloc(strlen(class_sig)+1);
strcpy(result, class_sig);
}
@@ -2124,7 +2124,7 @@
}
if (generic_ptr != NULL) {
*generic_ptr = NULL;
- if (!isPrimitive && Klass::cast(k)->oop_is_instance()) {
+ if (!isPrimitive && k->oop_is_instance()) {
Symbol* soo = InstanceKlass::cast(k)->generic_signature();
if (soo != NULL) {
const char *gen_sig = soo->as_C_string();
@@ -2155,7 +2155,7 @@
} else {
Klass* k = java_lang_Class::as_Klass(k_mirror);
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
- result = Klass::cast(k)->jvmti_class_status();
+ result = k->jvmti_class_status();
}
*status_ptr = result;
@@ -2173,7 +2173,7 @@
Klass* k_klass = java_lang_Class::as_Klass(k_mirror);
NULL_CHECK(k_klass, JVMTI_ERROR_INVALID_CLASS);
- if (!Klass::cast(k_klass)->oop_is_instance()) {
+ if (!k_klass->oop_is_instance()) {
return JVMTI_ERROR_ABSENT_INFORMATION;
}
@@ -2200,7 +2200,7 @@
if (!java_lang_Class::is_primitive(k_mirror)) {
Klass* k = java_lang_Class::as_Klass(k_mirror);
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
- result = Klass::cast(k)->compute_modifier_flags(current_thread);
+ result = k->compute_modifier_flags(current_thread);
JavaThread* THREAD = current_thread; // pass to macros
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
@@ -2208,7 +2208,7 @@
};
// Reset the deleted ACC_SUPER bit ( deleted in compute_modifier_flags()).
- if(Klass::cast(k)->is_super()) {
+ if(k->is_super()) {
result |= JVM_ACC_SUPER;
}
} else {
@@ -2237,11 +2237,11 @@
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
// Return CLASS_NOT_PREPARED error as per JVMTI spec.
- if (!(Klass::cast(k)->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
+ if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
return JVMTI_ERROR_CLASS_NOT_PREPARED;
}
- if (!Klass::cast(k)->oop_is_instance()) {
+ if (!k->oop_is_instance()) {
*method_count_ptr = 0;
*methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID));
return JVMTI_ERROR_NONE;
@@ -2293,11 +2293,11 @@
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
// Return CLASS_NOT_PREPARED error as per JVMTI spec.
- if (!(Klass::cast(k)->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
+ if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) )) {
return JVMTI_ERROR_CLASS_NOT_PREPARED;
}
- if (!Klass::cast(k)->oop_is_instance()) {
+ if (!k->oop_is_instance()) {
*field_count_ptr = 0;
*fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID));
return JVMTI_ERROR_NONE;
@@ -2348,10 +2348,10 @@
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
// Return CLASS_NOT_PREPARED error as per JVMTI spec.
- if (!(Klass::cast(k)->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) ))
+ if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) ))
return JVMTI_ERROR_CLASS_NOT_PREPARED;
- if (!Klass::cast(k)->oop_is_instance()) {
+ if (!k->oop_is_instance()) {
*interface_count_ptr = 0;
*interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass));
return JVMTI_ERROR_NONE;
@@ -2363,8 +2363,8 @@
for (int i_index = 0; i_index < result_length; i_index += 1) {
Klass* klass_at = interface_list->at(i_index);
assert(klass_at->is_klass(), "interfaces must be Klass*s");
- assert(Klass::cast(klass_at)->is_interface(), "interfaces must be interfaces");
- oop mirror_at = Klass::cast(klass_at)->java_mirror();
+ assert(klass_at->is_interface(), "interfaces must be interfaces");
+ oop mirror_at = klass_at->java_mirror();
Handle handle_at = Handle(current_thread, mirror_at);
result_list[i_index] = (jclass) jni_reference(handle_at);
}
@@ -2468,7 +2468,7 @@
bool result = false;
if (!java_lang_Class::is_primitive(k_mirror)) {
Klass* k = java_lang_Class::as_Klass(k_mirror);
- if (k != NULL && Klass::cast(k)->is_interface()) {
+ if (k != NULL && k->is_interface()) {
result = true;
}
}
@@ -2487,7 +2487,7 @@
bool result = false;
if (!java_lang_Class::is_primitive(k_mirror)) {
Klass* k = java_lang_Class::as_Klass(k_mirror);
- if (k != NULL && Klass::cast(k)->oop_is_array()) {
+ if (k != NULL && k->oop_is_array()) {
result = true;
}
}
@@ -2512,7 +2512,7 @@
Klass* k = java_lang_Class::as_Klass(k_mirror);
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
- oop result_oop = Klass::cast(k)->class_loader();
+ oop result_oop = k->class_loader();
if (result_oop == NULL) {
*classloader_ptr = (jclass) jni_reference(Handle());
return JVMTI_ERROR_NONE;
@@ -2535,7 +2535,7 @@
}
Klass* k = java_lang_Class::as_Klass(k_mirror);
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
- if (!Klass::cast(k)->oop_is_instance()) {
+ if (!k->oop_is_instance()) {
return JVMTI_ERROR_ABSENT_INFORMATION;
}
char* sde = InstanceKlass::cast(k)->source_debug_extension();
@@ -2822,7 +2822,7 @@
JavaThread* current_thread = JavaThread::current();
// does the klass have any local variable information?
- InstanceKlass* ik = InstanceKlass::cast(method_oop->method_holder());
+ InstanceKlass* ik = method_oop->method_holder();
if (!ik->access_flags().has_localvariable_table()) {
return (JVMTI_ERROR_ABSENT_INFORMATION);
}
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -590,7 +590,7 @@
jclass
JvmtiEnvBase::get_jni_class_non_null(Klass* k) {
assert(k != NULL, "k != NULL");
- return (jclass)jni_reference(Klass::cast(k)->java_mirror());
+ return (jclass)jni_reference(k->java_mirror());
}
#ifndef JVMTI_KERNEL
@@ -1365,7 +1365,7 @@
// Method return type signature.
char* ty_sign = 1 + strchr(signature->as_C_string(), ')');
- if (!VM_GetOrSetLocal::is_assignable(ty_sign, Klass::cast(ob_kh()), current_thread)) {
+ if (!VM_GetOrSetLocal::is_assignable(ty_sign, ob_kh(), current_thread)) {
return JVMTI_ERROR_TYPE_MISMATCH;
}
*ret_ob_h = ob_h;
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -196,7 +196,7 @@
jobject to_jobject(oop obj) { return JNIHandles::make_local(_thread,obj); }
#endif
- jclass to_jclass(Klass* klass) { return (klass == NULL ? NULL : (jclass)to_jobject(Klass::cast(klass)->java_mirror())); }
+ jclass to_jclass(Klass* klass) { return (klass == NULL ? NULL : (jclass)to_jobject(klass->java_mirror())); }
jmethodID to_jmethodID(methodHandle method) { return method->jmethod_id(); }
@@ -920,7 +920,7 @@
if (ets->is_enabled(JVMTI_EVENT_CLASS_LOAD)) {
EVT_TRACE(JVMTI_EVENT_CLASS_LOAD, ("JVMTI [%s] Evt Class Load sent %s",
JvmtiTrace::safe_get_thread_name(thread),
- kh()==NULL? "NULL" : Klass::cast(kh())->external_name() ));
+ kh()==NULL? "NULL" : kh()->external_name() ));
JvmtiEnv *env = ets->get_env();
JvmtiClassEventMark jem(thread, kh());
@@ -949,7 +949,7 @@
if (ets->is_enabled(JVMTI_EVENT_CLASS_PREPARE)) {
EVT_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("JVMTI [%s] Evt Class Prepare sent %s",
JvmtiTrace::safe_get_thread_name(thread),
- kh()==NULL? "NULL" : Klass::cast(kh())->external_name() ));
+ kh()==NULL? "NULL" : kh()->external_name() ));
JvmtiEnv *env = ets->get_env();
JvmtiClassEventMark jem(thread, kh());
@@ -979,12 +979,12 @@
for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
if (env->is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) {
EVT_TRACE(EXT_EVENT_CLASS_UNLOAD, ("JVMTI [?] Evt Class Unload sent %s",
- kh()==NULL? "NULL" : Klass::cast(kh())->external_name() ));
+ kh()==NULL? "NULL" : kh()->external_name() ));
// do everything manually, since this is a proxy - needs special care
JNIEnv* jni_env = real_thread->jni_environment();
jthread jt = (jthread)JNIHandles::make_local(real_thread, real_thread->threadObj());
- jclass jk = (jclass)JNIHandles::make_local(real_thread, Klass::cast(kh())->java_mirror());
+ jclass jk = (jclass)JNIHandles::make_local(real_thread, kh()->java_mirror());
// Before we call the JVMTI agent, we have to set the state in the
// thread for which we are proxying.
@@ -2121,7 +2121,7 @@
if (env->is_enabled(JVMTI_EVENT_VM_OBJECT_ALLOC)) {
EVT_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("JVMTI [%s] Evt vmobject alloc sent %s",
JvmtiTrace::safe_get_thread_name(thread),
- object==NULL? "NULL" : Klass::cast(java_lang_Class::as_Klass(object))->external_name()));
+ object==NULL? "NULL" : java_lang_Class::as_Klass(object)->external_name()));
JvmtiVMObjectAllocEventMark jem(thread, h());
JvmtiJavaThreadEventTransition jet(thread);
@@ -2177,7 +2177,7 @@
jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) {
char ebuf[1024];
char buffer[JVM_MAXPATHLEN];
- void* library;
+ void* library = NULL;
jint result = JNI_ERR;
// get agent name and options
@@ -2196,13 +2196,16 @@
library = os::dll_load(agent, ebuf, sizeof ebuf);
} else {
// Try to load the agent from the standard dll directory
- os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), agent);
- library = os::dll_load(buffer, ebuf, sizeof ebuf);
+ if (os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
+ agent)) {
+ library = os::dll_load(buffer, ebuf, sizeof ebuf);
+ }
if (library == NULL) {
// not found - try local path
char ns[1] = {0};
- os::dll_build_name(buffer, sizeof(buffer), ns, agent);
- library = os::dll_load(buffer, ebuf, sizeof ebuf);
+ if (os::dll_build_name(buffer, sizeof(buffer), ns, agent)) {
+ library = os::dll_load(buffer, ebuf, sizeof ebuf);
+ }
}
}
--- a/hotspot/src/share/vm/prims/jvmtiExport.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiExport.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -64,6 +64,8 @@
//
class JvmtiExport : public AllStatic {
friend class VMStructs;
+ friend class CompileReplay;
+
private:
#if INCLUDE_JVMTI
--- a/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -169,7 +169,7 @@
static void increment(Klass* k) {
JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
if (that->get_initiatingLoader() == NULL) {
- for (Klass* l = k; l != NULL; l = Klass::cast(l)->array_klass_or_null()) {
+ for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
that->set_count(that->get_count() + 1);
}
} else if (k != NULL) {
@@ -182,7 +182,7 @@
JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
oop class_loader = loader_data->class_loader();
if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) {
- for (Klass* l = k; l != NULL; l = Klass::cast(l)->array_klass_or_null()) {
+ for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
that->set_count(that->get_count() + 1);
}
}
@@ -200,14 +200,14 @@
JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
if (that->available()) {
if (that->get_initiatingLoader() == NULL) {
- for (Klass* l = k; l != NULL; l = Klass::cast(l)->array_klass_or_null()) {
- oop mirror = Klass::cast(l)->java_mirror();
+ for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
+ oop mirror = l->java_mirror();
that->set_element(that->get_index(), mirror);
that->set_index(that->get_index() + 1);
}
} else if (k != NULL) {
// if initiating loader not null, just include the instance with 1 dimension
- oop mirror = Klass::cast(k)->java_mirror();
+ oop mirror = k->java_mirror();
that->set_element(that->get_index(), mirror);
that->set_index(that->get_index() + 1);
}
@@ -219,8 +219,8 @@
if (that->available()) {
oop class_loader = loader_data->class_loader();
if (class_loader == JNIHandles::resolve(that->get_initiatingLoader())) {
- for (Klass* l = k; l != NULL; l = Klass::cast(l)->array_klass_or_null()) {
- oop mirror = Klass::cast(l)->java_mirror();
+ for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
+ oop mirror = l->java_mirror();
that->set_element(that->get_index(), mirror);
that->set_index(that->get_index() + 1);
}
@@ -234,7 +234,7 @@
static void increment_for_basic_type_arrays(Klass* k) {
JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
assert(that != NULL, "no JvmtiGetLoadedClassesClosure");
- for (Klass* l = k; l != NULL; l = Klass::cast(l)->array_klass_or_null()) {
+ for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
that->set_count(that->get_count() + 1);
}
}
@@ -244,8 +244,8 @@
JvmtiGetLoadedClassesClosure* that = JvmtiGetLoadedClassesClosure::get_this();
assert(that != NULL, "no JvmtiGetLoadedClassesClosure");
assert(that->available(), "no list");
- for (Klass* l = k; l != NULL; l = Klass::cast(l)->array_klass_or_null()) {
- oop mirror = Klass::cast(l)->java_mirror();
+ for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
+ oop mirror = l->java_mirror();
that->set_element(that->get_index(), mirror);
that->set_index(that->get_index() + 1);
}
--- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -641,14 +641,14 @@
int super_depth = klass->super_depth();
int idx;
for (idx = 0; idx < super_depth; idx++) {
- if (Klass::cast(klass->primary_super_of_depth(idx))->name() == ty_sym) {
+ if (klass->primary_super_of_depth(idx)->name() == ty_sym) {
return true;
}
}
// Compare secondary supers
Array<Klass*>* sec_supers = klass->secondary_supers();
for (idx = 0; idx < sec_supers->length(); idx++) {
- if (Klass::cast((Klass*) sec_supers->at(idx))->name() == ty_sym) {
+ if (((Klass*) sec_supers->at(idx))->name() == ty_sym) {
return true;
}
}
@@ -726,7 +726,7 @@
KlassHandle ob_kh = KlassHandle(cur_thread, obj->klass());
NULL_CHECK(ob_kh, (_result = JVMTI_ERROR_INVALID_OBJECT, false));
- if (!is_assignable(signature, Klass::cast(ob_kh()), cur_thread)) {
+ if (!is_assignable(signature, ob_kh(), cur_thread)) {
_result = JVMTI_ERROR_TYPE_MISMATCH;
return false;
}
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -222,7 +222,7 @@
}
Klass* the_class_oop = java_lang_Class::as_Klass(klass_mirror);
// classes for arrays cannot be redefined
- if (the_class_oop == NULL || !Klass::cast(the_class_oop)->oop_is_instance()) {
+ if (the_class_oop == NULL || !the_class_oop->oop_is_instance()) {
return false;
}
return true;
@@ -573,8 +573,8 @@
// Check for NULL superclass first since this might be java.lang.Object
if (the_class->super() != scratch_class->super() &&
(the_class->super() == NULL || scratch_class->super() == NULL ||
- Klass::cast(the_class->super())->name() !=
- Klass::cast(scratch_class->super())->name())) {
+ the_class->super()->name() !=
+ scratch_class->super()->name())) {
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
}
@@ -592,8 +592,8 @@
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
}
for (i = 0; i < n_intfs; i++) {
- if (Klass::cast(k_interfaces->at(i))->name() !=
- Klass::cast(k_new_interfaces->at(i))->name()) {
+ if (k_interfaces->at(i)->name() !=
+ k_new_interfaces->at(i)->name()) {
return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
}
}
@@ -2684,7 +2684,7 @@
// interface, then we have to call adjust_method_entries() for
// every InstanceKlass that has an itable since there isn't a
// subclass relationship between an interface and an InstanceKlass.
- if (ik->itable_length() > 0 && (Klass::cast(_the_class_oop)->is_interface()
+ if (ik->itable_length() > 0 && (_the_class_oop->is_interface()
|| ik->is_subclass_of(_the_class_oop))) {
// ik->itable() creates a wrapper object; rm cleans it up
ResourceMark rm(THREAD);
@@ -2929,7 +2929,7 @@
Symbol* signature) {
TempNewSymbol name_symbol = SymbolTable::probe(name_str, (int)name_len);
if (name_symbol != NULL) {
- Method* method = Klass::cast(the_class())->lookup_method(name_symbol, signature);
+ Method* method = the_class()->lookup_method(name_symbol, signature);
if (method != NULL) {
// Even if prefixed, intermediate methods must exist.
if (method->is_native()) {
--- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -2774,7 +2774,7 @@
// a type array references its class
inline bool VM_HeapWalkOperation::iterate_over_type_array(oop o) {
Klass* k = o->klass();
- oop mirror = Klass::cast(k)->java_mirror();
+ oop mirror = k->java_mirror();
if (!CallbackInvoker::report_class_reference(o, mirror)) {
return false;
}
@@ -2823,7 +2823,7 @@
// super (only if something more interesting than java.lang.Object)
Klass* java_super = ik->java_super();
if (java_super != NULL && java_super != SystemDictionary::Object_klass()) {
- oop super = Klass::cast(java_super)->java_mirror();
+ oop super = java_super->java_mirror();
if (!CallbackInvoker::report_superclass_reference(mirror, super)) {
return false;
}
@@ -2865,7 +2865,7 @@
// If the entry is non-null it is resolved.
if (entry == NULL) continue;
} else {
- entry = Klass::cast(pool->resolved_klass_at(i))->java_mirror();
+ entry = pool->resolved_klass_at(i)->java_mirror();
}
if (!CallbackInvoker::report_constant_pool_reference(mirror, entry, (jint)i)) {
return false;
@@ -2879,7 +2879,7 @@
// but are specified by IterateOverReachableObjects and must be reported).
Array<Klass*>* interfaces = ik->local_interfaces();
for (i = 0; i < interfaces->length(); i++) {
- oop interf = Klass::cast((Klass*)interfaces->at(i))->java_mirror();
+ oop interf = ((Klass*)interfaces->at(i))->java_mirror();
if (interf == NULL) {
continue;
}
@@ -2928,7 +2928,7 @@
// references from the class).
inline bool VM_HeapWalkOperation::iterate_over_object(oop o) {
// reference to the class
- if (!CallbackInvoker::report_class_reference(o, Klass::cast(o->klass())->java_mirror())) {
+ if (!CallbackInvoker::report_class_reference(o, o->klass()->java_mirror())) {
return false;
}
--- a/hotspot/src/share/vm/prims/jvmtiTrace.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/jvmtiTrace.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -292,7 +292,7 @@
if (k_oop == NULL) {
return "INVALID";
}
- return Klass::cast(k_oop)->external_name();
+ return k_oop->external_name();
}
#endif /*JVMTI_TRACE */
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -138,7 +138,7 @@
oop clazz = java_lang_reflect_Method::clazz(target_oop);
int slot = java_lang_reflect_Method::slot(target_oop);
Klass* k = java_lang_Class::as_Klass(clazz);
- if (k != NULL && Klass::cast(k)->oop_is_instance()) {
+ if (k != NULL && k->oop_is_instance()) {
Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);
return init_method_MemberName(mname_oop, m, true, k);
}
@@ -146,7 +146,7 @@
oop clazz = java_lang_reflect_Constructor::clazz(target_oop);
int slot = java_lang_reflect_Constructor::slot(target_oop);
Klass* k = java_lang_Class::as_Klass(clazz);
- if (k != NULL && Klass::cast(k)->oop_is_instance()) {
+ if (k != NULL && k->oop_is_instance()) {
Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);
return init_method_MemberName(mname_oop, m, false, k);
}
@@ -187,14 +187,14 @@
} else if (mods.is_static()) {
flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
} else if (receiver_limit != mklass &&
- !Klass::cast(receiver_limit)->is_subtype_of(mklass)) {
+ !receiver_limit->is_subtype_of(mklass)) {
return NULL; // bad receiver limit
- } else if (Klass::cast(receiver_limit)->is_interface() &&
- Klass::cast(mklass)->is_interface()) {
+ } else if (receiver_limit->is_interface() &&
+ mklass->is_interface()) {
flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
receiver_limit = mklass; // ignore passed-in limit; interfaces are interconvertible
vmindex = klassItable::compute_itable_index(m);
- } else if (mklass != receiver_limit && Klass::cast(mklass)->is_interface()) {
+ } else if (mklass != receiver_limit && mklass->is_interface()) {
flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
// it is a miranda method, so m->vtable_index is not what we want
ResourceMark rm;
@@ -210,7 +210,7 @@
java_lang_invoke_MemberName::set_flags(mname_oop, flags);
java_lang_invoke_MemberName::set_vmtarget(mname_oop, m);
java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); // vtable/itable index
- java_lang_invoke_MemberName::set_clazz(mname_oop, Klass::cast(receiver_limit)->java_mirror());
+ java_lang_invoke_MemberName::set_clazz(mname_oop, receiver_limit->java_mirror());
// Note: name and type can be lazily computed by resolve_MemberName,
// if Java code needs them as resolved String and MethodType objects.
// The clazz must be eagerly stored, because it provides a GC
@@ -233,7 +233,7 @@
methodHandle m = info.resolved_method();
KlassHandle defc = info.resolved_klass();
int vmindex = -1;
- if (defc->is_interface() && Klass::cast(m->method_holder())->is_interface()) {
+ if (defc->is_interface() && m->method_holder()->is_interface()) {
// LinkResolver does not report itable indexes! (fix this?)
vmindex = klassItable::compute_itable_index(m());
} else if (m->can_be_statically_bound()) {
@@ -258,7 +258,7 @@
java_lang_invoke_MemberName::set_flags(mname_oop, flags);
java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget);
java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex);
- java_lang_invoke_MemberName::set_clazz(mname_oop, Klass::cast(field_holder)->java_mirror());
+ java_lang_invoke_MemberName::set_clazz(mname_oop, field_holder->java_mirror());
if (name != NULL)
java_lang_invoke_MemberName::set_name(mname_oop, name);
if (type != NULL)
@@ -299,7 +299,7 @@
// The following test will fail spuriously during bootstrap of MethodHandle itself:
// if (klass != SystemDictionary::MethodHandle_klass())
// Test the name instead:
- if (Klass::cast(klass)->name() != vmSymbols::java_lang_invoke_MethodHandle())
+ if (klass->name() != vmSymbols::java_lang_invoke_MethodHandle())
return false;
Symbol* poly_sig = vmSymbols::object_array_object_signature();
Method* m = InstanceKlass::cast(klass)->find_method(name, poly_sig);
@@ -363,7 +363,7 @@
vmIntrinsics::ID MethodHandles::signature_polymorphic_name_id(Klass* klass, Symbol* name) {
if (klass != NULL &&
- Klass::cast(klass)->name() == vmSymbols::java_lang_invoke_MethodHandle()) {
+ klass->name() == vmSymbols::java_lang_invoke_MethodHandle()) {
vmIntrinsics::ID iid = signature_polymorphic_name_id(name);
if (iid != vmIntrinsics::_none)
return iid;
@@ -539,7 +539,7 @@
static oop object_java_mirror() {
- return Klass::cast(SystemDictionary::Object_klass())->java_mirror();
+ return SystemDictionary::Object_klass()->java_mirror();
}
static oop field_name_or_null(Symbol* s) {
@@ -560,9 +560,9 @@
if (s == vmSymbols::object_signature()) {
return object_java_mirror();
} else if (s == vmSymbols::class_signature()) {
- return Klass::cast(SystemDictionary::Class_klass())->java_mirror();
+ return SystemDictionary::Class_klass()->java_mirror();
} else if (s == vmSymbols::string_signature()) {
- return Klass::cast(SystemDictionary::String_klass())->java_mirror();
+ return SystemDictionary::String_klass()->java_mirror();
}
}
return NULL;
@@ -603,8 +603,8 @@
{
Klass* defc_klass = java_lang_Class::as_Klass(defc_oop());
if (defc_klass == NULL) return empty; // a primitive; no resolution possible
- if (!Klass::cast(defc_klass)->oop_is_instance()) {
- if (!Klass::cast(defc_klass)->oop_is_array()) return empty;
+ if (!defc_klass->oop_is_instance()) {
+ if (!defc_klass->oop_is_array()) return empty;
defc_klass = SystemDictionary::Object_klass();
}
defc = instanceKlassHandle(THREAD, defc_klass);
@@ -749,8 +749,8 @@
DEBUG_ONLY(vmtarget = NULL); // safety
if (m.is_null()) break;
if (!have_defc) {
- Klass* defc = m->method_holder();
- java_lang_invoke_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror());
+ InstanceKlass* defc = m->method_holder();
+ java_lang_invoke_MemberName::set_clazz(mname(), defc->java_mirror());
}
if (!have_name) {
//not java_lang_String::create_from_symbol; let's intern member names
@@ -767,7 +767,7 @@
{
// This is taken from LinkResolver::resolve_field, sans access checks.
assert(vmtarget->is_klass(), "field vmtarget is Klass*");
- if (!Klass::cast((Klass*) vmtarget)->oop_is_instance()) break;
+ if (!((Klass*) vmtarget)->oop_is_instance()) break;
instanceKlassHandle defc(THREAD, (Klass*) vmtarget);
DEBUG_ONLY(vmtarget = NULL); // safety
bool is_static = ((flags & JVM_ACC_STATIC) != 0);
@@ -805,7 +805,7 @@
// %%% take caller into account!
- if (k == NULL || !Klass::cast(k)->oop_is_instance()) return -1;
+ if (k == NULL || !k->oop_is_instance()) return -1;
int rfill = 0, rlimit = results->length(), rskip = skip;
// overflow measurement:
@@ -1032,7 +1032,7 @@
if (!Reflection::verify_class_access(caller,
reference_klass,
true)) {
- THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), Klass::cast(reference_klass)->external_name());
+ THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), reference_klass->external_name());
}
}
}
@@ -1108,7 +1108,7 @@
if (vmtarget == NULL) {
x = NULL;
} else if (vmtarget->is_klass()) {
- x = Klass::cast((Klass*) vmtarget)->java_mirror();
+ x = ((Klass*) vmtarget)->java_mirror();
} else if (vmtarget->is_method()) {
Handle mname2 = MethodHandles::new_MemberName(CHECK_NULL);
x = MethodHandles::init_method_MemberName(mname2(), (Method*)vmtarget, false, NULL);
@@ -1237,7 +1237,7 @@
if (SystemDictionary::MethodHandle_klass() == NULL) {
enable_MH = false;
} else {
- oop mirror = Klass::cast(SystemDictionary::MethodHandle_klass())->java_mirror();
+ oop mirror = SystemDictionary::MethodHandle_klass()->java_mirror();
MH_class = (jclass) JNIHandles::make_local(env, mirror);
}
--- a/hotspot/src/share/vm/prims/nativeLookup.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/nativeLookup.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -165,8 +165,7 @@
// Note: It is critical for bootstrapping that Java_java_lang_ClassLoader_00024NativeLibrary_find
// gets found the first time around - otherwise an infinite loop can occure. This is
// another VM/library dependency
- Handle loader(THREAD,
- InstanceKlass::cast(method->method_holder())->class_loader());
+ Handle loader(THREAD, method->method_holder()->class_loader());
if (loader.is_null()) {
entry = lookup_special_native(jni_name);
if (entry == NULL) {
@@ -350,7 +349,7 @@
TempNewSymbol wrapper_symbol = SymbolTable::probe(wrapper_name, wrapper_name_len);
if (wrapper_symbol != NULL) {
KlassHandle kh(method->method_holder());
- Method* wrapper_method = Klass::cast(kh())->lookup_method(wrapper_symbol,
+ Method* wrapper_method = kh()->lookup_method(wrapper_symbol,
method->signature());
if (wrapper_method != NULL && !wrapper_method->is_native()) {
// we found a wrapper method, use its native entry
@@ -393,7 +392,7 @@
if (PrintJNIResolving) {
ResourceMark rm(THREAD);
tty->print_cr("[Dynamic-linking native method %s.%s ... JNI]",
- Klass::cast(method->method_holder())->external_name(),
+ method->method_holder()->external_name(),
method->name()->as_C_string());
}
}
--- a/hotspot/src/share/vm/prims/unsafe.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -771,7 +771,7 @@
oop mirror = JNIHandles::resolve_non_null(clazz);
Klass* klass = java_lang_Class::as_Klass(mirror);
- if (klass != NULL && Klass::cast(klass)->should_be_initialized()) {
+ if (klass != NULL && klass->should_be_initialized()) {
InstanceKlass* k = InstanceKlass::cast(klass);
k->initialize(CHECK);
}
@@ -785,7 +785,7 @@
}
oop mirror = JNIHandles::resolve_non_null(clazz);
Klass* klass = java_lang_Class::as_Klass(mirror);
- if (klass != NULL && Klass::cast(klass)->should_be_initialized()) {
+ if (klass != NULL && klass->should_be_initialized()) {
return true;
}
return false;
--- a/hotspot/src/share/vm/runtime/arguments.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "classfile/javaAssertions.hpp"
+#include "classfile/symbolTable.hpp"
#include "compiler/compilerOracle.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/cardTableRS.hpp"
@@ -1844,6 +1845,11 @@
status = status && verify_percentage(MinHeapFreeRatio, "MinHeapFreeRatio");
status = status && verify_percentage(MaxHeapFreeRatio, "MaxHeapFreeRatio");
+ // Divide by bucket size to prevent a large size from causing rollover when
+ // calculating amount of memory needed to be allocated for the String table.
+ status = status && verify_interval(StringTableSize, defaultStringTableSize,
+ (max_uintx / StringTable::bucket_size()), "StringTable size");
+
if (MinHeapFreeRatio > MaxHeapFreeRatio) {
jio_fprintf(defaultStream::error_stream(),
"MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or "
--- a/hotspot/src/share/vm/runtime/biasedLocking.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/biasedLocking.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -39,7 +39,7 @@
static GrowableArray<markOop>* _preserved_mark_stack = NULL;
static void enable_biased_locking(Klass* k) {
- Klass::cast(k)->set_prototype_header(markOopDesc::biased_locking_prototype());
+ k->set_prototype_header(markOopDesc::biased_locking_prototype());
}
class VM_EnableBiasedLocking: public VM_Operation {
@@ -149,7 +149,7 @@
if (TraceBiasedLocking) {
ResourceMark rm;
tty->print_cr(" (Skipping revocation of object of type %s because it's no longer biased)",
- Klass::cast(obj->klass())->external_name());
+ obj->klass()->external_name());
}
return BiasedLocking::NOT_BIASED;
}
@@ -161,7 +161,7 @@
if (TraceBiasedLocking && (Verbose || !is_bulk)) {
ResourceMark rm;
tty->print_cr("Revoking bias of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT " , allow rebias %d , requesting thread " INTPTR_FORMAT,
- (intptr_t) obj, (intptr_t) mark, Klass::cast(obj->klass())->external_name(), (intptr_t) Klass::cast(obj->klass())->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread);
+ (intptr_t) obj, (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread);
}
JavaThread* biased_thread = mark->biased_locker();
@@ -326,7 +326,7 @@
tty->print_cr("* Beginning bulk revocation (kind == %s) because of object "
INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(bulk_rebias ? "rebias" : "revoke"),
- (intptr_t) o, (intptr_t) o->mark(), Klass::cast(o->klass())->external_name());
+ (intptr_t) o, (intptr_t) o->mark(), o->klass()->external_name());
}
jlong cur_time = os::javaTimeMillis();
@@ -334,7 +334,7 @@
Klass* k_o = o->klass();
- Klass* klass = Klass::cast(k_o);
+ Klass* klass = k_o;
if (bulk_rebias) {
// Use the epoch in the klass of the object to implicitly revoke
@@ -546,7 +546,7 @@
return BIAS_REVOKED;
}
} else if (mark->has_bias_pattern()) {
- Klass* k = Klass::cast(obj->klass());
+ Klass* k = obj->klass();
markOop prototype_header = k->prototype_header();
if (!prototype_header->has_bias_pattern()) {
// This object has a stale bias from before the bulk revocation
@@ -590,7 +590,7 @@
if (heuristics == HR_NOT_BIASED) {
return NOT_BIASED;
} else if (heuristics == HR_SINGLE_REVOKE) {
- Klass *k = Klass::cast(obj->klass());
+ Klass *k = obj->klass();
markOop prototype_header = k->prototype_header();
if (mark->biased_locker() == THREAD &&
prototype_header->bias_epoch() == mark->bias_epoch()) {
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -97,6 +97,9 @@
// This is intended to force compiles for methods (usually for
// debugging) that would otherwise be interpreted for some reason.
bool CompilationPolicy::must_be_compiled(methodHandle m, int comp_level) {
+ // Don't allow Xcomp to cause compiles in replay mode
+ if (ReplayCompiles) return false;
+
if (m->has_compiled_code()) return false; // already compiled
if (!can_be_compiled(m, comp_level)) return false;
@@ -322,6 +325,16 @@
return NULL;
}
}
+ if (CompileTheWorld || ReplayCompiles) {
+ // Don't trigger other compiles in testing mode
+ if (bci == InvocationEntryBci) {
+ reset_counter_for_invocation_event(method);
+ } else {
+ reset_counter_for_back_branch_event(method);
+ }
+ return NULL;
+ }
+
if (bci == InvocationEntryBci) {
// when code cache is full, compilation gets switched off, UseCompiler
// is set to false
@@ -627,7 +640,7 @@
// negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg
if (m->is_abstract()) return (_msg = "abstract method");
// note: we allow ik->is_abstract()
- if (!InstanceKlass::cast(m->method_holder())->is_initialized()) return (_msg = "method holder not initialized");
+ if (!m->method_holder()->is_initialized()) return (_msg = "method holder not initialized");
if (m->is_native()) return (_msg = "native method");
nmethod* m_code = m->code();
if (m_code != NULL && m_code->code_size() > InlineSmallCode)
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1191,12 +1191,12 @@
if (!constant_pool->tag_at(index).is_symbol()) return;
- Handle class_loader (THREAD, InstanceKlass::cast(constant_pool->pool_holder())->class_loader());
+ Handle class_loader (THREAD, constant_pool->pool_holder()->class_loader());
Symbol* symbol = constant_pool->symbol_at(index);
// class name?
if (symbol->byte_at(0) != '(') {
- Handle protection_domain (THREAD, Klass::cast(constant_pool->pool_holder())->protection_domain());
+ Handle protection_domain (THREAD, constant_pool->pool_holder()->protection_domain());
SystemDictionary::resolve_or_null(symbol, class_loader, protection_domain, CHECK);
return;
}
@@ -1206,7 +1206,7 @@
for (SignatureStream ss(symbol); !ss.is_done(); ss.next()) {
if (ss.is_object()) {
Symbol* class_name = ss.as_symbol(CHECK);
- Handle protection_domain (THREAD, Klass::cast(constant_pool->pool_holder())->protection_domain());
+ Handle protection_domain (THREAD, constant_pool->pool_holder()->protection_domain());
SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK);
}
}
--- a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -36,7 +36,7 @@
oop fieldDescriptor::loader() const {
- return InstanceKlass::cast(_cp->pool_holder())->class_loader();
+ return _cp->pool_holder()->class_loader();
}
Symbol* fieldDescriptor::generic_signature() const {
@@ -45,7 +45,7 @@
}
int idx = 0;
- InstanceKlass* ik = InstanceKlass::cast(field_holder());
+ InstanceKlass* ik = field_holder();
for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
if (idx == _index) {
return fs.generic_signature();
@@ -58,7 +58,7 @@
}
AnnotationArray* fieldDescriptor::annotations() const {
- InstanceKlass* ik = InstanceKlass::cast(field_holder());
+ InstanceKlass* ik = field_holder();
Array<AnnotationArray*>* md = ik->fields_annotations();
if (md == NULL)
return NULL;
--- a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -43,12 +43,12 @@
// update the access_flags for the field in the klass
void update_klass_field_access_flag() {
- InstanceKlass* ik = InstanceKlass::cast(field_holder());
+ InstanceKlass* ik = field_holder();
ik->field(index())->set_access_flags(_access_flags.as_short());
}
FieldInfo* field() const {
- InstanceKlass* ik = InstanceKlass::cast(field_holder());
+ InstanceKlass* ik = field_holder();
return ik->field(_index);
}
@@ -59,46 +59,46 @@
Symbol* signature() const {
return field()->signature(_cp);
}
- Klass* field_holder() const { return _cp->pool_holder(); }
- ConstantPool* constants() const { return _cp(); }
- AccessFlags access_flags() const { return _access_flags; }
- oop loader() const;
+ InstanceKlass* field_holder() const { return _cp->pool_holder(); }
+ ConstantPool* constants() const { return _cp(); }
+ AccessFlags access_flags() const { return _access_flags; }
+ oop loader() const;
// Offset (in words) of field from start of instanceOop / Klass*
- int offset() const { return field()->offset(); }
- Symbol* generic_signature() const;
- int index() const { return _index; }
- AnnotationArray* annotations() const;
+ int offset() const { return field()->offset(); }
+ Symbol* generic_signature() const;
+ int index() const { return _index; }
+ AnnotationArray* annotations() const;
// Initial field value
- bool has_initial_value() const { return field()->initval_index() != 0; }
- int initial_value_index() const { return field()->initval_index(); }
+ bool has_initial_value() const { return field()->initval_index() != 0; }
+ int initial_value_index() const { return field()->initval_index(); }
constantTag initial_value_tag() const; // The tag will return true on one of is_int(), is_long(), is_single(), is_double()
- jint int_initial_value() const;
- jlong long_initial_value() const;
- jfloat float_initial_value() const;
- jdouble double_initial_value() const;
- oop string_initial_value(TRAPS) const;
+ jint int_initial_value() const;
+ jlong long_initial_value() const;
+ jfloat float_initial_value() const;
+ jdouble double_initial_value() const;
+ oop string_initial_value(TRAPS) const;
// Field signature type
- BasicType field_type() const { return FieldType::basic_type(signature()); }
+ BasicType field_type() const { return FieldType::basic_type(signature()); }
// Access flags
- bool is_public() const { return access_flags().is_public(); }
- bool is_private() const { return access_flags().is_private(); }
- bool is_protected() const { return access_flags().is_protected(); }
- bool is_package_private() const { return !is_public() && !is_private() && !is_protected(); }
+ bool is_public() const { return access_flags().is_public(); }
+ bool is_private() const { return access_flags().is_private(); }
+ bool is_protected() const { return access_flags().is_protected(); }
+ bool is_package_private() const { return !is_public() && !is_private() && !is_protected(); }
- bool is_static() const { return access_flags().is_static(); }
- bool is_final() const { return access_flags().is_final(); }
- bool is_volatile() const { return access_flags().is_volatile(); }
- bool is_transient() const { return access_flags().is_transient(); }
+ bool is_static() const { return access_flags().is_static(); }
+ bool is_final() const { return access_flags().is_final(); }
+ bool is_volatile() const { return access_flags().is_volatile(); }
+ bool is_transient() const { return access_flags().is_transient(); }
- bool is_synthetic() const { return access_flags().is_synthetic(); }
+ bool is_synthetic() const { return access_flags().is_synthetic(); }
- bool is_field_access_watched() const { return access_flags().is_field_access_watched(); }
+ bool is_field_access_watched() const { return access_flags().is_field_access_watched(); }
bool is_field_modification_watched() const
- { return access_flags().is_field_modification_watched(); }
- bool has_generic_signature() const { return access_flags().field_has_generic_signature(); }
+ { return access_flags().is_field_modification_watched(); }
+ bool has_generic_signature() const { return access_flags().field_has_generic_signature(); }
void set_is_field_access_watched(const bool value) {
_access_flags.set_is_field_access_watched(value);
--- a/hotspot/src/share/vm/runtime/globals.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/globals.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -3189,6 +3189,26 @@
product(ccstrlist, CompileCommand, "", \
"Prepend to .hotspot_compiler; e.g. log,java/lang/String.<init>") \
\
+ develop(bool, ReplayCompiles, false, \
+ "Enable replay of compilations from ReplayDataFile") \
+ \
+ develop(ccstr, ReplayDataFile, "replay.txt", \
+ "file containing compilation replay information") \
+ \
+ develop(intx, ReplaySuppressInitializers, 2, \
+ "Controls handling of class initialization during replay" \
+ "0 - don't do anything special" \
+ "1 - treat all class initializers as empty" \
+ "2 - treat class initializers for application classes as empty" \
+ "3 - allow all class initializers to run during bootstrap but" \
+ " pretend they are empty after starting replay") \
+ \
+ develop(bool, ReplayIgnoreInitErrors, false, \
+ "Ignore exceptions thrown during initialization for replay") \
+ \
+ develop(bool, DumpReplayDataOnError, true, \
+ "record replay data for crashing compiler threads") \
+ \
product(bool, CICompilerCountPerCPU, false, \
"1 compiler thread for log(N CPUs)") \
\
@@ -3593,9 +3613,18 @@
diagnostic(bool, PrintDTraceDOF, false, \
"Print the DTrace DOF passed to the system for JSDT probes") \
\
- product(uintx, StringTableSize, 1009, \
+ product(uintx, StringTableSize, defaultStringTableSize, \
"Number of buckets in the interned String table") \
\
+ develop(bool, TraceDefaultMethods, false, \
+ "Trace the default method processing steps") \
+ \
+ develop(bool, ParseAllGenericSignatures, false, \
+ "Parse all generic signatures while classloading") \
+ \
+ develop(bool, VerifyGenericSignatures, false, \
+ "Abort VM on erroneous or inconsistent generic signatures") \
+ \
product(bool, UseVMInterruptibleIO, false, \
"(Unstable, Solaris-specific) Thread interrupt before or with " \
"EINTR for I/O operations results in OS_INTRPT. The default value"\
--- a/hotspot/src/share/vm/runtime/javaCalls.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/javaCalls.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -189,7 +189,7 @@
assert(method->name() == vmSymbols::object_initializer_name(), "Should only be called for default constructor");
assert(method->signature() == vmSymbols::void_method_signature(), "Should only be called for default constructor");
- InstanceKlass* ik = InstanceKlass::cast(method->method_holder());
+ InstanceKlass* ik = method->method_holder();
if (ik->is_initialized() && ik->has_vanilla_constructor()) {
// safe to skip constructor call
} else {
@@ -344,11 +344,11 @@
#ifdef ASSERT
- { Klass* holder = method->method_holder();
+ { InstanceKlass* holder = method->method_holder();
// A klass might not be initialized since JavaCall's might be used during the executing of
// the <clinit>. For example, a Thread.start might start executing on an object that is
// not fully initialized! (bad Java programming style)
- assert(InstanceKlass::cast(holder)->is_linked(), "rewritting must have taken place");
+ assert(holder->is_linked(), "rewritting must have taken place");
}
#endif
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -140,6 +140,7 @@
Monitor* JfrMsg_lock = NULL;
Mutex* JfrBuffer_lock = NULL;
Mutex* JfrStream_lock = NULL;
+Monitor* PeriodicTask_lock = NULL;
#define MAX_NUM_MUTEX 128
static Monitor * _mutex_array[MAX_NUM_MUTEX];
@@ -285,6 +286,7 @@
def(JfrMsg_lock , Monitor, nonleaf+2, true);
def(JfrBuffer_lock , Mutex, nonleaf+3, true);
def(JfrStream_lock , Mutex, nonleaf+4, true);
+ def(PeriodicTask_lock , Monitor, nonleaf+5, true);
}
GCMutexLocker::GCMutexLocker(Monitor * mutex) {
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -142,6 +142,7 @@
extern Monitor* JfrMsg_lock; // protects JFR messaging
extern Mutex* JfrBuffer_lock; // protects JFR buffer operations
extern Mutex* JfrStream_lock; // protects JFR stream access
+extern Monitor* PeriodicTask_lock; // protects the periodic task structure
// A MutexLocker provides mutual exclusion with respect to a given mutex
// for the scope which contains the locker. The lock is an OS lock, not
--- a/hotspot/src/share/vm/runtime/os.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/os.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -397,12 +397,16 @@
// Try to load verify dll first. In 1.3 java dll depends on it and is not
// always able to find it when the loading executable is outside the JDK.
// In order to keep working with 1.2 we ignore any loading errors.
- dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify");
- dll_load(buffer, ebuf, sizeof(ebuf));
+ if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
+ "verify")) {
+ dll_load(buffer, ebuf, sizeof(ebuf));
+ }
// Load java dll
- dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "java");
- _native_java_library = dll_load(buffer, ebuf, sizeof(ebuf));
+ if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
+ "java")) {
+ _native_java_library = dll_load(buffer, ebuf, sizeof(ebuf));
+ }
if (_native_java_library == NULL) {
vm_exit_during_initialization("Unable to load native library", ebuf);
}
@@ -410,8 +414,10 @@
#if defined(__OpenBSD__)
// Work-around OpenBSD's lack of $ORIGIN support by pre-loading libnet.so
// ignore errors
- dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "net");
- dll_load(buffer, ebuf, sizeof(ebuf));
+ if (dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
+ "net")) {
+ dll_load(buffer, ebuf, sizeof(ebuf));
+ }
#endif
}
static jboolean onLoaded = JNI_FALSE;
@@ -576,7 +582,9 @@
// if NULL is returned the calling functions assume out of memory.
size = 1;
}
-
+ if (size > size + space_before + space_after) { // Check for rollover.
+ return NULL;
+ }
NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
u_char* ptr = (u_char*)::malloc(size + space_before + space_after);
@@ -1156,7 +1164,7 @@
if (inpath == NULL) {
return NULL;
}
- strncpy(inpath, path, strlen(path));
+ strcpy(inpath, path);
int count = 1;
char* p = strchr(inpath, psepchar);
// Get a count of elements to allocate memory
--- a/hotspot/src/share/vm/runtime/os.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/os.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -479,7 +479,8 @@
static const char* get_current_directory(char *buf, int buflen);
// Builds a platform-specific full library path given a ld path and lib name
- static void dll_build_name(char* buffer, size_t size,
+ // Returns true if buffer contains full path to existing file, false otherwise
+ static bool dll_build_name(char* buffer, size_t size,
const char* pathname, const char* fname);
// Symbol lookup, find nearest function name; basically it implements
--- a/hotspot/src/share/vm/runtime/reflection.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/reflection.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -56,22 +56,22 @@
vframeStream vfst(jthread);
// skip over any frames belonging to java.lang.Class
while (!vfst.at_end() &&
- InstanceKlass::cast(vfst.method()->method_holder())->name() == vmSymbols::java_lang_Class()) {
+ vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class()) {
vfst.next();
}
if (!vfst.at_end()) {
// this frame is a likely suspect
caller = vfst.method()->method_holder();
line_number = vfst.method()->line_number_from_bci(vfst.bci());
- Symbol* s = InstanceKlass::cast(vfst.method()->method_holder())->source_file_name();
+ Symbol* s = vfst.method()->method_holder()->source_file_name();
if (s != NULL) {
source_file = s->as_C_string();
}
}
}
if (caller != NULL) {
- const char * from = Klass::cast(caller)->external_name();
- const char * to = Klass::cast(to_class)->external_name();
+ const char * from = caller->external_name();
+ const char * to = to_class->external_name();
// print in a single call to reduce interleaving between threads
if (source_file != NULL) {
tty->print("RESOLVE %s %s %s:%d (reflection)\n", from, to, source_file, line_number);
@@ -330,7 +330,7 @@
return TypeArrayKlass::cast(tak)->allocate(length, THREAD);
} else {
Klass* k = java_lang_Class::as_Klass(element_mirror);
- if (Klass::cast(k)->oop_is_array() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
+ if (k->oop_is_array() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
THROW_0(vmSymbols::java_lang_IllegalArgumentException());
}
return oopFactory::new_objArray(k, length, THREAD);
@@ -366,7 +366,7 @@
klass = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
} else {
klass = java_lang_Class::as_Klass(element_mirror);
- if (Klass::cast(klass)->oop_is_array()) {
+ if (klass->oop_is_array()) {
int k_dim = ArrayKlass::cast(klass)->dimension();
if (k_dim + len > MAX_DIM) {
THROW_0(vmSymbols::java_lang_IllegalArgumentException());
@@ -374,7 +374,7 @@
dim += k_dim;
}
}
- klass = Klass::cast(klass)->array_klass(dim, CHECK_NULL);
+ klass = klass->array_klass(dim, CHECK_NULL);
oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, THREAD);
assert(obj->is_array(), "just checking");
return arrayOop(obj);
@@ -387,7 +387,7 @@
}
Klass* klass = java_lang_Class::as_Klass(mirror);
- if (!Klass::cast(klass)->oop_is_array()) {
+ if (!klass->oop_is_array()) {
return NULL;
}
@@ -395,15 +395,15 @@
#ifdef ASSERT
oop result2 = NULL;
if (ArrayKlass::cast(klass)->dimension() == 1) {
- if (Klass::cast(klass)->oop_is_typeArray()) {
+ if (klass->oop_is_typeArray()) {
result2 = basic_type_arrayklass_to_mirror(klass, CHECK_NULL);
} else {
- result2 = Klass::cast(ObjArrayKlass::cast(klass)->element_klass())->java_mirror();
+ result2 = ObjArrayKlass::cast(klass)->element_klass()->java_mirror();
}
} else {
Klass* lower_dim = ArrayKlass::cast(klass)->lower_dimension();
- assert(Klass::cast(lower_dim)->oop_is_array(), "just checking");
- result2 = Klass::cast(lower_dim)->java_mirror();
+ assert(lower_dim->oop_is_array(), "just checking");
+ result2 = lower_dim->java_mirror();
}
assert(result == result2, "results must be consistent");
#endif //ASSERT
@@ -442,7 +442,7 @@
if (acc.is_protected()) {
if (target_class != client_class) {
if (!is_same_class_package(client_class, field_class)) {
- if (!Klass::cast(target_class)->is_subclass_of(client_class)) {
+ if (!target_class->is_subclass_of(client_class)) {
THROW_(vmSymbols::java_lang_IllegalAccessException(), false);
}
}
@@ -468,7 +468,13 @@
// sun/reflect/MagicAccessorImpl subclasses to succeed trivially.
if ( JDK_Version::is_gte_jdk14x_version()
&& UseNewReflection
- && Klass::cast(current_class)->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
+ && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
+ return true;
+ }
+
+ // Also allow all accesses from
+ // java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially.
+ if (current_class->is_subclass_of(SystemDictionary::lambda_MagicLambdaImpl_klass())) {
return true;
}
@@ -540,12 +546,12 @@
if (access.is_protected()) {
if (!protected_restriction) {
// See if current_class is a subclass of field_class
- if (Klass::cast(current_class)->is_subclass_of(field_class)) {
+ if (current_class->is_subclass_of(field_class)) {
if (access.is_static() || // static fields are ok, see 6622385
current_class == resolved_class ||
field_class == resolved_class ||
- Klass::cast(current_class)->is_subclass_of(resolved_class) ||
- Klass::cast(resolved_class)->is_subclass_of(current_class)) {
+ current_class->is_subclass_of(resolved_class) ||
+ resolved_class->is_subclass_of(current_class)) {
return true;
}
}
@@ -560,7 +566,13 @@
// sun/reflect/MagicAccessorImpl subclasses to succeed trivially.
if ( JDK_Version::is_gte_jdk14x_version()
&& UseNewReflection
- && Klass::cast(current_class)->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
+ && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
+ return true;
+ }
+
+ // Also allow all accesses from
+ // java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially.
+ if (current_class->is_subclass_of(SystemDictionary::lambda_MagicLambdaImpl_klass())) {
return true;
}
@@ -630,8 +642,8 @@
case T_OBJECT:
case T_ARRAY:
Symbol* name = ss->as_symbol(CHECK_NULL);
- oop loader = InstanceKlass::cast(method->method_holder())->class_loader();
- oop protection_domain = InstanceKlass::cast(method->method_holder())->protection_domain();
+ oop loader = method->method_holder()->class_loader();
+ oop protection_domain = method->method_holder()->protection_domain();
Klass* k = SystemDictionary::resolve_or_fail(
name,
Handle(THREAD, loader),
@@ -681,7 +693,7 @@
}
oop loader = InstanceKlass::cast(k())->class_loader();
- oop protection_domain = Klass::cast(k())->protection_domain();
+ oop protection_domain = k()->protection_domain();
Klass* result = SystemDictionary::resolve_or_fail(signature,
Handle(THREAD, loader),
Handle(THREAD, protection_domain),
@@ -691,7 +703,7 @@
trace_class_resolution(result);
}
- oop nt = Klass::cast(result)->java_mirror();
+ oop nt = result->java_mirror();
return Handle(THREAD, nt);
}
@@ -702,7 +714,7 @@
assert(!method()->is_initializer() ||
(for_constant_pool_access && method()->is_static()) ||
(method()->name() == vmSymbols::class_initializer_name()
- && Klass::cast(method()->method_holder())->is_interface() && JDK_Version::is_jdk12x_version()), "should call new_constructor instead");
+ && method()->method_holder()->is_interface() && JDK_Version::is_jdk12x_version()), "should call new_constructor instead");
instanceKlassHandle holder (THREAD, method->method_holder());
int slot = method->method_idnum();
@@ -820,7 +832,7 @@
Handle type = new_type(signature, holder, CHECK_NULL);
Handle rh = java_lang_reflect_Field::create(CHECK_NULL);
- java_lang_reflect_Field::set_clazz(rh(), Klass::cast(fd->field_holder())->java_mirror());
+ java_lang_reflect_Field::set_clazz(rh(), fd->field_holder()->java_mirror());
java_lang_reflect_Field::set_slot(rh(), fd->index());
java_lang_reflect_Field::set_name(rh(), name());
java_lang_reflect_Field::set_type(rh(), type());
@@ -888,7 +900,7 @@
method = reflected_method;
} else {
// resolve based on the receiver
- if (InstanceKlass::cast(reflected_method->method_holder())->is_interface()) {
+ if (reflected_method->method_holder()->is_interface()) {
// resolve interface call
if (ReflectionWrapResolutionErrors) {
// new default: 6531596
@@ -925,7 +937,7 @@
ResourceMark rm(THREAD);
Handle h_origexception = Exceptions::new_exception(THREAD,
vmSymbols::java_lang_AbstractMethodError(),
- Method::name_and_sig_as_C_string(Klass::cast(target_klass()),
+ Method::name_and_sig_as_C_string(target_klass(),
method->name(),
method->signature()));
JavaCallArguments args(h_origexception);
@@ -935,7 +947,7 @@
} else {
ResourceMark rm(THREAD);
THROW_MSG_0(vmSymbols::java_lang_AbstractMethodError(),
- Method::name_and_sig_as_C_string(Klass::cast(target_klass()),
+ Method::name_and_sig_as_C_string(target_klass(),
method->name(),
method->signature()));
}
@@ -950,7 +962,7 @@
if (method.is_null()) {
ResourceMark rm(THREAD);
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(),
- Method::name_and_sig_as_C_string(Klass::cast(klass()),
+ Method::name_and_sig_as_C_string(klass(),
reflected_method->name(),
reflected_method->signature()));
}
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1775,7 +1775,7 @@
// The copy_array mechanism is awkward and could be removed, but
// the compilers don't call this function except as a last resort,
// so it probably doesn't matter.
- Klass::cast(src->klass())->copy_array((arrayOopDesc*)src, src_pos,
+ src->klass()->copy_array((arrayOopDesc*)src, src_pos,
(arrayOopDesc*)dest, dest_pos,
length, thread);
}
@@ -1788,8 +1788,8 @@
vframeStream vfst(thread, true);
assert(!vfst.at_end(), "Java frame must exist");
Bytecode_checkcast cc(vfst.method(), vfst.method()->bcp_from(vfst.bci()));
- Klass* targetKlass = Klass::cast(vfst.method()->constants()->klass_at(
- cc.index(), thread));
+ Klass* targetKlass = vfst.method()->constants()->klass_at(
+ cc.index(), thread);
return generate_class_cast_message(objName, targetKlass->external_name());
}
--- a/hotspot/src/share/vm/runtime/signature.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/signature.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -354,7 +354,7 @@
return Universe::java_mirror(type());
Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL);
if (klass == NULL) return NULL;
- return Klass::cast(klass)->java_mirror();
+ return klass->java_mirror();
}
Symbol* SignatureStream::as_symbol_or_null() {
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1323,7 +1323,7 @@
ResourceMark rm;
tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(intptr_t) object, (intptr_t) object->mark(),
- Klass::cast(object->klass())->external_name());
+ object->klass()->external_name());
}
}
return m ;
@@ -1373,7 +1373,7 @@
ResourceMark rm;
tty->print_cr("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(intptr_t) object, (intptr_t) object->mark(),
- Klass::cast(object->klass())->external_name());
+ object->klass()->external_name());
}
}
return m ;
@@ -1440,7 +1440,7 @@
if (obj->is_instance()) {
ResourceMark rm;
tty->print_cr("Deflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
- (intptr_t) obj, (intptr_t) obj->mark(), Klass::cast(obj->klass())->external_name());
+ (intptr_t) obj, (intptr_t) obj->mark(), obj->klass()->external_name());
}
}
--- a/hotspot/src/share/vm/runtime/task.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/task.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -61,7 +61,7 @@
}
#endif
-void PeriodicTask::real_time_tick(size_t delay_time) {
+void PeriodicTask::real_time_tick(int delay_time) {
#ifndef PRODUCT
if (ProfilerCheckIntervals) {
_ticks++;
@@ -73,19 +73,39 @@
_intervalHistogram[ms]++;
}
#endif
- int orig_num_tasks = _num_tasks;
- for(int index = 0; index < _num_tasks; index++) {
- _tasks[index]->execute_if_pending(delay_time);
- if (_num_tasks < orig_num_tasks) { // task dis-enrolled itself
- index--; // re-do current slot as it has changed
- orig_num_tasks = _num_tasks;
+
+ {
+ MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+ int orig_num_tasks = _num_tasks;
+
+ for(int index = 0; index < _num_tasks; index++) {
+ _tasks[index]->execute_if_pending(delay_time);
+ if (_num_tasks < orig_num_tasks) { // task dis-enrolled itself
+ index--; // re-do current slot as it has changed
+ orig_num_tasks = _num_tasks;
+ }
}
}
}
+int PeriodicTask::time_to_wait() {
+ MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
+ NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+
+ if (_num_tasks == 0) {
+ return 0; // sleep until shutdown or a task is enrolled
+ }
+
+ int delay = _tasks[0]->time_to_next_interval();
+ for (int index = 1; index < _num_tasks; index++) {
+ delay = MIN2(delay, _tasks[index]->time_to_next_interval());
+ }
+ return delay;
+}
+
PeriodicTask::PeriodicTask(size_t interval_time) :
- _counter(0), _interval(interval_time) {
+ _counter(0), _interval((int) interval_time) {
// Sanity check the interval time
assert(_interval >= PeriodicTask::min_interval &&
_interval <= PeriodicTask::max_interval &&
@@ -94,33 +114,40 @@
}
PeriodicTask::~PeriodicTask() {
- if (is_enrolled())
- disenroll();
-}
-
-bool PeriodicTask::is_enrolled() const {
- for(int index = 0; index < _num_tasks; index++)
- if (_tasks[index] == this) return true;
- return false;
+ disenroll();
}
void PeriodicTask::enroll() {
- assert(WatcherThread::watcher_thread() == NULL, "dynamic enrollment of tasks not yet supported");
+ MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
+ NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
- if (_num_tasks == PeriodicTask::max_tasks)
+ if (_num_tasks == PeriodicTask::max_tasks) {
fatal("Overflow in PeriodicTask table");
+ }
_tasks[_num_tasks++] = this;
+
+ WatcherThread* thread = WatcherThread::watcher_thread();
+ if (thread) {
+ thread->unpark();
+ } else {
+ WatcherThread::start();
+ }
}
void PeriodicTask::disenroll() {
- assert(WatcherThread::watcher_thread() == NULL ||
- Thread::current() == WatcherThread::watcher_thread(),
- "dynamic disenrollment currently only handled from WatcherThread from within task() method");
+ MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
+ NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
int index;
- for(index = 0; index < _num_tasks && _tasks[index] != this; index++);
- if (index == _num_tasks) return;
+ for(index = 0; index < _num_tasks && _tasks[index] != this; index++)
+ ;
+
+ if (index == _num_tasks) {
+ return;
+ }
+
_num_tasks--;
+
for (; index < _num_tasks; index++) {
_tasks[index] = _tasks[index+1];
}
--- a/hotspot/src/share/vm/runtime/task.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/task.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -49,12 +49,12 @@
static int num_tasks() { return _num_tasks; }
private:
- size_t _counter;
- const size_t _interval;
+ int _counter;
+ const int _interval;
static int _num_tasks;
static PeriodicTask* _tasks[PeriodicTask::max_tasks];
- static void real_time_tick(size_t delay_time);
+ static void real_time_tick(int delay_time);
#ifndef PRODUCT
static elapsedTimer _timer; // measures time between ticks
@@ -69,51 +69,36 @@
PeriodicTask(size_t interval_time); // interval is in milliseconds of elapsed time
~PeriodicTask();
- // Tells whether is enrolled
- bool is_enrolled() const;
-
// Make the task active
- // NOTE: this may only be called before the WatcherThread has been started
+ // For dynamic enrollment at the time T, the task will execute somewhere
+ // between T and T + interval_time.
void enroll();
// Make the task deactive
- // NOTE: this may only be called either while the WatcherThread is
- // inactive or by a task from within its task() method. One-shot or
- // several-shot tasks may be implemented this way.
void disenroll();
- void execute_if_pending(size_t delay_time) {
- _counter += delay_time;
- if (_counter >= _interval) {
+ void execute_if_pending(int delay_time) {
+ // make sure we don't overflow
+ jlong tmp = (jlong) _counter + (jlong) delay_time;
+
+ if (tmp >= (jlong) _interval) {
_counter = 0;
task();
+ } else {
+ _counter += delay_time;
}
}
// Returns how long (time in milliseconds) before the next time we should
// execute this task.
- size_t time_to_next_interval() const {
+ int time_to_next_interval() const {
assert(_interval > _counter, "task counter greater than interval?");
return _interval - _counter;
}
// Calculate when the next periodic task will fire.
// Called by the WatcherThread's run method.
- // This assumes that periodic tasks aren't entering the system
- // dynamically, except for during startup.
- static size_t time_to_wait() {
- if (_num_tasks == 0) {
- // Don't wait any more; shut down the thread since we don't
- // currently support dynamic enrollment.
- return 0;
- }
-
- size_t delay = _tasks[0]->time_to_next_interval();
- for (int index = 1; index < _num_tasks; index++) {
- delay = MIN2(delay, _tasks[index]->time_to_next_interval());
- }
- return delay;
- }
+ static int time_to_wait();
// The task to perform at each period
virtual void task() = 0;
--- a/hotspot/src/share/vm/runtime/thread.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/thread.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1217,6 +1217,7 @@
// timer interrupts exists on the platform.
WatcherThread* WatcherThread::_watcher_thread = NULL;
+bool WatcherThread::_startable = false;
volatile bool WatcherThread::_should_terminate = false;
WatcherThread::WatcherThread() : Thread() {
@@ -1237,6 +1238,55 @@
}
}
+int WatcherThread::sleep() const {
+ MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+
+ // remaining will be zero if there are no tasks,
+ // causing the WatcherThread to sleep until a task is
+ // enrolled
+ int remaining = PeriodicTask::time_to_wait();
+ int time_slept = 0;
+
+ // we expect this to timeout - we only ever get unparked when
+ // we should terminate or when a new task has been enrolled
+ OSThreadWaitState osts(this->osthread(), false /* not Object.wait() */);
+
+ jlong time_before_loop = os::javaTimeNanos();
+
+ for (;;) {
+ bool timedout = PeriodicTask_lock->wait(Mutex::_no_safepoint_check_flag, remaining);
+ jlong now = os::javaTimeNanos();
+
+ if (remaining == 0) {
+ // if we didn't have any tasks we could have waited for a long time
+ // consider the time_slept zero and reset time_before_loop
+ time_slept = 0;
+ time_before_loop = now;
+ } else {
+ // need to recalulate since we might have new tasks in _tasks
+ time_slept = (int) ((now - time_before_loop) / 1000000);
+ }
+
+ // Change to task list or spurious wakeup of some kind
+ if (timedout || _should_terminate) {
+ break;
+ }
+
+ remaining = PeriodicTask::time_to_wait();
+ if (remaining == 0) {
+ // Last task was just disenrolled so loop around and wait until
+ // another task gets enrolled
+ continue;
+ }
+
+ remaining -= time_slept;
+ if (remaining <= 0)
+ break;
+ }
+
+ return time_slept;
+}
+
void WatcherThread::run() {
assert(this == watcher_thread(), "just checking");
@@ -1249,26 +1299,7 @@
// Calculate how long it'll be until the next PeriodicTask work
// should be done, and sleep that amount of time.
- size_t time_to_wait = PeriodicTask::time_to_wait();
-
- // we expect this to timeout - we only ever get unparked when
- // we should terminate
- {
- OSThreadWaitState osts(this->osthread(), false /* not Object.wait() */);
-
- jlong prev_time = os::javaTimeNanos();
- for (;;) {
- int res= _SleepEvent->park(time_to_wait);
- if (res == OS_TIMEOUT || _should_terminate)
- break;
- // spurious wakeup of some kind
- jlong now = os::javaTimeNanos();
- time_to_wait -= (now - prev_time) / 1000000;
- if (time_to_wait <= 0)
- break;
- prev_time = now;
- }
- }
+ int time_waited = sleep();
if (is_error_reported()) {
// A fatal error has happened, the error handler(VMError::report_and_die)
@@ -1298,13 +1329,7 @@
}
}
- PeriodicTask::real_time_tick(time_to_wait);
-
- // If we have no more tasks left due to dynamic disenrollment,
- // shut down the thread since we don't currently support dynamic enrollment
- if (PeriodicTask::num_tasks() == 0) {
- _should_terminate = true;
- }
+ PeriodicTask::real_time_tick(time_waited);
}
// Signal that it is terminated
@@ -1319,22 +1344,33 @@
}
void WatcherThread::start() {
- if (watcher_thread() == NULL) {
+ assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required");
+
+ if (watcher_thread() == NULL && _startable) {
_should_terminate = false;
// Create the single instance of WatcherThread
new WatcherThread();
}
}
+void WatcherThread::make_startable() {
+ assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required");
+ _startable = true;
+}
+
void WatcherThread::stop() {
+ {
+ MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+ _should_terminate = true;
+ OrderAccess::fence(); // ensure WatcherThread sees update in main loop
+
+ WatcherThread* watcher = watcher_thread();
+ if (watcher != NULL)
+ watcher->unpark();
+ }
+
// it is ok to take late safepoints here, if needed
MutexLocker mu(Terminator_lock);
- _should_terminate = true;
- OrderAccess::fence(); // ensure WatcherThread sees update in main loop
-
- Thread* watcher = watcher_thread();
- if (watcher != NULL)
- watcher->_SleepEvent->unpark();
while(watcher_thread() != NULL) {
// This wait should make safepoint checks, wait without a timeout,
@@ -1352,6 +1388,11 @@
}
}
+void WatcherThread::unpark() {
+ MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+ PeriodicTask_lock->notify();
+}
+
void WatcherThread::print_on(outputStream* st) const {
st->print("\"%s\" ", name());
Thread::print_on(st);
@@ -1744,7 +1785,7 @@
jio_fprintf(defaultStream::error_stream(),
"\nException: %s thrown from the UncaughtExceptionHandler"
" in thread \"%s\"\n",
- Klass::cast(pending_exception()->klass())->external_name(),
+ pending_exception()->klass()->external_name(),
get_thread_name());
CLEAR_PENDING_EXCEPTION;
}
@@ -3658,12 +3699,18 @@
}
}
- // Start up the WatcherThread if there are any periodic tasks
- // NOTE: All PeriodicTasks should be registered by now. If they
- // aren't, late joiners might appear to start slowly (we might
- // take a while to process their first tick).
- if (PeriodicTask::num_tasks() > 0) {
- WatcherThread::start();
+ {
+ MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+ // Make sure the watcher thread can be started by WatcherThread::start()
+ // or by dynamic enrollment.
+ WatcherThread::make_startable();
+ // Start up the WatcherThread if there are any periodic tasks
+ // NOTE: All PeriodicTasks should be registered by now. If they
+ // aren't, late joiners might appear to start slowly (we might
+ // take a while to process their first tick).
+ if (PeriodicTask::num_tasks() > 0) {
+ WatcherThread::start();
+ }
}
// Give os specific code one last chance to start
@@ -3706,8 +3753,10 @@
}
} else {
// Try to load the agent from the standard dll directory
- os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), name);
- library = os::dll_load(buffer, ebuf, sizeof ebuf);
+ if (os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(),
+ name)) {
+ library = os::dll_load(buffer, ebuf, sizeof ebuf);
+ }
#ifdef KERNEL
// Download instrument dll
if (library == NULL && strcmp(name, "instrument") == 0) {
@@ -3732,8 +3781,9 @@
#endif // KERNEL
if (library == NULL) { // Try the local directory
char ns[1] = {0};
- os::dll_build_name(buffer, sizeof(buffer), ns, name);
- library = os::dll_load(buffer, ebuf, sizeof ebuf);
+ if (os::dll_build_name(buffer, sizeof(buffer), ns, name)) {
+ library = os::dll_load(buffer, ebuf, sizeof ebuf);
+ }
if (library == NULL) {
const char *sub_msg = " on the library path, with error: ";
size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;
--- a/hotspot/src/share/vm/runtime/thread.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/thread.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -722,6 +722,7 @@
private:
static WatcherThread* _watcher_thread;
+ static bool _startable;
volatile static bool _should_terminate; // updated without holding lock
public:
enum SomeConstants {
@@ -738,6 +739,7 @@
char* name() const { return (char*)"VM Periodic Task Thread"; }
void print_on(outputStream* st) const;
void print() const { print_on(tty); }
+ void unpark();
// Returns the single instance of WatcherThread
static WatcherThread* watcher_thread() { return _watcher_thread; }
@@ -745,6 +747,12 @@
// Create and start the single instance of WatcherThread, or stop it on shutdown
static void start();
static void stop();
+ // Only allow start once the VM is sufficiently initialized
+ // Otherwise the first task to enroll will trigger the start
+ static void make_startable();
+
+ private:
+ int sleep() const;
};
--- a/hotspot/src/share/vm/runtime/vframe.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/vframe.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -149,7 +149,7 @@
Klass* target_klass = java_lang_Class::as_Klass(obj());
st->print_cr("(a java.lang.Class for %s)", InstanceKlass::cast(target_klass)->external_name());
} else {
- Klass* k = Klass::cast(obj->klass());
+ Klass* k = obj->klass();
st->print_cr("(a %s)", k->external_name());
}
}
@@ -161,7 +161,7 @@
// If this is the first frame, and java.lang.Object.wait(...) then print out the receiver.
if (frame_count == 0) {
if (method()->name() == vmSymbols::wait_name() &&
- InstanceKlass::cast(method()->method_holder())->name() == vmSymbols::java_lang_Object()) {
+ method()->method_holder()->name() == vmSymbols::java_lang_Object()) {
StackValueCollection* locs = locals();
if (!locs->is_empty()) {
StackValue* sv = locs->at(0);
@@ -172,7 +172,7 @@
}
} else if (thread()->current_park_blocker() != NULL) {
oop obj = thread()->current_park_blocker();
- Klass* k = Klass::cast(obj->klass());
+ Klass* k = obj->klass();
st->print_cr("\t- %s <" INTPTR_FORMAT "> (a %s)", "parking to wait for ", (address)obj, k->external_name());
}
}
@@ -407,7 +407,7 @@
if (Universe::reflect_invoke_cache()->is_same_method(method())) {
// This is Method.invoke() -- skip it
} else if (use_new_reflection &&
- Klass::cast(method()->method_holder())
+ method()->method_holder()
->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) {
// This is an auxilary frame -- skip it
} else if (method()->is_method_handle_intrinsic() ||
@@ -471,8 +471,8 @@
void vframeStreamCommon::skip_reflection_related_frames() {
while (!at_end() &&
(JDK_Version::is_gte_jdk14x_version() && UseNewReflection &&
- (Klass::cast(method()->method_holder())->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass()) ||
- Klass::cast(method()->method_holder())->is_subclass_of(SystemDictionary::reflect_ConstructorAccessorImpl_klass())))) {
+ (method()->method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass()) ||
+ method()->method_holder()->is_subclass_of(SystemDictionary::reflect_ConstructorAccessorImpl_klass())))) {
next();
}
}
@@ -547,13 +547,13 @@
void javaVFrame::print_value() const {
Method* m = method();
- Klass* k = m->method_holder();
+ InstanceKlass* k = m->method_holder();
tty->print_cr("frame( sp=" INTPTR_FORMAT ", unextended_sp=" INTPTR_FORMAT ", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT ")",
_fr.sp(), _fr.unextended_sp(), _fr.fp(), _fr.pc());
- tty->print("%s.%s", Klass::cast(k)->internal_name(), m->name()->as_C_string());
+ tty->print("%s.%s", k->internal_name(), m->name()->as_C_string());
if (!m->is_native()) {
- Symbol* source_name = InstanceKlass::cast(k)->source_file_name();
+ Symbol* source_name = k->source_file_name();
int line_number = m->line_number_from_bci(bci());
if (source_name != NULL && (line_number != -1)) {
tty->print("(%s:%d)", source_name->as_C_string(), line_number);
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -289,7 +289,7 @@
nonstatic_field(CompiledICHolder, _holder_klass, Klass*) \
nonstatic_field(ConstantPool, _tags, Array<u1>*) \
nonstatic_field(ConstantPool, _cache, ConstantPoolCache*) \
- nonstatic_field(ConstantPool, _pool_holder, Klass*) \
+ nonstatic_field(ConstantPool, _pool_holder, InstanceKlass*) \
nonstatic_field(ConstantPool, _operands, Array<u2>*) \
nonstatic_field(ConstantPool, _length, int) \
nonstatic_field(ConstantPool, _resolved_references, jobject) \
@@ -993,6 +993,7 @@
\
nonstatic_field(ciMethod, _interpreter_invocation_count, int) \
nonstatic_field(ciMethod, _interpreter_throwout_count, int) \
+ nonstatic_field(ciMethod, _instructions_size, int) \
\
nonstatic_field(ciMethodData, _data_size, int) \
nonstatic_field(ciMethodData, _state, u_char) \
--- a/hotspot/src/share/vm/services/classLoadingService.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/services/classLoadingService.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -135,7 +135,7 @@
// The spec is unclear at this point to count array klasses or not
// and also indirect creation of array of super class and secondaries
//
- // for (Klass* l = k; l != NULL; l = Klass::cast(l)->array_klass_or_null()) {
+ // for (Klass* l = k; l != NULL; l = l->array_klass_or_null()) {
// KlassHandle h(_current_thread, l);
// _loaded_classes->append(h);
// }
--- a/hotspot/src/share/vm/services/heapDumper.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/services/heapDumper.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -879,7 +879,7 @@
writer->write_u4(STACK_TRACE_ID);
// class ID
- writer->write_classID(Klass::cast(k));
+ writer->write_classID(k);
// number of bytes that follow
writer->write_u4(instance_size(k) );
@@ -891,7 +891,7 @@
// creates HPROF_GC_CLASS_DUMP record for the given class and each of
// its array classes
void DumperSupport::dump_class_and_array_classes(DumpWriter* writer, Klass* k) {
- Klass* klass = Klass::cast(k);
+ Klass* klass = k;
assert(klass->oop_is_instance(), "not an InstanceKlass");
InstanceKlass* ik = (InstanceKlass*)klass;
@@ -906,7 +906,7 @@
if (java_super == NULL) {
writer->write_objectID(oop(NULL));
} else {
- writer->write_classID(Klass::cast(java_super));
+ writer->write_classID(java_super);
}
writer->write_objectID(ik->class_loader());
@@ -932,7 +932,7 @@
// array classes
k = klass->array_klass_or_null();
while (k != NULL) {
- Klass* klass = Klass::cast(k);
+ Klass* klass = k;
assert(klass->oop_is_objArray(), "not an ObjArrayKlass");
writer->write_u1(HPROF_GC_CLASS_DUMP);
@@ -942,7 +942,7 @@
// super class of array classes is java.lang.Object
java_super = klass->java_super();
assert(java_super != NULL, "checking");
- writer->write_classID(Klass::cast(java_super));
+ writer->write_classID(java_super);
writer->write_objectID(ik->class_loader());
writer->write_objectID(ik->signers());
@@ -965,7 +965,7 @@
void DumperSupport::dump_basic_type_array_class(DumpWriter* writer, Klass* k) {
// array classes
while (k != NULL) {
- Klass* klass = Klass::cast(k);
+ Klass* klass = k;
writer->write_u1(HPROF_GC_CLASS_DUMP);
writer->write_classID(klass);
@@ -974,7 +974,7 @@
// super class of array classes is java.lang.Object
Klass* java_super = klass->java_super();
assert(java_super != NULL, "checking");
- writer->write_classID(Klass::cast(java_super));
+ writer->write_classID(java_super);
writer->write_objectID(oop(NULL)); // loader
writer->write_objectID(oop(NULL)); // signers
@@ -1001,7 +1001,7 @@
writer->write_u4((u4)array->length());
// array class ID
- writer->write_classID(Klass::cast(array->klass()));
+ writer->write_classID(array->klass());
// [id]* elements
for (int index=0; index<array->length(); index++) {
@@ -1117,8 +1117,8 @@
writer->write_symbolID(m->name()); // method's name
writer->write_symbolID(m->signature()); // method's signature
- assert(Klass::cast(m->method_holder())->oop_is_instance(), "not InstanceKlass");
- writer->write_symbolID(InstanceKlass::cast(m->method_holder())->source_file_name()); // source file name
+ assert(m->method_holder()->oop_is_instance(), "not InstanceKlass");
+ writer->write_symbolID(m->method_holder()->source_file_name()); // source file name
writer->write_u4(class_serial_num); // class serial number
writer->write_u4((u4) line_number); // line number
}
@@ -1525,7 +1525,7 @@
writer()->write_u4(++class_serial_num);
// class ID
- Klass* klass = Klass::cast(k);
+ Klass* klass = k;
writer()->write_classID(klass);
// add the Klass* and class serial number pair
@@ -1796,7 +1796,7 @@
// write fake frame that makes it look like the thread, which caused OOME,
// is in the OutOfMemoryError zero-parameter constructor
if (thread == _oome_thread && _oome_constructor != NULL) {
- int oome_serial_num = _klass_map->find(Klass::cast(_oome_constructor->method_holder()));
+ int oome_serial_num = _klass_map->find(_oome_constructor->method_holder());
// the class serial number starts from 1
assert(oome_serial_num > 0, "OutOfMemoryError class not found");
DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, oome_serial_num,
@@ -1806,7 +1806,7 @@
for (int j=0; j < depth; j++) {
StackFrameInfo* frame = stack_trace->stack_frame_at(j);
Method* m = frame->method();
- int class_serial_num = _klass_map->find(Klass::cast(m->method_holder()));
+ int class_serial_num = _klass_map->find(m->method_holder());
// the class serial number starts from 1
assert(class_serial_num > 0, "class not found");
DumperSupport::dump_stack_frame(writer(), ++frame_serial_num, class_serial_num, m, frame->bci());
--- a/hotspot/src/share/vm/services/management.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/services/management.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1417,7 +1417,7 @@
for (int i = 0; i < num_classes; i++) {
KlassHandle kh = lce.get_klass(i);
- oop mirror = Klass::cast(kh())->java_mirror();
+ oop mirror = kh()->java_mirror();
classes_ah->obj_at_put(i, mirror);
}
--- a/hotspot/src/share/vm/services/memBaseline.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/services/memBaseline.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -115,17 +115,25 @@
while (malloc_ptr != NULL) {
index = flag2index(FLAGS_TO_MEMORY_TYPE(malloc_ptr->flags()));
size_t size = malloc_ptr->size();
- _total_malloced += size;
- _malloc_data[index].inc(size);
- if (MemPointerRecord::is_arena_record(malloc_ptr->flags())) {
- // see if arena size record present
- MemPointerRecord* next_malloc_ptr = (MemPointerRecordEx*)malloc_itr.peek_next();
- if (MemPointerRecord::is_arena_size_record(next_malloc_ptr->flags())) {
- assert(next_malloc_ptr->is_size_record_of_arena(malloc_ptr), "arena records do not match");
- size = next_malloc_ptr->size();
- _arena_data[index].inc(size);
- used_arena_size += size;
- malloc_itr.next();
+ if (malloc_ptr->is_arena_memory_record()) {
+ // We do have anonymous arenas, they are either used as value objects,
+ // which are embedded inside other objects, or used as stack objects.
+ _arena_data[index].inc(size);
+ used_arena_size += size;
+ } else {
+ _total_malloced += size;
+ _malloc_data[index].inc(size);
+ if (malloc_ptr->is_arena_record()) {
+ // see if arena memory record present
+ MemPointerRecord* next_malloc_ptr = (MemPointerRecordEx*)malloc_itr.peek_next();
+ if (next_malloc_ptr->is_arena_memory_record()) {
+ assert(next_malloc_ptr->is_memory_record_of_arena(malloc_ptr),
+ "Arena records do not match");
+ size = next_malloc_ptr->size();
+ _arena_data[index].inc(size);
+ used_arena_size += size;
+ malloc_itr.next();
+ }
}
}
malloc_ptr = (MemPointerRecordEx*)malloc_itr.next();
@@ -193,7 +201,7 @@
// baseline memory that is totaled over 1 KB
while (malloc_ptr != NULL) {
- if (!MemPointerRecord::is_arena_size_record(malloc_ptr->flags())) {
+ if (!MemPointerRecord::is_arena_memory_record(malloc_ptr->flags())) {
// skip thread stacks
if (!IS_MEMORY_TYPE(malloc_ptr->flags(), mtThreadStack)) {
if (malloc_callsite.addr() != malloc_ptr->pc()) {
--- a/hotspot/src/share/vm/services/memPtr.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/services/memPtr.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -165,7 +165,7 @@
return (flags & (otArena | tag_size)) == otArena;
}
- inline static bool is_arena_size_record(MEMFLAGS flags) {
+ inline static bool is_arena_memory_record(MEMFLAGS flags) {
return (flags & (otArena | tag_size)) == (otArena | tag_size);
}
@@ -256,8 +256,8 @@
}
// if this record records a size information of an arena
- inline bool is_arena_size_record() const {
- return is_arena_size_record(_flags);
+ inline bool is_arena_memory_record() const {
+ return is_arena_memory_record(_flags);
}
// if this pointer represents an address to an arena object
@@ -266,8 +266,8 @@
}
// if this record represents a size information of specific arena
- inline bool is_size_record_of_arena(const MemPointerRecord* arena_rc) {
- assert(is_arena_size_record(), "not size record");
+ inline bool is_memory_record_of_arena(const MemPointerRecord* arena_rc) {
+ assert(is_arena_memory_record(), "not size record");
assert(arena_rc->is_arena_record(), "not arena record");
return (arena_rc->addr() + sizeof(void*)) == addr();
}
@@ -311,6 +311,17 @@
inline bool contains_address(address add) const {
return (addr() <= add && addr() + size() > add);
}
+
+ // if this memory region overlaps another region
+ inline bool overlaps_region(const MemPointerRecord* other) const {
+ assert(other != NULL, "Just check");
+ assert(size() > 0 && other->size() > 0, "empty range");
+ return contains_address(other->addr()) ||
+ contains_address(other->addr() + other->size() - 1) || // exclude end address
+ other->contains_address(addr()) ||
+ other->contains_address(addr() + size() - 1); // exclude end address
+ }
+
};
// MemPointerRecordEx also records callsite pc, from where
--- a/hotspot/src/share/vm/services/memSnapshot.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/services/memSnapshot.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -31,6 +31,69 @@
#include "services/memSnapshot.hpp"
#include "services/memTracker.hpp"
+#ifdef ASSERT
+
+void decode_pointer_record(MemPointerRecord* rec) {
+ tty->print("Pointer: [" PTR_FORMAT " - " PTR_FORMAT "] size = %d bytes", rec->addr(),
+ rec->addr() + rec->size(), (int)rec->size());
+ tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags())));
+ if (rec->is_vm_pointer()) {
+ if (rec->is_allocation_record()) {
+ tty->print_cr(" (reserve)");
+ } else if (rec->is_commit_record()) {
+ tty->print_cr(" (commit)");
+ } else if (rec->is_uncommit_record()) {
+ tty->print_cr(" (uncommit)");
+ } else if (rec->is_deallocation_record()) {
+ tty->print_cr(" (release)");
+ } else {
+ tty->print_cr(" (tag)");
+ }
+ } else {
+ if (rec->is_arena_memory_record()) {
+ tty->print_cr(" (arena size)");
+ } else if (rec->is_allocation_record()) {
+ tty->print_cr(" (malloc)");
+ } else {
+ tty->print_cr(" (free)");
+ }
+ }
+ if (MemTracker::track_callsite()) {
+ char buf[1024];
+ address pc = ((MemPointerRecordEx*)rec)->pc();
+ if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) {
+ tty->print_cr("\tfrom %s", buf);
+ } else {
+ tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc);
+ }
+ }
+}
+
+void decode_vm_region_record(VMMemRegion* rec) {
+ tty->print("VM Region [" PTR_FORMAT " - " PTR_FORMAT "]", rec->addr(),
+ rec->addr() + rec->size());
+ tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags())));
+ if (rec->is_allocation_record()) {
+ tty->print_cr(" (reserved)");
+ } else if (rec->is_commit_record()) {
+ tty->print_cr(" (committed)");
+ } else {
+ ShouldNotReachHere();
+ }
+ if (MemTracker::track_callsite()) {
+ char buf[1024];
+ address pc = ((VMMemRegionEx*)rec)->pc();
+ if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) {
+ tty->print_cr("\tfrom %s", buf);
+ } else {
+ tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc);
+ }
+
+ }
+}
+
+#endif
+
bool VMMemPointerIterator::insert_record(MemPointerRecord* rec) {
VMMemRegionEx new_rec;
@@ -60,65 +123,85 @@
// in different types.
bool VMMemPointerIterator::add_reserved_region(MemPointerRecord* rec) {
assert(rec->is_allocation_record(), "Sanity check");
- VMMemRegion* cur = (VMMemRegion*)current();
+ VMMemRegion* reserved_region = (VMMemRegion*)current();
// we don't have anything yet
- if (cur == NULL) {
+ if (reserved_region == NULL) {
return insert_record(rec);
}
- assert(cur->is_reserved_region(), "Sanity check");
+ assert(reserved_region->is_reserved_region(), "Sanity check");
// duplicated records
- if (cur->is_same_region(rec)) {
+ if (reserved_region->is_same_region(rec)) {
return true;
}
- assert(cur->base() > rec->addr(), "Just check: locate()");
- assert(rec->addr() + rec->size() <= cur->base(), "Can not overlap");
+ // Overlapping stack regions indicate that a JNI thread failed to
+ // detach from the VM before exiting. This leaks the JavaThread object.
+ if (CheckJNICalls) {
+ guarantee(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) != mtThreadStack ||
+ !reserved_region->overlaps_region(rec),
+ "Attached JNI thread exited without being detached");
+ }
+ // otherwise, we should not have overlapping reserved regions
+ assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack ||
+ reserved_region->base() > rec->addr(), "Just check: locate()");
+ assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack ||
+ !reserved_region->overlaps_region(rec), "overlapping reserved regions");
+
return insert_record(rec);
}
// we do consolidate committed regions
bool VMMemPointerIterator::add_committed_region(MemPointerRecord* rec) {
assert(rec->is_commit_record(), "Sanity check");
- VMMemRegion* cur;
- cur = (VMMemRegion*)current();
- assert(cur->is_reserved_region() && cur->contains_region(rec),
+ VMMemRegion* reserved_rgn = (VMMemRegion*)current();
+ assert(reserved_rgn->is_reserved_region() && reserved_rgn->contains_region(rec),
"Sanity check");
// thread's native stack is always marked as "committed", ignore
// the "commit" operation for creating stack guard pages
- if (FLAGS_TO_MEMORY_TYPE(cur->flags()) == mtThreadStack &&
+ if (FLAGS_TO_MEMORY_TYPE(reserved_rgn->flags()) == mtThreadStack &&
FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) {
return true;
}
- cur = (VMMemRegion*)next();
- while (cur != NULL && cur->is_committed_region()) {
+ // if the reserved region has any committed regions
+ VMMemRegion* committed_rgn = (VMMemRegion*)next();
+ while (committed_rgn != NULL && committed_rgn->is_committed_region()) {
// duplicated commit records
- if(cur->contains_region(rec)) {
+ if(committed_rgn->contains_region(rec)) {
return true;
- }
- if (cur->base() > rec->addr()) {
- // committed regions can not overlap
- assert(rec->addr() + rec->size() <= cur->base(), "Can not overlap");
- if (rec->addr() + rec->size() == cur->base()) {
- cur->expand_region(rec->addr(), rec->size());
- return true;
+ } else if (committed_rgn->overlaps_region(rec)) {
+ // overlaps front part
+ if (rec->addr() < committed_rgn->addr()) {
+ committed_rgn->expand_region(rec->addr(),
+ committed_rgn->addr() - rec->addr());
} else {
- return insert_record(rec);
+ // overlaps tail part
+ address committed_rgn_end = committed_rgn->addr() +
+ committed_rgn->size();
+ assert(committed_rgn_end < rec->addr() + rec->size(),
+ "overlap tail part");
+ committed_rgn->expand_region(committed_rgn_end,
+ (rec->addr() + rec->size()) - committed_rgn_end);
}
- } else if (cur->base() + cur->size() == rec->addr()) {
- cur->expand_region(rec->addr(), rec->size());
+ } else if (committed_rgn->base() + committed_rgn->size() == rec->addr()) {
+ // adjunct each other
+ committed_rgn->expand_region(rec->addr(), rec->size());
VMMemRegion* next_reg = (VMMemRegion*)next();
// see if we can consolidate next committed region
if (next_reg != NULL && next_reg->is_committed_region() &&
- next_reg->base() == cur->base() + cur->size()) {
- cur->expand_region(next_reg->base(), next_reg->size());
+ next_reg->base() == committed_rgn->base() + committed_rgn->size()) {
+ committed_rgn->expand_region(next_reg->base(), next_reg->size());
+ // delete merged region
remove();
}
return true;
+ } else if (committed_rgn->base() > rec->addr()) {
+ // found the location, insert this committed region
+ return insert_record(rec);
}
- cur = (VMMemRegion*)next();
+ committed_rgn = (VMMemRegion*)next();
}
return insert_record(rec);
}
@@ -318,21 +401,31 @@
}
}
-void MemSnapshot::copy_pointer(MemPointerRecord* dest, const MemPointerRecord* src) {
+
+void MemSnapshot::copy_seq_pointer(MemPointerRecord* dest, const MemPointerRecord* src) {
assert(dest != NULL && src != NULL, "Just check");
assert(dest->addr() == src->addr(), "Just check");
+ assert(dest->seq() > 0 && src->seq() > 0, "not sequenced");
- MEMFLAGS flags = dest->flags();
+ if (MemTracker::track_callsite()) {
+ *(SeqMemPointerRecordEx*)dest = *(SeqMemPointerRecordEx*)src;
+ } else {
+ *(SeqMemPointerRecord*)dest = *(SeqMemPointerRecord*)src;
+ }
+}
+
+void MemSnapshot::assign_pointer(MemPointerRecord*dest, const MemPointerRecord* src) {
+ assert(src != NULL && dest != NULL, "Just check");
+ assert(dest->seq() == 0 && src->seq() >0, "cast away sequence");
if (MemTracker::track_callsite()) {
*(MemPointerRecordEx*)dest = *(MemPointerRecordEx*)src;
} else {
- *dest = *src;
+ *(MemPointerRecord*)dest = *(MemPointerRecord*)src;
}
}
-
-// merge a per-thread memory recorder to the staging area
+// merge a recorder to the staging area
bool MemSnapshot::merge(MemRecorder* rec) {
assert(rec != NULL && !rec->out_of_memory(), "Just check");
@@ -340,71 +433,45 @@
MutexLockerEx lock(_lock, true);
MemPointerIterator malloc_staging_itr(_staging_area.malloc_data());
- MemPointerRecord *p1, *p2;
- p1 = (MemPointerRecord*) itr.current();
- while (p1 != NULL) {
- if (p1->is_vm_pointer()) {
+ MemPointerRecord* incoming_rec = (MemPointerRecord*) itr.current();
+ MemPointerRecord* matched_rec;
+
+ while (incoming_rec != NULL) {
+ if (incoming_rec->is_vm_pointer()) {
// we don't do anything with virtual memory records during merge
- if (!_staging_area.vm_data()->append(p1)) {
+ if (!_staging_area.vm_data()->append(incoming_rec)) {
return false;
}
} else {
// locate matched record and/or also position the iterator to proper
// location for this incoming record.
- p2 = (MemPointerRecord*)malloc_staging_itr.locate(p1->addr());
- // we have not seen this memory block, so just add to staging area
- if (p2 == NULL) {
- if (!malloc_staging_itr.insert(p1)) {
+ matched_rec = (MemPointerRecord*)malloc_staging_itr.locate(incoming_rec->addr());
+ // we have not seen this memory block in this generation,
+ // so just add to staging area
+ if (matched_rec == NULL) {
+ if (!malloc_staging_itr.insert(incoming_rec)) {
return false;
}
- } else if (p1->addr() == p2->addr()) {
- MemPointerRecord* staging_next = (MemPointerRecord*)malloc_staging_itr.peek_next();
- // a memory block can have many tagging records, find right one to replace or
- // right position to insert
- while (staging_next != NULL && staging_next->addr() == p1->addr()) {
- if ((staging_next->flags() & MemPointerRecord::tag_masks) <=
- (p1->flags() & MemPointerRecord::tag_masks)) {
- p2 = (MemPointerRecord*)malloc_staging_itr.next();
- staging_next = (MemPointerRecord*)malloc_staging_itr.peek_next();
- } else {
- break;
- }
+ } else if (incoming_rec->addr() == matched_rec->addr()) {
+ // whoever has higher sequence number wins
+ if (incoming_rec->seq() > matched_rec->seq()) {
+ copy_seq_pointer(matched_rec, incoming_rec);
}
- int df = (p1->flags() & MemPointerRecord::tag_masks) -
- (p2->flags() & MemPointerRecord::tag_masks);
- if (df == 0) {
- assert(p1->seq() > 0, "not sequenced");
- assert(p2->seq() > 0, "not sequenced");
- if (p1->seq() > p2->seq()) {
- copy_pointer(p2, p1);
- }
- } else if (df < 0) {
- if (!malloc_staging_itr.insert(p1)) {
- return false;
- }
- } else {
- if (!malloc_staging_itr.insert_after(p1)) {
- return false;
- }
- }
- } else if (p1->addr() < p2->addr()) {
- if (!malloc_staging_itr.insert(p1)) {
+ } else if (incoming_rec->addr() < matched_rec->addr()) {
+ if (!malloc_staging_itr.insert(incoming_rec)) {
return false;
}
} else {
- if (!malloc_staging_itr.insert_after(p1)) {
- return false;
- }
+ ShouldNotReachHere();
}
}
- p1 = (MemPointerRecord*)itr.next();
+ incoming_rec = (MemPointerRecord*)itr.next();
}
NOT_PRODUCT(void check_staging_data();)
return true;
}
-
// promote data to next generation
bool MemSnapshot::promote() {
assert(_alloc_ptrs != NULL && _vm_ptrs != NULL, "Just check");
@@ -435,20 +502,25 @@
// found matched memory block
if (matched_rec != NULL && new_rec->addr() == matched_rec->addr()) {
// snapshot already contains 'live' records
- assert(matched_rec->is_allocation_record() || matched_rec->is_arena_size_record(),
+ assert(matched_rec->is_allocation_record() || matched_rec->is_arena_memory_record(),
"Sanity check");
// update block states
- if (new_rec->is_allocation_record() || new_rec->is_arena_size_record()) {
- copy_pointer(matched_rec, new_rec);
+ if (new_rec->is_allocation_record()) {
+ assign_pointer(matched_rec, new_rec);
+ } else if (new_rec->is_arena_memory_record()) {
+ if (new_rec->size() == 0) {
+ // remove size record once size drops to 0
+ malloc_snapshot_itr.remove();
+ } else {
+ assign_pointer(matched_rec, new_rec);
+ }
} else {
// a deallocation record
assert(new_rec->is_deallocation_record(), "Sanity check");
// an arena record can be followed by a size record, we need to remove both
if (matched_rec->is_arena_record()) {
MemPointerRecord* next = (MemPointerRecord*)malloc_snapshot_itr.peek_next();
- if (next->is_arena_size_record()) {
- // it has to match the arena record
- assert(next->is_size_record_of_arena(matched_rec), "Sanity check");
+ if (next->is_arena_memory_record() && next->is_memory_record_of_arena(matched_rec)) {
malloc_snapshot_itr.remove();
}
}
@@ -456,17 +528,13 @@
malloc_snapshot_itr.remove();
}
} else {
- // it is a new record, insert into snapshot
- if (new_rec->is_arena_size_record()) {
- MemPointerRecord* prev = (MemPointerRecord*)malloc_snapshot_itr.peek_prev();
- if (prev == NULL || !prev->is_arena_record() || !new_rec->is_size_record_of_arena(prev)) {
- // no matched arena record, ignore the size record
- new_rec = NULL;
- }
+ // don't insert size 0 record
+ if (new_rec->is_arena_memory_record() && new_rec->size() == 0) {
+ new_rec = NULL;
}
- // only 'live' record can go into snapshot
+
if (new_rec != NULL) {
- if (new_rec->is_allocation_record() || new_rec->is_arena_size_record()) {
+ if (new_rec->is_allocation_record() || new_rec->is_arena_memory_record()) {
if (matched_rec != NULL && new_rec->addr() > matched_rec->addr()) {
if (!malloc_snapshot_itr.insert_after(new_rec)) {
return false;
--- a/hotspot/src/share/vm/services/memSnapshot.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/services/memSnapshot.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -31,7 +31,6 @@
#include "services/memBaseline.hpp"
#include "services/memPtrArray.hpp"
-
// Snapshot pointer array iterator
// The pointer array contains malloc-ed pointers
@@ -165,39 +164,58 @@
};
class MallocRecordIterator : public MemPointerArrayIterator {
- protected:
+ private:
MemPointerArrayIteratorImpl _itr;
+
+
public:
MallocRecordIterator(MemPointerArray* arr) : _itr(arr) {
}
virtual MemPointer* current() const {
- MemPointerRecord* cur = (MemPointerRecord*)_itr.current();
- assert(cur == NULL || !cur->is_vm_pointer(), "seek error");
- MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next();
- if (next == NULL || next->addr() != cur->addr()) {
- return cur;
- } else {
- assert(!cur->is_vm_pointer(), "Sanity check");
- assert(cur->is_allocation_record() && next->is_deallocation_record(),
- "sorting order");
- assert(cur->seq() != next->seq(), "Sanity check");
- return cur->seq() > next->seq() ? cur : next;
+#ifdef ASSERT
+ MemPointer* cur_rec = _itr.current();
+ if (cur_rec != NULL) {
+ MemPointer* prev_rec = _itr.peek_prev();
+ MemPointer* next_rec = _itr.peek_next();
+ assert(prev_rec == NULL || prev_rec->addr() < cur_rec->addr(), "Sorting order");
+ assert(next_rec == NULL || next_rec->addr() > cur_rec->addr(), "Sorting order");
}
+#endif
+ return _itr.current();
}
-
virtual MemPointer* next() {
- MemPointerRecord* cur = (MemPointerRecord*)_itr.current();
- assert(cur == NULL || !cur->is_vm_pointer(), "Sanity check");
- MemPointerRecord* next = (MemPointerRecord*)_itr.next();
- if (next == NULL) {
- return NULL;
+ MemPointerRecord* next_rec = (MemPointerRecord*)_itr.next();
+ // arena memory record is a special case, which we have to compare
+ // sequence number against its associated arena record.
+ if (next_rec != NULL && next_rec->is_arena_memory_record()) {
+ MemPointerRecord* prev_rec = (MemPointerRecord*)_itr.peek_prev();
+ // if there is an associated arena record, it has to be previous
+ // record because of sorting order (by address) - NMT generates a pseudo address
+ // for arena's size record by offsetting arena's address, that guarantees
+ // the order of arena record and it's size record.
+ if (prev_rec != NULL && prev_rec->is_arena_record() &&
+ next_rec->is_memory_record_of_arena(prev_rec)) {
+ if (prev_rec->seq() > next_rec->seq()) {
+ // Skip this arena memory record
+ // Two scenarios:
+ // - if the arena record is an allocation record, this early
+ // size record must be leftover by previous arena,
+ // and the last size record should have size = 0.
+ // - if the arena record is a deallocation record, this
+ // size record should be its cleanup record, which should
+ // also have size = 0. In other world, arena alway reset
+ // its size before gone (see Arena's destructor)
+ assert(next_rec->size() == 0, "size not reset");
+ return _itr.next();
+ } else {
+ assert(prev_rec->is_allocation_record(),
+ "Arena size record ahead of allocation record");
+ }
+ }
}
- if (cur->addr() == next->addr()) {
- next = (MemPointerRecord*)_itr.next();
- }
- return current();
+ return next_rec;
}
MemPointer* peek_next() const { ShouldNotReachHere(); return NULL; }
@@ -213,9 +231,12 @@
// still chances seeing duplicated records during promotion.
// We want to use the record with higher sequence number, because it has
// more accurate callsite pc.
-class VMRecordIterator : public MallocRecordIterator {
+class VMRecordIterator : public MemPointerArrayIterator {
+ private:
+ MemPointerArrayIteratorImpl _itr;
+
public:
- VMRecordIterator(MemPointerArray* arr) : MallocRecordIterator(arr) {
+ VMRecordIterator(MemPointerArray* arr) : _itr(arr) {
MemPointerRecord* cur = (MemPointerRecord*)_itr.current();
MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next();
while (next != NULL) {
@@ -256,6 +277,12 @@
return cur;
}
+ MemPointer* peek_next() const { ShouldNotReachHere(); return NULL; }
+ MemPointer* peek_prev() const { ShouldNotReachHere(); return NULL; }
+ void remove() { ShouldNotReachHere(); }
+ bool insert(MemPointer* ptr) { ShouldNotReachHere(); return false; }
+ bool insert_after(MemPointer* ptr) { ShouldNotReachHere(); return false; }
+
private:
bool is_duplicated_record(MemPointerRecord* p1, MemPointerRecord* p2) const {
bool ret = (p1->addr() == p2->addr() && p1->size() == p2->size() && p1->flags() == p2->flags());
@@ -348,8 +375,10 @@
DEBUG_ONLY( void dump_all_vm_pointers();)
private:
- // copy pointer data from src to dest
- void copy_pointer(MemPointerRecord* dest, const MemPointerRecord* src);
+ // copy sequenced pointer from src to dest
+ void copy_seq_pointer(MemPointerRecord* dest, const MemPointerRecord* src);
+ // assign a sequenced pointer to non-sequenced pointer
+ void assign_pointer(MemPointerRecord*dest, const MemPointerRecord* src);
bool promote_malloc_records(MemPointerArrayIterator* itr);
bool promote_virtual_memory_records(MemPointerArrayIterator* itr);
--- a/hotspot/src/share/vm/services/memTracker.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/services/memTracker.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -284,14 +284,14 @@
}
}
- // record arena size
+ // record arena memory size
static inline void record_arena_size(address addr, size_t size) {
- // we add a positive offset to arena address, so we can have arena size record
+ // we add a positive offset to arena address, so we can have arena memory record
// sorted after arena record
if (is_on() && !UseMallocOnly) {
assert(addr != NULL, "Sanity check");
create_memory_record((addr + sizeof(void*)), MemPointerRecord::arena_size_tag(), size,
- 0, NULL);
+ DEBUG_CALLER_PC, NULL);
}
}
--- a/hotspot/src/share/vm/services/serviceUtil.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/services/serviceUtil.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -57,14 +57,13 @@
if (k->is_klass()) {
// if it's a class for an object, an object array, or
// primitive (type) array then it's visible.
- Klass* klass = k;
- if (Klass::cast(klass)->oop_is_instance()) {
+ if (k->oop_is_instance()) {
return true;
}
- if (Klass::cast(klass)->oop_is_objArray()) {
+ if (k->oop_is_objArray()) {
return true;
}
- if (Klass::cast(klass)->oop_is_typeArray()) {
+ if (k->oop_is_typeArray()) {
return true;
}
}
--- a/hotspot/src/share/vm/utilities/array.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/utilities/array.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -353,9 +353,9 @@
// sort the array.
bool contains(const T& x) const { return index_of(x) >= 0; }
- T at(int i) const { return _data[i]; }
- void at_put(const int i, const T& x) { _data[i] = x; }
- T* adr_at(const int i) { return &_data[i]; }
+ T at(int i) const { assert(i >= 0 && i< _length, err_msg_res("oob: 0 <= %d < %d", i, _length)); return _data[i]; }
+ void at_put(const int i, const T& x) { assert(i >= 0 && i< _length, err_msg_res("oob: 0 <= %d < %d", i, _length)); _data[i] = x; }
+ T* adr_at(const int i) { assert(i >= 0 && i< _length, err_msg_res("oob: 0 <= %d < %d", i, _length)); return &_data[i]; }
int find(const T& x) { return index_of(x); }
T at_acquire(const int which) { return OrderAccess::load_acquire(adr_at(which)); }
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -328,6 +328,12 @@
//----------------------------------------------------------------------------------------------------
+// Minimum StringTableSize value
+
+const int defaultStringTableSize=1009;
+
+
+//----------------------------------------------------------------------------------------------------
// HotSwap - for JVMTI aka Class File Replacement and PopFrame
//
// Determines whether on-the-fly class replacement and frame popping are enabled.
--- a/hotspot/src/share/vm/utilities/growableArray.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -217,7 +217,12 @@
return missed;
}
- E at(int i) const {
+ E& at(int i) {
+ assert(0 <= i && i < _len, "illegal index");
+ return _data[i];
+ }
+
+ E const& at(int i) const {
assert(0 <= i && i < _len, "illegal index");
return _data[i];
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/utilities/pair.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_UTILITIES_PAIR_HPP
+#define SHARE_VM_UTILITIES_PAIR_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/top.hpp"
+
+template<typename T, typename V, typename ALLOC_BASE = ResourceObj>
+class Pair : public ALLOC_BASE {
+ public:
+ T first;
+ V second;
+
+ Pair() {}
+ Pair(T t, V v) : first(t), second(v) {}
+};
+
+
+#endif // SHARE_VM_UTILITIES_PAIR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/utilities/resourceHash.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_UTILITIES_RESOURCEHASH_HPP
+#define SHARE_VM_UTILITIES_RESOURCEHASH_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/top.hpp"
+
+template<typename K> struct ResourceHashtableFns {
+ typedef unsigned (*hash_fn)(K const&);
+ typedef bool (*equals_fn)(K const&, K const&);
+};
+
+template<typename K> unsigned primitive_hash(const K& k) {
+ unsigned hash = (unsigned)((uintptr_t)k);
+ return hash ^ (hash > 3); // just in case we're dealing with aligned ptrs
+}
+
+template<typename K> bool primitive_equals(const K& k0, const K& k1) {
+ return k0 == k1;
+}
+
+template<
+ typename K, typename V,
+ typename ResourceHashtableFns<K>::hash_fn HASH = primitive_hash<K>,
+ typename ResourceHashtableFns<K>::equals_fn EQUALS = primitive_equals<K>,
+ unsigned SIZE = 256
+ >
+class ResourceHashtable : public ResourceObj {
+ private:
+
+ class Node : public ResourceObj {
+ public:
+ unsigned _hash;
+ K _key;
+ V _value;
+ Node* _next;
+
+ Node(unsigned hash, K const& key, V const& value) :
+ _hash(hash), _key(key), _value(value), _next(NULL) {}
+ };
+
+ Node* _table[SIZE];
+
+ // Returns a pointer to where the node where the value would reside if
+ // it's in the table.
+ Node** lookup_node(unsigned hash, K const& key) {
+ unsigned index = hash % SIZE;
+ Node** ptr = &_table[index];
+ while (*ptr != NULL) {
+ Node* node = *ptr;
+ if (node->_hash == hash && EQUALS(key, node->_key)) {
+ break;
+ }
+ ptr = &(node->_next);
+ }
+ return ptr;
+ }
+
+ Node const** lookup_node(unsigned hash, K const& key) const {
+ return const_cast<Node const**>(
+ const_cast<ResourceHashtable*>(this)->lookup_node(hash, key));
+ }
+
+ public:
+ ResourceHashtable() { memset(_table, 0, SIZE * sizeof(Node*)); }
+
+ bool contains(K const& key) const {
+ return get(key) != NULL;
+ }
+
+ V* get(K const& key) const {
+ unsigned hv = HASH(key);
+ Node const** ptr = lookup_node(hv, key);
+ if (*ptr != NULL) {
+ return const_cast<V*>(&(*ptr)->_value);
+ } else {
+ return NULL;
+ }
+ }
+
+ // Inserts or replaces a value in the table
+ void put(K const& key, V const& value) {
+ unsigned hv = HASH(key);
+ Node** ptr = lookup_node(hv, key);
+ if (*ptr != NULL) {
+ (*ptr)->_value = value;
+ } else {
+ *ptr = new Node(hv, key, value);
+ }
+ }
+
+ // ITER contains bool do_entry(K const&, V const&), which will be
+ // called for each entry in the table. If do_entry() returns false,
+ // the iteration is cancelled.
+ template<class ITER>
+ void iterate(ITER* iter) const {
+ Node* const* bucket = _table;
+ while (bucket < &_table[SIZE]) {
+ Node* node = *bucket;
+ while (node != NULL) {
+ bool cont = iter->do_entry(node->_key, node->_value);
+ if (!cont) { return; }
+ node = node->_next;
+ }
+ ++bucket;
+ }
+ }
+};
+
+
+#endif // SHARE_VM_UTILITIES_RESOURCEHASH_HPP
--- a/hotspot/src/share/vm/utilities/utf8.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/utilities/utf8.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -147,7 +147,7 @@
void UTF8::convert_to_unicode(const char* utf8_str, jchar* unicode_str, int unicode_length) {
unsigned char ch;
- const char *ptr = (const char *)utf8_str;
+ const char *ptr = utf8_str;
int index = 0;
/* ASCII case loop optimization */
@@ -162,6 +162,119 @@
}
}
+// returns the quoted ascii length of a 0-terminated utf8 string
+int UTF8::quoted_ascii_length(const char* utf8_str, int utf8_length) {
+ const char *ptr = utf8_str;
+ const char* end = ptr + utf8_length;
+ int result = 0;
+ while (ptr < end) {
+ jchar c;
+ ptr = UTF8::next(ptr, &c);
+ if (c >= 32 && c < 127) {
+ result++;
+ } else {
+ result += 6;
+ }
+ }
+ return result;
+}
+
+// converts a utf8 string to quoted ascii
+void UTF8::as_quoted_ascii(const char* utf8_str, char* buf, int buflen) {
+ const char *ptr = utf8_str;
+ char* p = buf;
+ char* end = buf + buflen;
+ while (*ptr != '\0') {
+ jchar c;
+ ptr = UTF8::next(ptr, &c);
+ if (c >= 32 && c < 127) {
+ if (p + 1 >= end) break; // string is truncated
+ *p++ = (char)c;
+ } else {
+ if (p + 6 >= end) break; // string is truncated
+ sprintf(p, "\\u%04x", c);
+ p += 6;
+ }
+ }
+ *p = '\0';
+}
+
+
+const char* UTF8::from_quoted_ascii(const char* quoted_ascii_str) {
+ const char *ptr = quoted_ascii_str;
+ char* result = NULL;
+ while (*ptr != '\0') {
+ char c = *ptr;
+ if (c < 32 || c >= 127) break;
+ }
+ if (*ptr == '\0') {
+ // nothing to do so return original string
+ return quoted_ascii_str;
+ }
+ // everything up to this point was ok.
+ int length = ptr - quoted_ascii_str;
+ char* buffer = NULL;
+ for (int round = 0; round < 2; round++) {
+ while (*ptr != '\0') {
+ if (*ptr != '\\') {
+ if (buffer != NULL) {
+ buffer[length] = *ptr;
+ }
+ length++;
+ } else {
+ switch (ptr[1]) {
+ case 'u': {
+ ptr += 2;
+ jchar value=0;
+ for (int i=0; i<4; i++) {
+ char c = *ptr++;
+ switch (c) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ value = (value << 4) + c - '0';
+ break;
+ case 'a': case 'b': case 'c':
+ case 'd': case 'e': case 'f':
+ value = (value << 4) + 10 + c - 'a';
+ break;
+ case 'A': case 'B': case 'C':
+ case 'D': case 'E': case 'F':
+ value = (value << 4) + 10 + c - 'A';
+ break;
+ default:
+ ShouldNotReachHere();
+ }
+ }
+ if (buffer == NULL) {
+ char utf8_buffer[4];
+ char* next = (char*)utf8_write((u_char*)utf8_buffer, value);
+ length += next - utf8_buffer;
+ } else {
+ char* next = (char*)utf8_write((u_char*)&buffer[length], value);
+ length += next - &buffer[length];
+ }
+ break;
+ }
+ case 't': if (buffer != NULL) buffer[length] = '\t'; ptr += 2; length++; break;
+ case 'n': if (buffer != NULL) buffer[length] = '\n'; ptr += 2; length++; break;
+ case 'r': if (buffer != NULL) buffer[length] = '\r'; ptr += 2; length++; break;
+ case 'f': if (buffer != NULL) buffer[length] = '\f'; ptr += 2; length++; break;
+ default:
+ ShouldNotReachHere();
+ }
+ }
+ }
+ if (round == 0) {
+ buffer = NEW_RESOURCE_ARRAY(char, length + 1);
+ ptr = quoted_ascii_str;
+ } else {
+ buffer[length] = '\0';
+ }
+ }
+ return buffer;
+}
+
+
// Returns NULL if 'c' it not found. This only works as long
// as 'c' is an ASCII character
const jbyte* UTF8::strrchr(const jbyte* base, int length, jbyte c) {
@@ -242,3 +355,35 @@
}
*utf8_buffer = '\0';
}
+
+// returns the quoted ascii length of a unicode string
+int UNICODE::quoted_ascii_length(jchar* base, int length) {
+ int result = 0;
+ for (int i = 0; i < length; i++) {
+ jchar c = base[i];
+ if (c >= 32 && c < 127) {
+ result++;
+ } else {
+ result += 6;
+ }
+ }
+ return result;
+}
+
+// converts a utf8 string to quoted ascii
+void UNICODE::as_quoted_ascii(const jchar* base, int length, char* buf, int buflen) {
+ char* p = buf;
+ char* end = buf + buflen;
+ for (int index = 0; index < length; index++) {
+ jchar c = base[index];
+ if (c >= 32 && c < 127) {
+ if (p + 1 >= end) break; // string is truncated
+ *p++ = (char)c;
+ } else {
+ if (p + 6 >= end) break; // string is truncated
+ sprintf(p, "\\u%04x", c);
+ p += 6;
+ }
+ }
+ *p = '\0';
+}
--- a/hotspot/src/share/vm/utilities/utf8.hpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/utilities/utf8.hpp Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -32,22 +32,32 @@
class UTF8 : AllStatic {
public:
- // returns the unicode length of a 0-terminated uft8 string
- static int unicode_length(const char* uft8_str);
+ // returns the unicode length of a 0-terminated utf8 string
+ static int unicode_length(const char* utf8_str);
- // returns the unicode length of a non-0-terminated uft8 string
- static int unicode_length(const char* uft8_str, int len);
+ // returns the unicode length of a non-0-terminated utf8 string
+ static int unicode_length(const char* utf8_str, int len);
- // converts a uft8 string to a unicode string
+ // converts a utf8 string to a unicode string
static void convert_to_unicode(const char* utf8_str, jchar* unicode_buffer, int unicode_length);
+ // returns the quoted ascii length of a utf8 string
+ static int quoted_ascii_length(const char* utf8_str, int utf8_length);
+
+ // converts a utf8 string to quoted ascii
+ static void as_quoted_ascii(const char* utf8_str, char* buf, int buflen);
+
+ // converts a quoted ascii string to utf8 string. returns the original
+ // string unchanged if nothing needs to be done.
+ static const char* from_quoted_ascii(const char* quoted_ascii_string);
+
// decodes the current utf8 character, stores the result in value,
- // and returns the end of the current uft8 chararacter.
+ // and returns the end of the current utf8 chararacter.
static char* next(const char* str, jchar* value);
// decodes the current utf8 character, gets the supplementary character instead of
// the surrogate pair when seeing a supplementary character in string,
- // stores the result in value, and returns the end of the current uft8 chararacter.
+ // stores the result in value, and returns the end of the current utf8 chararacter.
static char* next_character(const char* str, jint* value);
// Utility methods
@@ -79,6 +89,12 @@
// in resource area unless a buffer is provided.
static char* as_utf8(jchar* base, int length);
static char* as_utf8(jchar* base, int length, char* buf, int buflen);
+
+ // returns the quoted ascii length of a unicode string
+ static int quoted_ascii_length(jchar* base, int length);
+
+ // converts a utf8 string to quoted ascii
+ static void as_quoted_ascii(const jchar* base, int length, char* buf, int buflen);
};
#endif // SHARE_VM_UTILITIES_UTF8_HPP
--- a/hotspot/src/share/vm/utilities/vmError.cpp Fri Nov 30 12:39:37 2012 +0000
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Fri Nov 30 17:09:05 2012 -0800
@@ -1009,6 +1009,15 @@
OnError = NULL;
}
+ static bool skip_replay = false;
+ if (DumpReplayDataOnError && _thread && _thread->is_Compiler_thread() && !skip_replay) {
+ skip_replay = true;
+ ciEnv* env = ciEnv::current();
+ if (env != NULL) {
+ env->dump_replay_data();
+ }
+ }
+
static bool skip_bug_url = !should_report_bug(first_error->_id);
if (!skip_bug_url) {
skip_bug_url = true;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/8002069/Test8002069.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, 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 8002069
+ * @summary Assert failed in C2: assert(field->edge_count() > 0) failed: sanity
+ *
+ * @run main/othervm -Xmx32m -XX:+IgnoreUnrecognizedVMOptions -Xbatch -XX:CompileCommand=exclude,Test8002069.dummy Test8002069
+ */
+
+abstract class O {
+ int f;
+ public O() { f = 5; }
+ abstract void put(int i);
+ public int foo(int i) {
+ put(i);
+ return i;
+ }
+};
+
+class A extends O {
+ int[] a;
+ public A(int s) {
+ a = new int[s];
+ }
+ public void put(int i) {
+ a[i%a.length] = i;
+ }
+}
+
+class B extends O {
+ int sz;
+ int[] a;
+ public B(int s) {
+ sz = s;
+ a = new int[s];
+ }
+ public void put(int i) {
+ a[i%sz] = i;
+ }
+}
+
+public class Test8002069 {
+ public static void main(String args[]) {
+ int sum = 0;
+ for (int i=0; i<8000; i++) {
+ sum += test1(i);
+ }
+ for (int i=0; i<100000; i++) {
+ sum += test2(i);
+ }
+ System.out.println("PASSED. sum = " + sum);
+ }
+
+ private O o;
+
+ private int foo(int i) {
+ return o.foo(i);
+ }
+ static int test1(int i) {
+ Test8002069 t = new Test8002069();
+ t.o = new A(5);
+ return t.foo(i);
+ }
+ static int test2(int i) {
+ Test8002069 t = new Test8002069();
+ t.o = new B(5);
+ dummy(i);
+ return t.foo(i);
+ }
+
+ static int dummy(int i) {
+ return i*2;
+ }
+}
+
--- a/jaxp/.hgtags Fri Nov 30 12:39:37 2012 +0000
+++ b/jaxp/.hgtags Fri Nov 30 17:09:05 2012 -0800
@@ -185,3 +185,5 @@
6b1db0b41d2f6e2a7b3bdbc8a8db823b47752906 jdk8-b61
5d0fa0108d028c05753a47bcf2a598357dabf0c0 jdk8-b62
192d8a244bc36427757866e9fb3a08938c0e674c jdk8-b63
+27ab79568c34abf80958d5fa8c04fd1740d243da jdk8-b64
+5cf3c69a93d6d088a1cdfa28031d4f0f9438c0de jdk8-b65
--- a/jaxws/.hgtags Fri Nov 30 12:39:37 2012 +0000
+++ b/jaxws/.hgtags Fri Nov 30 17:09:05 2012 -0800
@@ -185,3 +185,5 @@
97e5e74e2a341d9142ce28043912a3c255e28e03 jdk8-b61
d265b9b4c0f55c23a1c9fda02a8052fd9df2eec5 jdk8-b62
86989f702267debe16d13720d5ae7ae9839796f4 jdk8-b63
+5ded18a14bcc80b2a253f2b84da0073a0ecac665 jdk8-b64
+fbe54291c9d337ea4dfef4d846f1d9a22f76249c jdk8-b65
--- a/jdk/.hgtags Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/.hgtags Fri Nov 30 17:09:05 2012 -0800
@@ -186,3 +186,5 @@
50b8b17449d200c66bfd68fb4f3a9197432c9e2b jdk8-b62
f117a3e06f78a258074674ad17601f99bcb1ce0d jdk8-b63
26dbd73fb7662a29b3e47179fdc88a0bfa4e231e jdk8-b64
+130d3a54d28becaac0846137256c2684adb34c33 jdk8-b65
+4d337fae2250135729ee9ed2bf8baf3c60da5d6d jdk8-b66
--- a/jdk/make/common/Defs-linux.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/make/common/Defs-linux.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -111,21 +111,18 @@
# since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
- # Default OBJCOPY comes from GNU Binutils on Linux:
- DEF_OBJCOPY=/usr/bin/objcopy
- ifdef CROSS_COMPILE_ARCH
- # don't try to generate .debuginfo files when cross compiling
- _JUNK_ := $(shell \
- echo >&2 "INFO: cross compiling for ARCH $(CROSS_COMPILE_ARCH)," \
- "skipping .debuginfo generation.")
- OBJCOPY=
+ ifndef CROSS_COMPILE_ARCH
+ # Default OBJCOPY comes from GNU Binutils on Linux:
+ DEF_OBJCOPY=/usr/bin/objcopy
else
- OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
- ifneq ($(ALT_OBJCOPY),)
- _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
- # disable .debuginfo support by setting ALT_OBJCOPY to a non-existent path
- OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
- endif
+ # Assume objcopy is part of the cross-compilation toolkit
+ DEF_OBJCOPY=$(COMPILER_PATH)/objcopy
+ endif
+ OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
+ ifneq ($(ALT_OBJCOPY),)
+ _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
+ # disable .debuginfo support by setting ALT_OBJCOPY to a non-existent path
+ OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
endif
# Setting ENABLE_FULL_DEBUG_SYMBOLS=1 (and OBJCOPY) above enables the
@@ -137,7 +134,7 @@
ifeq ($(OBJCOPY),)
_JUNK_ := $(shell \
- echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.")
+ echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files. You may need to set ALT_OBJCOPY.")
ENABLE_FULL_DEBUG_SYMBOLS=0
else
_JUNK_ := $(shell \
--- a/jdk/make/java/java/FILES_java.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/make/java/java/FILES_java.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -206,6 +206,7 @@
sun/util/locale/provider/BreakIteratorProviderImpl.java \
sun/util/locale/provider/CalendarDataProviderImpl.java \
sun/util/locale/provider/CalendarDataUtility.java \
+ sun/util/locale/provider/CalendarNameProviderImpl.java \
sun/util/locale/provider/CollationRules.java \
sun/util/locale/provider/CollatorProviderImpl.java \
sun/util/locale/provider/CurrencyNameProviderImpl.java \
@@ -396,6 +397,7 @@
java/util/prefs/Base64.java \
java/util/prefs/XmlSupport.java \
java/util/spi/CalendarDataProvider.java \
+ java/util/spi/CalendarNameProvider.java \
java/util/spi/CurrencyNameProvider.java \
java/util/spi/LocaleNameProvider.java \
java/util/spi/LocaleServiceProvider.java \
--- a/jdk/makefiles/CompileDemos.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/makefiles/CompileDemos.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -166,9 +166,9 @@
$(eval $(call SetupDemo,SwingApplet,jfc,,SwingApplet,,,README* *.html))
$(eval $(call SetupDemo,TableExample,jfc,,TableExample,,,README*))
$(eval $(call SetupDemo,TransparentRuler,jfc,,transparentruler.Ruler,,,README*))
-$(eval $(call SetupDemo,jconsole-plugin,scripting,-cp $(JDK_OUTPUTDIR)/lib/jconsole.jar,,,,*.xml *.txt,,,,Main-Class: \n))
+$(eval $(call SetupDemo,jconsole-plugin,scripting,,,,,*.xml *.txt,,,,Main-Class: \n))
$(eval $(call SetupDemo,FullThreadDump,management,,FullThreadDump,,,README*))
-$(eval $(call SetupDemo,JTop,management,-cp $(JDK_OUTPUTDIR)/lib/jconsole.jar,JTop,,,README*))
+$(eval $(call SetupDemo,JTop,management,,JTop,,,README*))
$(eval $(call SetupDemo,MemoryMonitor,management,,MemoryMonitor,,,README*))
$(eval $(call SetupDemo,VerboseGC,management,,VerboseGC,,,README*))
$(eval $(call SetupDemo,zipfs,nio,,,,,README* *.java,,,,Main-Class: \n))
--- a/jdk/makefiles/CompileLaunchers.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/makefiles/CompileLaunchers.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -238,7 +238,7 @@
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.tools.jar.Main"$(COMMA) }'))
$(eval $(call SetupLauncher,jarsigner,\
- -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.security.tools.jarSigner.Main"$(COMMA) }'))
+ -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.security.tools.jarsigner.Main"$(COMMA) }'))
$(eval $(call SetupLauncher,javac,\
-DEXPAND_CLASSPATH_WILDCARDS \
--- a/jdk/makefiles/CompileNativeLibraries.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/makefiles/CompileNativeLibraries.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -104,7 +104,7 @@
LANG:=C,\
CFLAGS:=$(CFLAGS_JDKLIB) \
-I$(JDK_TOPDIR)/src/share/native/java/lang/fdlibm/include,\
- LDFLAGS:=-nostdlib -r -arch i386 -arch x86_64,\
+ LDFLAGS:=-nostdlib -r -arch x86_64,\
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libfdlibm))
$(JDK_OUTPUTDIR)/objs/$(LIBRARY_PREFIX)fdlibm$(STATIC_LIBRARY_SUFFIX) : $(BUILD_LIBFDLIBM)
@@ -240,7 +240,7 @@
LDFLAGS:=$(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_SUFFIX_posix:=-ljvm -lverify, \
- LDFLAGS_SUFFIX_solaris:=-lnsl -lsocket -lscf $(LIBDL) $(BUILD_LIBFDLIBM) -lc,\
+ LDFLAGS_SUFFIX_solaris:=-lsocket -lnsl -lscf $(LIBDL) $(BUILD_LIBFDLIBM) -lc,\
LDFLAGS_SUFFIX_linux:=$(LIBDL) $(BUILD_LIBFDLIBM),\
LDFLAGS_SUFFIX_macosx:=-L$(JDK_OUTPUTDIR)/objs/ -lfdlibm \
-framework CoreFoundation \
@@ -300,6 +300,7 @@
$(call SET_SHARED_LIBRARY_ORIGIN),\
LDFLAGS_SUFFIX:=$(BUILD_LIBMLIB_LDLIBS) \
$(LDFLAGS_JDKLIB_SUFFIX),\
+ LDFLAGS_SUFFIX_solaris:=-lc, \
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
RC_FLAGS:=$(RC_FLAGS)\
-D "JDK_FNAME=mlib_image.dll" \
@@ -428,6 +429,7 @@
LDFLAGS:=$(LDFLAGS_JDKLIB) \
$(BUILD_LIBMLIB_LDLIBS) -ljava -ljvm \
$(call SET_SHARED_LIBRARY_ORIGIN),\
+ LDFLAGS_SUFFIX_solaris:=-lc,\
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libmlib_image_v))
$(BUILD_LIBMLIB_IMAGE_V): $(BUILD_LIBJAVA)
@@ -710,7 +712,7 @@
LDFLAGS:=$(LDFLAGS_JDKLIB) $(call SET_SHARED_LIBRARY_ORIGIN),\
LDFLAGS_solaris:=-R/usr/dt/lib$(OPENJDK_TARGET_CPU_ISADIR) -R$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR),\
LDFLAGS_SUFFIX_linux:=-ljvm $(LIBM) $(LIBDL) -ljava,\
- LDFLAGS_SUFFIX_solaris:=-ljvm $(LIBM) $(LIBDL) -ljava,\
+ LDFLAGS_SUFFIX_solaris:=-ljvm $(LIBM) $(LIBDL) -ljava -lc,\
LDFLAGS_SUFFIX_macosx:=-lmlib_image -ljvm $(LIBM) \
-framework Cocoa \
-framework OpenGL \
@@ -903,57 +905,34 @@
##########################################################################################
-BUILD_LIBZIP_FILES:=\
- CRC32.c \
- Adler32.c \
- Deflater.c \
- Inflater.c \
- ZipFile.c \
- zip_util.c
-
+BUILD_LIBZIP_EXCLUDES :=
ifeq ($(USE_EXTERNAL_LIBZ),true)
- LIBZ:=-lz
+ LIBZ := -lz
+ LIBZIP_EXCLUDES += zlib-1.2.5
else
-BUILD_LIBZIP_FILES += \
- compress.c \
- deflate.c \
- gzclose.c \
- gzlib.c \
- gzread.c \
- gzwrite.c \
- infback.c \
- inffast.c \
- inflate.c \
- inftrees.c \
- trees.c \
- uncompr.c \
- zadler32.c \
- zcrc32.c \
- zutil.c
-LIBZ_INCLUDE:=-I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5
+ ZLIB_CPPFLAGS := -I$(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5
endif
-BUILD_LIBZIP_REORDER:=
+BUILD_LIBZIP_REORDER :=
ifeq ($(OPENJDK_TARGET_OS), solaris)
ifneq ($(OPENJDK_TARGET_CPU), x86_64)
- BUILD_LIBZIP_REORDER:=$(JDK_TOPDIR)/makefiles/mapfiles/libzip/reorder-$(OPENJDK_TARGET_CPU)
+ BUILD_LIBZIP_REORDER := $(JDK_TOPDIR)/makefiles/mapfiles/libzip/reorder-$(OPENJDK_TARGET_CPU)
endif
endif
ifeq ($(LIBZIP_CAN_USE_MMAP), true)
- BUILD_LIBZIP_MMAP:=-DUSE_MMAP
+ BUILD_LIBZIP_MMAP := -DUSE_MMAP
endif
$(eval $(call SetupNativeCompilation,BUILD_LIBZIP,\
LIBRARY:=zip,\
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
- SRC:=$(JDK_TOPDIR)/src/share/native/java/util/zip \
- $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5,\
- INCLUDE_FILES:=$(BUILD_LIBZIP_FILES), \
LANG:=C,\
OPTIMIZATION:=LOW, \
+ SRC:=$(JDK_TOPDIR)/src/share/native/java/util/zip,\
+ EXCLUDES:=$(LIBZIP_EXCLUDES),\
CFLAGS:=$(CFLAGS_JDKLIB) \
- $(LIBZ_INCLUDE) \
+ $(ZLIB_CPPFLAGS) \
-I$(JDK_TOPDIR)/src/share/native/java/io \
-I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/java/io,\
CFLAGS_posix:=$(BUILD_LIBZIP_MMAP) -UDEBUG,\
@@ -966,7 +945,7 @@
-export:ZIP_ReadEntry -export:ZIP_GetNextEntry jvm.lib \
$(WIN_JAVA_LIB),\
LDFLAGS_SUFFIX_linux:=-ljvm -ljava $(LIBZ),\
- LDFLAGS_SUFFIX_solaris:=-ljvm -ljava $(LIBZ),\
+ LDFLAGS_SUFFIX_solaris:=-ljvm -ljava $(LIBZ) -lc,\
LDFLAGS_SUFFIX_macosx:=$(LIBZ) -ljava -ljvm,\
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
RC_FLAGS:=$(RC_FLAGS)\
@@ -1144,9 +1123,8 @@
LDFLAGS:=$(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN),\
LDFLAGS_SUFFIX_linux:=$(LIBDL),\
- LDFLAGS_SUFFIX_solaris:=$(LIBDL),\
+ LDFLAGS_SUFFIX_solaris:=$(LIBDL) -lc,\
LDFLAGS_SUFFIX_windows:=$(LDFLAGS_JDKLIB_SUFFIX),\
- LDFLAGS_SUFFIX:=,\
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
RC_FLAGS:=$(RC_FLAGS)\
-D "JDK_FNAME=jdwp.dll" \
@@ -1186,7 +1164,7 @@
$(call SET_SHARED_LIBRARY_ORIGIN),\
LDFLAGS_windows:=netapi32.lib user32.lib mpr.lib advapi32.lib,\
LDFLAGS_SUFFIX_windows:=$(LDFLAGS_JDKLIB_SUFFIX),\
- LDFLAGS_SUFFIX:=,\
+ LDFLAGS_SUFFIX_solaris:=-lc,\
EXCLUDE_FILES:=$(LIBJAAS_EXCLUDE_FILES),\
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
RC_FLAGS:=$(RC_FLAGS) \
@@ -1217,7 +1195,7 @@
LDFLAGS_SUFFIX_linux:=$(LIBDL),\
LDFLAGS_SUFFIX_windows:=$(LDFLAGS_JDKLIB_SUFFIX) $(LIBDL),\
LDFLAGS_SUFFIX_macosx:= $(LIBDL),\
- LDFLAGS_SUFFIX:=,\
+ LDFLAGS_SUFFIX_solaris:=-lc,\
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
RC_FLAGS:=$(RC_FLAGS)\
-D "JDK_FNAME=jsdt.dll" \
@@ -1237,15 +1215,7 @@
$(eval $(call SetupNativeCompilation,BUILD_LIBLCMS,\
LIBRARY:=lcms,\
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
- SRC:=$(JDK_TOPDIR)/src/share/native/sun/java2d/cmm/lcms \
- $(JDK_TOPDIR)/src/share/native/sun/java2d/,\
- INCLUDE_FILES:=cmscam02.c cmscgats.c cmscnvrt.c cmserr.c \
- cmsgamma.c cmsgmt.c cmsintrp.c cmsio0.c \
- cmsio1.c cmslut.c cmsmd5.c cmsmtrx.c \
- cmsnamed.c cmsopt.c cmspack.c cmspcs.c \
- cmsplugin.c cmsps2.c cmssamp.c cmssm.c \
- cmstypes.c cmsvirt.c cmswtpnt.c cmsxform.c \
- LCMS.c,\
+ SRC:=$(JDK_TOPDIR)/src/share/native/sun/java2d/cmm/lcms,\
LANG:=C,\
OPTIMIZATION:=LOW, \
CFLAGS:=$(filter-out -xc99=%none,$(CFLAGS_JDKLIB)) \
@@ -1259,7 +1229,7 @@
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_solaris:=/usr/lib$(OPENJDK_TARGET_CPU_ISADIR)/libm.so.2,\
LDFLAGS_windows:=$(WIN_AWT_LIB) $(WIN_JAVA_LIB),\
- LDFLAGS_SUFFIX_solaris:=-lawt -ljava -ljvm,\
+ LDFLAGS_SUFFIX_solaris:=-lawt -ljava -ljvm -lc,\
LDFLAGS_SUFFIX_macosx:=$(LIBM) -lawt -ljava -ljvm,\
LDFLAGS_SUFFIX_linux:=-lm -lawt -ljava -ljvm,\
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
@@ -1626,7 +1596,7 @@
-framework Cocoa -framework Security -framework ApplicationServices,\
LDFLAGS_SUFFIX:=$(LIBINSTRUMENT_LDFLAGS_SUFFIX),\
LDFLAGS_SUFFIX_macosx:=-liconv $(LIBZ),\
- LDFLAGS_SUFFIX_solaris:=$(LIBZ) -L $(INSTALL_LIBRARIES_HERE)/jli -ljli $(LIBDL),\
+ LDFLAGS_SUFFIX_solaris:=$(LIBZ) -L $(INSTALL_LIBRARIES_HERE)/jli -ljli $(LIBDL) -lc,\
LDFLAGS_SUFFIX_linux:=$(LIBZ) -L $(INSTALL_LIBRARIES_HERE)/jli -ljli $(LIBDL),\
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
RC_FLAGS:=$(RC_FLAGS)\
@@ -1716,10 +1686,6 @@
BUILD_LIBHPROF_LDFLAGS:=
-ifeq ($(OPENJDK_TARGET_OS),solaris)
- BUILD_LIBHPROF_LDFLAGS += -lsocket -lnsl -lc
-endif
-
LIBHPROF_OPTIMIZATION:=HIGHEST
ifneq ($(findstring $(OPENJDK_TARGET_OS),solaris linux),)
ifeq ($(ENABLE_DEBUG_SYMBOLS), yes)
@@ -1727,10 +1693,6 @@
endif
endif
-ifneq ($(OPENJDK_TARGET_OS),windows)
- BUILD_LIBHPROF_LDFLAGS += $(LIBDL)
-endif
-
$(eval $(call SetupNativeCompilation,BUILD_LIBHPROF,\
LIBRARY:=hprof, \
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
@@ -1744,7 +1706,9 @@
LDFLAGS:=$(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN),\
LDFLAGS_windows:=wsock32.lib winmm.lib advapi32.lib,\
- LDFLAGS_SUFFIX:=$(BUILD_LIBHPROF_LDFLAGS),\
+ LDFLAGS_SUFFIX_linux:=$(LIBDL),\
+ LDFLAGS_SUFFIX_macosx:=$(LIBDL),\
+ LDFLAGS_SUFFIX_solaris:=-lsocket -lnsl $(LIBDL) -lc,\
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
RC_FLAGS:=$(RC_FLAGS)\
-D "JDK_FNAME=hprof.dll" \
@@ -1768,6 +1732,7 @@
MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libjava_crw_demo/mapfile-vers, \
LDFLAGS:=$(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN),\
+ LDFLAGS_SUFFIX_solaris:=-lc,\
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
RC_FLAGS:=$(RC_FLAGS)\
-D "JDK_FNAME=java_crw_demo.dll" \
@@ -2010,7 +1975,7 @@
##########################################################################################
ifeq ($(OPENJDK_TARGET_OS_API),posix)
- # TODO make this work on macosx
+
ifneq ($(OPENJDK_TARGET_OS),macosx)
SCTP_WERROR := -Werror
@@ -2038,7 +2003,6 @@
LDFLAGS_SUFFIX_posix:=-lnio -lnet,\
LDFLAGS_SUFFIX_solaris:=-lsocket -ljava -ljvm -lc,\
LDFLAGS_SUFFIX_macosx:=-ljava -ljvm,\
- INCLUDE_FILES:=SctpNet.c SctpChannelImpl.c SctpServerChannelImpl.c,\
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libsctp))
BUILD_LIBRARIES += $(BUILD_LIBSCTP)
@@ -2109,7 +2073,7 @@
ifneq ($(USE_EXTERNAL_LIBZ),true)
BUILD_LIBJLI_SRC_DIRS += $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5
- LIBJLI_CFLAGS += $(LIBZ_INCLUDE)
+ LIBJLI_CFLAGS += $(ZLIB_CPPFLAGS)
BUILD_LIBJLI_FILES += \
inflate.c \
inftrees.c \
@@ -2392,7 +2356,7 @@
LANG:=C,\
OPTIMIZATION:=LOW, \
CFLAGS:=$(CFLAGS_JDKLIB) $(LIBAWT_HEADLESS_CFLAGS),\
- MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libawt_headless/mapfile-vers, \
+ MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libawt_headless/mapfile-vers,\
LDFLAGS:=$(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN),\
LDFLAGS_linux:=$(call SET_SHARED_LIBRARY_ORIGIN,/..),\
@@ -2402,8 +2366,8 @@
LDFLAGS_macosx:=$(call SET_SHARED_LIBRARY_ORIGIN).,\
REORDER:=$(LIBAWT_HEADLESS_REORDER), \
LDFLAGS_SUFFIX_linux:=-ljvm -lawt -lm $(LIBDL) -ljava,\
- LDFLAGS_SUFFIX_solaris:=$(LIBDL) -ljvm -lawt -lm -ljava $(LIBCXX), \
- LDFLAGS_SUFFIX_macosx:=-ljvm $(LIBCXX) -lawt $(LIBDL) -ljava, \
+ LDFLAGS_SUFFIX_solaris:=$(LIBDL) -ljvm -lawt -lm -ljava $(LIBCXX) -lc,\
+ LDFLAGS_SUFFIX_macosx:=-ljvm $(LIBCXX) -lawt $(LIBDL) -ljava,\
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libawt_headless))
$(BUILD_LIBAWT_HEADLESS) : $(BUILD_LIBAWT)
@@ -2420,8 +2384,14 @@
$(JDK_TOPDIR)/src/share/native/sun/awt/giflib \
$(JDK_TOPDIR)/src/share/native/sun/awt/image/jpeg \
$(JDK_TOPDIR)/src/share/native/sun/awt/libpng \
- $(JDK_TOPDIR)/src/share/native/sun/awt/splashscreen \
- $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt/splashscreen
+ $(JDK_TOPDIR)/src/share/native/sun/awt/splashscreen
+
+ifneq ($(OPENJDK_TARGET_OS), macosx)
+ LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/awt/splashscreen
+else
+ LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/macosx/native/sun/awt/splashscreen
+endif
+
LIBSPLASHSCREEN_CFLAGS:=-DSPLASHSCREEN -DPNG_NO_MMX_CODE \
$(foreach dir,$(LIBSPLASHSCREEN_DIRS),-I$(dir))
@@ -2447,104 +2417,11 @@
LIBSPLASHSCREEN_CFLAGS += -DWITH_WIN32
endif
-LIBSPLASHSCREEN_FILES:=\
- java_awt_SplashScreen.c \
- splashscreen_gfx_impl.c \
- splashscreen_gif.c \
- splashscreen_impl.c \
- splashscreen_jpeg.c \
- splashscreen_png.c \
- png.c \
- pngerror.c \
- pngget.c \
- pngmem.c \
- pngpread.c \
- pngread.c \
- pngrio.c \
- pngrtran.c \
- pngrutil.c \
- pngset.c \
- pngtrans.c \
- pngwio.c \
- pngwrite.c \
- pngwtran.c \
- pngwutil.c \
- dgif_lib.c \
- gif_err.c \
- gifalloc.c \
- jcomapi.c \
- jdapimin.c \
- jdapistd.c \
- jdcoefct.c \
- jdcolor.c \
- jddctmgr.c \
- jdhuff.c \
- jdinput.c \
- jdmainct.c \
- jdmarker.c \
- jdmaster.c \
- jdmerge.c \
- jdphuff.c \
- jdpostct.c \
- jdsample.c \
- jerror.c \
- jidctflt.c \
- jidctfst.c \
- jidctint.c \
- jidctred.c \
- jmemmgr.c \
- jmemnobs.c \
- jquant1.c \
- jquant2.c \
- jutils.c \
- jcapimin.c \
- jcapistd.c \
- jccoefct.c \
- jccolor.c \
- jcdctmgr.c \
- jchuff.c \
- jcinit.c \
- jcmainct.c \
- jcmarker.c \
- jcmaster.c \
- jcparam.c \
- jcphuff.c \
- jcprepct.c \
- jcsample.c \
- jctrans.c \
- jdtrans.c \
- jfdctflt.c \
- jfdctfst.c \
- jfdctint.c
-
-ifneq ($(OPENJDK_TARGET_OS), macosx)
-LIBSPLASHSCREEN_FILES += splashscreen_sys.c
-else
-LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/macosx/native/sun/awt/splashscreen
-LIBSPLASHSCREEN_FILES += splashscreen_sys.m
-endif
-
LIBSPLASHSCREEN_LDFLAGS_SUFFIX:=
ifneq ($(USE_EXTERNAL_LIBZ),true)
LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/share/native/java/util/zip/zlib-1.2.5
- LIBSPLASHSCREEN_CFLAGS += $(LIBZ_INCLUDE)
- LIBSPLASHSCREEN_FILES += \
- compress.c \
- deflate.c \
- gzclose.c \
- gzlib.c \
- gzread.c \
- gzwrite.c \
- infback.c \
- inffast.c \
- inflate.c \
- inftrees.c \
- trees.c \
- uncompr.c \
- zadler32.c \
- zcrc32.c \
- zutil.c
+ LIBSPLASHSCREEN_CFLAGS += $(ZLIB_CPPFLAGS)
endif
ifeq ($(OPENJDK_TARGET_OS), macosx)
@@ -2564,7 +2441,7 @@
LIBRARY:=splashscreen,\
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
SRC:=$(LIBSPLASHSCREEN_DIRS),\
- INCLUDE_FILES:=$(LIBSPLASHSCREEN_FILES),\
+ EXCLUDE_FILES:=imageioJPEG.c jpegdecoder.c pngtest.c,\
LANG:=C,\
OPTIMIZATION:=LOW, \
CFLAGS:=$(LIBSPLASHSCREEN_CFLAGS) $(CFLAGS_JDKLIB),\
@@ -2572,6 +2449,7 @@
LDFLAGS:=$(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN),\
LDFLAGS_SUFFIX:=$(LIBSPLASHSCREEN_LDFLAGS_SUFFIX) $(LIBZ),\
+ LDFLAGS_SUFFIX_solaris:=-lc,\
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
RC_FLAGS:=$(RC_FLAGS)\
-D "JDK_FNAME=splashscreen.dll" \
@@ -2647,6 +2525,7 @@
$(call SET_SHARED_LIBRARY_ORIGIN),\
LDFLAGS_SUFFIX_posix:=$(LIBDL), \
LDFLAGS_SUFFIX_windows:=winscard.lib,\
+ LDFLAGS_SUFFIX_solaris:=-lc,\
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
RC_FLAGS:=$(RC_FLAGS)\
-D "JDK_FNAME=j2pcsc.dll" \
@@ -2673,7 +2552,8 @@
MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libj2gss/mapfile-vers, \
LDFLAGS:=$(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN),\
- LDFLAGS_SUFFIX:=$(LIBDL), \
+ LDFLAGS_SUFFIX:=$(LIBDL),\
+ LDFLAGS_SUFFIX_solaris:=-lc,\
OBJECT_DIR:=$(JDK_OUTPUTDIR)/objs/libj2gss))
BUILD_LIBRARIES += $(BUILD_LIBJ2GSS)
@@ -2684,14 +2564,13 @@
BUILD_LIBKRB5_NAME:=
ifeq ($(OPENJDK_TARGET_OS), windows)
BUILD_LIBKRB5_NAME:=w2k_lsa_auth
- BUILD_LIBKRB5_FILES:=NativeCreds.c WindowsDirectory.c
BUILD_LIBKRB5_SRC:=$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/security/krb5
BUILD_LIBKRB5_LIBS:=advapi32.lib Secur32.lib netapi32.lib kernel32.lib user32.lib \
gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib \
ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib
else ifeq ($(OPENJDK_TARGET_OS), macosx)
BUILD_LIBKRB5_NAME:=osxkrb5
- BUILD_LIBKRB5_FILES:=nativeccache.c
+ BUILD_LIBKRB5_SRC:=$(JDK_TOPDIR)/src/share/native/sun/security/krb5
BUILD_LIBKRB5_LIBS:=-framework Kerberos
endif
@@ -2699,9 +2578,7 @@
$(eval $(call SetupNativeCompilation,BUILD_LIBKRB5,\
LIBRARY:=$(BUILD_LIBKRB5_NAME),\
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
- SRC:=$(JDK_TOPDIR)/src/share/native/sun/security/krb5 \
- $(BUILD_LIBKRB5_SRC) ,\
- INCLUDE_FILES:=$(BUILD_LIBKRB5_FILES),\
+ SRC:=$(BUILD_LIBKRB5_SRC),\
LANG:=C,\
OPTIMIZATION:=LOW, \
CFLAGS:=$(CFLAGS_JDKLIB) \
@@ -2767,7 +2644,8 @@
MAPFILE:=$(JDK_TOPDIR)/makefiles/mapfiles/libj2pkcs11/mapfile-vers, \
LDFLAGS:=$(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN),\
- LDFLAGS_SUFFIX_posix:=$(LIBDL), \
+ LDFLAGS_SUFFIX_posix:=$(LIBDL),\
+ LDFLAGS_SUFFIX_solaris:=-lc,\
VERSIONINFO_RESOURCE:=$(JDK_TOPDIR)/src/windows/resource/version.rc,\
RC_FLAGS:=$(RC_FLAGS)\
-D "JDK_FNAME=j2pkcs11.dll" \
@@ -3071,18 +2949,11 @@
ifeq ($(OPENJDK_TARGET_OS), macosx)
-LIBAPPLESCRIPTENGINE_FILES:=\
- AppleScriptEngine.m \
- AppleScriptExecutionContext.m \
- AS_NS_ConversionUtils.m \
- NS_Java_ConversionUtils.m
-
$(eval $(call SetupNativeCompilation,BUILD_LIBAPPLESCRIPTENGINE,\
LIBRARY:=AppleScriptEngine,\
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
SRC:=$(JDK_TOPDIR)/src/macosx/native/apple/applescript,\
LANG:=C,\
- INCLUDE_FILES:=$(LIBAPPLESCRIPTENGINE_FILES),\
OPTIMIZATION:=LOW, \
CFLAGS:=$(CFLAGS_JDKLIB) \
-I$(JDK_TOPDIR)/src/macosx/native/apple/applescript \
@@ -3107,18 +2978,11 @@
ifeq ($(OPENJDK_TARGET_OS), macosx)
-LIBOSXAPP_FILES:=\
- NSApplicationAWT.m \
- QueuingApplicationDelegate.m \
- PropertiesUtilities.m \
- ThreadUtilities.m
-
$(eval $(call SetupNativeCompilation,BUILD_LIBOSXAPP,\
LIBRARY:=osxapp,\
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
SRC:=$(JDK_TOPDIR)/src/macosx/native/sun/osxapp,\
LANG:=C,\
- INCLUDE_FILES:=$(LIBOSXAPP_FILES),\
OPTIMIZATION:=LOW, \
CFLAGS:=$(CFLAGS_JDKLIB) \
-I$(JDK_TOPDIR)/src/macosx/native/sun/osxapp \
@@ -3151,14 +3015,6 @@
ifeq ($(OPENJDK_TARGET_OS), macosx)
-LIBOSX_FILES:=\
- Dispatch.m \
- CFileManager.m \
- KeystoreImpl.m \
- JavaAppLauncher.m \
- MacOSXPreferencesFile.m \
- SCDynamicStoreConfig.m
-
LIBOSX_DIRS:=\
$(JDK_TOPDIR)/src/macosx/native/com/apple/concurrent \
$(JDK_TOPDIR)/src/macosx/native/java/util \
@@ -3171,7 +3027,6 @@
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
SRC:=$(LIBOSX_DIRS),\
LANG:=C,\
- INCLUDE_FILES:=$(LIBOSX_FILES),\
OPTIMIZATION:=LOW, \
CFLAGS:=$(CFLAGS_JDKLIB) \
$(foreach dir,$(LIBOSX_DIRS),-I$(dir)) \
@@ -3341,22 +3196,11 @@
ifeq ($(OPENJDK_TARGET_OS), macosx)
-LIBOSXUI_FILES:=\
- AquaFileView.m \
- AquaLookAndFeel.m \
- AquaNativeResources.m \
- JRSUIConstantSync.m \
- JRSUIController.m \
- JRSUIFocus.m \
- ScreenPopupFactory.m \
- ScreenMenu.m
-
$(eval $(call SetupNativeCompilation,BUILD_LIBOSXUI,\
LIBRARY:=osxui,\
OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\
SRC:=$(JDK_TOPDIR)/src/macosx/native/com/apple/laf,\
LANG:=C,\
- INCLUDE_FILES:=$(LIBOSXUI_FILES),\
OPTIMIZATION:=LOW, \
CFLAGS:=$(CFLAGS_JDKLIB) \
-I$(JDK_TOPDIR)/src/macosx/native/com/apple/laf \
--- a/jdk/makefiles/CreateJars.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/makefiles/CreateJars.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -271,7 +271,7 @@
ifeq ($(OPENJDK_TARGET_OS), macosx)
RT_JAR_EXCLUDES += com/sun/nio/sctp \
- sun/nio/ch/sctp \
+ sun/nio/ch/sctp
endif
# Find all files in the classes dir to use as dependencies. This could be more fine granular.
@@ -420,6 +420,23 @@
JARS+=$(IMAGES_OUTPUTDIR)/lib/jsse.jar
##########################################################################################
+# Create manifest for security jars
+
+#
+# Include these extra attributes for now, should probably take out.
+#
+JCE_MANIFEST := $(IMAGES_OUTPUTDIR)/lib/_the.security.manifest.mf
+$(JCE_MANIFEST): $(MAINMANIFEST)
+ $(MKDIR) -p $(@D)
+ $(RM) $@ $@.tmp
+ $(SED) -e "s#@@RELEASE@@#$(JDK_VERSION)#" \
+ -e "s#@@COMPANY_NAME@@#$(COMPANY_NAME)#" \
+ $(MAINMANIFEST) >> $@.tmp
+ $(ECHO) "Extension-Name: javax.crypto" >> $@.tmp
+ $(ECHO) "Implementation-Vendor-Id: com.sun" >> $@.tmp
+ $(MV) $@.tmp $@
+
+##########################################################################################
SUNPKCS11_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/ext/sunpkcs11.jar
@@ -440,8 +457,11 @@
SUFFIXES:=.class,\
INCLUDES:=sun/security/pkcs11,\
JAR:=$(SUNPKCS11_JAR_DST), \
+ MANIFEST:=$(JCE_MANIFEST), \
SKIP_METAINF := true))
+ $(SUNPKCS11_JAR_DST): $(JCE_MANIFEST)
+
endif
JARS += $(SUNPKCS11_JAR_DST)
@@ -452,9 +472,9 @@
ifndef OPENJDK
-SUNEC_JAR_SRC := $(JDK_TOPDIR)/make/closed/tools/crypto/ec/sunec.jar
+ SUNEC_JAR_SRC := $(JDK_TOPDIR)/make/closed/tools/crypto/ec/sunec.jar
-$(SUNEC_JAR_DST) : $(SUNEC_JAR_SRC)
+ $(SUNEC_JAR_DST) : $(SUNEC_JAR_SRC)
@$(ECHO) $(LOG_INFO) "\n>>>Installing prebuilt SunEC provider..."
$(MKDIR) -p $(@D)
$(RM) $@
@@ -462,13 +482,16 @@
else
-$(eval $(call SetupArchive,BUILD_SUNEC_JAR,,\
+ $(eval $(call SetupArchive,BUILD_SUNEC_JAR,,\
SRCS:=$(JDK_OUTPUTDIR)/classes, \
SUFFIXES:=.class,\
INCLUDES:=sun/security/ec,\
JAR:=$(SUNEC_JAR_DST), \
+ MANIFEST:=$(JCE_MANIFEST), \
SKIP_METAINF := true))
+ $(SUNEC_JAR_DST): $(JCE_MANIFEST)
+
endif
JARS += $(SUNEC_JAR_DST)
@@ -505,9 +528,11 @@
SUFFIXES:=.class,\
INCLUDES:= com/sun/crypto/provider,\
JAR:=$(SUNJCE_PROVIDER_JAR_DST), \
- MANIFEST := $(JDK_TOPDIR)/make/tools/manifest.mf, \
- EXTRA_MANIFEST_ATTR := Extension-Name: javax.crypto\nImplementation-Vendor-Id: com.sun, \
+ MANIFEST:=$(JCE_MANIFEST), \
SKIP_METAINF := true))
+
+ $(SUNJCE_PROVIDER_JAR_DST): $(JCE_MANIFEST)
+
endif
JARS += $(SUNJCE_PROVIDER_JAR_DST)
@@ -516,9 +541,9 @@
ifndef OPENJDK
-JCE_JAR_SRC := $(JDK_TOPDIR)/make/closed/tools/crypto/jce/jce.jar
+ JCE_JAR_SRC := $(JDK_TOPDIR)/make/closed/tools/crypto/jce/jce.jar
-$(JCE_JAR_DST) : $(JCE_JAR_SRC)
+ $(JCE_JAR_DST) : $(JCE_JAR_SRC)
@$(ECHO) $(LOG_INFO) "\n>>>Installing prebuilt jce.jar..."
$(MKDIR) -p $(@D)
$(RM) $@
@@ -526,14 +551,16 @@
else
-$(eval $(call SetupArchive,BUILD_JCE_JAR,,\
+ $(eval $(call SetupArchive,BUILD_JCE_JAR,,\
SRCS:=$(JDK_OUTPUTDIR)/classes, \
SUFFIXES:=.class,\
INCLUDES:= javax/crypto sun/security/internal,\
JAR:=$(JCE_JAR_DST), \
- MANIFEST := $(JDK_TOPDIR)/make/tools/manifest.mf, \
- EXTRA_MANIFEST_ATTR := Extension-Name: javax.crypto\nImplementation-Vendor-Id: com.sun, \
+ MANIFEST:=$(JCE_MANIFEST), \
SKIP_METAINF := true))
+
+ $(JCE_JAR_DST): $(JCE_MANIFEST)
+
endif
JARS += $(JCE_JAR_DST)
--- a/jdk/makefiles/GensrcIcons.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/makefiles/GensrcIcons.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -109,13 +109,17 @@
ifeq ($(OPENJDK_TARGET_OS),macosx)
- GENSRC_OSX_ICONS = $(GENSRC_OSX_ICONS_DST)/AWTIconData.h
- GENSRC_OSX_ICONS_SRC =
- GENSRC_OSX_ICONS_TMP = $(JDK_OUTPUTDIR)/gensrc
- GENSRC_OSX_ICONS_DST = $(GENSRC_OSX_ICONS_TMP)/sun/osxapp
-
-$(GENSRC_OSX_ICONS_DST)/AWTIconData.h: \
- $(JDK_TOPDIR)/src/macosx/native/sun/osxapp/resource/icons/JavaApp.icns
+ GENSRC_OSX_ICONS_TMP := $(JDK_OUTPUTDIR)/gensrc
+ GENSRC_OSX_ICONS_DST := $(GENSRC_OSX_ICONS_TMP)/sun/osxapp
+ GENSRC_OSX_ICONS := $(GENSRC_OSX_ICONS_DST)/AWTIconData.h
+
+ ifdef OPENJDK
+ GENSRC_OSX_ICONS_SRC := $(JDK_TOPDIR)/src/macosx/native/sun/osxapp/resource/icons/JavaApp.icns
+ else
+ GENSRC_OSX_ICONS_SRC := $(JDK_TOPDIR)/src/closed/macosx/native/sun/osxapp/resource/icons/JavaApp.icns
+ endif
+
+$(GENSRC_OSX_ICONS_DST)/AWTIconData.h: $(GENSRC_OSX_ICONS_SRC)
$(RM) $@ $@.tmp
$(MKDIR) -p $(dir $@)
$(ECHO) "static unsigned char sAWTIconData[] = { " >> $@.tmp
--- a/jdk/makefiles/GensrcLocaleDataMetaInfo.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/makefiles/GensrcLocaleDataMetaInfo.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -68,8 +68,9 @@
ALL_US_LOCALES += $$($1_US_LOCALES)
ALL_NON_US_LOCALES += $$($1_NON_US_LOCALES)
- SED_ARGS+= -e 's/$$(HASH)$1_USLocales$$(HASH)/ $$($1_US_LOCALES)/g'
- SED_ARGS+= -e 's/$$(HASH)$1_NonUSLocales$$(HASH)/ $$($1_NON_US_LOCALES)/g'
+ # Don't sed in a space if there are no locales.
+ SED_ARGS+= -e 's/$$(HASH)$1_USLocales$$(HASH)/$$(if $$($1_US_LOCALES),$$(SPACE)$$($1_US_LOCALES),)/g'
+ SED_ARGS+= -e 's/$$(HASH)$1_NonUSLocales$$(HASH)/$$(if $$($1_NON_US_LOCALES),$$(SPACE)$$($1_NON_US_LOCALES),)/g'
endef
#sun.text.resources.FormatData
--- a/jdk/makefiles/Import.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/makefiles/Import.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -121,7 +121,7 @@
endif
define CopyDir
- $1_SRC_FILES := $(shell $(FIND) $2 -type f -a ! -name "wb.jar")
+ $1_SRC_FILES := $(shell $(FIND) $2 -type f -a \( -name DUMMY $(addprefix -o$(SPACE)-name$(SPACE),$4) \))
$1_DST_FILES := $$(patsubst $2/%,$3/%,$$($1_SRC_FILES))
IMPORT_TARGET_FILES += $$($1_DST_FILES)
$3/% : $2/%
@@ -134,9 +134,10 @@
#
# Import hotspot
#
-
-$(eval $(call CopyDir,HOTSPOT0, $(HOTSPOT_LIB_DIR), $(INSTALL_LIBRARIES_HERE)))
-$(eval $(call CopyDir,HOTSPOT1, $(HOTSPOT_DIST)/lib, $(JDK_OUTPUTDIR)/lib))
+HOTSPOT_IMPORT_FILES:=$(addprefix $(LIBRARY_PREFIX), jvm.* saproc.* jsig.* sawindbg.* jvm_db.* jvm_dtrace.*) \
+ Xusage.txt sa-jdi.jar
+$(eval $(call CopyDir,HOTSPOT0, $(HOTSPOT_LIB_DIR), $(INSTALL_LIBRARIES_HERE), $(HOTSPOT_IMPORT_FILES)))
+$(eval $(call CopyDir,HOTSPOT1, $(HOTSPOT_DIST)/lib, $(JDK_OUTPUTDIR)/lib, $(HOTSPOT_IMPORT_FILES)))
JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.debuginfo) \
$(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
--- a/jdk/src/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -41,6 +41,7 @@
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.spi.CalendarDataProvider;
+import java.util.spi.CalendarNameProvider;
import java.util.spi.CurrencyNameProvider;
import java.util.spi.LocaleNameProvider;
import java.util.spi.TimeZoneNameProvider;
@@ -324,6 +325,30 @@
}
@Override
+ public int getFirstDayOfWeek(Locale locale) {
+ return getCalendarInt(locale.toLanguageTag(), CD_FIRSTDAYOFWEEK);
+ }
+
+ @Override
+ public int getMinimalDaysInFirstWeek(Locale locale) {
+ return getCalendarInt(locale.toLanguageTag(), CD_MINIMALDAYSINFIRSTWEEK);
+ }
+ };
+ }
+
+ public static CalendarNameProvider getCalendarNameProvider() {
+ return new CalendarNameProvider() {
+ @Override
+ public Locale[] getAvailableLocales() {
+ return getSupportedCalendarLocales();
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ return isSupportedCalendarLocale(locale);
+ }
+
+ @Override
public String getDisplayName(String calType, int field, int value,
int style, Locale locale) {
return null;
@@ -334,16 +359,6 @@
int field, int style, Locale locale) {
return null;
}
-
- @Override
- public int getFirstDayOfWeek(Locale locale) {
- return getCalendarInt(locale.toLanguageTag(), CD_FIRSTDAYOFWEEK);
- }
-
- @Override
- public int getMinimalDaysInFirstWeek(Locale locale) {
- return getCalendarInt(locale.toLanguageTag(), CD_MINIMALDAYSINFIRSTWEEK);
- }
};
}
--- a/jdk/src/share/bin/java.c Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/bin/java.c Fri Nov 30 17:09:05 2012 -0800
@@ -105,6 +105,7 @@
InvocationFunctions *ifn);
static jstring NewPlatformString(JNIEnv *env, char *s);
static jclass LoadMainClass(JNIEnv *env, int mode, char *name);
+static jclass GetApplicationClass(JNIEnv *env);
static void TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***pargv);
static jboolean AddApplicationOptions(int cpathc, const char **cpathv);
@@ -346,6 +347,7 @@
JavaVM *vm = 0;
JNIEnv *env = 0;
jclass mainClass = NULL;
+ jclass appClass = NULL; // actual application class being launched
jmethodID mainID;
jobjectArray mainArgs;
int ret = 0;
@@ -419,10 +421,28 @@
* all environments,
* 2) Remove the vestages of maintaining main_class through
* the environment (and remove these comments).
+ *
+ * This method also correctly handles launching existing JavaFX
+ * applications that may or may not have a Main-Class manifest entry.
*/
mainClass = LoadMainClass(env, mode, what);
CHECK_EXCEPTION_NULL_LEAVE(mainClass);
- PostJVMInit(env, mainClass, vm);
+ /*
+ * In some cases when launching an application that needs a helper, e.g., a
+ * JavaFX application with no main method, the mainClass will not be the
+ * applications own main class but rather a helper class. To keep things
+ * consistent in the UI we need to track and report the application main class.
+ */
+ appClass = GetApplicationClass(env);
+ NULL_CHECK(appClass);
+ /*
+ * PostJVMInit uses the class name as the application name for GUI purposes,
+ * for example, on OSX this sets the application name in the menu bar for
+ * both SWT and JavaFX. So we'll pass the actual application class here
+ * instead of mainClass as that may be a launcher or helper class instead
+ * of the application class.
+ */
+ PostJVMInit(env, appClass, vm);
/*
* The LoadMainClass not only loads the main class, it will also ensure
* that the main method's signature is correct, therefore further checking
@@ -1215,6 +1235,20 @@
return (jclass)result;
}
+static jclass
+GetApplicationClass(JNIEnv *env)
+{
+ jmethodID mid;
+ jobject result;
+ jclass cls = GetLauncherHelperClass(env);
+ NULL_CHECK0(cls);
+ NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,
+ "getApplicationClass",
+ "()Ljava/lang/Class;"));
+
+ return (*env)->CallStaticObjectMethod(env, cls, mid);
+}
+
/*
* For tools, convert command line args thus:
* javac -cp foo:foo/"*" -J-ms32m ...
--- a/jdk/src/share/bin/wildcard.c Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/bin/wildcard.c Fri Nov 30 17:09:05 2012 -0800
@@ -356,8 +356,13 @@
const char *basename;
FileList fl = FileList_new(16);
WildcardIterator it = WildcardIterator_for(wildcard);
+
if (it == NULL)
+ {
+ FileList_free(fl);
return NULL;
+ }
+
while ((basename = WildcardIterator_next(it)) != NULL)
if (isJarFileName(basename))
FileList_add(fl, wildcardConcat(wildcard, basename));
--- a/jdk/src/share/classes/com/sun/naming/internal/ResourceManager.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/com/sun/naming/internal/ResourceManager.java Fri Nov 30 17:09:05 2012 -0800
@@ -560,8 +560,7 @@
}
} finally {
while (resources.hasMore()) {
- InputStream istream = (InputStream)resources.next();
- istream.close();
+ resources.next().close();
}
}
--- a/jdk/src/share/classes/java/lang/Boolean.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/java/lang/Boolean.java Fri Nov 30 17:09:05 2012 -0800
@@ -196,11 +196,24 @@
* {@code true}; returns the integer {@code 1237} if this
* object represents {@code false}.
*/
+ @Override
public int hashCode() {
+ return Boolean.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code boolean} value; compatible with
+ * {@code Boolean.hashCode()}.
+ *
+ * @since 1.8
+ *
+ * @return a hash code value for a {@code boolean} value.
+ */
+ public static int hashCode(boolean value) {
return value ? 1231 : 1237;
}
- /**
+ /**
* Returns {@code true} if and only if the argument is not
* {@code null} and is a {@code Boolean} object that
* represents the same {@code boolean} value as this object.
--- a/jdk/src/share/classes/java/lang/Byte.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/java/lang/Byte.java Fri Nov 30 17:09:05 2012 -0800
@@ -389,7 +389,20 @@
*
* @return a hash code value for this {@code Byte}
*/
+ @Override
public int hashCode() {
+ return Byte.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code byte} value; compatible with
+ * {@code Byte.hashCode()}.
+ *
+ * @since 1.8
+ *
+ * @return a hash code value for a {@code byte} value.
+ */
+ public static int hashCode(byte value) {
return (int)value;
}
@@ -494,6 +507,14 @@
*/
public static final int SIZE = 8;
+ /**
+ * The number of bytes used to represent a {@code byte} value in two's
+ * complement binary form.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
/** use serialVersionUID from JDK 1.1. for interoperability */
private static final long serialVersionUID = -7183698231559129828L;
}
--- a/jdk/src/share/classes/java/lang/Character.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/java/lang/Character.java Fri Nov 30 17:09:05 2012 -0800
@@ -4588,7 +4588,20 @@
*
* @return a hash code value for this {@code Character}
*/
+ @Override
public int hashCode() {
+ return Character.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code char} value; compatible with
+ * {@code Character.hashCode()}.
+ *
+ * @since 1.8
+ *
+ * @return a hash code value for a {@code char} value.
+ */
+ public static int hashCode(char value) {
return (int)value;
}
@@ -7158,6 +7171,14 @@
public static final int SIZE = 16;
/**
+ * The number of bytes used to represent a {@code char} value in unsigned
+ * binary form.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
+ /**
* Returns the value obtained by reversing the order of the bytes in the
* specified <tt>char</tt> value.
*
--- a/jdk/src/share/classes/java/lang/Double.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/java/lang/Double.java Fri Nov 30 17:09:05 2012 -0800
@@ -123,6 +123,13 @@
public static final int SIZE = 64;
/**
+ * The number of bytes used to represent a {@code double} value.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
+ /**
* The {@code Class} instance representing the primitive type
* {@code double}.
*
@@ -740,7 +747,20 @@
*
* @return a {@code hash code} value for this object.
*/
+ @Override
public int hashCode() {
+ return Double.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code double} value; compatible with
+ * {@code Double.hashCode()}.
+ *
+ * @since 1.8
+ *
+ * @return a hash code value for a {@code double} value.
+ */
+ public static int hashCode(double value) {
long bits = doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));
}
--- a/jdk/src/share/classes/java/lang/Float.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/java/lang/Float.java Fri Nov 30 17:09:05 2012 -0800
@@ -121,6 +121,13 @@
public static final int SIZE = 32;
/**
+ * The number of bytes used to represent a {@code float} value.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
+ /**
* The {@code Class} instance representing the primitive type
* {@code float}.
*
@@ -648,7 +655,20 @@
*
* @return a hash code value for this object.
*/
+ @Override
public int hashCode() {
+ return Float.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code float} value; compatible with
+ * {@code Float.hashCode()}.
+ *
+ * @since 1.8
+ *
+ * @return a hash code value for a {@code float} value.
+ */
+ public static int hashCode(float value) {
return floatToIntBits(value);
}
--- a/jdk/src/share/classes/java/lang/Integer.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/java/lang/Integer.java Fri Nov 30 17:09:05 2012 -0800
@@ -918,7 +918,20 @@
* primitive {@code int} value represented by this
* {@code Integer} object.
*/
+ @Override
public int hashCode() {
+ return Integer.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code int} value; compatible with
+ * {@code Integer.hashCode()}.
+ *
+ * @since 1.8
+ *
+ * @return a hash code value for a {@code int} value.
+ */
+ public static int hashCode(int value) {
return value;
}
@@ -1285,6 +1298,14 @@
public static final int SIZE = 32;
/**
+ * The number of bytes used to represent a {@code int} value in two's
+ * complement binary form.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
+ /**
* Returns an {@code int} value with at most a single one-bit, in the
* position of the highest-order ("leftmost") one-bit in the specified
* {@code int} value. Returns zero if the specified value has no
--- a/jdk/src/share/classes/java/lang/Long.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/java/lang/Long.java Fri Nov 30 17:09:05 2012 -0800
@@ -1021,7 +1021,20 @@
*
* @return a hash code value for this object.
*/
+ @Override
public int hashCode() {
+ return Long.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code long} value; compatible with
+ * {@code Long.hashCode()}.
+ *
+ * @since 1.8
+ *
+ * @return a hash code value for a {@code long} value.
+ */
+ public static int hashCode(long value) {
return (int)(value ^ (value >>> 32));
}
@@ -1307,6 +1320,14 @@
public static final int SIZE = 64;
/**
+ * The number of bytes used to represent a {@code long} value in two's
+ * complement binary form.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
+ /**
* Returns a {@code long} value with at most a single one-bit, in the
* position of the highest-order ("leftmost") one-bit in the specified
* {@code long} value. Returns zero if the specified value has no
--- a/jdk/src/share/classes/java/lang/Short.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/java/lang/Short.java Fri Nov 30 17:09:05 2012 -0800
@@ -394,7 +394,20 @@
*
* @return a hash code value for this {@code Short}
*/
+ @Override
public int hashCode() {
+ return Short.hashCode(value);
+ }
+
+ /**
+ * Returns a hash code for a {@code short} value; compatible with
+ * {@code Short.hashCode()}.
+ *
+ * @since 1.8
+ *
+ * @return a hash code value for a {@code short} value.
+ */
+ public static int hashCode(short value) {
return (int)value;
}
@@ -458,6 +471,14 @@
public static final int SIZE = 16;
/**
+ * The number of bytes used to represent a {@code short} value in two's
+ * complement binary form.
+ *
+ * @since 1.8
+ */
+ public static final int BYTES = SIZE / Byte.SIZE;
+
+ /**
* Returns the value obtained by reversing the order of the bytes in the
* two's complement representation of the specified {@code short} value.
*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/annotation/Native.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.annotation;
+
+
+/**
+ * Indicates that a field defining a constant value may be referenced
+ * from native code.
+ *
+ * The annotation may be used as a hint by tools that generate native
+ * header files to determine whether a header file is required, and
+ * if so, what declarations it should contain.
+ *
+ * @since 1.8
+ */
+@Documented
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.SOURCE)
+public @interface Native {
+}
--- a/jdk/src/share/classes/java/util/Calendar.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/java/util/Calendar.java Fri Nov 30 17:09:05 2012 -0800
@@ -2699,12 +2699,9 @@
/* try to get the Locale data from the cache */
int[] data = cachedLocaleData.get(desiredLocale);
if (data == null) { /* cache miss */
- LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(CalendarDataProvider.class, desiredLocale);
- CalendarDataProvider provider = adapter.getCalendarDataProvider();
data = new int[2];
- data[0] = provider.getFirstDayOfWeek(desiredLocale);
- data[1] = provider.getMinimalDaysInFirstWeek(desiredLocale);
- assert data[0] != 0 && data[1] != 0;
+ data[0] = CalendarDataUtility.retrieveFirstDayOfWeek(desiredLocale);
+ data[1] = CalendarDataUtility.retrieveMinimalDaysInFirstWeek(desiredLocale);
cachedLocaleData.putIfAbsent(desiredLocale, data);
}
firstDayOfWeek = data[0];
--- a/jdk/src/share/classes/java/util/logging/FileHandler.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/java/util/logging/FileHandler.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,10 +25,19 @@
package java.util.logging;
-import java.io.*;
+import static java.nio.file.StandardOpenOption.CREATE_NEW;
+import static java.nio.file.StandardOpenOption.WRITE;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.security.*;
+import java.nio.file.FileAlreadyExistsException;
+import java.nio.file.Paths;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
/**
* Simple file logging <tt>Handler</tt>.
@@ -137,14 +146,16 @@
private int count;
private String pattern;
private String lockFileName;
- private FileOutputStream lockStream;
+ private FileChannel lockFileChannel;
private File files[];
private static final int MAX_LOCKS = 100;
private static java.util.HashMap<String, String> locks = new java.util.HashMap<>();
- // A metered stream is a subclass of OutputStream that
- // (a) forwards all its output to a target stream
- // (b) keeps track of how many bytes have been written
+ /**
+ * A metered stream is a subclass of OutputStream that
+ * (a) forwards all its output to a target stream
+ * (b) keeps track of how many bytes have been written
+ */
private class MeteredStream extends OutputStream {
OutputStream out;
int written;
@@ -189,9 +200,10 @@
setOutputStream(meter);
}
- // Private method to configure a FileHandler from LogManager
- // properties and/or default values as specified in the class
- // javadoc.
+ /**
+ * Configure a FileHandler from LogManager properties and/or default values
+ * as specified in the class javadoc.
+ */
private void configure() {
LogManager manager = LogManager.getLogManager();
@@ -287,7 +299,8 @@
* the caller does not have <tt>LoggingPermission("control")</tt>.
* @exception IllegalArgumentException if pattern is an empty string
*/
- public FileHandler(String pattern, boolean append) throws IOException, SecurityException {
+ public FileHandler(String pattern, boolean append) throws IOException,
+ SecurityException {
if (pattern.length() < 1 ) {
throw new IllegalArgumentException();
}
@@ -376,8 +389,10 @@
openFiles();
}
- // Private method to open the set of output files, based on the
- // configured instance variables.
+ /**
+ * Open the set of output files, based on the configured
+ * instance variables.
+ */
private void openFiles() throws IOException {
LogManager manager = LogManager.getLogManager();
manager.checkPermission();
@@ -413,18 +428,18 @@
// object. Try again.
continue;
}
- FileChannel fc;
+
try {
- lockStream = new FileOutputStream(lockFileName);
- fc = lockStream.getChannel();
- } catch (IOException ix) {
- // We got an IOException while trying to open the file.
- // Try the next file.
+ lockFileChannel = FileChannel.open(Paths.get(lockFileName),
+ CREATE_NEW, WRITE);
+ } catch (FileAlreadyExistsException ix) {
+ // try the next lock file name in the sequence
continue;
}
+
boolean available;
try {
- available = fc.tryLock() != null;
+ available = lockFileChannel.tryLock() != null;
// We got the lock OK.
} catch (IOException ix) {
// We got an IOException while trying to get the lock.
@@ -440,7 +455,7 @@
}
// We failed to get the lock. Try next file.
- fc.close();
+ lockFileChannel.close();
}
}
@@ -472,8 +487,17 @@
setErrorManager(new ErrorManager());
}
- // Generate a filename from a pattern.
- private File generate(String pattern, int generation, int unique) throws IOException {
+ /**
+ * Generate a file based on a user-supplied pattern, generation number,
+ * and an integer uniqueness suffix
+ * @param pattern the pattern for naming the output file
+ * @param generation the generation number to distinguish rotated logs
+ * @param unique a unique number to resolve conflicts
+ * @return the generated File
+ * @throws IOException
+ */
+ private File generate(String pattern, int generation, int unique)
+ throws IOException {
File file = null;
String word = "";
int ix = 0;
@@ -548,7 +572,9 @@
return file;
}
- // Rotate the set of output files
+ /**
+ * Rotate the set of output files
+ */
private synchronized void rotate() {
Level oldLevel = getLevel();
setLevel(Level.OFF);
@@ -615,9 +641,8 @@
return;
}
try {
- // Closing the lock file's FileOutputStream will close
- // the underlying channel and free any locks.
- lockStream.close();
+ // Close the lock file channel (which also will free any locks)
+ lockFileChannel.close();
} catch (Exception ex) {
// Problems closing the stream. Punt.
}
@@ -626,7 +651,7 @@
}
new File(lockFileName).delete();
lockFileName = null;
- lockStream = null;
+ lockFileChannel = null;
}
private static class InitializationErrorManager extends ErrorManager {
@@ -636,6 +661,8 @@
}
}
- // Private native method to check if we are in a set UID program.
+ /**
+ * check if we are in a set UID program.
+ */
private static native boolean isSetUID();
}
--- a/jdk/src/share/classes/java/util/spi/CalendarDataProvider.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/java/util/spi/CalendarDataProvider.java Fri Nov 30 17:09:05 2012 -0800
@@ -26,125 +26,15 @@
package java.util.spi;
import java.util.Calendar;
-import java.util.Map;
import java.util.Locale;
/**
- * An abstract class for service providers that provide localized {@link
- * Calendar} parameters and string representations (display names) of {@code
- * Calendar} field values.
- *
- * <p><a name="calendartypes"><b>Calendar Types</b></a>
- *
- * <p>Calendar types are used to specify calendar systems for which the {@link
- * #getDisplayName(String, int, int, int, Locale) getDisplayName} and {@link
- * #getDisplayNames(String, int, int, Locale) getDisplayNames} methods provide
- * calendar field value names. See {@link Calendar#getCalendarType()} for details.
- *
- * <p><b>Calendar Fields</b>
- *
- * <p>Calendar fields are specified with the constants defined in {@link
- * Calendar}. The following are calendar-common fields and their values to be
- * supported for each calendar system.
- *
- * <table style="border-bottom:1px solid" border="1" cellpadding="3" cellspacing="0" summary="Field values">
- * <tr>
- * <th>Field</th>
- * <th>Value</th>
- * <th>Description</th>
- * </tr>
- * <tr>
- * <td valign="top">{@link Calendar#MONTH}</td>
- * <td valign="top">{@link Calendar#JANUARY} to {@link Calendar#UNDECIMBER}</td>
- * <td>Month numbering is 0-based (e.g., 0 - January, ..., 11 -
- * December). Some calendar systems have 13 months. Month
- * names need to be supported in both the formatting and
- * stand-alone forms if required by the supported locales. If there's
- * no distinction in the two forms, the same names should be returned
- * in both of the forms.</td>
- * </tr>
- * <tr>
- * <td valign="top">{@link Calendar#DAY_OF_WEEK}</td>
- * <td valign="top">{@link Calendar#SUNDAY} to {@link Calendar#SATURDAY}</td>
- * <td>Day-of-week numbering is 1-based starting from Sunday (i.e., 1 - Sunday,
- * ..., 7 - Saturday).</td>
- * </tr>
- * <tr>
- * <td valign="top">{@link Calendar#AM_PM}</td>
- * <td valign="top">{@link Calendar#AM} to {@link Calendar#PM}</td>
- * <td>0 - AM, 1 - PM</td>
- * </tr>
- * </table>
- *
- * <p style="margin-top:20px">The following are calendar-specific fields and their values to be supported.
- *
- * <table style="border-bottom:1px solid" border="1" cellpadding="3" cellspacing="0" summary="Calendar type and field values">
- * <tr>
- * <th>Calendar Type</th>
- * <th>Field</th>
- * <th>Value</th>
- * <th>Description</th>
- * </tr>
- * <tr>
- * <td rowspan="2" valign="top">{@code "gregory"}</td>
- * <td rowspan="2" valign="top">{@link Calendar#ERA}</td>
- * <td>0</td>
- * <td>{@link java.util.GregorianCalendar#BC} (BCE)</td>
- * </tr>
- * <tr>
- * <td>1</td>
- * <td>{@link java.util.GregorianCalendar#AD} (CE)</td>
- * </tr>
- * <tr>
- * <td rowspan="2" valign="top">{@code "buddhist"}</td>
- * <td rowspan="2" valign="top">{@link Calendar#ERA}</td>
- * <td>0</td>
- * <td>BC (BCE)</td>
- * </tr>
- * <tr>
- * <td>1</td>
- * <td>B.E. (Buddhist Era)</td>
- * </tr>
- * <tr>
- * <td rowspan="6" valign="top">{@code "japanese"}</td>
- * <td rowspan="5" valign="top">{@link Calendar#ERA}</td>
- * <td>0</td>
- * <td>Seireki (Before Meiji)</td>
- * </tr>
- * <tr>
- * <td>1</td>
- * <td>Meiji</td>
- * </tr>
- * <tr>
- * <td>2</td>
- * <td>Taisho</td>
- * </tr>
- * <tr>
- * <td>3</td>
- * <td>Showa</td>
- * </tr>
- * <tr>
- * <td>4</td>
- * <td >Heisei</td>
- * </tr>
- * <tr>
- * <td>{@link Calendar#YEAR}</td>
- * <td>1</td>
- * <td>the first year in each era. It should be returned when a long
- * style ({@link Calendar#LONG_FORMAT} or {@link Calendar#LONG_STANDALONE}) is
- * specified. See also the <a href="../../text/SimpleDateFormat.html#year">
- * Year representation in {@code SimpleDateFormat}</a>.</td>
- * </tr>
- * </table>
- *
- * <p>Calendar field value names for {@code "gregory"} must be consistent with
- * the date-time symbols provided by {@link java.text.spi.DateFormatSymbolsProvider}.
- *
- * <p>Time zone names are supported by {@link TimeZoneNameProvider}.
+ * An abstract class for service providers that provide locale-dependent {@link
+ * Calendar} parameters.
*
* @author Masayoshi Okutsu
* @since 1.8
- * @see Locale#getUnicodeLocaleType(String)
+ * @see CalendarNameProvider
*/
public abstract class CalendarDataProvider extends LocaleServiceProvider {
@@ -188,112 +78,4 @@
* @see java.util.Calendar#getMinimalDaysInFirstWeek()
*/
public abstract int getMinimalDaysInFirstWeek(Locale locale);
-
- /**
- * Returns the string representation (display name) of the calendar
- * <code>field value</code> in the given <code>style</code> and
- * <code>locale</code>. If no string representation is
- * applicable, <code>null</code> is returned.
- *
- * <p>{@code field} is a {@code Calendar} field index, such as {@link
- * Calendar#MONTH}. The time zone fields, {@link Calendar#ZONE_OFFSET} and
- * {@link Calendar#DST_OFFSET}, are <em>not</em> supported by this
- * method. {@code null} must be returned if any time zone fields are
- * specified.
- *
- * <p>{@code value} is the numeric representation of the {@code field} value.
- * For example, if {@code field} is {@link Calendar#DAY_OF_WEEK}, the valid
- * values are {@link Calendar#SUNDAY} to {@link Calendar#SATURDAY}
- * (inclusive).
- *
- * <p>{@code style} gives the style of the string representation. It is one
- * of {@link Calendar#SHORT_FORMAT} ({@link Calendar#SHORT SHORT}),
- * {@link Calendar#SHORT_STANDALONE}, {@link Calendar#LONG_FORMAT}
- * ({@link Calendar#LONG LONG}), or {@link Calendar#LONG_STANDALONE}.
- *
- * <p>For example, the following call will return {@code "Sunday"}.
- * <pre>
- * getDisplayName("gregory", Calendar.DAY_OF_WEEK, Calendar.SUNDAY,
- * Calendar.LONG_STANDALONE, Locale.ENGLISH);
- * </pre>
- *
- * @param calendarType
- * the calendar type. (Any calendar type given by {@code locale}
- * is ignored.)
- * @param field
- * the {@code Calendar} field index,
- * such as {@link Calendar#DAY_OF_WEEK}
- * @param value
- * the value of the {@code Calendar field},
- * such as {@link Calendar#MONDAY}
- * @param style
- * the string representation style: one of {@link
- * Calendar#SHORT_FORMAT} ({@link Calendar#SHORT SHORT}),
- * {@link Calendar#SHORT_STANDALONE}, {@link
- * Calendar#LONG_FORMAT} ({@link Calendar#LONG LONG}), or
- * {@link Calendar#LONG_STANDALONE}
- * @param locale
- * the desired locale
- * @return the string representation of the {@code field value}, or {@code
- * null} if the string representation is not applicable or
- * the given calendar type is unknown
- * @throws IllegalArgumentException
- * if {@code field} or {@code style} is invalid
- * @throws NullPointerException if {@code locale} is {@code null}
- * @see TimeZoneNameProvider
- * @see java.util.Calendar#get(int)
- * @see java.util.Calendar#getDisplayName(int, int, Locale)
- */
- public abstract String getDisplayName(String calendarType,
- int field, int value,
- int style, Locale locale);
-
- /**
- * Returns a {@code Map} containing all string representations (display
- * names) of the {@code Calendar} {@code field} in the given {@code style}
- * and {@code locale} and their corresponding field values.
- *
- * <p>{@code field} is a {@code Calendar} field index, such as {@link
- * Calendar#MONTH}. The time zone fields, {@link Calendar#ZONE_OFFSET} and
- * {@link Calendar#DST_OFFSET}, are <em>not</em> supported by this
- * method. {@code null} must be returned if any time zone fields are specified.
- *
- * <p>{@code style} gives the style of the string representation. It must be
- * one of {@link Calendar#ALL_STYLES}, {@link Calendar#SHORT_FORMAT} ({@link
- * Calendar#SHORT SHORT}), {@link Calendar#SHORT_STANDALONE}, {@link
- * Calendar#LONG_FORMAT} ({@link Calendar#LONG LONG}), or {@link
- * Calendar#LONG_STANDALONE}.
- *
- * <p>For example, the following call will return a {@code Map} containing
- * {@code "January"} to {@link Calendar#JANUARY}, {@code "Jan"} to {@link
- * Calendar#JANUARY}, {@code "February"} to {@link Calendar#FEBRUARY},
- * {@code "Feb"} to {@link Calendar#FEBRUARY}, and so on.
- * <pre>
- * getDisplayNames("gregory", Calendar.MONTH, Calendar.ALL_STYLES, Locale.ENGLISH);
- * </pre>
- *
- * @param calendarType
- * the calendar type. (Any calendar type given by {@code locale}
- * is ignored.)
- * @param field
- * the calendar field for which the display names are returned
- * @param style
- * the style applied to the display names; one of
- * {@link Calendar#ALL_STYLES}, {@link Calendar#SHORT_FORMAT}
- * ({@link Calendar#SHORT SHORT}), {@link
- * Calendar#SHORT_STANDALONE}, {@link Calendar#LONG_FORMAT}
- * ({@link Calendar#LONG LONG}), or {@link
- * Calendar#LONG_STANDALONE}.
- * @param locale
- * the desired locale
- * @return a {@code Map} containing all display names of {@code field} in
- * {@code style} and {@code locale} and their {@code field} values,
- * or {@code null} if no display names are defined for {@code field}
- * @throws NullPointerException
- * if {@code locale} is {@code null}
- * @see Calendar#getDisplayNames(int, int, Locale)
- */
- public abstract Map<String, Integer> getDisplayNames(String calendarType,
- int field, int style,
- Locale locale);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/spi/CalendarNameProvider.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.util.spi;
+
+import java.util.Calendar;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * An abstract class for service providers that provide localized string
+ * representations (display names) of {@code Calendar} field values.
+ *
+ * <p><a name="calendartypes"><b>Calendar Types</b></a>
+ *
+ * <p>Calendar types are used to specify calendar systems for which the {@link
+ * #getDisplayName(String, int, int, int, Locale) getDisplayName} and {@link
+ * #getDisplayNames(String, int, int, Locale) getDisplayNames} methods provide
+ * calendar field value names. See {@link Calendar#getCalendarType()} for details.
+ *
+ * <p><b>Calendar Fields</b>
+ *
+ * <p>Calendar fields are specified with the constants defined in {@link
+ * Calendar}. The following are calendar-common fields and their values to be
+ * supported for each calendar system.
+ *
+ * <table style="border-bottom:1px solid" border="1" cellpadding="3" cellspacing="0" summary="Field values">
+ * <tr>
+ * <th>Field</th>
+ * <th>Value</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td valign="top">{@link Calendar#MONTH}</td>
+ * <td valign="top">{@link Calendar#JANUARY} to {@link Calendar#UNDECIMBER}</td>
+ * <td>Month numbering is 0-based (e.g., 0 - January, ..., 11 -
+ * December). Some calendar systems have 13 months. Month
+ * names need to be supported in both the formatting and
+ * stand-alone forms if required by the supported locales. If there's
+ * no distinction in the two forms, the same names should be returned
+ * in both of the forms.</td>
+ * </tr>
+ * <tr>
+ * <td valign="top">{@link Calendar#DAY_OF_WEEK}</td>
+ * <td valign="top">{@link Calendar#SUNDAY} to {@link Calendar#SATURDAY}</td>
+ * <td>Day-of-week numbering is 1-based starting from Sunday (i.e., 1 - Sunday,
+ * ..., 7 - Saturday).</td>
+ * </tr>
+ * <tr>
+ * <td valign="top">{@link Calendar#AM_PM}</td>
+ * <td valign="top">{@link Calendar#AM} to {@link Calendar#PM}</td>
+ * <td>0 - AM, 1 - PM</td>
+ * </tr>
+ * </table>
+ *
+ * <p style="margin-top:20px">The following are calendar-specific fields and their values to be supported.
+ *
+ * <table style="border-bottom:1px solid" border="1" cellpadding="3" cellspacing="0" summary="Calendar type and field values">
+ * <tr>
+ * <th>Calendar Type</th>
+ * <th>Field</th>
+ * <th>Value</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td rowspan="2" valign="top">{@code "gregory"}</td>
+ * <td rowspan="2" valign="top">{@link Calendar#ERA}</td>
+ * <td>0</td>
+ * <td>{@link java.util.GregorianCalendar#BC} (BCE)</td>
+ * </tr>
+ * <tr>
+ * <td>1</td>
+ * <td>{@link java.util.GregorianCalendar#AD} (CE)</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="2" valign="top">{@code "buddhist"}</td>
+ * <td rowspan="2" valign="top">{@link Calendar#ERA}</td>
+ * <td>0</td>
+ * <td>BC (BCE)</td>
+ * </tr>
+ * <tr>
+ * <td>1</td>
+ * <td>B.E. (Buddhist Era)</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="6" valign="top">{@code "japanese"}</td>
+ * <td rowspan="5" valign="top">{@link Calendar#ERA}</td>
+ * <td>0</td>
+ * <td>Seireki (Before Meiji)</td>
+ * </tr>
+ * <tr>
+ * <td>1</td>
+ * <td>Meiji</td>
+ * </tr>
+ * <tr>
+ * <td>2</td>
+ * <td>Taisho</td>
+ * </tr>
+ * <tr>
+ * <td>3</td>
+ * <td>Showa</td>
+ * </tr>
+ * <tr>
+ * <td>4</td>
+ * <td >Heisei</td>
+ * </tr>
+ * <tr>
+ * <td>{@link Calendar#YEAR}</td>
+ * <td>1</td>
+ * <td>the first year in each era. It should be returned when a long
+ * style ({@link Calendar#LONG_FORMAT} or {@link Calendar#LONG_STANDALONE}) is
+ * specified. See also the <a href="../../text/SimpleDateFormat.html#year">
+ * Year representation in {@code SimpleDateFormat}</a>.</td>
+ * </tr>
+ * </table>
+ *
+ * <p>Calendar field value names for {@code "gregory"} must be consistent with
+ * the date-time symbols provided by {@link java.text.spi.DateFormatSymbolsProvider}.
+ *
+ * <p>Time zone names are supported by {@link TimeZoneNameProvider}.
+ *
+ * @author Masayoshi Okutsu
+ * @since 1.8
+ * @see CalendarDataProvider
+ * @see Locale#getUnicodeLocaleType(String)
+ */
+public abstract class CalendarNameProvider extends LocaleServiceProvider {
+ /**
+ * Sole constructor. (For invocation by subclass constructors, typically
+ * implicit.)
+ */
+ protected CalendarNameProvider() {
+ }
+
+ /**
+ * Returns the string representation (display name) of the calendar
+ * <code>field value</code> in the given <code>style</code> and
+ * <code>locale</code>. If no string representation is
+ * applicable, <code>null</code> is returned.
+ *
+ * <p>{@code field} is a {@code Calendar} field index, such as {@link
+ * Calendar#MONTH}. The time zone fields, {@link Calendar#ZONE_OFFSET} and
+ * {@link Calendar#DST_OFFSET}, are <em>not</em> supported by this
+ * method. {@code null} must be returned if any time zone fields are
+ * specified.
+ *
+ * <p>{@code value} is the numeric representation of the {@code field} value.
+ * For example, if {@code field} is {@link Calendar#DAY_OF_WEEK}, the valid
+ * values are {@link Calendar#SUNDAY} to {@link Calendar#SATURDAY}
+ * (inclusive).
+ *
+ * <p>{@code style} gives the style of the string representation. It is one
+ * of {@link Calendar#SHORT_FORMAT} ({@link Calendar#SHORT SHORT}),
+ * {@link Calendar#SHORT_STANDALONE}, {@link Calendar#LONG_FORMAT}
+ * ({@link Calendar#LONG LONG}), or {@link Calendar#LONG_STANDALONE}.
+ *
+ * <p>For example, the following call will return {@code "Sunday"}.
+ * <pre>
+ * getDisplayName("gregory", Calendar.DAY_OF_WEEK, Calendar.SUNDAY,
+ * Calendar.LONG_STANDALONE, Locale.ENGLISH);
+ * </pre>
+ *
+ * @param calendarType
+ * the calendar type. (Any calendar type given by {@code locale}
+ * is ignored.)
+ * @param field
+ * the {@code Calendar} field index,
+ * such as {@link Calendar#DAY_OF_WEEK}
+ * @param value
+ * the value of the {@code Calendar field},
+ * such as {@link Calendar#MONDAY}
+ * @param style
+ * the string representation style: one of {@link
+ * Calendar#SHORT_FORMAT} ({@link Calendar#SHORT SHORT}),
+ * {@link Calendar#SHORT_STANDALONE}, {@link
+ * Calendar#LONG_FORMAT} ({@link Calendar#LONG LONG}), or
+ * {@link Calendar#LONG_STANDALONE}
+ * @param locale
+ * the desired locale
+ * @return the string representation of the {@code field value}, or {@code
+ * null} if the string representation is not applicable or
+ * the given calendar type is unknown
+ * @throws IllegalArgumentException
+ * if {@code field} or {@code style} is invalid
+ * @throws NullPointerException if {@code locale} is {@code null}
+ * @see TimeZoneNameProvider
+ * @see java.util.Calendar#get(int)
+ * @see java.util.Calendar#getDisplayName(int, int, Locale)
+ */
+ public abstract String getDisplayName(String calendarType,
+ int field, int value,
+ int style, Locale locale);
+
+ /**
+ * Returns a {@code Map} containing all string representations (display
+ * names) of the {@code Calendar} {@code field} in the given {@code style}
+ * and {@code locale} and their corresponding field values.
+ *
+ * <p>{@code field} is a {@code Calendar} field index, such as {@link
+ * Calendar#MONTH}. The time zone fields, {@link Calendar#ZONE_OFFSET} and
+ * {@link Calendar#DST_OFFSET}, are <em>not</em> supported by this
+ * method. {@code null} must be returned if any time zone fields are specified.
+ *
+ * <p>{@code style} gives the style of the string representation. It must be
+ * one of {@link Calendar#ALL_STYLES}, {@link Calendar#SHORT_FORMAT} ({@link
+ * Calendar#SHORT SHORT}), {@link Calendar#SHORT_STANDALONE}, {@link
+ * Calendar#LONG_FORMAT} ({@link Calendar#LONG LONG}), or {@link
+ * Calendar#LONG_STANDALONE}.
+ *
+ * <p>For example, the following call will return a {@code Map} containing
+ * {@code "January"} to {@link Calendar#JANUARY}, {@code "Jan"} to {@link
+ * Calendar#JANUARY}, {@code "February"} to {@link Calendar#FEBRUARY},
+ * {@code "Feb"} to {@link Calendar#FEBRUARY}, and so on.
+ * <pre>
+ * getDisplayNames("gregory", Calendar.MONTH, Calendar.ALL_STYLES, Locale.ENGLISH);
+ * </pre>
+ *
+ * @param calendarType
+ * the calendar type. (Any calendar type given by {@code locale}
+ * is ignored.)
+ * @param field
+ * the calendar field for which the display names are returned
+ * @param style
+ * the style applied to the display names; one of
+ * {@link Calendar#ALL_STYLES}, {@link Calendar#SHORT_FORMAT}
+ * ({@link Calendar#SHORT SHORT}), {@link
+ * Calendar#SHORT_STANDALONE}, {@link Calendar#LONG_FORMAT}
+ * ({@link Calendar#LONG LONG}), or {@link
+ * Calendar#LONG_STANDALONE}.
+ * @param locale
+ * the desired locale
+ * @return a {@code Map} containing all display names of {@code field} in
+ * {@code style} and {@code locale} and their {@code field} values,
+ * or {@code null} if no display names are defined for {@code field}
+ * @throws NullPointerException
+ * if {@code locale} is {@code null}
+ * @see Calendar#getDisplayNames(int, int, Locale)
+ */
+ public abstract Map<String, Integer> getDisplayNames(String calendarType,
+ int field, int style,
+ Locale locale);
+}
--- a/jdk/src/share/classes/javax/net/ssl/HandshakeCompletedEvent.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/HandshakeCompletedEvent.java Fri Nov 30 17:09:05 2012 -0800
@@ -29,7 +29,6 @@
import java.security.cert.Certificate;
import java.security.Principal;
import java.security.cert.X509Certificate;
-import javax.security.auth.x500.X500Principal;
/**
* This event indicates that an SSL handshake completed on a given
--- a/jdk/src/share/classes/javax/net/ssl/HostnameVerifier.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/HostnameVerifier.java Fri Nov 30 17:09:05 2012 -0800
@@ -40,6 +40,7 @@
* verification fail.
*
* @author Brad R. Wetmore
+ * @see HostnameVerifierFactory
* @since 1.4
*/
--- a/jdk/src/share/classes/javax/net/ssl/HttpsURLConnection.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/HttpsURLConnection.java Fri Nov 30 17:09:05 2012 -0800
@@ -29,7 +29,6 @@
import java.net.HttpURLConnection;
import java.security.Principal;
import java.security.cert.X509Certificate;
-import javax.security.auth.x500.X500Principal;
/**
* <code>HttpsURLConnection</code> extends <code>HttpURLConnection</code>
@@ -196,6 +195,7 @@
*/
private static class DefaultHostnameVerifier
implements HostnameVerifier {
+ @Override
public boolean verify(String hostname, SSLSession session) {
return false;
}
--- a/jdk/src/share/classes/javax/net/ssl/KeyManagerFactory.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/KeyManagerFactory.java Fri Nov 30 17:09:05 2012 -0800
@@ -68,6 +68,7 @@
public final static String getDefaultAlgorithm() {
String type;
type = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ @Override
public String run() {
return Security.getProperty(
"ssl.KeyManagerFactory.algorithm");
--- a/jdk/src/share/classes/javax/net/ssl/SSLContext.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/SSLContext.java Fri Nov 30 17:09:05 2012 -0800
@@ -26,7 +26,6 @@
package javax.net.ssl;
import java.security.*;
-import java.util.*;
import sun.security.jca.GetInstance;
--- a/jdk/src/share/classes/javax/net/ssl/SSLContextSpi.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/SSLContextSpi.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,7 +25,6 @@
package javax.net.ssl;
-import java.util.*;
import java.security.*;
/**
--- a/jdk/src/share/classes/javax/net/ssl/SSLEngineResult.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/SSLEngineResult.java Fri Nov 30 17:09:05 2012 -0800
@@ -230,6 +230,7 @@
/**
* Returns a String representation of this object.
*/
+ @Override
public String toString() {
return ("Status = " + status +
" HandshakeStatus = " + handshakeStatus +
--- a/jdk/src/share/classes/javax/net/ssl/SSLParameters.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/SSLParameters.java Fri Nov 30 17:09:05 2012 -0800
@@ -28,13 +28,11 @@
import java.security.AlgorithmConstraints;
import java.util.Map;
import java.util.List;
-import java.util.HashSet;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
-import java.util.regex.Pattern;
/**
* Encapsulates parameters for an SSL/TLS connection. The parameters
--- a/jdk/src/share/classes/javax/net/ssl/SSLPermission.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/SSLPermission.java Fri Nov 30 17:09:05 2012 -0800
@@ -26,11 +26,6 @@
package javax.net.ssl;
import java.security.*;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.StringTokenizer;
-import java.security.Permissions;
-import java.lang.SecurityManager;
/**
* This class is for various network permissions.
--- a/jdk/src/share/classes/javax/net/ssl/SSLServerSocketFactory.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/SSLServerSocketFactory.java Fri Nov 30 17:09:05 2012 -0800
@@ -160,23 +160,27 @@
new SocketException(reason.toString()).initCause(reason);
}
+ @Override
public ServerSocket createServerSocket() throws IOException {
return throwException();
}
+ @Override
public ServerSocket createServerSocket(int port)
throws IOException
{
return throwException();
}
+ @Override
public ServerSocket createServerSocket(int port, int backlog)
throws IOException
{
return throwException();
}
+ @Override
public ServerSocket
createServerSocket(int port, int backlog, InetAddress ifAddress)
throws IOException
@@ -184,10 +188,12 @@
return throwException();
}
+ @Override
public String [] getDefaultCipherSuites() {
return new String[0];
}
+ @Override
public String [] getSupportedCipherSuites() {
return new String[0];
}
--- a/jdk/src/share/classes/javax/net/ssl/SSLSession.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/SSLSession.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,7 +25,6 @@
package javax.net.ssl;
-import java.net.InetAddress;
import java.security.Principal;
/**
--- a/jdk/src/share/classes/javax/net/ssl/SSLSocket.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/SSLSocket.java Fri Nov 30 17:09:05 2012 -0800
@@ -28,9 +28,6 @@
import java.io.IOException;
import java.net.*;
-import java.util.Enumeration;
-import java.util.Vector;
-
/**
* This class extends <code>Socket</code>s and provides secure
--- a/jdk/src/share/classes/javax/net/ssl/SSLSocketFactory.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/SSLSocketFactory.java Fri Nov 30 17:09:05 2012 -0800
@@ -127,6 +127,7 @@
static String getSecurityProperty(final String name) {
return AccessController.doPrivileged(new PrivilegedAction<String>() {
+ @Override
public String run() {
String s = java.security.Security.getProperty(name);
if (s != null) {
@@ -247,18 +248,21 @@
new SocketException(reason.toString()).initCause(reason);
}
+ @Override
public Socket createSocket()
throws IOException
{
return throwException();
}
+ @Override
public Socket createSocket(String host, int port)
throws IOException
{
return throwException();
}
+ @Override
public Socket createSocket(Socket s, String host,
int port, boolean autoClose)
throws IOException
@@ -266,12 +270,14 @@
return throwException();
}
+ @Override
public Socket createSocket(InetAddress address, int port)
throws IOException
{
return throwException();
}
+ @Override
public Socket createSocket(String host, int port,
InetAddress clientAddress, int clientPort)
throws IOException
@@ -279,6 +285,7 @@
return throwException();
}
+ @Override
public Socket createSocket(InetAddress address, int port,
InetAddress clientAddress, int clientPort)
throws IOException
@@ -286,10 +293,12 @@
return throwException();
}
+ @Override
public String [] getDefaultCipherSuites() {
return new String[0];
}
+ @Override
public String [] getSupportedCipherSuites() {
return new String[0];
}
--- a/jdk/src/share/classes/javax/net/ssl/TrustManagerFactory.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/TrustManagerFactory.java Fri Nov 30 17:09:05 2012 -0800
@@ -65,6 +65,7 @@
public final static String getDefaultAlgorithm() {
String type;
type = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ @Override
public String run() {
return Security.getProperty(
"ssl.TrustManagerFactory.algorithm");
--- a/jdk/src/share/classes/javax/net/ssl/X509KeyManager.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/X509KeyManager.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,7 +25,6 @@
package javax.net.ssl;
-import java.security.KeyManagementException;
import java.security.PrivateKey;
import java.security.Principal;
import java.security.cert.X509Certificate;
--- a/jdk/src/share/classes/sun/launcher/LauncherHelper.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/sun/launcher/LauncherHelper.java Fri Nov 30 17:09:05 2012 -0800
@@ -69,7 +69,6 @@
public enum LauncherHelper {
INSTANCE;
private static final String MAIN_CLASS = "Main-Class";
-
private static StringBuilder outBuf = new StringBuilder();
private static final String INDENT = " ";
@@ -87,6 +86,9 @@
private static final ResourceBundle RB =
ResourceBundle.getBundle(defaultBundleName);
}
+ private static PrintStream ostream;
+ private static final ClassLoader scloader = ClassLoader.getSystemClassLoader();
+ private static Class<?> appClass; // application class, for GUI/reporting purposes
/*
* A method called by the launcher to print out the standard settings,
@@ -114,27 +116,27 @@
long initialHeapSize, long maxHeapSize, long stackSize,
boolean isServer) {
- PrintStream ostream = (printToStderr) ? System.err : System.out;
+ initOutput(printToStderr);
String opts[] = optionFlag.split(":");
String optStr = (opts.length > 1 && opts[1] != null)
? opts[1].trim()
: "all";
switch (optStr) {
case "vm":
- printVmSettings(ostream, initialHeapSize, maxHeapSize,
- stackSize, isServer);
+ printVmSettings(initialHeapSize, maxHeapSize,
+ stackSize, isServer);
break;
case "properties":
- printProperties(ostream);
+ printProperties();
break;
case "locale":
- printLocale(ostream);
+ printLocale();
break;
default:
- printVmSettings(ostream, initialHeapSize, maxHeapSize,
- stackSize, isServer);
- printProperties(ostream);
- printLocale(ostream);
+ printVmSettings(initialHeapSize, maxHeapSize, stackSize,
+ isServer);
+ printProperties();
+ printLocale();
break;
}
}
@@ -142,7 +144,7 @@
/*
* prints the main vm settings subopt/section
*/
- private static void printVmSettings(PrintStream ostream,
+ private static void printVmSettings(
long initialHeapSize, long maxHeapSize,
long stackSize, boolean isServer) {
@@ -172,14 +174,14 @@
/*
* prints the properties subopt/section
*/
- private static void printProperties(PrintStream ostream) {
+ private static void printProperties() {
Properties p = System.getProperties();
ostream.println(PROP_SETTINGS);
List<String> sortedPropertyKeys = new ArrayList<>();
sortedPropertyKeys.addAll(p.stringPropertyNames());
Collections.sort(sortedPropertyKeys);
for (String x : sortedPropertyKeys) {
- printPropertyValue(ostream, x, p.getProperty(x));
+ printPropertyValue(x, p.getProperty(x));
}
ostream.println();
}
@@ -188,8 +190,7 @@
return key.endsWith(".dirs") || key.endsWith(".path");
}
- private static void printPropertyValue(PrintStream ostream,
- String key, String value) {
+ private static void printPropertyValue(String key, String value) {
ostream.print(INDENT + key + " = ");
if (key.equals("line.separator")) {
for (byte b : value.getBytes()) {
@@ -229,7 +230,7 @@
/*
* prints the locale subopt/section
*/
- private static void printLocale(PrintStream ostream) {
+ private static void printLocale() {
Locale locale = Locale.getDefault();
ostream.println(LOCALE_SETTINGS);
ostream.println(INDENT + "default locale = " +
@@ -238,11 +239,11 @@
Locale.getDefault(Category.DISPLAY).getDisplayName());
ostream.println(INDENT + "default format locale = " +
Locale.getDefault(Category.FORMAT).getDisplayName());
- printLocales(ostream);
+ printLocales();
ostream.println();
}
- private static void printLocales(PrintStream ostream) {
+ private static void printLocales() {
Locale[] tlocales = Locale.getAvailableLocales();
final int len = tlocales == null ? 0 : tlocales.length;
if (len < 1 ) {
@@ -370,7 +371,7 @@
* initHelpSystem must be called before using this method.
*/
static void printHelpMessage(boolean printToStderr) {
- PrintStream ostream = (printToStderr) ? System.err : System.out;
+ initOutput(printToStderr);
outBuf = outBuf.append(getLocalizedMessage("java.launcher.opt.footer",
File.pathSeparator));
ostream.println(outBuf.toString());
@@ -380,7 +381,7 @@
* Prints the Xusage text to the desired output stream.
*/
static void printXUsageMessage(boolean printToStderr) {
- PrintStream ostream = (printToStderr) ? System.err : System.out;
+ initOutput(printToStderr);
ostream.println(getLocalizedMessage("java.launcher.X.usage",
File.pathSeparator));
if (System.getProperty("os.name").contains("OS X")) {
@@ -389,36 +390,32 @@
}
}
- static String getMainClassFromJar(PrintStream ostream, String jarname) {
- try {
- JarFile jarFile = null;
- try {
- jarFile = new JarFile(jarname);
- Manifest manifest = jarFile.getManifest();
- if (manifest == null) {
- abort(ostream, null, "java.launcher.jar.error2", jarname);
- }
- Attributes mainAttrs = manifest.getMainAttributes();
- if (mainAttrs == null) {
- abort(ostream, null, "java.launcher.jar.error3", jarname);
- }
- String mainValue = mainAttrs.getValue(MAIN_CLASS);
- if (mainValue == null) {
- abort(ostream, null, "java.launcher.jar.error3", jarname);
- }
- return mainValue.trim();
- } finally {
- if (jarFile != null) {
- jarFile.close();
- }
+ static void initOutput(boolean printToStderr) {
+ ostream = (printToStderr) ? System.err : System.out;
+ }
+
+ static String getMainClassFromJar(String jarname) {
+ String mainValue = null;
+ try (JarFile jarFile = new JarFile(jarname)) {
+ Manifest manifest = jarFile.getManifest();
+ if (manifest == null) {
+ abort(null, "java.launcher.jar.error2", jarname);
}
+ Attributes mainAttrs = manifest.getMainAttributes();
+ if (mainAttrs == null) {
+ abort(null, "java.launcher.jar.error3", jarname);
+ }
+ mainValue = mainAttrs.getValue(MAIN_CLASS);
+ if (mainValue == null) {
+ abort(null, "java.launcher.jar.error3", jarname);
+ }
+ return mainValue.trim();
} catch (IOException ioe) {
- abort(ostream, ioe, "java.launcher.jar.error1", jarname);
+ abort(ioe, "java.launcher.jar.error1", jarname);
}
return null;
}
-
// From src/share/bin/java.c:
// enum LaunchMode { LM_UNKNOWN = 0, LM_CLASS, LM_JAR };
@@ -426,7 +423,7 @@
private static final int LM_CLASS = 1;
private static final int LM_JAR = 2;
- static void abort(PrintStream ostream, Throwable t, String msgKey, Object... args) {
+ static void abort(Throwable t, String msgKey, Object... args) {
if (msgKey != null) {
ostream.println(getLocalizedMessage(msgKey, args));
}
@@ -450,19 +447,22 @@
* b. is there a main
* c. is the main public
* d. is the main static
- * c. does the main take a String array for args
- * 4. and off we go......
+ * e. does the main take a String array for args
+ * 4. if no main method and if the class extends FX Application, then call
+ * on FXHelper to determine the main class to launch
+ * 5. and off we go......
*
- * @param printToStderr
- * @param isJar
- * @param name
- * @return
+ * @param printToStderr if set, all output will be routed to stderr
+ * @param mode LaunchMode as determined by the arguments passed on the
+ * command line
+ * @param what either the jar file to launch or the main class when using
+ * LM_CLASS mode
+ * @return the application's main class
*/
public static Class<?> checkAndLoadMain(boolean printToStderr,
int mode,
String what) {
- final PrintStream ostream = (printToStderr) ? System.err : System.out;
- final ClassLoader ld = ClassLoader.getSystemClassLoader();
+ initOutput(printToStderr);
// get the class name
String cn = null;
switch (mode) {
@@ -470,44 +470,75 @@
cn = what;
break;
case LM_JAR:
- cn = getMainClassFromJar(ostream, what);
+ cn = getMainClassFromJar(what);
break;
default:
// should never happen
throw new InternalError("" + mode + ": Unknown launch mode");
}
cn = cn.replace('/', '.');
- Class<?> c = null;
+ Class<?> mainClass = null;
try {
- c = ld.loadClass(cn);
- } catch (ClassNotFoundException cnfe) {
- abort(ostream, cnfe, "java.launcher.cls.error1", cn);
+ mainClass = scloader.loadClass(cn);
+ } catch (NoClassDefFoundError | ClassNotFoundException cnfe) {
+ abort(cnfe, "java.launcher.cls.error1", cn);
}
- getMainMethod(ostream, c);
- return c;
+ // set to mainClass, FXHelper may return something else
+ appClass = mainClass;
+
+ Method m = getMainMethod(mainClass);
+ if (m != null) {
+ // this will abort if main method has the wrong signature
+ validateMainMethod(m);
+ return mainClass;
+ }
+
+ // Check if FXHelper can launch it using the FX launcher
+ Class<?> fxClass = FXHelper.getFXMainClass(mainClass);
+ if (fxClass != null) {
+ return fxClass;
+ }
+
+ // not an FX application either, abort with an error
+ abort(null, "java.launcher.cls.error4", mainClass.getName(),
+ FXHelper.JAVAFX_APPLICATION_CLASS_NAME);
+ return null; // avoid compiler error...
}
- static Method getMainMethod(PrintStream ostream, Class<?> clazz) {
- String classname = clazz.getName();
- Method method = null;
+ /*
+ * Accessor method called by the launcher after getting the main class via
+ * checkAndLoadMain(). The "application class" is the class that is finally
+ * executed to start the application and in this case is used to report
+ * the correct application name, typically for UI purposes.
+ */
+ public static Class<?> getApplicationClass() {
+ return appClass;
+ }
+
+ // Check for main method or return null if not found
+ static Method getMainMethod(Class<?> clazz) {
try {
- method = clazz.getMethod("main", String[].class);
- } catch (NoSuchMethodException nsme) {
- abort(ostream, null, "java.launcher.cls.error4", classname);
- }
+ return clazz.getMethod("main", String[].class);
+ } catch (NoSuchMethodException nsme) {}
+ return null;
+ }
+
+ // Check the signature of main and abort if it's incorrect
+ static void validateMainMethod(Method mainMethod) {
/*
* getMethod (above) will choose the correct method, based
* on its name and parameter type, however, we still have to
* ensure that the method is static and returns a void.
*/
- int mod = method.getModifiers();
+ int mod = mainMethod.getModifiers();
if (!Modifier.isStatic(mod)) {
- abort(ostream, null, "java.launcher.cls.error2", "static", classname);
+ abort(null, "java.launcher.cls.error2", "static",
+ mainMethod.getDeclaringClass().getName());
}
- if (method.getReturnType() != java.lang.Void.TYPE) {
- abort(ostream, null, "java.launcher.cls.error3", classname);
+ if (mainMethod.getReturnType() != java.lang.Void.TYPE) {
+ abort(null, "java.launcher.cls.error3",
+ mainMethod.getDeclaringClass().getName());
}
- return method;
}
private static final String encprop = "sun.jnu.encoding";
@@ -519,7 +550,7 @@
* previously implemented as a native method in the launcher.
*/
static String makePlatformString(boolean printToStderr, byte[] inArray) {
- final PrintStream ostream = (printToStderr) ? System.err : System.out;
+ initOutput(printToStderr);
if (encoding == null) {
encoding = System.getProperty(encprop);
isCharsetSupported = Charset.isSupported(encoding);
@@ -530,7 +561,7 @@
: new String(inArray);
return out;
} catch (UnsupportedEncodingException uee) {
- abort(ostream, uee, null);
+ abort(uee, null);
}
return null; // keep the compiler happy
}
@@ -611,5 +642,65 @@
return "StdArg{" + "arg=" + arg + ", needsExpansion=" + needsExpansion + '}';
}
}
+
+ static final class FXHelper {
+ private static final String JAVAFX_APPLICATION_CLASS_NAME =
+ "javafx.application.Application";
+ private static final String JAVAFX_LAUNCHER_CLASS_NAME =
+ "com.sun.javafx.application.LauncherImpl";
+
+ /*
+ * FX application launcher and launch method, so we can launch
+ * applications with no main method.
+ */
+ private static Class<?> fxLauncherClass = null;
+ private static Method fxLauncherMethod = null;
+
+ /*
+ * We can assume that the class does NOT have a main method or it would
+ * have been handled already. We do, however, need to check if the class
+ * extends Application and the launcher is available and abort with an
+ * error if it's not.
+ */
+ private static Class<?> getFXMainClass(Class<?> mainClass) {
+ // Check if mainClass extends Application
+ if (!doesExtendFXApplication(mainClass)) {
+ return null;
+ }
+
+ // Check for the FX launcher classes
+ try {
+ fxLauncherClass = scloader.loadClass(JAVAFX_LAUNCHER_CLASS_NAME);
+ fxLauncherMethod = fxLauncherClass.getMethod("launchApplication",
+ Class.class, String[].class);
+ } catch (ClassNotFoundException | NoSuchMethodException ex) {
+ abort(ex, "java.launcher.cls.error5", ex);
+ }
+
+ // That's all, return this class so we can launch later
+ return FXHelper.class;
+ }
+
+ /*
+ * Check if the given class is a JavaFX Application class. This is done
+ * in a way that does not cause the Application class to load or throw
+ * ClassNotFoundException if the JavaFX runtime is not available.
+ */
+ private static boolean doesExtendFXApplication(Class<?> mainClass) {
+ for (Class<?> sc = mainClass.getSuperclass(); sc != null;
+ sc = sc.getSuperclass()) {
+ if (sc.getName().equals(JAVAFX_APPLICATION_CLASS_NAME)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // preloader ?
+ public static void main(String... args) throws Exception {
+ // launch appClass via fxLauncherMethod
+ fxLauncherMethod.invoke(null, new Object[] {appClass, args});
+ }
+ }
}
--- a/jdk/src/share/classes/sun/launcher/resources/launcher.properties Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/sun/launcher/resources/launcher.properties Fri Nov 30 17:09:05 2012 -0800
@@ -131,7 +131,10 @@
\ public static void main(String[] args)
java.launcher.cls.error4=\
Error: Main method not found in class {0}, please define the main method as:\n\
-\ public static void main(String[] args)
+\ public static void main(String[] args)\n\
+ or a JavaFX application class must extend {1}
+java.launcher.cls.error5=\
+ Error: JavaFX runtime components are missing, and are required to run this application
java.launcher.jar.error1=\
Error: An unexpected error occurred while trying to open file {0}
java.launcher.jar.error2=manifest not found in {0}
--- a/jdk/src/share/classes/sun/security/krb5/Config.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/sun/security/krb5/Config.java Fri Nov 30 17:09:05 2012 -0800
@@ -1123,7 +1123,7 @@
*/
private String getKDCFromDNS(String realm) throws KrbException {
// use DNS to locate KDC
- String kdcs = null;
+ String kdcs = "";
String[] srvs = null;
// locate DNS SRV record using UDP
if (DEBUG) {
@@ -1133,7 +1133,7 @@
if (srvs == null) {
// locate DNS SRV record using TCP
if (DEBUG) {
- System.out.println("getKDCFromDNS using UDP");
+ System.out.println("getKDCFromDNS using TCP");
}
srvs = KrbServiceLocator.getKerberosService(realm, "_tcp");
}
@@ -1142,14 +1142,15 @@
throw new KrbException(Krb5.KRB_ERR_GENERIC,
"Unable to locate KDC for realm " + realm);
}
+ if (srvs.length == 0) {
+ return null;
+ }
for (int i = 0; i < srvs.length; i++) {
- String value = srvs[i];
- for (int j = 0; j < srvs[i].length(); j++) {
- // filter the KDC name
- if (value.charAt(j) == ':') {
- kdcs = (value.substring(0, j)).trim();
- }
- }
+ kdcs += srvs[i].trim() + " ";
+ }
+ kdcs = kdcs.trim();
+ if (kdcs.equals("")) {
+ return null;
}
return kdcs;
}
--- a/jdk/src/share/classes/sun/tools/jar/Main.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/sun/tools/jar/Main.java Fri Nov 30 17:09:05 2012 -0800
@@ -839,8 +839,8 @@
void replaceFSC(String files[]) {
if (files != null) {
- for (String file : files) {
- file = file.replace(File.separatorChar, '/');
+ for (int i = 0; i < files.length; i++) {
+ files[i] = files[i].replace(File.separatorChar, '/');
}
}
}
--- a/jdk/src/share/classes/sun/util/locale/provider/AuxLocaleProviderAdapter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/sun/util/locale/provider/AuxLocaleProviderAdapter.java Fri Nov 30 17:09:05 2012 -0800
@@ -38,6 +38,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.spi.CalendarDataProvider;
+import java.util.spi.CalendarNameProvider;
import java.util.spi.CurrencyNameProvider;
import java.util.spi.LocaleNameProvider;
import java.util.spi.LocaleServiceProvider;
@@ -135,6 +136,10 @@
return getLocaleServiceProvider(CalendarDataProvider.class);
}
+ @Override
+ public CalendarNameProvider getCalendarNameProvider() {
+ return getLocaleServiceProvider(CalendarNameProvider.class);
+ }
@Override
public LocaleResources getLocaleResources(Locale locale) {
--- a/jdk/src/share/classes/sun/util/locale/provider/CalendarDataProviderImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/sun/util/locale/provider/CalendarDataProviderImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,10 +24,9 @@
*/
package sun.util.locale.provider;
+import java.util.Calendar;
import static java.util.Calendar.*;
-import java.util.HashMap;
import java.util.Locale;
-import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.spi.CalendarDataProvider;
@@ -59,115 +58,11 @@
}
@Override
- public String getDisplayName(String calendarType, int field, int value, int style, Locale locale) {
- String name = null;
- String key = getKey(calendarType, field, style);
- if (key != null) {
- ResourceBundle rb = LocaleProviderAdapter.forType(type).getLocaleData().getDateFormatData(locale);
- if (rb.containsKey(key)) {
- String[] strings = rb.getStringArray(key);
- if (strings.length > 0) {
- if (field == DAY_OF_WEEK || field == YEAR) {
- --value;
- }
- name = strings[value];
- // If name is empty in standalone, try its `format' style.
- if (name.length() == 0
- && (style == SHORT_STANDALONE || style == LONG_STANDALONE)) {
- name = getDisplayName(calendarType, field, value,
- style == SHORT_STANDALONE ? SHORT_FORMAT : LONG_FORMAT,
- locale);
- }
- }
- }
- }
- return name;
- }
-
- @Override
- public Map<String, Integer> getDisplayNames(String calendarType, int field, int style, Locale locale) {
- Map<String, Integer> names;
- if (style == ALL_STYLES) {
- names = getDisplayNamesImpl(calendarType, field, SHORT_FORMAT, locale);
- if (field != AM_PM) {
- for (int st : new int[] { SHORT_STANDALONE, LONG_FORMAT, LONG_STANDALONE }) {
- names.putAll(getDisplayNamesImpl(calendarType, field, st, locale));
- }
- }
- } else {
- // specific style
- names = getDisplayNamesImpl(calendarType, field, style, locale);
- }
- return names.isEmpty() ? null : names;
- }
-
- private Map<String, Integer> getDisplayNamesImpl(String calendarType, int field,
- int style, Locale locale) {
- String key = getKey(calendarType, field, style);
- Map<String, Integer> map = new HashMap<>();
- if (key != null) {
- ResourceBundle rb = LocaleProviderAdapter.forType(type).getLocaleData().getDateFormatData(locale);
- if (rb.containsKey(key)) {
- String[] strings = rb.getStringArray(key);
- if (field == YEAR) {
- if (strings.length > 0) {
- map.put(strings[0], 1);
- }
- } else {
- int base = (field == DAY_OF_WEEK) ? 1 : 0;
- for (int i = 0; i < strings.length; i++) {
- String name = strings[i];
- // Ignore any empty string (some standalone month names
- // are not defined)
- if (name.length() == 0) {
- continue;
- }
- map.put(name, base + i);
- }
- }
- }
- }
- return map;
- }
-
- @Override
public Locale[] getAvailableLocales() {
return LocaleProviderAdapter.toLocaleArray(langtags);
}
@Override
- public boolean isSupportedLocale(Locale locale) {
- if (Locale.ROOT.equals(locale)) {
- return true;
- }
- String calendarType = null;
- if (locale.hasExtensions()) {
- calendarType = locale.getUnicodeLocaleType("ca");
- locale = locale.stripExtensions();
- }
-
- if (calendarType != null) {
- switch (calendarType) {
- case "buddhist":
- case "japanese":
- case "gregory":
- break;
- default:
- // Unknown calendar type
- return false;
- }
- }
- if (langtags.contains(locale.toLanguageTag())) {
- return true;
- }
- if (type == LocaleProviderAdapter.Type.JRE) {
- String oldname = locale.toString().replace('_', '-');
- return langtags.contains(oldname);
- }
- return false;
- }
-
- @Override
public Set<String> getAvailableLanguageTags() {
return langtags;
}
@@ -178,49 +73,6 @@
String firstday = rb.getString(key);
return Integer.parseInt(firstday);
}
- // Note that the base bundle of CLDR doesn't have the Calendar week parameters.
return 0;
}
-
- private String getKey(String type, int field, int style) {
- boolean standalone = (style & 0x8000) != 0;
- style &= ~0x8000;
-
- if ("gregory".equals(type)) {
- type = null;
- }
-
- StringBuilder key = new StringBuilder();
- switch (field) {
- case ERA:
- if (type != null) {
- key.append(type).append('.');
- }
- if (style == SHORT) {
- key.append("short.");
- }
- key.append("Eras");
- break;
-
- case YEAR:
- key.append(type).append(".FirstYear");
- break;
-
- case MONTH:
- if (standalone) {
- key.append("standalone.");
- }
- key.append(style == SHORT ? "MonthAbbreviations" : "MonthNames");
- break;
-
- case DAY_OF_WEEK:
- key.append(style == SHORT ? "DayAbbreviations" : "DayNames");
- break;
-
- case AM_PM:
- key.append("AmPmMarkers");
- break;
- }
- return key.length() > 0 ? key.toString() : null;
- }
}
--- a/jdk/src/share/classes/sun/util/locale/provider/CalendarDataUtility.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/sun/util/locale/provider/CalendarDataUtility.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,9 +25,12 @@
package sun.util.locale.provider;
+import java.util.Calendar;
+import static java.util.Calendar.*;
import java.util.Locale;
import java.util.Map;
import java.util.spi.CalendarDataProvider;
+import java.util.spi.CalendarNameProvider;
/**
* {@code CalendarDataUtility} is a utility class for calling the
@@ -44,16 +47,32 @@
private CalendarDataUtility() {
}
+ public static int retrieveFirstDayOfWeek(Locale locale) {
+ LocaleServiceProviderPool pool =
+ LocaleServiceProviderPool.getPool(CalendarDataProvider.class);
+ Integer value = pool.getLocalizedObject(CalendarWeekParameterGetter.INSTANCE,
+ locale, FIRST_DAY_OF_WEEK);
+ return (value != null && (value >= SUNDAY && value <= SATURDAY)) ? value : SUNDAY;
+ }
+
+ public static int retrieveMinimalDaysInFirstWeek(Locale locale) {
+ LocaleServiceProviderPool pool =
+ LocaleServiceProviderPool.getPool(CalendarDataProvider.class);
+ Integer value = pool.getLocalizedObject(CalendarWeekParameterGetter.INSTANCE,
+ locale, MINIMAL_DAYS_IN_FIRST_WEEK);
+ return (value != null && (value >= 1 && value <= 7)) ? value : 1;
+ }
+
public static String retrieveFieldValueName(String id, int field, int value, int style, Locale locale) {
LocaleServiceProviderPool pool =
- LocaleServiceProviderPool.getPool(CalendarDataProvider.class);
+ LocaleServiceProviderPool.getPool(CalendarNameProvider.class);
return pool.getLocalizedObject(CalendarFieldValueNameGetter.INSTANCE, locale, id,
field, value, style);
}
public static Map<String, Integer> retrieveFieldValueNames(String id, int field, int style, Locale locale) {
LocaleServiceProviderPool pool =
- LocaleServiceProviderPool.getPool(CalendarDataProvider.class);
+ LocaleServiceProviderPool.getPool(CalendarNameProvider.class);
return pool.getLocalizedObject(CalendarFieldValueNamesMapGetter.INSTANCE, locale, id, field, style);
}
@@ -62,13 +81,13 @@
* implementation.
*/
private static class CalendarFieldValueNameGetter
- implements LocaleServiceProviderPool.LocalizedObjectGetter<CalendarDataProvider,
+ implements LocaleServiceProviderPool.LocalizedObjectGetter<CalendarNameProvider,
String> {
private static final CalendarFieldValueNameGetter INSTANCE =
new CalendarFieldValueNameGetter();
@Override
- public String getObject(CalendarDataProvider calendarDataProvider,
+ public String getObject(CalendarNameProvider calendarNameProvider,
Locale locale,
String requestID, // calendarType
Object... params) {
@@ -76,7 +95,7 @@
int field = (int) params[0];
int value = (int) params[1];
int style = (int) params[2];
- return calendarDataProvider.getDisplayName(requestID, field, value, style, locale);
+ return calendarNameProvider.getDisplayName(requestID, field, value, style, locale);
}
}
@@ -85,20 +104,47 @@
* implementation.
*/
private static class CalendarFieldValueNamesMapGetter
- implements LocaleServiceProviderPool.LocalizedObjectGetter<CalendarDataProvider,
+ implements LocaleServiceProviderPool.LocalizedObjectGetter<CalendarNameProvider,
Map<String, Integer>> {
private static final CalendarFieldValueNamesMapGetter INSTANCE =
new CalendarFieldValueNamesMapGetter();
@Override
- public Map<String, Integer> getObject(CalendarDataProvider calendarDataProvider,
+ public Map<String, Integer> getObject(CalendarNameProvider calendarNameProvider,
Locale locale,
String requestID, // calendarType
Object... params) {
assert params.length == 2;
int field = (int) params[0];
int style = (int) params[1];
- return calendarDataProvider.getDisplayNames(requestID, field, style, locale);
+ return calendarNameProvider.getDisplayNames(requestID, field, style, locale);
+ }
+ }
+
+ private static class CalendarWeekParameterGetter
+ implements LocaleServiceProviderPool.LocalizedObjectGetter<CalendarDataProvider,
+ Integer> {
+ private static final CalendarWeekParameterGetter INSTANCE =
+ new CalendarWeekParameterGetter();
+
+ @Override
+ public Integer getObject(CalendarDataProvider calendarDataProvider,
+ Locale locale,
+ String requestID, // resource key
+ Object... params) {
+ assert params.length == 0;
+ int value;
+ switch (requestID) {
+ case FIRST_DAY_OF_WEEK:
+ value = calendarDataProvider.getFirstDayOfWeek(locale);
+ break;
+ case MINIMAL_DAYS_IN_FIRST_WEEK:
+ value = calendarDataProvider.getMinimalDaysInFirstWeek(locale);
+ break;
+ default:
+ throw new InternalError("invalid requestID: " + requestID);
+ }
+ return (value != 0) ? value : null;
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/util/locale/provider/CalendarNameProviderImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.util.locale.provider;
+
+import static java.util.Calendar.*;
+import java.util.Comparator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.spi.CalendarNameProvider;
+
+/**
+ * Concrete implementation of the {@link java.util.spi.CalendarDataProvider
+ * CalendarDataProvider} class for the JRE LocaleProviderAdapter.
+ *
+ * @author Masayoshi Okutsu
+ * @author Naoto Sato
+ */
+public class CalendarNameProviderImpl extends CalendarNameProvider implements AvailableLanguageTags {
+ private final LocaleProviderAdapter.Type type;
+ private final Set<String> langtags;
+
+ public CalendarNameProviderImpl(LocaleProviderAdapter.Type type, Set<String> langtags) {
+ this.type = type;
+ this.langtags = langtags;
+ }
+
+ @Override
+ public String getDisplayName(String calendarType, int field, int value, int style, Locale locale) {
+ String name = null;
+ String key = getKey(calendarType, field, style);
+ if (key != null) {
+ ResourceBundle rb = LocaleProviderAdapter.forType(type).getLocaleData().getDateFormatData(locale);
+ if (rb.containsKey(key)) {
+ String[] strings = rb.getStringArray(key);
+ if (strings.length > 0) {
+ if (field == DAY_OF_WEEK || field == YEAR) {
+ --value;
+ }
+ name = strings[value];
+ // If name is empty in standalone, try its `format' style.
+ if (name.length() == 0
+ && (style == SHORT_STANDALONE || style == LONG_STANDALONE)) {
+ name = getDisplayName(calendarType, field, value,
+ style == SHORT_STANDALONE ? SHORT_FORMAT : LONG_FORMAT,
+ locale);
+ }
+ }
+ }
+ }
+ return name;
+ }
+
+ @Override
+ public Map<String, Integer> getDisplayNames(String calendarType, int field, int style, Locale locale) {
+ Map<String, Integer> names;
+ if (style == ALL_STYLES) {
+ names = getDisplayNamesImpl(calendarType, field, SHORT_FORMAT, locale);
+ if (field != AM_PM) {
+ for (int st : new int[] { SHORT_STANDALONE, LONG_FORMAT, LONG_STANDALONE }) {
+ names.putAll(getDisplayNamesImpl(calendarType, field, st, locale));
+ }
+ }
+ } else {
+ // specific style
+ names = getDisplayNamesImpl(calendarType, field, style, locale);
+ }
+ return names.isEmpty() ? null : names;
+ }
+
+ private Map<String, Integer> getDisplayNamesImpl(String calendarType, int field,
+ int style, Locale locale) {
+ String key = getKey(calendarType, field, style);
+ Map<String, Integer> map = new TreeMap<>(LengthBasedComparator.INSTANCE);
+ if (key != null) {
+ ResourceBundle rb = LocaleProviderAdapter.forType(type).getLocaleData().getDateFormatData(locale);
+ if (rb.containsKey(key)) {
+ String[] strings = rb.getStringArray(key);
+ if (field == YEAR) {
+ if (strings.length > 0) {
+ map.put(strings[0], 1);
+ }
+ } else {
+ int base = (field == DAY_OF_WEEK) ? 1 : 0;
+ for (int i = 0; i < strings.length; i++) {
+ String name = strings[i];
+ // Ignore any empty string (some standalone month names
+ // are not defined)
+ if (name.length() == 0) {
+ continue;
+ }
+ map.put(name, base + i);
+ }
+ }
+ }
+ }
+ return map;
+ }
+
+ /**
+ * Comparator implementation for TreeMap which iterates keys from longest
+ * to shortest.
+ */
+ private static class LengthBasedComparator implements Comparator<String> {
+ private static final LengthBasedComparator INSTANCE = new LengthBasedComparator();
+
+ private LengthBasedComparator() {
+ }
+
+ @Override
+ public int compare(String o1, String o2) {
+ int n = o2.length() - o1.length();
+ return (n == 0) ? o1.compareTo(o2) : n;
+ }
+ }
+
+ @Override
+ public Locale[] getAvailableLocales() {
+ return LocaleProviderAdapter.toLocaleArray(langtags);
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ if (Locale.ROOT.equals(locale)) {
+ return true;
+ }
+ String calendarType = null;
+ if (locale.hasExtensions()) {
+ calendarType = locale.getUnicodeLocaleType("ca");
+ locale = locale.stripExtensions();
+ }
+
+ if (calendarType != null) {
+ switch (calendarType) {
+ case "buddhist":
+ case "japanese":
+ case "gregory":
+ break;
+ default:
+ // Unknown calendar type
+ return false;
+ }
+ }
+ if (langtags.contains(locale.toLanguageTag())) {
+ return true;
+ }
+ if (type == LocaleProviderAdapter.Type.JRE) {
+ String oldname = locale.toString().replace('_', '-');
+ return langtags.contains(oldname);
+ }
+ return false;
+ }
+
+ @Override
+ public Set<String> getAvailableLanguageTags() {
+ return langtags;
+ }
+
+ private int getIntData(String key, Locale locale) {
+ ResourceBundle rb = LocaleProviderAdapter.forType(type).getLocaleData().getCalendarData(locale);
+ if (rb.containsKey(key)) {
+ String firstday = rb.getString(key);
+ return Integer.parseInt(firstday);
+ }
+ // Note that the base bundle of CLDR doesn't have the Calendar week parameters.
+ return 0;
+ }
+
+ private String getKey(String type, int field, int style) {
+ boolean standalone = (style & 0x8000) != 0;
+ style &= ~0x8000;
+
+ if ("gregory".equals(type)) {
+ type = null;
+ }
+
+ StringBuilder key = new StringBuilder();
+ switch (field) {
+ case ERA:
+ if (type != null) {
+ key.append(type).append('.');
+ }
+ if (style == SHORT) {
+ key.append("short.");
+ }
+ key.append("Eras");
+ break;
+
+ case YEAR:
+ key.append(type).append(".FirstYear");
+ break;
+
+ case MONTH:
+ if (standalone) {
+ key.append("standalone.");
+ }
+ key.append(style == SHORT ? "MonthAbbreviations" : "MonthNames");
+ break;
+
+ case DAY_OF_WEEK:
+ key.append(style == SHORT ? "DayAbbreviations" : "DayNames");
+ break;
+
+ case AM_PM:
+ key.append("AmPmMarkers");
+ break;
+ }
+ return key.length() > 0 ? key.toString() : null;
+ }
+}
--- a/jdk/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java Fri Nov 30 17:09:05 2012 -0800
@@ -41,6 +41,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.spi.CalendarDataProvider;
+import java.util.spi.CalendarNameProvider;
import java.util.spi.CurrencyNameProvider;
import java.util.spi.LocaleNameProvider;
import java.util.spi.LocaleServiceProvider;
@@ -101,6 +102,8 @@
return (P) getTimeZoneNameProvider();
case "CalendarDataProvider":
return (P) getCalendarDataProvider();
+ case "CalendarNameProvider":
+ return (P) getCalendarNameProvider();
default:
throw new InternalError("should not come down here");
}
@@ -117,6 +120,7 @@
private volatile LocaleNameProvider localeNameProvider = null;
private volatile TimeZoneNameProvider timeZoneNameProvider = null;
private volatile CalendarDataProvider calendarDataProvider = null;
+ private volatile CalendarNameProvider calendarNameProvider = null;
/*
* Getter methods for java.text.spi.* providers
@@ -252,11 +256,9 @@
@Override
public CalendarDataProvider getCalendarDataProvider() {
if (calendarDataProvider == null) {
- Set<String> set = new HashSet<>();
- set.addAll(getLanguageTagSet("FormatData"));
- set.addAll(getLanguageTagSet("CalendarData"));
- CalendarDataProvider provider = new CalendarDataProviderImpl(getAdapterType(),
- set);
+ CalendarDataProvider provider;
+ provider = new CalendarDataProviderImpl(getAdapterType(),
+ getLanguageTagSet("CalendarData"));
synchronized (this) {
if (calendarDataProvider == null) {
calendarDataProvider = provider;
@@ -267,6 +269,21 @@
}
@Override
+ public CalendarNameProvider getCalendarNameProvider() {
+ if (calendarNameProvider == null) {
+ CalendarNameProvider provider;
+ provider = new CalendarNameProviderImpl(getAdapterType(),
+ getLanguageTagSet("FormatData"));
+ synchronized (this) {
+ if (calendarNameProvider == null) {
+ calendarNameProvider = provider;
+ }
+ }
+ }
+ return calendarNameProvider;
+ }
+
+ @Override
public LocaleResources getLocaleResources(Locale locale) {
LocaleResources lr = localeResourcesMap.get(locale);
if (lr == null) {
--- a/jdk/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java Fri Nov 30 17:09:05 2012 -0800
@@ -38,6 +38,7 @@
import java.util.ResourceBundle;
import java.util.Set;
import java.util.spi.CalendarDataProvider;
+import java.util.spi.CalendarNameProvider;
import java.util.spi.CurrencyNameProvider;
import java.util.spi.LocaleNameProvider;
import java.util.spi.LocaleServiceProvider;
@@ -387,6 +388,14 @@
*/
public abstract CalendarDataProvider getCalendarDataProvider();
+ /**
+ * Returns a CalendarNameProvider for this LocaleProviderAdapter, or null if no
+ * CalendarNameProvider is available.
+ *
+ * @return a CalendarNameProvider
+ */
+ public abstract CalendarNameProvider getCalendarNameProvider();
+
public abstract LocaleResources getLocaleResources(Locale locale);
public abstract LocaleData getLocaleData();
--- a/jdk/src/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java Fri Nov 30 17:09:05 2012 -0800
@@ -28,11 +28,29 @@
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import java.text.*;
-import java.text.spi.*;
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.spi.*;
+import java.text.BreakIterator;
+import java.text.Collator;
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.text.spi.BreakIteratorProvider;
+import java.text.spi.CollatorProvider;
+import java.text.spi.DateFormatProvider;
+import java.text.spi.DateFormatSymbolsProvider;
+import java.text.spi.DecimalFormatSymbolsProvider;
+import java.text.spi.NumberFormatProvider;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.spi.CalendarDataProvider;
+import java.util.spi.CalendarNameProvider;
+import java.util.spi.CurrencyNameProvider;
+import java.util.spi.LocaleNameProvider;
+import java.util.spi.LocaleServiceProvider;
+import java.util.spi.TimeZoneNameProvider;
/**
* LocaleProviderAdapter implementation for the installed SPI implementations.
@@ -73,7 +91,7 @@
IllegalAccessException e) {
LocaleServiceProviderPool.config(SPILocaleProviderAdapter.class, e.toString());
return null;
- }
+ }
}
((Delegate)delegate).addImpl(provider);
@@ -94,7 +112,7 @@
interface Delegate<P extends LocaleServiceProvider> {
public void addImpl(P impl);
public P getImpl(Locale locale);
-}
+ }
/*
* Obtain the real SPI implementation, using locale fallback
@@ -119,7 +137,7 @@
@Override
public void addImpl(BreakIteratorProvider impl) {
for (Locale l : impl.getAvailableLocales()) {
- map.put(l, impl);
+ map.putIfAbsent(l, impl);
}
}
@@ -174,7 +192,7 @@
@Override
public void addImpl(CollatorProvider impl) {
for (Locale l : impl.getAvailableLocales()) {
- map.put(l, impl);
+ map.putIfAbsent(l, impl);
}
}
@@ -208,7 +226,7 @@
@Override
public void addImpl(DateFormatProvider impl) {
for (Locale l : impl.getAvailableLocales()) {
- map.put(l, impl);
+ map.putIfAbsent(l, impl);
}
}
@@ -256,7 +274,7 @@
@Override
public void addImpl(DateFormatSymbolsProvider impl) {
for (Locale l : impl.getAvailableLocales()) {
- map.put(l, impl);
+ map.putIfAbsent(l, impl);
}
}
@@ -290,7 +308,7 @@
@Override
public void addImpl(DecimalFormatSymbolsProvider impl) {
for (Locale l : impl.getAvailableLocales()) {
- map.put(l, impl);
+ map.putIfAbsent(l, impl);
}
}
@@ -324,7 +342,7 @@
@Override
public void addImpl(NumberFormatProvider impl) {
for (Locale l : impl.getAvailableLocales()) {
- map.put(l, impl);
+ map.putIfAbsent(l, impl);
}
}
@@ -379,7 +397,7 @@
@Override
public void addImpl(CalendarDataProvider impl) {
for (Locale l : impl.getAvailableLocales()) {
- map.put(l, impl);
+ map.putIfAbsent(l, impl);
}
}
@@ -411,12 +429,39 @@
assert cdp != null;
return cdp.getMinimalDaysInFirstWeek(locale);
}
+ }
+
+ static class CalendarNameProviderDelegate extends CalendarNameProvider
+ implements Delegate<CalendarNameProvider> {
+ private ConcurrentMap<Locale, CalendarNameProvider> map = new ConcurrentHashMap<>();
+
+ @Override
+ public void addImpl(CalendarNameProvider impl) {
+ for (Locale l : impl.getAvailableLocales()) {
+ map.putIfAbsent(l, impl);
+ }
+ }
+
+ @Override
+ public CalendarNameProvider getImpl(Locale locale) {
+ return SPILocaleProviderAdapter.getImpl(map, locale);
+ }
+
+ @Override
+ public Locale[] getAvailableLocales() {
+ return map.keySet().toArray(new Locale[0]);
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ return map.containsKey(locale);
+ }
@Override
public String getDisplayName(String calendarType,
int field, int value,
int style, Locale locale) {
- CalendarDataProvider cdp = getImpl(locale);
+ CalendarNameProvider cdp = getImpl(locale);
assert cdp != null;
return cdp.getDisplayName(calendarType, field, value, style, locale);
}
@@ -425,7 +470,7 @@
public Map<String, Integer> getDisplayNames(String calendarType,
int field, int style,
Locale locale) {
- CalendarDataProvider cdp = getImpl(locale);
+ CalendarNameProvider cdp = getImpl(locale);
assert cdp != null;
return cdp.getDisplayNames(calendarType, field, style, locale);
}
@@ -438,7 +483,7 @@
@Override
public void addImpl(CurrencyNameProvider impl) {
for (Locale l : impl.getAvailableLocales()) {
- map.put(l, impl);
+ map.putIfAbsent(l, impl);
}
}
@@ -479,7 +524,7 @@
@Override
public void addImpl(LocaleNameProvider impl) {
for (Locale l : impl.getAvailableLocales()) {
- map.put(l, impl);
+ map.putIfAbsent(l, impl);
}
}
@@ -534,7 +579,7 @@
@Override
public void addImpl(TimeZoneNameProvider impl) {
for (Locale l : impl.getAvailableLocales()) {
- map.put(l, impl);
+ map.putIfAbsent(l, impl);
}
}
--- a/jdk/src/share/native/sun/security/jgss/wrapper/GSSLibStub.c Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/native/sun/security/jgss/wrapper/GSSLibStub.c Fri Nov 30 17:09:05 2012 -0800
@@ -571,7 +571,7 @@
*/
void inquireCred(JNIEnv *env, jobject jobj, gss_cred_id_t pCred,
jint type, void *result) {
- OM_uint32 minor, major=GSS_C_QOP_DEFAULT;
+ OM_uint32 minor, major=0;
OM_uint32 routineErr;
gss_cred_id_t credHdl;
--- a/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_mutex.c Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_mutex.c Fri Nov 30 17:09:05 2012 -0800
@@ -112,22 +112,34 @@
ckpInitArgs->UnlockMutex = NULL_PTR;
#else
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "CreateMutex", "Lsun/security/pkcs11/wrapper/CK_CREATEMUTEX;");
- if (fieldID == NULL) { return NULL; }
+ if (fieldID == NULL) {
+ free(ckpInitArgs);
+ return NULL;
+ }
jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
ckpInitArgs->CreateMutex = (jMutexHandler != NULL) ? &callJCreateMutex : NULL_PTR;
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "DestroyMutex", "Lsun/security/pkcs11/wrapper/CK_DESTROYMUTEX;");
- if (fieldID == NULL) { return NULL; }
+ if (fieldID == NULL) {
+ free(ckpInitArgs);
+ return NULL;
+ }
jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
ckpInitArgs->DestroyMutex = (jMutexHandler != NULL) ? &callJDestroyMutex : NULL_PTR;
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "LockMutex", "Lsun/security/pkcs11/wrapper/CK_LOCKMUTEX;");
- if (fieldID == NULL) { return NULL; }
+ if (fieldID == NULL) {
+ free(ckpInitArgs);
+ return NULL;
+ }
jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
ckpInitArgs->LockMutex = (jMutexHandler != NULL) ? &callJLockMutex : NULL_PTR;
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "UnlockMutex", "Lsun/security/pkcs11/wrapper/CK_UNLOCKMUTEX;");
- if (fieldID == NULL) { return NULL; }
+ if (fieldID == NULL) {
+ free(ckpInitArgs);
+ return NULL;
+ }
jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
ckpInitArgs->UnlockMutex = (jMutexHandler != NULL) ? &callJUnlockMutex : NULL_PTR;
@@ -151,13 +163,19 @@
/* convert and set the flags field */
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "flags", "J");
- if (fieldID == NULL) { return NULL; }
+ if (fieldID == NULL) {
+ free(ckpInitArgs);
+ return NULL;
+ }
jFlags = (*env)->GetLongField(env, jInitArgs, fieldID);
ckpInitArgs->flags = jLongToCKULong(jFlags);
/* pReserved should be NULL_PTR in this version */
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "pReserved", "Ljava/lang/Object;");
- if (fieldID == NULL) { return NULL; }
+ if (fieldID == NULL) {
+ free(ckpInitArgs);
+ return NULL;
+ }
jReserved = (*env)->GetObjectField(env, jInitArgs, fieldID);
/* we try to convert the reserved parameter also */
--- a/jdk/src/solaris/bin/java_md_solinux.c Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/solaris/bin/java_md_solinux.c Fri Nov 30 17:09:05 2012 -0800
@@ -478,9 +478,11 @@
JLI_TraceLauncher("mustsetenv: %s\n", mustsetenv ? "TRUE" : "FALSE");
if (mustsetenv == JNI_FALSE) {
+ JLI_MemFree(newargv);
return;
}
#else
+ JLI_MemFree(newargv);
return;
#endif /* SETENV_REQUIRED */
} else { /* do the same speculatively or exit */
--- a/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java Fri Nov 30 17:09:05 2012 -0800
@@ -27,7 +27,6 @@
import java.awt.*;
import java.awt.geom.*;
-
import sun.awt.SunToolkit;
import sun.java2d.SunGraphics2D;
import sun.java2d.loops.*;
@@ -39,6 +38,9 @@
import sun.java2d.pipe.ShapeSpanIterator;
import sun.java2d.pipe.LoopPipe;
+import static sun.java2d.xr.XRUtils.clampToShort;
+import static sun.java2d.xr.XRUtils.clampToUShort;
+
/**
* XRender provides only accalerated rectangles. To emulate higher "order"
* geometry we have to pass everything else to DoPath/FillSpans.
@@ -70,17 +72,16 @@
public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2) {
Region compClip = sg2d.getCompClip();
- int transX1 = x1 + sg2d.transX;
- int transY1 = y1 + sg2d.transY;
- int transX2 = x2 + sg2d.transX;
- int transY2 = y2 + sg2d.transY;
+ int transX1 = Region.clipAdd(x1, sg2d.transX);
+ int transY1 = Region.clipAdd(y1, sg2d.transY);
+ int transX2 = Region.clipAdd(x2, sg2d.transX);
+ int transY2 = Region.clipAdd(y2, sg2d.transY);
// Non clipped fast path
if (compClip.contains(transX1, transY1)
&& compClip.contains(transX2, transY2)) {
+ SunToolkit.awtLock();
try {
- SunToolkit.awtLock();
-
validateSurface(sg2d);
tileManager.addLine(transX1, transY1, transX2, transY2);
tileManager.fillMask((XRSurfaceData) sg2d.surfaceData);
@@ -115,20 +116,40 @@
draw(sg2d, new Polygon(xpoints, ypoints, npoints));
}
- public synchronized void fillRect(SunGraphics2D sg2d,
- int x, int y, int width, int height) {
+ public void fillRect(SunGraphics2D sg2d, int x, int y, int width, int height) {
+ x = Region.clipAdd(x, sg2d.transX);
+ y = Region.clipAdd(y, sg2d.transY);
+
+ /*
+ * Limit x/y to signed short, width/height to unsigned short,
+ * to match the X11 coordinate limits for rectangles.
+ * Correct width/height in case x/y have been modified by clipping.
+ */
+ if (x > Short.MAX_VALUE || y > Short.MAX_VALUE) {
+ return;
+ }
+
+ int x2 = Region.dimAdd(x, width);
+ int y2 = Region.dimAdd(y, height);
+
+ if (x2 < Short.MIN_VALUE || y2 < Short.MIN_VALUE) {
+ return;
+ }
+
+ x = clampToShort(x);
+ y = clampToShort(y);
+ width = clampToUShort(x2 - x);
+ height = clampToUShort(y2 - y);
+
+ if (width == 0 || height == 0) {
+ return;
+ }
+
SunToolkit.awtLock();
try {
validateSurface(sg2d);
-
- XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData;
-
- x += sg2d.transform.getTranslateX();
- y += sg2d.transform.getTranslateY();
-
tileManager.addRect(x, y, width, height);
- tileManager.fillMask(xrsd);
-
+ tileManager.fillMask((XRSurfaceData) sg2d.surfaceData);
} finally {
SunToolkit.awtUnlock();
}
--- a/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java Fri Nov 30 17:09:05 2012 -0800
@@ -255,7 +255,7 @@
: (x < Short.MIN_VALUE ? Short.MIN_VALUE : x));
}
- public static short clampToUShort(int x) {
- return (short) (x > 65535 ? 65535 : (x < 0) ? 0 : x);
+ public static int clampToUShort(int x) {
+ return (x > 65535 ? 65535 : (x < 0) ? 0 : x);
}
}
--- a/jdk/src/solaris/native/java/lang/java_props_macosx.c Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/solaris/native/java/lang/java_props_macosx.c Fri Nov 30 17:09:05 2012 -0800
@@ -145,27 +145,22 @@
return pref = HToolkit;
}
-void setUnknownOSAndVersion(java_props_t *sprops) {
- sprops->os_name = strdup("Unknown");
- sprops->os_version = strdup("Unknown");
-}
+void setOSNameAndVersion(java_props_t *sprops) {
+ /* Don't rely on JRSCopyOSName because there's no guarantee the value will
+ * remain the same, or even if the JRS functions will continue to be part of
+ * Mac OS X. So hardcode os_name, and fill in os_version if we can.
+ */
+ sprops->os_name = strdup("Mac OS X");
-void setOSNameAndVersion(java_props_t *sprops) {
void *jrsFwk = getJRSFramework();
- if (jrsFwk == NULL) {
- setUnknownOSAndVersion(sprops);
- return;
+ if (jrsFwk != NULL) {
+ char *(*copyOSVersion)() = dlsym(jrsFwk, "JRSCopyOSVersion");
+ if (copyOSVersion != NULL) {
+ sprops->os_version = copyOSVersion();
+ return;
+ }
}
-
- char *(*copyOSName)() = dlsym(jrsFwk, "JRSCopyOSName");
- char *(*copyOSVersion)() = dlsym(jrsFwk, "JRSCopyOSVersion");
- if (copyOSName == NULL || copyOSVersion == NULL) {
- setUnknownOSAndVersion(sprops);
- return;
- }
-
- sprops->os_name = copyOSName();
- sprops->os_version = copyOSVersion();
+ sprops->os_version = strdup("Unknown");
}
--- a/jdk/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/src/windows/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,7 +25,12 @@
package sun.util.locale.provider;
import java.lang.ref.SoftReference;
-import java.text.*;
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
import java.text.spi.DateFormatProvider;
import java.text.spi.DateFormatSymbolsProvider;
import java.text.spi.DecimalFormatSymbolsProvider;
@@ -34,12 +39,13 @@
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
+import java.util.ResourceBundle.Control;
import java.util.Set;
-import java.util.ResourceBundle.Control;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.spi.CalendarDataProvider;
+import java.util.spi.CalendarNameProvider;
/**
* LocaleProviderdapter implementation for the Windows locale data.
@@ -88,7 +94,7 @@
private static final Set<Locale> supportedLocaleSet;
static {
- Set<Locale> tmpSet = new HashSet<Locale>();
+ Set<Locale> tmpSet = new HashSet<>();
if (initialize()) {
// Assuming the default locales do not include any extensions, so
// no stripping is needed here.
@@ -258,7 +264,7 @@
if (ref == null || (patterns = ref.get()) == null) {
String langtag = locale.toLanguageTag();
- patterns = new AtomicReferenceArray<String>(NF_MAX+1);
+ patterns = new AtomicReferenceArray<>(NF_MAX+1);
for (int i = 0; i <= NF_MAX; i++) {
patterns.compareAndSet(i, null, getNumberPattern(i, langtag));
}
@@ -330,18 +336,6 @@
}
@Override
- public String getDisplayName(String calType, int field, int value,
- int style, Locale locale) {
- return null;
- }
-
- @Override
- public Map<String, Integer> getDisplayNames(String calType,
- int field, int style, Locale locale) {
- return null;
- }
-
- @Override
public int getFirstDayOfWeek(Locale locale) {
int first = getCalendarDataValue(
removeExtensions(locale).toLanguageTag(),
@@ -360,6 +354,32 @@
};
}
+ public static CalendarNameProvider getCalendarNameProvider() {
+ return new CalendarNameProvider() {
+ @Override
+ public Locale[] getAvailableLocales() {
+ return getSupportedCalendarLocales();
+ }
+
+ @Override
+ public boolean isSupportedLocale(Locale locale) {
+ return isSupportedCalendarLocale(locale);
+ }
+
+ @Override
+ public String getDisplayName(String calType, int field, int value,
+ int style, Locale locale) {
+ return null;
+ }
+
+ @Override
+ public Map<String, Integer> getDisplayNames(String calType,
+ int field, int style, Locale locale) {
+ return null;
+ }
+ };
+ }
+
private static String convertDateTimePattern(String winPattern) {
String ret = winPattern.replaceAll("dddd", "EEEE");
ret = ret.replaceAll("ddd", "EEE");
--- a/jdk/test/ProblemList.txt Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/test/ProblemList.txt Fri Nov 30 17:09:05 2012 -0800
@@ -148,9 +148,6 @@
# 6959636
javax/management/loading/LibraryLoader/LibraryLoaderTest.java windows-all
-# 7144846
-javax/management/remote/mandatory/connection/ReconnectTest.java generic-all
-
# 7120365
javax/management/remote/mandatory/notif/DiffHBTest.java generic-all
@@ -376,6 +373,9 @@
# Filed 6772009
java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java generic-all
+# 8003596
+java/util/logging/CheckLockLocationTest.java windows-all
+
# 7041639, Solaris DSA keypair generation bug
java/util/TimeZone/TimeZoneDatePermissionCheck.sh solaris-all
--- a/jdk/test/TEST.ROOT Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/test/TEST.ROOT Fri Nov 30 17:09:05 2012 -0800
@@ -9,4 +9,4 @@
othervm.dirs=java/awt java/beans java/rmi javax/accessibility javax/imageio javax/sound javax/print javax/management com/sun/awt sun/awt sun/java2d sun/pisces sun/rmi
# Tests that cannot run concurrently
-exclusiveAccess.dirs=java/rmi/Naming sun/management/jmxremote sun/tools/jstatd
+exclusiveAccess.dirs=java/rmi/Naming java/util/prefs sun/management/jmxremote sun/tools/jstatd sun/security/mscapi
--- a/jdk/test/java/lang/HashCode.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/test/java/lang/HashCode.java Fri Nov 30 17:09:05 2012 -0800
@@ -23,18 +23,20 @@
/*
* @test
- * @bug 4245470
+ * @bug 4245470 7088913
* @summary Test the primitive wrappers hashCode()
*/
+import java.util.Objects;
import java.util.Random;
public class HashCode {
final Random rnd = new Random();
- void test(String args[]) throws Exception {
- int[] ints = {
+ void testOrdinals(String args[]) throws Exception {
+ long[] longs = {
+ Long.MIN_VALUE,
Integer.MIN_VALUE,
Short.MIN_VALUE,
Character.MIN_VALUE,
@@ -44,20 +46,73 @@
Character.MAX_VALUE,
Short.MAX_VALUE,
Integer.MAX_VALUE,
+ Long.MAX_VALUE,
rnd.nextInt(),
};
- for (int x : ints) {
+ for (long x : longs) {
check( new Long(x).hashCode() == (int)((long)x ^ (long)x>>>32));
check(Long.valueOf(x).hashCode() == (int)((long)x ^ (long)x>>>32));
- check( new Integer(x).hashCode() == x);
- check(Integer.valueOf(x).hashCode() == x);
+ check( (new Long(x)).hashCode() == Long.hashCode(x));
+ check( new Integer((int)x).hashCode() == (int) x);
+ check(Integer.valueOf((int)x).hashCode() == (int) x);
+ check( (new Integer((int)x)).hashCode() == Integer.hashCode((int)x));
check( new Short((short)x).hashCode() == (short) x);
check(Short.valueOf((short)x).hashCode() == (short) x);
+ check( (new Short((short)x)).hashCode() == Short.hashCode((short)x));
check( new Character((char) x).hashCode() == (char) x);
check(Character.valueOf((char) x).hashCode() == (char) x);
+ check( (new Character((char)x)).hashCode() == Character.hashCode((char)x));
check( new Byte((byte) x).hashCode() == (byte) x);
check(Byte.valueOf((byte) x).hashCode() == (byte) x);
+ check( (new Byte((byte)x)).hashCode() == Byte.hashCode((byte)x));
+ }
+ }
+
+ void testBoolean() {
+ check( Boolean.FALSE.hashCode() == 1237);
+ check( Boolean.TRUE.hashCode() == 1231);
+ check( Boolean.valueOf(false).hashCode() == 1237);
+ check( Boolean.valueOf(true).hashCode() == 1231);
+ check( (new Boolean(false)).hashCode() == 1237);
+ check( (new Boolean(true)).hashCode() == 1231);
+ check( Boolean.hashCode(false) == 1237);
+ check( Boolean.hashCode(true) == 1231);
+ }
+
+ void testFloat() {
+ float[] floats = {
+ Float.NaN,
+ Float.NEGATIVE_INFINITY,
+ -1f,
+ 0f,
+ 1f,
+ Float.POSITIVE_INFINITY
+ };
+
+ for(float f : floats) {
+ check( Float.hashCode(f) == Float.floatToIntBits(f));
+ check( Float.valueOf(f).hashCode() == Float.floatToIntBits(f));
+ check( (new Float(f)).hashCode() == Float.floatToIntBits(f));
+ }
+ }
+
+ void testDouble() {
+ double[] doubles = {
+ Double.NaN,
+ Double.NEGATIVE_INFINITY,
+ -1f,
+ 0f,
+ 1f,
+ Double.POSITIVE_INFINITY
+ };
+
+ for(double d : doubles) {
+ long bits = Double.doubleToLongBits(d);
+ int bitsHash = (int)(bits^(bits>>>32));
+ check( Double.hashCode(d) == bitsHash);
+ check( Double.valueOf(d).hashCode() == bitsHash);
+ check( (new Double(d)).hashCode() == bitsHash);
}
}
@@ -69,12 +124,16 @@
void unexpected(Throwable t) {failed++; t.printStackTrace();}
void check(boolean cond) {if (cond) pass(); else fail();}
void equal(Object x, Object y) {
- if (x == null ? y == null : x.equals(y)) pass();
+ if (Objects.equals(x,y)) pass();
else fail(x + " not equal to " + y);}
public static void main(String[] args) throws Throwable {
new HashCode().instanceMain(args);}
public void instanceMain(String[] args) throws Throwable {
- try {test(args);} catch (Throwable t) {unexpected(t);}
+ try { testOrdinals(args);
+ testBoolean();
+ testFloat();
+ testDouble();
+ } catch (Throwable t) {unexpected(t);}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
}
--- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Unbounded.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Unbounded.java Fri Nov 30 17:09:05 2012 -0800
@@ -36,6 +36,12 @@
// number of concurrent completion handlers
static final int CONCURRENCY_COUNT = 256;
+ // set to true if an I/O operation fails
+ static volatile boolean failed;
+
+ // set to true when the test is done
+ static volatile boolean finished;
+
public static void main(String[] args) throws Exception {
// all accepted connections are added to a queue
final ArrayBlockingQueue<AsynchronousSocketChannel> queue =
@@ -51,6 +57,10 @@
listener.accept((Void)null, this);
}
public void failed(Throwable exc, Void att) {
+ if (!finished) {
+ failed = true;
+ System.err.println("accept failed: " + exc);
+ }
}
});
System.out.println("Listener created.");
@@ -94,6 +104,9 @@
}
}
public void failed(Throwable exc, AsynchronousSocketChannel ch) {
+ failed = true;
+ System.err.println("read failed: " + exc);
+ completed(0, ch);
}
});
}
@@ -104,6 +117,7 @@
while (remaining > 0) {
AsynchronousSocketChannel ch = queue.take();
ch.write(ByteBuffer.wrap("welcome".getBytes())).get();
+ ch.shutdownOutput();
ch.close();
remaining--;
}
@@ -111,6 +125,11 @@
// wait for all threads to reach the barrier
System.out.println("Waiting for all threads to reach barrier");
barrier.await();
+
+ // finish up
+ finished = true;
listener.close();
+ if (failed)
+ throw new RuntimeException("I/O operation failed, see log for details");
}
}
--- a/jdk/test/java/util/PluggableLocale/CalendarDataProviderTest.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/test/java/util/PluggableLocale/CalendarDataProviderTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -36,17 +36,11 @@
*
* Test strategy:
* com.bar.CalendarDataProviderImpl supports only ja_JP_kids locale. It returns
- * month names only in full-width digits, followed by "gatsu" in Hiragana if
- * it's a long style, and also returns unusual week parameter values, WEDNESDAY
- * - first day of week, 7 - minimal days in the first week. The standalone
- * styles are used because DateFormatSymbols has precedence for the format
- * styles.
+ * unusual week parameter values, WEDNESDAY - first day of week, 7 - minimal
+ * days in the first week.
*
* A Calendar instance created with ja_JP_kids should use the week parameters
- * provided by com.bar.CalendarDataProviderImpl. Calendar.getDisplayName(s)
- * should be called with kids to get the month names provided by
- * com.bar.CalendarDataProviderImpl. Other display names should be the same as
- * what a Calendar constructed with ja_JP returns.
+ * provided by com.bar.CalendarDataProviderImpl.
*/
public class CalendarDataProviderTest {
@@ -62,45 +56,6 @@
// check the week parameters
checkResult("firstDayOfWeek", kcal.getFirstDayOfWeek(), WEDNESDAY);
checkResult("minimalDaysInFirstWeek", kcal.getMinimalDaysInFirstWeek(), 7);
-
- // check month names and week day names
- Map<String, Integer> mapAllStyles = new HashMap<>();
- for (int style : new int[] { SHORT_STANDALONE, LONG_STANDALONE }) {
- // Check month names provided by com.bar.CalendarDataProviderImpl
- Map<String, Integer> map = new HashMap<>();
- for (int month = JANUARY; month <= DECEMBER; month++) {
- kcal.set(DAY_OF_MONTH, 1);
- kcal.set(MONTH, month);
- kcal.set(HOUR_OF_DAY, 12); // avoid any standard-daylight transitions...
- kcal.getTimeInMillis();
- String name = kcal.getDisplayName(MONTH, style, kids);
- checkResult("Month name",
- name,
- CalendarDataProviderImpl.toMonthName(kcal.get(MONTH) + 1, style));
-
- // Builds the map with name to its integer value.
- map.put(name, kcal.get(MONTH));
- }
- checkResult((style == SHORT_STANDALONE ? "Short" : "Long") + " month names map",
- kcal.getDisplayNames(MONTH, style, kids), map);
- mapAllStyles.putAll(map);
- if (style == LONG_STANDALONE) {
- checkResult("Short and long month names map",
- kcal.getDisplayNames(MONTH, ALL_STYLES, kids), mapAllStyles);
- }
-
- // Check week names: kcal and jcal should return the same names and maps.
- for (int dow = SUNDAY; dow <= SATURDAY; dow++) {
- kcal.set(DAY_OF_WEEK, dow);
- jcal.setTimeInMillis(kcal.getTimeInMillis());
- String name = kcal.getDisplayName(DAY_OF_WEEK, style, kids);
- checkResult("Day of week name", name,
- jcal.getDisplayName(DAY_OF_WEEK, style, Locale.JAPAN));
- }
- checkResult("Short day of week names", kcal.getDisplayNames(DAY_OF_WEEK, style, kids),
- jcal.getDisplayNames(DAY_OF_WEEK, style, Locale.JAPAN));
- }
-
}
private <T> void checkResult(String msg, T got, T expected) {
--- a/jdk/test/java/util/PluggableLocale/CalendarDataProviderTest.sh Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/test/java/util/PluggableLocale/CalendarDataProviderTest.sh Fri Nov 30 17:09:05 2012 -0800
@@ -23,6 +23,6 @@
#!/bin/sh
#
# @test
-# @bug 7058206
+# @bug 7058207 8000986
# @summary CalendarDataProvider tests
# @run shell ExecTest.sh bar CalendarDataProviderTest true
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/PluggableLocale/CalendarNameProviderTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2012, 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.text.*;
+import java.util.*;
+import static java.util.Calendar.*;
+import sun.util.locale.provider.*;
+import sun.util.resources.*;
+import com.bar.CalendarNameProviderImpl;
+
+/**
+ * Test case for CalendarNameProvider.
+ *
+ * Test strategy:
+ * com.bar.CalendarNameProviderImpl supports only ja_JP_kids locale. It returns
+ * month names only in full-width digits, followed by "gatsu" in Hiragana if
+ * it's a long style. The standalone styles are used because DateFormatSymbols
+ * has precedence for the format styles.
+ *
+ * Calendar.getDisplayName(s) should be called with kids to get the month
+ * names provided by com.bar.CalendarNameProviderImpl. Other display names
+ * should be the same as what a Calendar constructed with ja_JP returns.
+ */
+public class CalendarNameProviderTest {
+
+ public static void main(String[] s) {
+ new CalendarNameProviderTest().test();
+ }
+
+ void test() {
+ Locale kids = new Locale("ja", "JP", "kids"); // test provider's supported locale
+ Calendar kcal = Calendar.getInstance(kids);
+ Calendar jcal = Calendar.getInstance(Locale.JAPAN);
+
+ // check month names and week day names
+ Map<String, Integer> mapAllStyles = new HashMap<>();
+ for (int style : new int[] { SHORT_STANDALONE, LONG_STANDALONE }) {
+ // Check month names provided by com.bar.CalendarNameProviderImpl
+ Map<String, Integer> map = new HashMap<>();
+ for (int month = JANUARY; month <= DECEMBER; month++) {
+ kcal.set(DAY_OF_MONTH, 1);
+ kcal.set(MONTH, month);
+ kcal.set(HOUR_OF_DAY, 12); // avoid any standard-daylight transitions...
+ kcal.getTimeInMillis();
+ String name = kcal.getDisplayName(MONTH, style, kids);
+ checkResult("Month name",
+ name,
+ CalendarNameProviderImpl.toMonthName(kcal.get(MONTH) + 1, style));
+
+ // Builds the map with name to its integer value.
+ map.put(name, kcal.get(MONTH));
+ }
+ checkResult((style == SHORT_STANDALONE ? "Short" : "Long") + " month names map",
+ kcal.getDisplayNames(MONTH, style, kids), map);
+ mapAllStyles.putAll(map);
+ if (style == LONG_STANDALONE) {
+ checkResult("Short and long month names map",
+ kcal.getDisplayNames(MONTH, ALL_STYLES, kids), mapAllStyles);
+ }
+
+ // Check week names: kcal and jcal should return the same names and maps.
+ for (int dow = SUNDAY; dow <= SATURDAY; dow++) {
+ kcal.set(DAY_OF_WEEK, dow);
+ jcal.setTimeInMillis(kcal.getTimeInMillis());
+ String name = kcal.getDisplayName(DAY_OF_WEEK, style, kids);
+ checkResult("Day of week name", name,
+ jcal.getDisplayName(DAY_OF_WEEK, style, Locale.JAPAN));
+ }
+ checkResult("Short day of week names", kcal.getDisplayNames(DAY_OF_WEEK, style, kids),
+ jcal.getDisplayNames(DAY_OF_WEEK, style, Locale.JAPAN));
+ }
+
+ }
+
+ private <T> void checkResult(String msg, T got, T expected) {
+ if (!expected.equals(got)) {
+ String s = String.format("%s: got='%s', expected='%s'", msg, got, expected);
+ throw new RuntimeException(s);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/PluggableLocale/CalendarNameProviderTest.sh Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2012, 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 8000986
+# @summary CalendarNameProvider tests
+# @run shell ExecTest.sh bar CalendarNameProviderTest true
--- a/jdk/test/java/util/PluggableLocale/CurrencyNameProviderTest.sh Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/test/java/util/PluggableLocale/CurrencyNameProviderTest.sh Fri Nov 30 17:09:05 2012 -0800
@@ -23,6 +23,6 @@
#!/bin/sh
#
# @test
-# @bug 4052440 8000997
+# @bug 4052440 7199750 8000997
# @summary CurrencyNameProvider tests
# @run shell ExecTest.sh bar CurrencyNameProviderTest true
--- a/jdk/test/java/util/PluggableLocale/GenericTest.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/test/java/util/PluggableLocale/GenericTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -42,6 +42,7 @@
com.bar.LocaleNameProviderImpl localeNP = new com.bar.LocaleNameProviderImpl();
com.bar.TimeZoneNameProviderImpl tzNP = new com.bar.TimeZoneNameProviderImpl();
com.bar.CalendarDataProviderImpl calDataP = new com.bar.CalendarDataProviderImpl();
+ com.bar.CalendarNameProviderImpl calNameP = new com.bar.CalendarNameProviderImpl();
public static void main(String[] s) {
new GenericTest();
@@ -73,6 +74,7 @@
expected.addAll(Arrays.asList(localeNP.getAvailableLocales()));
expected.addAll(Arrays.asList(tzNP.getAvailableLocales()));
expected.addAll(Arrays.asList(calDataP.getAvailableLocales()));
+ expected.addAll(Arrays.asList(calNameP.getAvailableLocales()));
if (!result.equals(expected)) {
throw new RuntimeException("Locale.getAvailableLocales() does not return the union of locales: diff="
+ getDiff(result, expected));
Binary file jdk/test/java/util/PluggableLocale/barprovider.jar has changed
Binary file jdk/test/java/util/PluggableLocale/fooprovider.jar has changed
--- a/jdk/test/java/util/PluggableLocale/providersrc/CalendarDataProviderImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/test/java/util/PluggableLocale/providersrc/CalendarDataProviderImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -48,65 +48,7 @@
}
@Override
- public String getDisplayName(String calendarType, int field, int value, int style, Locale locale) {
- if (calendarType == null || locale == null) {
- throw new NullPointerException();
- }
- if (!Utils.supportsLocale(Arrays.asList(avail), locale)) {
- throw new IllegalArgumentException("locale is not one of available locales: "+ locale);
- }
- if (field != MONTH) {
- return null;
- }
- return toMonthName(value + 1, style);
- }
-
- @Override
- public Map<String, Integer> getDisplayNames(String calendarType, int field, int style, Locale locale) {
- if (calendarType == null || locale == null) {
- throw new NullPointerException();
- }
- if (!Utils.supportsLocale(Arrays.asList(avail), locale)) {
- throw new IllegalArgumentException("locale is not one of available locales: " + locale);
- }
- if (field != MONTH) {
- return null;
- }
- Map<String, Integer> map = new HashMap<>();
- if (style == LONG_STANDALONE) {
- style = LONG;
- } else if (style == SHORT_STANDALONE) {
- style = SHORT;
- }
- for (int month = JANUARY; month <= DECEMBER; month++) {
- if (style == ALL_STYLES || style == LONG) {
- map.put(toMonthName(month + 1, LONG), month);
- }
- if (style == ALL_STYLES || style == SHORT) {
- map.put(toMonthName(month + 1, SHORT), month);
- }
- }
- return map;
- }
-
- @Override
public Locale[] getAvailableLocales() {
return avail.clone();
}
-
- // month is 1-based.
- public static String toMonthName(int month, int style) {
- StringBuilder sb = new StringBuilder();
- if (month >= 10) {
- sb.append((char)(FULLWIDTH_ZERO + 1));
- sb.appendCodePoint((char)(FULLWIDTH_ZERO + (month % 10)));
- } else {
- sb.appendCodePoint((char)(FULLWIDTH_ZERO + month));
- }
- if (style == SHORT || style == SHORT_STANDALONE) {
- return sb.toString(); // full-width digit(s)
- }
- sb.append("\u304c\u3064"); // + "gatsu" in Hiragana
- return sb.toString();
- }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/PluggableLocale/providersrc/CalendarNameProviderImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+package com.bar;
+
+import com.foobar.Utils;
+import java.util.Arrays;
+import static java.util.Calendar.*;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.spi.CalendarNameProvider;
+
+public class CalendarNameProviderImpl extends CalendarNameProvider {
+ static final char FULLWIDTH_ZERO = '\uff10';
+ static final Locale[] avail = {
+ new Locale("ja", "JP", "kids"),
+ };
+
+ @Override
+ public String getDisplayName(String calendarType, int field, int value, int style, Locale locale) {
+ if (calendarType == null || locale == null) {
+ throw new NullPointerException();
+ }
+ if (!Utils.supportsLocale(Arrays.asList(avail), locale)) {
+ throw new IllegalArgumentException("locale is not one of available locales: "+ locale);
+ }
+ if (field != MONTH) {
+ return null;
+ }
+ return toMonthName(value + 1, style);
+ }
+
+ @Override
+ public Map<String, Integer> getDisplayNames(String calendarType, int field, int style, Locale locale) {
+ if (calendarType == null || locale == null) {
+ throw new NullPointerException();
+ }
+ if (!Utils.supportsLocale(Arrays.asList(avail), locale)) {
+ throw new IllegalArgumentException("locale is not one of available locales: " + locale);
+ }
+ if (field != MONTH) {
+ return null;
+ }
+ Map<String, Integer> map = new HashMap<>();
+ if (style == LONG_STANDALONE) {
+ style = LONG;
+ } else if (style == SHORT_STANDALONE) {
+ style = SHORT;
+ }
+ for (int month = JANUARY; month <= DECEMBER; month++) {
+ if (style == ALL_STYLES || style == LONG) {
+ map.put(toMonthName(month + 1, LONG), month);
+ }
+ if (style == ALL_STYLES || style == SHORT) {
+ map.put(toMonthName(month + 1, SHORT), month);
+ }
+ }
+ return map;
+ }
+
+ @Override
+ public Locale[] getAvailableLocales() {
+ return avail.clone();
+ }
+
+ // month is 1-based.
+ public static String toMonthName(int month, int style) {
+ StringBuilder sb = new StringBuilder();
+ if (month >= 10) {
+ sb.append((char)(FULLWIDTH_ZERO + 1));
+ sb.appendCodePoint((char)(FULLWIDTH_ZERO + (month % 10)));
+ } else {
+ sb.appendCodePoint((char)(FULLWIDTH_ZERO + month));
+ }
+ if (style == SHORT || style == SHORT_STANDALONE) {
+ return sb.toString(); // full-width digit(s)
+ }
+ sb.append("\u304c\u3064"); // + "gatsu" in Hiragana
+ return sb.toString();
+ }
+}
--- a/jdk/test/java/util/PluggableLocale/providersrc/CurrencyNameProviderImpl2.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/test/java/util/PluggableLocale/providersrc/CurrencyNameProviderImpl2.java Fri Nov 30 17:09:05 2012 -0800
@@ -32,7 +32,8 @@
import com.foobar.Utils;
public class CurrencyNameProviderImpl2 extends CurrencyNameProvider {
- static Locale[] avail = {new Locale("ja", "JP", "tokyo")};
+ static Locale[] avail = {new Locale("ja", "JP", "tokyo"),
+ new Locale("ja", "JP", "osaka"), };
public Locale[] getAvailableLocales() {
return avail;
}
@@ -43,8 +44,12 @@
throw new IllegalArgumentException("locale is not supported: "+locale);
}
- if (c.equals("JPY") && Utils.supportsLocale(avail[0], locale)) {
- return "JPY-tokyo";
+ if (c.equals("JPY")) {
+ if (Utils.supportsLocale(avail[0], locale)) {
+ return "JPY-tokyo";
+ } else if (Utils.supportsLocale(avail[1], locale)) {
+ return "JPY-osaka";
+ }
}
return null;
}
@@ -55,8 +60,12 @@
throw new IllegalArgumentException("locale is not supported: "+locale);
}
- if (c.equals("JPY") && Utils.supportsLocale(avail[0], locale)) {
- return "JPY-tokyo";
+ if (c.equals("JPY")) {
+ if (Utils.supportsLocale(avail[0], locale)) {
+ return "JPY-tokyo";
+ } else if (Utils.supportsLocale(avail[1], locale)) {
+ return "JPY-osaka";
+ }
}
return null;
}
--- a/jdk/test/java/util/PluggableLocale/providersrc/Makefile Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/test/java/util/PluggableLocale/providersrc/Makefile Fri Nov 30 17:09:05 2012 -0800
@@ -20,7 +20,8 @@
java.util.spi.CurrencyNameProvider \
java.util.spi.TimeZoneNameProvider \
java.util.spi.LocaleNameProvider \
- java.util.spi.CalendarDataProvider
+ java.util.spi.CalendarDataProvider \
+ java.util.spi.CalendarNameProvider
FOOFILES_JAVA = \
BreakIteratorProviderImpl.java \
@@ -39,6 +40,7 @@
TimeZoneNameProviderImpl.java \
LocaleNameProviderImpl.java \
CalendarDataProviderImpl.java \
+ CalendarNameProviderImpl.java \
Utils.java
BARFILES_PROPERTIES = \
@@ -68,3 +70,8 @@
cp $(BARFILES_PROPERTIES) $(BARDIR)/com/bar
rm -f $(DESTDIR)/barprovider.jar
$(BINDIR)/jar cvf $(DESTDIR)/barprovider.jar -C $(BARDIR) .
+
+clean:
+ rm -rf $(BARDIR) $(FOODIR)
+
+.PHONY: all clean
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/PluggableLocale/providersrc/java.util.spi.CalendarNameProvider Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,7 @@
+#
+#
+#
+# fully-qualified name of the java.util.spi.CalendarNameProvider
+# implementation class
+#
+com.bar.CalendarNameProviderImpl
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/CheckLockLocationTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2012, 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 6244047
+ * @author Jim Gish
+ * @summary throw more precise IOException when pattern specifies invalid directory
+ *
+ * @run main/othervm CheckLockLocationTest
+ */
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.file.AccessDeniedException;
+import java.nio.file.FileSystemException;
+import java.nio.file.NoSuchFileException;
+import java.util.logging.FileHandler;
+public class CheckLockLocationTest {
+
+ private static final String NON_WRITABLE_DIR = "non-writable-dir";
+ private static final String NOT_A_DIR = "not-a-dir";
+ private static final String WRITABLE_DIR = "writable-dir";
+ private static final String NON_EXISTENT_DIR = "non-existent-dir";
+
+ public static void main(String... args) throws IOException {
+ // we'll base all file creation attempts on the system temp directory,
+ // %t and also try specifying non-existent directories and plain files
+ // that should be directories, and non-writable directories,
+ // to exercise all code paths of checking the lock location
+ File writableDir = setup();
+ // we now have three files/directories to work with:
+ // writableDir
+ // notAdir
+ // nonWritableDir
+ // nonExistentDir (which doesn't exist)
+ runTests(writableDir);
+ }
+
+ /**
+ * @param writableDir in which log and lock file are created
+ * @throws SecurityException
+ * @throws RuntimeException
+ * @throws IOException
+ */
+ private static void runTests(File writableDir) throws SecurityException,
+ RuntimeException, IOException {
+ // Test 1: make sure we can create FileHandler in writable directory
+ try {
+ new FileHandler("%t/" + WRITABLE_DIR + "/log.log");
+ } catch (IOException ex) {
+ throw new RuntimeException("Test failed: should have been able"
+ + " to create FileHandler for " + "%t/" + WRITABLE_DIR
+ + "/log.log in writable directory.", ex);
+ } finally {
+ // the above test leaves files in the directory. Get rid of the
+ // files created and the directory
+ delete(writableDir);
+ }
+
+ // Test 2: creating FileHandler in non-writable directory should fail
+ try {
+ new FileHandler("%t/" + NON_WRITABLE_DIR + "/log.log");
+ throw new RuntimeException("Test failed: should not have been able"
+ + " to create FileHandler for " + "%t/" + NON_WRITABLE_DIR
+ + "/log.log in non-writable directory.");
+ } catch (IOException ex) {
+ // check for the right exception
+ if (!(ex instanceof AccessDeniedException)) {
+ throw new RuntimeException("Test failed: Expected exception was not an AccessDeniedException", ex);
+ }
+ }
+
+ // Test 3: creating FileHandler in non-directory should fail
+ try {
+ new FileHandler("%t/" + NOT_A_DIR + "/log.log");
+ throw new RuntimeException("Test failed: should not have been able"
+ + " to create FileHandler for " + "%t/" + NOT_A_DIR
+ + "/log.log in non-directory.");
+ } catch (IOException ex) {
+ // check for the right exception
+ if (!(ex instanceof FileSystemException && ex.getMessage().contains("Not a directory"))) {
+ throw new RuntimeException("Test failed: Expected exception was not a FileSystemException", ex);
+ }
+ }
+
+ // Test 4: make sure we can't create a FileHandler in a non-existent dir
+ try {
+ new FileHandler("%t/" + NON_EXISTENT_DIR + "/log.log");
+ throw new RuntimeException("Test failed: should not have been able"
+ + " to create FileHandler for " + "%t/" + NON_EXISTENT_DIR
+ + "/log.log in a non-existent directory.");
+ } catch (IOException ex) {
+ // check for the right exception
+ if (!(ex instanceof NoSuchFileException)) {
+ throw new RuntimeException("Test failed: Expected exception was not a NoSuchFileException", ex);
+ }
+ }
+ }
+
+ /**
+ * Setup all the files and directories needed for the tests
+ *
+ * @return writable directory created that needs to be deleted when done
+ * @throws RuntimeException
+ */
+ private static File setup() throws RuntimeException {
+ // First do some setup in the temporary directory (using same logic as
+ // FileHandler for %t pattern)
+ String tmpDir = System.getProperty("java.io.tmpdir"); // i.e. %t
+ if (tmpDir == null) {
+ tmpDir = System.getProperty("user.home");
+ }
+ File tmpOrHomeDir = new File(tmpDir);
+ // Create a writable directory here (%t/writable-dir)
+ File writableDir = new File(tmpOrHomeDir, WRITABLE_DIR);
+ if (!createFile(writableDir, true)) {
+ throw new RuntimeException("Test setup failed: unable to create"
+ + " writable working directory "
+ + writableDir.getAbsolutePath() );
+ }
+ // writableDirectory and its contents will be deleted after the test
+ // that uses it
+
+ // Create a plain file which we will attempt to use as a directory
+ // (%t/not-a-dir)
+ File notAdir = new File(tmpOrHomeDir, NOT_A_DIR);
+ if (!createFile(notAdir, false)) {
+ throw new RuntimeException("Test setup failed: unable to a plain"
+ + " working file " + notAdir.getAbsolutePath() );
+ }
+ notAdir.deleteOnExit();
+
+ // Create a non-writable directory (%t/non-writable-dir)
+ File nonWritableDir = new File(tmpOrHomeDir, NON_WRITABLE_DIR);
+ if (!createFile(nonWritableDir, true)) {
+ throw new RuntimeException("Test setup failed: unable to create"
+ + " a non-"
+ + "writable working directory "
+ + nonWritableDir.getAbsolutePath() );
+ }
+ nonWritableDir.deleteOnExit();
+
+ // make it non-writable
+ if (!nonWritableDir.setWritable(false)) {
+ throw new RuntimeException("Test setup failed: unable to make"
+ + " working directory " + nonWritableDir.getAbsolutePath()
+ + " non-writable.");
+ }
+
+ // make sure non-existent directory really doesn't exist
+ File nonExistentDir = new File(tmpOrHomeDir, NON_EXISTENT_DIR);
+ if (nonExistentDir.exists()) {
+ nonExistentDir.delete();
+ }
+ return writableDir;
+ }
+
+ /**
+ * @param newFile
+ * @return true if file already exists or creation succeeded
+ */
+ private static boolean createFile(File newFile, boolean makeDirectory) {
+ if (newFile.exists()) {
+ return true;
+ }
+ if (makeDirectory) {
+ return newFile.mkdir();
+ } else {
+ try {
+ return newFile.createNewFile();
+ } catch (IOException ioex) {
+ ioex.printStackTrace();
+ return false;
+ }
+ }
+ }
+
+ /*
+ * Recursively delete all files starting at specified file
+ */
+ private static void delete(File f) throws IOException {
+ if (f != null && f.isDirectory()) {
+ for (File c : f.listFiles())
+ delete(c);
+ }
+ if (!f.delete())
+ throw new FileNotFoundException("Failed to delete file: " + f);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/config/DNS.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// See dns.sh.
+import sun.security.krb5.Config;
+
+public class DNS {
+ public static void main(String[] args) throws Exception {
+ System.setProperty("java.security.krb5.conf",
+ System.getProperty("test.src", ".") +"/nothing.conf");
+ Config config = Config.getInstance();
+ String kdcs = config.getKDCList("X");
+ if (!kdcs.equals("a.com.:88 b.com.:99") &&
+ !kdcs.equals("a.com. b.com.:99")) {
+ throw new Exception("Strange KDC: [" + kdcs + "]");
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/config/NamingManager.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+package javax.naming.spi;
+
+import com.sun.jndi.dns.DnsContext;
+import java.util.Hashtable;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+
+/**
+ * A fake javax.naming.spi.NamingManager. It allows reading a DNS
+ * record without contacting a real server.
+ *
+ * See DNS.java and dns.sh.
+ */
+public class NamingManager {
+ NamingManager() {}
+ public static Context getURLContext(
+ String scheme, Hashtable<?,?> environment)
+ throws NamingException {
+ return new DnsContext("", null, new Hashtable<String,String>()) {
+ public Attributes getAttributes(String name, String[] attrIds)
+ throws NamingException {
+ return new BasicAttributes() {
+ public Attribute get(String attrID) {
+ BasicAttribute ba = new BasicAttribute(attrID);
+ ba.add("1 1 99 b.com.");
+ ba.add("0 0 88 a.com."); // 2nd has higher priority
+ return ba;
+ }
+ };
+ }
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/config/dns.sh Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2012, 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 8002344
+# @summary Krb5LoginModule config class does not return proper KDC list from DNS
+#
+
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC="."
+fi
+
+$TESTJAVA/bin/javac -d . \
+ ${TESTSRC}/NamingManager.java ${TESTSRC}/DNS.java
+$TESTJAVA/bin/java -Xbootclasspath/p:. DNS
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/JarBackSlash.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug 7201156
+ * @summary jar tool fails to convert file separation characters for list and extract
+ * @author Sean Chou
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+
+import sun.tools.jar.Main;
+
+public class JarBackSlash {
+
+ // used construct an entry JarBackSlash/dir/file.txt
+ private static String JARBACKSLASH = "JarBackSlash";
+ private static String DIR = "dir";
+ private static String FILENAME = "file.txt";
+
+ private static File createJarFile() throws IOException {
+ File jarFile = File.createTempFile("JarBackSlashTest", ".jar");
+ jarFile.deleteOnExit();
+
+ try (JarOutputStream output = new JarOutputStream(new FileOutputStream(jarFile))) {
+ JarEntry entry = new JarEntry(JARBACKSLASH + "/" + DIR + "/" + FILENAME);
+ output.putNextEntry(entry);
+ }
+
+ return jarFile;
+ }
+
+ private static void testJarList(String jarFile) throws IOException {
+ List<String> argList = new ArrayList<String>();
+ argList.add("-tvf");
+ argList.add(jarFile);
+ argList.add(JARBACKSLASH + File.separatorChar + DIR + File.separatorChar + FILENAME);
+
+ String jarArgs[] = new String[argList.size()];
+ jarArgs = argList.toArray(jarArgs);
+
+ PipedOutputStream pipedOutput = new PipedOutputStream();
+ PipedInputStream pipedInput = new PipedInputStream(pipedOutput);
+ PrintStream out = new PrintStream(pipedOutput);
+
+ Main jarTool = new Main(out, System.err, "jar");
+ if (!jarTool.run(jarArgs)) {
+ fail("Could not list jar file.");
+ }
+
+ out.flush();
+ check(pipedInput.available() > 0);
+ }
+
+
+ private static void testJarExtract(String jarFile) throws IOException {
+ List<String> argList = new ArrayList<String>();
+ argList.add("-xvf");
+ argList.add(jarFile);
+ argList.add(JARBACKSLASH + File.separatorChar + DIR + File.separatorChar + FILENAME);
+
+ String jarArgs[] = new String[argList.size()];
+ jarArgs = argList.toArray(jarArgs);
+
+ PipedOutputStream pipedOutput = new PipedOutputStream();
+ PipedInputStream pipedInput = new PipedInputStream(pipedOutput);
+ PrintStream out = new PrintStream(pipedOutput);
+
+ Main jarTool = new Main(out, System.err, "jar");
+ if (!jarTool.run(jarArgs)) {
+ fail("Could not list jar file.");
+ }
+
+ out.flush();
+ check(pipedInput.available() > 0);
+ }
+
+ public static void realMain(String[] args) throws Throwable {
+ File tmpJarFile = createJarFile();
+ String tmpJarFilePath = tmpJarFile.getAbsolutePath();
+
+ testJarList(tmpJarFilePath);
+ testJarExtract(tmpJarFilePath);
+ }
+
+
+ //--------------------- Infrastructure ---------------------------
+ static volatile int passed = 0, failed = 0;
+ static void pass() {passed++;}
+ static void fail() {failed++; Thread.dumpStack();}
+ static void fail(String msg) {System.out.println(msg); fail();}
+ static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ static void check(boolean cond) {if (cond) pass(); else fail();}
+ static void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ try {realMain(args);} catch (Throwable t) {unexpected(t);}
+ System.out.println("\nPassed = " + passed + " failed = " + failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/FXLauncherTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2012, 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 8001533
+ * @summary Test launching FX application with java -jar
+ * Test uses main method and blank main method, a jfx app class and an incorrest
+ * jfx app class, a main-class for the manifest, a bogus one and none.
+ * All should execute except the incorrect fx app class entries.
+ * @run main FXLauncherTest
+ */
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FXLauncherTest extends TestHelper {
+ private static final String FX_MARKER_CLASS = "javafx.application.Application";
+ private static void line() {
+ System.out.println("_____________________________________________");
+ }
+ private static File MainJavaFile = null;
+ private static final File FXtestJar = new File("fxtest.jar");
+ private static final File ManifestFile = new File("manifest.txt");
+ private static final File ScratchDir = new File(".");
+
+ /* standard main class can be used as java main for fx app class */
+ static final String StdMainClass = "helloworld.HelloWorld";
+ static int testcount = 0;
+
+ /* a main method and a blank. */
+ static final String[] MAIN_METHODS = {
+ "public static void main(String[] args) { launch(args); }",
+ " "
+ };
+
+ // Array of parameters to pass to fx application.
+ static final String[] APP_PARMS = { "one", "two" };
+
+ // Create fx java file for test application
+ static void createJavaFile(String mainmethod) {
+ try {
+ String mainClass = "HelloWorld";
+ List<String> contents = new ArrayList<>();
+ contents.add("package helloworld;");
+ contents.add("import javafx.application.Application;");
+ contents.add("import javafx.event.ActionEvent;");
+ contents.add("import javafx.event.EventHandler;");
+ contents.add("import javafx.scene.Scene;");
+ contents.add("import javafx.scene.control.Button;");
+ contents.add("import javafx.scene.layout.StackPane;");
+ contents.add("import javafx.stage.Stage;");
+ contents.add("public class HelloWorld extends Application {");
+ contents.add(mainmethod);
+ contents.add("@Override");
+ contents.add("public void start(Stage primaryStage) {");
+ contents.add(" primaryStage.setTitle(\"Hello World!\");");
+ contents.add(" Button btn = new Button();");
+ contents.add(" btn.setText(\"Say 'Hello World'\");");
+ contents.add(" btn.setOnAction(new EventHandler<ActionEvent>() {");
+ contents.add(" @Override");
+ contents.add(" public void handle(ActionEvent event) {");
+ contents.add(" System.out.println(\"Hello World!\");");
+ contents.add(" }");
+ contents.add(" });");
+ contents.add(" StackPane root = new StackPane();");
+ contents.add(" root.getChildren().add(btn);");
+ contents.add(" primaryStage.setScene(new Scene(root, 300, 250));");
+ contents.add("// primaryStage.show(); no GUI for auto tests. ");
+ contents.add(" System.out.println(\"HelloWorld.primaryStage.show();\");");
+ contents.add(" System.out.println(\"Parameters:\");" );
+ contents.add(" for(String p : getParameters().getUnnamed())");
+ contents.add(" System.out.println(\"parameter: \" + p );" );
+ contents.add(" System.exit(0);");
+ contents.add("}");
+ contents.add("}");
+
+ // Create and compile java source.
+ MainJavaFile = new File(mainClass + JAVA_FILE_EXT);
+ createFile(MainJavaFile, contents);
+ compile("-d", ".", mainClass + JAVA_FILE_EXT);
+ } catch (java.io.IOException ioe) {
+ ioe.printStackTrace();
+ throw new RuntimeException("Failed creating HelloWorld.");
+ }
+ }
+
+ /*
+ * Create class to extend fx java file for test application
+ * TODO: make test to create java file and this extension of the java file
+ * and jar them together an run app via this java class.
+ */
+ static void createExtJavaFile(String mainmethod) {
+ try {
+ String mainClass = "ExtHello";
+ List<String> contents = new ArrayList<>();
+ contents.add("package helloworld;");
+ contents.add("public class ExtHello extends HelloWorld {");
+ contents.add(mainmethod);
+ contents.add("}");
+ // Create and compile java source.
+ MainJavaFile = new File(mainClass + JAVA_FILE_EXT);
+ createFile(MainJavaFile, contents);
+ compile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT);
+ } catch (java.io.IOException ioe) {
+ ioe.printStackTrace();
+ throw new RuntimeException("Failed creating HelloWorld.");
+ }
+ }
+
+ // Create manifest for test fx application
+ static List<String> createManifestContents(String mainclassentry) {
+ List<String> mcontents = new ArrayList<>();
+ mcontents.add("Manifest-Version: 1.0");
+ mcontents.add("Created-By: FXLauncherTest");
+ mcontents.add("Main-Class: " + mainclassentry);
+ return mcontents;
+ }
+
+ // Method to marshal createJar to TestHelper.createJar()
+ static void createJar(File theJar, File manifestFile) {
+ createJar("cvmf", manifestFile.getName(),
+ theJar.getAbsolutePath(), "helloworld");
+ }
+
+ static void saveFile(String tname, int testcount, File srcFile) {
+ File newFile = new File(tname + "-" + testcount + "-" + srcFile.getName());
+ System.out.println("renaming " + srcFile.getName() +
+ " to " + newFile.getName());
+ srcFile.renameTo(newFile);
+ }
+
+ static void cleanupFiles() throws IOException {
+ for(File f : ScratchDir.listFiles()) {
+ recursiveDelete(f);
+ }
+ }
+
+ static void checkStatus(TestResult tr, String testName, int testCount,
+ String mainclass) throws Exception {
+ if (tr.testStatus) {
+ System.out.println("PASS: " + testName + ":" + testCount +
+ " : test with " + mainclass);
+ cleanupFiles();
+ } else {
+ saveFile(testName, testcount, FXtestJar);
+ System.out.println("FAIL: " + testName + ":" + testCount +
+ " : test with " + mainclass);
+ cleanupFiles();
+ System.err.println(tr);
+ throw new Exception("Failed: " + testName + ":" + testCount);
+ }
+ }
+
+ /*
+ * Set Main-Class and iterate main_methods.
+ * Try launching with both -jar and -cp methods.
+ * All cases should run.
+ */
+ @Test
+ static void testBasicFXApp() throws Exception {
+ testBasicFXApp(true);
+ testBasicFXApp(false);
+ }
+
+ static void testBasicFXApp(boolean useCP) throws Exception {
+ String testname = "testBasicFXApp";
+ for (String mm : MAIN_METHODS) {
+ testcount++;
+ line();
+ System.out.println("test# " + testcount +
+ "- Main method: " + mm +
+ "; MF main class: " + StdMainClass);
+ createJavaFile(mm);
+ createFile(ManifestFile, createManifestContents(StdMainClass));
+ createJar(FXtestJar, ManifestFile);
+ String sTestJar = FXtestJar.getAbsolutePath();
+ TestResult tr;
+ if (useCP) {
+ tr = doExec(javaCmd, "-cp", sTestJar, StdMainClass, APP_PARMS[0], APP_PARMS[1]);
+ testname = testname.concat("_useCP");
+ } else {
+ tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
+ }
+ tr.checkPositive();
+ if (tr.testStatus && tr.contains("HelloWorld.primaryStage.show()")) {
+ for (String p : APP_PARMS) {
+ if (!tr.contains(p)) {
+ System.err.println("ERROR: Did not find "
+ + p + " in output!");
+ }
+ }
+ }
+ checkStatus(tr, testname, testcount, StdMainClass);
+ }
+ }
+
+ /*
+ * Set Main-Class and iterate main methods.
+ * Main class extends another class that extends Application.
+ * Try launching with both -jar and -cp methods.
+ * All cases should run.
+ */
+ @Test
+ static void testExtendFXApp() throws Exception {
+ testExtendFXApp(true);
+ testExtendFXApp(false);
+ }
+
+ static void testExtendFXApp(boolean useCP) throws Exception {
+ String testname = "testExtendFXApp";
+ for (String mm : MAIN_METHODS) {
+ testcount++;
+ line();
+ System.out.println("test# " + testcount +
+ "- Main method: " + mm + "; MF main class: " + StdMainClass);
+ createJavaFile(mm);
+ createExtJavaFile(mm);
+ createFile(ManifestFile, createManifestContents(StdMainClass));
+ createJar(FXtestJar, ManifestFile);
+ String sTestJar = FXtestJar.getAbsolutePath();
+ TestResult tr;
+ if (useCP) {
+ tr = doExec(javaCmd, "-cp", sTestJar, StdMainClass, APP_PARMS[0], APP_PARMS[1]);
+ testname = testname.concat("_useCP");
+ } else {
+ tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
+ }
+ tr.checkPositive();
+ if (tr.testStatus && tr.contains("HelloWorld.primaryStage.show()")) {
+ for (String p : APP_PARMS) {
+ if (!tr.contains(p)) {
+ System.err.println("ERROR: Did not find "
+ + p + " in output!");
+ }
+ }
+ }
+ checkStatus(tr, testname, testcount, StdMainClass);
+ }
+ }
+
+ /*
+ * test to ensure that we don't load any extraneous fx jars when
+ * launching a standard java application
+ */
+ @Test
+ static void testExtraneousJars()throws Exception {
+ String testname = "testExtraneousJars";
+ testcount++;
+ line();
+ System.out.println("test# " + testcount);
+ TestResult tr = doExec(javacCmd, "-J-verbose:class", "-version");
+ if (!tr.notContains("jfxrt.jar")) {
+ System.out.println("testing for extraneous jfxrt jar");
+ System.out.println(tr);
+ throw new Exception("jfxrt.jar is being loaded by javac!!!");
+ }
+ checkStatus(tr, testname, testcount, StdMainClass);
+ }
+
+ public static void main(String... args) throws Exception {
+ //check if fx is part of jdk
+ Class<?> fxClass = null;
+ try {
+ fxClass = Class.forName(FX_MARKER_CLASS);
+ } catch (ClassNotFoundException ex) {
+ // do nothing
+ }
+ if (fxClass != null) {
+ FXLauncherTest fxt = new FXLauncherTest();
+ fxt.run(args);
+ if (testExitValue > 0) {
+ System.out.println("Total of " + testExitValue
+ + " failed. Test cases covered: "
+ + FXLauncherTest.testcount);
+ System.exit(1);
+ } else {
+ System.out.println("All tests pass. Test cases covered: "
+ + FXLauncherTest.testcount);
+ }
+ } else {
+ System.err.println("Warning: JavaFX components missing or not supported");
+ System.err.println(" test passes vacuosly.");
+ }
+ }
+}
--- a/jdk/test/tools/launcher/TestHelper.java Fri Nov 30 12:39:37 2012 +0000
+++ b/jdk/test/tools/launcher/TestHelper.java Fri Nov 30 17:09:05 2012 -0800
@@ -559,6 +559,16 @@
return false;
}
+ boolean notContains(String str) {
+ for (String x : testOutput) {
+ if (x.contains(str)) {
+ appendError("string <" + str + "> found");
+ return false;
+ }
+ }
+ return true;
+ }
+
boolean matches(String stringToMatch) {
for (String x : testOutput) {
if (x.matches(stringToMatch)) {
--- a/langtools/.hgtags Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/.hgtags Fri Nov 30 17:09:05 2012 -0800
@@ -185,3 +185,5 @@
26020b247ad3806dbca33e029ee12e1b191f59f9 jdk8-b61
b47bb81ba962ef80bb6f0b863c33a0afcfb0b49e jdk8-b62
92e6f2190ca0567c857f85c3fb7a2be5adf079d0 jdk8-b63
+e6ee43b3e2473798b17a556e9f11eebe25ab81d4 jdk8-b64
+5f2faba89cac665e365c05074064ffc934a495eb jdk8-b65
--- a/langtools/make/build.xml Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/make/build.xml Fri Nov 30 17:09:05 2012 -0800
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2007, 2012, 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
@@ -277,7 +277,7 @@
<!-- transform the output to a simple html -->
<xslt in="${dist.checkstyle.dir}/checkstyle_report.xml"
out="${dist.checkstyle.dir}/checkstyle_report.html"
- style="${checkstyle.home}/contrib/checkstyle-simple.xsl"/>
+ style="${checkstyle.home}/contrib/checkstyle-simple.xsl"/>
<!-- transform the output to a very simple emacs friendly text file -->
<xslt in="${dist.checkstyle.dir}/checkstyle_report.xml"
out="${dist.checkstyle.dir}/checkstyle_report.tmp"
@@ -297,9 +297,9 @@
<target name="checkstyle-ide" depends="checkstyle">
<concat>
<fileset file="${dist.checkstyle.dir}/checkstyle_report.emacs.txt"/>
- </concat>
+ </concat>
</target>
-
+
<target name="findbugs" depends="-def-findbugs,build-all-tools">
<property name="findbugs.reportLevel" value="medium"/>
<mkdir dir="${dist.findbugs.dir}"/>
@@ -368,7 +368,7 @@
executable="${dist.bin.dir}/javac"
srcdir="test/tools/javac/diags"
destdir="${build.dir}/diag-examples/classes"
- includes="ArgTypeCompilerFactory.java,Example.java,FileManager.java,HTMLWriter.java,RunExamples.java"
+ includes="ArgTypeCompilerFactory.java,Example.java,FileManager.java,HTMLWriter.java,RunExamples.java,DocCommentProcessor.java"
sourcepath=""
classpath="${dist.lib.dir}/javac.jar"
includeAntRuntime="no"
@@ -381,6 +381,7 @@
dir="test/tools/javac/diags"
classpath="${build.dir}/diag-examples/classes;${dist.lib.dir}/javac.jar"
classname="RunExamples">
+ <jvmarg value="-Dtest.classes=${build.dir}/diag-examples/classes"/>
<arg value="-examples"/>
<arg value="examples"/>
<arg value="-o"/>
@@ -695,7 +696,7 @@
<target name="-check-checkstyle.home" depends="-def-check">
<check name="checkstyle" property="checkstyle.home" marker="${checkstyle.name.version}.jar"/>
</target>
-
+
<target name="-check-jtreg.home" depends="-def-check">
<check name="jtreg" property="jtreg.home" marker="lib/jtreg.jar"/>
</target>
@@ -1005,7 +1006,7 @@
</taskdef>
<property name="checkstyle.defined" value="true"/>
</target>
-
+
<target name="-def-findbugs" unless="findbugs.defined"
depends="-check-findbugs.home,-check-target.java.home">
<taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask">
--- a/langtools/makefiles/BuildLangtools.gmk Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/makefiles/BuildLangtools.gmk Fri Nov 30 17:09:05 2012 -0800
@@ -38,6 +38,9 @@
SERVER_JVM:=$(SJAVAC_SERVER_JAVA),\
FLAGS:=-XDignore.symbol.file=true -g -Xlint:all$(COMMA)-deprecation -Werror))
+# javax.tools.JavaCompilerTool isn't really a suffix but this gets the file copied.
+RESOURCE_SUFFIXES:=.gif .xml .css .js javax.tools.JavaCompilerTool
+
# Now setup the compilation of the properties compilation tool. You can depend
# upon $(BUILD_TOOLS) to trigger a compilation of the tools. Note that we
# add src/share/classes to the sourcepath. This is necessary since the GenStubs
@@ -99,6 +102,7 @@
DISABLE_SJAVAC:=true,\
SRC:=$(LANGTOOLS_TOPDIR)/src/share/classes $(LANGTOOLS_OUTPUTDIR)/gensrc,\
EXCLUDES:=com/sun/tools/javac/nio,\
+ COPY:=$(RESOURCE_SUFFIXES),\
BIN:=$(LANGTOOLS_OUTPUTDIR)/btclasses/bootstrap))
$(eval $(call SetupArchive,ARCHIVE_BOOTSTRAP_JAVAC,$(BUILD_BOOTSTRAP_LANGTOOLS),\
@@ -119,6 +123,7 @@
$(eval $(call SetupArchive,ARCHIVE_BOOTSTRAP_JAVADOC,$(BUILD_BOOTSTRAP_LANGTOOLS),\
SRCS:=$(LANGTOOLS_OUTPUTDIR)/btclasses/bootstrap,\
JAR:=$(LANGTOOLS_OUTPUTDIR)/dist/bootstrap/lib/javadoc.jar,\
+ SUFFIXES:=.class $(RESOURCE_SUFFIXES),\
JARMAIN:=com.sun.tools.javadoc.Main))
# GenStubs is used to bootstrap any dependencies from javac to the new JDK that is not
@@ -172,9 +177,6 @@
SERVER_DIR:=$(SJAVAC_SERVER_DIR),\
SERVER_JVM:=$(SJAVAC_SERVER_JAVA)))
- # javax.tools.JavaCompilerTool isn't really a suffix but this gets the file copied.
- RESOURCE_SUFFIXES:=.gif .xml .css javax.tools.JavaCompilerTool
-
$(eval $(call SetupJavaCompilation,BUILD_FULL_JAVAC,\
SETUP:=GENERATE_NEWBYTECODE,\
SRC:=$(LANGTOOLS_TOPDIR)/src/share/classes $(LANGTOOLS_OUTPUTDIR)/gensrc \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/AttributeTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+import javax.lang.model.element.Name;
+
+/**
+ * A tree node for an attribute in an HTML element.
+ *
+ * @since 1.8
+ */
+public interface AttributeTree extends DocTree {
+ enum ValueKind { EMPTY, UNQUOTED, SINGLE, DOUBLE };
+
+ Name getName();
+ ValueKind getValueKind();
+ List<? extends DocTree> getValue();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/AuthorTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ * A tree node for an @author block tag.
+ *
+ * <p>
+ * @author name-text.
+ *
+ * @since 1.8
+ */
+public interface AuthorTree extends BlockTagTree {
+ List<? extends DocTree> getName();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/BlockTagTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+/**
+ * A tree node used as the base class for the different types of
+ * block tags.
+ *
+ * @since 1.8
+ */
+public interface BlockTagTree extends DocTree {
+ String getTagName();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/CommentTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+/**
+ * An embedded HTML comment.
+ *
+ * <p>
+ * {@literal <!-- text --> }
+ *
+ * @since 1.8
+ */
+public interface CommentTree extends DocTree {
+ String getBody();
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/DeprecatedTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ * A tree node for an @deprecated block tag.
+ *
+ * <p>
+ * @deprecated deprecated text.
+ *
+ * @since 1.8
+ */
+public interface DeprecatedTree extends BlockTagTree {
+ List<? extends DocTree> getBody();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/DocCommentTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ * The top level representation of a documentation comment.
+ *
+ * <p>
+ * first-sentence body block-tags
+ *
+ * @since 1.8
+ */
+public interface DocCommentTree extends DocTree {
+ List<? extends DocTree> getFirstSentence();
+ List<? extends DocTree> getBody();
+ List<? extends DocTree> getBlockTags();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/DocRootTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+/**
+ * A tree node for an @docroot inline tag.
+ *
+ * <p>
+ * {@docroot}
+ *
+ * @since 1.8
+ */
+public interface DocRootTree extends InlineTagTree { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/DocTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+/**
+ * Common interface for all nodes in a documentation syntax tree.
+ *
+ * @since 1.8
+ */
+public interface DocTree {
+ enum Kind {
+ /**
+ * Used for instances of {@link AttributeTree}
+ * representing an HTML attribute.
+ */
+ ATTRIBUTE,
+
+ /**
+ * Used for instances of {@link AuthorTree}
+ * representing an @author tag.
+ */
+ AUTHOR("author"),
+
+ /**
+ * Used for instances of {@link LiteralTree}
+ * representing an @code tag.
+ */
+ CODE("code"),
+
+ /**
+ * Used for instances of {@link CommentTree}
+ * representing an HTML comment.
+ */
+ COMMENT,
+
+ /**
+ * Used for instances of {@link DeprecatedTree}
+ * representing an @deprecated tag.
+ */
+ DEPRECATED("deprecated"),
+
+ /**
+ * Used for instances of {@link DocCommentTree}
+ * representing a complete doc comment.
+ */
+ DOC_COMMENT,
+
+ /**
+ * Used for instances of {@link DocRootTree}
+ * representing an @docRoot tag.
+ */
+ DOC_ROOT("docRoot"),
+
+ /**
+ * Used for instances of {@link EndElementTree}
+ * representing the end of an HTML element.
+ */
+ END_ELEMENT,
+
+ /**
+ * Used for instances of {@link EntityTree}
+ * representing an HTML entity.
+ */
+ ENTITY,
+
+ /**
+ * Used for instances of {@link ErroneousTree}
+ * representing some invalid text.
+ */
+ ERRONEOUS,
+
+ /**
+ * Used for instances of {@link ThrowsTree}
+ * representing an @exception tag.
+ */
+ EXCEPTION("exception"),
+
+ /**
+ * Used for instances of {@link IdentifierTree}
+ * representing an identifier.
+ */
+ IDENTIFIER,
+
+ /**
+ * Used for instances of {@link InheritDocTree}
+ * representing an @inheritDoc tag.
+ */
+ INHERIT_DOC("inheritDoc"),
+
+ /**
+ * Used for instances of {@link LinkTree}
+ * representing an @link tag.
+ */
+ LINK("link"),
+
+ /**
+ * Used for instances of {@link LinkTree}
+ * representing an @linkplain tag.
+ */
+ LINK_PLAIN("linkplain"),
+
+ /**
+ * Used for instances of {@link LiteralTree}
+ * representing an @literal tag.
+ */
+ LITERAL("literal"),
+
+ /**
+ * Used for instances of {@link ParamTree}
+ * representing an @param tag.
+ */
+ PARAM("param"),
+
+ /**
+ * Used for instances of {@link ReferenceTree}
+ * representing a reference to a element in the
+ * Java programming language.
+ */
+ REFERENCE,
+
+ /**
+ * Used for instances of {@link ReturnTree}
+ * representing an @return tag.
+ */
+ RETURN("return"),
+
+ /**
+ * Used for instances of {@link SeeTree}
+ * representing an @see tag.
+ */
+ SEE("see"),
+
+ /**
+ * Used for instances of {@link SerialTree}
+ * representing an @serial tag.
+ */
+ SERIAL("serial"),
+
+ /**
+ * Used for instances of {@link SerialDataTree}
+ * representing an @serialData tag.
+ */
+ SERIAL_DATA("serialData"),
+
+ /**
+ * Used for instances of {@link SerialFieldTree}
+ * representing an @serialField tag.
+ */
+ SERIAL_FIELD("serialField"),
+
+ /**
+ * Used for instances of {@link SinceTree}
+ * representing an @since tag.
+ */
+ SINCE("since"),
+
+ /**
+ * Used for instances of {@link EndElementTree}
+ * representing the start of an HTML element.
+ */
+ START_ELEMENT,
+
+ /**
+ * Used for instances of {@link TextTree}
+ * representing some documentation text.
+ */
+ TEXT,
+
+ /**
+ * Used for instances of {@link ThrowsTree}
+ * representing an @throws tag.
+ */
+ THROWS("throws"),
+
+ /**
+ * Used for instances of {@link UnknownBlockTagTree}
+ * representing an unknown block tag.
+ */
+ UNKNOWN_BLOCK_TAG,
+
+ /**
+ * Used for instances of {@link UnknownInlineTagTree}
+ * representing an unknown inline tag.
+ */
+ UNKNOWN_INLINE_TAG,
+
+ /**
+ * Used for instances of {@link ValueTree}
+ * representing an @value tag.
+ */
+ VALUE("value"),
+
+ /**
+ * Used for instances of {@link VersionTree}
+ * representing an @version tag.
+ */
+ VERSION("version"),
+
+ /**
+ * An implementation-reserved node. This is the not the node
+ * you are looking for.
+ */
+ OTHER;
+
+ public final String tagName;
+
+ Kind() {
+ tagName = null;
+ }
+
+ Kind(String tagName) {
+ this.tagName = tagName;
+ }
+ };
+
+ /**
+ * Gets the kind of this tree.
+ *
+ * @return the kind of this tree.
+ */
+ Kind getKind();
+
+ /**
+ * Accept method used to implement the visitor pattern. The
+ * visitor pattern is used to implement operations on trees.
+ *
+ * @param <R> result type of this operation.
+ * @param <D> type of additional data.
+ */
+ <R, D> R accept(DocTreeVisitor<R,D> visitor, D data);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/DocTreeVisitor.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+
+/**
+ * A visitor of trees, in the style of the visitor design pattern.
+ * Classes implementing this interface are used to operate
+ * on a tree when the kind of tree is unknown at compile time.
+ * When a visitor is passed to an tree's {@link DocTree#accept
+ * accept} method, the <tt>visit<i>XYZ</i></tt> method most applicable
+ * to that tree is invoked.
+ *
+ * <p> Classes implementing this interface may or may not throw a
+ * {@code NullPointerException} if the additional parameter {@code p}
+ * is {@code null}; see documentation of the implementing class for
+ * details.
+ *
+ * <p> <b>WARNING:</b> It is possible that methods will be added to
+ * this interface to accommodate new, currently unknown, doc comment
+ * structures added to future versions of the Java™ programming
+ * language. Therefore, visitor classes directly implementing this
+ * interface may be source incompatible with future versions of the
+ * platform.
+ *
+ * @param <R> the return type of this visitor's methods. Use {@link
+ * Void} for visitors that do not need to return results.
+ * @param <P> the type of the additional parameter to this visitor's
+ * methods. Use {@code Void} for visitors that do not need an
+ * additional parameter.
+ *
+ * @since 1.8
+ */
+public interface DocTreeVisitor<R,P> {
+ R visitAttribute(AttributeTree node, P p);
+ R visitAuthor(AuthorTree node, P p);
+ R visitComment(CommentTree node, P p);
+ R visitDeprecated(DeprecatedTree node, P p);
+ R visitDocComment(DocCommentTree node, P p);
+ R visitDocRoot(DocRootTree node, P p);
+ R visitEndElement(EndElementTree node, P p);
+ R visitEntity(EntityTree node, P p);
+ R visitErroneous(ErroneousTree node, P p);
+ R visitIdentifier(IdentifierTree node, P p);
+ R visitInheritDoc(InheritDocTree node, P p);
+ R visitLink(LinkTree node, P p);
+ R visitLiteral(LiteralTree node, P p);
+ R visitParam(ParamTree node, P p);
+ R visitReference(ReferenceTree node, P p);
+ R visitReturn(ReturnTree node, P p);
+ R visitSee(SeeTree node, P p);
+ R visitSerial(SerialTree node, P p);
+ R visitSerialData(SerialDataTree node, P p);
+ R visitSerialField(SerialFieldTree node, P p);
+ R visitSince(SinceTree node, P p);
+ R visitStartElement(StartElementTree node, P p);
+ R visitText(TextTree node, P p);
+ R visitThrows(ThrowsTree node, P p);
+ R visitUnknownBlockTag(UnknownBlockTagTree node, P p);
+ R visitUnknownInlineTag(UnknownInlineTagTree node, P p);
+ R visitValue(ValueTree node, P p);
+ R visitVersion(VersionTree node, P p);
+ R visitOther(DocTree node, P p);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/EndElementTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import javax.lang.model.element.Name;
+
+/**
+ * A tree node for the end of an HTML element.
+ *
+ * <p>
+ * </ name >
+ *
+ * @since 1.8
+ */
+public interface EndElementTree extends DocTree {
+ Name getName();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/EntityTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import javax.lang.model.element.Name;
+
+
+/**
+ * A tree node for an HTML entity.
+ *
+ * <p>
+ * & name ;
+ *
+ * @since 1.8
+ */
+public interface EntityTree extends DocTree {
+ Name getName();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/ErroneousTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.source.doctree;
+
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+
+/**
+ * A tree node to stand in for a malformed text
+ *
+ * @since 1.8
+ */
+public interface ErroneousTree extends TextTree {
+ /**
+ * Gets a diagnostic object giving details about
+ * the reason the body text is in error.
+ *
+ * @return a diagnostic
+ */
+ Diagnostic<JavaFileObject> getDiagnostic();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/IdentifierTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import javax.lang.model.element.Name;
+
+/**
+ * An identifier in a documentation comment.
+ *
+ * <p>
+ * name
+ *
+ * @since 1.8
+ */
+public interface IdentifierTree extends DocTree {
+ Name getName();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/InheritDocTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+/**
+ *
+ * A tree node for an @inheritDoc inline tag.
+ *
+ * <p>
+ * {@inheritDoc}
+ *
+ * @since 1.8
+ */
+public interface InheritDocTree extends InlineTagTree { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/InlineTagTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+/**
+ * A tree node used as the base class for the different types of
+ * inline tags.
+ *
+ * @since 1.8
+ */
+public interface InlineTagTree extends DocTree {
+ String getTagName();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/LinkTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ * A tree node for an @link or @linkplain inline tag.
+ *
+ * <p>
+ * {@link reference label} <br>
+ * {@linkplain reference label }
+ *
+ * @since 1.8
+ */
+public interface LinkTree extends InlineTagTree {
+ ReferenceTree getReference();
+ List<? extends DocTree> getLabel();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/LiteralTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+/**
+ *
+ * A tree node for an @literal or @code inline tag.
+ *
+ * <p>
+ * {@literal text}
+ *
+ * @since 1.8
+ */
+public interface LiteralTree extends InlineTagTree {
+ TextTree getBody();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/ParamTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ * A tree node for an @param block tag.
+ *
+ * <p>
+ * @param parameter-name description
+ *
+ * @since 1.8
+ */
+public interface ParamTree extends BlockTagTree {
+ boolean isTypeParameter();
+ IdentifierTree getName();
+ List<? extends DocTree> getDescription();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/ReferenceTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+/**
+ * A tree node to a reference to a Java language element.
+ *
+ * <p>
+ * package.class#field
+ *
+ * @since 1.8
+ */
+public interface ReferenceTree extends DocTree {
+ String getSignature();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/ReturnTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ * A tree node for an @return block tag.
+ *
+ * <p>
+ * @return description
+ *
+ * @since 1.8
+ */
+public interface ReturnTree extends BlockTagTree {
+ List<? extends DocTree> getDescription();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/SeeTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ *
+ * A tree node for an @see block tag.
+ *
+ * <p>
+ * @see "string" <br>
+ * @see <a href="URL#value"> label </a> <br>
+ * @see reference
+ *
+ * @since 1.8
+ */
+public interface SeeTree extends BlockTagTree {
+ List<? extends DocTree> getReference();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/SerialDataTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ * A tree node for an @serialData block tag.
+ *
+ * <p>
+ * @serialData data-description
+ *
+ * @since 1.8
+ */
+public interface SerialDataTree extends BlockTagTree {
+ List<? extends DocTree> getDescription();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/SerialFieldTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ * A tree node for an @serialData block tag.
+ *
+ * <p>
+ * @serialField field-name field-type field-description
+ *
+ * @since 1.8
+ */
+public interface SerialFieldTree extends BlockTagTree {
+ IdentifierTree getName();
+ ReferenceTree getType();
+ List<? extends DocTree> getDescription();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/SerialTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ * A tree node for an @serial block tag.
+ *
+ * <p>
+ * @serial field-description | include | exclude
+ *
+ * @since 1.8
+ */
+public interface SerialTree extends BlockTagTree {
+ List<? extends DocTree> getDescription();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/SinceTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ * A tree node for an @since block tag.
+ *
+ * <p>
+ * @since since-text
+ *
+ * @since 1.8
+ */
+public interface SinceTree extends BlockTagTree {
+ List<? extends DocTree> getBody();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/StartElementTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+import javax.lang.model.element.Name;
+
+/**
+ * A tree node for the start of an HTML element.
+ *
+ * <p>
+ * < name [attributes] [/]>
+ *
+ * @since 1.8
+ */
+public interface StartElementTree extends DocTree {
+ Name getName();
+ List<? extends DocTree> getAttributes();
+ boolean isSelfClosing();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/TextTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+/**
+ * A tree node for plain text.
+ *
+ * @since 1.8
+ */
+public interface TextTree extends DocTree {
+ String getBody();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/ThrowsTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ *
+ * A tree node for an @exception or @throws block tag.
+ * @exception is a synonym for @throws.
+ *
+ * <p>
+ * @exception class-name description <br>
+ * @throws class-name description
+ *
+ * @since 1.8
+ */
+public interface ThrowsTree extends BlockTagTree {
+ ReferenceTree getExceptionName();
+ List<? extends DocTree> getDescription();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/UnknownBlockTagTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ * A tree node for an unrecognized inline tag.
+ *
+ * <p>
+ * @name content
+ *
+ * @since 1.8
+ *
+ */
+public interface UnknownBlockTagTree extends BlockTagTree {
+ List<? extends DocTree> getContent();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/UnknownInlineTagTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ * A tree node for an unrecognized inline tag.
+ *
+ * <p>
+ * {@name content}
+ *
+ * @since 1.8
+ *
+ */
+public interface UnknownInlineTagTree extends InlineTagTree {
+ List<? extends DocTree> getContent();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/ValueTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+/**
+ * A tree node for an @value inline tag.
+ *
+ * <p>
+ * { @value reference }
+ *
+ * @since 1.8
+ */
+public interface ValueTree extends InlineTagTree {
+ ReferenceTree getReference();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/VersionTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+import java.util.List;
+
+/**
+ *
+ * A tree node for an @version block tag.
+ *
+ * <p>
+ * @version version-text
+ *
+ * @since 1.8
+ */
+public interface VersionTree extends BlockTagTree {
+ List<? extends DocTree> getBody();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/doctree/package-info.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Provides interfaces to represent documentation comments as abstract syntax
+ * trees (AST).
+ *
+ * @author Jonathan Gibbons
+ * @since 1.8
+ * @see <a href="http://download.oracle.com/javase/6/docs/technotes/tools/solaris/javadoc.html#javadoctags">http://download.oracle.com/javase/6/docs/technotes/tools/solaris/javadoc.html#javadoctags</a>
+ */
+package com.sun.source.doctree;
--- a/langtools/src/share/classes/com/sun/source/tree/Tree.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/source/tree/Tree.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -610,7 +610,7 @@
* visitor pattern is used to implement operations on trees.
*
* @param <R> result type of this operation.
- * @param <D> type of additonal data.
+ * @param <D> type of additional data.
*/
<R,D> R accept(TreeVisitor<R,D> visitor, D data);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/util/DocTreeScanner.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.util;
+
+import com.sun.source.doctree.*;
+
+
+/**
+ * A TreeVisitor that visits all the child tree nodes.
+ * To visit nodes of a particular type, just override the
+ * corresponding visitXYZ method.
+ * Inside your method, call super.visitXYZ to visit descendant
+ * nodes.
+ *
+ * <p>The default implementation of the visitXYZ methods will determine
+ * a result as follows:
+ * <ul>
+ * <li>If the node being visited has no children, the result will be null.
+ * <li>If the node being visited has one child, the result will be the
+ * result of calling {@code scan} on that child. The child may be a simple node
+ * or itself a list of nodes.
+ * <li> If the node being visited has more than one child, the result will
+ * be determined by calling {@code scan} each child in turn, and then combining the
+ * result of each scan after the first with the cumulative result
+ * so far, as determined by the {@link #reduce} method. Each child may be either
+ * a simple node of a list of nodes. The default behavior of the {@code reduce}
+ * method is such that the result of the visitXYZ method will be the result of
+ * the last child scanned.
+ * </ul>
+ *
+ * <p>Here is an example to count the number of erroneous nodes in a tree:
+ * <pre>
+ * class CountErrors extends DocTreeScanner<Integer,Void> {
+ * {@literal @}Override
+ * public Integer visitErroneous(ErroneousTree node, Void p) {
+ * return 1;
+ * }
+ * {@literal @}Override
+ * public Integer reduce(Integer r1, Integer r2) {
+ * return (r1 == null ? 0 : r1) + (r2 == null ? 0 : r2);
+ * }
+ * }
+ * </pre>
+ *
+ * @since 1.8
+ */
+public class DocTreeScanner<R,P> implements DocTreeVisitor<R,P> {
+
+ /**
+ * Scan a single node.
+ */
+ public R scan(DocTree node, P p) {
+ return (node == null) ? null : node.accept(this, p);
+ }
+
+ private R scanAndReduce(DocTree node, P p, R r) {
+ return reduce(scan(node, p), r);
+ }
+
+ /**
+ * Scan a list of nodes.
+ */
+ public R scan(Iterable<? extends DocTree> nodes, P p) {
+ R r = null;
+ if (nodes != null) {
+ boolean first = true;
+ for (DocTree node : nodes) {
+ r = (first ? scan(node, p) : scanAndReduce(node, p, r));
+ first = false;
+ }
+ }
+ return r;
+ }
+
+ private R scanAndReduce(Iterable<? extends DocTree> nodes, P p, R r) {
+ return reduce(scan(nodes, p), r);
+ }
+
+ /**
+ * Reduces two results into a combined result.
+ * The default implementation is to return the first parameter.
+ * The general contract of the method is that it may take any action whatsoever.
+ */
+ public R reduce(R r1, R r2) {
+ return r1;
+ }
+
+
+/* ***************************************************************************
+ * Visitor methods
+ ****************************************************************************/
+
+ @Override
+ public R visitAttribute(AttributeTree node, P p) {
+ return null;
+ }
+
+ @Override
+ public R visitAuthor(AuthorTree node, P p) {
+ return scan(node.getName(), p);
+ }
+
+ @Override
+ public R visitComment(CommentTree node, P p) {
+ return null;
+ }
+
+ @Override
+ public R visitDeprecated(DeprecatedTree node, P p) {
+ return scan(node.getBody(), p);
+ }
+
+ @Override
+ public R visitDocComment(DocCommentTree node, P p) {
+ R r = scan(node.getFirstSentence(), p);
+ r = scanAndReduce(node.getBody(), p, r);
+ r = scanAndReduce(node.getBlockTags(), p, r);
+ return r;
+ }
+
+ @Override
+ public R visitDocRoot(DocRootTree node, P p) {
+ return null;
+ }
+
+ @Override
+ public R visitEndElement(EndElementTree node, P p) {
+ return null;
+ }
+
+ @Override
+ public R visitEntity(EntityTree node, P p) {
+ return null;
+ }
+
+ @Override
+ public R visitErroneous(ErroneousTree node, P p) {
+ return null;
+ }
+
+ @Override
+ public R visitIdentifier(IdentifierTree node, P p) {
+ return null;
+ }
+
+ @Override
+ public R visitInheritDoc(InheritDocTree node, P p) {
+ return null;
+ }
+
+ @Override
+ public R visitLink(LinkTree node, P p) {
+ R r = scan(node.getReference(), p);
+ r = scanAndReduce(node.getLabel(), p, r);
+ return r;
+ }
+
+ @Override
+ public R visitLiteral(LiteralTree node, P p) {
+ return null;
+ }
+
+ @Override
+ public R visitParam(ParamTree node, P p) {
+ R r = scan(node.getName(), p);
+ r = scanAndReduce(node.getDescription(), p, r);
+ return r;
+ }
+
+ @Override
+ public R visitReference(ReferenceTree node, P p) {
+ return null;
+ }
+
+ @Override
+ public R visitReturn(ReturnTree node, P p) {
+ return scan(node.getDescription(), p);
+ }
+
+ @Override
+ public R visitSee(SeeTree node, P p) {
+ return scan(node.getReference(), p);
+ }
+
+ @Override
+ public R visitSerial(SerialTree node, P p) {
+ return scan(node.getDescription(), p);
+ }
+
+ @Override
+ public R visitSerialData(SerialDataTree node, P p) {
+ return scan(node.getDescription(), p);
+ }
+
+ @Override
+ public R visitSerialField(SerialFieldTree node, P p) {
+ R r = scan(node.getName(), p);
+ r = scanAndReduce(node.getType(), p, r);
+ r = scanAndReduce(node.getDescription(), p, r);
+ return r;
+ }
+
+ @Override
+ public R visitSince(SinceTree node, P p) {
+ return scan(node.getBody(), p);
+ }
+
+ @Override
+ public R visitStartElement(StartElementTree node, P p) {
+ return scan(node.getAttributes(), p);
+ }
+
+ @Override
+ public R visitText(TextTree node, P p) {
+ return null;
+ }
+
+ @Override
+ public R visitThrows(ThrowsTree node, P p) {
+ R r = scan(node.getExceptionName(), p);
+ r = scanAndReduce(node.getDescription(), p, r);
+ return r;
+ }
+
+ @Override
+ public R visitUnknownBlockTag(UnknownBlockTagTree node, P p) {
+ return scan(node.getContent(), p);
+ }
+
+ @Override
+ public R visitUnknownInlineTag(UnknownInlineTagTree node, P p) {
+ return scan(node.getContent(), p);
+ }
+
+ @Override
+ public R visitValue(ValueTree node, P p) {
+ return scan(node.getReference(), p);
+ }
+
+ @Override
+ public R visitVersion(VersionTree node, P p) {
+ return scan(node.getBody(), p);
+ }
+
+ @Override
+ public R visitOther(DocTree node, P p) {
+ return null;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/util/DocTrees.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.util;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+import javax.tools.JavaCompiler.CompilationTask;
+
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.doctree.ReferenceTree;
+import javax.tools.Diagnostic;
+
+/**
+ * Provides access to syntax trees for doc comments.
+ *
+ * @since 1.8
+ */
+public abstract class DocTrees extends Trees {
+ /**
+ * Gets a DocTrees object for a given CompilationTask.
+ * @param task the compilation task for which to get the Trees object
+ * @throws IllegalArgumentException if the task does not support the Trees API.
+ */
+ public static DocTrees instance(CompilationTask task) {
+ if (!task.getClass().getName().equals("com.sun.tools.javac.api.JavacTaskImpl"))
+ throw new IllegalArgumentException();
+ return (DocTrees) getJavacTrees(CompilationTask.class, task);
+ }
+
+ /**
+ * Gets a DocTrees object for a given ProcessingEnvironment.
+ * @param env the processing environment for which to get the Trees object
+ * @throws IllegalArgumentException if the env does not support the Trees API.
+ */
+ public static DocTrees instance(ProcessingEnvironment env) {
+ if (!env.getClass().getName().equals("com.sun.tools.javac.processing.JavacProcessingEnvironment"))
+ throw new IllegalArgumentException();
+ return (DocTrees) getJavacTrees(ProcessingEnvironment.class, env);
+ }
+
+ /**
+ * Gets the doc comment tree, if any, for the Tree node identified by a given TreePath.
+ * Returns null if no doc comment was found.
+ */
+ public abstract DocCommentTree getDocCommentTree(TreePath path);
+
+ /**
+ * Gets the language model element referred to by a ReferenceTree that
+ * appears on the declaration identified by the given path.
+ */
+ public abstract Element getElement(TreePath path, ReferenceTree reference);
+
+ /**
+ * Prints a message of the specified kind at the location of the
+ * tree within the provided compilation unit
+ *
+ * @param kind the kind of message
+ * @param msg the message, or an empty string if none
+ * @param t the tree to use as a position hint
+ * @param root the compilation unit that contains tree
+ */
+ public abstract void printMessage(Diagnostic.Kind kind, CharSequence msg,
+ com.sun.source.doctree.DocTree t,
+ com.sun.source.doctree.DocCommentTree c,
+ com.sun.source.tree.CompilationUnitTree root);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/util/Plugin.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2005, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.source.util;
+
+import java.util.ServiceLoader;
+import javax.tools.StandardLocation;
+
+/**
+ * The interface for a javac plug-in.
+ *
+ * <p>The javac plug-in mechanism allows a user to specify one or more plug-ins
+ * on the javac command line, to be started soon after the compilation
+ * has begun. Plug-ins are identified by a user-friendly name. Each plug-in that
+ * is started will be passed an array of strings, which may be used to
+ * provide the plug-in with values for any desired options or other arguments.
+ *
+ * <p>Plug-ins are located via a {@link ServiceLoader},
+ * using the same class path as annotation processors (i.e.
+ * {@link StandardLocation#PROCESSOR_PATH PROCESSOR_PATH} or
+ * {@code -processorpath}).
+ *
+ * <p>It is expected that a typical plug-in will simply register a
+ * {@link TaskListener} to be informed of events during the execution
+ * of the compilation, and that the rest of the work will be done
+ * by the task listener.
+ *
+ * @since 1.8
+ */
+public interface Plugin {
+ /**
+ * Get the user-friendly name of this plug-in.
+ * @return the user-friendly name of the plug-in
+ */
+ String getName();
+
+ /**
+ * Invoke the plug-in for a given compilation task.
+ * @param task The compilation task that has just been started
+ * @param args Arguments, if any, for the plug-in
+ */
+ void call(JavacTask task, String... args);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2005, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.util;
+
+import com.sun.source.doctree.*;
+
+/**
+ * A simple visitor for tree nodes.
+ *
+ * @since 1.8
+ */
+public class SimpleDocTreeVisitor<R,P> implements DocTreeVisitor<R, P> {
+ protected final R DEFAULT_VALUE;
+
+ protected SimpleDocTreeVisitor() {
+ DEFAULT_VALUE = null;
+ }
+
+ protected SimpleDocTreeVisitor(R defaultValue) {
+ DEFAULT_VALUE = defaultValue;
+ }
+
+ protected R defaultAction(DocTree node, P p) {
+ return DEFAULT_VALUE;
+ }
+
+ public final R visit(DocTree node, P p) {
+ return (node == null) ? null : node.accept(this, p);
+ }
+
+ public final R visit(Iterable<? extends DocTree> nodes, P p) {
+ R r = null;
+ if (nodes != null) {
+ for (DocTree node : nodes)
+ r = visit(node, p);
+ }
+ return r;
+ }
+
+ public R visitAttribute(AttributeTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitAuthor(AuthorTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitComment(CommentTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitDeprecated(DeprecatedTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitDocComment(DocCommentTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitDocRoot(DocRootTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitEndElement(EndElementTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitEntity(EntityTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitErroneous(ErroneousTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitIdentifier(IdentifierTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitInheritDoc(InheritDocTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitLink(LinkTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitLiteral(LiteralTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitParam(ParamTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitReference(ReferenceTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitReturn(ReturnTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitSee(SeeTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitSerial(SerialTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitSerialData(SerialDataTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitSerialField(SerialFieldTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitSince(SinceTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitStartElement(StartElementTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitText(TextTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitThrows(ThrowsTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitUnknownBlockTag(UnknownBlockTagTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitUnknownInlineTag(UnknownInlineTagTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitValue(ValueTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitVersion(VersionTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+ public R visitOther(DocTree node, P p) {
+ return defaultAction(node, p);
+ }
+
+}
--- a/langtools/src/share/classes/com/sun/source/util/Trees.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/source/util/Trees.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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,6 +26,7 @@
package com.sun.source.util;
import java.lang.reflect.Method;
+
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
@@ -57,7 +58,9 @@
* @throws IllegalArgumentException if the task does not support the Trees API.
*/
public static Trees instance(CompilationTask task) {
- if (!task.getClass().getName().equals("com.sun.tools.javac.api.JavacTaskImpl"))
+ String taskClassName = task.getClass().getName();
+ if (!taskClassName.equals("com.sun.tools.javac.api.JavacTaskImpl")
+ && !taskClassName.equals("com.sun.tools.javac.api.BasicJavacTask"))
throw new IllegalArgumentException();
return getJavacTrees(CompilationTask.class, task);
}
@@ -73,7 +76,7 @@
return getJavacTrees(ProcessingEnvironment.class, env);
}
- private static Trees getJavacTrees(Class<?> argType, Object arg) {
+ static Trees getJavacTrees(Class<?> argType, Object arg) {
try {
ClassLoader cl = arg.getClass().getClassLoader();
Class<?> c = Class.forName("com.sun.tools.javac.api.JavacTrees", false, cl);
@@ -168,6 +171,7 @@
/**
* Gets the doc comment, if any, for the Tree node identified by a given TreePath.
* Returns null if no doc comment was found.
+ * @see DocTrees#getDocCommentTree(TreePath)
*/
public abstract String getDocComment(TreePath path);
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -45,7 +45,7 @@
public abstract class AbstractExecutableMemberWriter extends AbstractMemberWriter {
public AbstractExecutableMemberWriter(SubWriterHolderWriter writer,
- ClassDoc classdoc) {
+ ClassDoc classdoc) {
super(writer, classdoc);
}
@@ -61,7 +61,7 @@
* @return the display length required to write this information.
*/
protected int addTypeParameters(ExecutableMemberDoc member, Content htmltree) {
- LinkInfoImpl linkInfo = new LinkInfoImpl(
+ LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_MEMBER_TYPE_PARAMS, member, false);
String typeParameters = writer.getTypeParameterLinks(linkInfo);
if (linkInfo.displayLength > 0) {
@@ -129,8 +129,8 @@
boolean isVarArg, Content tree) {
if (param.type() != null) {
Content link = new RawHtml(writer.getLink(new LinkInfoImpl(
- LinkInfoImpl.CONTEXT_EXECUTABLE_MEMBER_PARAM, param.type(),
- isVarArg)));
+ configuration, LinkInfoImpl.CONTEXT_EXECUTABLE_MEMBER_PARAM,
+ param.type(), isVarArg)));
tree.addContent(link);
}
if(param.name().length() > 0) {
@@ -161,7 +161,7 @@
htmltree.addContent("(");
Parameter[] params = member.parameters();
String indent = makeSpace(writer.displayLength);
- if (configuration().linksource) {
+ if (configuration.linksource) {
//add spaces to offset indentation changes caused by link.
indent+= makeSpace(member.name().length());
}
@@ -212,7 +212,7 @@
protected void addExceptions(ExecutableMemberDoc member, Content htmltree) {
Type[] exceptions = member.thrownExceptionTypes();
if(exceptions.length > 0) {
- LinkInfoImpl memberTypeParam = new LinkInfoImpl(
+ LinkInfoImpl memberTypeParam = new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_MEMBER, member, false);
int retlen = getReturnTypeLength(member);
writer.getTypeParameterLinks(memberTypeParam);
@@ -224,7 +224,7 @@
htmltree.addContent(indent);
htmltree.addContent("throws ");
indent += " ";
- Content link = new RawHtml(writer.getLink(new LinkInfoImpl(
+ Content link = new RawHtml(writer.getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_MEMBER, exceptions[0])));
htmltree.addContent(link);
for(int i = 1; i < exceptions.length; i++) {
@@ -232,7 +232,7 @@
htmltree.addContent(DocletConstants.NL);
htmltree.addContent(indent);
Content exceptionLink = new RawHtml(writer.getLink(new LinkInfoImpl(
- LinkInfoImpl.CONTEXT_MEMBER, exceptions[i])));
+ configuration, LinkInfoImpl.CONTEXT_MEMBER, exceptions[i])));
htmltree.addContent(exceptionLink);
}
}
@@ -246,7 +246,7 @@
return rettype.typeName().length() +
rettype.dimension().length();
} else {
- LinkInfoImpl linkInfo = new LinkInfoImpl(
+ LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_MEMBER, rettype);
writer.getLink(linkInfo);
return linkInfo.displayLength;
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractIndexWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -140,7 +140,8 @@
*/
protected void addDescription(ClassDoc cd, Content dlTree) {
Content link = new RawHtml(
- getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_INDEX, cd, true)));
+ getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.CONTEXT_INDEX, cd, true)));
Content dt = HtmlTree.DT(link);
dt.addContent(" - ");
addClassInfo(cd, dt);
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -49,15 +49,20 @@
*/
public abstract class AbstractMemberWriter {
- protected boolean printedSummaryHeader = false;
+ protected final ConfigurationImpl configuration;
protected final SubWriterHolderWriter writer;
protected final ClassDoc classdoc;
+ protected Map<String,Integer> typeMap = new LinkedHashMap<String,Integer>();
+ protected Set<MethodTypes> methodTypes = EnumSet.noneOf(MethodTypes.class);
+ private int methodTypesOr = 0;
public final boolean nodepr;
- public AbstractMemberWriter(SubWriterHolderWriter writer,
- ClassDoc classdoc) {
+ protected boolean printedSummaryHeader = false;
+
+ public AbstractMemberWriter(SubWriterHolderWriter writer, ClassDoc classdoc) {
+ this.configuration = writer.configuration;
this.writer = writer;
- this.nodepr = configuration().nodeprecated;
+ this.nodepr = configuration.nodeprecated;
this.classdoc = classdoc;
}
@@ -281,11 +286,11 @@
code.addContent(new HtmlTree(HtmlTag.BR));
}
code.addContent(new RawHtml(
- writer.getLink(new LinkInfoImpl(
+ writer.getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_SUMMARY_RETURN_TYPE, type))));
} else {
code.addContent(new RawHtml(
- writer.getLink(new LinkInfoImpl(
+ writer.getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_SUMMARY_RETURN_TYPE, type))));
}
@@ -305,7 +310,7 @@
} else if (member.isPrivate()) {
code.addContent("private ");
} else if (!member.isPublic()) { // Package private
- code.addContent(configuration().getText("doclet.Package_private"));
+ code.addContent(configuration.getText("doclet.Package_private"));
code.addContent(" ");
}
if (member.isMethod() && ((MethodDoc)member).isAbstract()) {
@@ -389,7 +394,7 @@
String tableSummary, String[] tableHeader, Content contentTree) {
if (deprmembers.size() > 0) {
Content table = HtmlTree.TABLE(0, 3, 0, tableSummary,
- writer.getTableCaption(configuration().getText(headingKey)));
+ writer.getTableCaption(configuration.getText(headingKey)));
table.addContent(writer.getSummaryTableHeader(tableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
for (int i = 0; i < deprmembers.size(); i++) {
@@ -507,8 +512,8 @@
}
protected void serialWarning(SourcePosition pos, String key, String a1, String a2) {
- if (configuration().serialwarn) {
- ConfigurationImpl.getInstance().getDocletSpecificMsg().warning(pos, key, a1, a2);
+ if (configuration.serialwarn) {
+ configuration.getDocletSpecificMsg().warning(pos, key, a1, a2);
}
}
@@ -516,21 +521,17 @@
return nodepr? Util.excludeDeprecatedMembers(members): members;
}
- public ConfigurationImpl configuration() {
- return writer.configuration;
- }
-
/**
* Add the member summary for the given class.
*
* @param classDoc the class that is being documented
* @param member the member being documented
* @param firstSentenceTags the first sentence tags to be added to the summary
- * @param tableTree the content tree to which the documentation will be added
- * @param counter the counter for determing style for the table row
+ * @param tableContents the list of contents to which the documentation will be added
+ * @param counter the counter for determining id and style for the table row
*/
public void addMemberSummary(ClassDoc classDoc, ProgramElementDoc member,
- Tag[] firstSentenceTags, Content tableTree, int counter) {
+ Tag[] firstSentenceTags, List<Content> tableContents, int counter) {
HtmlTree tdSummaryType = new HtmlTree(HtmlTag.TD);
tdSummaryType.addStyle(HtmlStyle.colFirst);
writer.addSummaryType(this, member, tdSummaryType);
@@ -540,11 +541,46 @@
writer.addSummaryLinkComment(this, member, firstSentenceTags, tdSummary);
HtmlTree tr = HtmlTree.TR(tdSummaryType);
tr.addContent(tdSummary);
+ if (member instanceof MethodDoc && !member.isAnnotationTypeElement()) {
+ int methodType = (member.isStatic()) ? MethodTypes.STATIC.value() :
+ MethodTypes.INSTANCE.value();
+ methodType = (classdoc.isInterface() || ((MethodDoc)member).isAbstract()) ?
+ methodType | MethodTypes.ABSTRACT.value() :
+ methodType | MethodTypes.CONCRETE.value();
+ if (Util.isDeprecated(member) || Util.isDeprecated(classdoc)) {
+ methodType = methodType | MethodTypes.DEPRECATED.value();
+ }
+ methodTypesOr = methodTypesOr | methodType;
+ String tableId = "i" + counter;
+ typeMap.put(tableId, methodType);
+ tr.addAttr(HtmlAttr.ID, tableId);
+ }
if (counter%2 == 0)
tr.addStyle(HtmlStyle.altColor);
else
tr.addStyle(HtmlStyle.rowColor);
- tableTree.addContent(tr);
+ tableContents.add(tr);
+ }
+
+ /**
+ * Generate the method types set and return true if the method summary table
+ * needs to show tabs.
+ *
+ * @return true if the table should show tabs
+ */
+ public boolean showTabs() {
+ int value;
+ for (MethodTypes type : EnumSet.allOf(MethodTypes.class)) {
+ value = type.value();
+ if ((value & methodTypesOr) == value) {
+ methodTypes.add(type);
+ }
+ }
+ boolean showTabs = methodTypes.size() > 1;
+ if (showTabs) {
+ methodTypes.add(MethodTypes.ALL);
+ }
+ return showTabs;
}
/**
@@ -597,10 +633,11 @@
* Get the summary table tree for the given class.
*
* @param classDoc the class for which the summary table is generated
+ * @param tableContents list of contents to be displayed in the summary table
* @return a content tree for the summary table
*/
- public Content getSummaryTableTree(ClassDoc classDoc) {
- return writer.getSummaryTableTree(this, classDoc);
+ public Content getSummaryTableTree(ClassDoc classDoc, List<Content> tableContents) {
+ return writer.getSummaryTableTree(this, classDoc, tableContents, showTabs());
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractTreeWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -138,7 +138,7 @@
for (int i = 0; i < interfaces.length; i++) {
if (parent != interfaces[i]) {
if (! (interfaces[i].isPublic() ||
- Util.isLinkable(interfaces[i], configuration()))) {
+ Util.isLinkable(interfaces[i], configuration))) {
continue;
}
if (counter == 0) {
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AllClassesFrameWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -159,10 +159,11 @@
String label = italicsClassName(cd, false);
Content linkContent;
if(wantFrames){
- linkContent = new RawHtml(getLink(new LinkInfoImpl(
+ linkContent = new RawHtml(getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.ALL_CLASSES_FRAME, cd, label, "classFrame")));
} else {
- linkContent = new RawHtml(getLink(new LinkInfoImpl(cd, label)));
+ linkContent = new RawHtml(getLink(new LinkInfoImpl(
+ configuration, cd, label)));
}
Content li = HtmlTree.LI(linkContent);
content.addContent(li);
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeOptionalMemberWriterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -103,16 +103,16 @@
* {@inheritDoc}
*/
public String getTableSummary() {
- return configuration().getText("doclet.Member_Table_Summary",
- configuration().getText("doclet.Annotation_Type_Optional_Member_Summary"),
- configuration().getText("doclet.annotation_type_optional_members"));
+ return configuration.getText("doclet.Member_Table_Summary",
+ configuration.getText("doclet.Annotation_Type_Optional_Member_Summary"),
+ configuration.getText("doclet.annotation_type_optional_members"));
}
/**
* {@inheritDoc}
*/
public String getCaption() {
- return configuration().getText("doclet.Annotation_Type_Optional_Members");
+ return configuration.getText("doclet.Annotation_Type_Optional_Members");
}
/**
@@ -121,9 +121,9 @@
public String[] getSummaryTableHeader(ProgramElementDoc member) {
String[] header = new String[] {
writer.getModifierTypeHeader(),
- configuration().getText("doclet.0_and_1",
- configuration().getText("doclet.Annotation_Type_Optional_Member"),
- configuration().getText("doclet.Description"))
+ configuration.getText("doclet.0_and_1",
+ configuration.getText("doclet.Annotation_Type_Optional_Member"),
+ configuration.getText("doclet.Description"))
};
return header;
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -52,7 +52,7 @@
* @param annotationType the AnnotationType that holds this member.
*/
public AnnotationTypeRequiredMemberWriterImpl(SubWriterHolderWriter writer,
- AnnotationTypeDoc annotationType) {
+ AnnotationTypeDoc annotationType) {
super(writer, annotationType);
}
@@ -106,11 +106,11 @@
writer.addAnnotationInfo(member, pre);
addModifiers(member, pre);
Content link = new RawHtml(
- writer.getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_MEMBER,
- getType(member))));
+ writer.getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.CONTEXT_MEMBER, getType(member))));
pre.addContent(link);
pre.addContent(writer.getSpace());
- if (configuration().linksource) {
+ if (configuration.linksource) {
Content memberName = new StringContent(member.name());
writer.addSrcLink(member, memberName, pre);
} else {
@@ -175,16 +175,16 @@
* {@inheritDoc}
*/
public String getTableSummary() {
- return configuration().getText("doclet.Member_Table_Summary",
- configuration().getText("doclet.Annotation_Type_Required_Member_Summary"),
- configuration().getText("doclet.annotation_type_required_members"));
+ return configuration.getText("doclet.Member_Table_Summary",
+ configuration.getText("doclet.Annotation_Type_Required_Member_Summary"),
+ configuration.getText("doclet.annotation_type_required_members"));
}
/**
* {@inheritDoc}
*/
public String getCaption() {
- return configuration().getText("doclet.Annotation_Type_Required_Members");
+ return configuration.getText("doclet.Annotation_Type_Required_Members");
}
/**
@@ -193,9 +193,9 @@
public String[] getSummaryTableHeader(ProgramElementDoc member) {
String[] header = new String[] {
writer.getModifierTypeHeader(),
- configuration().getText("doclet.0_and_1",
- configuration().getText("doclet.Annotation_Type_Required_Member"),
- configuration().getText("doclet.Description"))
+ configuration.getText("doclet.0_and_1",
+ configuration.getText("doclet.Annotation_Type_Required_Member"),
+ configuration.getText("doclet.Description"))
};
return header;
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AnnotationTypeWriterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -65,10 +65,10 @@
* @param prevType the previous class that was documented.
* @param nextType the next class being documented.
*/
- public AnnotationTypeWriterImpl(AnnotationTypeDoc annotationType,
- Type prevType, Type nextType)
+ public AnnotationTypeWriterImpl(ConfigurationImpl configuration,
+ AnnotationTypeDoc annotationType, Type prevType, Type nextType)
throws Exception {
- super(ConfigurationImpl.getInstance(), DocPath.forClass(annotationType));
+ super(configuration, DocPath.forClass(annotationType));
this.annotationType = annotationType;
configuration.currentcd = annotationType.asClassDoc();
this.prev = prevType;
@@ -116,7 +116,7 @@
public Content getNavLinkPrevious() {
Content li;
if (prev != null) {
- Content prevLink = new RawHtml(getLink(new LinkInfoImpl(
+ Content prevLink = new RawHtml(getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_CLASS, prev.asClassDoc(), "",
configuration.getText("doclet.Prev_Class"), true)));
li = HtmlTree.LI(prevLink);
@@ -134,7 +134,7 @@
public Content getNavLinkNext() {
Content li;
if (next != null) {
- Content nextLink = new RawHtml(getLink(new LinkInfoImpl(
+ Content nextLink = new RawHtml(getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_CLASS, next.asClassDoc(), "",
configuration.getText("doclet.Next_Class"), true)));
li = HtmlTree.LI(nextLink);
@@ -162,7 +162,7 @@
Content pkgNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, pkgNameContent);
div.addContent(pkgNameDiv);
}
- LinkInfoImpl linkInfo = new LinkInfoImpl(
+ LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_CLASS_HEADER, annotationType, false);
Content headerContent = new StringContent(header);
Content heading = HtmlTree.HEADING(HtmlConstants.CLASS_PAGE_HEADING, true,
@@ -219,11 +219,11 @@
Content pre = new HtmlTree(HtmlTag.PRE);
addAnnotationInfo(annotationType, pre);
pre.addContent(modifiers);
- LinkInfoImpl linkInfo = new LinkInfoImpl(
+ LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_CLASS_SIGNATURE, annotationType, false);
Content annotationName = new StringContent(annotationType.name());
Content parameterLinks = new RawHtml(getTypeParameterLinks(linkInfo));
- if (configuration().linksource) {
+ if (configuration.linksource) {
addSrcLink(annotationType, annotationName, pre);
pre.addContent(parameterLinks);
} else {
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassUseWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -256,9 +256,9 @@
*/
protected void addPackageList(Content contentTree) throws IOException {
Content table = HtmlTree.TABLE(0, 3, 0, useTableSummary,
- getTableCaption(configuration().getText(
+ getTableCaption(configuration.getText(
"doclet.ClassUse_Packages.that.use.0",
- getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc,
+ getLink(new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc,
false)))));
table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
@@ -287,14 +287,14 @@
protected void addPackageAnnotationList(Content contentTree) throws IOException {
if ((!classdoc.isAnnotationType()) ||
pkgToPackageAnnotations == null ||
- pkgToPackageAnnotations.size() == 0) {
+ pkgToPackageAnnotations.isEmpty()) {
return;
}
Content table = HtmlTree.TABLE(0, 3, 0, useTableSummary,
- getTableCaption(configuration().getText(
+ getTableCaption(configuration.getText(
"doclet.ClassUse_PackageAnnotation",
- getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc,
- false)))));
+ getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc, false)))));
table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
Iterator<PackageDoc> it = pkgToPackageAnnotations.iterator();
@@ -333,7 +333,7 @@
Content li = HtmlTree.LI(HtmlStyle.blockList, getMarkerAnchor(pkg.name()));
Content link = new RawHtml(
configuration.getText("doclet.ClassUse_Uses.of.0.in.1",
- getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS_USE_HEADER,
+ getLink(new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_CLASS_USE_HEADER,
classdoc, false)),
getPackageLinkString(pkg, Util.getPackageName(pkg), false)));
Content heading = HtmlTree.HEADING(HtmlConstants.SUMMARY_HEADING, link);
@@ -368,7 +368,7 @@
* @param contentTree the content tree to which the class use information will be added
*/
protected void addClassUse(PackageDoc pkg, Content contentTree) throws IOException {
- String classLink = getLink(new LinkInfoImpl(
+ String classLink = getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc, false));
String pkgLink = getPackageLinkString(pkg, Util.getPackageName(pkg), false);
classSubWriter.addUseInfo(pkgToClassAnnotations.get(pkg.name()),
@@ -477,8 +477,8 @@
*/
protected Content getNavLinkClass() {
Content linkContent = new RawHtml(getLink(new LinkInfoImpl(
- LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc, "",
- configuration.getText("doclet.Class"), false)));
+ configuration, LinkInfoImpl.CONTEXT_CLASS_USE_HEADER, classdoc,
+ "", configuration.getText("doclet.Class"), false)));
Content li = HtmlTree.LI(linkContent);
return li;
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -34,6 +34,7 @@
import com.sun.tools.doclets.internal.toolkit.builders.*;
import com.sun.tools.doclets.internal.toolkit.taglets.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
+import java.io.IOException;
/**
* Generate the Class Information Page.
@@ -56,24 +57,25 @@
public class ClassWriterImpl extends SubWriterHolderWriter
implements ClassWriter {
- protected ClassDoc classDoc;
+ protected final ClassDoc classDoc;
- protected ClassTree classtree;
+ protected final ClassTree classtree;
- protected ClassDoc prev;
+ protected final ClassDoc prev;
- protected ClassDoc next;
+ protected final ClassDoc next;
/**
+ * @param configuration the configuration data for the doclet
* @param classDoc the class being documented.
* @param prevClass the previous class that was documented.
* @param nextClass the next class being documented.
* @param classTree the class tree for the given class.
*/
- public ClassWriterImpl (ClassDoc classDoc,
+ public ClassWriterImpl (ConfigurationImpl configuration, ClassDoc classDoc,
ClassDoc prevClass, ClassDoc nextClass, ClassTree classTree)
- throws Exception {
- super(ConfigurationImpl.getInstance(), DocPath.forClass(classDoc));
+ throws IOException {
+ super(configuration, DocPath.forClass(classDoc));
this.classDoc = classDoc;
configuration.currentcd = classDoc;
this.classtree = classTree;
@@ -122,7 +124,7 @@
public Content getNavLinkPrevious() {
Content li;
if (prev != null) {
- Content prevLink = new RawHtml(getLink(new LinkInfoImpl(
+ Content prevLink = new RawHtml(getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_CLASS, prev, "",
configuration.getText("doclet.Prev_Class"), true)));
li = HtmlTree.LI(prevLink);
@@ -140,7 +142,7 @@
public Content getNavLinkNext() {
Content li;
if (next != null) {
- Content nextLink = new RawHtml(getLink(new LinkInfoImpl(
+ Content nextLink = new RawHtml(getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_CLASS, next, "",
configuration.getText("doclet.Next_Class"), true)));
li = HtmlTree.LI(nextLink);
@@ -168,8 +170,8 @@
Content pkgNameDiv = HtmlTree.DIV(HtmlStyle.subTitle, pkgNameContent);
div.addContent(pkgNameDiv);
}
- LinkInfoImpl linkInfo = new LinkInfoImpl( LinkInfoImpl.CONTEXT_CLASS_HEADER,
- classDoc, false);
+ LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
+ LinkInfoImpl.CONTEXT_CLASS_HEADER, classDoc, false);
//Let's not link to ourselves in the header.
linkInfo.linkToSelf = false;
Content headerContent = new StringContent(header);
@@ -228,13 +230,13 @@
Content pre = new HtmlTree(HtmlTag.PRE);
addAnnotationInfo(classDoc, pre);
pre.addContent(modifiers);
- LinkInfoImpl linkInfo = new LinkInfoImpl(
+ LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_CLASS_SIGNATURE, classDoc, false);
//Let's not link to ourselves in the signature.
linkInfo.linkToSelf = false;
Content className = new StringContent(classDoc.name());
Content parameterLinks = new RawHtml(getTypeParameterLinks(linkInfo));
- if (configuration().linksource) {
+ if (configuration.linksource) {
addSrcLink(classDoc, className, pre);
pre.addContent(parameterLinks);
} else {
@@ -244,11 +246,11 @@
}
if (!isInterface) {
Type superclass = Util.getFirstVisibleSuperClass(classDoc,
- configuration());
+ configuration);
if (superclass != null) {
pre.addContent(DocletConstants.NL);
pre.addContent("extends ");
- Content link = new RawHtml(getLink(new LinkInfoImpl(
+ Content link = new RawHtml(getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
superclass)));
pre.addContent(link);
@@ -260,7 +262,7 @@
for (int i = 0; i < implIntfacs.length; i++) {
ClassDoc classDoc = implIntfacs[i].asClassDoc();
if (! (classDoc.isPublic() ||
- Util.isLinkable(classDoc, configuration()))) {
+ Util.isLinkable(classDoc, configuration))) {
continue;
}
if (counter == 0) {
@@ -269,7 +271,7 @@
} else {
pre.addContent(", ");
}
- Content link = new RawHtml(getLink(new LinkInfoImpl(
+ Content link = new RawHtml(getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_CLASS_SIGNATURE_PARENT_NAME,
implIntfacs[i])));
pre.addContent(link);
@@ -315,7 +317,7 @@
do {
sup = Util.getFirstVisibleSuperClass(
type instanceof ClassDoc ? (ClassDoc) type : type.asClassDoc(),
- configuration());
+ configuration);
if (sup != null) {
HtmlTree ul = new HtmlTree(HtmlTag.UL);
ul.addStyle(HtmlStyle.inheritance);
@@ -345,7 +347,7 @@
Content li = new HtmlTree(HtmlTag.LI);
if (type.equals(classDoc)) {
String typeParameters = getTypeParameterLinks(
- new LinkInfoImpl(LinkInfoImpl.CONTEXT_TREE,
+ new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_TREE,
classDoc, false));
if (configuration.shouldExcludeQualifier(
classDoc.containingPackage().name())) {
@@ -356,7 +358,7 @@
li.addContent(new RawHtml(typeParameters));
}
} else {
- Content link = new RawHtml(getLink(new LinkInfoImpl(
+ Content link = new RawHtml(getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_CLASS_TREE_PARENT,
type instanceof ClassDoc ? (ClassDoc) type : type,
configuration.getClassName(type.asClassDoc()), false)));
@@ -504,8 +506,8 @@
Content dt = HtmlTree.DT(label);
Content dl = HtmlTree.DL(dt);
Content dd = new HtmlTree(HtmlTag.DD);
- dd.addContent(new RawHtml(getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CLASS, outerClass,
- false))));
+ dd.addContent(new RawHtml(getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.CONTEXT_CLASS, outerClass, false))));
dl.addContent(dd);
classInfoTree.addContent(dl);
}
@@ -549,11 +551,11 @@
}
if (typeList[i] instanceof ClassDoc) {
Content link = new RawHtml(getLink(
- new LinkInfoImpl(context, (ClassDoc)(typeList[i]))));
+ new LinkInfoImpl(configuration, context, (ClassDoc)(typeList[i]))));
dd.addContent(link);
} else {
Content link = new RawHtml(getLink(
- new LinkInfoImpl(context, (Type)(typeList[i]))));
+ new LinkInfoImpl(configuration, context, (Type)(typeList[i]))));
dd.addContent(link);
}
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -28,9 +28,13 @@
import java.net.*;
import java.util.*;
+import javax.tools.JavaFileManager;
+
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.util.Context;
/**
* Configure the output based on the command line options.
@@ -57,8 +61,6 @@
*/
public class ConfigurationImpl extends Configuration {
- private static ConfigurationImpl instance = new ConfigurationImpl();
-
/**
* The build date. Note: For now, we will use
* a version number instead of a date.
@@ -183,34 +185,21 @@
/**
* The classdoc for the class file getting generated.
*/
- public ClassDoc currentcd = null; // Set this classdoc in the
- // ClassWriter.
+ public ClassDoc currentcd = null; // Set this classdoc in the ClassWriter.
/**
* Constructor. Initializes resource for the
* {@link com.sun.tools.doclets.internal.toolkit.util.MessageRetriever MessageRetriever}.
*/
- private ConfigurationImpl() {
+ public ConfigurationImpl() {
standardmessage = new MessageRetriever(this,
"com.sun.tools.doclets.formats.html.resources.standard");
}
/**
- * Reset to a fresh new ConfigurationImpl, to allow multiple invocations
- * of javadoc within a single VM. It would be better not to be using
- * static fields at all, but .... (sigh).
- */
- public static void reset() {
- instance = new ConfigurationImpl();
- }
-
- public static ConfigurationImpl getInstance() {
- return instance;
- }
-
- /**
* Return the build date for the doclet.
*/
+ @Override
public String getDocletSpecificBuildDate() {
return BUILD_DATE;
}
@@ -221,6 +210,7 @@
*
* @param options The array of option names and values.
*/
+ @Override
public void setSpecificDocletOptions(String[][] options) {
for (int oi = 0; oi < options.length; ++oi) {
String[] os = options[oi];
@@ -339,6 +329,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public boolean validOptions(String options[][],
DocErrorReporter reporter) {
boolean helpfile = false;
@@ -427,6 +418,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public MessageRetriever getDocletSpecificMsg() {
return standardmessage;
}
@@ -496,6 +488,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public WriterFactory getWriterFactory() {
return new WriterFactoryImpl(this);
}
@@ -503,6 +496,7 @@
/**
* {@inheritDoc}
*/
+ @Override
public Comparator<ProgramElementDoc> getMemberComparator() {
return null;
}
@@ -510,10 +504,27 @@
/**
* {@inheritDoc}
*/
+ @Override
public Locale getLocale() {
if (root instanceof com.sun.tools.javadoc.RootDocImpl)
return ((com.sun.tools.javadoc.RootDocImpl)root).getLocale();
else
return Locale.getDefault();
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public JavaFileManager getFileManager() {
+ if (fileManager == null) {
+ if (root instanceof com.sun.tools.javadoc.RootDocImpl)
+ fileManager = ((com.sun.tools.javadoc.RootDocImpl)root).getFileManager();
+ else
+ fileManager = new JavacFileManager(new Context(), false, null);
+ }
+ return fileManager;
+ }
+
+ private JavaFileManager fileManager;
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstantsSummaryWriterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -184,9 +184,9 @@
*/
public Content getConstantMembersHeader(ClassDoc cd) {
//generate links backward only to public classes.
- String classlink = (cd.isPublic() || cd.isProtected())?
- getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_CONSTANT_SUMMARY, cd,
- false)) :
+ String classlink = (cd.isPublic() || cd.isProtected()) ?
+ getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.CONTEXT_CONSTANT_SUMMARY, cd, false)) :
cd.qualifiedName();
String name = cd.containingPackage().name();
if (name.length() > 0) {
@@ -260,7 +260,7 @@
code.addContent(modifier);
code.addContent(getSpace());
}
- Content type = new RawHtml(getLink(new LinkInfoImpl(
+ Content type = new RawHtml(getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_CONSTANT_SUMMARY, member.type())));
code.addContent(type);
tdType.addContent(code);
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -60,7 +60,7 @@
ClassDoc classDoc) {
super(writer, classDoc);
VisibleMemberMap visibleMemberMap = new VisibleMemberMap(classDoc,
- VisibleMemberMap.CONSTRUCTORS, configuration().nodeprecated);
+ VisibleMemberMap.CONSTRUCTORS, configuration.nodeprecated);
List<ProgramElementDoc> constructors = new ArrayList<ProgramElementDoc>(visibleMemberMap.getMembersFor(classDoc));
for (int i = 0; i < constructors.size(); i++) {
if ((constructors.get(i)).isProtected() ||
@@ -130,7 +130,7 @@
Content pre = new HtmlTree(HtmlTag.PRE);
writer.addAnnotationInfo(constructor, pre);
addModifiers(constructor, pre);
- if (configuration().linksource) {
+ if (configuration.linksource) {
Content constructorName = new StringContent(constructor.name());
writer.addSrcLink(constructor, constructorName, pre);
} else {
@@ -217,16 +217,16 @@
* {@inheritDoc}
*/
public String getTableSummary() {
- return configuration().getText("doclet.Member_Table_Summary",
- configuration().getText("doclet.Constructor_Summary"),
- configuration().getText("doclet.constructors"));
+ return configuration.getText("doclet.Member_Table_Summary",
+ configuration.getText("doclet.Constructor_Summary"),
+ configuration.getText("doclet.constructors"));
}
/**
* {@inheritDoc}
*/
public String getCaption() {
- return configuration().getText("doclet.Constructors");
+ return configuration.getText("doclet.Constructors");
}
/**
@@ -236,17 +236,17 @@
String[] header;
if (foundNonPubConstructor) {
header = new String[] {
- configuration().getText("doclet.Modifier"),
- configuration().getText("doclet.0_and_1",
- configuration().getText("doclet.Constructor"),
- configuration().getText("doclet.Description"))
+ configuration.getText("doclet.Modifier"),
+ configuration.getText("doclet.0_and_1",
+ configuration.getText("doclet.Constructor"),
+ configuration.getText("doclet.Description"))
};
}
else {
header = new String[] {
- configuration().getText("doclet.0_and_1",
- configuration().getText("doclet.Constructor"),
- configuration().getText("doclet.Description"))
+ configuration.getText("doclet.0_and_1",
+ configuration.getText("doclet.Constructor"),
+ configuration.getText("doclet.Description"))
};
}
return header;
@@ -313,7 +313,7 @@
code.addContent(writer.getSpace());
} else {
code.addContent(
- configuration().getText("doclet.Package_private"));
+ configuration.getText("doclet.Package_private"));
}
tdSummaryType.addContent(code);
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/EnumConstantWriterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -101,11 +101,11 @@
Content pre = new HtmlTree(HtmlTag.PRE);
writer.addAnnotationInfo(enumConstant, pre);
addModifiers(enumConstant, pre);
- Content enumConstantLink = new RawHtml(writer.getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_MEMBER,
- enumConstant.type())));
+ Content enumConstantLink = new RawHtml(writer.getLink(new LinkInfoImpl(
+ configuration, LinkInfoImpl.CONTEXT_MEMBER, enumConstant.type())));
pre.addContent(enumConstantLink);
pre.addContent(" ");
- if (configuration().linksource) {
+ if (configuration.linksource) {
Content enumConstantName = new StringContent(enumConstant.name());
writer.addSrcLink(enumConstant, enumConstantName, pre);
} else {
@@ -174,16 +174,16 @@
* {@inheritDoc}
*/
public String getTableSummary() {
- return configuration().getText("doclet.Member_Table_Summary",
- configuration().getText("doclet.Enum_Constant_Summary"),
- configuration().getText("doclet.enum_constants"));
+ return configuration.getText("doclet.Member_Table_Summary",
+ configuration.getText("doclet.Enum_Constant_Summary"),
+ configuration.getText("doclet.enum_constants"));
}
/**
* {@inheritDoc}
*/
public String getCaption() {
- return configuration().getText("doclet.Enum_Constants");
+ return configuration.getText("doclet.Enum_Constants");
}
/**
@@ -191,9 +191,9 @@
*/
public String[] getSummaryTableHeader(ProgramElementDoc member) {
String[] header = new String[] {
- configuration().getText("doclet.0_and_1",
- configuration().getText("doclet.Enum_Constant"),
- configuration().getText("doclet.Description"))
+ configuration.getText("doclet.0_and_1",
+ configuration.getText("doclet.Enum_Constant"),
+ configuration.getText("doclet.Description"))
};
return header;
}
@@ -266,7 +266,7 @@
return writer.getHyperLink((cd == null)?
"enum_constant_summary":
"enum_constants_inherited_from_class_" +
- configuration().getClassName(cd),
+ configuration.getClassName(cd),
writer.getResource("doclet.navEnum"));
} else {
return writer.getResource("doclet.navEnum");
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/FieldWriterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -102,11 +102,11 @@
Content pre = new HtmlTree(HtmlTag.PRE);
writer.addAnnotationInfo(field, pre);
addModifiers(field, pre);
- Content fieldlink = new RawHtml(writer.getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_MEMBER,
- field.type())));
+ Content fieldlink = new RawHtml(writer.getLink(new LinkInfoImpl(
+ configuration, LinkInfoImpl.CONTEXT_MEMBER, field.type())));
pre.addContent(fieldlink);
pre.addContent(" ");
- if (configuration().linksource) {
+ if (configuration.linksource) {
Content fieldName = new StringContent(field.name());
writer.addSrcLink(field, fieldName, pre);
} else {
@@ -129,7 +129,7 @@
ClassDoc holder = field.containingClass();
if (field.inlineTags().length > 0) {
if (holder.equals(classdoc) ||
- (! (holder.isPublic() || Util.isLinkable(holder, configuration())))) {
+ (! (holder.isPublic() || Util.isLinkable(holder, configuration)))) {
writer.addInlineComment(field, fieldDocTree);
} else {
Content link = new RawHtml(
@@ -195,16 +195,16 @@
* {@inheritDoc}
*/
public String getTableSummary() {
- return configuration().getText("doclet.Member_Table_Summary",
- configuration().getText("doclet.Field_Summary"),
- configuration().getText("doclet.fields"));
+ return configuration.getText("doclet.Member_Table_Summary",
+ configuration.getText("doclet.Field_Summary"),
+ configuration.getText("doclet.fields"));
}
/**
* {@inheritDoc}
*/
public String getCaption() {
- return configuration().getText("doclet.Fields");
+ return configuration.getText("doclet.Fields");
}
/**
@@ -213,9 +213,9 @@
public String[] getSummaryTableHeader(ProgramElementDoc member) {
String[] header = new String[] {
writer.getModifierTypeHeader(),
- configuration().getText("doclet.0_and_1",
- configuration().getText("doclet.Field"),
- configuration().getText("doclet.Description"))
+ configuration.getText("doclet.0_and_1",
+ configuration.getText("doclet.Field"),
+ configuration.getText("doclet.Description"))
};
return header;
}
@@ -232,7 +232,7 @@
*/
public void addInheritedSummaryAnchor(ClassDoc cd, Content inheritedTree) {
inheritedTree.addContent(writer.getMarkerAnchor(
- "fields_inherited_from_class_" + configuration().getClassName(cd)));
+ "fields_inherited_from_class_" + configuration.getClassName(cd)));
}
/**
@@ -242,8 +242,8 @@
Content classLink = new RawHtml(writer.getPreQualifiedClassLink(
LinkInfoImpl.CONTEXT_MEMBER, cd, false));
Content label = new StringContent(cd.isClass() ?
- configuration().getText("doclet.Fields_Inherited_From_Class") :
- configuration().getText("doclet.Fields_Inherited_From_Interface"));
+ configuration.getText("doclet.Fields_Inherited_From_Class") :
+ configuration.getText("doclet.Fields_Inherited_From_Interface"));
Content labelHeading = HtmlTree.HEADING(HtmlConstants.INHERITED_SUMMARY_HEADING,
label);
labelHeading.addContent(writer.getSpace());
@@ -296,7 +296,7 @@
return writer.getHyperLink((cd == null)?
"field_summary":
"fields_inherited_from_class_" +
- configuration().getClassName(cd),
+ configuration.getClassName(cd),
writer.getResource("doclet.navField"));
} else {
return writer.getResource("doclet.navField");
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java Fri Nov 30 17:09:05 2012 -0800
@@ -46,14 +46,17 @@
*
*/
public class HtmlDoclet extends AbstractDoclet {
+ // An instance will be created by validOptions, and used by start.
+ private static HtmlDoclet docletToStart = null;
+
public HtmlDoclet() {
- configuration = (ConfigurationImpl) configuration();
+ configuration = new ConfigurationImpl();
}
/**
* The global configuration information for this run.
*/
- public ConfigurationImpl configuration;
+ public final ConfigurationImpl configuration;
/**
* The "start" method as required by Javadoc.
@@ -63,12 +66,16 @@
* @return true if the doclet ran without encountering any errors.
*/
public static boolean start(RootDoc root) {
- try {
- HtmlDoclet doclet = new HtmlDoclet();
- return doclet.start(doclet, root);
- } finally {
- ConfigurationImpl.reset();
+ // In typical use, options will have been set up by calling validOptions,
+ // which will create an HtmlDoclet for use here.
+ HtmlDoclet doclet;
+ if (docletToStart != null) {
+ doclet = docletToStart;
+ docletToStart = null;
+ } else {
+ doclet = new HtmlDoclet();
}
+ return doclet.start(doclet, root);
}
/**
@@ -77,7 +84,7 @@
* configuration.
*/
public Configuration configuration() {
- return ConfigurationImpl.getInstance();
+ return configuration;
}
/**
@@ -110,6 +117,8 @@
copyResourceFile("tab.gif");
copyResourceFile("titlebar.gif");
copyResourceFile("titlebar_end.gif");
+ copyResourceFile("activetitlebar.gif");
+ copyResourceFile("activetitlebar_end.gif");
// do early to reduce memory footprint
if (configuration.classuse) {
ClassUseWriter.generate(configuration, classtree);
@@ -145,10 +154,13 @@
}
// If a stylesheet file is not specified, copy the default stylesheet
// and replace newline with platform-specific newline.
+ DocFile f;
if (configuration.stylesheetfile.length() == 0) {
- DocFile f = DocFile.createFileForOutput(configuration, DocPaths.STYLESHEET);
+ f = DocFile.createFileForOutput(configuration, DocPaths.STYLESHEET);
f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.STYLESHEET), false, true);
}
+ f = DocFile.createFileForOutput(configuration, DocPaths.JAVASCRIPT);
+ f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.JAVASCRIPT), true, true);
}
/**
@@ -220,6 +232,9 @@
}
}
+ public static final ConfigurationImpl sharedInstanceForOptions =
+ new ConfigurationImpl();
+
/**
* Check for doclet added options here.
*
@@ -228,7 +243,7 @@
*/
public static int optionLength(String option) {
// Construct temporary configuration for check
- return (ConfigurationImpl.getInstance()).optionLength(option);
+ return sharedInstanceForOptions.optionLength(option);
}
/**
@@ -244,8 +259,8 @@
*/
public static boolean validOptions(String options[][],
DocErrorReporter reporter) {
- // Construct temporary configuration for check
- return (ConfigurationImpl.getInstance()).validOptions(options, reporter);
+ docletToStart = new HtmlDoclet();
+ return docletToStart.configuration.validOptions(options, reporter);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -82,7 +82,7 @@
/**
* The global configuration information for this run.
*/
- public ConfigurationImpl configuration;
+ public final ConfigurationImpl configuration;
/**
* To check whether annotation heading is printed or not.
@@ -302,7 +302,7 @@
*/
public void printHtmlDocument(String[] metakeywords, boolean includeScript,
Content body) throws IOException {
- Content htmlDocType = DocType.Transitional();
+ Content htmlDocType = DocType.TRANSITIONAL;
Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
Content head = new HtmlTree(HtmlTag.HEAD);
if (!configuration.notimestamp) {
@@ -327,6 +327,7 @@
}
}
head.addContent(getStyleSheetProperties());
+ head.addContent(getScriptProperties());
Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
head, body);
Content htmlDocument = new HtmlDocument(htmlDocType,
@@ -835,7 +836,7 @@
String tableSummary, String[] tableHeader, Content contentTree) {
if (deprPkgs.size() > 0) {
Content table = HtmlTree.TABLE(0, 3, 0, tableSummary,
- getTableCaption(configuration().getText(headingKey)));
+ getTableCaption(configuration.getText(headingKey)));
table.addContent(getSummaryTableHeader(tableHeader, "col"));
Content tbody = new HtmlTree(HtmlTag.TBODY);
for (int i = 0; i < deprPkgs.size(); i++) {
@@ -1079,7 +1080,7 @@
* @return a content tree for the link
*/
public Content getQualifiedClassLink(int context, ClassDoc cd) {
- return new RawHtml(getLink(new LinkInfoImpl(context, cd,
+ return new RawHtml(getLink(new LinkInfoImpl(configuration, context, cd,
configuration.getClassName(cd), "")));
}
@@ -1110,7 +1111,8 @@
if(pd != null && ! configuration.shouldExcludeQualifier(pd.name())) {
classlink = getPkgName(cd);
}
- classlink += getLink(new LinkInfoImpl(context, cd, cd.name(), isStrong));
+ classlink += getLink(new LinkInfoImpl(configuration,
+ context, cd, cd.name(), isStrong));
return classlink;
}
@@ -1130,7 +1132,7 @@
if(pd != null && ! configuration.shouldExcludeQualifier(pd.name())) {
contentTree.addContent(getPkgName(cd));
}
- contentTree.addContent(new RawHtml(getLink(new LinkInfoImpl(
+ contentTree.addContent(new RawHtml(getLink(new LinkInfoImpl(configuration,
context, cd, cd.name(), isStrong))));
}
@@ -1187,14 +1189,14 @@
public String getDocLink(int context, ClassDoc classDoc, MemberDoc doc,
String label, boolean strong) {
if (! (doc.isIncluded() ||
- Util.isLinkable(classDoc, configuration()))) {
+ Util.isLinkable(classDoc, configuration))) {
return label;
} else if (doc instanceof ExecutableMemberDoc) {
ExecutableMemberDoc emd = (ExecutableMemberDoc)doc;
- return getLink(new LinkInfoImpl(context, classDoc,
+ return getLink(new LinkInfoImpl(configuration, context, classDoc,
getAnchor(emd), label, strong));
} else if (doc instanceof MemberDoc) {
- return getLink(new LinkInfoImpl(context, classDoc,
+ return getLink(new LinkInfoImpl(configuration, context, classDoc,
doc.name(), label, strong));
} else {
return label;
@@ -1215,14 +1217,14 @@
public Content getDocLink(int context, ClassDoc classDoc, MemberDoc doc,
String label) {
if (! (doc.isIncluded() ||
- Util.isLinkable(classDoc, configuration()))) {
+ Util.isLinkable(classDoc, configuration))) {
return new StringContent(label);
} else if (doc instanceof ExecutableMemberDoc) {
ExecutableMemberDoc emd = (ExecutableMemberDoc)doc;
- return new RawHtml(getLink(new LinkInfoImpl(context, classDoc,
+ return new RawHtml(getLink(new LinkInfoImpl(configuration, context, classDoc,
getAnchor(emd), label, false)));
} else if (doc instanceof MemberDoc) {
- return new RawHtml(getLink(new LinkInfoImpl(context, classDoc,
+ return new RawHtml(getLink(new LinkInfoImpl(configuration, context, classDoc,
doc.name(), label, false)));
} else {
return new StringContent(label);
@@ -1302,7 +1304,7 @@
if (label.isEmpty()) {
label = plainOrCodeText(plain, refClass.name());
}
- return getLink(new LinkInfoImpl(refClass, label));
+ return getLink(new LinkInfoImpl(configuration, refClass, label));
} else if (refMem == null) {
// Must be a member reference since refClass is not null and refMemName is not null.
// However, refMem is null, so this referenced member does not exist.
@@ -1313,7 +1315,7 @@
ClassDoc containing = refMem.containingClass();
if (see.text().trim().startsWith("#") &&
! (containing.isPublic() ||
- Util.isLinkable(containing, configuration()))) {
+ Util.isLinkable(containing, configuration))) {
// Since the link is relative and the holder is not even being
// documented, this must be an inherited link. Redirect it.
// The current class either overrides the referenced member or
@@ -1502,7 +1504,7 @@
StringBuilder textBuff = new StringBuilder();
while (lines.hasMoreTokens()) {
StringBuilder line = new StringBuilder(lines.nextToken());
- Util.replaceTabs(configuration.sourcetab, line);
+ Util.replaceTabs(configuration, line);
textBuff.append(line.toString());
}
result.append(textBuff);
@@ -1687,6 +1689,17 @@
}
/**
+ * Returns a link to the JavaScript file.
+ *
+ * @return an HtmlTree for the Script tag which provides the JavaScript location
+ */
+ public HtmlTree getScriptProperties() {
+ HtmlTree script = HtmlTree.SCRIPT("text/javascript",
+ pathToRoot.resolve(DocPaths.JAVASCRIPT).getPath());
+ return script;
+ }
+
+ /**
* According to
* <cite>The Java™ Language Specification</cite>,
* all the outer classes and static nested classes are core classes.
@@ -1784,7 +1797,7 @@
continue;
}
annotation = new StringBuilder();
- LinkInfoImpl linkInfo = new LinkInfoImpl(
+ LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_ANNOTATION, annotationDoc);
linkInfo.label = "@" + annotationDoc.name();
annotation.append(getLink(linkInfo));
@@ -1835,7 +1848,7 @@
if (annotationValue.value() instanceof Type) {
Type type = (Type) annotationValue.value();
if (type.asClassDoc() != null) {
- LinkInfoImpl linkInfo = new LinkInfoImpl(
+ LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
LinkInfoImpl.CONTEXT_ANNOTATION, type);
linkInfo.label = (type.asClassDoc().isIncluded() ?
type.typeName() :
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialFieldWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -130,7 +130,7 @@
pre.addContent(fieldTypeStr);
} else {
Content fieldContent = new RawHtml(writer.getLink(new LinkInfoImpl(
- LinkInfoImpl.CONTEXT_SERIAL_MEMBER, fieldType)));
+ configuration, LinkInfoImpl.CONTEXT_SERIAL_MEMBER, fieldType)));
pre.addContent(fieldContent);
}
pre.addContent(fieldDimensions + " ");
@@ -187,8 +187,8 @@
*/
public void addMemberTags(FieldDoc field, Content contentTree) {
TagletOutputImpl output = new TagletOutputImpl("");
- TagletWriter.genTagOuput(configuration().tagletManager, field,
- configuration().tagletManager.getCustomTags(field),
+ TagletWriter.genTagOuput(configuration.tagletManager, field,
+ configuration.tagletManager.getCustomTags(field),
writer.getTagletWriterInstance(false), output);
String outputString = output.toString().trim();
Content dlTags = new HtmlTree(HtmlTag.DL);
@@ -208,7 +208,7 @@
* @return true if overview details need to be printed
*/
public boolean shouldPrintOverview(FieldDoc field) {
- if (!configuration().nocomment) {
+ if (!configuration.nocomment) {
if(!field.commentText().isEmpty() ||
writer.hasSerializationOverviewTags(field))
return true;
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlSerialMethodWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -148,7 +148,7 @@
public void addMemberTags(MethodDoc member, Content methodsContentTree) {
TagletOutputImpl output = new TagletOutputImpl("");
TagletManager tagletManager =
- ConfigurationImpl.getInstance().tagletManager;
+ configuration.tagletManager;
TagletWriter.genTagOuput(tagletManager, member,
tagletManager.getSerializedFormTags(),
writer.getTagletWriterInstance(false), output);
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -74,7 +74,7 @@
StringBuilder label = new StringBuilder(
classLinkInfo.getClassLinkLabel(m_writer.configuration));
classLinkInfo.displayLength += label.length();
- Configuration configuration = ConfigurationImpl.getInstance();
+ Configuration configuration = m_writer.configuration;
LinkOutputImpl linkOutput = new LinkOutputImpl();
if (classDoc.isIncluded()) {
if (configuration.isGeneratedDoc(classDoc)) {
@@ -118,8 +118,8 @@
*/
protected LinkOutput getTypeParameterLink(LinkInfo linkInfo,
Type typeParam) {
- LinkInfoImpl typeLinkInfo = new LinkInfoImpl(linkInfo.getContext(),
- typeParam);
+ LinkInfoImpl typeLinkInfo = new LinkInfoImpl(m_writer.configuration,
+ linkInfo.getContext(), typeParam);
typeLinkInfo.excludeTypeBounds = linkInfo.excludeTypeBounds;
typeLinkInfo.excludeTypeParameterLinks = linkInfo.excludeTypeParameterLinks;
typeLinkInfo.linkToSelf = linkInfo.linkToSelf;
@@ -135,10 +135,10 @@
* @return the tool tip for the appropriate class.
*/
private String getClassToolTip(ClassDoc classDoc, boolean isTypeLink) {
- Configuration configuration = ConfigurationImpl.getInstance();
+ Configuration configuration = m_writer.configuration;
if (isTypeLink) {
return configuration.getText("doclet.Href_Type_Param_Title",
- classDoc.name());
+ classDoc.name());
} else if (classDoc.isInterface()){
return configuration.getText("doclet.Href_Interface_Title",
Util.getPackageName(classDoc.containingPackage()));
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -198,6 +198,8 @@
*/
public static final int CONTEXT_CLASS_USE_HEADER = 33;
+ public final ConfigurationImpl configuration;
+
/**
* The integer indicating the location of the link.
*/
@@ -214,20 +216,22 @@
public String styleName ="";
/**
- * The valueof the target.
+ * The value of the target.
*/
public String target = "";
/**
* Construct a LinkInfo object.
*
+ * @param configuration the configuration data for the doclet
* @param context the context of the link.
* @param classDoc the class to link to.
* @param label the label for the link.
* @param target the value of the target attribute.
*/
- public LinkInfoImpl (int context, ClassDoc classDoc, String label,
- String target){
+ public LinkInfoImpl(ConfigurationImpl configuration,
+ int context, ClassDoc classDoc, String label, String target) {
+ this.configuration = configuration;
this.classDoc = classDoc;
this.label = label;
this.target = target;
@@ -237,6 +241,7 @@
/**
* Construct a LinkInfo object.
*
+ * @param configuration the configuration data for the doclet
* @param context the context of the link.
* @param classDoc the class to link to.
* @param where the value of the marker #.
@@ -244,8 +249,10 @@
* @param isStrong true if the link should be strong.
* @param styleName String style of text defined in style sheet.
*/
- public LinkInfoImpl (int context, ClassDoc classDoc, String where, String label,
- boolean isStrong, String styleName){
+ public LinkInfoImpl(ConfigurationImpl configuration,
+ int context, ClassDoc classDoc, String where, String label,
+ boolean isStrong, String styleName) {
+ this.configuration = configuration;
this.classDoc = classDoc;
this.where = where;
this.label = label;
@@ -257,14 +264,17 @@
/**
* Construct a LinkInfo object.
*
+ * @param configuration the configuration data for the doclet
* @param context the context of the link.
* @param classDoc the class to link to.
* @param where the value of the marker #.
* @param label the label for the link.
* @param isStrong true if the link should be strong.
*/
- public LinkInfoImpl (int context, ClassDoc classDoc, String where, String label,
- boolean isStrong){
+ public LinkInfoImpl(ConfigurationImpl configuration,
+ int context, ClassDoc classDoc, String where, String label,
+ boolean isStrong) {
+ this.configuration = configuration;
this.classDoc = classDoc;
this.where = where;
this.label = label;
@@ -275,10 +285,13 @@
/**
* Construct a LinkInfo object.
*
+ * @param configuration the configuration data for the doclet
* @param classDoc the class to link to.
* @param label the label for the link.
*/
- public LinkInfoImpl (ClassDoc classDoc, String label){
+ public LinkInfoImpl(ConfigurationImpl configuration,
+ ClassDoc classDoc, String label) {
+ this.configuration = configuration;
this.classDoc = classDoc;
this.label = label;
setContext(context);
@@ -287,12 +300,15 @@
/**
* Construct a LinkInfo object.
*
+ * @param configuration the configuration data for the doclet
* @param context the context of the link.
* @param executableMemberDoc the member to link to.
* @param isStrong true if the link should be strong.
*/
- public LinkInfoImpl (int context, ExecutableMemberDoc executableMemberDoc,
- boolean isStrong){
+ public LinkInfoImpl(ConfigurationImpl configuration,
+ int context, ExecutableMemberDoc executableMemberDoc,
+ boolean isStrong) {
+ this.configuration = configuration;
this.executableMemberDoc = executableMemberDoc;
this.isStrong = isStrong;
setContext(context);
@@ -301,11 +317,14 @@
/**
* Construct a LinkInfo object.
*
+ * @param configuration the configuration data for the doclet
* @param context the context of the link.
* @param classDoc the class to link to.
* @param isStrong true if the link should be strong.
*/
- public LinkInfoImpl (int context, ClassDoc classDoc, boolean isStrong){
+ public LinkInfoImpl(ConfigurationImpl configuration,
+ int context, ClassDoc classDoc, boolean isStrong) {
+ this.configuration = configuration;
this.classDoc = classDoc;
this.isStrong = isStrong;
setContext(context);
@@ -314,10 +333,13 @@
/**
* Construct a LinkInfo object.
*
+ * @param configuration the configuration data for the doclet
* @param context the context of the link.
* @param type the class to link to.
*/
- public LinkInfoImpl (int context, Type type){
+ public LinkInfoImpl(ConfigurationImpl configuration,
+ int context, Type type) {
+ this.configuration = configuration;
this.type = type;
setContext(context);
}
@@ -325,11 +347,14 @@
/**
* Construct a LinkInfo object.
*
+ * @param configuration the configuration data for the doclet
* @param context the context of the link.
* @param type the class to link to.
* @param isVarArg true if this is a link to a var arg.
*/
- public LinkInfoImpl (int context, Type type, boolean isVarArg){
+ public LinkInfoImpl(ConfigurationImpl configuration,
+ int context, Type type, boolean isVarArg) {
+ this.configuration = configuration;
this.type = type;
this.isVarArg = isVarArg;
setContext(context);
@@ -338,13 +363,16 @@
/**
* Construct a LinkInfo object.
*
+ * @param configuration the configuration data for the doclet
* @param context the context of the link.
* @param type the class to link to.
* @param label the label for the link.
* @param isStrong true if the link should be strong.
*/
- public LinkInfoImpl (int context, Type type, String label,
- boolean isStrong){
+ public LinkInfoImpl(ConfigurationImpl configuration,
+ int context, Type type, String label,
+ boolean isStrong) {
+ this.configuration = configuration;
this.type = type;
this.label = label;
this.isStrong = isStrong;
@@ -354,13 +382,16 @@
/**
* Construct a LinkInfo object.
*
+ * @param configuration the configuration data for the doclet
* @param context the context of the link.
* @param classDoc the class to link to.
* @param label the label for the link.
* @param isStrong true if the link should be strong.
*/
- public LinkInfoImpl (int context, ClassDoc classDoc, String label,
- boolean isStrong){
+ public LinkInfoImpl(ConfigurationImpl configuration,
+ int context, ClassDoc classDoc, String label,
+ boolean isStrong) {
+ this.configuration = configuration;
this.classDoc = classDoc;
this.label = label;
this.isStrong = isStrong;
@@ -448,6 +479,6 @@
* desired place.
*/
public boolean isLinkable() {
- return Util.isLinkable(classDoc, ConfigurationImpl.getInstance());
+ return Util.isLinkable(classDoc, configuration);
}
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -123,7 +123,7 @@
addModifiers(method, pre);
addTypeParameters(method, pre);
addReturnType(method, pre);
- if (configuration().linksource) {
+ if (configuration.linksource) {
Content methodName = new StringContent(method.name());
writer.addSrcLink(method, methodName, pre);
} else {
@@ -149,7 +149,7 @@
if (method.inlineTags().length > 0) {
if (holder.asClassDoc().equals(classdoc) ||
(! (holderClassDoc.isPublic() ||
- Util.isLinkable(holderClassDoc, configuration())))) {
+ Util.isLinkable(holderClassDoc, configuration)))) {
writer.addInlineComment(method, methodDocTree);
} else {
Content link = new RawHtml(
@@ -215,16 +215,16 @@
* {@inheritDoc}
*/
public String getTableSummary() {
- return configuration().getText("doclet.Member_Table_Summary",
- configuration().getText("doclet.Method_Summary"),
- configuration().getText("doclet.methods"));
+ return configuration.getText("doclet.Member_Table_Summary",
+ configuration.getText("doclet.Method_Summary"),
+ configuration.getText("doclet.methods"));
}
/**
* {@inheritDoc}
*/
public String getCaption() {
- return configuration().getText("doclet.Methods");
+ return configuration.getText("doclet.Methods");
}
/**
@@ -233,9 +233,9 @@
public String[] getSummaryTableHeader(ProgramElementDoc member) {
String[] header = new String[] {
writer.getModifierTypeHeader(),
- configuration().getText("doclet.0_and_1",
- configuration().getText("doclet.Method"),
- configuration().getText("doclet.Description"))
+ configuration.getText("doclet.0_and_1",
+ configuration.getText("doclet.Method"),
+ configuration.getText("doclet.Description"))
};
return header;
}
@@ -253,7 +253,7 @@
public void addInheritedSummaryAnchor(ClassDoc cd, Content inheritedTree) {
inheritedTree.addContent(writer.getMarkerAnchor(
"methods_inherited_from_class_" +
- configuration().getClassName(cd)));
+ configuration.getClassName(cd)));
}
/**
@@ -263,8 +263,8 @@
Content classLink = new RawHtml(writer.getPreQualifiedClassLink(
LinkInfoImpl.CONTEXT_MEMBER, cd, false));
Content label = new StringContent(cd.isClass() ?
- configuration().getText("doclet.Methods_Inherited_From_Class") :
- configuration().getText("doclet.Methods_Inherited_From_Interface"));
+ configuration.getText("doclet.Methods_Inherited_From_Class") :
+ configuration.getText("doclet.Methods_Inherited_From_Interface"));
Content labelHeading = HtmlTree.HEADING(HtmlConstants.INHERITED_SUMMARY_HEADING,
label);
labelHeading.addContent(writer.getSpace());
@@ -285,12 +285,12 @@
*/
protected static void addOverridden(HtmlDocletWriter writer,
Type overriddenType, MethodDoc method, Content dl) {
- if(writer.configuration.nocomment){
+ if (writer.configuration.nocomment) {
return;
}
ClassDoc holderClassDoc = overriddenType.asClassDoc();
if (! (holderClassDoc.isPublic() ||
- Util.isLinkable(holderClassDoc, writer.configuration()))) {
+ Util.isLinkable(holderClassDoc, writer.configuration))) {
//This is an implementation detail that should not be documented.
return;
}
@@ -303,7 +303,7 @@
int context = LinkInfoImpl.CONTEXT_METHOD_OVERRIDES;
if (method != null) {
- if(overriddenType.asClassDoc().isAbstract() && method.isAbstract()){
+ if (overriddenType.asClassDoc().isAbstract() && method.isAbstract()){
//Abstract method is implemented from abstract class,
//not overridden
label = writer.specifiedByLabel;
@@ -312,11 +312,11 @@
Content dt = HtmlTree.DT(HtmlTree.STRONG(label));
dl.addContent(dt);
Content overriddenTypeLink = new RawHtml(
- writer.getLink(new LinkInfoImpl(context, overriddenType)));
+ writer.getLink(new LinkInfoImpl(writer.configuration, context, overriddenType)));
Content codeOverridenTypeLink = HtmlTree.CODE(overriddenTypeLink);
String name = method.name();
Content methlink = new RawHtml(writer.getLink(
- new LinkInfoImpl(LinkInfoImpl.CONTEXT_MEMBER,
+ new LinkInfoImpl(writer.configuration, LinkInfoImpl.CONTEXT_MEMBER,
overriddenType.asClassDoc(),
writer.getAnchor(method), name, false)));
Content codeMethLink = HtmlTree.CODE(methlink);
@@ -362,7 +362,7 @@
MethodDoc implementedMeth = implementedMethods[i];
Type intfac = implementedMethodsFinder.getMethodHolder(implementedMeth);
Content intfaclink = new RawHtml(writer.getLink(new LinkInfoImpl(
- LinkInfoImpl.CONTEXT_METHOD_SPECIFIED_BY, intfac)));
+ writer.configuration, LinkInfoImpl.CONTEXT_METHOD_SPECIFIED_BY, intfac)));
Content codeIntfacLink = HtmlTree.CODE(intfaclink);
Content dt = HtmlTree.DT(HtmlTree.STRONG(writer.specifiedByLabel));
dl.addContent(dt);
@@ -389,7 +389,7 @@
Type type = method.returnType();
if (type != null) {
Content linkContent = new RawHtml(writer.getLink(
- new LinkInfoImpl(LinkInfoImpl.CONTEXT_RETURN_TYPE, type)));
+ new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_RETURN_TYPE, type)));
htmltree.addContent(linkContent);
htmltree.addContent(writer.getSpace());
}
@@ -403,7 +403,7 @@
return writer.getHyperLink((cd == null)?
"method_summary":
"methods_inherited_from_class_" +
- configuration().getClassName(cd),
+ configuration.getClassName(cd),
writer.getResource("doclet.navMethod"));
} else {
return writer.getResource("doclet.navMethod");
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/NestedClassWriterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -93,16 +93,16 @@
* {@inheritDoc}
*/
public String getTableSummary() {
- return configuration().getText("doclet.Member_Table_Summary",
- configuration().getText("doclet.Nested_Class_Summary"),
- configuration().getText("doclet.nested_classes"));
+ return configuration.getText("doclet.Member_Table_Summary",
+ configuration.getText("doclet.Nested_Class_Summary"),
+ configuration.getText("doclet.nested_classes"));
}
/**
* {@inheritDoc}
*/
public String getCaption() {
- return configuration().getText("doclet.Nested_Classes");
+ return configuration.getText("doclet.Nested_Classes");
}
/**
@@ -113,17 +113,17 @@
if (member.isInterface()) {
header = new String[] {
writer.getModifierTypeHeader(),
- configuration().getText("doclet.0_and_1",
- configuration().getText("doclet.Interface"),
- configuration().getText("doclet.Description"))
+ configuration.getText("doclet.0_and_1",
+ configuration.getText("doclet.Interface"),
+ configuration.getText("doclet.Description"))
};
}
else {
header = new String[] {
writer.getModifierTypeHeader(),
- configuration().getText("doclet.0_and_1",
- configuration().getText("doclet.Class"),
- configuration().getText("doclet.Description"))
+ configuration.getText("doclet.0_and_1",
+ configuration.getText("doclet.Class"),
+ configuration.getText("doclet.Description"))
};
}
return header;
@@ -151,8 +151,8 @@
Content classLink = new RawHtml(writer.getPreQualifiedClassLink(
LinkInfoImpl.CONTEXT_MEMBER, cd, false));
Content label = new StringContent(cd.isInterface() ?
- configuration().getText("doclet.Nested_Classes_Interface_Inherited_From_Interface") :
- configuration().getText("doclet.Nested_Classes_Interfaces_Inherited_From_Class"));
+ configuration.getText("doclet.Nested_Classes_Interface_Inherited_From_Interface") :
+ configuration.getText("doclet.Nested_Classes_Interfaces_Inherited_From_Class"));
Content labelHeading = HtmlTree.HEADING(HtmlConstants.INHERITED_SUMMARY_HEADING,
label);
labelHeading.addContent(writer.getSpace());
@@ -166,7 +166,7 @@
protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
Content tdSummary) {
Content strong = HtmlTree.STRONG(new RawHtml(
- writer.getLink(new LinkInfoImpl(context, (ClassDoc)member, false))));
+ writer.getLink(new LinkInfoImpl(configuration, context, (ClassDoc)member, false))));
Content code = HtmlTree.CODE(strong);
tdSummary.addContent(code);
}
@@ -177,7 +177,7 @@
protected void addInheritedSummaryLink(ClassDoc cd,
ProgramElementDoc member, Content linksTree) {
linksTree.addContent(new RawHtml(
- writer.getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_MEMBER,
+ writer.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_MEMBER,
(ClassDoc)member, false))));
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageFrameWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -121,7 +121,7 @@
* @param contentTree the content tree to which the listing will be added
*/
protected void addClassListing(Content contentTree) {
- Configuration config = configuration();
+ Configuration config = configuration;
if (packageDoc.isIncluded()) {
addClassKindListing(packageDoc.interfaces(),
getResource("doclet.Interfaces"), contentTree);
@@ -181,7 +181,7 @@
contentTree.addContent(heading);
printedHeader = true;
}
- Content link = new RawHtml (getLink(new LinkInfoImpl(
+ Content link = new RawHtml (getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.PACKAGE_FRAME, arr[i],
(arr[i].isInterface() ? italicsText(arr[i].name()) :
arr[i].name()),"classFrame")));
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageUseWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -152,7 +152,7 @@
*/
protected void addPackageList(Content contentTree) throws IOException {
Content table = HtmlTree.TABLE(0, 3, 0, useTableSummary,
- getTableCaption(configuration().getText(
+ getTableCaption(configuration.getText(
"doclet.ClassUse_Packages.that.use.0",
getPackageLinkString(pkgdoc, Util.getPackageName(pkgdoc), false))));
table.addContent(getSummaryTableHeader(packageTableHeader, "col"));
@@ -197,7 +197,7 @@
String tableSummary = configuration.getText("doclet.Use_Table_Summary",
configuration.getText("doclet.classes"));
Content table = HtmlTree.TABLE(0, 3, 0, tableSummary,
- getTableCaption(configuration().getText(
+ getTableCaption(configuration.getText(
"doclet.ClassUse_Classes.in.0.used.by.1",
getPackageLinkString(pkgdoc, Util.getPackageName(pkgdoc), false),
getPackageLinkString(usingPackage,Util.getPackageName(usingPackage), false))));
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/PackageWriterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -179,7 +179,8 @@
continue;
}
Content classContent = new RawHtml(getLink(new LinkInfoImpl(
- LinkInfoImpl.CONTEXT_PACKAGE, classes[i], false)));
+ configuration, LinkInfoImpl.CONTEXT_PACKAGE, classes[i],
+ false)));
Content tdClass = HtmlTree.TD(HtmlStyle.colFirst, classContent);
HtmlTree tr = HtmlTree.TR(tdClass);
if (i%2 == 0)
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SerializedFormWriterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SerializedFormWriterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -46,11 +46,13 @@
implements SerializedFormWriter {
/**
+ * @param configuration the configuration data for the doclet
* @throws IOException
* @throws DocletAbortException
*/
- public SerializedFormWriterImpl() throws IOException {
- super(ConfigurationImpl.getInstance(), DocPaths.SERIALIZED_FORM);
+ public SerializedFormWriterImpl(ConfigurationImpl configuration)
+ throws IOException {
+ super(configuration, DocPaths.SERIALIZED_FORM);
}
/**
@@ -126,15 +128,16 @@
*/
public Content getClassHeader(ClassDoc classDoc) {
String classLink = (classDoc.isPublic() || classDoc.isProtected())?
- getLink(new LinkInfoImpl(classDoc,
+ getLink(new LinkInfoImpl(configuration, classDoc,
configuration.getClassName(classDoc))):
classDoc.qualifiedName();
Content li = HtmlTree.LI(HtmlStyle.blockList, getMarkerAnchor(
classDoc.qualifiedName()));
String superClassLink =
classDoc.superclassType() != null ?
- getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_SERIALIZED_FORM,
- classDoc.superclassType())) :
+ getLink(new LinkInfoImpl(configuration,
+ LinkInfoImpl.CONTEXT_SERIALIZED_FORM,
+ classDoc.superclassType())) :
null;
//Print the heading.
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java Fri Nov 30 17:09:05 2012 -0800
@@ -60,16 +60,24 @@
*/
private static final Content NEW_LINE = new RawHtml(DocletConstants.NL);
+ private final ConfigurationImpl configuration;
+
+ private final RootDoc rootDoc;
+
+ private DocPath outputdir;
+
/**
* Relative path from the documentation root to the file that is being
* generated.
*/
- private static DocPath relativePath = DocPath.empty;
+ private DocPath relativePath = DocPath.empty;
- /**
- * Source is converted to HTML using static methods below.
- */
- private SourceToHTMLConverter() {}
+ private SourceToHTMLConverter(ConfigurationImpl configuration, RootDoc rd,
+ DocPath outputdir) {
+ this.configuration = configuration;
+ this.rootDoc = rd;
+ this.outputdir = outputdir;
+ }
/**
* Convert the Classes in the given RootDoc to an HTML.
@@ -80,36 +88,38 @@
*/
public static void convertRoot(ConfigurationImpl configuration, RootDoc rd,
DocPath outputdir) {
- if (rd == null || outputdir == null) {
+ new SourceToHTMLConverter(configuration, rd, outputdir).generate();
+ }
+
+ void generate() {
+ if (rootDoc == null || outputdir == null) {
return;
}
- PackageDoc[] pds = rd.specifiedPackages();
+ PackageDoc[] pds = rootDoc.specifiedPackages();
for (int i = 0; i < pds.length; i++) {
// If -nodeprecated option is set and the package is marked as deprecated,
// do not convert the package files to HTML.
if (!(configuration.nodeprecated && Util.isDeprecated(pds[i])))
- convertPackage(configuration, pds[i], outputdir);
+ convertPackage(pds[i], outputdir);
}
- ClassDoc[] cds = rd.specifiedClasses();
+ ClassDoc[] cds = rootDoc.specifiedClasses();
for (int i = 0; i < cds.length; i++) {
// If -nodeprecated option is set and the class is marked as deprecated
// or the containing package is deprecated, do not convert the
// package files to HTML.
if (!(configuration.nodeprecated &&
(Util.isDeprecated(cds[i]) || Util.isDeprecated(cds[i].containingPackage()))))
- convertClass(configuration, cds[i], outputdir);
+ convertClass(cds[i], outputdir);
}
}
/**
* Convert the Classes in the given Package to an HTML.
*
- * @param configuration the configuration.
* @param pd the Package to convert.
* @param outputdir the name of the directory to output to.
*/
- public static void convertPackage(ConfigurationImpl configuration, PackageDoc pd,
- DocPath outputdir) {
+ public void convertPackage(PackageDoc pd, DocPath outputdir) {
if (pd == null) {
return;
}
@@ -120,19 +130,17 @@
// containing package deprecation since it is already check in
// the calling method above.
if (!(configuration.nodeprecated && Util.isDeprecated(cds[i])))
- convertClass(configuration, cds[i], outputdir);
+ convertClass(cds[i], outputdir);
}
}
/**
* Convert the given Class to an HTML.
*
- * @param configuration the configuration.
* @param cd the class to convert.
* @param outputdir the name of the directory to output to.
*/
- public static void convertClass(ConfigurationImpl configuration, ClassDoc cd,
- DocPath outputdir) {
+ public void convertClass(ClassDoc cd, DocPath outputdir) {
if (cd == null) {
return;
}
@@ -164,7 +172,7 @@
try {
while ((line = reader.readLine()) != null) {
addLineNo(pre, lineno);
- addLine(pre, line, configuration.sourcetab, lineno);
+ addLine(pre, line, lineno);
lineno++;
}
} finally {
@@ -173,7 +181,7 @@
addBlankLines(pre);
Content div = HtmlTree.DIV(HtmlStyle.sourceContainer, pre);
body.addContent(div);
- writeToFile(body, outputdir.resolve(DocPath.forClass(cd)), configuration);
+ writeToFile(body, outputdir.resolve(DocPath.forClass(cd)));
} catch (IOException e) {
e.printStackTrace();
}
@@ -184,15 +192,13 @@
*
* @param body the documentation content to be written to the file.
* @param path the path for the file.
- * @param configuration the Doclet configuration to pass notices to.
*/
- private static void writeToFile(Content body, DocPath path,
- ConfigurationImpl configuration) throws IOException {
- Content htmlDocType = DocType.Transitional();
+ private void writeToFile(Content body, DocPath path) throws IOException {
+ Content htmlDocType = DocType.TRANSITIONAL;
Content head = new HtmlTree(HtmlTag.HEAD);
head.addContent(HtmlTree.TITLE(new StringContent(
configuration.getText("doclet.Window_Source_title"))));
- head.addContent(getStyleSheetProperties(configuration));
+ head.addContent(getStyleSheetProperties());
Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
head, body);
Content htmlDocument = new HtmlDocument(htmlDocType, htmlTree);
@@ -210,10 +216,9 @@
/**
* Returns a link to the stylesheet file.
*
- * @param configuration the doclet configuration for the current run of javadoc
* @return an HtmlTree for the lINK tag which provides the stylesheet location
*/
- public static HtmlTree getStyleSheetProperties(ConfigurationImpl configuration) {
+ public HtmlTree getStyleSheetProperties() {
String filename = configuration.stylesheetfile;
DocPath stylesheet;
if (filename.length() > 0) {
@@ -260,14 +265,13 @@
*
* @param pre the content tree to which the line will be added.
* @param line the string to format.
- * @param tabLength the number of spaces for each tab.
* @param currentLineNo the current number.
*/
- private static void addLine(Content pre, String line, int tabLength,
- int currentLineNo) {
+ private void addLine(Content pre, String line, int currentLineNo) {
if (line != null) {
- StringBuilder lineBuffer = new StringBuilder(Util.escapeHtmlChars(line));
- Util.replaceTabs(tabLength, lineBuffer);
+ StringBuilder lineBuffer = new StringBuilder(line);
+ Util.replaceTabs(configuration, lineBuffer);
+ Util.escapeHtmlChars(lineBuffer);
pre.addContent(new RawHtml(lineBuffer.toString()));
Content anchor = HtmlTree.A_NAME("line." + Integer.toString(currentLineNo));
pre.addContent(anchor);
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/SubWriterHolderWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -26,6 +26,7 @@
package com.sun.tools.doclets.formats.html;
import java.io.*;
+import java.util.*;
import com.sun.javadoc.*;
import com.sun.tools.doclets.formats.html.markup.*;
@@ -77,16 +78,71 @@
*
* @param mw the writer for the member being documented
* @param cd the classdoc to be documented
+ * @param tableContents list of summary table contents
+ * @param showTabs true if the table needs to show tabs
* @return the content tree for the summary table
*/
- public Content getSummaryTableTree(AbstractMemberWriter mw, ClassDoc cd) {
+ public Content getSummaryTableTree(AbstractMemberWriter mw, ClassDoc cd,
+ List<Content> tableContents, boolean showTabs) {
+ Content caption;
+ if (showTabs) {
+ caption = getTableCaption(mw.methodTypes);
+ generateMethodTypesScript(mw.typeMap, mw.methodTypes);
+ }
+ else {
+ caption = getTableCaption(mw.getCaption());
+ }
Content table = HtmlTree.TABLE(HtmlStyle.overviewSummary, 0, 3, 0,
- mw.getTableSummary(), getTableCaption(mw.getCaption()));
+ mw.getTableSummary(), caption);
table.addContent(getSummaryTableHeader(mw.getSummaryTableHeader(cd), "col"));
+ for (int i = 0; i < tableContents.size(); i++) {
+ table.addContent(tableContents.get(i));
+ }
return table;
}
/**
+ * Get the summary table caption.
+ *
+ * @param methodTypes set comprising of method types to show as table caption
+ * @return the caption for the summary table
+ */
+ public Content getTableCaption(Set<MethodTypes> methodTypes) {
+ Content tabbedCaption = new HtmlTree(HtmlTag.CAPTION);
+ for (MethodTypes type : methodTypes) {
+ Content captionSpan;
+ Content span;
+ if (type.isDefaultTab()) {
+ captionSpan = HtmlTree.SPAN(new StringContent(type.text()));
+ span = HtmlTree.SPAN(type.tabId(),
+ HtmlStyle.activeTableTab, captionSpan);
+ } else {
+ captionSpan = HtmlTree.SPAN(getMethodTypeLinks(type));
+ span = HtmlTree.SPAN(type.tabId(),
+ HtmlStyle.tableTab, captionSpan);
+ }
+ Content tabSpan = HtmlTree.SPAN(HtmlStyle.tabEnd, getSpace());
+ span.addContent(tabSpan);
+ tabbedCaption.addContent(span);
+ }
+ return tabbedCaption;
+ }
+
+ /**
+ * Get the method type links for the table caption.
+ *
+ * @param methodType the method type to be displayed as link
+ * @return the content tree for the method type link
+ */
+ public Content getMethodTypeLinks(MethodTypes methodType) {
+ StringBuilder jsShow = new StringBuilder("javascript:show(");
+ jsShow.append(methodType.value()).append(");");
+ HtmlTree link = HtmlTree.A(jsShow.toString(),
+ new StringContent(methodType.text()));
+ return link;
+ }
+
+ /**
* Add the inherited summary header.
*
* @param mw the writer for the member being documented
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/TagletWriterImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -46,11 +46,13 @@
public class TagletWriterImpl extends TagletWriter {
- private HtmlDocletWriter htmlWriter;
+ private final HtmlDocletWriter htmlWriter;
+ private final ConfigurationImpl configuration;
public TagletWriterImpl(HtmlDocletWriter htmlWriter, boolean isFirstSentence) {
+ super(isFirstSentence);
this.htmlWriter = htmlWriter;
- this.isFirstSentence = isFirstSentence;
+ configuration = htmlWriter.configuration;
}
/**
@@ -64,8 +66,8 @@
* {@inheritDoc}
*/
public TagletOutput getDocRootOutput() {
- if (htmlWriter.configuration.docrootparent.length() > 0)
- return new TagletOutputImpl(htmlWriter.configuration.docrootparent);
+ if (configuration.docrootparent.length() > 0)
+ return new TagletOutputImpl(configuration.docrootparent);
else if (htmlWriter.pathToRoot.isEmpty())
return new TagletOutputImpl(".");
else
@@ -81,7 +83,7 @@
if (doc instanceof ClassDoc) {
if (Util.isDeprecated((ProgramElementDoc) doc)) {
output.append("<span class=\"strong\">" +
- ConfigurationImpl.getInstance().
+ configuration.
getText("doclet.Deprecated") + "</span> ");
if (deprs.length > 0) {
Tag[] commentTags = deprs[0].inlineTags();
@@ -97,7 +99,7 @@
MemberDoc member = (MemberDoc) doc;
if (Util.isDeprecated((ProgramElementDoc) doc)) {
output.append("<span class=\"strong\">" +
- ConfigurationImpl.getInstance().
+ configuration.
getText("doclet.Deprecated") + "</span> ");
if (deprs.length > 0) {
output.append("<i>");
@@ -108,7 +110,7 @@
} else {
if (Util.isDeprecated(member.containingClass())) {
output.append("<span class=\"strong\">" +
- ConfigurationImpl.getInstance().
+ configuration.
getText("doclet.Deprecated") + "</span> ");
}
}
@@ -120,7 +122,7 @@
* {@inheritDoc}
*/
public MessageRetriever getMsgRetriever() {
- return htmlWriter.configuration.message;
+ return configuration.message;
}
/**
@@ -147,7 +149,7 @@
*/
public TagletOutput returnTagOutput(Tag returnTag) {
TagletOutput result = new TagletOutputImpl(DocletConstants.NL + "<dt>" +
- "<span class=\"strong\">" + htmlWriter.configuration.getText("doclet.Returns") +
+ "<span class=\"strong\">" + configuration.getText("doclet.Returns") +
"</span>" + "</dt>" + "<dd>" +
htmlWriter.commentTagsToString(returnTag, null, returnTag.inlineTags(),
false) + "</dd>");
@@ -178,7 +180,7 @@
((ClassWriterImpl) htmlWriter).getClassDoc().qualifiedName() + "." + ((FieldDoc) holder).name();
DocLink link = constantsPath.fragment(whichConstant);
result += htmlWriter.getHyperLinkString(link,
- htmlWriter.configuration.getText("doclet.Constants_Summary"),
+ configuration.getText("doclet.Constants_Summary"),
false);
}
if (holder.isClass() && ((ClassDoc)holder).isSerializable()) {
@@ -189,7 +191,7 @@
DocPath serialPath = htmlWriter.pathToRoot.resolve(DocPaths.SERIALIZED_FORM);
DocLink link = serialPath.fragment(((ClassDoc)holder).qualifiedName());
result += htmlWriter.getHyperLinkString(link,
- htmlWriter.configuration.getText("doclet.Serialized_Form"), false);
+ configuration.getText("doclet.Serialized_Form"), false);
}
}
return result.equals("") ? null : new TagletOutputImpl(result + "</dd>");
@@ -200,7 +202,7 @@
return result + ", " + DocletConstants.NL;
} else {
return "<dt><span class=\"strong\">" +
- htmlWriter.configuration().getText("doclet.See_Also") + "</span></dt><dd>";
+ configuration.getText("doclet.See_Also") + "</span></dt><dd>";
}
}
@@ -234,7 +236,7 @@
*/
public TagletOutput getThrowsHeader() {
return new TagletOutputImpl(DocletConstants.NL + "<dt>" + "<span class=\"strong\">" +
- htmlWriter.configuration().getText("doclet.Throws") + "</span></dt>");
+ configuration.getText("doclet.Throws") + "</span></dt>");
}
/**
@@ -245,7 +247,7 @@
result += throwsTag.exceptionType() == null ?
htmlWriter.codeText(throwsTag.exceptionName()) :
htmlWriter.codeText(
- htmlWriter.getLink(new LinkInfoImpl(LinkInfoImpl.CONTEXT_MEMBER,
+ htmlWriter.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_MEMBER,
throwsTag.exceptionType())));
TagletOutput text = new TagletOutputImpl(
htmlWriter.commentTagsToString(throwsTag, null,
@@ -263,7 +265,7 @@
public TagletOutput throwsTagOutput(Type throwsType) {
return new TagletOutputImpl(DocletConstants.NL + "<dd>" +
htmlWriter.codeText(htmlWriter.getLink(
- new LinkInfoImpl(LinkInfoImpl.CONTEXT_MEMBER, throwsType))) + "</dd>");
+ new LinkInfoImpl(configuration, LinkInfoImpl.CONTEXT_MEMBER, throwsType))) + "</dd>");
}
/**
@@ -303,7 +305,7 @@
* {@inheritDoc}
*/
public Configuration configuration() {
- return htmlWriter.configuration();
+ return configuration;
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/WriterFactoryImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,6 +25,8 @@
package com.sun.tools.doclets.formats.html;
+import java.io.IOException;
+
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
@@ -42,7 +44,7 @@
*/
public class WriterFactoryImpl implements WriterFactory {
- private ConfigurationImpl configuration;
+ private final ConfigurationImpl configuration;
public WriterFactoryImpl(ConfigurationImpl configuration) {
this.configuration = configuration;
@@ -60,7 +62,7 @@
*/
public PackageSummaryWriter getPackageSummaryWriter(PackageDoc packageDoc,
PackageDoc prevPkg, PackageDoc nextPkg) throws Exception {
- return new PackageWriterImpl(ConfigurationImpl.getInstance(), packageDoc,
+ return new PackageWriterImpl(configuration, packageDoc,
prevPkg, nextPkg);
}
@@ -68,9 +70,9 @@
* {@inheritDoc}
*/
public ClassWriter getClassWriter(ClassDoc classDoc, ClassDoc prevClass,
- ClassDoc nextClass, ClassTree classTree)
- throws Exception {
- return new ClassWriterImpl(classDoc, prevClass, nextClass, classTree);
+ ClassDoc nextClass, ClassTree classTree) throws IOException {
+ return new ClassWriterImpl(configuration, classDoc,
+ prevClass, nextClass, classTree);
}
/**
@@ -79,7 +81,8 @@
public AnnotationTypeWriter getAnnotationTypeWriter(
AnnotationTypeDoc annotationType, Type prevType, Type nextType)
throws Exception {
- return new AnnotationTypeWriterImpl(annotationType, prevType, nextType);
+ return new AnnotationTypeWriterImpl(configuration,
+ annotationType, prevType, nextType);
}
/**
@@ -106,7 +109,7 @@
/**
* {@inheritDoc}
*/
- public EnumConstantWriter getEnumConstantWriter(ClassWriter classWriter)
+ public EnumConstantWriterImpl getEnumConstantWriter(ClassWriter classWriter)
throws Exception {
return new EnumConstantWriterImpl((SubWriterHolderWriter) classWriter,
classWriter.getClassDoc());
@@ -115,7 +118,7 @@
/**
* {@inheritDoc}
*/
- public FieldWriter getFieldWriter(ClassWriter classWriter)
+ public FieldWriterImpl getFieldWriter(ClassWriter classWriter)
throws Exception {
return new FieldWriterImpl((SubWriterHolderWriter) classWriter,
classWriter.getClassDoc());
@@ -124,7 +127,7 @@
/**
* {@inheritDoc}
*/
- public MethodWriter getMethodWriter(ClassWriter classWriter)
+ public MethodWriterImpl getMethodWriter(ClassWriter classWriter)
throws Exception {
return new MethodWriterImpl((SubWriterHolderWriter) classWriter,
classWriter.getClassDoc());
@@ -133,7 +136,7 @@
/**
* {@inheritDoc}
*/
- public ConstructorWriter getConstructorWriter(ClassWriter classWriter)
+ public ConstructorWriterImpl getConstructorWriter(ClassWriter classWriter)
throws Exception {
return new ConstructorWriterImpl((SubWriterHolderWriter) classWriter,
classWriter.getClassDoc());
@@ -143,20 +146,20 @@
* {@inheritDoc}
*/
public MemberSummaryWriter getMemberSummaryWriter(
- ClassWriter classWriter, int memberType)
- throws Exception {
+ ClassWriter classWriter, int memberType)
+ throws Exception {
switch (memberType) {
case VisibleMemberMap.CONSTRUCTORS:
- return (ConstructorWriterImpl) getConstructorWriter(classWriter);
+ return getConstructorWriter(classWriter);
case VisibleMemberMap.ENUM_CONSTANTS:
- return (EnumConstantWriterImpl) getEnumConstantWriter(classWriter);
+ return getEnumConstantWriter(classWriter);
case VisibleMemberMap.FIELDS:
- return (FieldWriterImpl) getFieldWriter(classWriter);
+ return getFieldWriter(classWriter);
case VisibleMemberMap.INNERCLASSES:
return new NestedClassWriterImpl((SubWriterHolderWriter)
classWriter, classWriter.getClassDoc());
case VisibleMemberMap.METHODS:
- return (MethodWriterImpl) getMethodWriter(classWriter);
+ return getMethodWriter(classWriter);
default:
return null;
}
@@ -184,6 +187,6 @@
* {@inheritDoc}
*/
public SerializedFormWriter getSerializedFormWriter() throws Exception {
- return new SerializedFormWriterImpl();
+ return new SerializedFormWriterImpl(configuration);
}
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/DocType.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/DocType.java Fri Nov 30 17:09:05 2012 -0800
@@ -41,13 +41,15 @@
*
* @author Bhavesh Patel
*/
-public class DocType extends Content{
+public class DocType extends Content {
private String docType;
- private static DocType transitional;
+ public static final DocType TRANSITIONAL =
+ new DocType("Transitional", "http://www.w3.org/TR/html4/loose.dtd");
- private static DocType frameset;
+ public static final DocType FRAMESET =
+ new DocType("Frameset", "http://www.w3.org/TR/html4/frameset.dtd");
/**
* Constructor to construct a DocType object.
@@ -59,28 +61,6 @@
"//EN\" \"" + dtd + "\">" + DocletConstants.NL;
}
- /**
- * Construct and return a HTML 4.01 transitional DocType content
- *
- * @return a content tree for transitional DocType
- */
- public static DocType Transitional() {
- if (transitional == null)
- transitional = new DocType("Transitional", "http://www.w3.org/TR/html4/loose.dtd");
- return transitional;
- }
-
- /**
- * Construct and return a HTML 4.01 frameset DocType content
- *
- * @return a content tree for frameset DocType
- */
- public static DocType Frameset() {
- if (frameset == null)
- frameset = new DocType("Frameset", "http://www.w3.org/TR/html4/frameset.dtd");
- return frameset;
- }
-
/**
* This method is not supported by the class.
*
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlDocWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -31,6 +31,7 @@
import com.sun.javadoc.*;
import com.sun.tools.doclets.formats.html.ConfigurationImpl;
import com.sun.tools.doclets.internal.toolkit.*;
+import com.sun.tools.doclets.internal.toolkit.util.DocFile;
import com.sun.tools.doclets.internal.toolkit.util.DocLink;
import com.sun.tools.doclets.internal.toolkit.util.DocPath;
import com.sun.tools.doclets.internal.toolkit.util.DocPaths;
@@ -63,7 +64,7 @@
throws IOException {
super(configuration, filename);
configuration.message.notice("doclet.Generating_0",
- filename.resolveAgainst(configuration.destDirName));
+ DocFile.createFileForOutput(configuration, filename).getPath());
}
/**
@@ -254,7 +255,7 @@
*/
public void printFramesetDocument(String title, boolean noTimeStamp,
Content frameset) throws IOException {
- Content htmlDocType = DocType.Frameset();
+ Content htmlDocType = DocType.FRAMESET;
Content htmlComment = new Comment(configuration.getText("doclet.New_Page"));
Content head = new HtmlTree(HtmlTag.HEAD);
if (! noTimeStamp) {
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlStyle.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlStyle.java Fri Nov 30 17:09:05 2012 -0800
@@ -37,6 +37,7 @@
*/
public enum HtmlStyle {
aboutLanguage,
+ activeTableTab,
altColor,
bar,
block,
@@ -75,6 +76,7 @@
summary,
deprecatedContent,
tabEnd,
+ tableTab,
title,
topNav;
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -494,6 +494,20 @@
}
/**
+ * Generates a SCRIPT tag with the type and src attributes.
+ *
+ * @param type type of link
+ * @param src the path for the script
+ * @return an HtmlTree object for the SCRIPT tag
+ */
+ public static HtmlTree SCRIPT(String type, String src) {
+ HtmlTree htmltree = new HtmlTree(HtmlTag.SCRIPT);
+ htmltree.addAttr(HtmlAttr.TYPE, nullCheck(type));
+ htmltree.addAttr(HtmlAttr.SRC, nullCheck(src));
+ return htmltree;
+ }
+
+ /**
* Generates a SMALL tag with some content.
*
* @param body content for the tag
@@ -540,6 +554,23 @@
}
/**
+ * Generates a SPAN tag with id and style class attributes. It also encloses
+ * a content.
+ *
+ * @param id the id for the tag
+ * @param styleClass stylesheet class for the tag
+ * @param body content for the tag
+ * @return an HtmlTree object for the SPAN tag
+ */
+ public static HtmlTree SPAN(String id, HtmlStyle styleClass, Content body) {
+ HtmlTree htmltree = new HtmlTree(HtmlTag.SPAN, nullCheck(body));
+ htmltree.addAttr(HtmlAttr.ID, nullCheck(id));
+ if (styleClass != null)
+ htmltree.addStyle(styleClass);
+ return htmltree;
+ }
+
+ /**
* Generates a Table tag with border, width and summary attributes and
* some content.
*
@@ -742,6 +773,9 @@
return (hasAttr(HtmlAttr.HREF) && !hasContent());
case META :
return (hasAttr(HtmlAttr.CONTENT) && !hasContent());
+ case SCRIPT :
+ return ((hasAttr(HtmlAttr.TYPE) && hasAttr(HtmlAttr.SRC) && !hasContent()) ||
+ (hasAttr(HtmlAttr.TYPE) && hasContent()));
default :
return hasContent();
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -26,6 +26,7 @@
package com.sun.tools.doclets.formats.html.markup;
import java.io.*;
+import java.util.*;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
@@ -144,6 +145,8 @@
private final Writer writer;
+ private Content script;
+
/**
* Constructor.
*
@@ -301,7 +304,8 @@
// Don't print windowtitle script for overview-frame, allclasses-frame
// and package-frame
if (includeScript) {
- body.addContent(getWinTitleScript());
+ this.script = getWinTitleScript();
+ body.addContent(script);
Content noScript = HtmlTree.NOSCRIPT(
HtmlTree.DIV(getResource("doclet.No_Script_Message")));
body.addContent(noScript);
@@ -310,6 +314,53 @@
}
/**
+ * Generated javascript variables for the document.
+ *
+ * @param typeMap map comprising of method and type relationship
+ * @param methodTypes set comprising of all methods types for this class
+ */
+ public void generateMethodTypesScript(Map<String,Integer> typeMap,
+ Set<MethodTypes> methodTypes) {
+ String sep = "";
+ StringBuilder vars = new StringBuilder("var methods = {");
+ for (Map.Entry<String,Integer> entry : typeMap.entrySet()) {
+ vars.append(sep);
+ sep = ",";
+ vars.append("\"");
+ vars.append(entry.getKey());
+ vars.append("\":");
+ vars.append(entry.getValue());
+ }
+ vars.append("};").append(DocletConstants.NL);
+ sep = "";
+ vars.append("var tabs = {");
+ for (MethodTypes entry : methodTypes) {
+ vars.append(sep);
+ sep = ",";
+ vars.append(entry.value()).append(":");
+ vars.append("[").append("\"").append(entry.tabId());
+ vars.append("\"").append(sep).append("\"").append(entry.text()).append("\"]");
+ }
+ vars.append("};").append(DocletConstants.NL);
+ addStyles(HtmlStyle.altColor, vars);
+ addStyles(HtmlStyle.rowColor, vars);
+ addStyles(HtmlStyle.tableTab, vars);
+ addStyles(HtmlStyle.activeTableTab, vars);
+ script.addContent(new RawHtml(vars.toString()));
+ }
+
+ /**
+ * Adds javascript style variables to the document.
+ *
+ * @param style style to be added as a javascript variable
+ * @param vars variable string to which the style variable will be added
+ */
+ public void addStyles(HtmlStyle style, StringBuilder vars) {
+ vars.append("var ").append(style).append(" = \"").append(style)
+ .append("\";").append(DocletConstants.NL);
+ }
+
+ /**
* Returns an HtmlTree for the TITLE tag.
*
* @return an HtmlTree for the TITLE tag
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties Fri Nov 30 17:09:05 2012 -0800
@@ -41,32 +41,21 @@
doclet.Help=Help
doclet.Skip_navigation_links=Skip navigation links
doclet.New_Page=NewPage
-doclet.None=None
-doclet.Factory_Method_Detail=Static Factory Method Detail
doclet.navDeprecated=Deprecated
-doclet.Deprecated_List=Deprecated List
doclet.Window_Deprecated_List=Deprecated List
-doclet.Note_0_is_deprecated=Note: {0} is deprecated.
doclet.Overrides=Overrides:
doclet.in_class=in class
-doclet.0_Fields_and_Methods="{0}" Fields and Methods
-doclet.Index_of_Fields_and_Methods=Index of Fields and Methods
doclet.Static_variable_in=Static variable in {0}
doclet.Variable_in=Variable in {0}
doclet.Constructor_for=Constructor for {0}
doclet.Static_method_in=Static method in {0}
doclet.Method_in=Method in {0}
-doclet.throws=throws
doclet.package=package
doclet.MalformedURL=Malformed URL: {0}
doclet.File_error=Error reading file: {0}
doclet.URL_error=Error fetching URL: {0}
-doclet.No_Package_Comment_File=For Package {0} Package.Comment file not found
-doclet.No_Source_For_Class=Source information for class {0} not available.
doclet.see.class_or_package_not_found=Tag {0}: reference not found: {1}
doclet.see.class_or_package_not_accessible=Tag {0}: reference not accessible: {1}
-doclet.see.malformed_tag=Tag {0}: Malformed: {1}
-doclet.Inherited_API_Summary=Inherited API Summary
doclet.Deprecated_API=Deprecated API
doclet.Deprecated_Packages=Deprecated Packages
doclet.Deprecated_Classes=Deprecated Classes
@@ -92,10 +81,7 @@
doclet.deprecated_methods=deprecated methods
doclet.deprecated_enum_constants=deprecated enum constants
doclet.deprecated_annotation_type_members=deprecated annotation type elements
-doclet.Frame_Output=Frame Output
-doclet.Docs_generated_by_Javadoc=Documentation generated by Javadoc.
doclet.Generated_Docs_Untitled=Generated Documentation (Untitled)
-doclet.Blank=Blank
doclet.Other_Packages=Other Packages
doclet.Package_Description=Package {0} Description
doclet.Description=Description
@@ -105,32 +91,22 @@
doclet.Subinterfaces=All Known Subinterfaces:
doclet.Implementing_Classes=All Known Implementing Classes:
doclet.also=also
-doclet.Option=Option
-doclet.Or=Or
doclet.Frames=Frames
doclet.No_Frames=No Frames
doclet.Package_Hierarchies=Package Hierarchies:
doclet.Hierarchy_For_Package=Hierarchy For Package {0}
-doclet.Source_Code=Source Code:
doclet.Hierarchy_For_All_Packages=Hierarchy For All Packages
-doclet.Cannot_handle_no_packages=Cannot handle no packages.
doclet.Frame_Alert=Frame Alert
-doclet.Overview-Member-Frame=Overview Member Frame
doclet.Frame_Warning_Message=This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to {0}.
doclet.No_Script_Message=JavaScript is disabled on your browser.
doclet.Non_Frame_Version=Non-frame version
-doclet.Frame_Version=Frame version
-doclet.Following_From_Class=Following copied from class: {0}
-doclet.Following_From_Interface=Following copied from interface: {0}
doclet.Description_From_Interface=Description copied from interface:
doclet.Description_From_Class=Description copied from class:
-doclet.Standard_doclet_invoked=Standard doclet invoked...
doclet.No_Non_Deprecated_Classes_To_Document=No non-deprecated classes found to document.
doclet.Interfaces_Italic=Interfaces (italic)
doclet.Enclosing_Class=Enclosing class:
doclet.Enclosing_Interface=Enclosing interface:
doclet.Window_Source_title=Source code
-doclet.Help_title=API Help
doclet.Window_Help_title=API Help
doclet.Help_line_1=How This API Document Is Organized
doclet.Help_line_2=This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
@@ -168,19 +144,6 @@
doclet.Help_annotation_type_line_1=Each annotation type has its own separate page with the following sections:
doclet.Help_annotation_type_line_2=Annotation Type declaration
doclet.Help_annotation_type_line_3=Annotation Type description
-doclet.Style_line_1=Javadoc style sheet
-doclet.Style_line_2=Define colors, fonts and other style attributes here to override the defaults
-doclet.Style_line_3=Page background color
-doclet.Style_Headings=Headings
-doclet.Style_line_4=Table colors
-doclet.Style_line_5=Dark mauve
-doclet.Style_line_6=Light mauve
-doclet.Style_line_7=White
-doclet.Style_line_8=Font used in left-hand frame lists
-doclet.Style_line_9=Example of smaller, sans-serif font in frames
-doclet.Style_line_10=Navigation bar fonts and colors
-doclet.Style_line_11=Dark Blue
-doclet.Style_line_12=Table caption style
doclet.ClassUse_Packages.that.use.0=Packages that use {0}
doclet.ClassUse_Uses.of.0.in.1=Uses of {0} in {1}
doclet.ClassUse_Classes.in.0.used.by.1=Classes in {0} used by {1}
@@ -210,12 +173,9 @@
doclet.Window_ClassUse_Header=Uses of {0} {1}
doclet.ClassUse_Title=Uses of {0}<br>{1}
doclet.navClassUse=Use
-doclet.link_option_twice=Extern URL link option (link or linkoffline) used twice.
doclet.Error_in_packagelist=Error in using -group option: {0} {1}
doclet.Groupname_already_used=In -group option, groupname already used: {0}
doclet.Same_package_name_used=Package name format used twice: {0}
-doclet.Serialization.Excluded_Class=Non-transient field {1} uses excluded class {0}.
-doclet.Serialization.Nonexcluded_Class=Non-transient field {1} uses hidden, non-included class {0}.
doclet.exception_encountered=Exception encountered while processing {1}\n{0}
doclet.usage=Provided by Standard doclet:\n\
-d <directory> Destination directory for output files\n\
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java Fri Nov 30 17:09:05 2012 -0800
@@ -51,8 +51,8 @@
/**
* The only doclet that may use this toolkit is {@value}
*/
- private static final String TOOLKIT_DOCLET_NAME = new
- com.sun.tools.doclets.formats.html.HtmlDoclet().getClass().getName();
+ private static final String TOOLKIT_DOCLET_NAME =
+ com.sun.tools.doclets.formats.html.HtmlDoclet.class.getName();
/**
* Verify that the only doclet that is using this toolkit is
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java Fri Nov 30 17:09:05 2012 -0800
@@ -32,6 +32,7 @@
import com.sun.tools.doclets.internal.toolkit.builders.BuilderFactory;
import com.sun.tools.doclets.internal.toolkit.taglets.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
+import javax.tools.JavaFileManager;
/**
* Configure the output based on the options. Doclets should sub-class
@@ -77,14 +78,16 @@
/**
* This is true if option "-serialwarn" is used. Defualt value is false to
- * supress excessive warnings about serial tag.
+ * suppress excessive warnings about serial tag.
*/
public boolean serialwarn = false;
/**
* The specified amount of space between tab stops.
*/
- public int sourcetab = DocletConstants.DEFAULT_TAB_STOP_LENGTH;
+ public int sourcetab;
+
+ public String tabSpaces;
/**
* True if we should generate browsable sources.
@@ -259,6 +262,7 @@
"com.sun.tools.doclets.internal.toolkit.resources.doclets");
excludedDocFileDirs = new HashSet<String>();
excludedQualifiers = new HashSet<String>();
+ setTabWidth(DocletConstants.DEFAULT_TAB_STOP_LENGTH);
}
/**
@@ -382,7 +386,7 @@
} else if (opt.equals("-sourcetab")) {
linksource = true;
try {
- sourcetab = Integer.parseInt(os[1]);
+ setTabWidth(Integer.parseInt(os[1]));
} catch (NumberFormatException e) {
//Set to -1 so that warning will be printed
//to indicate what is valid argument.
@@ -390,7 +394,7 @@
}
if (sourcetab <= 0) {
message.warning("doclet.sourcetab_warning");
- sourcetab = DocletConstants.DEFAULT_TAB_STOP_LENGTH;
+ setTabWidth(DocletConstants.DEFAULT_TAB_STOP_LENGTH);
}
} else if (opt.equals("-notimestamp")) {
notimestamp = true;
@@ -442,7 +446,7 @@
/**
* Initialize the taglet manager. The strings to initialize the simple custom tags should
* be in the following format: "[tag name]:[location str]:[heading]".
- * @param customTagStrs the set two dimentional arrays of strings. These arrays contain
+ * @param customTagStrs the set two dimensional arrays of strings. These arrays contain
* either -tag or -taglet arguments.
*/
private void initTagletManager(Set<String[]> customTagStrs) {
@@ -453,11 +457,11 @@
for (Iterator<String[]> it = customTagStrs.iterator(); it.hasNext(); ) {
args = it.next();
if (args[0].equals("-taglet")) {
- tagletManager.addCustomTag(args[1], tagletpath);
+ tagletManager.addCustomTag(args[1], getFileManager(), tagletpath);
continue;
}
String[] tokens = tokenize(args[1],
- TagletManager.SIMPLE_TAGLET_OPT_SEPERATOR, 3);
+ TagletManager.SIMPLE_TAGLET_OPT_SEPARATOR, 3);
if (tokens.length == 1) {
String tagName = args[1];
if (tagletManager.isKnownCustomTag(tagName)) {
@@ -749,7 +753,7 @@
* @return the input steam to the builder XML.
* @throws FileNotFoundException when the given XML file cannot be found.
*/
- public InputStream getBuilderXML() throws FileNotFoundException {
+ public InputStream getBuilderXML() throws IOException {
return builderXMLPath == null ?
Configuration.class.getResourceAsStream(DEFAULT_BUILDER_XML) :
DocFile.createFileForInput(this, builderXMLPath).openInputStream();
@@ -761,10 +765,20 @@
public abstract Locale getLocale();
/**
+ * Return the current file manager.
+ */
+ public abstract JavaFileManager getFileManager();
+
+ /**
* Return the comparator that will be used to sort member documentation.
* To no do any sorting, return null.
*
* @return the {@link java.util.Comparator} used to sort members.
*/
public abstract Comparator<ProgramElementDoc> getMemberComparator();
+
+ private void setTabWidth(int n) {
+ sourcetab = n;
+ tabSpaces = String.format("%" + n + "s", "");
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/MemberSummaryWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/MemberSummaryWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -58,9 +58,11 @@
* Get the summary table for the given class.
*
* @param classDoc the class the summary table belongs to
+ * @param tableContents list of contents that will be added to the summary table
* @return a content tree for the member summary table
*/
- public Content getSummaryTableTree(ClassDoc classDoc);
+ public Content getSummaryTableTree(ClassDoc classDoc,
+ List<Content> tableContents);
/**
* Add the member summary for the given class and member.
@@ -68,11 +70,11 @@
* @param classDoc the class the summary belongs to
* @param member the member that is documented
* @param firstSentenceTags the tags for the sentence being documented
- * @param tableTree the content treeto which the information will be added
- * @param counter the counter for determing style for the table row
+ * @param tableContents list of contents to which the summary will be added
+ * @param counter the counter for determining id and style for the table row
*/
public void addMemberSummary(ClassDoc classDoc, ProgramElementDoc member,
- Tag[] firstSentenceTags, Content tableTree, int counter);
+ Tag[] firstSentenceTags, List<Content> tableContents, int counter);
/**
* Get the inherited member summary header for the given class.
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -52,18 +52,46 @@
*/
public abstract class AbstractBuilder {
+ public static class Context {
+ /**
+ * The configuration used in this run of the doclet.
+ */
+ final Configuration configuration;
+
+ /**
+ * Keep track of which packages we have seen for
+ * efficiency purposes. We don't want to copy the
+ * doc files multiple times for a single package.
+ */
+ final Set<String> containingPackagesSeen;
+
+ /**
+ * Shared parser for the builder XML file
+ */
+ final LayoutParser layoutParser;
+
+ Context(Configuration configuration,
+ Set<String> containingPackagesSeen,
+ LayoutParser layoutParser) {
+ this.configuration = configuration;
+ this.containingPackagesSeen = containingPackagesSeen;
+ this.layoutParser = layoutParser;
+ }
+ }
/**
* The configuration used in this run of the doclet.
*/
- protected Configuration configuration;
+ protected final Configuration configuration;
/**
* Keep track of which packages we have seen for
* efficiency purposes. We don't want to copy the
* doc files multiple times for a single package.
*/
- protected static Set<String> containingPackagesSeen;
+ protected final Set<String> containingPackagesSeen;
+
+ protected final LayoutParser layoutParser;
/**
* True if we want to print debug output.
@@ -75,8 +103,10 @@
* @param configuration the configuration used in this run
* of the doclet.
*/
- public AbstractBuilder(Configuration configuration) {
- this.configuration = configuration;
+ public AbstractBuilder(Context c) {
+ this.configuration = c.configuration;
+ this.containingPackagesSeen = c.containingPackagesSeen;
+ this.layoutParser = c.layoutParser;
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractMemberBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractMemberBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,6 +25,8 @@
package com.sun.tools.doclets.internal.toolkit.builders;
+import java.util.Set;
+
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
@@ -48,8 +50,8 @@
* @param configuration the configuration used in this run
* of the doclet.
*/
- public AbstractMemberBuilder(Configuration configuration) {
- super(configuration);
+ public AbstractMemberBuilder(Context context) {
+ super(context);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -54,12 +54,12 @@
/**
* The annotation type being documented.
*/
- private AnnotationTypeDoc annotationTypeDoc;
+ private final AnnotationTypeDoc annotationTypeDoc;
/**
* The doclet specific writer.
*/
- private AnnotationTypeWriter writer;
+ private final AnnotationTypeWriter writer;
/**
* The content tree for the annotation documentation.
@@ -69,38 +69,37 @@
/**
* Construct a new ClassBuilder.
*
- * @param configuration the current configuration of the
- * doclet.
+ * @param context the build context.
+ * @param annotationTypeDoc the class being documented.
+ * @param writer the doclet specific writer.
*/
- private AnnotationTypeBuilder(Configuration configuration) {
- super(configuration);
+ private AnnotationTypeBuilder(Context context,
+ AnnotationTypeDoc annotationTypeDoc,
+ AnnotationTypeWriter writer) {
+ super(context);
+ this.annotationTypeDoc = annotationTypeDoc;
+ this.writer = writer;
}
/**
* Construct a new ClassBuilder.
*
- * @param configuration the current configuration of the doclet.
+ * @param context the build context.
* @param annotationTypeDoc the class being documented.
* @param writer the doclet specific writer.
*/
- public static AnnotationTypeBuilder getInstance(Configuration configuration,
- AnnotationTypeDoc annotationTypeDoc, AnnotationTypeWriter writer)
- throws Exception {
- AnnotationTypeBuilder builder = new AnnotationTypeBuilder(configuration);
- builder.configuration = configuration;
- builder.annotationTypeDoc = annotationTypeDoc;
- builder.writer = writer;
- if(containingPackagesSeen == null) {
- containingPackagesSeen = new HashSet<String>();
- }
- return builder;
+ public static AnnotationTypeBuilder getInstance(Context context,
+ AnnotationTypeDoc annotationTypeDoc,
+ AnnotationTypeWriter writer)
+ throws Exception {
+ return new AnnotationTypeBuilder(context, annotationTypeDoc, writer);
}
/**
* {@inheritDoc}
*/
public void build() throws IOException {
- build(LayoutParser.getInstance(configuration).parseXML(ROOT), contentTree);
+ build(layoutParser.parseXML(ROOT), contentTree);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeOptionalMemberBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeOptionalMemberBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,8 +25,6 @@
package com.sun.tools.doclets.internal.toolkit.builders;
-import java.util.*;
-
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
@@ -44,43 +42,36 @@
* @since 1.5
*/
public class AnnotationTypeOptionalMemberBuilder extends
- AnnotationTypeRequiredMemberBuilder {
+ AnnotationTypeRequiredMemberBuilder {
/**
* Construct a new AnnotationTypeMemberBuilder.
*
- * @param configuration the current configuration of the
- * doclet.
+ * @param context the build context.
+ * @param classDoc the class whose members are being documented.
+ * @param writer the doclet specific writer.
*/
- private AnnotationTypeOptionalMemberBuilder(Configuration configuration) {
- super(configuration);
+ private AnnotationTypeOptionalMemberBuilder(Context context,
+ ClassDoc classDoc,
+ AnnotationTypeOptionalMemberWriter writer) {
+ super(context, classDoc, writer,
+ VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL);
}
/**
* Construct a new AnnotationTypeMemberBuilder.
*
- * @param configuration the current configuration of the doclet.
- * @param classDoc the class whoses members are being documented.
+ * @param context the build context.
+ * @param classDoc the class whose members are being documented.
* @param writer the doclet specific writer.
*/
public static AnnotationTypeOptionalMemberBuilder getInstance(
- Configuration configuration, ClassDoc classDoc,
+ Context context, ClassDoc classDoc,
AnnotationTypeOptionalMemberWriter writer) {
- AnnotationTypeOptionalMemberBuilder builder =
- new AnnotationTypeOptionalMemberBuilder(configuration);
- builder.classDoc = classDoc;
- builder.writer = writer;
- builder.visibleMemberMap = new VisibleMemberMap(classDoc,
- VisibleMemberMap.ANNOTATION_TYPE_MEMBER_OPTIONAL, configuration.nodeprecated);
- builder.members = new ArrayList<ProgramElementDoc>(
- builder.visibleMemberMap.getMembersFor(classDoc));
- if (configuration.getMemberComparator() != null) {
- Collections.sort(builder.members,
- configuration.getMemberComparator());
- }
- return builder;
+ return new AnnotationTypeOptionalMemberBuilder(context,
+ classDoc, writer);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AnnotationTypeRequiredMemberBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -74,37 +74,40 @@
/**
* Construct a new AnnotationTypeRequiredMemberBuilder.
*
- * @param configuration the current configuration of the
- * doclet.
+ * @param context the build context.
+ * @param classDoc the class whose members are being documented.
+ * @param writer the doclet specific writer.
*/
- protected AnnotationTypeRequiredMemberBuilder(Configuration configuration) {
- super(configuration);
+ protected AnnotationTypeRequiredMemberBuilder(Context context,
+ ClassDoc classDoc,
+ AnnotationTypeRequiredMemberWriter writer,
+ int memberType) {
+ super(context);
+ this.classDoc = classDoc;
+ this.writer = writer;
+ this.visibleMemberMap = new VisibleMemberMap(classDoc, memberType,
+ configuration.nodeprecated);
+ this.members = new ArrayList<ProgramElementDoc>(
+ this.visibleMemberMap.getMembersFor(classDoc));
+ if (configuration.getMemberComparator() != null) {
+ Collections.sort(this.members, configuration.getMemberComparator());
+ }
}
/**
* Construct a new AnnotationTypeMemberBuilder.
*
- * @param configuration the current configuration of the doclet.
- * @param classDoc the class whoses members are being documented.
+ * @param context the build context.
+ * @param classDoc the class whose members are being documented.
* @param writer the doclet specific writer.
*/
public static AnnotationTypeRequiredMemberBuilder getInstance(
- Configuration configuration, ClassDoc classDoc,
+ Context context, ClassDoc classDoc,
AnnotationTypeRequiredMemberWriter writer) {
- AnnotationTypeRequiredMemberBuilder builder =
- new AnnotationTypeRequiredMemberBuilder(configuration);
- builder.classDoc = classDoc;
- builder.writer = writer;
- builder.visibleMemberMap = new VisibleMemberMap(classDoc,
- VisibleMemberMap.ANNOTATION_TYPE_MEMBER_REQUIRED, configuration.nodeprecated);
- builder.members = new ArrayList<ProgramElementDoc>(
- builder.visibleMemberMap.getMembersFor(classDoc));
- if (configuration.getMemberComparator() != null) {
- Collections.sort(builder.members,
- configuration.getMemberComparator());
- }
- return builder;
+ return new AnnotationTypeRequiredMemberBuilder(context, classDoc,
+ writer,
+ VisibleMemberMap.ANNOTATION_TYPE_MEMBER_REQUIRED);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/BuilderFactory.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,6 +25,9 @@
package com.sun.tools.doclets.internal.toolkit.builders;
+import java.util.HashSet;
+import java.util.Set;
+
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
@@ -46,12 +49,14 @@
/**
* The current configuration of the doclet.
*/
- private Configuration configuration;
+ private final Configuration configuration;
/**
* The factory to retrieve the required writers from.
*/
- private WriterFactory writerFactory;
+ private final WriterFactory writerFactory;
+
+ private final AbstractBuilder.Context context;
/**
* Construct a builder factory using the given configuration.
@@ -61,6 +66,10 @@
public BuilderFactory (Configuration configuration) {
this.configuration = configuration;
this.writerFactory = configuration.getWriterFactory();
+
+ Set<String> containingPackagesSeen = new HashSet<String>();
+ context = new AbstractBuilder.Context(configuration, containingPackagesSeen,
+ LayoutParser.getInstance(configuration));
}
/**
@@ -68,7 +77,7 @@
* @return the builder that builds the constant summary.
*/
public AbstractBuilder getConstantsSummaryBuider() throws Exception {
- return ConstantsSummaryBuilder.getInstance(configuration,
+ return ConstantsSummaryBuilder.getInstance(context,
writerFactory.getConstantsSummaryWriter());
}
@@ -82,7 +91,7 @@
*/
public AbstractBuilder getPackageSummaryBuilder(PackageDoc pkg, PackageDoc prevPkg,
PackageDoc nextPkg) throws Exception {
- return PackageSummaryBuilder.getInstance(configuration, pkg,
+ return PackageSummaryBuilder.getInstance(context, pkg,
writerFactory.getPackageSummaryWriter(pkg, prevPkg, nextPkg));
}
@@ -97,9 +106,9 @@
* writer is not supported by the doclet.
*/
public AbstractBuilder getClassBuilder(ClassDoc classDoc,
- ClassDoc prevClass, ClassDoc nextClass, ClassTree classTree)
+ ClassDoc prevClass, ClassDoc nextClass, ClassTree classTree)
throws Exception {
- return ClassBuilder.getInstance(configuration, classDoc,
+ return ClassBuilder.getInstance(context, classDoc,
writerFactory.getClassWriter(classDoc, prevClass, nextClass,
classTree));
}
@@ -117,9 +126,8 @@
AnnotationTypeDoc annotationType,
Type prevType, Type nextType)
throws Exception {
- return AnnotationTypeBuilder.getInstance(configuration, annotationType,
- writerFactory.getAnnotationTypeWriter(annotationType, prevType,
- nextType));
+ return AnnotationTypeBuilder.getInstance(context, annotationType,
+ writerFactory.getAnnotationTypeWriter(annotationType, prevType, nextType));
}
/**
@@ -129,7 +137,7 @@
*/
public AbstractBuilder getMethodBuilder(ClassWriter classWriter)
throws Exception {
- return MethodBuilder.getInstance(configuration,
+ return MethodBuilder.getInstance(context,
classWriter.getClassDoc(),
writerFactory.getMethodWriter(classWriter));
}
@@ -144,7 +152,7 @@
public AbstractBuilder getAnnotationTypeOptionalMemberBuilder(
AnnotationTypeWriter annotationTypeWriter)
throws Exception {
- return AnnotationTypeOptionalMemberBuilder.getInstance(configuration,
+ return AnnotationTypeOptionalMemberBuilder.getInstance(context,
annotationTypeWriter.getAnnotationTypeDoc(),
writerFactory.getAnnotationTypeOptionalMemberWriter(
annotationTypeWriter));
@@ -160,7 +168,7 @@
public AbstractBuilder getAnnotationTypeRequiredMemberBuilder(
AnnotationTypeWriter annotationTypeWriter)
throws Exception {
- return AnnotationTypeRequiredMemberBuilder.getInstance(configuration,
+ return AnnotationTypeRequiredMemberBuilder.getInstance(context,
annotationTypeWriter.getAnnotationTypeDoc(),
writerFactory.getAnnotationTypeRequiredMemberWriter(
annotationTypeWriter));
@@ -173,7 +181,7 @@
*/
public AbstractBuilder getEnumConstantsBuilder(ClassWriter classWriter)
throws Exception {
- return EnumConstantBuilder.getInstance(configuration, classWriter.getClassDoc(),
+ return EnumConstantBuilder.getInstance(context, classWriter.getClassDoc(),
writerFactory.getEnumConstantWriter(classWriter));
}
@@ -184,7 +192,7 @@
*/
public AbstractBuilder getFieldBuilder(ClassWriter classWriter)
throws Exception {
- return FieldBuilder.getInstance(configuration, classWriter.getClassDoc(),
+ return FieldBuilder.getInstance(context, classWriter.getClassDoc(),
writerFactory.getFieldWriter(classWriter));
}
@@ -195,9 +203,9 @@
*/
public AbstractBuilder getConstructorBuilder(ClassWriter classWriter)
throws Exception {
- return ConstructorBuilder.getInstance(configuration,
- classWriter.getClassDoc(), writerFactory.getConstructorWriter(
- classWriter));
+ return ConstructorBuilder.getInstance(context,
+ classWriter.getClassDoc(),
+ writerFactory.getConstructorWriter(classWriter));
}
/**
@@ -207,7 +215,7 @@
*/
public AbstractBuilder getMemberSummaryBuilder(ClassWriter classWriter)
throws Exception {
- return MemberSummaryBuilder.getInstance(classWriter, configuration);
+ return MemberSummaryBuilder.getInstance(classWriter, context);
}
/**
@@ -220,8 +228,7 @@
public AbstractBuilder getMemberSummaryBuilder(
AnnotationTypeWriter annotationTypeWriter)
throws Exception {
- return MemberSummaryBuilder.getInstance(annotationTypeWriter,
- configuration);
+ return MemberSummaryBuilder.getInstance(annotationTypeWriter, context);
}
/**
@@ -231,6 +238,6 @@
*/
public AbstractBuilder getSerializedFormBuilder()
throws Exception {
- return SerializedFormBuilder.getInstance(configuration);
+ return SerializedFormBuilder.getInstance(context);
}
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -54,22 +54,22 @@
/**
* The class being documented.
*/
- private ClassDoc classDoc;
+ private final ClassDoc classDoc;
/**
* The doclet specific writer.
*/
- private ClassWriter writer;
+ private final ClassWriter writer;
/**
* Keep track of whether or not this classdoc is an interface.
*/
- private boolean isInterface = false;
+ private final boolean isInterface;
/**
* Keep track of whether or not this classdoc is an enum.
*/
- private boolean isEnum = false;
+ private final boolean isEnum;
/**
* The content tree for the class documentation.
@@ -79,44 +79,45 @@
/**
* Construct a new ClassBuilder.
*
- * @param configuration the current configuration of the
- * doclet.
+ * @param context the build context
+ * @param classDoc the class being documented.
+ * @param writer the doclet specific writer.
*/
- private ClassBuilder(Configuration configuration) {
- super(configuration);
+ private ClassBuilder(Context context,
+ ClassDoc classDoc, ClassWriter writer) {
+ super(context);
+ this.classDoc = classDoc;
+ this.writer = writer;
+ if (classDoc.isInterface()) {
+ isInterface = true;
+ isEnum = false;
+ } else if (classDoc.isEnum()) {
+ isInterface = false;
+ isEnum = true;
+ Util.setEnumDocumentation(configuration, classDoc);
+ } else {
+ isInterface = false;
+ isEnum = false;
+ }
}
/**
* Construct a new ClassBuilder.
*
- * @param configuration the current configuration of the doclet.
+ * @param context the build context
* @param classDoc the class being documented.
* @param writer the doclet specific writer.
*/
- public static ClassBuilder getInstance(Configuration configuration,
- ClassDoc classDoc, ClassWriter writer)
- throws Exception {
- ClassBuilder builder = new ClassBuilder(configuration);
- builder.configuration = configuration;
- builder.classDoc = classDoc;
- builder.writer = writer;
- if (classDoc.isInterface()) {
- builder.isInterface = true;
- } else if (classDoc.isEnum()) {
- builder.isEnum = true;
- Util.setEnumDocumentation(configuration, classDoc);
- }
- if(containingPackagesSeen == null) {
- containingPackagesSeen = new HashSet<String>();
- }
- return builder;
+ public static ClassBuilder getInstance(Context context,
+ ClassDoc classDoc, ClassWriter writer) {
+ return new ClassBuilder(context, classDoc, writer);
}
/**
* {@inheritDoc}
*/
public void build() throws IOException {
- build(LayoutParser.getInstance(configuration).parseXML(ROOT), contentTree);
+ build(layoutParser.parseXML(ROOT), contentTree);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ConstantsSummaryBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ConstantsSummaryBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -60,12 +60,12 @@
/**
* The writer used to write the results.
*/
- protected ConstantsSummaryWriter writer;
+ protected final ConstantsSummaryWriter writer;
/**
* The set of ClassDocs that have constant fields.
*/
- protected Set<ClassDoc> classDocsWithConstFields;
+ protected final Set<ClassDoc> classDocsWithConstFields;
/**
* The set of printed package headers.
@@ -90,27 +90,25 @@
/**
* Construct a new ConstantsSummaryBuilder.
*
- * @param configuration the current configuration of the
- * doclet.
+ * @param context the build context.
+ * @param writer the writer for the summary.
*/
- private ConstantsSummaryBuilder(Configuration configuration) {
- super(configuration);
+ private ConstantsSummaryBuilder(Context context,
+ ConstantsSummaryWriter writer) {
+ super(context);
+ this.writer = writer;
+ this.classDocsWithConstFields = new HashSet<ClassDoc>();
}
/**
* Construct a ConstantsSummaryBuilder.
*
- * @param configuration the configuration used in this run
- * of the doclet.
+ * @param context the build context.
* @param writer the writer for the summary.
*/
- public static ConstantsSummaryBuilder getInstance(
- Configuration configuration, ConstantsSummaryWriter writer) {
- ConstantsSummaryBuilder builder = new ConstantsSummaryBuilder(
- configuration);
- builder.writer = writer;
- builder.classDocsWithConstFields = new HashSet<ClassDoc>();
- return builder;
+ public static ConstantsSummaryBuilder getInstance(Context context,
+ ConstantsSummaryWriter writer) {
+ return new ConstantsSummaryBuilder(context, writer);
}
/**
@@ -121,7 +119,7 @@
//Doclet does not support this output.
return;
}
- build(LayoutParser.getInstance(configuration).parseXML(ROOT), contentTree);
+ build(layoutParser.parseXML(ROOT), contentTree);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ConstructorBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ConstructorBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -59,66 +59,64 @@
/**
* The class whose constructors are being documented.
*/
- private ClassDoc classDoc;
+ private final ClassDoc classDoc;
/**
* The visible constructors for the given class.
*/
- private VisibleMemberMap visibleMemberMap;
+ private final VisibleMemberMap visibleMemberMap;
/**
* The writer to output the constructor documentation.
*/
- private ConstructorWriter writer;
+ private final ConstructorWriter writer;
/**
* The constructors being documented.
*/
- private List<ProgramElementDoc> constructors;
+ private final List<ProgramElementDoc> constructors;
/**
* Construct a new ConstructorBuilder.
*
- * @param configuration the current configuration of the
- * doclet.
+ * @param context the build context.
+ * @param classDoc the class whoses members are being documented.
+ * @param writer the doclet specific writer.
*/
- private ConstructorBuilder(Configuration configuration) {
- super(configuration);
+ private ConstructorBuilder(Context context,
+ ClassDoc classDoc,
+ ConstructorWriter writer) {
+ super(context);
+ this.classDoc = classDoc;
+ this.writer = writer;
+ visibleMemberMap =
+ new VisibleMemberMap(
+ classDoc,
+ VisibleMemberMap.CONSTRUCTORS,
+ configuration.nodeprecated);
+ constructors =
+ new ArrayList<ProgramElementDoc>(visibleMemberMap.getMembersFor(classDoc));
+ for (int i = 0; i < constructors.size(); i++) {
+ if (constructors.get(i).isProtected()
+ || constructors.get(i).isPrivate()) {
+ writer.setFoundNonPubConstructor(true);
+ }
+ }
+ if (configuration.getMemberComparator() != null) {
+ Collections.sort(constructors,configuration.getMemberComparator());
+ }
}
/**
* Construct a new ConstructorBuilder.
*
- * @param configuration the current configuration of the doclet.
+ * @param context the build context.
* @param classDoc the class whoses members are being documented.
* @param writer the doclet specific writer.
*/
- public static ConstructorBuilder getInstance(
- Configuration configuration,
- ClassDoc classDoc,
- ConstructorWriter writer) {
- ConstructorBuilder builder = new ConstructorBuilder(configuration);
- builder.classDoc = classDoc;
- builder.writer = writer;
- builder.visibleMemberMap =
- new VisibleMemberMap(
- classDoc,
- VisibleMemberMap.CONSTRUCTORS,
- configuration.nodeprecated);
- builder.constructors =
- new ArrayList<ProgramElementDoc>(builder.visibleMemberMap.getMembersFor(classDoc));
- for (int i = 0; i < builder.constructors.size(); i++) {
- if (builder.constructors.get(i).isProtected()
- || builder.constructors.get(i).isPrivate()) {
- writer.setFoundNonPubConstructor(true);
- }
- }
- if (configuration.getMemberComparator() != null) {
- Collections.sort(
- builder.constructors,
- configuration.getMemberComparator());
- }
- return builder;
+ public static ConstructorBuilder getInstance(Context context,
+ ClassDoc classDoc, ConstructorWriter writer) {
+ return new ConstructorBuilder(context, classDoc, writer);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/EnumConstantBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/EnumConstantBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -48,22 +48,22 @@
/**
* The class whose enum constants are being documented.
*/
- private ClassDoc classDoc;
+ private final ClassDoc classDoc;
/**
* The visible enum constantss for the given class.
*/
- private VisibleMemberMap visibleMemberMap;
+ private final VisibleMemberMap visibleMemberMap;
/**
* The writer to output the enum constants documentation.
*/
- private EnumConstantWriter writer;
+ private final EnumConstantWriter writer;
/**
* The list of enum constants being documented.
*/
- private List<ProgramElementDoc> enumConstants;
+ private final List<ProgramElementDoc> enumConstants;
/**
* The index of the current enum constant that is being documented at this point
@@ -74,40 +74,37 @@
/**
* Construct a new EnumConstantsBuilder.
*
- * @param configuration the current configuration of the
- * doclet.
+ * @param context the build context.
+ * @param classDoc the class whoses members are being documented.
+ * @param writer the doclet specific writer.
*/
- private EnumConstantBuilder(Configuration configuration) {
- super(configuration);
+ private EnumConstantBuilder(Context context,
+ ClassDoc classDoc, EnumConstantWriter writer) {
+ super(context);
+ this.classDoc = classDoc;
+ this.writer = writer;
+ visibleMemberMap =
+ new VisibleMemberMap(
+ classDoc,
+ VisibleMemberMap.ENUM_CONSTANTS,
+ configuration.nodeprecated);
+ enumConstants =
+ new ArrayList<ProgramElementDoc>(visibleMemberMap.getMembersFor(classDoc));
+ if (configuration.getMemberComparator() != null) {
+ Collections.sort(enumConstants, configuration.getMemberComparator());
+ }
}
/**
* Construct a new EnumConstantsBuilder.
*
- * @param configuration the current configuration of the doclet.
+ * @param context the build context.
* @param classDoc the class whoses members are being documented.
* @param writer the doclet specific writer.
*/
- public static EnumConstantBuilder getInstance(
- Configuration configuration,
- ClassDoc classDoc,
- EnumConstantWriter writer) {
- EnumConstantBuilder builder = new EnumConstantBuilder(configuration);
- builder.classDoc = classDoc;
- builder.writer = writer;
- builder.visibleMemberMap =
- new VisibleMemberMap(
- classDoc,
- VisibleMemberMap.ENUM_CONSTANTS,
- configuration.nodeprecated);
- builder.enumConstants =
- new ArrayList<ProgramElementDoc>(builder.visibleMemberMap.getMembersFor(classDoc));
- if (configuration.getMemberComparator() != null) {
- Collections.sort(
- builder.enumConstants,
- configuration.getMemberComparator());
- }
- return builder;
+ public static EnumConstantBuilder getInstance(Context context,
+ ClassDoc classDoc, EnumConstantWriter writer) {
+ return new EnumConstantBuilder(context, classDoc, writer);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/FieldBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/FieldBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -48,22 +48,22 @@
/**
* The class whose fields are being documented.
*/
- private ClassDoc classDoc;
+ private final ClassDoc classDoc;
/**
* The visible fields for the given class.
*/
- private VisibleMemberMap visibleMemberMap;
+ private final VisibleMemberMap visibleMemberMap;
/**
* The writer to output the field documentation.
*/
- private FieldWriter writer;
+ private final FieldWriter writer;
/**
* The list of fields being documented.
*/
- private List<ProgramElementDoc> fields;
+ private final List<ProgramElementDoc> fields;
/**
* The index of the current field that is being documented at this point
@@ -74,41 +74,40 @@
/**
* Construct a new FieldBuilder.
*
- * @param configuration the current configuration of the
- * doclet.
+ * @param context the build context.
+ * @param classDoc the class whoses members are being documented.
+ * @param writer the doclet specific writer.
*/
- private FieldBuilder(Configuration configuration) {
- super(configuration);
+ private FieldBuilder(Context context,
+ ClassDoc classDoc,
+ FieldWriter writer) {
+ super(context);
+ this.classDoc = classDoc;
+ this.writer = writer;
+ visibleMemberMap =
+ new VisibleMemberMap(
+ classDoc,
+ VisibleMemberMap.FIELDS,
+ configuration.nodeprecated);
+ fields =
+ new ArrayList<ProgramElementDoc>(visibleMemberMap.getLeafClassMembers(
+ configuration));
+ if (configuration.getMemberComparator() != null) {
+ Collections.sort(fields, configuration.getMemberComparator());
+ }
}
/**
* Construct a new FieldBuilder.
*
- * @param configuration the current configuration of the doclet.
+ * @param context the build context.
* @param classDoc the class whoses members are being documented.
* @param writer the doclet specific writer.
*/
- public static FieldBuilder getInstance(
- Configuration configuration,
+ public static FieldBuilder getInstance(Context context,
ClassDoc classDoc,
FieldWriter writer) {
- FieldBuilder builder = new FieldBuilder(configuration);
- builder.classDoc = classDoc;
- builder.writer = writer;
- builder.visibleMemberMap =
- new VisibleMemberMap(
- classDoc,
- VisibleMemberMap.FIELDS,
- configuration.nodeprecated);
- builder.fields =
- new ArrayList<ProgramElementDoc>(builder.visibleMemberMap.getLeafClassMembers(
- configuration));
- if (configuration.getMemberComparator() != null) {
- Collections.sort(
- builder.fields,
- configuration.getMemberComparator());
- }
- return builder;
+ return new FieldBuilder(context, classDoc, writer);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/LayoutParser.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/LayoutParser.java Fri Nov 30 17:09:05 2012 -0800
@@ -55,14 +55,10 @@
*/
private Map<String,XMLNode> xmlElementsMap;
private XMLNode currentNode;
- private Configuration configuration;
- private static LayoutParser instance;
+ private final Configuration configuration;
private String currentRoot;
private boolean isParsing;
- /**
- * This class is a singleton.
- */
private LayoutParser(Configuration configuration) {
xmlElementsMap = new HashMap<String,XMLNode>();
this.configuration = configuration;
@@ -75,10 +71,7 @@
* @return an instance of the BuilderXML.
*/
public static LayoutParser getInstance(Configuration configuration) {
- if (instance == null) {
- instance = new LayoutParser(configuration);
- }
- return instance;
+ return new LayoutParser(configuration);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -53,7 +53,7 @@
/**
* The visible members for the given class.
*/
- private VisibleMemberMap[] visibleMemberMaps;
+ private final VisibleMemberMap[] visibleMemberMaps;
/**
* The member summary writers for the given class.
@@ -63,10 +63,27 @@
/**
* The type being documented.
*/
- private ClassDoc classDoc;
+ private final ClassDoc classDoc;
- private MemberSummaryBuilder(Configuration configuration) {
- super(configuration);
+ /**
+ * Construct a new MemberSummaryBuilder.
+ *
+ * @param classWriter the writer for the class whose members are being
+ * summarized.
+ * @param context the build context.
+ */
+ private MemberSummaryBuilder(Context context, ClassDoc classDoc) {
+ super(context);
+ this.classDoc = classDoc;
+ visibleMemberMaps =
+ new VisibleMemberMap[VisibleMemberMap.NUM_MEMBER_TYPES];
+ for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
+ visibleMemberMaps[i] =
+ new VisibleMemberMap(
+ classDoc,
+ i,
+ configuration.nodeprecated);
+ }
}
/**
@@ -74,14 +91,22 @@
*
* @param classWriter the writer for the class whose members are being
* summarized.
- * @param configuration the current configuration of the doclet.
+ * @param context the build context.
*/
public static MemberSummaryBuilder getInstance(
- ClassWriter classWriter, Configuration configuration)
+ ClassWriter classWriter, Context context)
throws Exception {
- MemberSummaryBuilder builder = new MemberSummaryBuilder(configuration);
- builder.classDoc = classWriter.getClassDoc();
- builder.init(classWriter);
+ MemberSummaryBuilder builder = new MemberSummaryBuilder(context,
+ classWriter.getClassDoc());
+ builder.memberSummaryWriters =
+ new MemberSummaryWriter[VisibleMemberMap.NUM_MEMBER_TYPES];
+ WriterFactory wf = context.configuration.getWriterFactory();
+ for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
+ builder.memberSummaryWriters[i] =
+ builder.visibleMemberMaps[i].noVisibleMembers() ?
+ null :
+ wf.getMemberSummaryWriter(classWriter, i);
+ }
return builder;
}
@@ -93,42 +118,21 @@
* @param configuration the current configuration of the doclet.
*/
public static MemberSummaryBuilder getInstance(
- AnnotationTypeWriter annotationTypeWriter, Configuration configuration)
+ AnnotationTypeWriter annotationTypeWriter, Context context)
throws Exception {
- MemberSummaryBuilder builder = new MemberSummaryBuilder(configuration);
- builder.classDoc = annotationTypeWriter.getAnnotationTypeDoc();
- builder.init(annotationTypeWriter);
- return builder;
- }
-
- private void init(Object writer) throws Exception {
- visibleMemberMaps =
- new VisibleMemberMap[VisibleMemberMap.NUM_MEMBER_TYPES];
+ MemberSummaryBuilder builder = new MemberSummaryBuilder(context,
+ annotationTypeWriter.getAnnotationTypeDoc());
+ builder.memberSummaryWriters =
+ new MemberSummaryWriter[VisibleMemberMap.NUM_MEMBER_TYPES];
+ WriterFactory wf = context.configuration.getWriterFactory();
for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
- visibleMemberMaps[i] =
- new VisibleMemberMap(
- classDoc,
- i,
- configuration.nodeprecated);
+ builder.memberSummaryWriters[i] =
+ builder.visibleMemberMaps[i].noVisibleMembers()?
+ null :
+ wf.getMemberSummaryWriter(
+ annotationTypeWriter, i);
}
- memberSummaryWriters =
- new MemberSummaryWriter[VisibleMemberMap.NUM_MEMBER_TYPES];
- for (int i = 0; i < VisibleMemberMap.NUM_MEMBER_TYPES; i++) {
- if (classDoc.isAnnotationType()) {
- memberSummaryWriters[i] =
- visibleMemberMaps[i].noVisibleMembers()?
- null :
- configuration.getWriterFactory().getMemberSummaryWriter(
- (AnnotationTypeWriter) writer, i);
- } else {
- memberSummaryWriters[i] =
- visibleMemberMaps[i].noVisibleMembers()?
- null :
- configuration.getWriterFactory().getMemberSummaryWriter(
- (ClassWriter) writer, i);
- }
- }
-
+ return builder;
}
/**
@@ -304,7 +308,7 @@
configuration));
if (members.size() > 0) {
Collections.sort(members);
- Content tableTree = writer.getSummaryTableTree(classDoc);
+ List<Content> tableContents = new LinkedList<Content>();
for (int i = 0; i < members.size(); i++) {
ProgramElementDoc member = members.get(i);
Tag[] firstSentenceTags = member.firstSentenceTags();
@@ -313,14 +317,15 @@
//necessary.
DocFinder.Output inheritedDoc =
DocFinder.search(new DocFinder.Input((MethodDoc) member));
- if (inheritedDoc.holder != null &&
- inheritedDoc.holder.firstSentenceTags().length > 0) {
+ if (inheritedDoc.holder != null
+ && inheritedDoc.holder.firstSentenceTags().length > 0) {
firstSentenceTags = inheritedDoc.holder.firstSentenceTags();
}
}
- writer.addMemberSummary(classDoc, member, firstSentenceTags, tableTree, i);
+ writer.addMemberSummary(classDoc, member, firstSentenceTags,
+ tableContents, i);
}
- summaryTreeList.add(tableTree);
+ summaryTreeList.add(writer.getSummaryTableTree(classDoc, tableContents));
}
}
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MethodBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MethodBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -54,57 +54,61 @@
/**
* The class whose methods are being documented.
*/
- private ClassDoc classDoc;
+ private final ClassDoc classDoc;
/**
* The visible methods for the given class.
*/
- private VisibleMemberMap visibleMemberMap;
+ private final VisibleMemberMap visibleMemberMap;
/**
* The writer to output the method documentation.
*/
- private MethodWriter writer;
+ private final MethodWriter writer;
/**
* The methods being documented.
*/
private List<ProgramElementDoc> methods;
- private MethodBuilder(Configuration configuration) {
- super(configuration);
+
+ /**
+ * Construct a new MethodBuilder.
+ *
+ * @param context the build context.
+ * @param classDoc the class whoses members are being documented.
+ * @param writer the doclet specific writer.
+ */
+ private MethodBuilder(Context context,
+ ClassDoc classDoc,
+ MethodWriter writer) {
+ super(context);
+ this.classDoc = classDoc;
+ this.writer = writer;
+ visibleMemberMap = new VisibleMemberMap(
+ classDoc,
+ VisibleMemberMap.METHODS,
+ configuration.nodeprecated);
+ methods =
+ new ArrayList<ProgramElementDoc>(visibleMemberMap.getLeafClassMembers(
+ configuration));
+ if (configuration.getMemberComparator() != null) {
+ Collections.sort(methods, configuration.getMemberComparator());
+ }
}
/**
* Construct a new MethodBuilder.
*
- * @param configuration the current configuration of the doclet.
+ * @param context the build context.
* @param classDoc the class whoses members are being documented.
* @param writer the doclet specific writer.
*
* @return an instance of a MethodBuilder.
*/
- public static MethodBuilder getInstance(
- Configuration configuration,
- ClassDoc classDoc,
- MethodWriter writer) {
- MethodBuilder builder = new MethodBuilder(configuration);
- builder.classDoc = classDoc;
- builder.writer = writer;
- builder.visibleMemberMap =
- new VisibleMemberMap(
- classDoc,
- VisibleMemberMap.METHODS,
- configuration.nodeprecated);
- builder.methods =
- new ArrayList<ProgramElementDoc>(builder.visibleMemberMap.getLeafClassMembers(
- configuration));
- if (configuration.getMemberComparator() != null) {
- Collections.sort(
- builder.methods,
- configuration.getMemberComparator());
- }
- return builder;
+ public static MethodBuilder getInstance(Context context,
+ ClassDoc classDoc, MethodWriter writer) {
+ return new MethodBuilder(context, classDoc, writer);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/PackageSummaryBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -52,40 +52,47 @@
/**
* The package being documented.
*/
- private PackageDoc packageDoc;
+ private final PackageDoc packageDoc;
/**
* The doclet specific writer that will output the result.
*/
- private PackageSummaryWriter packageWriter;
+ private final PackageSummaryWriter packageWriter;
/**
* The content that will be added to the package summary documentation tree.
*/
private Content contentTree;
- private PackageSummaryBuilder(Configuration configuration) {
- super(configuration);
+ /**
+ * Construct a new PackageSummaryBuilder.
+ *
+ * @param context the build context.
+ * @param pkg the package being documented.
+ * @param packageWriter the doclet specific writer that will output the
+ * result.
+ */
+ private PackageSummaryBuilder(Context context,
+ PackageDoc pkg,
+ PackageSummaryWriter packageWriter) {
+ super(context);
+ this.packageDoc = pkg;
+ this.packageWriter = packageWriter;
}
/**
* Construct a new PackageSummaryBuilder.
- * @param configuration the current configuration of the doclet.
+ *
+ * @param context the build context.
* @param pkg the package being documented.
* @param packageWriter the doclet specific writer that will output the
* result.
*
* @return an instance of a PackageSummaryBuilder.
*/
- public static PackageSummaryBuilder getInstance(
- Configuration configuration,
- PackageDoc pkg,
- PackageSummaryWriter packageWriter) {
- PackageSummaryBuilder builder =
- new PackageSummaryBuilder(configuration);
- builder.packageDoc = pkg;
- builder.packageWriter = packageWriter;
- return builder;
+ public static PackageSummaryBuilder getInstance(Context context,
+ PackageDoc pkg, PackageSummaryWriter packageWriter) {
+ return new PackageSummaryBuilder(context, pkg, packageWriter);
}
/**
@@ -96,7 +103,7 @@
//Doclet does not support this output.
return;
}
- build(LayoutParser.getInstance(configuration).parseXML(ROOT), contentTree);
+ build(layoutParser.parseXML(ROOT), contentTree);
}
/**
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/SerializedFormBuilder.java Fri Nov 30 17:09:05 2012 -0800
@@ -93,17 +93,21 @@
*/
private Content contentTree;
- private SerializedFormBuilder(Configuration configuration) {
- super(configuration);
+
+ /**
+ * Construct a new SerializedFormBuilder.
+ * @param context the build context.
+ */
+ private SerializedFormBuilder(Context context) {
+ super(context);
}
/**
* Construct a new SerializedFormBuilder.
- * @param configuration the current configuration of the doclet.
+ * @param context the build context.
*/
- public static SerializedFormBuilder getInstance(Configuration configuration) {
- SerializedFormBuilder builder = new SerializedFormBuilder(configuration);
- return builder;
+ public static SerializedFormBuilder getInstance(Context context) {
+ return new SerializedFormBuilder(context);
}
/**
@@ -123,7 +127,7 @@
} catch (Exception e) {
throw new DocletAbortException();
}
- build(LayoutParser.getInstance(configuration).parseXML(NAME), contentTree);
+ build(layoutParser.parseXML(NAME), contentTree);
writer.close();
}
Binary file langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/activetitlebar.gif has changed
Binary file langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/activetitlebar_end.gif has changed
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Fri Nov 30 17:09:05 2012 -0800
@@ -21,10 +21,8 @@
doclet.Copying_File_0_To_File_1=Copying file {0} to file {1}...
doclet.No_Public_Classes_To_Document=No public or protected classes found to document.
doclet.Unable_to_create_directory_0=Unable to create directory {0}
-doclet.destination_directory_not_found_0=Destination directory not found {0}
doclet.destination_directory_not_directory_0=Destination directory is not a directory {0}
doclet.destination_directory_not_writable_0=Destination directory not writable {0}
-doclet.Error_creating_tmp_file=Error creating temporary file, using default platform encoding.
doclet.Encoding_not_supported=Encoding not supported: {0}
doclet.Building_Tree=Building tree for all the packages and classes...
doclet.Building_Index=Building index for all the packages and classes...
@@ -74,7 +72,6 @@
doclet.Enum_Constant_Summary=Enum Constant Summary
doclet.Constructor_Summary=Constructor Summary
doclet.Method_Summary=Method Summary
-doclet.Factory_Method_Summary=Static Factory Method Summary
doclet.Interfaces=Interfaces
doclet.Enums=Enums
doclet.AnnotationTypes=Annotation Types
@@ -88,7 +85,6 @@
doclet.All_Implemented_Interfaces=All Implemented Interfaces:
doclet.All_classes_and_interfaces=All classes and interfaces (except non-static nested types)
doclet.Package_class_and_interface_descriptions=Package, class and interface descriptions
-doclet.Members=Members
doclet.Interface=Interface
doclet.Class=Class
doclet.AnnotationType=Annotation Type
@@ -107,18 +103,13 @@
doclet.Exception=Exception
doclet.exception=exception
doclet.exceptions=exceptions
-doclet.extended_by=extended by
-doclet.extends=extends
doclet.Package_private=(package private)
-doclet.implements=implementsdoclet.Same_package_name_used=Package name format used twice: {0}
doclet.Nested_Classes_Interfaces_Inherited_From_Class=Nested classes/interfaces inherited from class
doclet.Nested_Classes_Interface_Inherited_From_Interface=Nested classes/interfaces inherited from interface
doclet.Methods_Inherited_From_Class=Methods inherited from class
doclet.Methods_Inherited_From_Interface=Methods inherited from interface
doclet.Fields_Inherited_From_Class=Fields inherited from class
doclet.Fields_Inherited_From_Interface=Fields inherited from interface
-doclet.Serializable=Serializable
-doclet.Externalizable=Externalizable
doclet.Annotation_Type_Member_Detail=Element Detail
doclet.Enum_Constant_Detail=Enum Constant Detail
doclet.Constants_Summary=Constant Field Values
@@ -126,7 +117,6 @@
doclet.Method_Detail=Method Detail
doclet.Constructor_Detail=Constructor Detail
doclet.Deprecated=Deprecated.
-doclet.Deprecated_class=This class is deprecated.
doclet.Groupname_already_used=In -group option, groupname already used: {0}
doclet.value_tag_invalid_reference={0} (referenced by @value tag) is an unknown reference.
doclet.value_tag_invalid_constant=@value tag (which references {0}) can only be used in constants.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/script.js Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,30 @@
+function show(type)
+{
+ count = 0;
+ for (var key in methods) {
+ var row = document.getElementById(key);
+ if ((methods[key] & type) != 0) {
+ row.style.display = '';
+ row.className = (count++ % 2) ? rowColor : altColor;
+ }
+ else
+ row.style.display = 'none';
+ }
+ updateTabs(type);
+}
+
+function updateTabs(type)
+{
+ for (var value in tabs) {
+ var sNode = document.getElementById(tabs[value][0]);
+ var spanNode = sNode.firstChild;
+ if (value == type) {
+ sNode.className = activeTableTab;
+ spanNode.innerHTML = tabs[value][1];
+ }
+ else {
+ sNode.className = tableTab;
+ spanNode.innerHTML = "<a href=\"javascript:show("+ value + ");\">" + tabs[value][1] + "</a>";
+ }
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css Fri Nov 30 17:09:05 2012 -0800
@@ -381,6 +381,31 @@
background-image:url(resources/titlebar.gif);
height:18px;
}
+.contentContainer ul.blockList li.blockList caption span.activeTableTab span {
+ white-space:nowrap;
+ padding-top:8px;
+ padding-left:8px;
+ display:block;
+ float:left;
+ background-image:url(resources/activetitlebar.gif);
+ height:18px;
+}
+.contentContainer ul.blockList li.blockList caption span.tableTab span {
+ white-space:nowrap;
+ padding-top:8px;
+ padding-left:8px;
+ display:block;
+ float:left;
+ background-image:url(resources/titlebar.gif);
+ height:18px;
+}
+.contentContainer ul.blockList li.blockList caption span.tableTab, .contentContainer ul.blockList li.blockList caption span.activeTableTab {
+ padding-top:0px;
+ padding-left:0px;
+ background-image:none;
+ float:none;
+ display:inline;
+}
.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd {
width:10px;
background-image:url(resources/titlebar_end.gif);
@@ -389,6 +414,24 @@
position:relative;
float:left;
}
+.contentContainer ul.blockList li.blockList .activeTableTab .tabEnd {
+ width:10px;
+ margin-right:5px;
+ background-image:url(resources/activetitlebar_end.gif);
+ background-repeat:no-repeat;
+ background-position:top right;
+ position:relative;
+ float:left;
+}
+.contentContainer ul.blockList li.blockList .tableTab .tabEnd {
+ width:10px;
+ margin-right:5px;
+ background-image:url(resources/titlebar_end.gif);
+ background-repeat:no-repeat;
+ background-position:top right;
+ position:relative;
+ float:left;
+}
ul.blockList ul.blockList li.blockList table {
margin:0 0 12px 0px;
width:100%;
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/InheritDocTaglet.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/InheritDocTaglet.java Fri Nov 30 17:09:05 2012 -0800
@@ -26,6 +26,7 @@
package com.sun.tools.doclets.internal.toolkit.taglets;
import com.sun.javadoc.*;
+import com.sun.tools.doclets.internal.toolkit.Configuration;
import com.sun.tools.doclets.internal.toolkit.util.*;
/**
@@ -104,7 +105,7 @@
/**
* Given a <code>MethodDoc</code> item, a <code>Tag</code> in the
- * <code>MethodDoc</code> item and a String, replace all occurances
+ * <code>MethodDoc</code> item and a String, replace all occurrences
* of @inheritDoc with documentation from it's superclass or superinterface.
*
* @param writer the writer that is writing the output.
@@ -116,12 +117,13 @@
MethodDoc md, Tag holderTag, boolean isFirstSentence) {
TagletOutput replacement = writer.getTagletOutputInstance();
+ Configuration configuration = writer.configuration();
Taglet inheritableTaglet = holderTag == null ?
- null : writer.configuration().tagletManager.getTaglet(holderTag.name());
+ null : configuration.tagletManager.getTaglet(holderTag.name());
if (inheritableTaglet != null &&
!(inheritableTaglet instanceof InheritableTaglet)) {
//This tag does not support inheritence.
- writer.configuration().message.warning(md.position(),
+ configuration.message.warning(md.position(),
"doclet.noInheritedDoc", md.name() + md.flatSignature());
}
DocFinder.Output inheritedDoc =
@@ -129,7 +131,7 @@
(InheritableTaglet) inheritableTaglet, holderTag,
isFirstSentence, true));
if (inheritedDoc.isValidInheritDocTag == false) {
- writer.configuration().message.warning(md.position(),
+ configuration.message.warning(md.position(),
"doclet.noInheritedDoc", md.name() + md.flatSignature());
} else if (inheritedDoc.inlineTags.length > 0) {
replacement = writer.commentTagsToOutput(inheritedDoc.holderTag,
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java Fri Nov 30 17:09:05 2012 -0800
@@ -30,6 +30,9 @@
import java.net.*;
import java.util.*;
+import javax.tools.DocumentationTool;
+import javax.tools.JavaFileManager;
+
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.util.*;
@@ -48,16 +51,16 @@
public class TagletManager {
/**
- * The default seperator for the simple tag option.
+ * The default separator for the simple tag option.
*/
- public static final char SIMPLE_TAGLET_OPT_SEPERATOR = ':';
+ public static final char SIMPLE_TAGLET_OPT_SEPARATOR = ':';
/**
- * The alternate seperator for simple tag options. Use this
- * with you want the default seperator to be in the name of the
+ * The alternate separator for simple tag options. Use this
+ * when you want the default separator to be in the name of the
* custom tag.
*/
- public static final String ALT_SIMPLE_TAGLET_OPT_SEPERATOR = "-";
+ public static final String ALT_SIMPLE_TAGLET_OPT_SEPARATOR = "-";
/**
* The map of custom tags.
@@ -200,18 +203,24 @@
* @param classname the name of the class representing the custom tag.
* @param tagletPath the path to the class representing the custom tag.
*/
- public void addCustomTag(String classname, String tagletPath) {
+ public void addCustomTag(String classname, JavaFileManager fileManager, String tagletPath) {
try {
Class<?> customTagClass = null;
// construct class loader
String cpString = null; // make sure env.class.path defaults to dot
- // do prepends to get correct ordering
- cpString = appendPath(System.getProperty("env.class.path"), cpString);
- cpString = appendPath(System.getProperty("java.class.path"), cpString);
- cpString = appendPath(tagletPath, cpString);
- URLClassLoader appClassLoader = new URLClassLoader(pathToURLs(cpString));
- customTagClass = appClassLoader.loadClass(classname);
+ ClassLoader tagClassLoader;
+ if (fileManager != null && fileManager.hasLocation(DocumentationTool.Location.TAGLET_PATH)) {
+ tagClassLoader = fileManager.getClassLoader(DocumentationTool.Location.TAGLET_PATH);
+ } else {
+ // do prepends to get correct ordering
+ cpString = appendPath(System.getProperty("env.class.path"), cpString);
+ cpString = appendPath(System.getProperty("java.class.path"), cpString);
+ cpString = appendPath(tagletPath, cpString);
+ tagClassLoader = new URLClassLoader(pathToURLs(cpString));
+ }
+
+ customTagClass = tagClassLoader.loadClass(classname);
Method meth = customTagClass.getMethod("register",
new Class<?>[] {java.util.Map.class});
Object[] list = customTags.values().toArray();
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -46,7 +46,11 @@
/**
* True if we only want to write the first sentence.
*/
- protected boolean isFirstSentence = false;
+ protected final boolean isFirstSentence;
+
+ protected TagletWriter(boolean isFirstSentence) {
+ this.isFirstSentence = isFirstSentence;
+ }
/**
* @return an instance of the output object.
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFile.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFile.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,14 +25,9 @@
package com.sun.tools.doclets.internal.toolkit.util;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -40,10 +35,6 @@
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
import javax.tools.JavaFileManager.Location;
import javax.tools.StandardLocation;
@@ -61,46 +52,36 @@
*
* @since 8
*/
-public class DocFile {
+public abstract class DocFile {
+
+ /** Create a DocFile for a directory. */
+ public static DocFile createFileForDirectory(Configuration configuration, String file) {
+ return DocFileFactory.getFactory(configuration).createFileForDirectory(file);
+ }
- /**
- * The doclet configuration.
- * Provides access to options such as docencoding, output directory, etc.
- */
+ /** Create a DocFile for a file that will be opened for reading. */
+ public static DocFile createFileForInput(Configuration configuration, String file) {
+ return DocFileFactory.getFactory(configuration).createFileForInput(file);
+ }
+
+ /** Create a DocFile for a file that will be opened for writing. */
+ public static DocFile createFileForOutput(Configuration configuration, DocPath path) {
+ return DocFileFactory.getFactory(configuration).createFileForOutput(path);
+ }
+
private final Configuration configuration;
/**
* The location for this file. Maybe null if the file was created without
* a location or path.
*/
- private final Location location;
+ protected final Location location;
/**
* The path relative to the (output) location. Maybe null if the file was
* created without a location or path.
*/
- private final DocPath path;
-
- /**
- * The file object itself.
- * This is temporary, until we create different subtypes of DocFile.
- */
- private final File file;
-
- /** Create a DocFile for a directory. */
- public static DocFile createFileForDirectory(Configuration configuration, String file) {
- return new DocFile(configuration, new File(file));
- }
-
- /** Create a DocFile for a file that will be opened for reading. */
- public static DocFile createFileForInput(Configuration configuration, String file) {
- return new DocFile(configuration, new File(file));
- }
-
- /** Create a DocFile for a file that will be opened for writing. */
- public static DocFile createFileForOutput(Configuration configuration, DocPath path) {
- return new DocFile(configuration, StandardLocation.CLASS_OUTPUT, path);
- }
+ protected final DocPath path;
/**
* List the directories and files found in subdirectories along the
@@ -111,85 +92,46 @@
* list files
*/
public static Iterable<DocFile> list(Configuration configuration, Location location, DocPath path) {
- if (location != StandardLocation.SOURCE_PATH)
- throw new IllegalArgumentException();
-
- Set<DocFile> files = new LinkedHashSet<DocFile>();
- for (String s : configuration.sourcepath.split(File.pathSeparator)) {
- if (s.isEmpty())
- continue;
- File f = new File(s);
- if (f.isDirectory()) {
- f = new File(f, path.getPath());
- if (f.exists())
- files.add(new DocFile(configuration, f));
- }
- }
- return files;
+ return DocFileFactory.getFactory(configuration).list(location, path);
}
- /** Create a DocFile for a given file. */
- private DocFile(Configuration configuration, File file) {
+ /** Create a DocFile without a location or path */
+ protected DocFile(Configuration configuration) {
this.configuration = configuration;
this.location = null;
this.path = null;
- this.file = file;
}
/** Create a DocFile for a given location and relative path. */
- private DocFile(Configuration configuration, Location location, DocPath path) {
+ protected DocFile(Configuration configuration, Location location, DocPath path) {
this.configuration = configuration;
this.location = location;
this.path = path;
- this.file = path.resolveAgainst(configuration.destDirName);
}
/** Open an input stream for the file. */
- public InputStream openInputStream() throws FileNotFoundException {
- return new BufferedInputStream(new FileInputStream(file));
- }
+ public abstract InputStream openInputStream() throws IOException;
/**
* Open an output stream for the file.
* The file must have been created with a location of
- * {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path.
+ * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT}
+ * and a corresponding relative path.
*/
- public OutputStream openOutputStream() throws IOException, UnsupportedEncodingException {
- if (location != StandardLocation.CLASS_OUTPUT)
- throw new IllegalStateException();
-
- createDirectoryForFile(file);
- return new BufferedOutputStream(new FileOutputStream(file));
- }
+ public abstract OutputStream openOutputStream() throws IOException, UnsupportedEncodingException;
/**
* Open an writer for the file, using the encoding (if any) given in the
* doclet configuration.
* The file must have been created with a location of
- * {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path.
+ * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
*/
- public Writer openWriter() throws IOException, UnsupportedEncodingException {
- if (location != StandardLocation.CLASS_OUTPUT)
- throw new IllegalStateException();
-
- createDirectoryForFile(file);
- FileOutputStream fos = new FileOutputStream(file);
- if (configuration.docencoding == null) {
- return new BufferedWriter(new OutputStreamWriter(fos));
- } else {
- return new BufferedWriter(new OutputStreamWriter(fos, configuration.docencoding));
- }
- }
+ public abstract Writer openWriter() throws IOException, UnsupportedEncodingException;
/**
* Copy the contents of another file directly to this file.
*/
public void copyFile(DocFile fromFile) throws IOException {
- if (location != StandardLocation.CLASS_OUTPUT)
- throw new IllegalStateException();
-
- createDirectoryForFile(file);
-
InputStream input = fromFile.openInputStream();
OutputStream output = openOutputStream();
try {
@@ -215,20 +157,15 @@
* separator
*/
public void copyResource(DocPath resource, boolean overwrite, boolean replaceNewLine) {
- if (location != StandardLocation.CLASS_OUTPUT)
- throw new IllegalStateException();
-
- if (file.exists() && !overwrite)
+ if (exists() && !overwrite)
return;
- createDirectoryForFile(file);
-
try {
InputStream in = Configuration.class.getResourceAsStream(resource.getPath());
if (in == null)
return;
- OutputStream out = new FileOutputStream(file);
+ OutputStream out = openOutputStream();
try {
if (!replaceNewLine) {
byte[] buf = new byte[2048];
@@ -265,68 +202,37 @@
}
/** Return true if the file can be read. */
- public boolean canRead() {
- return file.canRead();
- }
+ public abstract boolean canRead();
/** Return true if the file can be written. */
- public boolean canWrite() {
- return file.canRead();
- }
+ public abstract boolean canWrite();
/** Return true if the file exists. */
- public boolean exists() {
- return file.exists();
- }
+ public abstract boolean exists();
/** Return the base name (last component) of the file name. */
- public String getName() {
- return file.getName();
- }
+ public abstract String getName();
/** Return the file system path for this file. */
- public String getPath() {
- return file.getPath();
- }
+ public abstract String getPath();
- /** Return true is file has an absolute path name. */
- boolean isAbsolute() {
- return file.isAbsolute();
- }
+ /** Return true if file has an absolute path name. */
+ public abstract boolean isAbsolute();
- /** Return true is file identifies a directory. */
- public boolean isDirectory() {
- return file.isDirectory();
- }
+ /** Return true if file identifies a directory. */
+ public abstract boolean isDirectory();
- /** Return true is file identifies a file. */
- public boolean isFile() {
- return file.isFile();
- }
+ /** Return true if file identifies a file. */
+ public abstract boolean isFile();
/** Return true if this file is the same as another. */
- public boolean isSameFile(DocFile other) {
- try {
- return file.exists()
- && file.getCanonicalFile().equals(other.file.getCanonicalFile());
- } catch (IOException e) {
- return false;
- }
- }
+ public abstract boolean isSameFile(DocFile other);
/** If the file is a directory, list its contents. */
- public Iterable<DocFile> list() {
- List<DocFile> files = new ArrayList<DocFile>();
- for (File f: file.listFiles()) {
- files.add(new DocFile(configuration, f));
- }
- return files;
- }
+ public abstract Iterable<DocFile> list() throws IOException;
/** Create the file as a directory, including any parent directories. */
- public boolean mkdirs() {
- return file.mkdirs();
- }
+ public abstract boolean mkdirs();
/**
* Derive a new file by resolving a relative path against this file.
@@ -334,9 +240,7 @@
* If this file has a path set, the new file will have a corresponding
* new path.
*/
- public DocFile resolve(DocPath p) {
- return resolve(p.getPath());
- }
+ public abstract DocFile resolve(DocPath p);
/**
* Derive a new file by resolving a relative path against this file.
@@ -344,56 +248,12 @@
* If this file has a path set, the new file will have a corresponding
* new path.
*/
- public DocFile resolve(String p) {
- if (location == null && path == null) {
- return new DocFile(configuration, new File(file, p));
- } else {
- return new DocFile(configuration, location, path.resolve(p));
- }
- }
+ public abstract DocFile resolve(String p);
/**
* Resolve a relative file against the given output location.
- * @param locn Currently, only SOURCE_OUTPUT is supported.
- */
- public DocFile resolveAgainst(StandardLocation locn) {
- if (locn != StandardLocation.CLASS_OUTPUT)
- throw new IllegalArgumentException();
- return new DocFile(configuration,
- new File(configuration.destDirName, file.getPath()));
- }
-
- /**
- * Given a path string create all the directories in the path. For example,
- * if the path string is "java/applet", the method will create directory
- * "java" and then "java/applet" if they don't exist. The file separator
- * string "/" is platform dependent system property.
- *
- * @param path Directory path string.
+ * @param locn Currently, only
+ * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} is supported.
*/
- private void createDirectoryForFile(File file) {
- File dir = file.getParentFile();
- if (dir == null || dir.exists() || dir.mkdirs())
- return;
-
- configuration.message.error(
- "doclet.Unable_to_create_directory_0", dir.getPath());
- throw new DocletAbortException();
- }
-
- /** Return a string to identify the contents of this object,
- * for debugging purposes.
- */
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("DocFile[");
- if (location != null)
- sb.append("locn:").append(location).append(",");
- if (path != null)
- sb.append("path:").append(path.getPath()).append(",");
- sb.append("file:").append(file);
- sb.append("]");
- return sb.toString();
- }
+ public abstract DocFile resolveAgainst(Location locn);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFileFactory.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1998, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.doclets.internal.toolkit.util;
+
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+
+import com.sun.tools.doclets.internal.toolkit.Configuration;
+
+/**
+ * Factory for DocFile objects.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ *
+ * @since 1.8
+ */
+abstract class DocFileFactory {
+ private static Map<Configuration, DocFileFactory> factories =
+ new WeakHashMap<Configuration, DocFileFactory>();
+
+ /**
+ * Get the appropriate factory, based on the file manager given in the
+ * configuration.
+ */
+ static synchronized DocFileFactory getFactory(Configuration configuration) {
+ DocFileFactory f = factories.get(configuration);
+ if (f == null) {
+ JavaFileManager fm = configuration.getFileManager();
+ if (fm instanceof StandardJavaFileManager)
+ f = new StandardDocFileFactory(configuration);
+ else {
+ try {
+ Class<?> pathFileManagerClass =
+ Class.forName("com.sun.tools.javac.nio.PathFileManager");
+ if (pathFileManagerClass.isAssignableFrom(fm.getClass()))
+ f = new PathDocFileFactory(configuration);
+ } catch (Throwable t) {
+ throw new IllegalStateException(t);
+ }
+ }
+ factories.put(configuration, f);
+ }
+ return f;
+ }
+
+ protected Configuration configuration;
+
+ protected DocFileFactory(Configuration configuration) {
+ this.configuration = configuration;
+ }
+
+ /** Create a DocFile for a directory. */
+ abstract DocFile createFileForDirectory(String file);
+
+ /** Create a DocFile for a file that will be opened for reading. */
+ abstract DocFile createFileForInput(String file);
+
+ /** Create a DocFile for a file that will be opened for writing. */
+ abstract DocFile createFileForOutput(DocPath path);
+
+ /**
+ * List the directories and files found in subdirectories along the
+ * elements of the given location.
+ * @param location currently, only {@link StandardLocation#SOURCE_PATH} is supported.
+ * @param path the subdirectory of the directories of the location for which to
+ * list files
+ */
+ abstract Iterable<DocFile> list(Location location, DocPath path);
+}
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocPath.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocPath.java Fri Nov 30 17:09:05 2012 -0800
@@ -27,7 +27,6 @@
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.PackageDoc;
-import java.io.File;
/**
* Abstraction for immutable relative paths.
@@ -159,15 +158,6 @@
}
/**
- * Get the file created by evaluating the path against a specified directory.
- */
- // Temporary: this signature should not use String for dir.
- // Eventually, this should involve javax.tools.Location.
- public File resolveAgainst(String dir) {
- return dir.isEmpty() ? new File(path) : new File(dir, path);
- }
-
- /**
* Return the inverse path for this path.
* For example, if the path is a/b/c, the inverse path is ../../..
*/
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocPaths.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocPaths.java Fri Nov 30 17:09:05 2012 -0800
@@ -72,6 +72,9 @@
return DocPath.create("index-" + n + ".html");
}
+ /** The name of the default javascript file. */
+ public static final DocPath JAVASCRIPT = DocPath.create("script.js");
+
/** The name of the file for the overview frame. */
public static final DocPath OVERVIEW_FRAME = DocPath.create("overview-frame.html");
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Extern.java Fri Nov 30 17:09:05 2012 -0800
@@ -30,7 +30,7 @@
import java.util.HashMap;
import java.util.Map;
-import javax.tools.StandardLocation;
+import javax.tools.DocumentationTool;
import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*;
@@ -253,7 +253,7 @@
throws Fault {
DocFile file = pkgListPath.resolve(DocPaths.PACKAGE_LIST);
if (! (file.isAbsolute() || linkoffline)){
- file = file.resolveAgainst(StandardLocation.CLASS_OUTPUT);
+ file = file.resolveAgainst(DocumentationTool.Location.DOCUMENTATION_OUTPUT);
}
try {
if (file.exists() && file.canRead()) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MethodTypes.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.doclets.internal.toolkit.util;
+
+/**
+ * Enum representing method types.
+ *
+ * @author Bhavesh Patel
+ */
+public enum MethodTypes {
+ ALL(0xffff, "All Methods", "t0", true),
+ STATIC(0x1, "Static Methods", "t1", false),
+ INSTANCE(0x2, "Instance Methods", "t2", false),
+ ABSTRACT(0x4, "Abstract Methods", "t3", false),
+ CONCRETE(0x8, "Concrete Methods", "t4", false),
+ DEPRECATED(0x10, "Deprecated Methods", "t5", false);
+
+ private final int value;
+ private final String text;
+ private final String tabId;
+ private final boolean isDefaultTab;
+
+ MethodTypes(int v, String t, String id, boolean dt) {
+ this.value = v;
+ this.text = t;
+ this.tabId = id;
+ this.isDefaultTab = dt;
+ }
+
+ public int value() {
+ return value;
+ }
+
+ public String text() {
+ return text;
+ }
+
+ public String tabId() {
+ return tabId;
+ }
+
+ public boolean isDefaultTab() {
+ return isDefaultTab;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/PathDocFileFactory.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 1998, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.doclets.internal.toolkit.util;
+
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.tools.DocumentationTool;
+import javax.tools.FileObject;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
+
+import com.sun.tools.doclets.internal.toolkit.Configuration;
+import com.sun.tools.javac.nio.PathFileManager;
+
+
+/**
+ * Implementation of DocFileFactory using a {@link PathFileManager}.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ *
+ * @since 1.8
+ */
+class PathDocFileFactory extends DocFileFactory {
+ private final PathFileManager fileManager;
+ private final Path destDir;
+
+ public PathDocFileFactory(Configuration configuration) {
+ super(configuration);
+ fileManager = (PathFileManager) configuration.getFileManager();
+
+ if (!configuration.destDirName.isEmpty()
+ || !fileManager.hasLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT)) {
+ try {
+ String dirName = configuration.destDirName.isEmpty() ? "." : configuration.destDirName;
+ Path dir = fileManager.getDefaultFileSystem().getPath(dirName);
+ fileManager.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(dir));
+ } catch (IOException e) {
+ throw new DocletAbortException();
+ }
+ }
+
+ destDir = fileManager.getLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT).iterator().next();
+ }
+
+ public DocFile createFileForDirectory(String file) {
+ return new StandardDocFile(fileManager.getDefaultFileSystem().getPath(file));
+ }
+
+ public DocFile createFileForInput(String file) {
+ return new StandardDocFile(fileManager.getDefaultFileSystem().getPath(file));
+ }
+
+ public DocFile createFileForOutput(DocPath path) {
+ return new StandardDocFile(DocumentationTool.Location.DOCUMENTATION_OUTPUT, path);
+ }
+
+ @Override
+ Iterable<DocFile> list(Location location, DocPath path) {
+ if (location != StandardLocation.SOURCE_PATH)
+ throw new IllegalArgumentException();
+
+ Set<DocFile> files = new LinkedHashSet<DocFile>();
+ if (fileManager.hasLocation(location)) {
+ for (Path f: fileManager.getLocation(location)) {
+ if (Files.isDirectory(f)) {
+ f = f.resolve(path.getPath());
+ if (Files.exists(f))
+ files.add(new StandardDocFile(f));
+ }
+ }
+ }
+ return files;
+ }
+
+ class StandardDocFile extends DocFile {
+ private Path file;
+
+ /** Create a StandardDocFile for a given file. */
+ private StandardDocFile(Path file) {
+ super(configuration);
+ this.file = file;
+ }
+
+ /** Create a StandardDocFile for a given location and relative path. */
+ private StandardDocFile(Location location, DocPath path) {
+ super(configuration, location, path);
+ this.file = destDir.resolve(path.getPath());
+ }
+
+ /** Open an input stream for the file. */
+ public InputStream openInputStream() throws IOException {
+ JavaFileObject fo = getJavaFileObjectForInput(file);
+ return new BufferedInputStream(fo.openInputStream());
+ }
+
+ /**
+ * Open an output stream for the file.
+ * The file must have been created with a location of
+ * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
+ */
+ public OutputStream openOutputStream() throws IOException, UnsupportedEncodingException {
+ if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
+ throw new IllegalStateException();
+
+ OutputStream out = getFileObjectForOutput(path).openOutputStream();
+ return new BufferedOutputStream(out);
+ }
+
+ /**
+ * Open an writer for the file, using the encoding (if any) given in the
+ * doclet configuration.
+ * The file must have been created with a location of
+ * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
+ */
+ public Writer openWriter() throws IOException, UnsupportedEncodingException {
+ if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
+ throw new IllegalStateException();
+
+ OutputStream out = getFileObjectForOutput(path).openOutputStream();
+ if (configuration.docencoding == null) {
+ return new BufferedWriter(new OutputStreamWriter(out));
+ } else {
+ return new BufferedWriter(new OutputStreamWriter(out, configuration.docencoding));
+ }
+ }
+
+ /** Return true if the file can be read. */
+ public boolean canRead() {
+ return Files.isReadable(file);
+ }
+
+ /** Return true if the file can be written. */
+ public boolean canWrite() {
+ return Files.isWritable(file);
+ }
+
+ /** Return true if the file exists. */
+ public boolean exists() {
+ return Files.exists(file);
+ }
+
+ /** Return the base name (last component) of the file name. */
+ public String getName() {
+ return file.getFileName().toString();
+ }
+
+ /** Return the file system path for this file. */
+ public String getPath() {
+ return file.toString();
+ }
+
+ /** Return true is file has an absolute path name. */
+ public boolean isAbsolute() {
+ return file.isAbsolute();
+ }
+
+ /** Return true is file identifies a directory. */
+ public boolean isDirectory() {
+ return Files.isDirectory(file);
+ }
+
+ /** Return true is file identifies a file. */
+ public boolean isFile() {
+ return Files.isRegularFile(file);
+ }
+
+ /** Return true if this file is the same as another. */
+ public boolean isSameFile(DocFile other) {
+ if (!(other instanceof StandardDocFile))
+ return false;
+
+ try {
+ return Files.isSameFile(file, ((StandardDocFile) other).file);
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ /** If the file is a directory, list its contents. */
+ public Iterable<DocFile> list() throws IOException {
+ List<DocFile> files = new ArrayList<DocFile>();
+ for (Path f: Files.newDirectoryStream(file)) {
+ files.add(new StandardDocFile(f));
+ }
+ return files;
+ }
+
+ /** Create the file as a directory, including any parent directories. */
+ public boolean mkdirs() {
+ try {
+ Files.createDirectories(file);
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Derive a new file by resolving a relative path against this file.
+ * The new file will inherit the configuration and location of this file
+ * If this file has a path set, the new file will have a corresponding
+ * new path.
+ */
+ public DocFile resolve(DocPath p) {
+ return resolve(p.getPath());
+ }
+
+ /**
+ * Derive a new file by resolving a relative path against this file.
+ * The new file will inherit the configuration and location of this file
+ * If this file has a path set, the new file will have a corresponding
+ * new path.
+ */
+ public DocFile resolve(String p) {
+ if (location == null && path == null) {
+ return new StandardDocFile(file.resolve(p));
+ } else {
+ return new StandardDocFile(location, path.resolve(p));
+ }
+ }
+
+ /**
+ * Resolve a relative file against the given output location.
+ * @param locn Currently, only
+ * {@link DocumentationTool.Location.DOCUMENTATION_OUTPUT} is supported.
+ */
+ public DocFile resolveAgainst(Location locn) {
+ if (locn != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
+ throw new IllegalArgumentException();
+ return new StandardDocFile(destDir.resolve(file));
+ }
+
+ /** Return a string to identify the contents of this object,
+ * for debugging purposes.
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("PathDocFile[");
+ if (location != null)
+ sb.append("locn:").append(location).append(",");
+ if (path != null)
+ sb.append("path:").append(path.getPath()).append(",");
+ sb.append("file:").append(file);
+ sb.append("]");
+ return sb.toString();
+ }
+
+ private JavaFileObject getJavaFileObjectForInput(Path file) {
+ return fileManager.getJavaFileObjects(file).iterator().next();
+ }
+
+ private FileObject getFileObjectForOutput(DocPath path) throws IOException {
+ // break the path into a package-part and the rest, by finding
+ // the position of the last '/' before an invalid character for a
+ // package name, such as the "." before an extension or the "-"
+ // in filenames like package-summary.html, doc-files or src-html.
+ String p = path.getPath();
+ int lastSep = -1;
+ for (int i = 0; i < p.length(); i++) {
+ char ch = p.charAt(i);
+ if (ch == '/') {
+ lastSep = i;
+ } else if (i == lastSep + 1 && !Character.isJavaIdentifierStart(ch)
+ || !Character.isJavaIdentifierPart(ch)) {
+ break;
+ }
+ }
+ String pkg = (lastSep == -1) ? "" : p.substring(0, lastSep);
+ String rest = p.substring(lastSep + 1);
+ return fileManager.getFileForOutput(location, pkg, rest, null);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SimpleDocFileFactory.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 1998, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.doclets.internal.toolkit.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.tools.DocumentationTool;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.StandardLocation;
+
+import com.sun.tools.doclets.internal.toolkit.Configuration;
+
+/**
+ * Implementation of DocFileFactory that just uses java.io.File API,
+ * and does not use a JavaFileManager..
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ *
+ * @since 1.8
+ */
+class SimpleDocFileFactory extends DocFileFactory {
+
+ public SimpleDocFileFactory(Configuration configuration) {
+ super(configuration);
+ }
+
+ public DocFile createFileForDirectory(String file) {
+ return new SimpleDocFile(new File(file));
+ }
+
+ public DocFile createFileForInput(String file) {
+ return new SimpleDocFile(new File(file));
+ }
+
+ public DocFile createFileForOutput(DocPath path) {
+ return new SimpleDocFile(DocumentationTool.Location.DOCUMENTATION_OUTPUT, path);
+ }
+
+ @Override
+ Iterable<DocFile> list(Location location, DocPath path) {
+ if (location != StandardLocation.SOURCE_PATH)
+ throw new IllegalArgumentException();
+
+ Set<DocFile> files = new LinkedHashSet<DocFile>();
+ for (String s : configuration.sourcepath.split(File.pathSeparator)) {
+ if (s.isEmpty())
+ continue;
+ File f = new File(s);
+ if (f.isDirectory()) {
+ f = new File(f, path.getPath());
+ if (f.exists())
+ files.add(new SimpleDocFile(f));
+ }
+ }
+ return files;
+ }
+
+ class SimpleDocFile extends DocFile {
+ private File file;
+
+ /** Create a DocFile for a given file. */
+ private SimpleDocFile(File file) {
+ super(configuration);
+ this.file = file;
+ }
+
+ /** Create a DocFile for a given location and relative path. */
+ private SimpleDocFile(Location location, DocPath path) {
+ super(configuration, location, path);
+ String destDirName = configuration.destDirName;
+ this.file = destDirName.isEmpty() ? new File(path.getPath())
+ : new File(destDirName, path.getPath());
+ }
+
+ /** Open an input stream for the file. */
+ public InputStream openInputStream() throws FileNotFoundException {
+ return new BufferedInputStream(new FileInputStream(file));
+ }
+
+ /**
+ * Open an output stream for the file.
+ * The file must have been created with a location of
+ * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
+ */
+ public OutputStream openOutputStream() throws IOException, UnsupportedEncodingException {
+ if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
+ throw new IllegalStateException();
+
+ createDirectoryForFile(file);
+ return new BufferedOutputStream(new FileOutputStream(file));
+ }
+
+ /**
+ * Open an writer for the file, using the encoding (if any) given in the
+ * doclet configuration.
+ * The file must have been created with a location of
+ * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
+ */
+ public Writer openWriter() throws IOException, UnsupportedEncodingException {
+ if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
+ throw new IllegalStateException();
+
+ createDirectoryForFile(file);
+ FileOutputStream fos = new FileOutputStream(file);
+ if (configuration.docencoding == null) {
+ return new BufferedWriter(new OutputStreamWriter(fos));
+ } else {
+ return new BufferedWriter(new OutputStreamWriter(fos, configuration.docencoding));
+ }
+ }
+
+ /** Return true if the file can be read. */
+ public boolean canRead() {
+ return file.canRead();
+ }
+
+ /** Return true if the file can be written. */
+ public boolean canWrite() {
+ return file.canRead();
+ }
+
+ /** Return true if the file exists. */
+ public boolean exists() {
+ return file.exists();
+ }
+
+ /** Return the base name (last component) of the file name. */
+ public String getName() {
+ return file.getName();
+ }
+
+ /** Return the file system path for this file. */
+ public String getPath() {
+ return file.getPath();
+ }
+
+ /** Return true is file has an absolute path name. */
+ public boolean isAbsolute() {
+ return file.isAbsolute();
+ }
+
+ /** Return true is file identifies a directory. */
+ public boolean isDirectory() {
+ return file.isDirectory();
+ }
+
+ /** Return true is file identifies a file. */
+ public boolean isFile() {
+ return file.isFile();
+ }
+
+ /** Return true if this file is the same as another. */
+ public boolean isSameFile(DocFile other) {
+ if (!(other instanceof SimpleDocFile))
+ return false;
+
+ try {
+ return file.exists()
+ && file.getCanonicalFile().equals(((SimpleDocFile)other).file.getCanonicalFile());
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ /** If the file is a directory, list its contents. */
+ public Iterable<DocFile> list() {
+ List<DocFile> files = new ArrayList<DocFile>();
+ for (File f: file.listFiles()) {
+ files.add(new SimpleDocFile(f));
+ }
+ return files;
+ }
+
+ /** Create the file as a directory, including any parent directories. */
+ public boolean mkdirs() {
+ return file.mkdirs();
+ }
+
+ /**
+ * Derive a new file by resolving a relative path against this file.
+ * The new file will inherit the configuration and location of this file
+ * If this file has a path set, the new file will have a corresponding
+ * new path.
+ */
+ public DocFile resolve(DocPath p) {
+ return resolve(p.getPath());
+ }
+
+ /**
+ * Derive a new file by resolving a relative path against this file.
+ * The new file will inherit the configuration and location of this file
+ * If this file has a path set, the new file will have a corresponding
+ * new path.
+ */
+ public DocFile resolve(String p) {
+ if (location == null && path == null) {
+ return new SimpleDocFile(new File(file, p));
+ } else {
+ return new SimpleDocFile(location, path.resolve(p));
+ }
+ }
+
+ /**
+ * Resolve a relative file against the given output location.
+ * @param locn Currently, only
+ * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} is supported.
+ */
+ public DocFile resolveAgainst(Location locn) {
+ if (locn != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
+ throw new IllegalArgumentException();
+ return new SimpleDocFile(
+ new File(configuration.destDirName, file.getPath()));
+ }
+
+ /**
+ * Given a path string create all the directories in the path. For example,
+ * if the path string is "java/applet", the method will create directory
+ * "java" and then "java/applet" if they don't exist. The file separator
+ * string "/" is platform dependent system property.
+ *
+ * @param path Directory path string.
+ */
+ private void createDirectoryForFile(File file) {
+ File dir = file.getParentFile();
+ if (dir == null || dir.exists() || dir.mkdirs())
+ return;
+
+ configuration.message.error(
+ "doclet.Unable_to_create_directory_0", dir.getPath());
+ throw new DocletAbortException();
+ }
+
+ /** Return a string to identify the contents of this object,
+ * for debugging purposes.
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("DocFile[");
+ if (location != null)
+ sb.append("locn:").append(location).append(",");
+ if (path != null)
+ sb.append("path:").append(path.getPath()).append(",");
+ sb.append("file:").append(file);
+ sb.append("]");
+ return sb.toString();
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/StandardDocFileFactory.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,322 @@
+/*
+ * Copyright (c) 1998, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.doclets.internal.toolkit.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.tools.DocumentationTool;
+import javax.tools.FileObject;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+
+import com.sun.tools.doclets.internal.toolkit.Configuration;
+import com.sun.tools.javac.util.Assert;
+
+/**
+ * Implementation of DocFileFactory using a {@link StandardJavaFileManager}.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ *
+ * @since 1.8
+ */
+class StandardDocFileFactory extends DocFileFactory {
+ private final StandardJavaFileManager fileManager;
+ private File destDir;
+
+ public StandardDocFileFactory(Configuration configuration) {
+ super(configuration);
+ fileManager = (StandardJavaFileManager) configuration.getFileManager();
+ }
+
+ private File getDestDir() {
+ if (destDir == null) {
+ if (!configuration.destDirName.isEmpty()
+ || !fileManager.hasLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT)) {
+ try {
+ String dirName = configuration.destDirName.isEmpty() ? "." : configuration.destDirName;
+ File dir = new File(dirName);
+ fileManager.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(dir));
+ } catch (IOException e) {
+ throw new DocletAbortException();
+ }
+ }
+
+ destDir = fileManager.getLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT).iterator().next();
+ }
+ return destDir;
+ }
+
+ public DocFile createFileForDirectory(String file) {
+ return new StandardDocFile(new File(file));
+ }
+
+ public DocFile createFileForInput(String file) {
+ return new StandardDocFile(new File(file));
+ }
+
+ public DocFile createFileForOutput(DocPath path) {
+ return new StandardDocFile(DocumentationTool.Location.DOCUMENTATION_OUTPUT, path);
+ }
+
+ @Override
+ Iterable<DocFile> list(Location location, DocPath path) {
+ if (location != StandardLocation.SOURCE_PATH)
+ throw new IllegalArgumentException();
+
+ Set<DocFile> files = new LinkedHashSet<DocFile>();
+ Location l = fileManager.hasLocation(StandardLocation.SOURCE_PATH)
+ ? StandardLocation.SOURCE_PATH : StandardLocation.CLASS_PATH;
+ for (File f: fileManager.getLocation(l)) {
+ if (f.isDirectory()) {
+ f = new File(f, path.getPath());
+ if (f.exists())
+ files.add(new StandardDocFile(f));
+ }
+ }
+ return files;
+ }
+
+ private static File newFile(File dir, String path) {
+ return (dir == null) ? new File(path) : new File(dir, path);
+ }
+
+ class StandardDocFile extends DocFile {
+ private File file;
+
+
+ /** Create a StandardDocFile for a given file. */
+ private StandardDocFile(File file) {
+ super(configuration);
+ this.file = file;
+ }
+
+ /** Create a StandardDocFile for a given location and relative path. */
+ private StandardDocFile(Location location, DocPath path) {
+ super(configuration, location, path);
+ Assert.check(location == DocumentationTool.Location.DOCUMENTATION_OUTPUT);
+ this.file = newFile(getDestDir(), path.getPath());
+ }
+
+ /** Open an input stream for the file. */
+ public InputStream openInputStream() throws IOException {
+ JavaFileObject fo = getJavaFileObjectForInput(file);
+ return new BufferedInputStream(fo.openInputStream());
+ }
+
+ /**
+ * Open an output stream for the file.
+ * The file must have been created with a location of
+ * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
+ */
+ public OutputStream openOutputStream() throws IOException, UnsupportedEncodingException {
+ if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
+ throw new IllegalStateException();
+
+ OutputStream out = getFileObjectForOutput(path).openOutputStream();
+ return new BufferedOutputStream(out);
+ }
+
+ /**
+ * Open an writer for the file, using the encoding (if any) given in the
+ * doclet configuration.
+ * The file must have been created with a location of
+ * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} and a corresponding relative path.
+ */
+ public Writer openWriter() throws IOException, UnsupportedEncodingException {
+ if (location != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
+ throw new IllegalStateException();
+
+ OutputStream out = getFileObjectForOutput(path).openOutputStream();
+ if (configuration.docencoding == null) {
+ return new BufferedWriter(new OutputStreamWriter(out));
+ } else {
+ return new BufferedWriter(new OutputStreamWriter(out, configuration.docencoding));
+ }
+ }
+
+ /** Return true if the file can be read. */
+ public boolean canRead() {
+ return file.canRead();
+ }
+
+ /** Return true if the file can be written. */
+ public boolean canWrite() {
+ return file.canWrite();
+ }
+
+ /** Return true if the file exists. */
+ public boolean exists() {
+ return file.exists();
+ }
+
+ /** Return the base name (last component) of the file name. */
+ public String getName() {
+ return file.getName();
+ }
+
+ /** Return the file system path for this file. */
+ public String getPath() {
+ return file.getPath();
+ }
+
+ /** Return true is file has an absolute path name. */
+ public boolean isAbsolute() {
+ return file.isAbsolute();
+ }
+
+ /** Return true is file identifies a directory. */
+ public boolean isDirectory() {
+ return file.isDirectory();
+ }
+
+ /** Return true is file identifies a file. */
+ public boolean isFile() {
+ return file.isFile();
+ }
+
+ /** Return true if this file is the same as another. */
+ public boolean isSameFile(DocFile other) {
+ if (!(other instanceof StandardDocFile))
+ return false;
+
+ try {
+ return file.exists()
+ && file.getCanonicalFile().equals(((StandardDocFile) other).file.getCanonicalFile());
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ /** If the file is a directory, list its contents. */
+ public Iterable<DocFile> list() {
+ List<DocFile> files = new ArrayList<DocFile>();
+ for (File f: file.listFiles()) {
+ files.add(new StandardDocFile(f));
+ }
+ return files;
+ }
+
+ /** Create the file as a directory, including any parent directories. */
+ public boolean mkdirs() {
+ return file.mkdirs();
+ }
+
+ /**
+ * Derive a new file by resolving a relative path against this file.
+ * The new file will inherit the configuration and location of this file
+ * If this file has a path set, the new file will have a corresponding
+ * new path.
+ */
+ public DocFile resolve(DocPath p) {
+ return resolve(p.getPath());
+ }
+
+ /**
+ * Derive a new file by resolving a relative path against this file.
+ * The new file will inherit the configuration and location of this file
+ * If this file has a path set, the new file will have a corresponding
+ * new path.
+ */
+ public DocFile resolve(String p) {
+ if (location == null && path == null) {
+ return new StandardDocFile(new File(file, p));
+ } else {
+ return new StandardDocFile(location, path.resolve(p));
+ }
+ }
+
+ /**
+ * Resolve a relative file against the given output location.
+ * @param locn Currently, only
+ * {@link DocumentationTool.Location#DOCUMENTATION_OUTPUT} is supported.
+ */
+ public DocFile resolveAgainst(Location locn) {
+ if (locn != DocumentationTool.Location.DOCUMENTATION_OUTPUT)
+ throw new IllegalArgumentException();
+ return new StandardDocFile(newFile(getDestDir(), file.getPath()));
+ }
+
+ /** Return a string to identify the contents of this object,
+ * for debugging purposes.
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("StandardDocFile[");
+ if (location != null)
+ sb.append("locn:").append(location).append(",");
+ if (path != null)
+ sb.append("path:").append(path.getPath()).append(",");
+ sb.append("file:").append(file);
+ sb.append("]");
+ return sb.toString();
+ }
+
+ private JavaFileObject getJavaFileObjectForInput(File file) {
+ return fileManager.getJavaFileObjects(file).iterator().next();
+ }
+
+ private FileObject getFileObjectForOutput(DocPath path) throws IOException {
+ // break the path into a package-part and the rest, by finding
+ // the position of the last '/' before an invalid character for a
+ // package name, such as the "." before an extension or the "-"
+ // in filenames like package-summary.html, doc-files or src-html.
+ String p = path.getPath();
+ int lastSep = -1;
+ for (int i = 0; i < p.length(); i++) {
+ char ch = p.charAt(i);
+ if (ch == '/') {
+ lastSep = i;
+ } else if (i == lastSep + 1 && !Character.isJavaIdentifierStart(ch)
+ || !Character.isJavaIdentifierPart(ch)) {
+ break;
+ }
+ }
+ String pkg = (lastSep == -1) ? "" : p.substring(0, lastSep);
+ String rest = p.substring(lastSep + 1);
+ return fileManager.getFileForOutput(location, pkg, rest, null);
+ }
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java Fri Nov 30 17:09:05 2012 -0800
@@ -46,13 +46,6 @@
public class Util {
/**
- * A mapping between characters and their
- * corresponding HTML escape character.
- */
- public static final String[][] HTML_ESCAPE_CHARS =
- {{"&", "&"}, {"<", "<"}, {">", ">"}};
-
- /**
* Return array of class members whose documentation is to be generated.
* If the member is deprecated do not include such a member in the
* returned array.
@@ -424,18 +417,44 @@
* return the result.
*
* @param s The string to check.
- * @return the original string with all of the HTML characters
- * escaped.
- *
- * @see #HTML_ESCAPE_CHARS
+ * @return the original string with all of the HTML characters escaped.
*/
public static String escapeHtmlChars(String s) {
- String result = s;
- for (int i = 0; i < HTML_ESCAPE_CHARS.length; i++) {
- result = Util.replaceText(result,
- HTML_ESCAPE_CHARS[i][0], HTML_ESCAPE_CHARS[i][1]);
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s.charAt(i);
+ switch (ch) {
+ // only start building a new string if we need to
+ case '<': case '>': case '&':
+ StringBuilder sb = new StringBuilder(s.substring(0, i));
+ for ( ; i < s.length(); i++) {
+ ch = s.charAt(i);
+ switch (ch) {
+ case '<': sb.append("<"); break;
+ case '>': sb.append(">"); break;
+ case '&': sb.append("&"); break;
+ default: sb.append(ch); break;
+ }
+ }
+ return sb.toString();
+ }
}
- return result;
+ return s;
+ }
+
+ /**
+ * Escape all special html characters in a string buffer.
+ *
+ * @param sb The string buffer to update
+ */
+ public static void escapeHtmlChars(StringBuilder sb) {
+ // scan backwards, replacing characters as needed.
+ for (int i = sb.length() - 1; i >= 0; i--) {
+ switch (sb.charAt(i)) {
+ case '<': sb.replace(i, i+1, "<"); break;
+ case '>': sb.replace(i, i+1, ">"); break;
+ case '&': sb.replace(i, i+1, "&"); break;
+ }
+ }
}
/**
@@ -555,7 +574,7 @@
*
* @param cd the ClassDoc to check.
* @param lowerCaseOnly true if you want the name returned in lower case.
- * If false, the first letter of the name is capatilized.
+ * If false, the first letter of the name is capitalized.
* @return
*/
public static String getTypeName(Configuration config,
@@ -579,22 +598,21 @@
}
/**
- * Given a string, replace all tabs with the appropriate
- * number of spaces.
- * @param tabLength the length of each tab.
- * @param s the String to scan.
+ * Replace all tabs with the appropriate number of spaces.
+ * @param configuration the doclet configuration defining the setting for the
+ * tab length.
+ * @param sb the StringBuilder in which to replace the tabs
*/
- public static void replaceTabs(int tabLength, StringBuilder s) {
- if (whitespace == null || whitespace.length() < tabLength)
- whitespace = String.format("%" + tabLength + "s", " ");
+ public static void replaceTabs(Configuration configuration, StringBuilder sb) {
+ int tabLength = configuration.sourcetab;
+ String whitespace = configuration.tabSpaces;
int index = 0;
- while ((index = s.indexOf("\t", index)) != -1) {
+ while ((index = sb.indexOf("\t", index)) != -1) {
int spaceCount = tabLength - index % tabLength;
- s.replace(index, index+1, whitespace.substring(0, spaceCount));
+ sb.replace(index, index+1, whitespace.substring(0, spaceCount));
index += spaceCount;
}
}
- private static String whitespace;
/**
* The documentation for values() and valueOf() in Enums are set by the
--- a/langtools/src/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Fri Nov 30 17:09:05 2012 -0800
@@ -140,6 +140,14 @@
* For internal use only. This method will be
* removed without warning.
*/
+ public Context getContext() {
+ return context;
+ }
+
+ /**
+ * For internal use only. This method will be
+ * removed without warning.
+ */
public void updateContext(Context newContext) {
context = newContext;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java Fri Nov 30 17:09:05 2012 -0800
@@ -149,7 +149,7 @@
return fo;
}
- <T /*super JavaFileOject*/> DiagnosticListener<T> wrap(DiagnosticListener<T> dl) {
+ public <T /*super JavaFileOject*/> DiagnosticListener<T> wrap(DiagnosticListener<T> dl) {
if (isTrusted(dl))
return dl;
return new WrappedDiagnosticListener<T>(dl);
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -74,7 +74,7 @@
private List<JavaFileObject> fileObjects;
private Map<JavaFileObject, JCCompilationUnit> notYetEntered;
private ListBuffer<Env<AttrContext>> genList;
- private AtomicBoolean used = new AtomicBoolean();
+ private final AtomicBoolean used = new AtomicBoolean();
private Iterable<? extends Processor> processors;
private Main.Result result = null;
@@ -99,11 +99,11 @@
}
JavacTaskImpl(Main compilerMain,
- Iterable<String> flags,
+ Iterable<String> args,
Context context,
Iterable<String> classes,
Iterable<? extends JavaFileObject> fileObjects) {
- this(compilerMain, toArray(flags), toArray(classes), context, toList(fileObjects));
+ this(compilerMain, toArray(args), toArray(classes), context, toList(fileObjects));
}
static private String[] toArray(Iterable<String> iter) {
@@ -489,22 +489,6 @@
* For internal use only. This method will be
* removed without warning.
*/
- public Context getContext() {
- return context;
- }
-
- /**
- * For internal use only. This method will be
- * removed without warning.
- */
- public void updateContext(Context newContext) {
- context = newContext;
- }
-
- /**
- * For internal use only. This method will be
- * removed without warning.
- */
public Type parseType(String expr, TypeElement scope) {
if (expr == null || expr.equals(""))
throw new IllegalArgumentException();
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Fri Nov 30 17:09:05 2012 -0800
@@ -26,6 +26,8 @@
package com.sun.tools.javac.api;
import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
@@ -40,19 +42,31 @@
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.doctree.ReferenceTree;
import com.sun.source.tree.CatchTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Scope;
import com.sun.source.tree.Tree;
+import com.sun.source.util.DocTrees;
import com.sun.source.util.JavacTask;
import com.sun.source.util.SourcePositions;
import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symbol.TypeSymbol;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.ArrayType;
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.code.Type.ErrorType;
import com.sun.tools.javac.code.Type.UnionClassType;
+import com.sun.tools.javac.code.Types;
+import com.sun.tools.javac.code.Types.TypeRelation;
import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Enter;
@@ -61,6 +75,9 @@
import com.sun.tools.javac.comp.Resolve;
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.tree.DCTree;
+import com.sun.tools.javac.tree.DCTree.DCDocComment;
+import com.sun.tools.javac.tree.DCTree.DCReference;
import com.sun.tools.javac.tree.EndPosTable;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
@@ -71,8 +88,12 @@
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic;
import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
import com.sun.tools.javac.util.Pair;
+import static com.sun.tools.javac.code.TypeTag.*;
/**
* Provides an implementation of Trees.
@@ -84,7 +105,7 @@
*
* @author Peter von der Ahé
*/
-public class JavacTrees extends Trees {
+public class JavacTrees extends DocTrees {
// in a world of a single context per compilation, these would all be final
private Resolve resolve;
@@ -95,12 +116,14 @@
private TreeMaker treeMaker;
private JavacElements elements;
private JavacTaskImpl javacTaskImpl;
+ private Names names;
+ private Types types;
// called reflectively from Trees.instance(CompilationTask task)
public static JavacTrees instance(JavaCompiler.CompilationTask task) {
- if (!(task instanceof JavacTaskImpl))
+ if (!(task instanceof BasicJavacTask))
throw new IllegalArgumentException();
- return instance(((JavacTaskImpl)task).getContext());
+ return instance(((BasicJavacTask)task).getContext());
}
// called reflectively from Trees.instance(ProcessingEnvironment env)
@@ -134,6 +157,8 @@
resolve = Resolve.instance(context);
treeMaker = TreeMaker.instance(context);
memberEnter = MemberEnter.instance(context);
+ names = Names.instance(context);
+ types = Types.instance(context);
JavacTask t = context.get(JavacTask.class);
if (t instanceof JavacTaskImpl)
@@ -229,6 +254,324 @@
return sym;
}
+ @Override
+ public Element getElement(TreePath path, ReferenceTree reference) {
+ if (!(reference instanceof DCReference))
+ return null;
+ DCReference ref = (DCReference) reference;
+
+ Env<AttrContext> env = getAttrContext(path);
+
+ Log.DeferredDiagnosticHandler deferredDiagnosticHandler =
+ new Log.DeferredDiagnosticHandler(log);
+ try {
+ final ClassSymbol tsym;
+ final Name memberName;
+ if (ref.qualifierExpression == null) {
+ tsym = env.enclClass.sym;
+ memberName = ref.memberName;
+ } else {
+ // See if the qualifierExpression is a type or package name.
+ // javac does not provide the exact method required, so
+ // we first check if qualifierExpression identifies a type,
+ // and if not, then we check to see if it identifies a package.
+ Type t = attr.attribType(ref.qualifierExpression, env);
+ if (t.isErroneous()) {
+ if (ref.memberName == null) {
+ // Attr/Resolve assume packages exist and create symbols as needed
+ // so use getPackageElement to restrict search to existing packages
+ PackageSymbol pck = elements.getPackageElement(ref.qualifierExpression.toString());
+ if (pck != null) {
+ return pck;
+ } else if (ref.qualifierExpression.hasTag(JCTree.Tag.IDENT)) {
+ // fixup: allow "identifier" instead of "#identifier"
+ // for compatibility with javadoc
+ tsym = env.enclClass.sym;
+ memberName = ((JCIdent) ref.qualifierExpression).name;
+ } else
+ return null;
+ } else {
+ return null;
+ }
+ } else {
+ tsym = (ClassSymbol) t.tsym;
+ memberName = ref.memberName;
+ }
+ }
+
+ if (memberName == null)
+ return tsym;
+
+ final List<Type> paramTypes;
+ if (ref.paramTypes == null)
+ paramTypes = null;
+ else {
+ ListBuffer<Type> lb = new ListBuffer<Type>();
+ for (List<JCTree> l = ref.paramTypes; l.nonEmpty(); l = l.tail) {
+ JCTree tree = l.head;
+ Type t = attr.attribType(tree, env);
+ lb.add(t);
+ }
+ paramTypes = lb.toList();
+ }
+
+ Symbol msym = (memberName == tsym.name)
+ ? findConstructor(tsym, paramTypes)
+ : findMethod(tsym, memberName, paramTypes);
+ if (paramTypes != null) {
+ // explicit (possibly empty) arg list given, so cannot be a field
+ return msym;
+ }
+
+ VarSymbol vsym = (ref.paramTypes != null) ? null : findField(tsym, memberName);
+ // prefer a field over a method with no parameters
+ if (vsym != null &&
+ (msym == null ||
+ types.isSubtypeUnchecked(vsym.enclClass().asType(), msym.enclClass().asType()))) {
+ return vsym;
+ } else {
+ return msym;
+ }
+ } finally {
+ log.popDiagnosticHandler(deferredDiagnosticHandler);
+ }
+ }
+
+ /** @see com.sun.tools.javadoc.ClassDocImpl#findField */
+ private VarSymbol findField(ClassSymbol tsym, Name fieldName) {
+ return searchField(tsym, fieldName, new HashSet<ClassSymbol>());
+ }
+
+ /** @see com.sun.tools.javadoc.ClassDocImpl#searchField */
+ private VarSymbol searchField(ClassSymbol tsym, Name fieldName, Set<ClassSymbol> searched) {
+ if (searched.contains(tsym)) {
+ return null;
+ }
+ searched.add(tsym);
+
+ for (com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(fieldName);
+ e.scope != null; e = e.next()) {
+ if (e.sym.kind == Kinds.VAR) {
+ return (VarSymbol)e.sym;
+ }
+ }
+
+ //### If we found a VarSymbol above, but which did not pass
+ //### the modifier filter, we should return failure here!
+
+ ClassSymbol encl = tsym.owner.enclClass();
+ if (encl != null) {
+ VarSymbol vsym = searchField(encl, fieldName, searched);
+ if (vsym != null) {
+ return vsym;
+ }
+ }
+
+ // search superclass
+ Type superclass = tsym.getSuperclass();
+ if (superclass.tsym != null) {
+ VarSymbol vsym = searchField((ClassSymbol) superclass.tsym, fieldName, searched);
+ if (vsym != null) {
+ return vsym;
+ }
+ }
+
+ // search interfaces
+ List<Type> intfs = tsym.getInterfaces();
+ for (List<Type> l = intfs; l.nonEmpty(); l = l.tail) {
+ Type intf = l.head;
+ if (intf.isErroneous()) continue;
+ VarSymbol vsym = searchField((ClassSymbol) intf.tsym, fieldName, searched);
+ if (vsym != null) {
+ return vsym;
+ }
+ }
+
+ return null;
+ }
+
+ /** @see com.sun.tools.javadoc.ClassDocImpl#findConstructor */
+ MethodSymbol findConstructor(ClassSymbol tsym, List<Type> paramTypes) {
+ for (com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(names.init);
+ e.scope != null; e = e.next()) {
+ if (e.sym.kind == Kinds.MTH) {
+ if (hasParameterTypes((MethodSymbol) e.sym, paramTypes)) {
+ return (MethodSymbol) e.sym;
+ }
+ }
+ }
+ return null;
+ }
+
+ /** @see com.sun.tools.javadoc.ClassDocImpl#findMethod */
+ private MethodSymbol findMethod(ClassSymbol tsym, Name methodName, List<Type> paramTypes) {
+ return searchMethod(tsym, methodName, paramTypes, new HashSet<ClassSymbol>());
+ }
+
+ /** @see com.sun.tools.javadoc.ClassDocImpl#searchMethod */
+ private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName,
+ List<Type> paramTypes, Set<ClassSymbol> searched) {
+ //### Note that this search is not necessarily what the compiler would do!
+
+ // do not match constructors
+ if (methodName == names.init)
+ return null;
+
+ if (searched.contains(tsym))
+ return null;
+ searched.add(tsym);
+
+ // search current class
+ com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(methodName);
+
+ //### Using modifier filter here isn't really correct,
+ //### but emulates the old behavior. Instead, we should
+ //### apply the normal rules of visibility and inheritance.
+
+ if (paramTypes == null) {
+ // If no parameters specified, we are allowed to return
+ // any method with a matching name. In practice, the old
+ // code returned the first method, which is now the last!
+ // In order to provide textually identical results, we
+ // attempt to emulate the old behavior.
+ MethodSymbol lastFound = null;
+ for (; e.scope != null; e = e.next()) {
+ if (e.sym.kind == Kinds.MTH) {
+ if (e.sym.name == methodName) {
+ lastFound = (MethodSymbol)e.sym;
+ }
+ }
+ }
+ if (lastFound != null) {
+ return lastFound;
+ }
+ } else {
+ for (; e.scope != null; e = e.next()) {
+ if (e.sym != null &&
+ e.sym.kind == Kinds.MTH) {
+ if (hasParameterTypes((MethodSymbol) e.sym, paramTypes)) {
+ return (MethodSymbol) e.sym;
+ }
+ }
+ }
+ }
+
+ //### If we found a MethodSymbol above, but which did not pass
+ //### the modifier filter, we should return failure here!
+
+ // search superclass
+ Type superclass = tsym.getSuperclass();
+ if (superclass.tsym != null) {
+ MethodSymbol msym = searchMethod((ClassSymbol) superclass.tsym, methodName, paramTypes, searched);
+ if (msym != null) {
+ return msym;
+ }
+ }
+
+ // search interfaces
+ List<Type> intfs = tsym.getInterfaces();
+ for (List<Type> l = intfs; l.nonEmpty(); l = l.tail) {
+ Type intf = l.head;
+ if (intf.isErroneous()) continue;
+ MethodSymbol msym = searchMethod((ClassSymbol) intf.tsym, methodName, paramTypes, searched);
+ if (msym != null) {
+ return msym;
+ }
+ }
+
+ // search enclosing class
+ ClassSymbol encl = tsym.owner.enclClass();
+ if (encl != null) {
+ MethodSymbol msym = searchMethod(encl, methodName, paramTypes, searched);
+ if (msym != null) {
+ return msym;
+ }
+ }
+
+ return null;
+ }
+
+ /** @see com.sun.tools.javadoc.ClassDocImpl */
+ private boolean hasParameterTypes(MethodSymbol method, List<Type> paramTypes) {
+ if (paramTypes == null)
+ return true;
+
+ if (method.params().size() != paramTypes.size())
+ return false;
+
+ List<Type> methodParamTypes = types.erasureRecursive(method.asType()).getParameterTypes();
+
+ return (Type.isErroneous(paramTypes))
+ ? fuzzyMatch(paramTypes, methodParamTypes)
+ : types.isSameTypes(paramTypes, methodParamTypes);
+ }
+
+ boolean fuzzyMatch(List<Type> paramTypes, List<Type> methodParamTypes) {
+ List<Type> l1 = paramTypes;
+ List<Type> l2 = methodParamTypes;
+ while (l1.nonEmpty()) {
+ if (!fuzzyMatch(l1.head, l2.head))
+ return false;
+ l1 = l1.tail;
+ l2 = l2.tail;
+ }
+ return true;
+ }
+
+ boolean fuzzyMatch(Type paramType, Type methodParamType) {
+ Boolean b = fuzzyMatcher.visit(paramType, methodParamType);
+ return (b == Boolean.TRUE);
+ }
+
+ TypeRelation fuzzyMatcher = new TypeRelation() {
+ @Override
+ public Boolean visitType(Type t, Type s) {
+ if (t == s)
+ return true;
+
+ if (s.isPartial())
+ return visit(s, t);
+
+ switch (t.getTag()) {
+ case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
+ case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
+ return t.getTag() == s.getTag();
+
+ default:
+ throw new AssertionError("fuzzyMatcher " + t.getTag());
+ }
+ }
+
+ @Override
+ public Boolean visitArrayType(ArrayType t, Type s) {
+ if (t == s)
+ return true;
+
+ if (s.isPartial())
+ return visit(s, t);
+
+ return s.getTag() == ARRAY
+ && visit(t.elemtype, types.elemtype(s));
+ }
+
+ @Override
+ public Boolean visitClassType(ClassType t, Type s) {
+ if (t == s)
+ return true;
+
+ if (s.isPartial())
+ return visit(s, t);
+
+ return t.tsym == s.tsym;
+ }
+
+ @Override
+ public Boolean visitErrorType(ErrorType t, Type s) {
+ return s.getTag() == CLASS
+ && t.tsym.name == ((ClassType) s).tsym.name;
+ }
+ };
+
public TypeMirror getTypeMirror(TreePath path) {
Tree t = path.getLeaf();
return ((JCTree)t).type;
@@ -250,6 +593,18 @@
return null;
}
+ public DocCommentTree getDocCommentTree(TreePath path) {
+ CompilationUnitTree t = path.getCompilationUnit();
+ Tree leaf = path.getLeaf();
+ if (t instanceof JCTree.JCCompilationUnit && leaf instanceof JCTree) {
+ JCCompilationUnit cu = (JCCompilationUnit) t;
+ if (cu.docComments != null) {
+ return cu.docComments.getCommentTree((JCTree) leaf);
+ }
+ }
+ return null;
+ }
+
public boolean isAccessible(Scope scope, TypeElement type) {
if (scope instanceof JavacScope && type instanceof ClassSymbol) {
Env<AttrContext> env = ((JavacScope) scope).env;
@@ -418,14 +773,27 @@
public void printMessage(Diagnostic.Kind kind, CharSequence msg,
com.sun.source.tree.Tree t,
com.sun.source.tree.CompilationUnitTree root) {
+ printMessage(kind, msg, ((JCTree) t).pos(), root);
+ }
+
+ public void printMessage(Diagnostic.Kind kind, CharSequence msg,
+ com.sun.source.doctree.DocTree t,
+ com.sun.source.doctree.DocCommentTree c,
+ com.sun.source.tree.CompilationUnitTree root) {
+ printMessage(kind, msg, ((DCTree) t).pos((DCDocComment) c), root);
+ }
+
+ private void printMessage(Diagnostic.Kind kind, CharSequence msg,
+ JCDiagnostic.DiagnosticPosition pos,
+ com.sun.source.tree.CompilationUnitTree root) {
JavaFileObject oldSource = null;
JavaFileObject newSource = null;
- JCDiagnostic.DiagnosticPosition pos = null;
newSource = root.getSourceFile();
- if (newSource != null) {
+ if (newSource == null) {
+ pos = null;
+ } else {
oldSource = log.useSource(newSource);
- pos = ((JCTree) t).pos();
}
try {
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Fri Nov 30 17:09:05 2012 -0800
@@ -262,7 +262,7 @@
* Flag that marks class as auxiliary, ie a non-public class following
* the public class in a source file, that could block implicit compilation.
*/
- public static final long AUXILIARY = 1L<<43;
+ public static final long AUXILIARY = 1L<<44;
/** Modifier masks.
*/
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Fri Nov 30 17:09:05 2012 -0800
@@ -206,6 +206,9 @@
public boolean allowDefaultMethods() {
return compareTo(JDK1_8) >= 0;
}
+ public boolean allowStrictMethodClashCheck() {
+ return compareTo(JDK1_8) >= 0;
+ }
public boolean allowEffectivelyFinalInInnerClasses() {
return compareTo(JDK1_8) >= 0;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Nov 30 17:09:05 2012 -0800
@@ -438,7 +438,8 @@
}
public Set<Modifier> getModifiers() {
- return Flags.asModifierSet(flags());
+ long flags = flags();
+ return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags);
}
public Name getSimpleName() {
@@ -475,6 +476,7 @@
public String toString() { return other.toString(); }
public Symbol location() { return other.location(); }
public Symbol location(Type site, Types types) { return other.location(site, types); }
+ public Symbol baseSymbol() { return other; }
public Type erasure(Types types) { return other.erasure(types); }
public Type externalType(Types types) { return other.externalType(types); }
public boolean isLocal() { return other.isLocal(); }
@@ -1192,9 +1194,9 @@
// check for an inherited implementation
if ((flags() & ABSTRACT) != 0 ||
- (other.flags() & ABSTRACT) == 0 ||
- !other.isOverridableIn(origin) ||
- !this.isMemberOf(origin, types))
+ ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) ||
+ !other.isOverridableIn(origin) ||
+ !this.isMemberOf(origin, types))
return false;
// assert types.asSuper(origin.type, other.owner) != null;
@@ -1202,7 +1204,7 @@
Type ot = types.memberType(origin.type, other);
return
types.isSubSignature(mt, ot) &&
- (!checkResult || types.resultSubtype(mt, ot, Warner.noWarnings));
+ (!checkResult || types.resultSubtype(mt, ot, types.noWarnings));
}
private boolean isOverridableIn(TypeSymbol origin) {
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Fri Nov 30 17:09:05 2012 -0800
@@ -130,6 +130,7 @@
public final Type methodHandleLookupType;
public final Type methodTypeType;
public final Type nativeHeaderType;
+ public final Type nativeHeaderType_old;
public final Type throwableType;
public final Type errorType;
public final Type interruptedExceptionType;
@@ -505,7 +506,8 @@
List.of(exceptionType), methodClass),
autoCloseableType.tsym);
trustMeType = enterClass("java.lang.SafeVarargs");
- nativeHeaderType = enterClass("javax.tools.annotation.GenerateNativeHeader");
+ nativeHeaderType = enterClass("java.lang.annotation.Native");
+ nativeHeaderType_old = enterClass("javax.tools.annotation.GenerateNativeHeader");
lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory");
synthesizeEmptyInterfaceIfMissing(autoCloseableType);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Nov 30 17:09:05 2012 -0800
@@ -75,6 +75,7 @@
final boolean allowBoxing;
final boolean allowCovariantReturns;
final boolean allowObjectToPrimitiveCast;
+ final boolean allowDefaultMethods;
final ClassReader reader;
final Check chk;
JCDiagnostic.Factory diags;
@@ -82,6 +83,8 @@
final Name capturedName;
private final FunctionDescriptorLookupError functionDescriptorLookupError;
+ public final Warner noWarnings;
+
// <editor-fold defaultstate="collapsed" desc="Instantiating">
public static Types instance(Context context) {
Types instance = context.get(typesKey);
@@ -98,12 +101,14 @@
allowBoxing = source.allowBoxing();
allowCovariantReturns = source.allowCovariantReturns();
allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast();
+ allowDefaultMethods = source.allowDefaultMethods();
reader = ClassReader.instance(context);
chk = Check.instance(context);
capturedName = names.fromString("<captured wildcard>");
messages = JavacMessages.instance(context);
diags = JCDiagnostic.Factory.instance(context);
functionDescriptorLookupError = new FunctionDescriptorLookupError();
+ noWarnings = new Warner(null);
}
// </editor-fold>
@@ -294,7 +299,7 @@
* convertions to s?
*/
public boolean isConvertible(Type t, Type s) {
- return isConvertible(t, s, Warner.noWarnings);
+ return isConvertible(t, s, noWarnings);
}
// </editor-fold>
@@ -392,15 +397,10 @@
@Override
public boolean accepts(Symbol sym) {
- return sym.kind == Kinds.MTH &&
- (sym.flags() & ABSTRACT) != 0 &&
- !overridesObjectMethod(origin, sym) &&
- notOverridden(sym);
- }
-
- private boolean notOverridden(Symbol msym) {
- Symbol impl = ((MethodSymbol)msym).implementation(origin, Types.this, false);
- return impl == null || (impl.flags() & ABSTRACT) != 0;
+ return sym.kind == Kinds.MTH &&
+ (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT &&
+ !overridesObjectMethod(origin, sym) &&
+ (interfaceCandidates(origin.type, (MethodSymbol)sym).head.flags() & DEFAULT) == 0;
}
};
@@ -591,7 +591,7 @@
* Is t an unchecked subtype of s?
*/
public boolean isSubtypeUnchecked(Type t, Type s) {
- return isSubtypeUnchecked(t, s, Warner.noWarnings);
+ return isSubtypeUnchecked(t, s, noWarnings);
}
/**
* Is t an unchecked subtype of s?
@@ -1194,7 +1194,7 @@
// <editor-fold defaultstate="collapsed" desc="isCastable">
public boolean isCastable(Type t, Type s) {
- return isCastable(t, s, Warner.noWarnings);
+ return isCastable(t, s, noWarnings);
}
/**
@@ -1257,7 +1257,7 @@
return true;
if (s.tag == TYPEVAR) {
- if (isCastable(t, s.getUpperBound(), Warner.noWarnings)) {
+ if (isCastable(t, s.getUpperBound(), noWarnings)) {
warnStack.head.warn(LintCategory.UNCHECKED);
return true;
} else {
@@ -1267,7 +1267,7 @@
if (t.isCompound()) {
Warner oldWarner = warnStack.head;
- warnStack.head = Warner.noWarnings;
+ warnStack.head = noWarnings;
if (!visit(supertype(t), s))
return false;
for (Type intf : interfaces(t)) {
@@ -1366,7 +1366,7 @@
case BOT:
return true;
case TYPEVAR:
- if (isCastable(s, t, Warner.noWarnings)) {
+ if (isCastable(s, t, noWarnings)) {
warnStack.head.warn(LintCategory.UNCHECKED);
return true;
} else {
@@ -1394,7 +1394,7 @@
case TYPEVAR:
if (isSubtype(t, s)) {
return true;
- } else if (isCastable(t.bound, s, Warner.noWarnings)) {
+ } else if (isCastable(t.bound, s, noWarnings)) {
warnStack.head.warn(LintCategory.UNCHECKED);
return true;
} else {
@@ -1533,7 +1533,7 @@
TypeVar tv = (TypeVar) t;
return !isCastable(tv.bound,
relaxBound(s),
- Warner.noWarnings);
+ noWarnings);
}
if (s.tag != WILDCARD)
s = upperBound(s);
@@ -1836,7 +1836,7 @@
// <editor-fold defaultstate="collapsed" desc="isAssignable">
public boolean isAssignable(Type t, Type s) {
- return isAssignable(t, s, Warner.noWarnings);
+ return isAssignable(t, s, noWarnings);
}
/**
@@ -2146,6 +2146,13 @@
return List.nil();
}
};
+
+ public boolean isDirectSuperInterface(TypeSymbol isym, TypeSymbol origin) {
+ for (Type i2 : interfaces(origin.type)) {
+ if (isym == i2.tsym) return true;
+ }
+ return false;
+ }
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
@@ -2215,7 +2222,9 @@
* Return list of bounds of the given type variable.
*/
public List<Type> getBounds(TypeVar t) {
- if (t.bound.isErroneous() || !t.bound.isCompound())
+ if (t.bound.hasTag(NONE))
+ return List.nil();
+ else if (t.bound.isErroneous() || !t.bound.isCompound())
return List.of(t.bound);
else if ((erasure(t).tsym.flags() & INTERFACE) == 0)
return interfaces(t).prepend(supertype(t));
@@ -2455,6 +2464,63 @@
}
// </editor-fold>
+
+ //where
+ public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) {
+ Filter<Symbol> filter = new MethodFilter(ms, site);
+ List<MethodSymbol> candidates = List.nil();
+ for (Symbol s : membersClosure(site, false).getElements(filter)) {
+ if (!site.tsym.isInterface() && !s.owner.isInterface()) {
+ return List.of((MethodSymbol)s);
+ } else if (!candidates.contains(s)) {
+ candidates = candidates.prepend((MethodSymbol)s);
+ }
+ }
+ return prune(candidates, ownerComparator);
+ }
+
+ public List<MethodSymbol> prune(List<MethodSymbol> methods, Comparator<MethodSymbol> cmp) {
+ ListBuffer<MethodSymbol> methodsMin = ListBuffer.lb();
+ for (MethodSymbol m1 : methods) {
+ boolean isMin_m1 = true;
+ for (MethodSymbol m2 : methods) {
+ if (m1 == m2) continue;
+ if (cmp.compare(m2, m1) < 0) {
+ isMin_m1 = false;
+ break;
+ }
+ }
+ if (isMin_m1)
+ methodsMin.append(m1);
+ }
+ return methodsMin.toList();
+ }
+
+ Comparator<MethodSymbol> ownerComparator = new Comparator<MethodSymbol>() {
+ public int compare(MethodSymbol s1, MethodSymbol s2) {
+ return s1.owner.isSubClass(s2.owner, Types.this) ? -1 : 1;
+ }
+ };
+ // where
+ private class MethodFilter implements Filter<Symbol> {
+
+ Symbol msym;
+ Type site;
+
+ MethodFilter(Symbol msym, Type site) {
+ this.msym = msym;
+ this.site = site;
+ }
+
+ public boolean accepts(Symbol s) {
+ return s.kind == Kinds.MTH &&
+ s.name == msym.name &&
+ s.isInheritedIn(site.tsym, Types.this) &&
+ overrideEquivalent(memberType(site, s), memberType(site, msym));
+ }
+ };
+ // </editor-fold>
+
/**
* Does t have the same arguments as s? It is assumed that both
* types are (possibly polymorphic) method types. Monomorphic
@@ -3385,11 +3451,11 @@
*/
public boolean returnTypeSubstitutable(Type r1, Type r2) {
if (hasSameArgs(r1, r2))
- return resultSubtype(r1, r2, Warner.noWarnings);
+ return resultSubtype(r1, r2, noWarnings);
else
return covariantReturnType(r1.getReturnType(),
erasure(r2.getReturnType()),
- Warner.noWarnings);
+ noWarnings);
}
public boolean returnTypeSubstitutable(Type r1,
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Nov 30 17:09:05 2012 -0800
@@ -133,8 +133,9 @@
allowCovariantReturns = source.allowCovariantReturns();
allowAnonOuterThis = source.allowAnonOuterThis();
allowStringsInSwitch = source.allowStringsInSwitch();
- allowPoly = source.allowPoly() && options.isSet("allowPoly");
+ allowPoly = source.allowPoly();
allowLambda = source.allowLambda();
+ allowDefaultMethods = source.allowDefaultMethods();
sourceName = source.name;
relax = (options.isSet("-retrofit") ||
options.isSet("-relax"));
@@ -182,6 +183,10 @@
*/
boolean allowLambda;
+ /** Switch: support default methods ?
+ */
+ boolean allowDefaultMethods;
+
/** Switch: allow references to surrounding object from anonymous
* objects during constructor call?
*/
@@ -519,6 +524,10 @@
protected ResultInfo dup(Type newPt) {
return new ResultInfo(pkind, newPt, checkContext);
}
+
+ protected ResultInfo dup(CheckContext newContext) {
+ return new ResultInfo(pkind, pt, newContext);
+ }
}
class RecoveryInfo extends ResultInfo {
@@ -535,7 +544,7 @@
}
@Override
public void report(DiagnosticPosition pos, JCDiagnostic details) {
- //do nothing
+ chk.basicHandler.report(pos, details);
}
});
}
@@ -590,8 +599,10 @@
this.env = env;
this.resultInfo = resultInfo;
tree.accept(this);
- if (tree == breakTree)
+ if (tree == breakTree &&
+ resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
throw new BreakAttr(env);
+ }
return result;
} catch (CompletionFailure ex) {
tree.type = syms.errType;
@@ -611,13 +622,13 @@
/** Derived visitor method: attribute an expression tree with
* no constraints on the computed type.
*/
- Type attribExpr(JCTree tree, Env<AttrContext> env) {
+ public Type attribExpr(JCTree tree, Env<AttrContext> env) {
return attribTree(tree, env, unknownExprInfo);
}
/** Derived visitor method: attribute a type tree.
*/
- Type attribType(JCTree tree, Env<AttrContext> env) {
+ public Type attribType(JCTree tree, Env<AttrContext> env) {
Type result = attribType(tree, env, Type.noType);
return result;
}
@@ -898,6 +909,10 @@
localEnv.info.lint = lint;
+ if (isDefaultMethod && types.overridesObjectMethod(m.enclClass(), m)) {
+ log.error(tree, "default.overrides.object.member", m.name, Kinds.kindName(m.location()), m.location());
+ }
+
// Enter all type parameters into the local method scope.
for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
localEnv.info.scope.enterIfAbsent(l.head.type.tsym);
@@ -961,10 +976,12 @@
log.error(tree.pos(),
"default.allowed.in.intf.annotation.member");
}
- } else if ((owner.flags() & INTERFACE) != 0 && !isDefaultMethod) {
- log.error(tree.body.pos(), "intf.meth.cant.have.body");
- } else if ((tree.mods.flags & ABSTRACT) != 0) {
- log.error(tree.pos(), "abstract.meth.cant.have.body");
+ } else if ((tree.sym.flags() & ABSTRACT) != 0 && !isDefaultMethod) {
+ if ((owner.flags() & INTERFACE) != 0) {
+ log.error(tree.body.pos(), "intf.meth.cant.have.body");
+ } else {
+ log.error(tree.pos(), "abstract.meth.cant.have.body");
+ }
} else if ((tree.mods.flags & NATIVE) != 0) {
log.error(tree.pos(), "native.meth.cant.have.body");
} else {
@@ -1349,11 +1366,8 @@
types.asSuper(resource, syms.autoCloseableType.tsym) != null &&
!types.isSameType(resource, syms.autoCloseableType)) { // Don't emit warning for AutoCloseable itself
Symbol close = syms.noSymbol;
- Filter<JCDiagnostic> prevDeferDiagsFilter = log.deferredDiagFilter;
- Queue<JCDiagnostic> prevDeferredDiags = log.deferredDiagnostics;
+ Log.DiagnosticHandler discardHandler = new Log.DiscardDiagnosticHandler(log);
try {
- log.deferAll();
- log.deferredDiagnostics = ListBuffer.lb();
close = rs.resolveQualifiedMethod(pos,
env,
resource,
@@ -1362,8 +1376,7 @@
List.<Type>nil());
}
finally {
- log.deferredDiagFilter = prevDeferDiagsFilter;
- log.deferredDiagnostics = prevDeferredDiags;
+ log.popDiagnosticHandler(discardHandler);
}
if (close.kind == MTH &&
close.overrides(syms.autoCloseableClose, resource.tsym, types, true) &&
@@ -1383,13 +1396,14 @@
if (!standaloneConditional && resultInfo.pt.hasTag(VOID)) {
//cannot get here (i.e. it means we are returning from void method - which is already an error)
+ resultInfo.checkContext.report(tree, diags.fragment("conditional.target.cant.be.void"));
result = tree.type = types.createErrorType(resultInfo.pt);
return;
}
ResultInfo condInfo = standaloneConditional ?
unknownExprInfo :
- new ResultInfo(VAL, pt(), new Check.NestedCheckContext(resultInfo.checkContext) {
+ resultInfo.dup(new Check.NestedCheckContext(resultInfo.checkContext) {
//this will use enclosing check context to check compatibility of
//subexpression against target type; if we are in a method check context,
//depending on whether boxing is allowed, we could have incompatibilities
@@ -1412,11 +1426,11 @@
result = check(tree, owntype, VAL, resultInfo);
}
//where
- @SuppressWarnings("fallthrough")
private boolean isBooleanOrNumeric(Env<AttrContext> env, JCExpression tree) {
switch (tree.getTag()) {
case LITERAL: return ((JCLiteral)tree).typetag.isSubRangeOf(DOUBLE) ||
- ((JCLiteral)tree).typetag == BOOLEAN;
+ ((JCLiteral)tree).typetag == BOOLEAN ||
+ ((JCLiteral)tree).typetag == BOT;
case LAMBDA: case REFERENCE: return false;
case PARENS: return isBooleanOrNumeric(env, ((JCParens)tree).expr);
case CONDEXPR:
@@ -1605,19 +1619,23 @@
// it conforms to result type of enclosing method.
if (tree.expr != null) {
if (env.info.returnResult.pt.hasTag(VOID)) {
- log.error(tree.expr.pos(),
- "cant.ret.val.from.meth.decl.void");
+ env.info.returnResult.checkContext.report(tree.expr.pos(),
+ diags.fragment("unexpected.ret.val"));
}
attribTree(tree.expr, env, env.info.returnResult);
} else if (!env.info.returnResult.pt.hasTag(VOID)) {
- log.error(tree.pos(), "missing.ret.val");
+ env.info.returnResult.checkContext.report(tree.pos(),
+ diags.fragment("missing.ret.val"));
}
}
result = null;
}
public void visitThrow(JCThrow tree) {
- attribExpr(tree.expr, env, syms.throwableType);
+ Type owntype = attribExpr(tree.expr, env, allowPoly ? Type.noType : syms.throwableType);
+ if (allowPoly) {
+ chk.checkType(tree, owntype, syms.throwableType);
+ }
result = null;
}
@@ -2061,7 +2079,7 @@
resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt());
Type inferred = deferredAttr.attribSpeculative(tree, env, findDiamondResult).type;
if (!inferred.isErroneous() &&
- types.isAssignable(inferred, pt().hasTag(NONE) ? syms.objectType : pt(), Warner.noWarnings)) {
+ types.isAssignable(inferred, pt().hasTag(NONE) ? syms.objectType : pt(), types.noWarnings)) {
String key = types.isSameType(clazztype, inferred) ?
"diamond.redundant.args" :
"diamond.redundant.args.1";
@@ -2165,7 +2183,7 @@
}
//create an environment for attribution of the lambda expression
final Env<AttrContext> localEnv = lambdaEnv(that, env);
- boolean needsRecovery = resultInfo.checkContext.deferredAttrContext() == deferredAttr.emptyDeferredAttrContext ||
+ boolean needsRecovery =
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
try {
List<Type> explicitParamTypes = null;
@@ -2175,10 +2193,16 @@
explicitParamTypes = TreeInfo.types(that.params);
}
- Type target = infer.instantiateFunctionalInterface(that, pt(), explicitParamTypes, resultInfo.checkContext);
- Type lambdaType = (target == Type.recoveryType) ?
- fallbackDescriptorType(that) :
- types.findDescriptorType(target);
+ Type target;
+ Type lambdaType;
+ if (pt() != Type.recoveryType) {
+ target = infer.instantiateFunctionalInterface(that, pt(), explicitParamTypes, resultInfo.checkContext);
+ lambdaType = types.findDescriptorType(target);
+ chk.checkFunctionalInterface(that, target);
+ } else {
+ target = Type.recoveryType;
+ lambdaType = fallbackDescriptorType(that);
+ }
if (!TreeInfo.isExplicitLambda(that)) {
//add param type info in the AST
@@ -2243,7 +2267,7 @@
checkLambdaCompatible(that, lambdaType, resultInfo.checkContext, isSpeculativeRound);
if (!isSpeculativeRound) {
- checkAccessibleFunctionalDescriptor(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType);
+ checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, target);
}
result = check(that, target, VAL, resultInfo);
} catch (Types.FunctionDescriptorLookupError ex) {
@@ -2278,17 +2302,22 @@
return null;
}
- private void checkAccessibleFunctionalDescriptor(final DiagnosticPosition pos,
- final Env<AttrContext> env, final InferenceContext inferenceContext, final Type desc) {
- if (inferenceContext.free(desc)) {
- inferenceContext.addFreeTypeListener(List.of(desc), new FreeTypeListener() {
+ private void checkAccessibleTypes(final DiagnosticPosition pos, final Env<AttrContext> env, final InferenceContext inferenceContext, final Type... ts) {
+ checkAccessibleTypes(pos, env, inferenceContext, List.from(ts));
+ }
+
+ private void checkAccessibleTypes(final DiagnosticPosition pos, final Env<AttrContext> env, final InferenceContext inferenceContext, final List<Type> ts) {
+ if (inferenceContext.free(ts)) {
+ inferenceContext.addFreeTypeListener(ts, new FreeTypeListener() {
@Override
public void typesInferred(InferenceContext inferenceContext) {
- checkAccessibleFunctionalDescriptor(pos, env, inferenceContext, inferenceContext.asInstType(desc, types));
+ checkAccessibleTypes(pos, env, inferenceContext, inferenceContext.asInstTypes(ts, types));
}
});
} else {
- chk.checkAccessibleFunctionalDescriptor(pos, env, desc);
+ for (Type t : ts) {
+ rs.checkAccessibleType(env, t);
+ }
}
}
@@ -2404,15 +2433,20 @@
typeargtypes = attribTypes(that.typeargs, localEnv);
}
- Type target = infer.instantiateFunctionalInterface(that, pt(), null, resultInfo.checkContext);
- Type desc = (target == Type.recoveryType) ?
- fallbackDescriptorType(that) :
- types.findDescriptorType(target);
+ Type target;
+ Type desc;
+ if (pt() != Type.recoveryType) {
+ target = infer.instantiateFunctionalInterface(that, pt(), null, resultInfo.checkContext);
+ desc = types.findDescriptorType(target);
+ chk.checkFunctionalInterface(that, target);
+ } else {
+ target = Type.recoveryType;
+ desc = fallbackDescriptorType(that);
+ }
List<Type> argtypes = desc.getParameterTypes();
boolean allowBoxing =
- resultInfo.checkContext.deferredAttrContext() == deferredAttr.emptyDeferredAttrContext ||
resultInfo.checkContext.deferredAttrContext().phase.isBoxingRequired();
Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = rs.resolveMemberReference(that.pos(), localEnv, that,
that.expr.type, that.name, argtypes, typeargtypes, allowBoxing);
@@ -2448,18 +2482,25 @@
JCDiagnostic diag = diags.create(diagKind, log.currentSource(), that,
"invalid.mref", Kinds.kindName(that.getMode()), detailsDiag);
- if (targetError) {
- resultInfo.checkContext.report(that, diag);
+ if (targetError && target == Type.recoveryType) {
+ //a target error doesn't make sense during recovery stage
+ //as we don't know what actual parameter types are
+ result = that.type = target;
+ return;
} else {
- log.report(diag);
+ if (targetError) {
+ resultInfo.checkContext.report(that, diag);
+ } else {
+ log.report(diag);
+ }
+ result = that.type = types.createErrorType(target);
+ return;
}
- result = that.type = types.createErrorType(target);
- return;
}
if (desc.getReturnType() == Type.recoveryType) {
// stop here
- result = that.type = types.createErrorType(target);
+ result = that.type = target;
return;
}
@@ -2485,7 +2526,7 @@
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
checkReferenceCompatible(that, desc, refType, resultInfo.checkContext, isSpeculativeRound);
if (!isSpeculativeRound) {
- checkAccessibleFunctionalDescriptor(that, localEnv, resultInfo.checkContext.inferenceContext(), desc);
+ checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, target);
}
result = check(that, target, VAL, resultInfo);
} catch (Types.FunctionDescriptorLookupError ex) {
@@ -2519,7 +2560,7 @@
if (!returnType.hasTag(VOID) && !resType.hasTag(VOID)) {
if (resType.isErroneous() ||
- new LambdaReturnContext(checkContext).compatible(resType, returnType, Warner.noWarnings)) {
+ new LambdaReturnContext(checkContext).compatible(resType, returnType, types.noWarnings)) {
incompatibleReturnType = null;
}
}
@@ -3032,15 +3073,52 @@
Symbol sym,
Env<AttrContext> env,
ResultInfo resultInfo) {
- Type pt = resultInfo.pt.hasTag(FORALL) || resultInfo.pt.hasTag(METHOD) ?
- resultInfo.pt.map(deferredAttr.new DeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase)) :
- resultInfo.pt;
-
- DeferredAttr.DeferredTypeMap recoveryMap =
- deferredAttr.new RecoveryDeferredTypeMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase);
-
+ return (resultInfo.pt.hasTag(FORALL) || resultInfo.pt.hasTag(METHOD)) ?
+ checkMethodId(tree, site, sym, env, resultInfo) :
+ checkIdInternal(tree, site, sym, resultInfo.pt, env, resultInfo);
+ }
+
+ Type checkMethodId(JCTree tree,
+ Type site,
+ Symbol sym,
+ Env<AttrContext> env,
+ ResultInfo resultInfo) {
+ boolean isPolymorhicSignature =
+ sym.kind == MTH && ((MethodSymbol)sym.baseSymbol()).isSignaturePolymorphic(types);
+ return isPolymorhicSignature ?
+ checkSigPolyMethodId(tree, site, sym, env, resultInfo) :
+ checkMethodIdInternal(tree, site, sym, env, resultInfo);
+ }
+
+ Type checkSigPolyMethodId(JCTree tree,
+ Type site,
+ Symbol sym,
+ Env<AttrContext> env,
+ ResultInfo resultInfo) {
+ //recover original symbol for signature polymorphic methods
+ checkMethodIdInternal(tree, site, sym.baseSymbol(), env, resultInfo);
+ env.info.pendingResolutionPhase = Resolve.MethodResolutionPhase.BASIC;
+ return sym.type;
+ }
+
+ Type checkMethodIdInternal(JCTree tree,
+ Type site,
+ Symbol sym,
+ Env<AttrContext> env,
+ ResultInfo resultInfo) {
+ Type pt = resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase));
+ Type owntype = checkIdInternal(tree, site, sym, pt, env, resultInfo);
+ resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase));
+ return owntype;
+ }
+
+ Type checkIdInternal(JCTree tree,
+ Type site,
+ Symbol sym,
+ Type pt,
+ Env<AttrContext> env,
+ ResultInfo resultInfo) {
if (pt.isErroneous()) {
- Type.map(resultInfo.pt.getParameterTypes(), recoveryMap);
return types.createErrorType(site);
}
Type owntype; // The computed type of this identifier occurrence.
@@ -3125,7 +3203,6 @@
break;
}
case PCK: case ERR:
- Type.map(resultInfo.pt.getParameterTypes(), recoveryMap);
owntype = sym.type;
break;
default:
@@ -3281,6 +3358,23 @@
}
}
+ if (env.info.defaultSuperCallSite != null) {
+ for (Type sup : types.interfaces(env.enclClass.type).prepend(types.supertype((env.enclClass.type)))) {
+ if (!sup.tsym.isSubClass(sym.enclClass(), types) ||
+ types.isSameType(sup, env.info.defaultSuperCallSite)) continue;
+ List<MethodSymbol> icand_sup =
+ types.interfaceCandidates(sup, (MethodSymbol)sym);
+ if (icand_sup.nonEmpty() &&
+ icand_sup.head != sym &&
+ icand_sup.head.overrides(sym, icand_sup.head.enclClass(), types, true)) {
+ log.error(env.tree.pos(), "illegal.default.super.call", env.info.defaultSuperCallSite,
+ diags.fragment("overridden.default", sym, sup));
+ break;
+ }
+ }
+ env.info.defaultSuperCallSite = null;
+ }
+
// Compute the identifier's instantiated type.
// For methods, we need to compute the instance type by
// Resolve.instantiate from the symbol's type as well as
@@ -3700,6 +3794,9 @@
// are compatible (i.e. no two define methods with same arguments
// yet different return types). (JLS 8.4.6.3)
chk.checkCompatibleSupertypes(tree.pos(), c.type);
+ if (allowDefaultMethods) {
+ chk.checkDefaultMethodClashes(tree.pos(), c.type);
+ }
}
// Check that class does not import the same parameterized interface
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Fri Nov 30 17:09:05 2012 -0800
@@ -72,6 +72,10 @@
*/
Attr.ResultInfo returnResult = null;
+ /** Symbol corresponding to the site of a qualified default super call
+ */
+ Type defaultSuperCallSite = null;
+
/** Duplicate this context, replacing scope field and copying all others.
*/
AttrContext dup(Scope scope) {
@@ -84,6 +88,7 @@
info.lint = lint;
info.enclVar = enclVar;
info.returnResult = returnResult;
+ info.defaultSuperCallSite = defaultSuperCallSite;
return info;
}
@@ -104,6 +109,7 @@
pendingResolutionPhase.isVarargsRequired();
}
+ @Override
public String toString() {
return "AttrContext[" + scope.toString() + "]";
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Nov 30 17:09:05 2012 -0800
@@ -119,6 +119,8 @@
allowAnnotations = source.allowAnnotations();
allowCovariantReturns = source.allowCovariantReturns();
allowSimplifiedVarargs = source.allowSimplifiedVarargs();
+ allowDefaultMethods = source.allowDefaultMethods();
+ allowStrictMethodClashCheck = source.allowStrictMethodClashCheck();
complexInference = options.isSet("complexinference");
warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
@@ -162,6 +164,14 @@
*/
boolean allowSimplifiedVarargs;
+ /** Switch: default methods enabled?
+ */
+ boolean allowDefaultMethods;
+
+ /** Switch: should unrelated return types trigger a method clash?
+ */
+ boolean allowStrictMethodClashCheck;
+
/** Switch: -complexinference option set?
*/
boolean complexInference;
@@ -440,8 +450,6 @@
public Infer.InferenceContext inferenceContext();
public DeferredAttr.DeferredAttrContext deferredAttrContext();
-
- public boolean allowBoxing();
}
/**
@@ -476,10 +484,6 @@
public DeferredAttrContext deferredAttrContext() {
return enclosingContext.deferredAttrContext();
}
-
- public boolean allowBoxing() {
- return enclosingContext.allowBoxing();
- }
}
/**
@@ -504,10 +508,6 @@
public DeferredAttrContext deferredAttrContext() {
return deferredAttr.emptyDeferredAttrContext;
}
-
- public boolean allowBoxing() {
- return true;
- }
};
/** Check that a given type is assignable to a given proto-type.
@@ -614,7 +614,7 @@
a = types.upperBound(a);
return types.isSubtype(a, bound);
} else if (a.isExtendsBound()) {
- return types.isCastable(bound, types.upperBound(a), Warner.noWarnings);
+ return types.isCastable(bound, types.upperBound(a), types.noWarnings);
} else if (a.isSuperBound()) {
return !types.notSoftSubtype(types.lowerBound(a), bound);
}
@@ -898,19 +898,21 @@
"unchecked.generic.array.creation",
argtype);
}
- Type elemtype = types.elemtype(argtype);
- switch (tree.getTag()) {
- case APPLY:
- ((JCMethodInvocation) tree).varargsElement = elemtype;
- break;
- case NEWCLASS:
- ((JCNewClass) tree).varargsElement = elemtype;
- break;
- case REFERENCE:
- ((JCMemberReference) tree).varargsElement = elemtype;
- break;
- default:
- throw new AssertionError(""+tree);
+ if (!((MethodSymbol)sym.baseSymbol()).isSignaturePolymorphic(types)) {
+ Type elemtype = types.elemtype(argtype);
+ switch (tree.getTag()) {
+ case APPLY:
+ ((JCMethodInvocation) tree).varargsElement = elemtype;
+ break;
+ case NEWCLASS:
+ ((JCNewClass) tree).varargsElement = elemtype;
+ break;
+ case REFERENCE:
+ ((JCMemberReference) tree).varargsElement = elemtype;
+ break;
+ default:
+ throw new AssertionError(""+tree);
+ }
}
}
return owntype;
@@ -926,65 +928,6 @@
return;
}
- void checkAccessibleFunctionalDescriptor(DiagnosticPosition pos, Env<AttrContext> env, Type desc) {
- AccessChecker accessChecker = new AccessChecker(env);
- //check args accessibility (only if implicit parameter types)
- for (Type arg : desc.getParameterTypes()) {
- if (!accessChecker.visit(arg)) {
- log.error(pos, "cant.access.arg.type.in.functional.desc", arg);
- return;
- }
- }
- //check return type accessibility
- if (!accessChecker.visit(desc.getReturnType())) {
- log.error(pos, "cant.access.return.in.functional.desc", desc.getReturnType());
- return;
- }
- //check thrown types accessibility
- for (Type thrown : desc.getThrownTypes()) {
- if (!accessChecker.visit(thrown)) {
- log.error(pos, "cant.access.thrown.in.functional.desc", thrown);
- return;
- }
- }
- }
-
- class AccessChecker extends Types.UnaryVisitor<Boolean> {
-
- Env<AttrContext> env;
-
- AccessChecker(Env<AttrContext> env) {
- this.env = env;
- }
-
- Boolean visit(List<Type> ts) {
- for (Type t : ts) {
- if (!visit(t))
- return false;
- }
- return true;
- }
-
- public Boolean visitType(Type t, Void s) {
- return true;
- }
-
- @Override
- public Boolean visitArrayType(ArrayType t, Void s) {
- return visit(t.elemtype);
- }
-
- @Override
- public Boolean visitClassType(ClassType t, Void s) {
- return rs.isAccessible(env, t, true) &&
- visit(t.getTypeArguments());
- }
-
- @Override
- public Boolean visitWildcardType(WildcardType t, Void s) {
- return visit(t.type);
- }
- };
/**
* Check that type 't' is a valid instantiation of a generic class
* (see JLS 4.5)
@@ -1114,7 +1057,7 @@
} else if ((sym.owner.flags_field & INTERFACE) != 0) {
if ((flags & DEFAULT) != 0) {
mask = InterfaceDefaultMethodMask;
- implicit = PUBLIC;
+ implicit = PUBLIC | ABSTRACT;
} else {
mask = implicit = InterfaceMethodFlags;
}
@@ -1908,8 +1851,8 @@
types.isSameType(rt1, rt2) ||
!rt1.isPrimitiveOrVoid() &&
!rt2.isPrimitiveOrVoid() &&
- (types.covariantReturnType(rt1, rt2, Warner.noWarnings) ||
- types.covariantReturnType(rt2, rt1, Warner.noWarnings)) ||
+ (types.covariantReturnType(rt1, rt2, types.noWarnings) ||
+ types.covariantReturnType(rt2, rt1, types.noWarnings)) ||
checkCommonOverriderIn(s1,s2,site);
if (!compat) {
log.error(pos, "types.incompatible.diff.ret",
@@ -1954,8 +1897,8 @@
boolean compat =
!rt13.isPrimitiveOrVoid() &&
!rt23.isPrimitiveOrVoid() &&
- (types.covariantReturnType(rt13, rt1, Warner.noWarnings) &&
- types.covariantReturnType(rt23, rt2, Warner.noWarnings));
+ (types.covariantReturnType(rt13, rt1, types.noWarnings) &&
+ types.covariantReturnType(rt23, rt2, types.noWarnings));
if (compat)
return true;
}
@@ -2047,11 +1990,21 @@
undef == null && e != null;
e = e.sibling) {
if (e.sym.kind == MTH &&
- (e.sym.flags() & (ABSTRACT|IPROXY)) == ABSTRACT) {
+ (e.sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) {
MethodSymbol absmeth = (MethodSymbol)e.sym;
MethodSymbol implmeth = absmeth.implementation(impl, types, true);
- if (implmeth == null || implmeth == absmeth)
+ if (implmeth == null || implmeth == absmeth) {
+ //look for default implementations
+ if (allowDefaultMethods) {
+ MethodSymbol prov = types.interfaceCandidates(impl.type, absmeth).head;
+ if (prov != null && prov.overrides(absmeth, impl, types, true)) {
+ implmeth = prov;
+ }
+ }
+ }
+ if (implmeth == null || implmeth == absmeth) {
undef = absmeth;
+ }
}
}
if (undef == null) {
@@ -2259,19 +2212,33 @@
c.flags_field |= ACYCLIC;
}
+ /**
+ * Check that functional interface methods would make sense when seen
+ * from the perspective of the implementing class
+ */
+ void checkFunctionalInterface(JCTree tree, Type funcInterface) {
+ ClassType c = new ClassType(Type.noType, List.<Type>nil(), null);
+ ClassSymbol csym = new ClassSymbol(0, names.empty, c, syms.noSymbol);
+ c.interfaces_field = List.of(funcInterface);
+ c.supertype_field = syms.objectType;
+ c.tsym = csym;
+ csym.members_field = new Scope(csym);
+ csym.completer = null;
+ checkImplementations(tree, csym, csym);
+ }
+
/** Check that all methods which implement some
* method conform to the method they implement.
* @param tree The class definition whose members are checked.
*/
void checkImplementations(JCClassDecl tree) {
- checkImplementations(tree, tree.sym);
+ checkImplementations(tree, tree.sym, tree.sym);
}
//where
/** Check that all methods which implement some
* method in `ic' conform to the method they implement.
*/
- void checkImplementations(JCClassDecl tree, ClassSymbol ic) {
- ClassSymbol origin = tree.sym;
+ void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) {
for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
ClassSymbol lc = (ClassSymbol)l.head.tsym;
if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) {
@@ -2354,7 +2321,7 @@
if (m2 == m1) continue;
//if (i) the signature of 'sym' is not a subsignature of m1 (seen as
//a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
- if (!types.isSubSignature(sym.type, types.memberType(site, m2), false) &&
+ if (!types.isSubSignature(sym.type, types.memberType(site, m2), allowStrictMethodClashCheck) &&
types.hasSameArgs(m2.erasure(types), m1.erasure(types))) {
sym.flags_field |= CLASH;
String key = m1 == sym ?
@@ -2386,7 +2353,7 @@
for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) {
//if (i) the signature of 'sym' is not a subsignature of m1 (seen as
//a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
- if (!types.isSubSignature(sym.type, types.memberType(site, s), false) &&
+ if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck) &&
types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
log.error(pos,
"name.clash.same.erasure.no.hide",
@@ -2420,6 +2387,62 @@
}
}
+ void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) {
+ DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site);
+ for (Symbol m : types.membersClosure(site, false).getElements(dcf)) {
+ Assert.check(m.kind == MTH);
+ List<MethodSymbol> prov = types.interfaceCandidates(site, (MethodSymbol)m);
+ if (prov.size() > 1) {
+ ListBuffer<Symbol> abstracts = ListBuffer.lb();
+ ListBuffer<Symbol> defaults = ListBuffer.lb();
+ for (MethodSymbol provSym : prov) {
+ if ((provSym.flags() & DEFAULT) != 0) {
+ defaults = defaults.append(provSym);
+ } else if ((provSym.flags() & ABSTRACT) != 0) {
+ abstracts = abstracts.append(provSym);
+ }
+ if (defaults.nonEmpty() && defaults.size() + abstracts.size() >= 2) {
+ //strong semantics - issue an error if two sibling interfaces
+ //have two override-equivalent defaults - or if one is abstract
+ //and the other is default
+ String errKey;
+ Symbol s1 = defaults.first();
+ Symbol s2;
+ if (defaults.size() > 1) {
+ errKey = "types.incompatible.unrelated.defaults";
+ s2 = defaults.toList().tail.head;
+ } else {
+ errKey = "types.incompatible.abstract.default";
+ s2 = abstracts.first();
+ }
+ log.error(pos, errKey,
+ Kinds.kindName(site.tsym), site,
+ m.name, types.memberType(site, m).getParameterTypes(),
+ s1.location(), s2.location());
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ //where
+ private class DefaultMethodClashFilter implements Filter<Symbol> {
+
+ Type site;
+
+ DefaultMethodClashFilter(Type site) {
+ this.site = site;
+ }
+
+ public boolean accepts(Symbol s) {
+ return s.kind == MTH &&
+ (s.flags() & DEFAULT) != 0 &&
+ s.isInheritedIn(site.tsym, types) &&
+ !s.isConstructor();
+ }
+ }
+
/** Report a conflict between a user symbol and a synthetic symbol.
*/
private void syntheticError(DiagnosticPosition pos, Symbol sym) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Fri Nov 30 17:09:05 2012 -0800
@@ -38,14 +38,13 @@
import javax.tools.JavaFileObject;
import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.WeakHashMap;
-import static com.sun.tools.javac.code.TypeTag.DEFERRED;
-import static com.sun.tools.javac.code.TypeTag.NONE;
+import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
/**
@@ -137,19 +136,6 @@
}
/**
- * Clone a speculative cache entry as a fresh entry associated
- * with a new method (this maybe required to fixup speculative cache
- * misses after Resolve.access())
- */
- void dupAllTo(Symbol from, Symbol to) {
- Assert.check(cache.get(to) == null);
- List<Entry> entries = cache.get(from);
- if (entries != null) {
- cache.put(to, entries);
- }
- }
-
- /**
* Retrieve a speculative cache entry corresponding to given symbol
* and resolution phase
*/
@@ -194,7 +180,7 @@
DeferredAttrContext deferredAttrContext =
resultInfo.checkContext.deferredAttrContext();
Assert.check(deferredAttrContext != emptyDeferredAttrContext);
- List<Type> stuckVars = stuckVars(tree, resultInfo);
+ List<Type> stuckVars = stuckVars(tree, env, resultInfo);
if (stuckVars.nonEmpty()) {
deferredAttrContext.addDeferredAttrNode(this, resultInfo, stuckVars);
return Type.noType;
@@ -249,28 +235,25 @@
JCTree newTree = new TreeCopier<Object>(make).copy(tree);
Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared()));
speculativeEnv.info.scope.owner = env.info.scope.owner;
- Filter<JCDiagnostic> prevDeferDiagsFilter = log.deferredDiagFilter;
- Queue<JCDiagnostic> prevDeferredDiags = log.deferredDiagnostics;
final JavaFileObject currentSource = log.currentSourceFile();
+ Log.DeferredDiagnosticHandler deferredDiagnosticHandler =
+ new Log.DeferredDiagnosticHandler(log, new Filter<JCDiagnostic>() {
+ public boolean accepts(JCDiagnostic t) {
+ return t.getDiagnosticSource().getFile().equals(currentSource);
+ }
+ });
try {
- log.deferredDiagnostics = new ListBuffer<JCDiagnostic>();
- log.deferredDiagFilter = new Filter<JCDiagnostic>() {
- public boolean accepts(JCDiagnostic t) {
- return t.getDiagnosticSource().getFile().equals(currentSource);
- }
- };
attr.attribTree(newTree, speculativeEnv, resultInfo);
unenterScanner.scan(newTree);
return newTree;
} catch (Abort ex) {
//if some very bad condition occurred during deferred attribution
//we should dump all errors before killing javac
- log.reportDeferredDiagnostics();
+ deferredDiagnosticHandler.reportDeferredDiagnostics();
throw ex;
} finally {
unenterScanner.scan(newTree);
- log.deferredDiagFilter = prevDeferDiagsFilter;
- log.deferredDiagnostics = prevDeferredDiags;
+ log.popDiagnosticHandler(deferredDiagnosticHandler);
}
}
//where
@@ -278,6 +261,10 @@
@Override
public void visitClassDef(JCClassDecl tree) {
ClassSymbol csym = tree.sym;
+ //if something went wrong during method applicability check
+ //it is possible that nested expressions inside argument expression
+ //are left unchecked - in such cases there's nothing to clean up.
+ if (csym == null) return;
enter.typeEnvs.remove(csym);
chk.compiled.remove(csym.flatname);
syms.classes.remove(csym.flatname);
@@ -336,7 +323,7 @@
*/
void complete() {
while (!deferredAttrNodes.isEmpty()) {
- Set<Type> stuckVars = new HashSet<Type>();
+ Set<Type> stuckVars = new LinkedHashSet<Type>();
boolean progress = false;
//scan a defensive copy of the node list - this is because a deferred
//attribution round can add new nodes to the list
@@ -410,7 +397,7 @@
/** an empty deferred attribution context - all methods throw exceptions */
final DeferredAttrContext emptyDeferredAttrContext =
- new DeferredAttrContext(null, null, null, null) {
+ new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, null) {
@Override
void addDeferredAttrNode(DeferredType dt, ResultInfo ri, List<Type> stuckVars) {
Assert.error("Empty deferred context!");
@@ -474,13 +461,13 @@
public class RecoveryDeferredTypeMap extends DeferredTypeMap {
public RecoveryDeferredTypeMap(AttrMode mode, Symbol msym, MethodResolutionPhase phase) {
- super(mode, msym, phase);
+ super(mode, msym, phase != null ? phase : MethodResolutionPhase.BOX);
}
@Override
protected Type typeOf(DeferredType dt) {
Type owntype = super.typeOf(dt);
- return owntype.hasTag(NONE) ?
+ return owntype == Type.noType ?
recover(dt) : owntype;
}
@@ -498,16 +485,7 @@
*/
private Type recover(DeferredType dt) {
dt.check(attr.new RecoveryInfo(deferredAttrContext));
- switch (TreeInfo.skipParens(dt.tree).getTag()) {
- case LAMBDA:
- case REFERENCE:
- case CONDEXPR:
- //propagate those deferred types to the
- //diagnostic formatter
- return dt;
- default:
- return super.apply(dt);
- }
+ return super.apply(dt);
}
}
@@ -516,11 +494,11 @@
* an AST node can be type-checked
*/
@SuppressWarnings("fallthrough")
- List<Type> stuckVars(JCTree tree, ResultInfo resultInfo) {
- if (resultInfo.pt.hasTag(NONE) || resultInfo.pt.isErroneous()) {
+ List<Type> stuckVars(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
+ if (resultInfo.pt.hasTag(NONE) || resultInfo.pt.isErroneous()) {
return List.nil();
} else {
- StuckChecker sc = new StuckChecker(resultInfo);
+ StuckChecker sc = new StuckChecker(resultInfo, env);
sc.scan(tree);
return List.from(sc.stuckVars);
}
@@ -537,7 +515,8 @@
Type pt;
Filter<JCTree> treeFilter;
Infer.InferenceContext inferenceContext;
- Set<Type> stuckVars = new HashSet<Type>();
+ Set<Type> stuckVars = new LinkedHashSet<Type>();
+ Env<AttrContext> env;
final Filter<JCTree> argsFilter = new Filter<JCTree>() {
public boolean accepts(JCTree t) {
@@ -566,10 +545,11 @@
}
};
- StuckChecker(ResultInfo resultInfo) {
+ StuckChecker(ResultInfo resultInfo, Env<AttrContext> env) {
this.pt = resultInfo.pt;
this.inferenceContext = resultInfo.checkContext.inferenceContext();
this.treeFilter = argsFilter;
+ this.env = env;
}
@Override
@@ -619,6 +599,7 @@
if (!types.isFunctionalInterface(pt.tsym)) {
return;
}
+
Type descType = types.findDescriptorType(pt);
List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes());
stuckVars.addAll(freeArgVars);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Env.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Env.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -122,6 +122,7 @@
return env1;
}
+ @Override
public String toString() {
return "Env[" + info + (outer == null ? "" : ",outer=" + outer) + "]";
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Fri Nov 30 17:09:05 2012 -0800
@@ -213,24 +213,21 @@
}
public void analyzeLambda(Env<AttrContext> env, JCLambda that, TreeMaker make, boolean speculative) {
- java.util.Queue<JCDiagnostic> prevDeferredDiagnostics = log.deferredDiagnostics;
- Filter<JCDiagnostic> prevDeferDiagsFilter = log.deferredDiagFilter;
+ Log.DiagnosticHandler diagHandler = null;
//we need to disable diagnostics temporarily; the problem is that if
//a lambda expression contains e.g. an unreachable statement, an error
//message will be reported and will cause compilation to skip the flow analyis
//step - if we suppress diagnostics, we won't stop at Attr for flow-analysis
//related errors, which will allow for more errors to be detected
if (!speculative) {
- log.deferAll();
- log.deferredDiagnostics = ListBuffer.lb();
+ diagHandler = new Log.DiscardDiagnosticHandler(log);
}
try {
new AliveAnalyzer().analyzeTree(env, that, make);
new FlowAnalyzer().analyzeTree(env, that, make);
} finally {
if (!speculative) {
- log.deferredDiagFilter = prevDeferDiagsFilter;
- log.deferredDiagnostics = prevDeferredDiagnostics;
+ log.popDiagnosticHandler(diagHandler);
}
}
}
@@ -275,9 +272,7 @@
Source source = Source.instance(context);
allowImprovedRethrowAnalysis = source.allowImprovedRethrowAnalysis();
allowImprovedCatchAnalysis = source.allowImprovedCatchAnalysis();
- Options options = Options.instance(context);
- allowEffectivelyFinalInInnerClasses = source.allowEffectivelyFinalInInnerClasses() &&
- options.isSet("allowEffectivelyFinalInInnerClasses"); //pre-lambda guard
+ allowEffectivelyFinalInInnerClasses = source.allowEffectivelyFinalInInnerClasses();
}
/**
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Nov 30 17:09:05 2012 -0800
@@ -501,10 +501,10 @@
}
for (Type t : funcInterfaceContext.undetvars) {
UndetVar uv = (UndetVar)t;
- minimizeInst(uv, Warner.noWarnings);
+ minimizeInst(uv, types.noWarnings);
if (uv.inst == null &&
Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter).nonEmpty()) {
- maximizeInst(uv, Warner.noWarnings);
+ maximizeInst(uv, types.noWarnings);
}
}
@@ -801,7 +801,7 @@
for (Type t : varsToSolve) {
UndetVar uv = (UndetVar)asFree(t, types);
if (uv.inst == null) {
- infer.minimizeInst(uv, Warner.noWarnings);
+ infer.minimizeInst(uv, types.noWarnings);
if (uv.inst != null) {
progress = true;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Fri Nov 30 17:09:05 2012 -0800
@@ -1120,10 +1120,10 @@
if (context != null
&& tree.encl == null
&& tree.def == null
- && tree.type.getEnclosingType().hasTag(NONE)) {
+ && !tree.type.getEnclosingType().hasTag(NONE)) {
Type encl = tree.type.getEnclosingType();
Type current = context.owner.enclClass().type;
- while (current.hasTag(NONE)) {
+ while (!current.hasTag(NONE)) {
if (current.tsym.isSubClass(encl.tsym, types)) {
return true;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Fri Nov 30 17:09:05 2012 -0800
@@ -502,7 +502,7 @@
JCNewClass tree = make.NewClass(null,
null, make.QualIdent(ctype.tsym), args, null);
tree.constructor = rs.resolveConstructor(
- make_pos, attrEnv, ctype, TreeInfo.types(args), null, false, false);
+ make_pos, attrEnv, ctype, TreeInfo.types(args), List.<Type>nil());
tree.type = ctype;
return tree;
}
@@ -682,7 +682,7 @@
/** Look up a method in a given scope.
*/
private MethodSymbol lookupMethod(DiagnosticPosition pos, Name name, Type qual, List<Type> args) {
- return rs.resolveInternalMethod(pos, attrEnv, qual, name, args, null);
+ return rs.resolveInternalMethod(pos, attrEnv, qual, name, args, List.<Type>nil());
}
/** Look up a constructor.
@@ -3631,15 +3631,26 @@
public void visitSelect(JCFieldAccess tree) {
// need to special case-access of the form C.super.x
- // these will always need an access method.
+ // these will always need an access method, unless C
+ // is a default interface subclassed by the current class.
boolean qualifiedSuperAccess =
tree.selected.hasTag(SELECT) &&
- TreeInfo.name(tree.selected) == names._super;
+ TreeInfo.name(tree.selected) == names._super &&
+ !types.isDirectSuperInterface(((JCFieldAccess)tree.selected).selected.type.tsym, currentClass);
tree.selected = translate(tree.selected);
- if (tree.name == names._class)
+ if (tree.name == names._class) {
result = classOf(tree.selected);
- else if (tree.name == names._this || tree.name == names._super)
+ }
+ else if (tree.name == names._super &&
+ types.isDirectSuperInterface(tree.selected.type.tsym, currentClass)) {
+ //default super call!! Not a classic qualified super call
+ TypeSymbol supSym = tree.selected.type.tsym;
+ Assert.checkNonNull(types.asSuper(currentClass.type, supSym));
+ result = tree;
+ }
+ else if (tree.name == names._this || tree.name == names._super) {
result = makeThis(tree.pos(), tree.selected.type.tsym);
+ }
else
result = access(tree.sym, tree, enclOp, qualifiedSuperAccess);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Nov 30 17:09:05 2012 -0800
@@ -560,6 +560,12 @@
MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner);
m.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, m, tree);
tree.sym = m;
+
+ //if this is a default method, add the DEFAULT flag to the enclosing interface
+ if ((tree.mods.flags & DEFAULT) != 0) {
+ m.enclClass().flags_field |= DEFAULT;
+ }
+
Env<AttrContext> localEnv = methodEnv(tree, env);
DeferredLintHandler prevLintHandler =
@@ -677,7 +683,7 @@
localEnv.info.scope.owner = tree.sym;
}
if ((tree.mods.flags & STATIC) != 0 ||
- (env.enclClass.sym.flags() & INTERFACE) != 0)
+ ((env.enclClass.sym.flags() & INTERFACE) != 0 && env.enclMethod == null))
localEnv.info.staticLevel++;
return localEnv;
}
@@ -1001,20 +1007,19 @@
}
}
- // If this is a class, enter symbols for this and super into
- // current scope.
- if ((c.flags_field & INTERFACE) == 0) {
- VarSymbol thisSym =
- new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
- thisSym.pos = Position.FIRSTPOS;
- env.info.scope.enter(thisSym);
- if (ct.supertype_field.hasTag(CLASS)) {
- VarSymbol superSym =
- new VarSymbol(FINAL | HASINIT, names._super,
- ct.supertype_field, c);
- superSym.pos = Position.FIRSTPOS;
- env.info.scope.enter(superSym);
- }
+ // enter symbols for 'this' into current scope.
+ VarSymbol thisSym =
+ new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
+ thisSym.pos = Position.FIRSTPOS;
+ env.info.scope.enter(thisSym);
+ // if this is a class, enter symbol for 'super' into current scope.
+ if ((c.flags_field & INTERFACE) == 0 &&
+ ct.supertype_field.hasTag(CLASS)) {
+ VarSymbol superSym =
+ new VarSymbol(FINAL | HASINIT, names._super,
+ ct.supertype_field, c);
+ superSym.pos = Position.FIRSTPOS;
+ env.info.scope.enter(superSym);
}
// check that no package exists with same fully qualified name,
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Nov 30 17:09:05 2012 -0800
@@ -51,7 +51,10 @@
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.Map;
+import java.util.Set;
import javax.lang.model.element.ElementVisitor;
@@ -88,6 +91,7 @@
public final boolean boxingEnabled; // = source.allowBoxing();
public final boolean varargsEnabled; // = source.allowVarargs();
public final boolean allowMethodHandles;
+ public final boolean allowDefaultMethods;
private final boolean debugResolve;
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
@@ -122,6 +126,7 @@
verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
Target target = Target.instance(context);
allowMethodHandles = target.hasMethodHandles();
+ allowDefaultMethods = source.allowDefaultMethods();
polymorphicSignatureScope = new Scope(syms.noSymbol);
inapplicableMethodException = new InapplicableMethodException(diags);
@@ -422,6 +427,60 @@
return c != null;
}
+ /**
+ * Performs a recursive scan of a type looking for accessibility problems
+ * from current attribution environment
+ */
+ void checkAccessibleType(Env<AttrContext> env, Type t) {
+ accessibilityChecker.visit(t, env);
+ }
+
+ /**
+ * Accessibility type-visitor
+ */
+ Types.SimpleVisitor<Void, Env<AttrContext>> accessibilityChecker =
+ new Types.SimpleVisitor<Void, Env<AttrContext>>() {
+
+ void visit(List<Type> ts, Env<AttrContext> env) {
+ for (Type t : ts) {
+ visit(t, env);
+ }
+ }
+
+ public Void visitType(Type t, Env<AttrContext> env) {
+ return null;
+ }
+
+ @Override
+ public Void visitArrayType(ArrayType t, Env<AttrContext> env) {
+ visit(t.elemtype, env);
+ return null;
+ }
+
+ @Override
+ public Void visitClassType(ClassType t, Env<AttrContext> env) {
+ visit(t.getTypeArguments(), env);
+ if (!isAccessible(env, t, true)) {
+ accessBase(new AccessError(t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true);
+ }
+ return null;
+ }
+
+ @Override
+ public Void visitWildcardType(WildcardType t, Env<AttrContext> env) {
+ visit(t.type, env);
+ return null;
+ }
+
+ @Override
+ public Void visitMethodType(MethodType t, Env<AttrContext> env) {
+ visit(t.getParameterTypes(), env);
+ visit(t.getReturnType(), env);
+ visit(t.getThrownTypes(), env);
+ return null;
+ }
+ };
+
/** Try to instantiate the type of a method so that it fits
* given type arguments and argument types. If succesful, return
* the method's instantiated type, else return null.
@@ -447,22 +506,9 @@
List<Type> typeargtypes,
boolean allowBoxing,
boolean useVarargs,
- Warner warn)
- throws Infer.InferenceException {
- if (useVarargs && (m.flags() & VARARGS) == 0) {
- //better error recovery - if we stumbled upon a non-varargs method
- //during varargs applicability phase, the method should be treated as
- //not applicable; the reason for inapplicability can be found in the
- //candidate for 'm' that was created during the BOX phase.
- Candidate prevCandidate = currentResolutionContext.getCandidate(m, BOX);
- JCDiagnostic details = null;
- if (prevCandidate != null && !prevCandidate.isApplicable()) {
- details = prevCandidate.details;
- }
- throw inapplicableMethodException.setMessage(details);
- }
+ Warner warn) throws Infer.InferenceException {
+
Type mt = types.memberType(site, m);
-
// tvars is the list of formal type variables for which type arguments
// need to inferred.
List<Type> tvars = List.nil();
@@ -758,10 +804,6 @@
public boolean compatible(Type found, Type req, Warner warn) {
return types.isSubtypeUnchecked(found, inferenceContext.asFree(req, types), warn);
}
-
- public boolean allowBoxing() {
- return false;
- }
}
/**
@@ -778,10 +820,6 @@
public boolean compatible(Type found, Type req, Warner warn) {
return types.isConvertible(found, inferenceContext.asFree(req, types), warn);
}
-
- public boolean allowBoxing() {
- return true;
- }
}
/**
@@ -800,7 +838,7 @@
DeferredAttr.DeferredAttrContext deferredAttrContext;
- public MethodResultInfo(Type pt, MethodCheckContext checkContext, DeferredAttr.DeferredAttrContext deferredAttrContext) {
+ public MethodResultInfo(Type pt, CheckContext checkContext, DeferredAttr.DeferredAttrContext deferredAttrContext) {
attr.super(VAL, pt, checkContext);
this.deferredAttrContext = deferredAttrContext;
}
@@ -817,7 +855,12 @@
@Override
protected MethodResultInfo dup(Type newPt) {
- return new MethodResultInfo(newPt, (MethodCheckContext)checkContext, deferredAttrContext);
+ return new MethodResultInfo(newPt, checkContext, deferredAttrContext);
+ }
+
+ @Override
+ protected ResultInfo dup(CheckContext newContext) {
+ return new MethodResultInfo(pt, newContext, deferredAttrContext);
}
}
@@ -1020,25 +1063,28 @@
boolean allowBoxing,
boolean useVarargs,
boolean operator) {
- if (sym.kind == ERR) return bestSoFar;
- if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
+ if (sym.kind == ERR ||
+ !sym.isInheritedIn(site.tsym, types) ||
+ (useVarargs && (sym.flags() & VARARGS) == 0)) {
+ return bestSoFar;
+ }
Assert.check(sym.kind < AMBIGUOUS);
try {
Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
- allowBoxing, useVarargs, Warner.noWarnings);
+ allowBoxing, useVarargs, types.noWarnings);
if (!operator)
currentResolutionContext.addApplicableCandidate(sym, mt);
} catch (InapplicableMethodException ex) {
if (!operator)
currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
switch (bestSoFar.kind) {
- case ABSENT_MTH:
- return new InapplicableSymbolError(currentResolutionContext);
- case WRONG_MTH:
- if (operator) return bestSoFar;
- bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
- default:
- return bestSoFar;
+ case ABSENT_MTH:
+ return new InapplicableSymbolError(currentResolutionContext);
+ case WRONG_MTH:
+ if (operator) return bestSoFar;
+ bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
+ default:
+ return bestSoFar;
}
}
if (!isAccessible(env, site, sym)) {
@@ -1327,6 +1373,42 @@
}
}
+ Symbol findMethodInScope(Env<AttrContext> env,
+ Type site,
+ Name name,
+ List<Type> argtypes,
+ List<Type> typeargtypes,
+ Scope sc,
+ Symbol bestSoFar,
+ boolean allowBoxing,
+ boolean useVarargs,
+ boolean operator,
+ boolean abstractok) {
+ for (Symbol s : sc.getElementsByName(name, new LookupFilter(abstractok))) {
+ bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
+ bestSoFar, allowBoxing, useVarargs, operator);
+ }
+ return bestSoFar;
+ }
+ //where
+ class LookupFilter implements Filter<Symbol> {
+
+ boolean abstractOk;
+
+ LookupFilter(boolean abstractOk) {
+ this.abstractOk = abstractOk;
+ }
+
+ public boolean accepts(Symbol s) {
+ long flags = s.flags();
+ return s.kind == MTH &&
+ (flags & SYNTHETIC) == 0 &&
+ (abstractOk ||
+ (flags & DEFAULT) != 0 ||
+ (flags & ABSTRACT) == 0);
+ }
+ };
+
/** Find best qualified method matching given name, type and value
* arguments.
* @param env The current environment.
@@ -1371,49 +1453,76 @@
boolean allowBoxing,
boolean useVarargs,
boolean operator) {
- boolean abstractOk = true;
- List<Type> itypes = List.nil();
+ @SuppressWarnings({"unchecked","rawtypes"})
+ List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() };
+ InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK;
for (TypeSymbol s : superclasses(intype)) {
- bestSoFar = lookupMethod(env, site, name, argtypes, typeargtypes,
+ bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
s.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
- //We should not look for abstract methods if receiver is a concrete class
- //(as concrete classes are expected to implement all abstracts coming
- //from superinterfaces)
- abstractOk &= (s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0;
- if (abstractOk) {
+ if (name == names.init) return bestSoFar;
+ iphase = (iphase == null) ? null : iphase.update(s, this);
+ if (iphase != null) {
for (Type itype : types.interfaces(s.type)) {
- itypes = types.union(types.closure(itype), itypes);
+ itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]);
}
}
- if (name == names.init) break;
}
Symbol concrete = bestSoFar.kind < ERR &&
(bestSoFar.flags() & ABSTRACT) == 0 ?
bestSoFar : methodNotFound;
- if (name != names.init) {
+ for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) {
+ if (iphase2 == InterfaceLookupPhase.DEFAULT_OK && !allowDefaultMethods) break;
//keep searching for abstract methods
- for (Type itype : itypes) {
+ for (Type itype : itypes[iphase2.ordinal()]) {
if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure())
- bestSoFar = lookupMethod(env, site, name, argtypes, typeargtypes,
- itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
- if (concrete != bestSoFar &&
- concrete.kind < ERR && bestSoFar.kind < ERR &&
- types.isSubSignature(concrete.type, bestSoFar.type)) {
- //this is an hack - as javac does not do full membership checks
- //most specific ends up comparing abstract methods that might have
- //been implemented by some concrete method in a subclass and,
- //because of raw override, it is possible for an abstract method
- //to be more specific than the concrete method - so we need
- //to explicitly call that out (see CR 6178365)
- bestSoFar = concrete;
- }
+ if (iphase2 == InterfaceLookupPhase.DEFAULT_OK &&
+ (itype.tsym.flags() & DEFAULT) == 0) continue;
+ bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
+ itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
+ if (concrete != bestSoFar &&
+ concrete.kind < ERR && bestSoFar.kind < ERR &&
+ types.isSubSignature(concrete.type, bestSoFar.type)) {
+ //this is an hack - as javac does not do full membership checks
+ //most specific ends up comparing abstract methods that might have
+ //been implemented by some concrete method in a subclass and,
+ //because of raw override, it is possible for an abstract method
+ //to be more specific than the concrete method - so we need
+ //to explicitly call that out (see CR 6178365)
+ bestSoFar = concrete;
+ }
}
}
return bestSoFar;
}
+ enum InterfaceLookupPhase {
+ ABSTRACT_OK() {
+ @Override
+ InterfaceLookupPhase update(Symbol s, Resolve rs) {
+ //We should not look for abstract methods if receiver is a concrete class
+ //(as concrete classes are expected to implement all abstracts coming
+ //from superinterfaces)
+ if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) {
+ return this;
+ } else if (rs.allowDefaultMethods) {
+ return DEFAULT_OK;
+ } else {
+ return null;
+ }
+ }
+ },
+ DEFAULT_OK() {
+ @Override
+ InterfaceLookupPhase update(Symbol s, Resolve rs) {
+ return this;
+ }
+ };
+
+ abstract InterfaceLookupPhase update(Symbol s, Resolve rs);
+ }
+
/**
* Return an Iterable object to scan the superclasses of a given type.
* It's crucial that the scan is done lazily, as we don't want to accidentally
@@ -1467,34 +1576,6 @@
};
}
- /**
- * Lookup a method with given name and argument types in a given scope
- */
- Symbol lookupMethod(Env<AttrContext> env,
- Type site,
- Name name,
- List<Type> argtypes,
- List<Type> typeargtypes,
- Scope sc,
- Symbol bestSoFar,
- boolean allowBoxing,
- boolean useVarargs,
- boolean operator,
- boolean abstractok) {
- for (Symbol s : sc.getElementsByName(name, lookupFilter)) {
- bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
- bestSoFar, allowBoxing, useVarargs, operator);
- }
- return bestSoFar;
- }
- //where
- Filter<Symbol> lookupFilter = new Filter<Symbol>() {
- public boolean accepts(Symbol s) {
- return s.kind == MTH &&
- (s.flags() & SYNTHETIC) == 0;
- }
- };
-
/** Find unqualified method matching given name, type and value arguments.
* @param env The current environment.
* @param name The method's name.
@@ -1701,7 +1782,7 @@
/** Find an unqualified identifier which matches a specified kind set.
* @param env The current environment.
- * @param name The indentifier's name.
+ * @param name The identifier's name.
* @param kind Indicates the possible symbol kinds
* (a subset of VAL, TYP, PCK).
*/
@@ -1891,28 +1972,31 @@
(typeargtypes == null || !Type.isErroneous(typeargtypes));
}
public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
- if (syms.operatorNames.contains(name)) {
- return argtypes;
- } else {
- Symbol msym = errSym.kind == WRONG_MTH ?
- ((InapplicableSymbolError)errSym).errCandidate().sym : accessedSym;
-
- List<Type> argtypes2 = Type.map(argtypes,
- deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, msym, currentResolutionContext.firstErroneousResolutionPhase()));
-
- if (msym != accessedSym) {
- //fixup deferred type caches - this 'hack' is required because the symbol
- //returned by InapplicableSymbolError.access() will hide the candidate
- //method symbol that can be used for lookups in the speculative cache,
- //causing problems in Attr.checkId()
- for (Type t : argtypes) {
- if (t.hasTag(DEFERRED)) {
- DeferredType dt = (DeferredType)t;
- dt.speculativeCache.dupAllTo(msym, accessedSym);
- }
+ return (syms.operatorNames.contains(name)) ?
+ argtypes :
+ Type.map(argtypes, new ResolveDeferredRecoveryMap(accessedSym));
+ }
+
+ class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
+
+ public ResolveDeferredRecoveryMap(Symbol msym) {
+ deferredAttr.super(AttrMode.SPECULATIVE, msym, currentResolutionContext.step);
+ }
+
+ @Override
+ protected Type typeOf(DeferredType dt) {
+ Type res = super.typeOf(dt);
+ if (!res.isErroneous()) {
+ switch (TreeInfo.skipParens(dt.tree).getTag()) {
+ case LAMBDA:
+ case REFERENCE:
+ return dt;
+ case CONDEXPR:
+ return res == Type.recoveryType ?
+ dt : res;
}
}
- return argtypes2;
+ return res;
}
}
};
@@ -1920,7 +2004,7 @@
/** Check that sym is not an abstract method.
*/
void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
- if ((sym.flags() & ABSTRACT) != 0)
+ if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0)
log.error(pos, "abstract.cant.be.accessed.directly",
kindName(sym), sym, sym.location());
}
@@ -1992,33 +2076,14 @@
Name name,
List<Type> argtypes,
List<Type> typeargtypes) {
- MethodResolutionContext prevResolutionContext = currentResolutionContext;
- try {
- currentResolutionContext = new MethodResolutionContext();
- Symbol sym = methodNotFound;
- List<MethodResolutionPhase> steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
- sym = findFun(env, name, argtypes, typeargtypes,
- steps.head.isBoxingRequired,
- steps.head.isVarargsRequired);
- currentResolutionContext.resolutionCache.put(steps.head, sym);
- steps = steps.tail;
+ return lookupMethod(env, pos, env.enclClass.sym, new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) {
+ @Override
+ Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
+ return findFun(env, name, argtypes, typeargtypes,
+ phase.isBoxingRequired(),
+ phase.isVarargsRequired());
}
- if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
- MethodResolutionPhase errPhase =
- currentResolutionContext.firstErroneousResolutionPhase();
- sym = accessMethod(currentResolutionContext.resolutionCache.get(errPhase),
- pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
- env.info.pendingResolutionPhase = errPhase;
- }
- return sym;
- }
- finally {
- currentResolutionContext = prevResolutionContext;
- }
+ });
}
/** Resolve a qualified method identifier
@@ -2044,40 +2109,26 @@
DiagnosticPosition pos, Env<AttrContext> env,
Symbol location, Type site, Name name, List<Type> argtypes,
List<Type> typeargtypes) {
- MethodResolutionContext prevResolutionContext = currentResolutionContext;
- try {
- currentResolutionContext = resolveContext;
- Symbol sym = methodNotFound;
- List<MethodResolutionPhase> steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
- sym = findMethod(env, site, name, argtypes, typeargtypes,
- steps.head.isBoxingRequired(),
- steps.head.isVarargsRequired(), false);
- currentResolutionContext.resolutionCache.put(steps.head, sym);
- steps = steps.tail;
+ return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) {
+ @Override
+ Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
+ return findMethod(env, site, name, argtypes, typeargtypes,
+ phase.isBoxingRequired(),
+ phase.isVarargsRequired(), false);
}
- if (sym.kind >= AMBIGUOUS) {
- //if nothing is found return the 'first' error
- MethodResolutionPhase errPhase =
- currentResolutionContext.firstErroneousResolutionPhase();
- sym = accessMethod(currentResolutionContext.resolutionCache.get(errPhase),
- pos, location, site, name, true, argtypes, typeargtypes);
- env.info.pendingResolutionPhase = errPhase;
- } else if (allowMethodHandles) {
- MethodSymbol msym = (MethodSymbol)sym;
- if (msym.isSignaturePolymorphic(types)) {
- env.info.pendingResolutionPhase = BASIC;
- return findPolymorphicSignatureInstance(env, sym, argtypes);
+ @Override
+ Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
+ if (sym.kind >= AMBIGUOUS) {
+ sym = super.access(env, pos, location, sym);
+ } else if (allowMethodHandles) {
+ MethodSymbol msym = (MethodSymbol)sym;
+ if (msym.isSignaturePolymorphic(types)) {
+ return findPolymorphicSignatureInstance(env, sym, argtypes);
+ }
}
+ return sym;
}
- return sym;
- }
- finally {
- currentResolutionContext = prevResolutionContext;
- }
+ });
}
/** Find or create an implicit method of exactly the given type (after erasure).
@@ -2088,7 +2139,7 @@
* @param argtypes The required argument types
*/
Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
- Symbol spMethod,
+ final Symbol spMethod,
List<Type> argtypes) {
Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
(MethodSymbol)spMethod, currentResolutionContext, argtypes);
@@ -2100,7 +2151,12 @@
// create the desired method
long flags = ABSTRACT | HYPOTHETICAL | spMethod.flags() & Flags.AccessFlags;
- Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner);
+ Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) {
+ @Override
+ public Symbol baseSymbol() {
+ return spMethod;
+ }
+ };
polymorphicSignatureScope.enter(msym);
return msym;
}
@@ -2145,38 +2201,53 @@
List<Type> typeargtypes) {
return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
}
+
private Symbol resolveConstructor(MethodResolutionContext resolveContext,
- DiagnosticPosition pos,
+ final DiagnosticPosition pos,
Env<AttrContext> env,
Type site,
List<Type> argtypes,
List<Type> typeargtypes) {
- MethodResolutionContext prevResolutionContext = currentResolutionContext;
- try {
- currentResolutionContext = resolveContext;
- Symbol sym = methodNotFound;
- List<MethodResolutionPhase> steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
- sym = findConstructor(pos, env, site, argtypes, typeargtypes,
- steps.head.isBoxingRequired(),
- steps.head.isVarargsRequired());
- currentResolutionContext.resolutionCache.put(steps.head, sym);
- steps = steps.tail;
+ return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
+ @Override
+ Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
+ return findConstructor(pos, env, site, argtypes, typeargtypes,
+ phase.isBoxingRequired(),
+ phase.isVarargsRequired());
}
- if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
- MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
- sym = accessMethod(currentResolutionContext.resolutionCache.get(errPhase),
- pos, site, names.init, true, argtypes, typeargtypes);
- env.info.pendingResolutionPhase = errPhase;
- }
- return sym;
- }
- finally {
- currentResolutionContext = prevResolutionContext;
- }
+ });
+ }
+
+ /** Resolve a constructor, throw a fatal error if not found.
+ * @param pos The position to use for error reporting.
+ * @param env The environment current at the method invocation.
+ * @param site The type to be constructed.
+ * @param argtypes The types of the invocation's value arguments.
+ * @param typeargtypes The types of the invocation's type arguments.
+ */
+ public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
+ Type site,
+ List<Type> argtypes,
+ List<Type> typeargtypes) {
+ MethodResolutionContext resolveContext = new MethodResolutionContext();
+ resolveContext.internalResolution = true;
+ Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
+ if (sym.kind == MTH) return (MethodSymbol)sym;
+ else throw new FatalError(
+ diags.fragment("fatal.err.cant.locate.ctor", site));
+ }
+
+ Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
+ Type site, List<Type> argtypes,
+ List<Type> typeargtypes,
+ boolean allowBoxing,
+ boolean useVarargs) {
+ Symbol sym = findMethod(env, site,
+ names.init, argtypes,
+ typeargtypes, allowBoxing,
+ useVarargs, false);
+ chk.checkDeprecated(pos, env.info.scope.owner, sym);
+ return sym;
}
/** Resolve constructor using diamond inference.
@@ -2194,47 +2265,36 @@
Type site,
List<Type> argtypes,
List<Type> typeargtypes) {
- MethodResolutionContext prevResolutionContext = currentResolutionContext;
- try {
- currentResolutionContext = new MethodResolutionContext();
- Symbol sym = methodNotFound;
- List<MethodResolutionPhase> steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
- sym = findDiamond(env, site, argtypes, typeargtypes,
- steps.head.isBoxingRequired(),
- steps.head.isVarargsRequired());
- currentResolutionContext.resolutionCache.put(steps.head, sym);
- steps = steps.tail;
+ return lookupMethod(env, pos, site.tsym, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
+ @Override
+ Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
+ return findDiamond(env, site, argtypes, typeargtypes,
+ phase.isBoxingRequired(),
+ phase.isVarargsRequired());
}
- if (sym.kind >= AMBIGUOUS) {
- Symbol errSym =
- currentResolutionContext.resolutionCache.get(currentResolutionContext.firstErroneousResolutionPhase());
- final JCDiagnostic details = errSym.kind == WRONG_MTH ?
- ((InapplicableSymbolError)errSym).errCandidate().details :
- null;
- errSym = new InapplicableSymbolError(errSym.kind, "diamondError", currentResolutionContext) {
- @Override
- JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
- Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
- String key = details == null ?
- "cant.apply.diamond" :
- "cant.apply.diamond.1";
- return diags.create(dkind, log.currentSource(), pos, key,
- diags.fragment("diamond", site.tsym), details);
- }
- };
- MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
- sym = accessMethod(errSym, pos, site, names.init, true, argtypes, typeargtypes);
- env.info.pendingResolutionPhase = errPhase;
+ @Override
+ Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
+ if (sym.kind >= AMBIGUOUS) {
+ final JCDiagnostic details = sym.kind == WRONG_MTH ?
+ ((InapplicableSymbolError)sym).errCandidate().details :
+ null;
+ sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
+ @Override
+ JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
+ Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
+ String key = details == null ?
+ "cant.apply.diamond" :
+ "cant.apply.diamond.1";
+ return diags.create(dkind, log.currentSource(), pos, key,
+ diags.fragment("diamond", site.tsym), details);
+ }
+ };
+ sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
+ env.info.pendingResolutionPhase = currentResolutionContext.step;
+ }
+ return sym;
}
- return sym;
- }
- finally {
- currentResolutionContext = prevResolutionContext;
- }
+ });
}
/** This method scans all the constructor symbol in a given class scope -
@@ -2281,392 +2341,7 @@
return bestSoFar;
}
- /**
- * Resolution of member references is typically done as a single
- * overload resolution step, where the argument types A are inferred from
- * the target functional descriptor.
- *
- * If the member reference is a method reference with a type qualifier,
- * a two-step lookup process is performed. The first step uses the
- * expected argument list A, while the second step discards the first
- * type from A (which is treated as a receiver type).
- *
- * There are two cases in which inference is performed: (i) if the member
- * reference is a constructor reference and the qualifier type is raw - in
- * which case diamond inference is used to infer a parameterization for the
- * type qualifier; (ii) if the member reference is an unbound reference
- * where the type qualifier is raw - in that case, during the unbound lookup
- * the receiver argument type is used to infer an instantiation for the raw
- * qualifier type.
- *
- * When a multi-step resolution process is exploited, it is an error
- * if two candidates are found (ambiguity).
- *
- * This routine returns a pair (T,S), where S is the member reference symbol,
- * and T is the type of the class in which S is defined. This is necessary as
- * the type T might be dynamically inferred (i.e. if constructor reference
- * has a raw qualifier).
- */
- Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(DiagnosticPosition pos,
- Env<AttrContext> env,
- JCMemberReference referenceTree,
- Type site,
- Name name, List<Type> argtypes,
- List<Type> typeargtypes,
- boolean boxingAllowed) {
- //step 1 - bound lookup
- ReferenceLookupHelper boundLookupHelper = name.equals(names.init) ?
- new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, boxingAllowed) :
- new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, boxingAllowed);
- Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
- Symbol boundSym = findMemberReference(boundEnv, boundLookupHelper);
-
- //step 2 - unbound lookup
- ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup();
- Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
- Symbol unboundSym = findMemberReference(unboundEnv, unboundLookupHelper);
-
- //merge results
- Pair<Symbol, ReferenceLookupHelper> res;
- if (unboundSym.kind != MTH) {
- res = new Pair<Symbol, ReferenceLookupHelper>(boundSym, boundLookupHelper);
- env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
- } else if (boundSym.kind == MTH) {
- res = new Pair<Symbol, ReferenceLookupHelper>(ambiguityError(boundSym, unboundSym), boundLookupHelper);
- env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
- } else {
- res = new Pair<Symbol, ReferenceLookupHelper>(unboundSym, unboundLookupHelper);
- env.info.pendingResolutionPhase = unboundEnv.info.pendingResolutionPhase;
- }
-
- return res;
- }
-
- /**
- * Helper for defining custom method-like lookup logic; a lookup helper
- * provides hooks for (i) the actual lookup logic and (ii) accessing the
- * lookup result (this step might result in compiler diagnostics to be generated)
- */
- abstract class LookupHelper {
-
- /** name of the symbol to lookup */
- Name name;
-
- /** location in which the lookup takes place */
- Type site;
-
- /** actual types used during the lookup */
- List<Type> argtypes;
-
- /** type arguments used during the lookup */
- List<Type> typeargtypes;
-
- LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
- this.name = name;
- this.site = site;
- this.argtypes = argtypes;
- this.typeargtypes = typeargtypes;
- }
-
- /**
- * Search for a symbol under a given overload resolution phase - this method
- * is usually called several times, once per each overload resolution phase
- */
- abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase);
-
- /**
- * Validate the result of the lookup
- */
- abstract Symbol access(Env<AttrContext> env, Symbol symbol);
- }
-
- /**
- * Helper class for member reference lookup. A reference lookup helper
- * defines the basic logic for member reference lookup; a method gives
- * access to an 'unbound' helper used to perform an unbound member
- * reference lookup.
- */
- abstract class ReferenceLookupHelper extends LookupHelper {
-
- /** The member reference tree */
- JCMemberReference referenceTree;
-
- /** Max overload resolution phase handled by this helper */
- MethodResolutionPhase maxPhase;
-
- ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
- List<Type> argtypes, List<Type> typeargtypes, boolean boxingAllowed) {
- super(name, site, argtypes, typeargtypes);
- this.referenceTree = referenceTree;
- this.maxPhase = boxingAllowed ? VARARITY : BASIC;
- }
-
- /**
- * Returns an unbound version of this lookup helper. By default, this
- * method returns an dummy lookup helper.
- */
- ReferenceLookupHelper unboundLookup() {
- //dummy loopkup helper that always return 'methodNotFound'
- return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase.isBoxingRequired()) {
- @Override
- ReferenceLookupHelper unboundLookup() {
- return this;
- }
- @Override
- Symbol lookupReference(Env<AttrContext> env, MethodResolutionPhase phase) {
- return methodNotFound;
- }
- @Override
- ReferenceKind referenceKind(Symbol sym) {
- Assert.error();
- return null;
- }
- };
- }
-
- /**
- * Get the kind of the member reference
- */
- abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
-
- @Override
- Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
- return (env.info.pendingResolutionPhase.ordinal() > maxPhase.ordinal()) ?
- methodNotFound : lookupReference(env, phase);
- }
-
- abstract Symbol lookupReference(Env<AttrContext> env, MethodResolutionPhase phase);
-
- Symbol access(Env<AttrContext> env, Symbol sym) {
- if (sym.kind >= AMBIGUOUS) {
- MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
- if (errPhase.ordinal() > maxPhase.ordinal()) {
- errPhase = maxPhase;
- }
- env.info.pendingResolutionPhase = errPhase;
- sym = currentResolutionContext.resolutionCache.get(errPhase);
- }
- return sym;
- }
- }
-
- /**
- * Helper class for method reference lookup. The lookup logic is based
- * upon Resolve.findMethod; in certain cases, this helper class has a
- * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
- * In such cases, non-static lookup results are thrown away.
- */
- class MethodReferenceLookupHelper extends ReferenceLookupHelper {
-
- MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
- List<Type> argtypes, List<Type> typeargtypes, boolean boxingAllowed) {
- super(referenceTree, name, site, argtypes, typeargtypes, boxingAllowed);
- }
-
- protected Symbol lookupReferenceInternal(Env<AttrContext> env, MethodResolutionPhase phase) {
- return findMethod(env, site, name, argtypes, typeargtypes,
- phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
- }
-
- protected Symbol adjustLookupResult(Env<AttrContext> env, Symbol sym) {
- return !TreeInfo.isStaticSelector(referenceTree.expr, names) ||
- sym.kind != MTH ||
- sym.isStatic() ? sym : new StaticError(sym);
- }
-
- @Override
- final Symbol lookupReference(Env<AttrContext> env, MethodResolutionPhase phase) {
- return adjustLookupResult(env, lookupReferenceInternal(env, phase));
- }
-
- @Override
- ReferenceLookupHelper unboundLookup() {
- if (TreeInfo.isStaticSelector(referenceTree.expr, names) &&
- argtypes.nonEmpty() &&
- types.isSubtypeUnchecked(argtypes.head, site)) {
- return new UnboundMethodReferenceLookupHelper(referenceTree, name,
- site, argtypes, typeargtypes, maxPhase.isBoxingRequired());
- } else {
- return super.unboundLookup();
- }
- }
-
- @Override
- ReferenceKind referenceKind(Symbol sym) {
- if (sym.isStatic()) {
- return TreeInfo.isStaticSelector(referenceTree.expr, names) ?
- ReferenceKind.STATIC : ReferenceKind.STATIC_EVAL;
- } else {
- Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
- return selName != null && selName == names._super ?
- ReferenceKind.SUPER :
- ReferenceKind.BOUND;
- }
- }
- }
-
- /**
- * Helper class for unbound method reference lookup. Essentially the same
- * as the basic method reference lookup helper; main difference is that static
- * lookup results are thrown away. If qualifier type is raw, an attempt to
- * infer a parameterized type is made using the first actual argument (that
- * would otherwise be ignored during the lookup).
- */
- class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
-
- UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
- List<Type> argtypes, List<Type> typeargtypes, boolean boxingAllowed) {
- super(referenceTree, name,
- site.isRaw() ? types.asSuper(argtypes.head, site.tsym) : site,
- argtypes.tail, typeargtypes, boxingAllowed);
- }
-
- @Override
- protected Symbol adjustLookupResult(Env<AttrContext> env, Symbol sym) {
- return sym.kind != MTH || !sym.isStatic() ? sym : new StaticError(sym);
- }
-
- @Override
- ReferenceLookupHelper unboundLookup() {
- return this;
- }
-
- @Override
- ReferenceKind referenceKind(Symbol sym) {
- return ReferenceKind.UNBOUND;
- }
- }
-
- /**
- * Helper class for constructor reference lookup. The lookup logic is based
- * upon either Resolve.findMethod or Resolve.findDiamond - depending on
- * whether the constructor reference needs diamond inference (this is the case
- * if the qualifier type is raw). A special erroneous symbol is returned
- * if the lookup returns the constructor of an inner class and there's no
- * enclosing instance in scope.
- */
- class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
-
- boolean needsInference;
-
- ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
- List<Type> typeargtypes, boolean boxingAllowed) {
- super(referenceTree, names.init, site, argtypes, typeargtypes, boxingAllowed);
- if (site.isRaw()) {
- this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym);
- needsInference = true;
- }
- }
-
- @Override
- protected Symbol lookupReference(Env<AttrContext> env, MethodResolutionPhase phase) {
- Symbol sym = needsInference ?
- findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
- findMethod(env, site, name, argtypes, typeargtypes,
- phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
- return sym.kind != MTH ||
- site.getEnclosingType().hasTag(NONE) ||
- hasEnclosingInstance(env, site) ?
- sym : new InvalidSymbolError(Kinds.MISSING_ENCL, sym, null) {
- @Override
- JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
- return diags.create(dkind, log.currentSource(), pos,
- "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
- }
- };
- }
-
- @Override
- ReferenceKind referenceKind(Symbol sym) {
- return site.getEnclosingType().hasTag(NONE) ?
- ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
- }
- }
-
- /**
- * Resolution step for member reference. This generalizes a standard
- * method/constructor lookup - on each overload resolution step, a
- * lookup helper class is used to perform the reference lookup; at the end
- * of the lookup, the helper is used to validate the results.
- */
- Symbol findMemberReference(Env<AttrContext> env, LookupHelper lookupHelper) {
- MethodResolutionContext prevResolutionContext = currentResolutionContext;
- try {
- currentResolutionContext = new MethodResolutionContext();
- Symbol sym = methodNotFound;
- List<MethodResolutionPhase> steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
- sym = lookupHelper.lookup(env, steps.head);
- currentResolutionContext.resolutionCache.put(steps.head, sym);
- steps = steps.tail;
- }
- return lookupHelper.access(env, sym);
- }
- finally {
- currentResolutionContext = prevResolutionContext;
- }
- }
-
- /** Resolve constructor.
- * @param pos The position to use for error reporting.
- * @param env The environment current at the constructor invocation.
- * @param site The type of class for which a constructor is searched.
- * @param argtypes The types of the constructor invocation's value
- * arguments.
- * @param typeargtypes The types of the constructor invocation's type
- * arguments.
- * @param allowBoxing Allow boxing and varargs conversions.
- * @param useVarargs Box trailing arguments into an array for varargs.
- */
- Symbol resolveConstructor(DiagnosticPosition pos, Env<AttrContext> env,
- Type site, List<Type> argtypes,
- List<Type> typeargtypes,
- boolean allowBoxing,
- boolean useVarargs) {
- MethodResolutionContext prevResolutionContext = currentResolutionContext;
- try {
- currentResolutionContext = new MethodResolutionContext();
- return findConstructor(pos, env, site, argtypes, typeargtypes, allowBoxing, useVarargs);
- }
- finally {
- currentResolutionContext = prevResolutionContext;
- }
- }
-
- Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
- Type site, List<Type> argtypes,
- List<Type> typeargtypes,
- boolean allowBoxing,
- boolean useVarargs) {
- Symbol sym = findMethod(env, site,
- names.init, argtypes,
- typeargtypes, allowBoxing,
- useVarargs, false);
- chk.checkDeprecated(pos, env.info.scope.owner, sym);
- return sym;
- }
-
- /** Resolve a constructor, throw a fatal error if not found.
- * @param pos The position to use for error reporting.
- * @param env The environment current at the method invocation.
- * @param site The type to be constructed.
- * @param argtypes The types of the invocation's value arguments.
- * @param typeargtypes The types of the invocation's type arguments.
- */
- public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
- Type site,
- List<Type> argtypes,
- List<Type> typeargtypes) {
- MethodResolutionContext resolveContext = new MethodResolutionContext();
- resolveContext.internalResolution = true;
- Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
- if (sym.kind == MTH) return (MethodSymbol)sym;
- else throw new FatalError(
- diags.fragment("fatal.err.cant.locate.ctor", site));
- }
+
/** Resolve operator.
* @param pos The position to use for error reporting.
@@ -2719,6 +2394,350 @@
}
/**
+ * Resolution of member references is typically done as a single
+ * overload resolution step, where the argument types A are inferred from
+ * the target functional descriptor.
+ *
+ * If the member reference is a method reference with a type qualifier,
+ * a two-step lookup process is performed. The first step uses the
+ * expected argument list A, while the second step discards the first
+ * type from A (which is treated as a receiver type).
+ *
+ * There are two cases in which inference is performed: (i) if the member
+ * reference is a constructor reference and the qualifier type is raw - in
+ * which case diamond inference is used to infer a parameterization for the
+ * type qualifier; (ii) if the member reference is an unbound reference
+ * where the type qualifier is raw - in that case, during the unbound lookup
+ * the receiver argument type is used to infer an instantiation for the raw
+ * qualifier type.
+ *
+ * When a multi-step resolution process is exploited, it is an error
+ * if two candidates are found (ambiguity).
+ *
+ * This routine returns a pair (T,S), where S is the member reference symbol,
+ * and T is the type of the class in which S is defined. This is necessary as
+ * the type T might be dynamically inferred (i.e. if constructor reference
+ * has a raw qualifier).
+ */
+ Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(DiagnosticPosition pos,
+ Env<AttrContext> env,
+ JCMemberReference referenceTree,
+ Type site,
+ Name name, List<Type> argtypes,
+ List<Type> typeargtypes,
+ boolean boxingAllowed) {
+ MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC;
+ //step 1 - bound lookup
+ ReferenceLookupHelper boundLookupHelper = name.equals(names.init) ?
+ new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase) :
+ new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
+ Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
+ Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, boundLookupHelper);
+
+ //step 2 - unbound lookup
+ ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup();
+ Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
+ Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, unboundLookupHelper);
+
+ //merge results
+ Pair<Symbol, ReferenceLookupHelper> res;
+ if (unboundSym.kind != MTH) {
+ res = new Pair<Symbol, ReferenceLookupHelper>(boundSym, boundLookupHelper);
+ env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
+ } else if (boundSym.kind == MTH) {
+ res = new Pair<Symbol, ReferenceLookupHelper>(ambiguityError(boundSym, unboundSym), boundLookupHelper);
+ env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
+ } else {
+ res = new Pair<Symbol, ReferenceLookupHelper>(unboundSym, unboundLookupHelper);
+ env.info.pendingResolutionPhase = unboundEnv.info.pendingResolutionPhase;
+ }
+
+ return res;
+ }
+
+ /**
+ * Helper for defining custom method-like lookup logic; a lookup helper
+ * provides hooks for (i) the actual lookup logic and (ii) accessing the
+ * lookup result (this step might result in compiler diagnostics to be generated)
+ */
+ abstract class LookupHelper {
+
+ /** name of the symbol to lookup */
+ Name name;
+
+ /** location in which the lookup takes place */
+ Type site;
+
+ /** actual types used during the lookup */
+ List<Type> argtypes;
+
+ /** type arguments used during the lookup */
+ List<Type> typeargtypes;
+
+ /** Max overload resolution phase handled by this helper */
+ MethodResolutionPhase maxPhase;
+
+ LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
+ this.name = name;
+ this.site = site;
+ this.argtypes = argtypes;
+ this.typeargtypes = typeargtypes;
+ this.maxPhase = maxPhase;
+ }
+
+ /**
+ * Should lookup stop at given phase with given result
+ */
+ protected boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
+ return phase.ordinal() > maxPhase.ordinal() ||
+ sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS;
+ }
+
+ /**
+ * Search for a symbol under a given overload resolution phase - this method
+ * is usually called several times, once per each overload resolution phase
+ */
+ abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase);
+
+ /**
+ * Validate the result of the lookup
+ */
+ abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym);
+ }
+
+ abstract class BasicLookupHelper extends LookupHelper {
+
+ BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
+ super(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
+ }
+
+ @Override
+ Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
+ if (sym.kind >= AMBIGUOUS) {
+ //if nothing is found return the 'first' error
+ sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes);
+ }
+ return sym;
+ }
+ }
+
+ /**
+ * Helper class for member reference lookup. A reference lookup helper
+ * defines the basic logic for member reference lookup; a method gives
+ * access to an 'unbound' helper used to perform an unbound member
+ * reference lookup.
+ */
+ abstract class ReferenceLookupHelper extends LookupHelper {
+
+ /** The member reference tree */
+ JCMemberReference referenceTree;
+
+ ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
+ List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
+ super(name, site, argtypes, typeargtypes, maxPhase);
+ this.referenceTree = referenceTree;
+
+ }
+
+ /**
+ * Returns an unbound version of this lookup helper. By default, this
+ * method returns an dummy lookup helper.
+ */
+ ReferenceLookupHelper unboundLookup() {
+ //dummy loopkup helper that always return 'methodNotFound'
+ return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
+ @Override
+ ReferenceLookupHelper unboundLookup() {
+ return this;
+ }
+ @Override
+ Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
+ return methodNotFound;
+ }
+ @Override
+ ReferenceKind referenceKind(Symbol sym) {
+ Assert.error();
+ return null;
+ }
+ };
+ }
+
+ /**
+ * Get the kind of the member reference
+ */
+ abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
+
+ Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
+ //skip error reporting
+ return sym;
+ }
+ }
+
+ /**
+ * Helper class for method reference lookup. The lookup logic is based
+ * upon Resolve.findMethod; in certain cases, this helper class has a
+ * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
+ * In such cases, non-static lookup results are thrown away.
+ */
+ class MethodReferenceLookupHelper extends ReferenceLookupHelper {
+
+ MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
+ List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
+ super(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
+ }
+
+ protected Symbol lookupReferenceInternal(Env<AttrContext> env, MethodResolutionPhase phase) {
+ return findMethod(env, site, name, argtypes, typeargtypes,
+ phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
+ }
+
+ protected Symbol adjustLookupResult(Env<AttrContext> env, Symbol sym) {
+ return !TreeInfo.isStaticSelector(referenceTree.expr, names) ||
+ sym.kind != MTH ||
+ sym.isStatic() ? sym : new StaticError(sym);
+ }
+
+ @Override
+ final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
+ return adjustLookupResult(env, lookupReferenceInternal(env, phase));
+ }
+
+ @Override
+ ReferenceLookupHelper unboundLookup() {
+ if (TreeInfo.isStaticSelector(referenceTree.expr, names) &&
+ argtypes.nonEmpty() &&
+ types.isSubtypeUnchecked(argtypes.head, site)) {
+ return new UnboundMethodReferenceLookupHelper(referenceTree, name,
+ site, argtypes, typeargtypes, maxPhase);
+ } else {
+ return super.unboundLookup();
+ }
+ }
+
+ @Override
+ ReferenceKind referenceKind(Symbol sym) {
+ if (sym.isStatic()) {
+ return TreeInfo.isStaticSelector(referenceTree.expr, names) ?
+ ReferenceKind.STATIC : ReferenceKind.STATIC_EVAL;
+ } else {
+ Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
+ return selName != null && selName == names._super ?
+ ReferenceKind.SUPER :
+ ReferenceKind.BOUND;
+ }
+ }
+ }
+
+ /**
+ * Helper class for unbound method reference lookup. Essentially the same
+ * as the basic method reference lookup helper; main difference is that static
+ * lookup results are thrown away. If qualifier type is raw, an attempt to
+ * infer a parameterized type is made using the first actual argument (that
+ * would otherwise be ignored during the lookup).
+ */
+ class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
+
+ UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
+ List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
+ super(referenceTree, name,
+ site.isRaw() ? types.asSuper(argtypes.head, site.tsym) : site,
+ argtypes.tail, typeargtypes, maxPhase);
+ }
+
+ @Override
+ protected Symbol adjustLookupResult(Env<AttrContext> env, Symbol sym) {
+ return sym.kind != MTH || !sym.isStatic() ? sym : new StaticError(sym);
+ }
+
+ @Override
+ ReferenceLookupHelper unboundLookup() {
+ return this;
+ }
+
+ @Override
+ ReferenceKind referenceKind(Symbol sym) {
+ return ReferenceKind.UNBOUND;
+ }
+ }
+
+ /**
+ * Helper class for constructor reference lookup. The lookup logic is based
+ * upon either Resolve.findMethod or Resolve.findDiamond - depending on
+ * whether the constructor reference needs diamond inference (this is the case
+ * if the qualifier type is raw). A special erroneous symbol is returned
+ * if the lookup returns the constructor of an inner class and there's no
+ * enclosing instance in scope.
+ */
+ class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
+
+ boolean needsInference;
+
+ ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
+ List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
+ super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
+ if (site.isRaw()) {
+ this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym);
+ needsInference = true;
+ }
+ }
+
+ @Override
+ protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
+ Symbol sym = needsInference ?
+ findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
+ findMethod(env, site, name, argtypes, typeargtypes,
+ phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
+ return sym.kind != MTH ||
+ site.getEnclosingType().hasTag(NONE) ||
+ hasEnclosingInstance(env, site) ?
+ sym : new InvalidSymbolError(Kinds.MISSING_ENCL, sym, null) {
+ @Override
+ JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
+ return diags.create(dkind, log.currentSource(), pos,
+ "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
+ }
+ };
+ }
+
+ @Override
+ ReferenceKind referenceKind(Symbol sym) {
+ return site.getEnclosingType().hasTag(NONE) ?
+ ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
+ }
+ }
+
+ /**
+ * Main overload resolution routine. On each overload resolution step, a
+ * lookup helper class is used to perform the method/constructor lookup;
+ * at the end of the lookup, the helper is used to validate the results
+ * (this last step might trigger overload resolution diagnostics).
+ */
+ Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, LookupHelper lookupHelper) {
+ return lookupMethod(env, pos, location, new MethodResolutionContext(), lookupHelper);
+ }
+
+ Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location,
+ MethodResolutionContext resolveContext, LookupHelper lookupHelper) {
+ MethodResolutionContext prevResolutionContext = currentResolutionContext;
+ try {
+ Symbol bestSoFar = methodNotFound;
+ currentResolutionContext = resolveContext;
+ for (MethodResolutionPhase phase : methodResolutionSteps) {
+ if (!phase.isApplicable(boxingEnabled, varargsEnabled) ||
+ lookupHelper.shouldStop(bestSoFar, phase)) break;
+ MethodResolutionPhase prevPhase = currentResolutionContext.step;
+ Symbol prevBest = bestSoFar;
+ currentResolutionContext.step = phase;
+ bestSoFar = phase.mergeResults(bestSoFar, lookupHelper.lookup(env, phase));
+ env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase;
+ }
+ return lookupHelper.access(env, pos, location, bestSoFar);
+ } finally {
+ currentResolutionContext = prevResolutionContext;
+ }
+ }
+
+ /**
* Resolve `c.name' where name == this or name == super.
* @param pos The position to use for error reporting.
* @param env The environment current at the expression.
@@ -2744,9 +2763,47 @@
if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
env1 = env1.outer;
}
+ if (allowDefaultMethods && c.isInterface() &&
+ name == names._super && !isStatic(env) &&
+ types.isDirectSuperInterface(c, env.enclClass.sym)) {
+ //this might be a default super call if one of the superinterfaces is 'c'
+ for (Type t : pruneInterfaces(env.enclClass.type)) {
+ if (t.tsym == c) {
+ env.info.defaultSuperCallSite = t;
+ return new VarSymbol(0, names._super,
+ types.asSuper(env.enclClass.type, c), env.enclClass.sym);
+ }
+ }
+ //find a direct superinterface that is a subtype of 'c'
+ for (Type i : types.interfaces(env.enclClass.type)) {
+ if (i.tsym.isSubClass(c, types) && i.tsym != c) {
+ log.error(pos, "illegal.default.super.call", c,
+ diags.fragment("redundant.supertype", c, i));
+ return syms.errSymbol;
+ }
+ }
+ Assert.error();
+ }
log.error(pos, "not.encl.class", c);
return syms.errSymbol;
}
+ //where
+ private List<Type> pruneInterfaces(Type t) {
+ ListBuffer<Type> result = ListBuffer.lb();
+ for (Type t1 : types.interfaces(t)) {
+ boolean shouldAdd = true;
+ for (Type t2 : types.interfaces(t)) {
+ if (t1 != t2 && types.isSubtypeNoCapture(t2, t1)) {
+ shouldAdd = false;
+ }
+ }
+ if (shouldAdd) {
+ result.append(t1);
+ }
+ }
+ return result.toList();
+ }
+
/**
* Resolve `c.this' for an enclosing class c that contains the
@@ -3114,20 +3171,14 @@
return types.createErrorType(name, location, syms.errSymbol.type).tsym;
}
- protected boolean shouldReport(Candidate c) {
- MethodResolutionPhase errPhase = resolveContext.firstErroneousResolutionPhase();
- return !c.isApplicable() &&
- c.step == errPhase;
- }
-
private Candidate errCandidate() {
+ Candidate bestSoFar = null;
for (Candidate c : resolveContext.candidates) {
- if (shouldReport(c)) {
- return c;
- }
+ if (c.isApplicable()) continue;
+ bestSoFar = c;
}
- Assert.error();
- return null;
+ Assert.checkNonNull(bestSoFar);
+ return bestSoFar;
}
}
@@ -3156,8 +3207,8 @@
pos,
"cant.apply.symbols",
name == names.init ? KindName.CONSTRUCTOR : absentKind(kind),
- getName(),
- argtypes);
+ name == names.init ? site.tsym.name : name,
+ methodArguments(argtypes));
return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site));
} else {
return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
@@ -3167,24 +3218,17 @@
//where
List<JCDiagnostic> candidateDetails(Type site) {
- List<JCDiagnostic> details = List.nil();
+ Map<Symbol, JCDiagnostic> details = new LinkedHashMap<Symbol, JCDiagnostic>();
for (Candidate c : resolveContext.candidates) {
- if (!shouldReport(c)) continue;
+ if (c.isApplicable()) continue;
JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
Kinds.kindName(c.sym),
c.sym.location(site, types),
c.sym.asMemberOf(site, types),
c.details);
- details = details.prepend(detailDiag);
+ details.put(c.sym, detailDiag);
}
- return details.reverse();
- }
-
- private Name getName() {
- Symbol sym = resolveContext.candidates.head.sym;
- return sym.name == names.init ?
- sym.owner.name :
- sym.name;
+ return List.from(details.values());
}
}
@@ -3322,7 +3366,21 @@
enum MethodResolutionPhase {
BASIC(false, false),
BOX(true, false),
- VARARITY(true, true);
+ VARARITY(true, true) {
+ @Override
+ public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
+ switch (sym.kind) {
+ case WRONG_MTH:
+ return (bestSoFar.kind == WRONG_MTH || bestSoFar.kind == WRONG_MTHS) ?
+ bestSoFar :
+ sym;
+ case ABSENT_MTH:
+ return bestSoFar;
+ default:
+ return sym;
+ }
+ }
+ };
boolean isBoxingRequired;
boolean isVarargsRequired;
@@ -3344,6 +3402,10 @@
return (varargsEnabled || !isVarargsRequired) &&
(boxingEnabled || !isBoxingRequired);
}
+
+ public Symbol mergeResults(Symbol prev, Symbol sym) {
+ return sym;
+ }
}
final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
@@ -3359,29 +3421,11 @@
private List<Candidate> candidates = List.nil();
- private Map<MethodResolutionPhase, Symbol> resolutionCache =
- new EnumMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.class);
-
MethodResolutionPhase step = null;
private boolean internalResolution = false;
private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
- private MethodResolutionPhase firstErroneousResolutionPhase() {
- MethodResolutionPhase bestSoFar = BASIC;
- Symbol sym = methodNotFound;
- List<MethodResolutionPhase> steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= WRONG_MTHS) {
- sym = resolutionCache.get(steps.head);
- if (sym.kind == ABSENT_MTH) break; //ignore spurious empty entries
- bestSoFar = steps.head;
- steps = steps.tail;
- }
- return bestSoFar;
- }
-
void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
candidates = candidates.append(c);
@@ -3392,16 +3436,6 @@
candidates = candidates.append(c);
}
- Candidate getCandidate(Symbol sym, MethodResolutionPhase phase) {
- for (Candidate c : currentResolutionContext.candidates) {
- if (c.step == phase &&
- c.sym.baseSymbol() == sym.baseSymbol()) {
- return c;
- }
- }
- return null;
- }
-
/**
* This class represents an overload resolution candidate. There are two
* kinds of candidates: applicable methods and inapplicable methods;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Fri Nov 30 17:09:05 2012 -0800
@@ -133,7 +133,7 @@
JCExpression coerce(JCExpression tree, Type target) {
Type btarget = target.baseType();
if (tree.type.isPrimitive() == target.isPrimitive()) {
- return types.isAssignable(tree.type, btarget, Warner.noWarnings)
+ return types.isAssignable(tree.type, btarget, types.noWarnings)
? tree
: cast(tree, btarget);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java Fri Nov 30 17:09:05 2012 -0800
@@ -503,6 +503,14 @@
result = sr;
}
+ @Override
+ public void visitLetExpr(LetExpr tree) {
+ SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
+ sr.mergeWith(csp(tree.defs));
+ sr.mergeWith(csp(tree.expr));
+ result = sr;
+ }
+
public void visitTypeParameter(JCTypeParameter tree) {
SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
sr.mergeWith(csp(tree.bounds));
@@ -525,7 +533,7 @@
*/
public int startPos(JCTree tree) {
if (tree == null) return Position.NOPOS;
- return tree.pos;
+ return TreeInfo.getStartPos(tree);
}
/** The end position of given tree, if it has
@@ -533,9 +541,7 @@
*/
public int endPos(JCTree tree) {
if (tree == null) return Position.NOPOS;
- if (tree.hasTag(JCTree.Tag.BLOCK))
- return ((JCBlock) tree).endpos;
- return endPosTable.getEndPos(tree);
+ return TreeInfo.getEndPos(tree, endPosTable);
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java Fri Nov 30 17:09:05 2012 -0800
@@ -104,7 +104,8 @@
V45_3(45, 3), // base level for all attributes
V49(49, 0), // JDK 1.5: enum, generics, annotations
V50(50, 0), // JDK 1.6: stackmaps
- V51(51, 0); // JDK 1.7
+ V51(51, 0), // JDK 1.7
+ V52(52, 0); // JDK 1.8: lambda, type annos, param names
Version(int major, int minor) {
this.major = major;
this.minor = minor;
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Nov 30 17:09:05 2012 -0800
@@ -115,6 +115,9 @@
*/
boolean lintClassfile;
+ /** Switch: allow default methods
+ */
+ boolean allowDefaultMethods;
/** Switch: preserve parameter names from the variable table.
*/
@@ -279,6 +282,7 @@
allowVarargs = source.allowVarargs();
allowAnnotations = source.allowAnnotations();
allowSimplifiedVarargs = source.allowSimplifiedVarargs();
+ allowDefaultMethods = source.allowDefaultMethods();
saveParameterNames = options.isSet("save-parameter-names");
cacheCompletionFailure = options.isUnset("dev");
preferSource = "source".equals(options.get("-Xprefer"));
@@ -1737,6 +1741,17 @@
long flags = adjustMethodFlags(nextChar());
Name name = readName(nextChar());
Type type = readType(nextChar());
+ if (currentOwner.isInterface() &&
+ (flags & ABSTRACT) == 0 && !name.equals(names.clinit)) {
+ if (majorVersion > Target.JDK1_8.majorVersion ||
+ (majorVersion == Target.JDK1_8.majorVersion && minorVersion >= Target.JDK1_8.minorVersion)) {
+ currentOwner.flags_field |= DEFAULT;
+ flags |= DEFAULT | ABSTRACT;
+ } else {
+ //protect against ill-formed classfiles
+ throw new CompletionFailure(currentOwner, "default method found in pre JDK 8 classfile");
+ }
+ }
if (name == names.init && currentOwner.hasOuterInstance()) {
// Sometimes anonymous classes don't have an outer
// instance, however, there is no reliable way to tell so
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -1540,7 +1540,7 @@
List<Type> interfaces = types.interfaces(c.type);
List<Type> typarams = c.type.getTypeArguments();
- int flags = adjustFlags(c.flags());
+ int flags = adjustFlags(c.flags() & ~DEFAULT);
if ((flags & PROTECTED) != 0) flags |= PUBLIC;
flags = flags & ClassFlags & ~STRICTFP;
if ((flags & INTERFACE) == 0) flags |= ACC_SUPER;
@@ -1676,6 +1676,8 @@
result |= ACC_BRIDGE;
if ((flags & VARARGS) != 0 && target.useVarargsFlag())
result |= ACC_VARARGS;
+ if ((flags & DEFAULT) != 0)
+ result &= ~ABSTRACT;
return result;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java Fri Nov 30 17:09:05 2012 -0800
@@ -523,7 +523,7 @@
Item invoke() {
MethodType mtype = (MethodType)member.externalType(types);
int rescode = Code.typecode(mtype.restype);
- if ((member.owner.flags() & Flags.INTERFACE) != 0) {
+ if ((member.owner.flags() & Flags.INTERFACE) != 0 && !nonvirtual) {
code.emitInvokeinterface(pool.put(member), mtype);
} else if (nonvirtual) {
code.emitInvokespecial(pool.put(member), mtype);
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Fri Nov 30 17:09:05 2012 -0800
@@ -157,13 +157,20 @@
if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0)
return false;
+ /* temporary code for backwards compatibility */
for (Attribute.Compound a: c.annotations.getAttributes()) {
- if (a.type.tsym == syms.nativeHeaderType.tsym)
+ if (a.type.tsym == syms.nativeHeaderType_old.tsym)
return true;
}
+ /* end of temporary code for backwards compatibility */
+
for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) {
if (i.sym.kind == Kinds.MTH && (i.sym.flags() & Flags.NATIVE) != 0)
return true;
+ for (Attribute.Compound a: i.sym.annotations.getAttributes()) {
+ if (a.type.tsym == syms.nativeHeaderType.tsym)
+ return true;
+ }
}
if (checkNestedClasses) {
for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) {
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Pool.java Fri Nov 30 17:09:05 2012 -0800
@@ -95,10 +95,7 @@
* package. Return the object's index in the pool.
*/
public int put(Object value) {
- if (value instanceof MethodSymbol)
- value = new Method((MethodSymbol)value);
- else if (value instanceof VarSymbol)
- value = new Variable((VarSymbol)value);
+ value = makePoolValue(value);
// assert !(value instanceof Type.TypeVar);
Integer index = indices.get(value);
if (index == null) {
@@ -115,6 +112,18 @@
return index.intValue();
}
+ Object makePoolValue(Object o) {
+ if (o instanceof DynamicMethodSymbol) {
+ return new DynamicMethod((DynamicMethodSymbol)o);
+ } else if (o instanceof MethodSymbol) {
+ return new Method((MethodSymbol)o);
+ } else if (o instanceof VarSymbol) {
+ return new Variable((VarSymbol)o);
+ } else {
+ return o;
+ }
+ }
+
/** Return the given object's index in the pool,
* or -1 if object is not in there.
*/
@@ -145,6 +154,36 @@
}
}
+ static class DynamicMethod extends Method {
+
+ DynamicMethod(DynamicMethodSymbol m) {
+ super(m);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!super.equals(other)) return false;
+ if (!(other instanceof DynamicMethod)) return false;
+ DynamicMethodSymbol dm1 = (DynamicMethodSymbol)m;
+ DynamicMethodSymbol dm2 = (DynamicMethodSymbol)((DynamicMethod)other).m;
+ return dm1.bsm == dm2.bsm &&
+ dm1.bsmKind == dm2.bsmKind &&
+ Arrays.equals(dm1.staticArgs, dm2.staticArgs);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = super.hashCode();
+ DynamicMethodSymbol dm = (DynamicMethodSymbol)m;
+ hash += dm.bsmKind * 7 +
+ dm.bsm.hashCode() * 11;
+ for (int i = 0; i < dm.staticArgs.length; i++) {
+ hash += (dm.staticArgs[i].hashCode() * 23);
+ }
+ return hash;
+ }
+ }
+
static class Variable extends DelegatedSymbol {
VarSymbol v;
Variable(VarSymbol v) {
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -68,8 +68,8 @@
/** JDK 7. */
JDK1_7("1.7", 51, 0),
- /** JDK 8. */ // For now, a clone of 7
- JDK1_8("1.8", 51, 0);
+ /** JDK 8. */
+ JDK1_8("1.8", 52, 0);
private static final Context.Key<Target> targetKey =
new Context.Key<Target>();
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri Nov 30 17:09:05 2012 -0800
@@ -1018,6 +1018,8 @@
*/
boolean processAnnotations = false;
+ Log.DeferredDiagnosticHandler deferredDiagnosticHandler;
+
/**
* Object to handle annotation processing.
*/
@@ -1038,7 +1040,8 @@
if (options.isSet(PROC, "none")) {
processAnnotations = false;
} else if (procEnvImpl == null) {
- procEnvImpl = new JavacProcessingEnvironment(context, processors);
+ procEnvImpl = JavacProcessingEnvironment.instance(context);
+ procEnvImpl.setProcessors(processors);
processAnnotations = procEnvImpl.atLeastOneProcessor();
if (processAnnotations) {
@@ -1048,7 +1051,7 @@
genEndPos = true;
if (!taskListener.isEmpty())
taskListener.started(new TaskEvent(TaskEvent.Kind.ANNOTATION_PROCESSING));
- log.deferAll();
+ deferredDiagnosticHandler = new Log.DeferredDiagnosticHandler(log);
} else { // free resources
procEnvImpl.close();
}
@@ -1079,7 +1082,8 @@
// or other errors during enter which cannot be fixed by running
// any annotation processors.
if (unrecoverableError()) {
- log.reportDeferredDiagnostics();
+ deferredDiagnosticHandler.reportDeferredDiagnostics();
+ log.popDiagnosticHandler(deferredDiagnosticHandler);
return this;
}
}
@@ -1102,10 +1106,12 @@
log.error("proc.no.explicit.annotation.processing.requested",
classnames);
}
- log.reportDeferredDiagnostics();
+ Assert.checkNull(deferredDiagnosticHandler);
return this; // continue regular compilation
}
+ Assert.checkNonNull(deferredDiagnosticHandler);
+
try {
List<ClassSymbol> classSymbols = List.nil();
List<PackageSymbol> pckSymbols = List.nil();
@@ -1115,7 +1121,8 @@
if (!explicitAnnotationProcessingRequested()) {
log.error("proc.no.explicit.annotation.processing.requested",
classnames);
- log.reportDeferredDiagnostics();
+ deferredDiagnosticHandler.reportDeferredDiagnostics();
+ log.popDiagnosticHandler(deferredDiagnosticHandler);
return this; // TODO: Will this halt compilation?
} else {
boolean errors = false;
@@ -1148,33 +1155,36 @@
}
}
if (errors) {
- log.reportDeferredDiagnostics();
+ deferredDiagnosticHandler.reportDeferredDiagnostics();
+ log.popDiagnosticHandler(deferredDiagnosticHandler);
return this;
}
}
}
try {
- JavaCompiler c = procEnvImpl.doProcessing(context, roots, classSymbols, pckSymbols);
+ JavaCompiler c = procEnvImpl.doProcessing(context, roots, classSymbols, pckSymbols,
+ deferredDiagnosticHandler);
if (c != this)
annotationProcessingOccurred = c.annotationProcessingOccurred = true;
// doProcessing will have handled deferred diagnostics
- Assert.check(c.log.deferredDiagFilter == null
- && c.log.deferredDiagnostics.size() == 0);
return c;
} finally {
procEnvImpl.close();
}
} catch (CompletionFailure ex) {
log.error("cant.access", ex.sym, ex.getDetailValue());
- log.reportDeferredDiagnostics();
+ deferredDiagnosticHandler.reportDeferredDiagnostics();
+ log.popDiagnosticHandler(deferredDiagnosticHandler);
return this;
}
}
private boolean unrecoverableError() {
- for (JCDiagnostic d: log.deferredDiagnostics) {
- if (d.getKind() == JCDiagnostic.Kind.ERROR && !d.isFlagSet(RECOVERABLE))
- return true;
+ if (deferredDiagnosticHandler != null) {
+ for (JCDiagnostic d: deferredDiagnosticHandler.getDiagnostics()) {
+ if (d.getKind() == JCDiagnostic.Kind.ERROR && !d.isFlagSet(RECOVERABLE))
+ return true;
+ }
}
return false;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java Fri Nov 30 17:09:05 2012 -0800
@@ -33,24 +33,29 @@
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Iterator;
import java.util.LinkedHashSet;
+import java.util.ServiceLoader;
import java.util.Set;
+
+import javax.annotation.processing.Processor;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
-import javax.annotation.processing.Processor;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.Plugin;
import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.file.CacheFSInfo;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.jvm.Target;
+import com.sun.tools.javac.processing.AnnotationProcessingError;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.Log.WriterKind;
import com.sun.tools.javac.util.Log.PrefixKind;
-import com.sun.tools.javac.processing.AnnotationProcessingError;
-
+import com.sun.tools.javac.util.Log.WriterKind;
import static com.sun.tools.javac.main.Option.*;
-/** This class provides a commandline interface to the GJC compiler.
+/** This class provides a command line interface to the javac compiler.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
@@ -423,6 +428,42 @@
if (batchMode)
CacheFSInfo.preRegister(context);
+ // invoke any available plugins
+ String plugins = options.get(PLUGIN);
+ if (plugins != null) {
+ JavacProcessingEnvironment pEnv = JavacProcessingEnvironment.instance(context);
+ ClassLoader cl = pEnv.getProcessorClassLoader();
+ ServiceLoader<Plugin> sl = ServiceLoader.load(Plugin.class, cl);
+ Set<List<String>> pluginsToCall = new LinkedHashSet<List<String>>();
+ for (String plugin: plugins.split("\\x00")) {
+ pluginsToCall.add(List.from(plugin.split("\\s+")));
+ }
+ JavacTask task = null;
+ Iterator<Plugin> iter = sl.iterator();
+ while (iter.hasNext()) {
+ Plugin plugin = iter.next();
+ for (List<String> p: pluginsToCall) {
+ if (plugin.getName().equals(p.head)) {
+ pluginsToCall.remove(p);
+ try {
+ if (task == null)
+ task = JavacTask.instance(pEnv);
+ plugin.call(task, p.tail.toArray(new String[p.tail.size()]));
+ } catch (Throwable ex) {
+ if (apiMode)
+ throw new RuntimeException(ex);
+ pluginMessage(ex);
+ return Result.SYSERR;
+ }
+
+ }
+ }
+ }
+ for (List<String> p: pluginsToCall) {
+ log.printLines(PrefixKind.JAVAC, "msg.plugin.not.found", p.head);
+ }
+ }
+
fileManager = context.get(JavaFileManager.class);
comp = JavaCompiler.instance(context);
@@ -533,10 +574,18 @@
* annotation processor.
*/
void apMessage(AnnotationProcessingError ex) {
- log.printLines("msg.proc.annotation.uncaught.exception");
+ log.printLines(PrefixKind.JAVAC, "msg.proc.annotation.uncaught.exception");
ex.getCause().printStackTrace(log.getWriter(WriterKind.NOTICE));
}
+ /** Print a message reporting an uncaught exception from an
+ * annotation processor.
+ */
+ void pluginMessage(Throwable ex) {
+ log.printLines(PrefixKind.JAVAC, "msg.plugin.uncaught.exception");
+ ex.printStackTrace(log.getWriter(WriterKind.NOTICE));
+ }
+
/** Display the location and checksum of a class. */
void showClass(String className) {
PrintWriter pw = log.getWriter(WriterKind.NOTICE);
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Option.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Option.java Fri Nov 30 17:09:05 2012 -0800
@@ -393,6 +393,16 @@
/* -Xjcov produces tables to support the code coverage tool jcov. */
XJCOV("-Xjcov", null, HIDDEN, BASIC),
+ PLUGIN("-Xplugin:", "opt.arg.plugin", "opt.plugin", EXTENDED, BASIC) {
+ @Override
+ public boolean process(OptionHelper helper, String option) {
+ String p = option.substring(option.indexOf(':') + 1);
+ String prev = helper.get(PLUGIN);
+ helper.put(PLUGIN.text, (prev == null) ? p : prev + '\0' + p.trim());
+ return false;
+ }
+ },
+
/* This is a back door to the compiler's option table.
* -XDx=y sets the option x to the value y.
* -XDx sets the option x to the value x.
--- a/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012, 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
@@ -253,7 +253,8 @@
for (File f: files)
pl.add(f.toPath());
}
- pathsForLocation.put(locn, pl);
+ if (!pl.isEmpty())
+ pathsForLocation.put(locn, pl);
}
private void lazyInitSearchPaths() {
@@ -513,7 +514,8 @@
}
private static String getRelativePath(String packageName, String relativeName) {
- return packageName.replace(".", "/") + relativeName;
+ return packageName.isEmpty()
+ ? relativeName : packageName.replace(".", "/") + "/" + relativeName;
}
private static String getBaseName(String relativePath) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,1288 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.parser;
+
+import com.sun.tools.javac.util.Filter;
+import java.text.BreakIterator;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+
+import com.sun.source.doctree.AttributeTree.ValueKind;
+import com.sun.tools.javac.parser.DocCommentParser.TagParser.Kind;
+import com.sun.tools.javac.parser.Tokens.Comment;
+import com.sun.tools.javac.parser.Tokens.TokenKind;
+import com.sun.tools.javac.tree.DCTree;
+import com.sun.tools.javac.tree.DCTree.DCAttribute;
+import com.sun.tools.javac.tree.DCTree.DCDocComment;
+import com.sun.tools.javac.tree.DCTree.DCEndElement;
+import com.sun.tools.javac.tree.DCTree.DCErroneous;
+import com.sun.tools.javac.tree.DCTree.DCIdentifier;
+import com.sun.tools.javac.tree.DCTree.DCReference;
+import com.sun.tools.javac.tree.DCTree.DCStartElement;
+import com.sun.tools.javac.tree.DCTree.DCText;
+import com.sun.tools.javac.tree.DocTreeMaker;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.util.DiagnosticSource;
+import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
+import com.sun.tools.javac.util.Options;
+import com.sun.tools.javac.util.Position;
+import static com.sun.tools.javac.util.LayoutCharacters.*;
+
+/**
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class DocCommentParser {
+ static class ParseException extends Exception {
+ private static final long serialVersionUID = 0;
+ ParseException(String key) {
+ super(key);
+ }
+ }
+
+ final ParserFactory fac;
+ final DiagnosticSource diagSource;
+ final Comment comment;
+ final DocTreeMaker m;
+ final Names names;
+
+ BreakIterator sentenceBreaker;
+
+ /** The input buffer, index of most recent character read,
+ * index of one past last character in buffer.
+ */
+ protected char[] buf;
+ protected int bp;
+ protected int buflen;
+
+ /** The current character.
+ */
+ protected char ch;
+
+ int textStart = -1;
+ int lastNonWhite = -1;
+ boolean newline = true;
+
+ Map<Name, TagParser> tagParsers;
+
+ DocCommentParser(ParserFactory fac, DiagnosticSource diagSource, Comment comment) {
+ this.fac = fac;
+ this.diagSource = diagSource;
+ this.comment = comment;
+ names = fac.names;
+ m = fac.docTreeMaker;
+
+ Locale locale = (fac.locale == null) ? Locale.getDefault() : fac.locale;
+
+ Options options = fac.options;
+ boolean useBreakIterator = options.isSet("breakIterator");
+ if (useBreakIterator || !locale.getLanguage().equals(Locale.ENGLISH.getLanguage()))
+ sentenceBreaker = BreakIterator.getSentenceInstance(locale);
+
+ initTagParsers();
+ }
+
+ DCDocComment parse() {
+ String c = comment.getText();
+ buf = new char[c.length() + 1];
+ c.getChars(0, c.length(), buf, 0);
+ buf[buf.length - 1] = EOI;
+ buflen = buf.length - 1;
+ bp = -1;
+ nextChar();
+
+ List<DCTree> body = blockContent();
+ List<DCTree> tags = blockTags();
+
+ // split body into first sentence and body
+ ListBuffer<DCTree> fs = new ListBuffer<DCTree>();
+ loop:
+ for (; body.nonEmpty(); body = body.tail) {
+ DCTree t = body.head;
+ switch (t.getKind()) {
+ case TEXT:
+ String s = ((DCText) t).getBody();
+ int i = getSentenceBreak(s);
+ if (i > 0) {
+ int i0 = i;
+ while (i0 > 0 && isWhitespace(s.charAt(i0 - 1)))
+ i0--;
+ fs.add(m.at(t.pos).Text(s.substring(0, i0)));
+ int i1 = i;
+ while (i1 < s.length() && isWhitespace(s.charAt(i1)))
+ i1++;
+ body = body.tail;
+ if (i1 < s.length())
+ body = body.prepend(m.at(t.pos + i1).Text(s.substring(i1)));
+ break loop;
+ } else if (body.tail.nonEmpty()) {
+ if (isSentenceBreak(body.tail.head)) {
+ int i0 = s.length() - 1;
+ while (i0 > 0 && isWhitespace(s.charAt(i0)))
+ i0--;
+ fs.add(m.at(t.pos).Text(s.substring(0, i0 + 1)));
+ body = body.tail;
+ break loop;
+ }
+ }
+ break;
+
+ case START_ELEMENT:
+ case END_ELEMENT:
+ if (isSentenceBreak(t))
+ break loop;
+ break;
+ }
+ fs.add(t);
+ }
+
+ @SuppressWarnings("unchecked")
+ DCTree first = getFirst(fs.toList(), body, tags);
+ int pos = (first == null) ? Position.NOPOS : first.pos;
+
+ DCDocComment dc = m.at(pos).DocComment(comment, fs.toList(), body, tags);
+ return dc;
+ }
+
+ void nextChar() {
+ ch = buf[bp < buflen ? ++bp : buflen];
+ switch (ch) {
+ case '\f': case '\n': case '\r':
+ newline = true;
+ }
+ }
+
+ /**
+ * Read block content, consisting of text, html and inline tags.
+ * Terminated by the end of input, or the beginning of the next block tag:
+ * i.e. @ as the first non-whitespace character on a line.
+ */
+ @SuppressWarnings("fallthrough")
+ protected List<DCTree> blockContent() {
+ ListBuffer<DCTree> trees = new ListBuffer<DCTree>();
+ textStart = -1;
+
+ loop:
+ while (bp < buflen) {
+ switch (ch) {
+ case '\n': case '\r': case '\f':
+ newline = true;
+ // fallthrough
+
+ case ' ': case '\t':
+ nextChar();
+ break;
+
+ case '&':
+ entity(trees);
+ break;
+
+ case '<':
+ newline = false;
+ addPendingText(trees, bp - 1);
+ trees.add(html());
+ if (textStart == -1) {
+ textStart = bp;
+ lastNonWhite = -1;
+ }
+ break;
+
+ case '>':
+ newline = false;
+ addPendingText(trees, bp - 1);
+ trees.add(m.at(bp).Erroneous(newString(bp, bp+1), diagSource, "dc.bad.gt"));
+ nextChar();
+ if (textStart == -1) {
+ textStart = bp;
+ lastNonWhite = -1;
+ }
+ break;
+
+ case '{':
+ inlineTag(trees);
+ break;
+
+ case '@':
+ if (newline) {
+ addPendingText(trees, lastNonWhite);
+ break loop;
+ }
+ // fallthrough
+
+ default:
+ newline = false;
+ if (textStart == -1)
+ textStart = bp;
+ lastNonWhite = bp;
+ nextChar();
+ }
+ }
+
+ if (lastNonWhite != -1)
+ addPendingText(trees, lastNonWhite);
+
+ return trees.toList();
+ }
+
+ /**
+ * Read a series of block tags, including their content.
+ * Standard tags parse their content appropriately.
+ * Non-standard tags are represented by {@link UnknownBlockTag}.
+ */
+ protected List<DCTree> blockTags() {
+ ListBuffer<DCTree> tags = new ListBuffer<DCTree>();
+ while (ch == '@')
+ tags.add(blockTag());
+ return tags.toList();
+ }
+
+ /**
+ * Read a single block tag, including its content.
+ * Standard tags parse their content appropriately.
+ * Non-standard tags are represented by {@link UnknownBlockTag}.
+ */
+ protected DCTree blockTag() {
+ int p = bp;
+ try {
+ nextChar();
+ if (isIdentifierStart(ch)) {
+ int namePos = bp;
+ nextChar();
+ while (isIdentifierPart(ch))
+ nextChar();
+ int nameLen = bp - namePos;
+
+ Name name = names.fromChars(buf, namePos, nameLen);
+ TagParser tp = tagParsers.get(name);
+ if (tp == null) {
+ List<DCTree> content = blockContent();
+ return m.at(p).UnknownBlockTag(name, content);
+ } else {
+ switch (tp.getKind()) {
+ case BLOCK:
+ return tp.parse(p);
+ case INLINE:
+ return erroneous("dc.bad.inline.tag", p);
+ }
+ }
+ }
+ blockContent();
+
+ return erroneous("dc.no.tag.name", p);
+ } catch (ParseException e) {
+ blockContent();
+ return erroneous(e.getMessage(), p);
+ }
+ }
+
+ protected void inlineTag(ListBuffer<DCTree> list) {
+ newline = false;
+ nextChar();
+ if (ch == '@') {
+ addPendingText(list, bp - 2);
+ list.add(inlineTag());
+ textStart = bp;
+ lastNonWhite = -1;
+ } else {
+ if (textStart == -1)
+ textStart = bp - 1;
+ lastNonWhite = bp;
+ }
+ }
+
+ /**
+ * Read a single inline tag, including its content.
+ * Standard tags parse their content appropriately.
+ * Non-standard tags are represented by {@link UnknownBlockTag}.
+ * Malformed tags may be returned as {@link Erroneous}.
+ */
+ protected DCTree inlineTag() {
+ int p = bp - 1;
+ try {
+ nextChar();
+ if (isIdentifierStart(ch)) {
+ int namePos = bp;
+ nextChar();
+ while (isIdentifierPart(ch))
+ nextChar();
+ int nameLen = bp - namePos;
+ skipWhitespace();
+
+ Name name = names.fromChars(buf, namePos, nameLen);
+ TagParser tp = tagParsers.get(name);
+ if (tp == null) {
+ DCTree text = inlineText();
+ if (text != null) {
+ nextChar();
+ return m.at(p).UnknownInlineTag(name, List.of(text));
+ }
+ } else if (tp.getKind() == TagParser.Kind.INLINE) {
+ DCTree tree = tp.parse(p);
+ if (tree != null) {
+ return tree;
+ }
+ } else {
+ inlineText(); // skip content
+ nextChar();
+ }
+ }
+ return erroneous("dc.no.tag.name", p);
+ } catch (ParseException e) {
+ return erroneous(e.getMessage(), p);
+ }
+ }
+
+ /**
+ * Read plain text content of an inline tag.
+ * Matching pairs of { } are skipped; the text is terminated by the first
+ * unmatched }. It is an error if the beginning of the next tag is detected.
+ */
+ protected DCTree inlineText() throws ParseException {
+ skipWhitespace();
+ int pos = bp;
+ int depth = 1;
+
+ loop:
+ while (bp < buflen) {
+ switch (ch) {
+ case '\n': case '\r': case '\f':
+ newline = true;
+ break;
+
+ case ' ': case '\t':
+ break;
+
+ case '{':
+ newline = false;
+ lastNonWhite = bp;
+ depth++;
+ break;
+
+ case '}':
+ if (--depth == 0) {
+ return m.at(pos).Text(newString(pos, bp));
+ }
+ newline = false;
+ lastNonWhite = bp;
+ break;
+
+ case '@':
+ if (newline)
+ break loop;
+ newline = false;
+ lastNonWhite = bp;
+ break;
+
+ default:
+ newline = false;
+ lastNonWhite = bp;
+ break;
+ }
+ nextChar();
+ }
+ throw new ParseException("dc.unterminated.inline.tag");
+ }
+
+ /**
+ * Read Java class name, possibly followed by member
+ * Matching pairs of < > are skipped. The text is terminated by the first
+ * unmatched }. It is an error if the beginning of the next tag is detected.
+ */
+ // TODO: boolean allowMember should be enum FORBID, ALLOW, REQUIRE
+ // TODO: improve quality of parse to forbid bad constructions.
+ @SuppressWarnings("fallthrough")
+ protected DCReference reference(boolean allowMember) throws ParseException {
+ int pos = bp;
+ int depth = 0;
+
+ // scan to find the end of the signature, by looking for the first
+ // whitespace not enclosed in () or <>, or the end of the tag
+ loop:
+ while (bp < buflen) {
+ switch (ch) {
+ case '\n': case '\r': case '\f':
+ newline = true;
+ // fallthrough
+
+ case ' ': case '\t':
+ if (depth == 0)
+ break loop;
+ break;
+
+ case '(':
+ case '<':
+ newline = false;
+ depth++;
+ break;
+
+ case ')':
+ case '>':
+ newline = false;
+ --depth;
+ break;
+
+ case '}':
+ if (bp == pos)
+ return null;
+ newline = false;
+ break loop;
+
+ case '@':
+ if (newline)
+ break loop;
+ // fallthrough
+
+ default:
+ newline = false;
+
+ }
+ nextChar();
+ }
+
+ if (depth != 0)
+ throw new ParseException("dc.unterminated.signature");
+
+ String sig = newString(pos, bp);
+
+ // Break sig apart into qualifiedExpr member paramTypes.
+ JCTree qualExpr;
+ Name member;
+ List<JCTree> paramTypes;
+
+ Log.DeferredDiagnosticHandler deferredDiagnosticHandler
+ = new Log.DeferredDiagnosticHandler(fac.log);
+
+ try {
+ int hash = sig.indexOf("#");
+ int lparen = sig.indexOf("(", hash + 1);
+ if (hash == -1) {
+ if (lparen == -1) {
+ qualExpr = parseType(sig);
+ member = null;
+ } else {
+ qualExpr = null;
+ member = parseMember(sig.substring(0, lparen));
+ }
+ } else {
+ qualExpr = (hash == 0) ? null : parseType(sig.substring(0, hash));
+ if (lparen == -1)
+ member = parseMember(sig.substring(hash + 1));
+ else
+ member = parseMember(sig.substring(hash + 1, lparen));
+ }
+
+ if (lparen < 0) {
+ paramTypes = null;
+ } else {
+ int rparen = sig.indexOf(")", lparen);
+ if (rparen != sig.length() - 1)
+ throw new ParseException("dc.ref.bad.parens");
+ paramTypes = parseParams(sig.substring(lparen + 1, rparen));
+ }
+
+ if (!deferredDiagnosticHandler.getDiagnostics().isEmpty())
+ throw new ParseException("dc.ref.syntax.error");
+
+ } finally {
+ fac.log.popDiagnosticHandler(deferredDiagnosticHandler);
+ }
+
+ return m.at(pos).Reference(sig, qualExpr, member, paramTypes);
+ }
+
+ JCTree parseType(String s) throws ParseException {
+ JavacParser p = fac.newParser(s, false, false, false);
+ JCTree tree = p.parseType();
+ if (p.token().kind != TokenKind.EOF)
+ throw new ParseException("dc.ref.unexpected.input");
+ return tree;
+ }
+
+ Name parseMember(String s) throws ParseException {
+ JavacParser p = fac.newParser(s, false, false, false);
+ Name name = p.ident();
+ if (p.token().kind != TokenKind.EOF)
+ throw new ParseException("dc.ref.unexpected.input");
+ return name;
+ }
+
+ List<JCTree> parseParams(String s) throws ParseException {
+ if (s.trim().isEmpty())
+ return List.nil();
+
+ JavacParser p = fac.newParser(s.replace("...", "[]"), false, false, false);
+ ListBuffer<JCTree> paramTypes = new ListBuffer<JCTree>();
+ paramTypes.add(p.parseType());
+
+ if (p.token().kind == TokenKind.IDENTIFIER)
+ p.nextToken();
+
+ while (p.token().kind == TokenKind.COMMA) {
+ p.nextToken();
+ paramTypes.add(p.parseType());
+
+ if (p.token().kind == TokenKind.IDENTIFIER)
+ p.nextToken();
+ }
+
+ if (p.token().kind != TokenKind.EOF)
+ throw new ParseException("dc.ref.unexpected.input");
+
+ return paramTypes.toList();
+ }
+
+ /**
+ * Read Java identifier
+ * Matching pairs of { } are skipped; the text is terminated by the first
+ * unmatched }. It is an error if the beginning of the next tag is detected.
+ */
+ @SuppressWarnings("fallthrough")
+ protected DCIdentifier identifier() throws ParseException {
+ skipWhitespace();
+ int pos = bp;
+
+ if (isJavaIdentifierStart(ch)) {
+ nextChar();
+ while (isJavaIdentifierPart(ch))
+ nextChar();
+ return m.at(pos).Identifier(names.fromChars(buf, pos, bp - pos));
+ }
+
+ throw new ParseException("dc.identifier.expected");
+ }
+
+ /**
+ * Read a quoted string.
+ * It is an error if the beginning of the next tag is detected.
+ */
+ @SuppressWarnings("fallthrough")
+ protected DCText quotedString() {
+ int pos = bp;
+ nextChar();
+
+ loop:
+ while (bp < buflen) {
+ switch (ch) {
+ case '\n': case '\r': case '\f':
+ newline = true;
+ break;
+
+ case ' ': case '\t':
+ break;
+
+ case '"':
+ nextChar();
+ // trim trailing white-space?
+ return m.at(pos).Text(newString(pos, bp));
+
+ case '@':
+ if (newline)
+ break loop;
+
+ }
+ nextChar();
+ }
+ return null;
+ }
+
+ /**
+ * Read general text content of an inline tag, including HTML entities and elements.
+ * Matching pairs of { } are skipped; the text is terminated by the first
+ * unmatched }. It is an error if the beginning of the next tag is detected.
+ */
+ @SuppressWarnings("fallthrough")
+ protected List<DCTree> inlineContent() {
+ ListBuffer<DCTree> trees = new ListBuffer<DCTree>();
+
+ skipWhitespace();
+ int pos = bp;
+ int depth = 1;
+ textStart = -1;
+
+ loop:
+ while (bp < buflen) {
+
+ switch (ch) {
+ case '\n': case '\r': case '\f':
+ newline = true;
+ // fall through
+
+ case ' ': case '\t':
+ nextChar();
+ break;
+
+ case '&':
+ entity(trees);
+ break;
+
+ case '<':
+ newline = false;
+ addPendingText(trees, bp - 1);
+ trees.add(html());
+ break;
+
+ case '{':
+ newline = false;
+ depth++;
+ nextChar();
+ break;
+
+ case '}':
+ newline = false;
+ if (--depth == 0) {
+ addPendingText(trees, bp - 1);
+ nextChar();
+ return trees.toList();
+ }
+ nextChar();
+ break;
+
+ case '@':
+ if (newline)
+ break loop;
+ // fallthrough
+
+ default:
+ if (textStart == -1)
+ textStart = bp;
+ nextChar();
+ break;
+ }
+ }
+
+ return List.<DCTree>of(erroneous("dc.unterminated.inline.tag", pos));
+ }
+
+ protected void entity(ListBuffer<DCTree> list) {
+ newline = false;
+ addPendingText(list, bp - 1);
+ list.add(entity());
+ if (textStart == -1) {
+ textStart = bp;
+ lastNonWhite = -1;
+ }
+ }
+
+ /**
+ * Read an HTML entity.
+ * {@literal &identifier; } or {@literal &#digits; } or {@literal &#xhex-digits; }
+ */
+ protected DCTree entity() {
+ int p = bp;
+ nextChar();
+ int namep = bp;
+ boolean checkSemi = false;
+ if (ch == '#') {
+ nextChar();
+ if (isDecimalDigit(ch)) {
+ nextChar();
+ while (isDecimalDigit(ch))
+ nextChar();
+ checkSemi = true;
+ } else if (ch == 'x' || ch == 'X') {
+ nextChar();
+ if (isHexDigit(ch)) {
+ nextChar();
+ while (isHexDigit(ch))
+ nextChar();
+ checkSemi = true;
+ }
+ }
+ } else if (isIdentifierStart(ch)) {
+ nextChar();
+ while (isIdentifierPart(ch))
+ nextChar();
+ checkSemi = true;
+ }
+
+ if (checkSemi && ch == ';') {
+ nextChar();
+ return m.at(p).Entity(names.fromChars(buf, namep, bp - namep - 1));
+ } else {
+ String code = checkSemi ? "dc.missing.semicolon" : "dc.bad.entity";
+ return erroneous(code, p);
+ }
+ }
+
+ /**
+ * Read the start or end of an HTML tag, or an HTML comment
+ * {@literal <identifier attrs> } or {@literal </identifier> }
+ */
+ protected DCTree html() {
+ int p = bp;
+ nextChar();
+ if (isIdentifierStart(ch)) {
+ int namePos = bp;
+ nextChar();
+ while (isIdentifierPart(ch))
+ nextChar();
+ int nameLen = bp - namePos;
+ List<DCTree> attrs = htmlAttrs();
+ if (attrs != null) {
+ boolean selfClosing = false;
+ if (ch == '/') {
+ nextChar();
+ selfClosing = true;
+ }
+ if (ch == '>') {
+ nextChar();
+ Name name = names.fromChars(buf, namePos, nameLen);
+ return m.at(p).StartElement(name, attrs, selfClosing);
+ }
+ }
+ } else if (ch == '/') {
+ nextChar();
+ if (isIdentifierStart(ch)) {
+ int namePos = bp;
+ nextChar();
+ while (isIdentifierPart(ch))
+ nextChar();
+ int nameLen = bp - namePos;
+ skipWhitespace();
+ if (ch == '>') {
+ nextChar();
+ Name name = names.fromChars(buf, namePos, nameLen);
+ return m.at(p).EndElement(name);
+ }
+ }
+ } else if (ch == '!') {
+ nextChar();
+ if (ch == '-') {
+ nextChar();
+ if (ch == '-') {
+ nextChar();
+ while (bp < buflen) {
+ int dash = 0;
+ while (ch == '-') {
+ dash++;
+ nextChar();
+ }
+ // strictly speaking, a comment should not contain "--"
+ // so dash > 2 is an error, dash == 2 implies ch == '>'
+ if (dash >= 2 && ch == '>') {
+ nextChar();
+ return m.at(p).Comment(newString(p, bp));
+ }
+
+ nextChar();
+ }
+ }
+ }
+ }
+
+ bp = p + 1;
+ ch = buf[bp];
+ return erroneous("dc.malformed.html", p);
+ }
+
+ /**
+ * Read a series of HTML attributes, terminated by {@literal > }.
+ * Each attribute is of the form {@literal identifier[=value] }.
+ * "value" may be unquoted, single-quoted, or double-quoted.
+ */
+ protected List<DCTree> htmlAttrs() {
+ ListBuffer<DCTree> attrs = new ListBuffer<DCTree>();
+ skipWhitespace();
+
+ loop:
+ while (isIdentifierStart(ch)) {
+ int namePos = bp;
+ nextChar();
+ while (isIdentifierPart(ch))
+ nextChar();
+ int nameLen = bp - namePos;
+ skipWhitespace();
+ List<DCTree> value = null;
+ ValueKind vkind = ValueKind.EMPTY;
+ if (ch == '=') {
+ ListBuffer<DCTree> v = new ListBuffer<DCTree>();
+ nextChar();
+ skipWhitespace();
+ if (ch == '\'' || ch == '"') {
+ vkind = (ch == '\'') ? ValueKind.SINGLE : ValueKind.DOUBLE;
+ char quote = ch;
+ nextChar();
+ textStart = bp;
+ while (bp < buflen && ch != quote) {
+ if (newline && ch == '@') {
+ attrs.add(erroneous("dc.unterminated.string", namePos));
+ // No point trying to read more.
+ // In fact, all attrs get discarded by the caller
+ // and superseded by a malformed.html node because
+ // the html tag itself is not terminated correctly.
+ break loop;
+ }
+ attrValueChar(v);
+ }
+ addPendingText(v, bp - 1);
+ nextChar();
+ } else {
+ vkind = ValueKind.UNQUOTED;
+ textStart = bp;
+ while (bp < buflen && !isUnquotedAttrValueTerminator(ch)) {
+ attrValueChar(v);
+ }
+ addPendingText(v, bp - 1);
+ }
+ skipWhitespace();
+ value = v.toList();
+ }
+ Name name = names.fromChars(buf, namePos, nameLen);
+ DCAttribute attr = m.at(namePos).Attribute(name, vkind, value);
+ attrs.add(attr);
+ }
+
+ return attrs.toList();
+ }
+
+ protected void attrValueChar(ListBuffer<DCTree> list) {
+ switch (ch) {
+ case '&':
+ entity(list);
+ break;
+
+ case '{':
+ inlineTag(list);
+ break;
+
+ default:
+ nextChar();
+ }
+ }
+
+ protected void addPendingText(ListBuffer<DCTree> list, int textEnd) {
+ if (textStart != -1 && textStart <= textEnd) {
+ list.add(m.at(textStart).Text(newString(textStart, textEnd + 1)));
+ textStart = -1;
+ }
+ }
+
+ protected DCErroneous erroneous(String code, int pos) {
+ int i = bp - 1;
+ loop:
+ while (i > 0) {
+ switch (buf[i]) {
+ case '\f': case '\n': case '\r':
+ newline = true;
+ break;
+ case '\t': case ' ':
+ break;
+ default:
+ break loop;
+ }
+ i--;
+ }
+ textStart = -1;
+ return m.at(pos).Erroneous(newString(pos, i + 1), diagSource, code);
+ }
+
+ @SuppressWarnings("unchecked")
+ <T> T getFirst(List<T>... lists) {
+ for (List<T> list: lists) {
+ if (list.nonEmpty())
+ return list.head;
+ }
+ return null;
+ }
+
+ protected boolean isIdentifierStart(char ch) {
+ return Character.isUnicodeIdentifierStart(ch);
+ }
+
+ protected boolean isIdentifierPart(char ch) {
+ return Character.isUnicodeIdentifierPart(ch);
+ }
+
+ protected boolean isJavaIdentifierStart(char ch) {
+ return Character.isJavaIdentifierStart(ch);
+ }
+
+ protected boolean isJavaIdentifierPart(char ch) {
+ return Character.isJavaIdentifierPart(ch);
+ }
+
+ protected boolean isDecimalDigit(char ch) {
+ return ('0' <= ch && ch <= '9');
+ }
+
+ protected boolean isHexDigit(char ch) {
+ return ('0' <= ch && ch <= '9')
+ || ('a' <= ch && ch <= 'f')
+ || ('A' <= ch && ch <= 'F');
+ }
+
+ protected boolean isUnquotedAttrValueTerminator(char ch) {
+ switch (ch) {
+ case '\f': case '\n': case '\r': case '\t':
+ case ' ':
+ case '"': case '\'': case '`':
+ case '=': case '<': case '>':
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ protected boolean isWhitespace(char ch) {
+ return Character.isWhitespace(ch);
+ }
+
+ protected void skipWhitespace() {
+ while (isWhitespace(ch))
+ nextChar();
+ }
+
+ protected int getSentenceBreak(String s) {
+ if (sentenceBreaker != null) {
+ sentenceBreaker.setText(s);
+ int i = sentenceBreaker.next();
+ return (i == s.length()) ? -1 : i;
+ }
+
+ // scan for period followed by whitespace
+ boolean period = false;
+ for (int i = 0; i < s.length(); i++) {
+ switch (s.charAt(i)) {
+ case '.':
+ period = true;
+ break;
+
+ case ' ':
+ case '\f':
+ case '\n':
+ case '\r':
+ case '\t':
+ if (period)
+ return i;
+ break;
+
+ default:
+ period = false;
+ break;
+ }
+ }
+ return -1;
+ }
+
+
+ Set<String> htmlBlockTags = new HashSet<String>(Arrays.asList(
+ "h1", "h2", "h3", "h4", "h5", "h6", "p", "pre"));
+
+ protected boolean isSentenceBreak(Name n) {
+ return htmlBlockTags.contains(n.toString().toLowerCase());
+ }
+
+ protected boolean isSentenceBreak(DCTree t) {
+ switch (t.getKind()) {
+ case START_ELEMENT:
+ return isSentenceBreak(((DCStartElement) t).getName());
+
+ case END_ELEMENT:
+ return isSentenceBreak(((DCEndElement) t).getName());
+ }
+ return false;
+ }
+
+ /**
+ * @param start position of first character of string
+ * @param end position of character beyond last character to be included
+ */
+ String newString(int start, int end) {
+ return new String(buf, start, end - start);
+ }
+
+ static abstract class TagParser {
+ enum Kind { INLINE, BLOCK }
+
+ Kind kind;
+ DCTree.Kind treeKind;
+
+ TagParser(Kind k, DCTree.Kind tk) {
+ kind = k;
+ treeKind = tk;
+ }
+
+ Kind getKind() {
+ return kind;
+ }
+
+ DCTree.Kind getTreeKind() {
+ return treeKind;
+ }
+
+ abstract DCTree parse(int pos) throws ParseException;
+ }
+
+ /**
+ * @see <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javadoc.html#javadoctags">Javadoc Tags</a>
+ */
+ private void initTagParsers() {
+ TagParser[] parsers = {
+ // @author name-text
+ new TagParser(Kind.BLOCK, DCTree.Kind.AUTHOR) {
+ public DCTree parse(int pos) {
+ List<DCTree> name = blockContent();
+ return m.at(pos).Author(name);
+ }
+ },
+
+ // {@code text}
+ new TagParser(Kind.INLINE, DCTree.Kind.CODE) {
+ public DCTree parse(int pos) throws ParseException {
+ DCTree text = inlineText();
+ nextChar();
+ return m.at(pos).Code((DCText) text);
+ }
+ },
+
+ // @deprecated deprecated-text
+ new TagParser(Kind.BLOCK, DCTree.Kind.DEPRECATED) {
+ public DCTree parse(int pos) {
+ List<DCTree> reason = blockContent();
+ return m.at(pos).Deprecated(reason);
+ }
+ },
+
+ // {@docRoot}
+ new TagParser(Kind.INLINE, DCTree.Kind.DOC_ROOT) {
+ public DCTree parse(int pos) throws ParseException {
+ if (ch == '}') {
+ nextChar();
+ return m.at(pos).DocRoot();
+ }
+ inlineText(); // skip unexpected content
+ nextChar();
+ throw new ParseException("dc.unexpected.content");
+ }
+ },
+
+ // @exception class-name description
+ new TagParser(Kind.BLOCK, DCTree.Kind.EXCEPTION) {
+ public DCTree parse(int pos) throws ParseException {
+ skipWhitespace();
+ DCReference ref = reference(false);
+ List<DCTree> description = blockContent();
+ return m.at(pos).Exception(ref, description);
+ }
+ },
+
+ // {@inheritDoc}
+ new TagParser(Kind.INLINE, DCTree.Kind.INHERIT_DOC) {
+ public DCTree parse(int pos) throws ParseException {
+ if (ch == '}') {
+ nextChar();
+ return m.at(pos).InheritDoc();
+ }
+ inlineText(); // skip unexpected content
+ nextChar();
+ throw new ParseException("dc.unexpected.content");
+ }
+ },
+
+ // {@link package.class#member label}
+ new TagParser(Kind.INLINE, DCTree.Kind.LINK) {
+ public DCTree parse(int pos) throws ParseException {
+ DCReference ref = reference(true);
+ List<DCTree> label = inlineContent();
+ return m.at(pos).Link(ref, label);
+ }
+ },
+
+ // {@linkplain package.class#member label}
+ new TagParser(Kind.INLINE, DCTree.Kind.LINK_PLAIN) {
+ public DCTree parse(int pos) throws ParseException {
+ DCReference ref = reference(true);
+ List<DCTree> label = inlineContent();
+ return m.at(pos).LinkPlain(ref, label);
+ }
+ },
+
+ // {@literal text}
+ new TagParser(Kind.INLINE, DCTree.Kind.LITERAL) {
+ public DCTree parse(int pos) throws ParseException {
+ DCTree text = inlineText();
+ nextChar();
+ return m.at(pos).Literal((DCText) text);
+ }
+ },
+
+ // @param parameter-name description
+ new TagParser(Kind.BLOCK, DCTree.Kind.PARAM) {
+ public DCTree parse(int pos) throws ParseException {
+ skipWhitespace();
+
+ boolean typaram = false;
+ if (ch == '<') {
+ typaram = true;
+ nextChar();
+ }
+
+ DCIdentifier id = identifier();
+
+ if (typaram) {
+ if (ch != '>')
+ throw new ParseException("dc.gt.expected");
+ nextChar();
+ }
+
+ skipWhitespace();
+ List<DCTree> desc = blockContent();
+ return m.at(pos).Param(typaram, id, desc);
+ }
+ },
+
+ // @return description
+ new TagParser(Kind.BLOCK, DCTree.Kind.RETURN) {
+ public DCTree parse(int pos) {
+ List<DCTree> description = blockContent();
+ return m.at(pos).Return(description);
+ }
+ },
+
+ // @see reference | quoted-string | HTML
+ new TagParser(Kind.BLOCK, DCTree.Kind.SEE) {
+ public DCTree parse(int pos) throws ParseException {
+ skipWhitespace();
+ switch (ch) {
+ case '"':
+ DCText string = quotedString();
+ if (string != null) {
+ skipWhitespace();
+ if (ch == '@')
+ return m.at(pos).See(List.<DCTree>of(string));
+ }
+ break;
+
+ case '<':
+ List<DCTree> html = blockContent();
+ if (html != null)
+ return m.at(pos).See(html);
+ break;
+
+ default:
+ if (isJavaIdentifierStart(ch) || ch == '#') {
+ DCReference ref = reference(true);
+ List<DCTree> description = blockContent();
+ return m.at(pos).See(description.prepend(ref));
+ }
+ }
+ throw new ParseException("dc.unexpected.content");
+ }
+ },
+
+ // @serialData data-description
+ new TagParser(Kind.BLOCK, DCTree.Kind.SERIAL_DATA) {
+ public DCTree parse(int pos) {
+ List<DCTree> description = blockContent();
+ return m.at(pos).SerialData(description);
+ }
+ },
+
+ // @serialField field-name field-type description
+ new TagParser(Kind.BLOCK, DCTree.Kind.SERIAL_FIELD) {
+ public DCTree parse(int pos) throws ParseException {
+ skipWhitespace();
+ DCIdentifier name = identifier();
+ skipWhitespace();
+ DCReference type = reference(false);
+ List<DCTree> description = null;
+ if (isWhitespace(ch)) {
+ skipWhitespace();
+ description = blockContent();
+ }
+ return m.at(pos).SerialField(name, type, description);
+ }
+ },
+
+ // @serial field-description | include | exclude
+ new TagParser(Kind.BLOCK, DCTree.Kind.SERIAL) {
+ public DCTree parse(int pos) {
+ List<DCTree> description = blockContent();
+ return m.at(pos).Serial(description);
+ }
+ },
+
+ // @since since-text
+ new TagParser(Kind.BLOCK, DCTree.Kind.SINCE) {
+ public DCTree parse(int pos) {
+ List<DCTree> description = blockContent();
+ return m.at(pos).Since(description);
+ }
+ },
+
+ // @throws class-name description
+ new TagParser(Kind.BLOCK, DCTree.Kind.THROWS) {
+ public DCTree parse(int pos) throws ParseException {
+ skipWhitespace();
+ DCReference ref = reference(false);
+ List<DCTree> description = blockContent();
+ return m.at(pos).Throws(ref, description);
+ }
+ },
+
+ // {@value package.class#field}
+ new TagParser(Kind.INLINE, DCTree.Kind.VALUE) {
+ public DCTree parse(int pos) throws ParseException {
+ DCReference ref = reference(true);
+ skipWhitespace();
+ if (ch == '}') {
+ nextChar();
+ return m.at(pos).Value(ref);
+ }
+ nextChar();
+ throw new ParseException("dc.unexpected.content");
+ }
+ },
+
+ // @version version-text
+ new TagParser(Kind.BLOCK, DCTree.Kind.VERSION) {
+ public DCTree parse(int pos) {
+ List<DCTree> description = blockContent();
+ return m.at(pos).Version(description);
+ }
+ },
+ };
+
+ tagParsers = new HashMap<Name,TagParser>();
+ for (TagParser p: parsers)
+ tagParsers.put(names.fromString(p.getTreeKind().tagName), p);
+
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Fri Nov 30 17:09:05 2012 -0800
@@ -47,8 +47,8 @@
import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
+import static com.sun.tools.javac.tree.JCTree.Tag.*;
import static com.sun.tools.javac.util.ListBuffer.lb;
-import static com.sun.tools.javac.tree.JCTree.Tag.*;
/** The parser maps a token sequence into an abstract syntax
* tree. It operates by recursive descent, with code derived
@@ -88,6 +88,15 @@
/** End position mappings container */
private final AbstractEndPosTable endPosTable;
+ interface ErrorRecoveryAction {
+ JCTree doRecover(JavacParser parser);
+ }
+
+ enum BasicErrorRecoveryAction implements ErrorRecoveryAction {
+ BLOCK_STMT {public JCTree doRecover(JavacParser parser) { return parser.parseStatementAsBlock(); }},
+ CATCH_CLAUSE {public JCTree doRecover(JavacParser parser) { return parser.catchClause(); }}
+ }
+
/** Construct a parser from a given scanner, tree factory and log.
*/
protected JavacParser(ParserFactory fac,
@@ -112,14 +121,11 @@
this.allowDiamond = source.allowDiamond();
this.allowMulticatch = source.allowMulticatch();
this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
- this.allowLambda = source.allowLambda() &&
- fac.options.isSet("allowLambda"); //pre-lambda guard
- this.allowMethodReferences = source.allowMethodReferences() &&
- fac.options.isSet("allowMethodReferences"); //pre-lambda guard
- this.allowDefaultMethods = source.allowDefaultMethods() &&
- fac.options.isSet("allowDefaultMethods"); //pre-lambda guard
+ this.allowLambda = source.allowLambda();
+ this.allowMethodReferences = source.allowMethodReferences();
+ this.allowDefaultMethods = source.allowDefaultMethods();
this.keepDocComments = keepDocComments;
- docComments = newDocCommentTable(keepDocComments);
+ docComments = newDocCommentTable(keepDocComments, fac);
this.keepLineMap = keepLineMap;
this.errorTree = F.Erroneous();
endPosTable = newEndPosTable(keepEndPositions);
@@ -131,8 +137,8 @@
: new EmptyEndPosTable();
}
- protected DocCommentTable newDocCommentTable(boolean keepDocComments) {
- return keepDocComments ? new SimpleDocCommentTable() : null;
+ protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
+ return keepDocComments ? new LazyDocCommentTable(fac) : null;
}
/** Switch: Should generics be recognized?
@@ -223,7 +229,11 @@
protected Token token;
- protected void nextToken() {
+ public Token token() {
+ return token;
+ }
+
+ public void nextToken() {
S.nextToken();
token = S.token();
}
@@ -2102,11 +2112,15 @@
nextToken();
return toP(F.at(pos).Skip());
case ELSE:
- return toP(F.Exec(syntaxError("else.without.if")));
+ int elsePos = token.pos;
+ nextToken();
+ return doRecover(elsePos, BasicErrorRecoveryAction.BLOCK_STMT, "else.without.if");
case FINALLY:
- return toP(F.Exec(syntaxError("finally.without.try")));
+ int finallyPos = token.pos;
+ nextToken();
+ return doRecover(finallyPos, BasicErrorRecoveryAction.BLOCK_STMT, "finally.without.try");
case CATCH:
- return toP(F.Exec(syntaxError("catch.without.try")));
+ return doRecover(token.pos, BasicErrorRecoveryAction.CATCH_CLAUSE, "catch.without.try");
case ASSERT: {
if (allowAsserts && token.kind == ASSERT) {
nextToken();
@@ -2139,6 +2153,13 @@
}
}
+ private JCStatement doRecover(int startPos, ErrorRecoveryAction action, String key) {
+ int errPos = S.errPos();
+ JCTree stm = action.doRecover(this);
+ S.errPos(errPos);
+ return toP(F.Exec(syntaxError(startPos, List.<JCTree>of(stm), key)));
+ }
+
/** CatchClause = CATCH "(" FormalParameter ")" Block
*/
protected JCCatch catchClause() {
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java Fri Nov 30 17:09:05 2012 -0800
@@ -234,10 +234,12 @@
// If we find an exact match for pos, the other item in the pair
// gives the source pos; otherwise, compute the source position
// relative to the best match found in the array.
+ if (pos == Position.NOPOS)
+ return Position.NOPOS;
if (pos < 0 || pos >= docComment.length())
- throw new StringIndexOutOfBoundsException();
+ throw new StringIndexOutOfBoundsException(String.valueOf(pos));
if (docPosns == null)
- return -1;
+ return Position.NOPOS;
int start = 0;
int end = docPosns.length;
while (start < end - 2) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/LazyDocCommentTable.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1999, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.parser;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.sun.tools.javac.parser.Tokens.Comment;
+import com.sun.tools.javac.tree.DCTree.DCDocComment;
+import com.sun.tools.javac.tree.DocCommentTable;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.util.DiagnosticSource;
+
+
+/**
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class LazyDocCommentTable implements DocCommentTable {
+ private static class Entry {
+ final Comment comment;
+ DCDocComment tree;
+
+ Entry(Comment c) {
+ comment = c;
+ }
+ }
+
+ ParserFactory fac;
+ DiagnosticSource diagSource;
+ Map<JCTree, Entry> table;
+
+ LazyDocCommentTable(ParserFactory fac) {
+ this.fac = fac;
+ diagSource = fac.log.currentSource();
+ table = new HashMap<JCTree, Entry>();
+ }
+
+ public boolean hasComment(JCTree tree) {
+ return table.containsKey(tree);
+ }
+
+ public Comment getComment(JCTree tree) {
+ Entry e = table.get(tree);
+ return (e == null) ? null : e.comment;
+ }
+
+ public String getCommentText(JCTree tree) {
+ Comment c = getComment(tree);
+ return (c == null) ? null : c.getText();
+ }
+
+ public DCDocComment getCommentTree(JCTree tree) {
+ Entry e = table.get(tree);
+ if (e == null)
+ return null;
+ if (e.tree == null)
+ e.tree = new DocCommentParser(fac, diagSource, e.comment).parse();
+ return e.tree;
+ }
+
+ public void putComment(JCTree tree, Comment c) {
+ table.put(tree, new Entry(c));
+ }
+
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -25,7 +25,10 @@
package com.sun.tools.javac.parser;
+import java.util.Locale;
+
import com.sun.tools.javac.code.Source;
+import com.sun.tools.javac.tree.DocTreeMaker;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Log;
@@ -54,26 +57,30 @@
}
final TreeMaker F;
+ final DocTreeMaker docTreeMaker;
final Log log;
final Tokens tokens;
final Source source;
final Names names;
final Options options;
final ScannerFactory scannerFactory;
+ final Locale locale;
protected ParserFactory(Context context) {
super();
context.put(parserFactoryKey, this);
this.F = TreeMaker.instance(context);
+ this.docTreeMaker = DocTreeMaker.instance(context);
this.log = Log.instance(context);
this.names = Names.instance(context);
this.tokens = Tokens.instance(context);
this.source = Source.instance(context);
this.options = Options.instance(context);
this.scannerFactory = ScannerFactory.instance(context);
+ this.locale = context.get(Locale.class);
}
- public Parser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) {
+ public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) {
Lexer lexer = scannerFactory.newScanner(input, keepDocComments);
return new JavacParser(this, lexer, keepDocComments, keepLineMap, keepEndPos);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/SimpleDocCommentTable.java Fri Nov 30 12:39:37 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 1999, 2012, 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.javac.parser;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.sun.tools.javac.parser.Tokens.Comment;
-import com.sun.tools.javac.tree.DocCommentTable;
-import com.sun.tools.javac.tree.JCTree;
-
-
-/**
- *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own risk.
- * This code and its internal interfaces are subject to change or
- * deletion without notice.</b>
- */
-public class SimpleDocCommentTable implements DocCommentTable {
- Map<JCTree, Comment> table;
-
- SimpleDocCommentTable() {
- table = new HashMap<JCTree, Comment>();
- }
-
- public boolean hasComment(JCTree tree) {
- return table.containsKey(tree);
- }
-
- public Comment getComment(JCTree tree) {
- return table.get(tree);
- }
-
- public String getCommentText(JCTree tree) {
- Comment c = getComment(tree);
- return (c == null) ? null : c.getText();
- }
-
- public void putComment(JCTree tree, Comment c) {
- table.put(tree, c);
- }
-
-}
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Fri Nov 30 17:09:05 2012 -0800
@@ -145,6 +145,7 @@
Source source;
private ClassLoader processorClassLoader;
+ private SecurityException processorClassLoaderException;
/**
* JavacMessages object used for localization
@@ -155,7 +156,15 @@
private Context context;
- public JavacProcessingEnvironment(Context context, Iterable<? extends Processor> processors) {
+ /** Get the JavacProcessingEnvironment instance for this context. */
+ public static JavacProcessingEnvironment instance(Context context) {
+ JavacProcessingEnvironment instance = context.get(JavacProcessingEnvironment.class);
+ if (instance == null)
+ instance = new JavacProcessingEnvironment(context);
+ return instance;
+ }
+
+ protected JavacProcessingEnvironment(Context context) {
this.context = context;
log = Log.instance(context);
source = Source.instance(context);
@@ -184,6 +193,11 @@
unmatchedProcessorOptions = initUnmatchedProcessorOptions();
messages = JavacMessages.instance(context);
taskListener = MultiTaskListener.instance(context);
+ initProcessorClassLoader();
+ }
+
+ public void setProcessors(Iterable<? extends Processor> processors) {
+ Assert.checkNull(discoveredProcs);
initProcessorIterator(context, processors);
}
@@ -199,6 +213,23 @@
return Collections.unmodifiableSet(platformAnnotations);
}
+ private void initProcessorClassLoader() {
+ JavaFileManager fileManager = context.get(JavaFileManager.class);
+ try {
+ // If processorpath is not explicitly set, use the classpath.
+ processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
+ ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH)
+ : fileManager.getClassLoader(CLASS_PATH);
+
+ if (processorClassLoader != null && processorClassLoader instanceof Closeable) {
+ JavaCompiler compiler = JavaCompiler.instance(context);
+ compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader);
+ }
+ } catch (SecurityException e) {
+ processorClassLoaderException = e;
+ }
+ }
+
private void initProcessorIterator(Context context, Iterable<? extends Processor> processors) {
Log log = Log.instance(context);
Iterator<? extends Processor> processorIterator;
@@ -217,18 +248,7 @@
processorIterator = processors.iterator();
} else {
String processorNames = options.get(PROCESSOR);
- JavaFileManager fileManager = context.get(JavaFileManager.class);
- try {
- // If processorpath is not explicitly set, use the classpath.
- processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
- ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH)
- : fileManager.getClassLoader(CLASS_PATH);
-
- if (processorClassLoader != null && processorClassLoader instanceof Closeable) {
- JavaCompiler compiler = JavaCompiler.instance(context);
- compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader);
- }
-
+ if (processorClassLoaderException == null) {
/*
* If the "-processor" option is used, search the appropriate
* path for the named class. Otherwise, use a service
@@ -239,14 +259,15 @@
} else {
processorIterator = new ServiceIterator(processorClassLoader, log);
}
- } catch (SecurityException e) {
+ } else {
/*
* A security exception will occur if we can't create a classloader.
* Ignore the exception if, with hindsight, we didn't need it anyway
* (i.e. no processor was specified either explicitly, or implicitly,
* in service configuration file.) Otherwise, we cannot continue.
*/
- processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader", e);
+ processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader",
+ processorClassLoaderException);
}
}
discoveredProcs = new DiscoveredProcessors(processorIterator);
@@ -781,6 +802,8 @@
final JavaCompiler compiler;
/** The log for the round. */
final Log log;
+ /** The diagnostic handler for the round. */
+ final Log.DeferredDiagnosticHandler deferredDiagnosticHandler;
/** The ASTs to be compiled. */
List<JCCompilationUnit> roots;
@@ -798,7 +821,8 @@
int nMessagerErrors;
/** Create a round (common code). */
- private Round(Context context, int number, int priorErrors, int priorWarnings) {
+ private Round(Context context, int number, int priorErrors, int priorWarnings,
+ Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
this.context = context;
this.number = number;
@@ -806,7 +830,12 @@
log = Log.instance(context);
log.nerrors = priorErrors;
log.nwarnings += priorWarnings;
- log.deferAll();
+ if (number == 1) {
+ Assert.checkNonNull(deferredDiagnosticHandler);
+ this.deferredDiagnosticHandler = deferredDiagnosticHandler;
+ } else {
+ this.deferredDiagnosticHandler = new Log.DeferredDiagnosticHandler(log);
+ }
// the following is for the benefit of JavacProcessingEnvironment.getContext()
JavacProcessingEnvironment.this.context = context;
@@ -817,8 +846,9 @@
}
/** Create the first round. */
- Round(Context context, List<JCCompilationUnit> roots, List<ClassSymbol> classSymbols) {
- this(context, 1, 0, 0);
+ Round(Context context, List<JCCompilationUnit> roots, List<ClassSymbol> classSymbols,
+ Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
+ this(context, 1, 0, 0, deferredDiagnosticHandler);
this.roots = roots;
genClassFiles = new HashMap<String,JavaFileObject>();
@@ -841,7 +871,8 @@
this(prev.nextContext(),
prev.number+1,
prev.nMessagerErrors,
- prev.compiler.log.nwarnings);
+ prev.compiler.log.nwarnings,
+ null);
this.genClassFiles = prev.genClassFiles;
List<JCCompilationUnit> parsedFiles = compiler.parseFiles(newSourceFiles);
@@ -912,7 +943,7 @@
if (messager.errorRaised())
return true;
- for (JCDiagnostic d: log.deferredDiagnostics) {
+ for (JCDiagnostic d: deferredDiagnosticHandler.getDiagnostics()) {
switch (d.getKind()) {
case WARNING:
if (werror)
@@ -1006,7 +1037,8 @@
// suppress errors, which are all presumed to be transient resolve errors
kinds.remove(JCDiagnostic.Kind.ERROR);
}
- log.reportDeferredDiagnostics(kinds);
+ deferredDiagnosticHandler.reportDeferredDiagnostics(kinds);
+ log.popDiagnosticHandler(deferredDiagnosticHandler);
}
/** Print info about this round. */
@@ -1112,7 +1144,8 @@
public JavaCompiler doProcessing(Context context,
List<JCCompilationUnit> roots,
List<ClassSymbol> classSymbols,
- Iterable<? extends PackageSymbol> pckSymbols) {
+ Iterable<? extends PackageSymbol> pckSymbols,
+ Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
log = Log.instance(context);
Set<PackageSymbol> specifiedPackages = new LinkedHashSet<PackageSymbol>();
@@ -1120,7 +1153,7 @@
specifiedPackages.add(psym);
this.specifiedPackages = Collections.unmodifiableSet(specifiedPackages);
- Round round = new Round(context, roots, classSymbols);
+ Round round = new Round(context, roots, classSymbols, deferredDiagnosticHandler);
boolean errorStatus;
boolean moreToDo;
@@ -1461,13 +1494,19 @@
}
/**
- * For internal use only. This method will be
- * removed without warning.
+ * For internal use only. This method may be removed without warning.
*/
public Context getContext() {
return context;
}
+ /**
+ * For internal use only. This method may be removed without warning.
+ */
+ public ClassLoader getProcessorClassLoader() {
+ return processorClassLoader;
+ }
+
public String toString() {
return "javac ProcessingEnvironment";
}
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Nov 30 17:09:05 2012 -0800
@@ -170,19 +170,6 @@
compiler.misc.cant.apply.symbols=\
no suitable {0} found for {1}({2})
-
-# 0: type
-compiler.err.cant.access.arg.type.in.functional.desc=\
- cannot access parameter type {0} in target functional descriptor
-
-# 0: type
-compiler.err.cant.access.return.in.functional.desc=\
- cannot access return type {0} in target functional descriptor
-
-# 0: type
-compiler.err.cant.access.thrown.in.functional.desc=\
- cannot access thrown type {0} in target functional descriptor
-
# 0: symbol kind, 1: symbol
compiler.misc.no.abstracts=\
no abstract method found in {0} {1}
@@ -257,9 +244,6 @@
compiler.err.cant.ref.before.ctor.called=\
cannot reference {0} before supertype constructor has been called
-compiler.err.cant.ret.val.from.meth.decl.void=\
- cannot return a value from method whose result type is void
-
compiler.err.cant.select.static.class.from.param.type=\
cannot select a static class from a parameterized type
@@ -574,7 +558,7 @@
interface expected here
compiler.err.intf.meth.cant.have.body=\
- interface methods cannot have body
+ interface abstract methods cannot have body
compiler.err.invalid.annotation.member.type=\
invalid type for annotation member
@@ -661,8 +645,8 @@
compiler.misc.missing.ret.val=\
missing return value
-compiler.err.missing.ret.val=\
- missing return value
+compiler.misc.unexpected.ret.val=\
+ unexpected return value
# 0: set of modifier
compiler.err.mod.not.allowed.here=\
@@ -708,6 +692,9 @@
compiler.misc.incompatible.type.in.conditional=\
bad type in conditional expression; {0}
+compiler.misc.conditional.target.cant.be.void=\
+ target-type for conditional expression cannot be void
+
# 0: type
compiler.misc.incompatible.ret.type.in.lambda=\
bad return type in lambda expression\n\
@@ -941,6 +928,31 @@
compiler.err.types.incompatible.diff.ret=\
types {0} and {1} are incompatible; both define {2}, but with unrelated return types
+# 0: kind, 1: type, 2: name, 3: list of type, 4: symbol, 5: symbol
+compiler.err.types.incompatible.unrelated.defaults=\
+ {0} {1} inherits unrelated defaults for {2}({3}) from types {4} and {5}
+
+# 0: kind, 1: type, 2: name, 3: list of type, 4: symbol, 5: symbol
+compiler.err.types.incompatible.abstract.default=\
+ {0} {1} inherits abstract and default for {2}({3}) from types {4} and {5}
+
+# 0: name, 1: kind, 2: symbol
+compiler.err.default.overrides.object.member=\
+ default method {0} in {1} {2} overrides a member of java.lang.Object
+
+# 0: type, 1: message segment
+compiler.err.illegal.default.super.call=\
+ bad type qualifier {0} in default super call\n\
+ {1}
+
+# 0: symbol, 1: type
+compiler.misc.overridden.default=\
+ method {0} is overridden in {1}
+
+# 0: symbol, 1: symbol
+compiler.misc.redundant.supertype=\
+ redundant interface {0} is extended by {1}
+
compiler.err.unclosed.char.lit=\
unclosed character literal
@@ -2311,4 +2323,52 @@
compiler.misc.where.description.intersection.1=\
where {0} are intersection types:
-
+###
+# errors related to doc comments
+
+compiler.err.dc.bad.entity=\
+ bad HTML entity
+
+compiler.err.dc.bad.gt=\
+ bad use of ''>''
+
+compiler.err.dc.bad.inline.tag=\
+ incorrect use of inline tag
+
+compiler.err.dc.identifier.expected=\
+ identifier expected
+
+compiler.err.dc.malformed.html=\
+ malformed HTML
+
+compiler.err.dc.missing.semicolon=\
+ semicolon missing
+
+compiler.err.dc.no.tag.name=\
+ no tag name after '@'
+
+compiler.err.dc.gt.expected=\
+ ''>'' expected
+
+compiler.err.dc.ref.bad.parens=\
+ '')'' missing in reference
+
+compiler.err.dc.ref.syntax.error=\
+ syntax error in reference
+
+compiler.err.dc.ref.unexpected.input=\
+ unexpected text
+
+compiler.err.dc.unexpected.content=\
+ unexpected content
+
+compiler.err.dc.unterminated.inline.tag=\
+ unterminated inline tag
+
+compiler.err.dc.unterminated.signature=\
+ unterminated signature
+
+compiler.err.dc.unterminated.string=\
+ unterminated string
+
+
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties Fri Nov 30 17:09:05 2012 -0800
@@ -99,6 +99,10 @@
<release>
javac.opt.arg.number=\
<number>
+javac.opt.plugin=\
+ Name and optional arguments for a plug-in to be run
+javac.opt.arg.plugin=\
+ "name args"
## extended options
@@ -185,6 +189,8 @@
not a directory: {0}
javac.err.file.not.file=\
not a file: {0}
+javac.msg.plugin.not.found=\
+ plug-in not found: {0}
## messages
javac.msg.usage.header=\
@@ -212,6 +218,10 @@
\n\nAn annotation processor threw an uncaught exception.\n\
Consult the following stack trace for details.\n
+javac.msg.plugin.uncaught.exception=\
+\n\nA plugin threw an uncaught exception.\n\
+Consult the following stack trace for details.\n
+
javac.msg.resource=\
\n\nThe system is out of resources.\n\
Consult the following stack trace for details.\n
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/DCTree.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,848 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.tree;
+
+
+import javax.tools.Diagnostic;
+
+import com.sun.source.doctree.*;
+import com.sun.tools.javac.parser.Tokens.Comment;
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.DiagnosticSource;
+import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.Name;
+import javax.tools.JavaFileObject;
+
+/**
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public abstract class DCTree implements DocTree {
+
+ /**
+ * The position in the comment string.
+ * Use {@link #getSourcePosition getSourcePosition} to convert
+ * it to a position in the source file.
+ *
+ * TODO: why not simply translate all these values into
+ * source file positions? Is it useful to have string-offset
+ * positions as well?
+ */
+ public int pos;
+
+ public long getSourcePosition(DCDocComment dc) {
+ return dc.comment.getSourcePos(pos);
+ }
+
+ public JCDiagnostic.DiagnosticPosition pos(DCDocComment dc) {
+ return new SimpleDiagnosticPosition(dc.comment.getSourcePos(pos));
+ }
+
+ public static class DCDocComment extends DCTree implements DocCommentTree {
+ final Comment comment; // required for the implicit source pos table
+
+ public final List<DCTree> firstSentence;
+ public final List<DCTree> body;
+ public final List<DCTree> tags;
+
+ public DCDocComment(Comment comment,
+ List<DCTree> firstSentence, List<DCTree> body, List<DCTree> tags) {
+ this.comment = comment;
+ this.firstSentence = firstSentence;
+ this.body = body;
+ this.tags = tags;
+ }
+
+ public Kind getKind() {
+ return Kind.DOC_COMMENT;
+ }
+
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitDocComment(this, d);
+ }
+
+ public List<? extends DocTree> getFirstSentence() {
+ return firstSentence;
+ }
+
+ public List<? extends DocTree> getBody() {
+ return body;
+ }
+
+ public List<? extends DocTree> getBlockTags() {
+ return tags;
+ }
+
+ }
+
+ public static abstract class DCBlockTag extends DCTree implements InlineTagTree {
+ public String getTagName() {
+ return getKind().tagName;
+ }
+ }
+
+ public static abstract class DCInlineTag extends DCTree implements InlineTagTree {
+ public String getTagName() {
+ return getKind().tagName;
+ }
+ }
+
+ public static class DCAttribute extends DCTree implements AttributeTree {
+ public final Name name;
+ public final ValueKind vkind;
+ public final List<DCTree> value;
+
+ DCAttribute(Name name, ValueKind vkind, List<DCTree> value) {
+ Assert.check((vkind == ValueKind.EMPTY) ? (value == null) : (value != null));
+ this.name = name;
+ this.vkind = vkind;
+ this.value = value;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.ATTRIBUTE;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitAttribute(this, d);
+ }
+
+ @Override
+ public Name getName() {
+ return name;
+ }
+
+ @Override
+ public ValueKind getValueKind() {
+ return vkind;
+ }
+
+ @Override
+ public List<DCTree> getValue() {
+ return value;
+ }
+ }
+
+ public static class DCAuthor extends DCInlineTag implements AuthorTree {
+ public final List<DCTree> name;
+
+ DCAuthor(List<DCTree> name) {
+ this.name = name;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.AUTHOR;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitAuthor(this, d);
+ }
+
+ @Override
+ public List<? extends DocTree> getName() {
+ return name;
+ }
+ }
+
+ public static class DCComment extends DCTree implements CommentTree {
+ public final String body;
+
+ DCComment(String body) {
+ this.body = body;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.COMMENT;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitComment(this, d);
+ }
+
+ @Override
+ public String getBody() {
+ return body;
+ }
+ }
+
+ public static class DCDeprecated extends DCBlockTag implements DeprecatedTree {
+ public final List<DCTree> body;
+
+ DCDeprecated(List<DCTree> body) {
+ this.body = body;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.DEPRECATED;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitDeprecated(this, d);
+ }
+
+ @Override
+ public List<? extends DocTree> getBody() {
+ return body;
+ }
+ }
+
+ public static class DCDocRoot extends DCInlineTag implements DocRootTree {
+
+ @Override
+ public Kind getKind() {
+ return Kind.DOC_ROOT;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitDocRoot(this, d);
+ }
+ }
+
+ public static class DCEndElement extends DCTree implements EndElementTree {
+ public final Name name;
+
+ DCEndElement(Name name) {
+ this.name = name;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.END_ELEMENT;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitEndElement(this, d);
+ }
+
+ @Override
+ public Name getName() {
+ return name;
+ }
+ }
+
+ public static class DCEntity extends DCTree implements EntityTree {
+ public final Name name;
+
+ DCEntity(Name name) {
+ this.name = name;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.ENTITY;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitEntity(this, d);
+ }
+
+ @Override
+ public Name getName() {
+ return name;
+ }
+ }
+
+ public static class DCErroneous extends DCTree implements ErroneousTree, JCDiagnostic.DiagnosticPosition {
+ public final String body;
+ public final JCDiagnostic diag;
+
+ DCErroneous(String body, JCDiagnostic.Factory diags, DiagnosticSource diagSource, String code, Object... args) {
+ this.body = body;
+ this.diag = diags.error(diagSource, this, code, args);
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.ERRONEOUS;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitErroneous(this, d);
+ }
+
+ @Override
+ public String getBody() {
+ return body;
+ }
+
+ @Override
+ public Diagnostic<JavaFileObject> getDiagnostic() {
+ return diag;
+ }
+
+ @Override
+ public JCTree getTree() {
+ return null;
+ }
+
+ @Override
+ public int getStartPosition() {
+ return pos;
+ }
+
+ @Override
+ public int getPreferredPosition() {
+ return pos + body.length() - 1;
+ }
+
+ @Override
+ public int getEndPosition(EndPosTable endPosTable) {
+ return pos + body.length();
+ }
+ }
+
+ public static class DCIdentifier extends DCTree implements IdentifierTree {
+ public final Name name;
+
+ DCIdentifier(Name name) {
+ this.name = name;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.IDENTIFIER;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitIdentifier(this, d);
+ }
+
+ @Override
+ public Name getName() {
+ return name;
+ }
+ }
+
+ public static class DCInheritDoc extends DCInlineTag implements InheritDocTree {
+ @Override
+ public Kind getKind() {
+ return Kind.INHERIT_DOC;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitInheritDoc(this, d);
+ }
+ }
+
+ public static class DCLink extends DCInlineTag implements LinkTree {
+ public final Kind kind;
+ public final DCReference ref;
+ public final List<DCTree> label;
+
+ DCLink(Kind kind, DCReference ref, List<DCTree> label) {
+ Assert.check(kind == Kind.LINK || kind == Kind.LINK_PLAIN);
+ this.kind = kind;
+ this.ref = ref;
+ this.label = label;
+ }
+
+ @Override
+ public Kind getKind() {
+ return kind;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitLink(this, d);
+ }
+
+ @Override
+ public ReferenceTree getReference() {
+ return ref;
+ }
+
+ @Override
+ public List<? extends DocTree> getLabel() {
+ return label;
+ }
+ }
+
+ public static class DCLiteral extends DCInlineTag implements LiteralTree {
+ public final Kind kind;
+ public final DCText body;
+
+ DCLiteral(Kind kind, DCText body) {
+ Assert.check(kind == Kind.CODE || kind == Kind.LITERAL);
+ this.kind = kind;
+ this.body = body;
+ }
+
+ @Override
+ public Kind getKind() {
+ return kind;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitLiteral(this, d);
+ }
+
+ @Override
+ public DCText getBody() {
+ return body;
+ }
+ }
+
+ public static class DCParam extends DCBlockTag implements ParamTree {
+ public final boolean isTypeParameter;
+ public final DCIdentifier name;
+ public final List<DCTree> description;
+
+ DCParam(boolean isTypeParameter, DCIdentifier name, List<DCTree> description) {
+ this.isTypeParameter = isTypeParameter;
+ this.name = name;
+ this.description = description;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.PARAM;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitParam(this, d);
+ }
+
+ @Override
+ public boolean isTypeParameter() {
+ return isTypeParameter;
+ }
+
+ @Override
+ public IdentifierTree getName() {
+ return name;
+ }
+
+ @Override
+ public List<? extends DocTree> getDescription() {
+ return description;
+ }
+ }
+
+ public static class DCReference extends DCTree implements ReferenceTree {
+ public final String signature;
+
+ // The following are not directly exposed through ReferenceTree
+ // use DocTrees.getElement(TreePath,ReferenceTree)
+ public final JCTree qualifierExpression;
+ public final Name memberName;
+ public final List<JCTree> paramTypes;
+
+
+ DCReference(String signature, JCTree qualExpr, Name member, List<JCTree> paramTypes) {
+ this.signature = signature;
+ qualifierExpression = qualExpr;
+ memberName = member;
+ this.paramTypes = paramTypes;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.REFERENCE;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitReference(this, d);
+ }
+
+ @Override
+ public String getSignature() {
+ return signature;
+ }
+ }
+
+ public static class DCReturn extends DCBlockTag implements ReturnTree {
+ public final List<DCTree> description;
+
+ DCReturn(List<DCTree> description) {
+ this.description = description;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.RETURN;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitReturn(this, d);
+ }
+
+ @Override
+ public List<? extends DocTree> getDescription() {
+ return description;
+ }
+ }
+
+ public static class DCSee extends DCBlockTag implements SeeTree {
+ public final List<DCTree> reference;
+
+ DCSee(List<DCTree> reference) {
+ this.reference = reference;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.SEE;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitSee(this, d);
+ }
+
+ @Override
+ public List<? extends DocTree> getReference() {
+ return reference;
+ }
+ }
+
+ public static class DCSerial extends DCBlockTag implements SerialTree {
+ public final List<DCTree> description;
+
+ DCSerial(List<DCTree> description) {
+ this.description = description;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.SERIAL;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitSerial(this, d);
+ }
+
+ @Override
+ public List<? extends DocTree> getDescription() {
+ return description;
+ }
+ }
+
+ public static class DCSerialData extends DCBlockTag implements SerialDataTree {
+ public final List<DCTree> description;
+
+ DCSerialData(List<DCTree> description) {
+ this.description = description;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.SERIAL_DATA;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitSerialData(this, d);
+ }
+
+ @Override
+ public List<? extends DocTree> getDescription() {
+ return description;
+ }
+ }
+
+ public static class DCSerialField extends DCBlockTag implements SerialFieldTree {
+ public final DCIdentifier name;
+ public final DCReference type;
+ public final List<DCTree> description;
+
+ DCSerialField(DCIdentifier name, DCReference type, List<DCTree> description) {
+ this.description = description;
+ this.name = name;
+ this.type = type;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.SERIAL_FIELD;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitSerialField(this, d);
+ }
+
+ @Override
+ public List<? extends DocTree> getDescription() {
+ return description;
+ }
+
+ @Override
+ public IdentifierTree getName() {
+ return name;
+ }
+
+ @Override
+ public ReferenceTree getType() {
+ return type;
+ }
+ }
+
+ public static class DCSince extends DCInlineTag implements SinceTree {
+ public final List<DCTree> body;
+
+ DCSince(List<DCTree> body) {
+ this.body = body;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.SINCE;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitSince(this, d);
+ }
+
+ @Override
+ public List<? extends DocTree> getBody() {
+ return body;
+ }
+ }
+
+ public static class DCStartElement extends DCTree implements StartElementTree {
+ public final Name name;
+ public final List<DCTree> attrs;
+ public final boolean selfClosing;
+
+ DCStartElement(Name name, List<DCTree> attrs, boolean selfClosing) {
+ this.name = name;
+ this.attrs = attrs;
+ this.selfClosing = selfClosing;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.START_ELEMENT;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitStartElement(this, d);
+ }
+
+ @Override
+ public Name getName() {
+ return name;
+ }
+
+ @Override
+ public List<? extends DocTree> getAttributes() {
+ return attrs;
+ }
+
+ @Override
+ public boolean isSelfClosing() {
+ return selfClosing;
+ }
+ }
+
+ public static class DCText extends DCTree implements TextTree {
+ public final String text;
+
+ DCText(String text) {
+ this.text = text;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.TEXT;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitText(this, d);
+ }
+
+ @Override
+ public String getBody() {
+ return text;
+ }
+ }
+
+ public static class DCThrows extends DCBlockTag implements ThrowsTree {
+ public final Kind kind;
+ public final DCReference name;
+ public final List<DCTree> description;
+
+ DCThrows(Kind kind, DCReference name, List<DCTree> description) {
+ Assert.check(kind == Kind.EXCEPTION || kind == Kind.THROWS);
+ this.kind = kind;
+ this.name = name;
+ this.description = description;
+ }
+
+ @Override
+ public Kind getKind() {
+ return kind;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitThrows(this, d);
+ }
+
+ @Override
+ public ReferenceTree getExceptionName() {
+ return name;
+ }
+
+ @Override
+ public List<? extends DocTree> getDescription() {
+ return description;
+ }
+ }
+
+ public static class DCUnknownBlockTag extends DCBlockTag implements UnknownBlockTagTree {
+ public final Name name;
+ public final List<DCTree> content;
+
+ DCUnknownBlockTag(Name name, List<DCTree> content) {
+ this.name = name;
+ this.content = content;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.UNKNOWN_BLOCK_TAG;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitUnknownBlockTag(this, d);
+ }
+
+ @Override
+ public String getTagName() {
+ return name.toString();
+ }
+
+ @Override
+ public List<? extends DocTree> getContent() {
+ return content;
+ }
+ }
+
+ public static class DCUnknownInlineTag extends DCInlineTag implements UnknownInlineTagTree {
+ public final Name name;
+ public final List<DCTree> content;
+
+ DCUnknownInlineTag(Name name, List<DCTree> content) {
+ this.name = name;
+ this.content = content;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.UNKNOWN_INLINE_TAG;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitUnknownInlineTag(this, d);
+ }
+
+ @Override
+ public String getTagName() {
+ return name.toString();
+ }
+
+ @Override
+ public List<? extends DocTree> getContent() {
+ return content;
+ }
+ }
+
+ public static class DCValue extends DCInlineTag implements ValueTree {
+ public final DCReference ref;
+
+ DCValue(DCReference ref) {
+ this.ref = ref;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.VALUE;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitValue(this, d);
+ }
+
+ @Override
+ public ReferenceTree getReference() {
+ return ref;
+ }
+ }
+
+ public static class DCVersion extends DCBlockTag implements VersionTree {
+ public final List<DCTree> body;
+
+ DCVersion(List<DCTree> body) {
+ this.body = body;
+ }
+
+ @Override
+ public Kind getKind() {
+ return Kind.VERSION;
+ }
+
+ @Override
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitVersion(this, d);
+ }
+
+ @Override
+ public List<? extends DocTree> getBody() {
+ return body;
+ }
+ }
+
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/DocCommentTable.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/DocCommentTable.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,9 @@
*/
package com.sun.tools.javac.tree;
+import com.sun.source.doctree.ErroneousTree;
import com.sun.tools.javac.parser.Tokens.Comment;
+import com.sun.tools.javac.tree.DCTree.DCDocComment;
/**
* A table giving the doc comment, if any, for any tree node.
@@ -51,6 +53,13 @@
public String getCommentText(JCTree tree);
/**
+ * Get the parsed form of the doc comment as a DocTree. If any errors
+ * are detected during parsing, they will be reported via
+ * {@link ErroneousTree ErroneousTree} nodes within the resulting tree.
+ */
+ public DCDocComment getCommentTree(JCTree tree);
+
+ /**
* Set the Comment to be associated with a tree node.
*/
public void putComment(JCTree tree, Comment c);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/DocPretty.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 1999, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.tree;
+
+import java.io.Writer;
+
+import com.sun.source.doctree.*;
+import com.sun.source.doctree.AttributeTree.ValueKind;
+import com.sun.tools.javac.util.Convert;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Prints out a doc comment tree.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class DocPretty implements DocTreeVisitor<Void,Void> {
+
+ /**
+ * The output stream on which trees are printed.
+ */
+ final Writer out;
+
+ /**
+ * The left margin.
+ */
+ int lmargin = 0;
+
+ public DocPretty(Writer out) {
+ this.out = out;
+ }
+
+ /** Visitor method: print expression tree.
+ */
+ public void print(DocTree tree) throws IOException {
+ try {
+ if (tree == null)
+ print("/*missing*/");
+ else {
+ tree.accept(this, null);
+ }
+ } catch (UncheckedIOException ex) {
+ throw new IOException(ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Print string, replacing all non-ascii character with unicode escapes.
+ */
+ protected void print(Object s) throws IOException {
+ out.write(Convert.escapeUnicode(s.toString()));
+ }
+
+ /**
+ * Print list.
+ */
+ protected void print(List<? extends DocTree> list) throws IOException {
+ for (DocTree t: list) {
+ print(t);
+ }
+ }
+
+ /**
+ * Print list., with separators
+ */
+ protected void print(List<? extends DocTree> list, String sep) throws IOException {
+ if (list.isEmpty())
+ return;
+ boolean first = true;
+ for (DocTree t: list) {
+ if (!first)
+ print(sep);
+ print(t);
+ first = false;
+ }
+ }
+
+ /** Print new line.
+ */
+ protected void println() throws IOException {
+ out.write(lineSep);
+ }
+
+ protected void printTagName(DocTree node) throws IOException {
+ out.write("@");
+ out.write(node.getKind().tagName);
+ }
+
+ final String lineSep = System.getProperty("line.separator");
+
+ /**************************************************************************
+ * Traversal methods
+ *************************************************************************/
+
+ /** Exception to propagate IOException through visitXXX methods */
+ private static class UncheckedIOException extends Error {
+ static final long serialVersionUID = -4032692679158424751L;
+ UncheckedIOException(IOException e) {
+ super(e.getMessage(), e);
+ }
+ }
+
+
+ public Void visitAttribute(AttributeTree node, Void p) {
+ try {
+ print(node.getName());
+ String quote;
+ switch (node.getValueKind()) {
+ case EMPTY:
+ quote = null;
+ break;
+ case UNQUOTED:
+ quote = "";
+ break;
+ case SINGLE:
+ quote = "'";
+ break;
+ case DOUBLE:
+ quote = "\"";
+ break;
+ default:
+ throw new AssertionError();
+ }
+ if (quote != null) {
+ print("=" + quote);
+ print(node.getValue());
+ print(quote);
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitAuthor(AuthorTree node, Void p) {
+ try {
+ printTagName(node);
+ print(" ");
+ print(node.getName());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitComment(CommentTree node, Void p) {
+ try {
+ print(node.getBody());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitDeprecated(DeprecatedTree node, Void p) {
+ try {
+ printTagName(node);
+ if (!node.getBody().isEmpty()) {
+ print(" ");
+ print(node.getBody());
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitDocComment(DocCommentTree node, Void p) {
+ try {
+ List<? extends DocTree> fs = node.getFirstSentence();
+ List<? extends DocTree> b = node.getBody();
+ List<? extends DocTree> t = node.getBlockTags();
+ print(fs);
+ if (!fs.isEmpty() && !b.isEmpty())
+ print(" ");
+ print(b);
+ if ((!fs.isEmpty() || !b.isEmpty()) && !t.isEmpty())
+ print("\n");
+ print(t, "\n");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitDocRoot(DocRootTree node, Void p) {
+ try {
+ print("{");
+ printTagName(node);
+ print("}");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitEndElement(EndElementTree node, Void p) {
+ try {
+ print("</");
+ print(node.getName());
+ print(">");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitEntity(EntityTree node, Void p) {
+ try {
+ print("&");
+ print(node.getName());
+ print(";");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitErroneous(ErroneousTree node, Void p) {
+ try {
+ print(node.getBody());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitIdentifier(IdentifierTree node, Void p) {
+ try {
+ print(node.getName());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitInheritDoc(InheritDocTree node, Void p) {
+ try {
+ print("{");
+ printTagName(node);
+ print("}");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitLink(LinkTree node, Void p) {
+ try {
+ print("{");
+ printTagName(node);
+ print(" ");
+ print(node.getReference());
+ if (!node.getLabel().isEmpty()) {
+ print(" ");
+ print(node.getLabel());
+ }
+ print("}");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitLiteral(LiteralTree node, Void p) {
+ try {
+ print("{");
+ printTagName(node);
+ print(" ");
+ print(node.getBody());
+ print("}");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitParam(ParamTree node, Void p) {
+ try {
+ printTagName(node);
+ print(" ");
+ if (node.isTypeParameter()) print("<");
+ print(node.getName());
+ if (node.isTypeParameter()) print(">");
+ if (!node.getDescription().isEmpty()) {
+ print(" ");
+ print(node.getDescription());
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitReference(ReferenceTree node, Void p) {
+ try {
+ print(node.getSignature());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitReturn(ReturnTree node, Void p) {
+ try {
+ printTagName(node);
+ print(" ");
+ print(node.getDescription());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitSee(SeeTree node, Void p) {
+ try {
+ printTagName(node);
+ boolean first = true;
+ boolean needSep = true;
+ for (DocTree t: node.getReference()) {
+ if (needSep) print(" ");
+ needSep = (first && (t instanceof ReferenceTree));
+ first = false;
+ print(t);
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitSerial(SerialTree node, Void p) {
+ try {
+ printTagName(node);
+ if (!node.getDescription().isEmpty()) {
+ print(" ");
+ print(node.getDescription());
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitSerialData(SerialDataTree node, Void p) {
+ try {
+ printTagName(node);
+ if (!node.getDescription().isEmpty()) {
+ print(" ");
+ print(node.getDescription());
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitSerialField(SerialFieldTree node, Void p) {
+ try {
+ printTagName(node);
+ print(" ");
+ print(node.getName());
+ print(" ");
+ print(node.getType());
+ if (!node.getDescription().isEmpty()) {
+ print(" ");
+ print(node.getDescription());
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitSince(SinceTree node, Void p) {
+ try {
+ printTagName(node);
+ print(" ");
+ print(node.getBody());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitStartElement(StartElementTree node, Void p) {
+ try {
+ print("<");
+ print(node.getName());
+ List<? extends DocTree> attrs = node.getAttributes();
+ if (!attrs.isEmpty()) {
+ print(" ");
+ print(attrs);
+ DocTree last = node.getAttributes().get(attrs.size() - 1);
+ if (node.isSelfClosing() && last instanceof AttributeTree
+ && ((AttributeTree) last).getValueKind() == ValueKind.UNQUOTED)
+ print(" ");
+ }
+ if (node.isSelfClosing())
+ print("/");
+ print(">");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitText(TextTree node, Void p) {
+ try {
+ print(node.getBody());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitThrows(ThrowsTree node, Void p) {
+ try {
+ printTagName(node);
+ print(" ");
+ print(node.getExceptionName());
+ if (!node.getDescription().isEmpty()) {
+ print(" ");
+ print(node.getDescription());
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitUnknownBlockTag(UnknownBlockTagTree node, Void p) {
+ try {
+ print("@");
+ print(node.getTagName());
+ print(" ");
+ print(node.getContent());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitUnknownInlineTag(UnknownInlineTagTree node, Void p) {
+ try {
+ print("{");
+ print("@");
+ print(node.getTagName());
+ print(" ");
+ print(node.getContent());
+ print("}");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitValue(ValueTree node, Void p) {
+ try {
+ print("{");
+ printTagName(node);
+ if (node.getReference() != null) {
+ print(" ");
+ print(node.getReference());
+ }
+ print("}");
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitVersion(VersionTree node, Void p) {
+ try {
+ printTagName(node);
+ print(" ");
+ print(node.getBody());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ public Void visitOther(DocTree node, Void p) {
+ try {
+ print("(UNKNOWN: " + node + ")");
+ println();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2011, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.tree;
+
+import com.sun.source.doctree.AttributeTree.ValueKind;
+import com.sun.source.doctree.DocTree.Kind;
+
+import com.sun.tools.javac.parser.Tokens.Comment;
+import com.sun.tools.javac.tree.DCTree.*;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.DiagnosticSource;
+import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Position;
+
+/**
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class DocTreeMaker {
+
+ /** The context key for the tree factory. */
+ protected static final Context.Key<DocTreeMaker> treeMakerKey =
+ new Context.Key<DocTreeMaker>();
+
+ /** Get the TreeMaker instance. */
+ public static DocTreeMaker instance(Context context) {
+ DocTreeMaker instance = context.get(treeMakerKey);
+ if (instance == null)
+ instance = new DocTreeMaker(context);
+ return instance;
+ }
+
+ /** The position at which subsequent trees will be created.
+ */
+ public int pos = Position.NOPOS;
+
+ /** Access to diag factory for ErroneousTrees. */
+ private final JCDiagnostic.Factory diags;
+
+ /** Create a tree maker with NOPOS as initial position.
+ */
+ protected DocTreeMaker(Context context) {
+ context.put(treeMakerKey, this);
+ diags = JCDiagnostic.Factory.instance(context);
+ this.pos = Position.NOPOS;
+ }
+
+ /** Reassign current position.
+ */
+ public DocTreeMaker at(int pos) {
+ this.pos = pos;
+ return this;
+ }
+
+ /** Reassign current position.
+ */
+ public DocTreeMaker at(DiagnosticPosition pos) {
+ this.pos = (pos == null ? Position.NOPOS : pos.getStartPosition());
+ return this;
+ }
+
+ public DCAttribute Attribute(Name name, ValueKind vkind, List<DCTree> value) {
+ DCAttribute tree = new DCAttribute(name, vkind, value);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCAuthor Author(List<DCTree> name) {
+ DCAuthor tree = new DCAuthor(name);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCLiteral Code(DCText text) {
+ DCLiteral tree = new DCLiteral(Kind.CODE, text);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCComment Comment(String text) {
+ DCComment tree = new DCComment(text);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCDeprecated Deprecated(List<DCTree> text) {
+ DCDeprecated tree = new DCDeprecated(text);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCDocComment DocComment(Comment comment, List<DCTree> firstSentence, List<DCTree> body, List<DCTree> tags) {
+ DCDocComment tree = new DCDocComment(comment, firstSentence, body, tags);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCDocRoot DocRoot() {
+ DCDocRoot tree = new DCDocRoot();
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCEndElement EndElement(Name name) {
+ DCEndElement tree = new DCEndElement(name);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCEntity Entity(Name name) {
+ DCEntity tree = new DCEntity(name);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCErroneous Erroneous(String text, DiagnosticSource diagSource, String code, Object... args) {
+ DCErroneous tree = new DCErroneous(text, diags, diagSource, code, args);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCThrows Exception(DCReference name, List<DCTree> description) {
+ DCThrows tree = new DCThrows(Kind.EXCEPTION, name, description);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCIdentifier Identifier(Name name) {
+ DCIdentifier tree = new DCIdentifier(name);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCInheritDoc InheritDoc() {
+ DCInheritDoc tree = new DCInheritDoc();
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCLink Link(DCReference ref, List<DCTree> label) {
+ DCLink tree = new DCLink(Kind.LINK, ref, label);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCLink LinkPlain(DCReference ref, List<DCTree> label) {
+ DCLink tree = new DCLink(Kind.LINK_PLAIN, ref, label);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCLiteral Literal(DCText text) {
+ DCLiteral tree = new DCLiteral(Kind.LITERAL, text);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCParam Param(boolean isTypeParameter, DCIdentifier name, List<DCTree> description) {
+ DCParam tree = new DCParam(isTypeParameter, name, description);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCReference Reference(String signature,
+ JCTree qualExpr, Name member, List<JCTree> paramTypes) {
+ DCReference tree = new DCReference(signature, qualExpr, member, paramTypes);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCReturn Return(List<DCTree> description) {
+ DCReturn tree = new DCReturn(description);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCSee See(List<DCTree> reference) {
+ DCSee tree = new DCSee(reference);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCSerial Serial(List<DCTree> description) {
+ DCSerial tree = new DCSerial(description);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCSerialData SerialData(List<DCTree> description) {
+ DCSerialData tree = new DCSerialData(description);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCSerialField SerialField(DCIdentifier name, DCReference type, List<DCTree> description) {
+ DCSerialField tree = new DCSerialField(name, type, description);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCSince Since(List<DCTree> text) {
+ DCSince tree = new DCSince(text);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCStartElement StartElement(Name name, List<DCTree> attrs, boolean selfClosing) {
+ DCStartElement tree = new DCStartElement(name, attrs, selfClosing);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCText Text(String text) {
+ DCText tree = new DCText(text);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCThrows Throws(DCReference name, List<DCTree> description) {
+ DCThrows tree = new DCThrows(Kind.THROWS, name, description);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCUnknownBlockTag UnknownBlockTag(Name name, List<DCTree> content) {
+ DCUnknownBlockTag tree = new DCUnknownBlockTag(name, content);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCUnknownInlineTag UnknownInlineTag(Name name, List<DCTree> content) {
+ DCUnknownInlineTag tree = new DCUnknownInlineTag(name, content);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCValue Value(DCReference ref) {
+ DCValue tree = new DCValue(ref);
+ tree.pos = pos;
+ return tree;
+ }
+
+ public DCVersion Version(List<DCTree> text) {
+ DCVersion tree = new DCVersion(text);
+ tree.pos = pos;
+ return tree;
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java Fri Nov 30 17:09:05 2012 -0800
@@ -1110,7 +1110,7 @@
public void visitReference(JCMemberReference tree) {
try {
printExpr(tree.expr);
- print("#");
+ print("::");
if (tree.typeargs != null) {
print("<");
printExprs(tree.typeargs);
--- a/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java Fri Nov 30 17:09:05 2012 -0800
@@ -31,6 +31,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+
import javax.tools.JavaFileObject;
import com.sun.tools.javac.api.DiagnosticFormatter;
@@ -43,9 +44,8 @@
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.CapturedType;
+import com.sun.tools.javac.file.BaseFileObject;
import com.sun.tools.javac.tree.JCTree.*;
-
-import com.sun.tools.javac.file.BaseFileObject;
import com.sun.tools.javac.tree.Pretty;
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java Fri Nov 30 17:09:05 2012 -0800
@@ -73,6 +73,95 @@
final String value;
}
+ /**
+ * DiagnosticHandler's provide the initial handling for diagnostics.
+ * When a diagnostic handler is created and has been initialized, it
+ * should install itself as the current diagnostic handler. When a
+ * client has finished using a handler, the client should call
+ * {@code log.removeDiagnosticHandler();}
+ *
+ * Note that javax.tools.DiagnosticListener (if set) is called later in the
+ * diagnostic pipeline.
+ */
+ public static abstract class DiagnosticHandler {
+ /**
+ * The previously installed diagnostic handler.
+ */
+ protected DiagnosticHandler prev;
+
+ /**
+ * Install this diagnostic handler as the current one,
+ * recording the previous one.
+ */
+ protected void install(Log log) {
+ prev = log.diagnosticHandler;
+ log.diagnosticHandler = this;
+ }
+
+ /**
+ * Handle a diagnostic.
+ */
+ public abstract void report(JCDiagnostic diag);
+ }
+
+ /**
+ * A DiagnosticHandler that discards all diagnostics.
+ */
+ public static class DiscardDiagnosticHandler extends DiagnosticHandler {
+ public DiscardDiagnosticHandler(Log log) {
+ install(log);
+ }
+
+ public void report(JCDiagnostic diag) { }
+ }
+
+ /**
+ * A DiagnosticHandler that can defer some or all diagnostics,
+ * by buffering them for later examination and/or reporting.
+ * If a diagnostic is not deferred, or is subsequently reported
+ * with reportAllDiagnostics(), it will be reported to the previously
+ * active diagnostic handler.
+ */
+ public static class DeferredDiagnosticHandler extends DiagnosticHandler {
+ private Queue<JCDiagnostic> deferred = ListBuffer.lb();
+ private final Filter<JCDiagnostic> filter;
+
+ public DeferredDiagnosticHandler(Log log) {
+ this(log, null);
+ }
+
+ public DeferredDiagnosticHandler(Log log, Filter<JCDiagnostic> filter) {
+ this.filter = filter;
+ install(log);
+ }
+
+ public void report(JCDiagnostic diag) {
+ if (filter == null || filter.accepts(diag))
+ deferred.add(diag);
+ else
+ prev.report(diag);
+ }
+
+ public Queue<JCDiagnostic> getDiagnostics() {
+ return deferred;
+ }
+
+ /** Report all deferred diagnostics. */
+ public void reportDeferredDiagnostics() {
+ reportDeferredDiagnostics(EnumSet.allOf(JCDiagnostic.Kind.class));
+ }
+
+ /** Report selected deferred diagnostics. */
+ public void reportDeferredDiagnostics(Set<JCDiagnostic.Kind> kinds) {
+ JCDiagnostic d;
+ while ((d = deferred.poll()) != null) {
+ if (kinds.contains(d.getKind()))
+ prev.report(d);
+ }
+ deferred = null; // prevent accidental ongoing use
+ }
+ }
+
public enum WriterKind { NOTICE, WARNING, ERROR };
protected PrintWriter errWriter;
@@ -128,10 +217,9 @@
private JavacMessages messages;
/**
- * Deferred diagnostics
++ * Handler for initial dispatch of diagnostics.
*/
- public Filter<JCDiagnostic> deferredDiagFilter;
- public Queue<JCDiagnostic> deferredDiagnostics = new ListBuffer<JCDiagnostic>();
+ private DiagnosticHandler diagnosticHandler;
/** Construct a log with given I/O redirections.
*/
@@ -147,6 +235,8 @@
context.get(DiagnosticListener.class);
this.diagListener = dl;
+ diagnosticHandler = new DefaultDiagnosticHandler();
+
messages = JavacMessages.instance(context);
messages.add(Main.javacBundleName);
@@ -305,6 +395,17 @@
this.sourceMap = other.sourceMap;
}
+ /**
+ * Replace the specified diagnostic handler with the
+ * handler that was current at the time this handler was created.
+ * The given handler must be the currently installed handler;
+ * it must be specified explicitly for clarity and consistency checking.
+ */
+ public void popDiagnosticHandler(DiagnosticHandler h) {
+ Assert.check(diagnosticHandler == h);
+ diagnosticHandler = h.prev;
+ }
+
/** Flush the logs
*/
public void flush() {
@@ -443,64 +544,54 @@
nwarnings++;
}
- /** Report all deferred diagnostics, and clear the deferDiagnostics flag. */
- public void reportDeferredDiagnostics() {
- reportDeferredDiagnostics(EnumSet.allOf(JCDiagnostic.Kind.class));
- }
-
- /** Report selected deferred diagnostics, and clear the deferDiagnostics flag. */
- public void reportDeferredDiagnostics(Set<JCDiagnostic.Kind> kinds) {
- deferredDiagFilter = null;
- JCDiagnostic d;
- while ((d = deferredDiagnostics.poll()) != null) {
- if (kinds.contains(d.getKind()))
- report(d);
- }
- }
+ /**
+ * Primary method to report a diagnostic.
+ * @param diagnostic
+ */
+ public void report(JCDiagnostic diagnostic) {
+ diagnosticHandler.report(diagnostic);
+ }
/**
* Common diagnostic handling.
* The diagnostic is counted, and depending on the options and how many diagnostics have been
* reported so far, the diagnostic may be handed off to writeDiagnostic.
*/
- public void report(JCDiagnostic diagnostic) {
- if (deferredDiagFilter != null && deferredDiagFilter.accepts(diagnostic)) {
- deferredDiagnostics.add(diagnostic);
- return;
- }
+ private class DefaultDiagnosticHandler extends DiagnosticHandler {
+ public void report(JCDiagnostic diagnostic) {
+ if (expectDiagKeys != null)
+ expectDiagKeys.remove(diagnostic.getCode());
+
+ switch (diagnostic.getType()) {
+ case FRAGMENT:
+ throw new IllegalArgumentException();
- if (expectDiagKeys != null)
- expectDiagKeys.remove(diagnostic.getCode());
-
- switch (diagnostic.getType()) {
- case FRAGMENT:
- throw new IllegalArgumentException();
+ case NOTE:
+ // Print out notes only when we are permitted to report warnings
+ // Notes are only generated at the end of a compilation, so should be small
+ // in number.
+ if ((emitWarnings || diagnostic.isMandatory()) && !suppressNotes) {
+ writeDiagnostic(diagnostic);
+ }
+ break;
- case NOTE:
- // Print out notes only when we are permitted to report warnings
- // Notes are only generated at the end of a compilation, so should be small
- // in number.
- if ((emitWarnings || diagnostic.isMandatory()) && !suppressNotes) {
- writeDiagnostic(diagnostic);
- }
- break;
+ case WARNING:
+ if (emitWarnings || diagnostic.isMandatory()) {
+ if (nwarnings < MaxWarnings) {
+ writeDiagnostic(diagnostic);
+ nwarnings++;
+ }
+ }
+ break;
- case WARNING:
- if (emitWarnings || diagnostic.isMandatory()) {
- if (nwarnings < MaxWarnings) {
+ case ERROR:
+ if (nerrors < MaxErrors
+ && shouldReport(diagnostic.getSource(), diagnostic.getIntPosition())) {
writeDiagnostic(diagnostic);
- nwarnings++;
+ nerrors++;
}
+ break;
}
- break;
-
- case ERROR:
- if (nerrors < MaxErrors
- && shouldReport(diagnostic.getSource(), diagnostic.getIntPosition())) {
- writeDiagnostic(diagnostic);
- nerrors++;
- }
- break;
}
}
@@ -551,18 +642,6 @@
}
}
- public void deferAll() {
- deferredDiagFilter = new Filter<JCDiagnostic>() {
- public boolean accepts(JCDiagnostic t) {
- return true;
- }
- };
- }
-
- public void deferNone() {
- deferredDiagFilter = null;
- }
-
/** Find a localized string in the resource bundle.
* Because this method is static, it ignores the locale.
* Use localize(key, args) when possible.
--- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Fri Nov 30 17:09:05 2012 -0800
@@ -525,7 +525,8 @@
bound = ((ErrorType)bound).getOriginalType();
//retrieve the bound list - if the type variable
//has not been attributed the bound is not set
- List<Type> bounds = bound != null ?
+ List<Type> bounds = (bound != null) &&
+ (bound.hasTag(CLASS) || bound.hasTag(TYPEVAR)) ?
types.getBounds(t) :
List.<Type>nil();
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Warner.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Warner.java Fri Nov 30 17:09:05 2012 -0800
@@ -39,7 +39,6 @@
* deletion without notice.</b>
*/
public class Warner {
- public static final Warner noWarnings = new Warner();
private DiagnosticPosition pos = null;
protected boolean warned = false;
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocEnv.java Fri Nov 30 17:09:05 2012 -0800
@@ -102,6 +102,7 @@
Check chk;
Types types;
JavaFileManager fileManager;
+ Context context;
/** Allow documenting from class files? */
boolean docClasses = false;
@@ -122,6 +123,7 @@
*/
protected DocEnv(Context context) {
context.put(docEnvKey, this);
+ this.context = context;
messager = Messager.instance0(context);
syms = Symtab.instance(context);
@@ -209,8 +211,8 @@
public void setLocale(String localeName) {
// create locale specifics
doclocale = new DocLocale(this, localeName, breakiterator);
- // reset Messager if locale has changed.
- messager.reset();
+ // update Messager if locale has changed.
+ messager.setLocale(doclocale.locale);
}
/** Check whether this member should be documented. */
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocLocale.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocLocale.java Fri Nov 30 17:09:05 2012 -0800
@@ -49,7 +49,7 @@
final String localeName;
/**
- * The locale to be used. If user doesen't provide this,
+ * The locale to be used. If user doesn't provide this,
* then set it to default locale value.
*/
final Locale locale;
@@ -98,7 +98,7 @@
if (locale == null) {
docenv.exit();
} else {
- Locale.setDefault(locale);
+ Locale.setDefault(locale); // NOTE: updating global state
}
collator = Collator.getInstance(locale);
sentenceBreaker = BreakIterator.getSentenceInstance(locale);
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocletInvoker.java Fri Nov 30 17:09:05 2012 -0800
@@ -32,7 +32,12 @@
import java.net.URL;
import java.net.URLClassLoader;
+import javax.tools.DocumentationTool;
+import javax.tools.JavaFileManager;
+
import com.sun.javadoc.*;
+import com.sun.tools.javac.file.Locations;
+import com.sun.tools.javac.util.ClientCodeException;
import com.sun.tools.javac.util.List;
import static com.sun.javadoc.LanguageVersion.*;
@@ -57,6 +62,12 @@
private final Messager messager;
+ /**
+ * In API mode, exceptions thrown while calling the doclet are
+ * propagated using ClientCodeException.
+ */
+ private final boolean apiMode;
+
private static class DocletInvokeException extends Exception {
private static final long serialVersionUID = 0;
}
@@ -71,31 +82,45 @@
}
}
- public DocletInvoker(Messager messager,
+ public DocletInvoker(Messager messager, Class<?> docletClass, boolean apiMode) {
+ this.messager = messager;
+ this.docletClass = docletClass;
+ docletClassName = docletClass.getName();
+ appClassLoader = null;
+ this.apiMode = apiMode;
+ }
+
+ public DocletInvoker(Messager messager, JavaFileManager fileManager,
String docletClassName, String docletPath,
- ClassLoader docletParentClassLoader) {
+ ClassLoader docletParentClassLoader,
+ boolean apiMode) {
this.messager = messager;
this.docletClassName = docletClassName;
+ this.apiMode = apiMode;
- // construct class loader
- String cpString = null; // make sure env.class.path defaults to dot
+ if (fileManager != null && fileManager.hasLocation(DocumentationTool.Location.DOCLET_PATH)) {
+ appClassLoader = fileManager.getClassLoader(DocumentationTool.Location.DOCLET_PATH);
+ } else {
+ // construct class loader
+ String cpString = null; // make sure env.class.path defaults to dot
- // do prepends to get correct ordering
- cpString = appendPath(System.getProperty("env.class.path"), cpString);
- cpString = appendPath(System.getProperty("java.class.path"), cpString);
- cpString = appendPath(docletPath, cpString);
- URL[] urls = com.sun.tools.javac.file.Locations.pathToURLs(cpString);
- if (docletParentClassLoader == null)
- appClassLoader = new URLClassLoader(urls, getDelegationClassLoader(docletClassName));
- else
- appClassLoader = new URLClassLoader(urls, docletParentClassLoader);
+ // do prepends to get correct ordering
+ cpString = appendPath(System.getProperty("env.class.path"), cpString);
+ cpString = appendPath(System.getProperty("java.class.path"), cpString);
+ cpString = appendPath(docletPath, cpString);
+ URL[] urls = Locations.pathToURLs(cpString);
+ if (docletParentClassLoader == null)
+ appClassLoader = new URLClassLoader(urls, getDelegationClassLoader(docletClassName));
+ else
+ appClassLoader = new URLClassLoader(urls, docletParentClassLoader);
+ }
// attempt to find doclet
Class<?> dc = null;
try {
dc = appClassLoader.loadClass(docletClassName);
} catch (ClassNotFoundException exc) {
- messager.error(null, "main.doclet_class_not_found", docletClassName);
+ messager.error(Messager.NOPOS, "main.doclet_class_not_found", docletClassName);
messager.exit();
}
docletClass = dc;
@@ -168,7 +193,7 @@
if (retVal instanceof Boolean) {
return ((Boolean)retVal).booleanValue();
} else {
- messager.error(null, "main.must_return_boolean",
+ messager.error(Messager.NOPOS, "main.must_return_boolean",
docletClassName, methodName);
return false;
}
@@ -192,7 +217,7 @@
if (retVal instanceof Integer) {
return ((Integer)retVal).intValue();
} else {
- messager.error(null, "main.must_return_int",
+ messager.error(Messager.NOPOS, "main.must_return_int",
docletClassName, methodName);
return -1;
}
@@ -217,7 +242,7 @@
if (retVal instanceof Boolean) {
return ((Boolean)retVal).booleanValue();
} else {
- messager.error(null, "main.must_return_boolean",
+ messager.error(Messager.NOPOS, "main.must_return_boolean",
docletClassName, methodName);
return false;
}
@@ -241,7 +266,7 @@
if (retVal instanceof LanguageVersion) {
return (LanguageVersion)retVal;
} else {
- messager.error(null, "main.must_return_languageversion",
+ messager.error(Messager.NOPOS, "main.must_return_languageversion",
docletClassName, methodName);
return JAVA_1_1;
}
@@ -261,45 +286,48 @@
meth = docletClass.getMethod(methodName, paramTypes);
} catch (NoSuchMethodException exc) {
if (returnValueIfNonExistent == null) {
- messager.error(null, "main.doclet_method_not_found",
+ messager.error(Messager.NOPOS, "main.doclet_method_not_found",
docletClassName, methodName);
throw new DocletInvokeException();
} else {
return returnValueIfNonExistent;
}
} catch (SecurityException exc) {
- messager.error(null, "main.doclet_method_not_accessible",
+ messager.error(Messager.NOPOS, "main.doclet_method_not_accessible",
docletClassName, methodName);
throw new DocletInvokeException();
}
if (!Modifier.isStatic(meth.getModifiers())) {
- messager.error(null, "main.doclet_method_must_be_static",
+ messager.error(Messager.NOPOS, "main.doclet_method_must_be_static",
docletClassName, methodName);
throw new DocletInvokeException();
}
ClassLoader savedCCL =
Thread.currentThread().getContextClassLoader();
try {
- Thread.currentThread().setContextClassLoader(appClassLoader);
+ if (appClassLoader != null) // will be null if doclet class provided via API
+ Thread.currentThread().setContextClassLoader(appClassLoader);
return meth.invoke(null , params);
} catch (IllegalArgumentException exc) {
- messager.error(null, "main.internal_error_exception_thrown",
+ messager.error(Messager.NOPOS, "main.internal_error_exception_thrown",
docletClassName, methodName, exc.toString());
throw new DocletInvokeException();
} catch (IllegalAccessException exc) {
- messager.error(null, "main.doclet_method_not_accessible",
+ messager.error(Messager.NOPOS, "main.doclet_method_not_accessible",
docletClassName, methodName);
throw new DocletInvokeException();
} catch (NullPointerException exc) {
- messager.error(null, "main.internal_error_exception_thrown",
+ messager.error(Messager.NOPOS, "main.internal_error_exception_thrown",
docletClassName, methodName, exc.toString());
throw new DocletInvokeException();
} catch (InvocationTargetException exc) {
Throwable err = exc.getTargetException();
+ if (apiMode)
+ throw new ClientCodeException(err);
if (err instanceof java.lang.OutOfMemoryError) {
- messager.error(null, "main.out.of.memory");
+ messager.error(Messager.NOPOS, "main.out.of.memory");
} else {
- messager.error(null, "main.exception_thrown",
+ messager.error(Messager.NOPOS, "main.exception_thrown",
docletClassName, methodName, exc.toString());
exc.getTargetException().printStackTrace();
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java Fri Nov 30 17:09:05 2012 -0800
@@ -81,6 +81,9 @@
docenv.makeAnnotationTypeElementDoc(meth, docComment, tree, lineMap);
else
docenv.makeMethodDoc(meth, docComment, tree, lineMap);
+
+ // release resources
+ tree.body = null;
}
@Override
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Fri Nov 30 17:09:05 2012 -0800
@@ -38,7 +38,6 @@
import javax.tools.StandardLocation;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
-import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
@@ -65,11 +64,9 @@
public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
DocEnv docenv;
- final Context context;
final Messager messager;
- final JavadocClassReader reader;
- final JavadocEnter enter;
- final Annotate annotate;
+ final JavadocClassReader javadocReader;
+ final JavadocEnter javadocEnter;
/**
* Construct a new JavaCompiler processor, using appropriately
@@ -77,11 +74,9 @@
*/
protected JavadocTool(Context context) {
super(context);
- this.context = context;
messager = Messager.instance0(context);
- reader = JavadocClassReader.instance0(context);
- enter = JavadocEnter.instance0(context);
- annotate = Annotate.instance(context);
+ javadocReader = JavadocClassReader.instance0(context);
+ javadocEnter = JavadocEnter.instance0(context);
}
/**
@@ -124,6 +119,7 @@
ModifierFilter filter,
List<String> javaNames,
List<String[]> options,
+ Iterable<? extends JavaFileObject> fileObjects,
boolean breakiterator,
List<String> subPackages,
List<String> excludedPackages,
@@ -138,17 +134,18 @@
docenv.setEncoding(encoding);
docenv.docClasses = docClasses;
docenv.legacyDoclet = legacyDoclet;
- reader.sourceCompleter = docClasses ? null : this;
+ javadocReader.sourceCompleter = docClasses ? null : this;
ListBuffer<String> names = new ListBuffer<String>();
ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<JCCompilationUnit>();
ListBuffer<JCCompilationUnit> packTrees = new ListBuffer<JCCompilationUnit>();
try {
- StandardJavaFileManager fm = (StandardJavaFileManager) docenv.fileManager;
+ StandardJavaFileManager fm = docenv.fileManager instanceof StandardJavaFileManager
+ ? (StandardJavaFileManager) docenv.fileManager : null;
for (List<String> it = javaNames; it.nonEmpty(); it = it.tail) {
String name = it.head;
- if (!docClasses && name.endsWith(".java") && new File(name).exists()) {
+ if (!docClasses && fm != null && name.endsWith(".java") && new File(name).exists()) {
JavaFileObject fo = fm.getJavaFileObjects(name).iterator().next();
docenv.notice("main.Loading_source_file", name);
JCCompilationUnit tree = parse(fo);
@@ -156,11 +153,19 @@
} else if (isValidPackageName(name)) {
names = names.append(name);
} else if (name.endsWith(".java")) {
- docenv.error(null, "main.file_not_found", name);
+ if (fm == null)
+ throw new IllegalArgumentException();
+ else
+ docenv.error(null, "main.file_not_found", name);
} else {
docenv.error(null, "main.illegal_package_name", name);
}
}
+ for (JavaFileObject fo: fileObjects) {
+ docenv.notice("main.Loading_source_file", fo.getName());
+ JCCompilationUnit tree = parse(fo);
+ classTrees.append(tree);
+ }
if (!docClasses) {
// Recursively search given subpackages. If any packages
@@ -179,7 +184,7 @@
// Enter symbols for all files
docenv.notice("main.Building_tree");
- enter.main(classTrees.toList().appendList(packTrees.toList()));
+ javadocEnter.main(classTrees.toList().appendList(packTrees.toList()));
}
} catch (Abort ex) {}
@@ -240,7 +245,7 @@
}
if (!hasFiles) {
- messager.warning(null, "main.no_source_files_for_package",
+ messager.warning(Messager.NOPOS, "main.no_source_files_for_package",
name.replace(File.separatorChar, '.'));
}
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,13 +25,16 @@
package com.sun.tools.javadoc;
-import java.io.PrintWriter; // Access to 'javac' output streams
+import java.io.PrintWriter;
import java.text.MessageFormat;
-import java.util.MissingResourceException;
+import java.util.Locale;
import java.util.ResourceBundle;
import com.sun.javadoc.*;
import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
+import com.sun.tools.javac.util.JavacMessages;
import com.sun.tools.javac.util.Log;
/**
@@ -51,6 +54,7 @@
* @author Neal Gafter (rewrite)
*/
public class Messager extends Log implements DocErrorReporter {
+ public static final SourcePosition NOPOS = null;
/** Get the current messager, which is also the compiler log. */
public static Messager instance0(Context context) {
@@ -91,7 +95,9 @@
final String programName;
- private ResourceBundle messageRB = null;
+ private Locale locale;
+ private final JavacMessages messages;
+ private final JCDiagnostic.Factory javadocDiags;
/** The default writer for diagnostics
*/
@@ -121,6 +127,9 @@
PrintWriter warnWriter,
PrintWriter noticeWriter) {
super(context, errWriter, warnWriter, noticeWriter);
+ messages = JavacMessages.instance(context);
+ messages.add("com.sun.tools.javadoc.resources.javadoc");
+ javadocDiags = new JCDiagnostic.Factory(messages, "javadoc");
this.programName = programName;
}
@@ -134,94 +143,18 @@
return Integer.MAX_VALUE;
}
- /**
- * Reset resource bundle, eg. locale has changed.
- */
- public void reset() {
- messageRB = null;
- }
-
- /**
- * Get string from ResourceBundle, initialize ResourceBundle
- * if needed.
- */
- private String getString(String key) {
- if (messageRB == null) {
- try {
- messageRB = ResourceBundle.getBundle(
- "com.sun.tools.javadoc.resources.javadoc");
- } catch (MissingResourceException e) {
- throw new Error("Fatal: Resource for javadoc is missing");
- }
- }
- return messageRB.getString(key);
- }
-
- /**
- * get and format message string from resource
- *
- * @param key selects message from resource
- */
- String getText(String key) {
- return getText(key, (String)null);
+ public void setLocale(Locale locale) {
+ this.locale = locale;
}
/**
* get and format message string from resource
*
* @param key selects message from resource
- * @param a1 first argument
- */
- String getText(String key, String a1) {
- return getText(key, a1, null);
- }
-
- /**
- * get and format message string from resource
- *
- * @param key selects message from resource
- * @param a1 first argument
- * @param a2 second argument
- */
- String getText(String key, String a1, String a2) {
- return getText(key, a1, a2, null);
- }
-
- /**
- * get and format message string from resource
- *
- * @param key selects message from resource
- * @param a1 first argument
- * @param a2 second argument
- * @param a3 third argument
+ * @param args arguments for the message
*/
- String getText(String key, String a1, String a2, String a3) {
- return getText(key, a1, a2, a3, null);
- }
-
- /**
- * get and format message string from resource
- *
- * @param key selects message from resource
- * @param a1 first argument
- * @param a2 second argument
- * @param a3 third argument
- * @param a4 fourth argument
- */
- String getText(String key, String a1, String a2, String a3,
- String a4) {
- try {
- String message = getString(key);
- String[] args = new String[4];
- args[0] = a1;
- args[1] = a2;
- args[2] = a3;
- args[3] = a4;
- return MessageFormat.format(message, (Object[])args);
- } catch (MissingResourceException e) {
- return "********** Resource for javadoc is broken. There is no " +
- key + " key in resource.";
- }
+ String getText(String key, Object... args) {
+ return messages.getLocalizedString(locale, key, args);
}
/**
@@ -242,6 +175,11 @@
* @param msg message to print
*/
public void printError(SourcePosition pos, String msg) {
+ if (diagListener != null) {
+ report(DiagnosticType.ERROR, pos, msg);
+ return;
+ }
+
if (nerrors < MaxErrors) {
String prefix = (pos == null) ? programName : pos.toString();
errWriter.println(prefix + ": " + getText("javadoc.error") + " - " + msg);
@@ -269,6 +207,11 @@
* @param msg message to print
*/
public void printWarning(SourcePosition pos, String msg) {
+ if (diagListener != null) {
+ report(DiagnosticType.WARNING, pos, msg);
+ return;
+ }
+
if (nwarnings < MaxWarnings) {
String prefix = (pos == null) ? programName : pos.toString();
warnWriter.println(prefix + ": " + getText("javadoc.warning") +" - " + msg);
@@ -295,6 +238,11 @@
* @param msg message to print
*/
public void printNotice(SourcePosition pos, String msg) {
+ if (diagListener != null) {
+ report(DiagnosticType.NOTE, pos, msg);
+ return;
+ }
+
if (pos == null)
noticeWriter.println(msg);
else
@@ -307,41 +255,8 @@
*
* @param key selects message from resource
*/
- public void error(SourcePosition pos, String key) {
- printError(pos, getText(key));
- }
-
- /**
- * Print error message, increment error count.
- *
- * @param key selects message from resource
- * @param a1 first argument
- */
- public void error(SourcePosition pos, String key, String a1) {
- printError(pos, getText(key, a1));
- }
-
- /**
- * Print error message, increment error count.
- *
- * @param key selects message from resource
- * @param a1 first argument
- * @param a2 second argument
- */
- public void error(SourcePosition pos, String key, String a1, String a2) {
- printError(pos, getText(key, a1, a2));
- }
-
- /**
- * Print error message, increment error count.
- *
- * @param key selects message from resource
- * @param a1 first argument
- * @param a2 second argument
- * @param a3 third argument
- */
- public void error(SourcePosition pos, String key, String a1, String a2, String a3) {
- printError(pos, getText(key, a1, a2, a3));
+ public void error(SourcePosition pos, String key, Object... args) {
+ printError(pos, getText(key, args));
}
/**
@@ -349,54 +264,8 @@
*
* @param key selects message from resource
*/
- public void warning(SourcePosition pos, String key) {
- printWarning(pos, getText(key));
- }
-
- /**
- * Print warning message, increment warning count.
- *
- * @param key selects message from resource
- * @param a1 first argument
- */
- public void warning(SourcePosition pos, String key, String a1) {
- printWarning(pos, getText(key, a1));
- }
-
- /**
- * Print warning message, increment warning count.
- *
- * @param key selects message from resource
- * @param a1 first argument
- * @param a2 second argument
- */
- public void warning(SourcePosition pos, String key, String a1, String a2) {
- printWarning(pos, getText(key, a1, a2));
- }
-
- /**
- * Print warning message, increment warning count.
- *
- * @param key selects message from resource
- * @param a1 first argument
- * @param a2 second argument
- * @param a3 third argument
- */
- public void warning(SourcePosition pos, String key, String a1, String a2, String a3) {
- printWarning(pos, getText(key, a1, a2, a3));
- }
-
- /**
- * Print warning message, increment warning count.
- *
- * @param key selects message from resource
- * @param a1 first argument
- * @param a2 second argument
- * @param a3 third argument
- */
- public void warning(SourcePosition pos, String key, String a1, String a2, String a3,
- String a4) {
- printWarning(pos, getText(key, a1, a2, a3, a4));
+ public void warning(SourcePosition pos, String key, Object... args) {
+ printWarning(pos, getText(key, args));
}
/**
@@ -404,41 +273,8 @@
*
* @param key selects message from resource
*/
- public void notice(String key) {
- printNotice(getText(key));
- }
-
- /**
- * Print a message.
- *
- * @param key selects message from resource
- * @param a1 first argument
- */
- public void notice(String key, String a1) {
- printNotice(getText(key, a1));
- }
-
- /**
- * Print a message.
- *
- * @param key selects message from resource
- * @param a1 first argument
- * @param a2 second argument
- */
- public void notice(String key, String a1, String a2) {
- printNotice(getText(key, a1, a2));
- }
-
- /**
- * Print a message.
- *
- * @param key selects message from resource
- * @param a1 first argument
- * @param a2 second argument
- * @param a3 third argument
- */
- public void notice(String key, String a1, String a2, String a3) {
- printNotice(getText(key, a1, a2, a3));
+ public void notice(String key, Object... args) {
+ printNotice(getText(key, args));
}
/**
@@ -476,4 +312,21 @@
throw new ExitJavadoc();
}
+ private void report(DiagnosticType type, SourcePosition pos, String msg) {
+ switch (type) {
+ case ERROR:
+ case WARNING:
+ Object prefix = (pos == null) ? programName : pos;
+ report(javadocDiags.create(type, null, null, "msg", prefix, msg));
+ break;
+
+ case NOTE:
+ String key = (pos == null) ? "msg" : "pos.msg";
+ report(javadocDiags.create(type, null, null, key, pos, msg));
+ break;
+
+ default:
+ throw new IllegalArgumentException(type.toString());
+ }
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/ParamTagImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/ParamTagImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -43,7 +43,7 @@
*/
class ParamTagImpl extends TagImpl implements ParamTag {
- private static Pattern typeParamRE = Pattern.compile("<([^<>]+)>");
+ private static final Pattern typeParamRE = Pattern.compile("<([^<>]+)>");
private final String parameterName;
private final String parameterComment;
--- a/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -27,6 +27,7 @@
import java.io.IOException;
import java.util.Locale;
+import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
@@ -368,4 +369,11 @@
public Locale getLocale() {
return env.doclocale.locale;
}
+
+ /**
+ * Return the current file manager.
+ */
+ public JavaFileManager getFileManager() {
+ return env.fileManager;
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,7 +25,14 @@
package com.sun.tools.javadoc;
+import java.io.File;
+import java.util.Locale;
+
import com.sun.javadoc.*;
+import com.sun.tools.javac.code.Kinds;
+import com.sun.tools.javac.code.Printer;
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Type.CapturedType;
import com.sun.tools.javac.util.*;
/**
@@ -75,9 +82,63 @@
container = (ClassDocImpl)holder;
}
findReferenced(container);
+ if (showRef) showRef();
}
}
+ private static final boolean showRef = false;
+
+ private void showRef() {
+ Symbol sym;
+ if (referencedMember != null) {
+ if (referencedMember instanceof MethodDocImpl)
+ sym = ((MethodDocImpl) referencedMember).sym;
+ else if (referencedMember instanceof FieldDocImpl)
+ sym = ((FieldDocImpl) referencedMember).sym;
+ else
+ sym = ((ConstructorDocImpl) referencedMember).sym;
+ } else if (referencedClass != null) {
+ sym = ((ClassDocImpl) referencedClass).tsym;
+ } else if (referencedPackage != null) {
+ sym = ((PackageDocImpl) referencedPackage).sym;
+ } else
+ return;
+
+ final JavacMessages messages = JavacMessages.instance(docenv().context);
+ Locale locale = Locale.getDefault();
+ Printer printer = new Printer() {
+ int count;
+ @Override
+ protected String localize(Locale locale, String key, Object... args) {
+ return messages.getLocalizedString(locale, key, args);
+ }
+ @Override
+ protected String capturedVarId(CapturedType t, Locale locale) {
+ return "CAP#" + (++count);
+ }
+ };
+
+ String s = text.replaceAll("\\s+", " "); // normalize white space
+ int sp = s.indexOf(" ");
+ int lparen = s.indexOf("(");
+ int rparen = s.indexOf(")");
+ String seetext = (sp == -1) ? s
+ : (lparen == -1 || sp < lparen) ? s.substring(0, sp)
+ : s.substring(0, rparen + 1);
+
+ File file = new File(holder.position().file().getAbsoluteFile().toURI().normalize());
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("+++ ").append(file).append(": ")
+ .append(name()).append(" ").append(seetext).append(": ");
+ sb.append(sym.getKind()).append(" ");
+ if (sym.kind == Kinds.MTH || sym.kind == Kinds.VAR)
+ sb.append(printer.visit(sym.owner, locale)).append(".");
+ sb.append(printer.visit(sym, locale));
+
+ System.err.println(sb);
+ }
+
/**
* get the class name part of @see, For instance,
* if the comment is @see String#startsWith(java.lang.String) .
@@ -267,8 +328,6 @@
}
if (referencedClass == null) { /* may just not be in this run */
-// docenv().warning(holder, "tag.see.class_not_found",
-// where, text);
// check if it's a package name
referencedPackage = docenv().lookupPackage(where);
return;
--- a/langtools/src/share/classes/com/sun/tools/javadoc/Start.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/Start.java Fri Nov 30 17:09:05 2012 -0800
@@ -29,10 +29,16 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
-import java.util.StringTokenizer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
import com.sun.javadoc.*;
import com.sun.tools.javac.main.CommandLine;
+import com.sun.tools.javac.util.ClientCodeException;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
@@ -53,7 +59,9 @@
* @author Robert Field
* @author Neal Gafter (rewrite)
*/
-class Start {
+public class Start extends ToolOption.Helper {
+ /** Context for this invocation. */
+ private final Context context;
private final String defaultDocletClassName;
private final ClassLoader docletParentClassLoader;
@@ -63,24 +71,17 @@
private static final String standardDocletClassName =
"com.sun.tools.doclets.standard.Standard";
- private ListBuffer<String[]> options = new ListBuffer<String[]>();
-
- private ModifierFilter showAccess = null;
-
private long defaultFilter = PUBLIC | PROTECTED;
- private Messager messager;
-
- String docLocale = "";
-
- boolean breakiterator = false;
- boolean quiet = false;
- String encoding = null;
+ private final Messager messager;
private DocletInvoker docletInvoker;
- /* Treat warnings as errors. */
- private boolean rejectWarnings = false;
+ /**
+ * In API mode, exceptions thrown while calling the doclet are
+ * propagated using ClientCodeException.
+ */
+ private boolean apiMode;
Start(String programName,
PrintWriter errWriter,
@@ -96,8 +97,8 @@
PrintWriter noticeWriter,
String defaultDocletClassName,
ClassLoader docletParentClassLoader) {
- Context tempContext = new Context(); // interim context until option decoding completed
- messager = new Messager(tempContext, programName, errWriter, warnWriter, noticeWriter);
+ context = new Context();
+ messager = new Messager(context, programName, errWriter, warnWriter, noticeWriter);
this.defaultDocletClassName = defaultDocletClassName;
this.docletParentClassLoader = docletParentClassLoader;
}
@@ -108,8 +109,8 @@
Start(String programName, String defaultDocletClassName,
ClassLoader docletParentClassLoader) {
- Context tempContext = new Context(); // interim context until option decoding completed
- messager = new Messager(tempContext, programName);
+ context = new Context();
+ messager = new Messager(context, programName);
this.defaultDocletClassName = defaultDocletClassName;
this.docletParentClassLoader = docletParentClassLoader;
}
@@ -130,23 +131,59 @@
this(javadocName);
}
+ public Start(Context context) {
+ context.getClass(); // null check
+ this.context = context;
+ apiMode = true;
+ defaultDocletClassName = standardDocletClassName;
+ docletParentClassLoader = null;
+
+ Log log = context.get(Log.logKey);
+ if (log instanceof Messager)
+ messager = (Messager) log;
+ else {
+ PrintWriter out = context.get(Log.outKey);
+ messager = (out == null) ? new Messager(context, javadocName)
+ : new Messager(context, javadocName, out, out, out);
+ }
+ }
+
/**
* Usage
*/
- private void usage() {
+ @Override
+ void usage() {
+ usage(true);
+ }
+
+
+ /**
+ * Usage
+ */
+ private void usage(boolean exit) {
+ // RFE: it would be better to replace the following with code to
+ // write a header, then help for each option, then a footer.
messager.notice("main.usage");
// let doclet print usage information (does nothing on error)
if (docletInvoker != null) {
docletInvoker.optionLength("-help");
}
+
+ if (exit) exit();
+ }
+
+ @Override
+ void Xusage() {
+ Xusage(true);
}
/**
* Usage
*/
- private void Xusage() {
+ private void Xusage(boolean exit) {
messager.notice("main.Xusage");
+ if (exit) exit();
}
/**
@@ -161,22 +198,36 @@
* Main program - external wrapper
*/
int begin(String... argv) {
+ boolean ok = begin(null, argv, Collections.<JavaFileObject> emptySet());
+ return ok ? 0 : 1;
+ }
+
+ public boolean begin(Class<?> docletClass, Iterable<String> options, Iterable<? extends JavaFileObject> fileObjects) {
+ Collection<String> opts = new ArrayList<String>();
+ for (String opt: options) opts.add(opt);
+ return begin(docletClass, opts.toArray(new String[opts.size()]), fileObjects);
+ }
+
+ private boolean begin(Class<?> docletClass, String[] options, Iterable<? extends JavaFileObject> fileObjects) {
boolean failed = false;
try {
- failed = !parseAndExecute(argv);
- } catch(Messager.ExitJavadoc exc) {
+ failed = !parseAndExecute(docletClass, options, fileObjects);
+ } catch (Messager.ExitJavadoc exc) {
// ignore, we just exit this way
} catch (OutOfMemoryError ee) {
- messager.error(null, "main.out.of.memory");
+ messager.error(Messager.NOPOS, "main.out.of.memory");
failed = true;
+ } catch (ClientCodeException e) {
+ // simply rethrow these exceptions, to be caught and handled by JavadocTaskImpl
+ throw e;
} catch (Error ee) {
ee.printStackTrace(System.err);
- messager.error(null, "main.fatal.error");
+ messager.error(Messager.NOPOS, "main.fatal.error");
failed = true;
} catch (Exception ee) {
ee.printStackTrace(System.err);
- messager.error(null, "main.fatal.exception");
+ messager.error(Messager.NOPOS, "main.fatal.exception");
failed = true;
} finally {
messager.exitNotice();
@@ -184,22 +235,16 @@
}
failed |= messager.nerrors() > 0;
failed |= rejectWarnings && messager.nwarnings() > 0;
- return failed ? 1 : 0;
- }
-
- private void addToList(ListBuffer<String> list, String str){
- StringTokenizer st = new StringTokenizer(str, ":");
- String current;
- while(st.hasMoreTokens()){
- current = st.nextToken();
- list.append(current);
- }
+ return !failed;
}
/**
* Main program - internal
*/
- private boolean parseAndExecute(String... argv) throws IOException {
+ private boolean parseAndExecute(
+ Class<?> docletClass,
+ String[] argv,
+ Iterable<? extends JavaFileObject> fileObjects) throws IOException {
long tm = System.currentTimeMillis();
ListBuffer<String> javaNames = new ListBuffer<String>();
@@ -208,134 +253,39 @@
try {
argv = CommandLine.parse(argv);
} catch (FileNotFoundException e) {
- messager.error(null, "main.cant.read", e.getMessage());
+ messager.error(Messager.NOPOS, "main.cant.read", e.getMessage());
exit();
} catch (IOException e) {
e.printStackTrace(System.err);
exit();
}
- setDocletInvoker(argv);
- ListBuffer<String> subPackages = new ListBuffer<String>();
- ListBuffer<String> excludedPackages = new ListBuffer<String>();
- Context context = new Context();
- // Setup a new Messager, using the same initial parameters as the
- // existing Messager, except that this one will be able to use any
- // options that may be set up below.
- Messager.preRegister(context,
- messager.programName,
- messager.getWriter(Log.WriterKind.ERROR),
- messager.getWriter(Log.WriterKind.WARNING),
- messager.getWriter(Log.WriterKind.NOTICE));
+ JavaFileManager fileManager = context.get(JavaFileManager.class);
+ setDocletInvoker(docletClass, fileManager, argv);
- Options compOpts = Options.instance(context);
- boolean docClasses = false;
+ compOpts = Options.instance(context);
// Parse arguments
for (int i = 0 ; i < argv.length ; i++) {
String arg = argv[i];
- if (arg.equals("-subpackages")) {
- oneArg(argv, i++);
- addToList(subPackages, argv[i]);
- } else if (arg.equals("-exclude")){
- oneArg(argv, i++);
- addToList(excludedPackages, argv[i]);
- } else if (arg.equals("-verbose")) {
- setOption(arg);
- compOpts.put("-verbose", "");
- } else if (arg.equals("-encoding")) {
- oneArg(argv, i++);
- encoding = argv[i];
- compOpts.put("-encoding", argv[i]);
- } else if (arg.equals("-breakiterator")) {
- breakiterator = true;
- setOption("-breakiterator");
- } else if (arg.equals("-quiet")) {
- quiet = true;
- setOption("-quiet");
- } else if (arg.equals("-help")) {
- usage();
- exit();
- } else if (arg.equals("-Xclasses")) {
- setOption(arg);
- docClasses = true;
- } else if (arg.equals("-Xwerror")) {
- setOption(arg);
- rejectWarnings = true;
- } else if (arg.equals("-private")) {
- setOption(arg);
- setFilter(ModifierFilter.ALL_ACCESS);
- } else if (arg.equals("-package")) {
- setOption(arg);
- setFilter(PUBLIC | PROTECTED |
- ModifierFilter.PACKAGE );
- } else if (arg.equals("-protected")) {
- setOption(arg);
- setFilter(PUBLIC | PROTECTED );
- } else if (arg.equals("-public")) {
- setOption(arg);
- setFilter(PUBLIC);
- } else if (arg.equals("-source")) {
- oneArg(argv, i++);
- if (compOpts.get("-source") != null) {
- usageError("main.option.already.seen", arg);
+
+ ToolOption o = ToolOption.get(arg);
+ if (o != null) {
+ // hack: this restriction should be removed
+ if (o == ToolOption.LOCALE && i > 0)
+ usageError("main.locale_first");
+
+ if (o.hasArg) {
+ oneArg(argv, i++);
+ o.process(this, argv[i]);
+ } else {
+ setOption(arg);
+ o.process(this);
}
- compOpts.put("-source", argv[i]);
- } else if (arg.equals("-prompt")) {
- compOpts.put("-prompt", "-prompt");
- messager.promptOnError = true;
- } else if (arg.equals("-sourcepath")) {
- oneArg(argv, i++);
- if (compOpts.get("-sourcepath") != null) {
- usageError("main.option.already.seen", arg);
- }
- compOpts.put("-sourcepath", argv[i]);
- } else if (arg.equals("-classpath")) {
- oneArg(argv, i++);
- if (compOpts.get("-classpath") != null) {
- usageError("main.option.already.seen", arg);
- }
- compOpts.put("-classpath", argv[i]);
- } else if (arg.equals("-sysclasspath")) {
- oneArg(argv, i++);
- if (compOpts.get("-bootclasspath") != null) {
- usageError("main.option.already.seen", arg);
- }
- compOpts.put("-bootclasspath", argv[i]);
- } else if (arg.equals("-bootclasspath")) {
- oneArg(argv, i++);
- if (compOpts.get("-bootclasspath") != null) {
- usageError("main.option.already.seen", arg);
- }
- compOpts.put("-bootclasspath", argv[i]);
- } else if (arg.equals("-extdirs")) {
- oneArg(argv, i++);
- if (compOpts.get("-extdirs") != null) {
- usageError("main.option.already.seen", arg);
- }
- compOpts.put("-extdirs", argv[i]);
- } else if (arg.equals("-overview")) {
- oneArg(argv, i++);
- } else if (arg.equals("-doclet")) {
- i++; // handled in setDocletInvoker
- } else if (arg.equals("-docletpath")) {
- i++; // handled in setDocletInvoker
- } else if (arg.equals("-locale")) {
- if (i != 0)
- usageError("main.locale_first");
- oneArg(argv, i++);
- docLocale = argv[i];
- } else if (arg.equals("-Xmaxerrs") || arg.equals("-Xmaxwarns")) {
- oneArg(argv, i++);
- if (compOpts.get(arg) != null) {
- usageError("main.option.already.seen", arg);
- }
- compOpts.put(arg, argv[i]);
- } else if (arg.equals("-X")) {
- Xusage();
- exit();
+
} else if (arg.startsWith("-XD")) {
+ // hidden javac options
String s = arg.substring("-XD".length());
int eq = s.indexOf('=');
String key = (eq < 0) ? s : s.substring(0, eq);
@@ -344,7 +294,7 @@
}
// call doclet for its options
// other arg starts with - is invalid
- else if ( arg.startsWith("-") ) {
+ else if (arg.startsWith("-")) {
int optionLength;
optionLength = docletInvoker.optionLength(arg);
if (optionLength < 0) {
@@ -368,8 +318,9 @@
javaNames.append(arg);
}
}
+ compOpts.notifyListeners();
- if (javaNames.isEmpty() && subPackages.isEmpty()) {
+ if (javaNames.isEmpty() && subPackages.isEmpty() && isEmpty(fileObjects)) {
usageError("main.No_packages_or_classes_specified");
}
@@ -387,21 +338,27 @@
LanguageVersion languageVersion = docletInvoker.languageVersion();
RootDocImpl root = comp.getRootDocImpl(
- docLocale, encoding, showAccess,
- javaNames.toList(), options.toList(), breakiterator,
- subPackages.toList(), excludedPackages.toList(),
+ docLocale,
+ encoding,
+ showAccess,
+ javaNames.toList(),
+ options.toList(),
+ fileObjects,
+ breakiterator,
+ subPackages.toList(),
+ excludedPackages.toList(),
docClasses,
// legacy?
- languageVersion == null || languageVersion == LanguageVersion.JAVA_1_1, quiet);
+ languageVersion == null || languageVersion == LanguageVersion.JAVA_1_1,
+ quiet);
+
+ // release resources
+ comp = null;
// pass off control to the doclet
boolean ok = root != null;
if (ok) ok = docletInvoker.start(root);
- Messager docletMessager = Messager.instance0(context);
- messager.nwarnings += docletMessager.nwarnings;
- messager.nerrors += docletMessager.nerrors;
-
// We're done.
if (compOpts.get("-verbose") != null) {
tm = System.currentTimeMillis() - tm;
@@ -411,21 +368,43 @@
return ok;
}
- private void setDocletInvoker(String[] argv) {
+ private <T> boolean isEmpty(Iterable<T> iter) {
+ return !iter.iterator().hasNext();
+ }
+
+ /**
+ * Init the doclet invoker.
+ * The doclet class may be given explicitly, or via the -doclet option in
+ * argv.
+ * If the doclet class is not given explicitly, it will be loaded from
+ * the file manager's DOCLET_PATH location, if available, or via the
+ * -doclet path option in argv.
+ * @param docletClass The doclet class. May be null.
+ * @param fileManager The file manager used to get the class loader to load
+ * the doclet class if required. May be null.
+ * @param argv Args containing -doclet and -docletpath, in case they are required.
+ */
+ private void setDocletInvoker(Class<?> docletClass, JavaFileManager fileManager, String[] argv) {
+ if (docletClass != null) {
+ docletInvoker = new DocletInvoker(messager, docletClass, apiMode);
+ // TODO, check no -doclet, -docletpath
+ return;
+ }
+
String docletClassName = null;
String docletPath = null;
// Parse doclet specifying arguments
for (int i = 0 ; i < argv.length ; i++) {
String arg = argv[i];
- if (arg.equals("-doclet")) {
+ if (arg.equals(ToolOption.DOCLET.opt)) {
oneArg(argv, i++);
if (docletClassName != null) {
usageError("main.more_than_one_doclet_specified_0_and_1",
docletClassName, argv[i]);
}
docletClassName = argv[i];
- } else if (arg.equals("-docletpath")) {
+ } else if (arg.equals(ToolOption.DOCLETPATH.opt)) {
oneArg(argv, i++);
if (docletPath == null) {
docletPath = argv[i];
@@ -440,18 +419,10 @@
}
// attempt to find doclet
- docletInvoker = new DocletInvoker(messager,
- docletClassName, docletPath,
- docletParentClassLoader);
- }
-
- private void setFilter(long filterBits) {
- if (showAccess != null) {
- messager.error(null, "main.incompatible.access.flags");
- usage();
- exit();
- }
- showAccess = new ModifierFilter(filterBits);
+ docletInvoker = new DocletInvoker(messager, fileManager,
+ docletClassName, docletPath,
+ docletParentClassLoader,
+ apiMode);
}
/**
@@ -466,22 +437,10 @@
}
}
- private void usageError(String key) {
- messager.error(null, key);
- usage();
- exit();
- }
-
- private void usageError(String key, String a1) {
- messager.error(null, key, a1);
- usage();
- exit();
- }
-
- private void usageError(String key, String a1, String a2) {
- messager.error(null, key, a1, a2);
- usage();
- exit();
+ @Override
+ void usageError(String key, Object... args) {
+ messager.error(Messager.NOPOS, key, args);
+ usage(true);
}
/**
@@ -510,7 +469,6 @@
for (List<String> i = arguments; i.nonEmpty(); i=i.tail) {
args[k++] = i.head;
}
- options = options.append(args);
+ options.append(args);
}
-
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/ToolOption.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javadoc;
+
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Options;
+import java.util.StringTokenizer;
+
+
+/**
+ * javadoc tool options.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public enum ToolOption {
+ // ----- options for underlying compiler -----
+
+ BOOTCLASSPATH("-bootclasspath", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setCompilerOpt(opt, arg);
+ }
+ },
+
+ CLASSPATH("-classpath", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setCompilerOpt(opt, arg);
+ }
+ },
+
+ EXTDIRS("-extdirs", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setCompilerOpt(opt, arg);
+ }
+ },
+
+ SOURCEPATH("-sourcepath", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setCompilerOpt(opt, arg);
+ }
+ },
+
+ SYSCLASSPATH("-sysclasspath", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setCompilerOpt("-bootclasspath", arg);
+ }
+ },
+
+ ENCODING("-encoding", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.encoding = arg;
+ helper.setCompilerOpt(opt, arg);
+ }
+ },
+
+ SOURCE("-source", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setCompilerOpt(opt, arg);
+ }
+ },
+
+ XMAXERRS("-Xmaxerrs", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setCompilerOpt(opt, arg);
+ }
+ },
+
+ XMAXWARNS("-Xmaxwarns", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setCompilerOpt(opt, arg);
+ }
+ },
+
+ // ----- doclet options -----
+
+ DOCLET("-doclet", true), // handled in setDocletInvoker
+
+ DOCLETPATH("-docletpath", true), // handled in setDocletInvoker
+
+ // ----- selection options -----
+
+ SUBPACKAGES("-subpackages", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.addToList(helper.subPackages, arg);
+ }
+ },
+
+ EXCLUDE("-exclude", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.addToList(helper.excludedPackages, arg);
+ }
+ },
+
+ // ----- filtering options -----
+
+ PACKAGE("-package") {
+ @Override
+ public void process(Helper helper) {
+ helper.setFilter(
+ Flags.PUBLIC | Flags.PROTECTED | ModifierFilter.PACKAGE);
+ }
+ },
+
+ PRIVATE("-private") {
+ @Override
+ public void process(Helper helper) {
+ helper.setFilter(ModifierFilter.ALL_ACCESS);
+ }
+ },
+
+ PROTECTED("-protected") {
+ @Override
+ public void process(Helper helper) {
+ helper.setFilter(Flags.PUBLIC | Flags.PROTECTED);
+ }
+ },
+
+ PUBLIC("-public") {
+ @Override
+ public void process(Helper helper) {
+ helper.setFilter(Flags.PUBLIC);
+ }
+ },
+
+ // ----- output control options -----
+
+ PROMPT("-prompt") {
+ @Override
+ public void process(Helper helper) {
+ helper.compOpts.put("-prompt", "-prompt");
+ helper.promptOnError = true;
+ }
+ },
+
+ QUIET("-quiet") {
+ @Override
+ public void process(Helper helper) {
+ helper.quiet = true;
+ }
+ },
+
+ VERBOSE("-verbose") {
+ @Override
+ public void process(Helper helper) {
+ helper.compOpts.put("-verbose", "");
+ }
+ },
+
+ XWERROR("-Xwerror") {
+ @Override
+ public void process(Helper helper) {
+ helper.rejectWarnings = true;
+
+ }
+ },
+
+ // ----- other options -----
+
+ BREAKITERATOR("-breakiterator") {
+ @Override
+ public void process(Helper helper) {
+ helper.breakiterator = true;
+ }
+ },
+
+ LOCALE("-locale", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.docLocale = arg;
+ }
+ },
+
+ OVERVIEW("-overview", true),
+
+ XCLASSES("-Xclasses") {
+ @Override
+ public void process(Helper helper) {
+ helper.docClasses = true;
+
+ }
+ },
+
+ // ----- help options -----
+
+ HELP("-help") {
+ @Override
+ public void process(Helper helper) {
+ helper.usage();
+ }
+ },
+
+ X("-X") {
+ @Override
+ public void process(Helper helper) {
+ helper.Xusage();
+ }
+ };
+
+ public final String opt;
+ public final boolean hasArg;
+
+ ToolOption(String opt) {
+ this(opt, false);
+ }
+
+ ToolOption(String opt, boolean hasArg) {
+ this.opt = opt;
+ this.hasArg = hasArg;
+ }
+
+ void process(Helper helper, String arg) { }
+
+ void process(Helper helper) { }
+
+ static ToolOption get(String name) {
+ for (ToolOption o: values()) {
+ if (name.equals(o.opt))
+ return o;
+ }
+ return null;
+ }
+
+ static abstract class Helper {
+ /** List of decoded options. */
+ final ListBuffer<String[]> options = new ListBuffer<String[]>();
+
+ /** Selected packages, from -subpackages. */
+ final ListBuffer<String> subPackages = new ListBuffer<String>();
+
+ /** Excluded packages, from -exclude. */
+ final ListBuffer<String> excludedPackages = new ListBuffer<String>();
+
+ /** javac options, set by various options. */
+ Options compOpts; // = Options.instance(context)
+
+ /* Encoding for javac, and files written? set by -encoding. */
+ String encoding = null;
+
+ /** Set by -breakiterator. */
+ boolean breakiterator = false;
+
+ /** Set by -quiet. */
+ boolean quiet = false;
+
+ /** Set by -Xclasses. */
+ boolean docClasses = false;
+
+ /** Set by -Xwerror. */
+ boolean rejectWarnings = false;
+
+ /** Set by -prompt. */
+ boolean promptOnError;
+
+ /** Set by -locale. */
+ String docLocale = "";
+
+ /** Set by -public, private, -protected, -package. */
+ ModifierFilter showAccess = null;
+
+ abstract void usage();
+ abstract void Xusage();
+
+ abstract void usageError(String msg, Object... args);
+
+ protected void addToList(ListBuffer<String> list, String str){
+ StringTokenizer st = new StringTokenizer(str, ":");
+ String current;
+ while(st.hasMoreTokens()){
+ current = st.nextToken();
+ list.append(current);
+ }
+ }
+
+ protected void setFilter(long filterBits) {
+ if (showAccess != null) {
+ usageError("main.incompatible.access.flags");
+ }
+ showAccess = new ModifierFilter(filterBits);
+ }
+
+ private void setCompilerOpt(String opt, String arg) {
+ if (compOpts.get(opt) != null) {
+ usageError("main.option.already.seen", opt);
+ }
+ compOpts.put(opt, arg);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/api/JavadocTaskImpl.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.javadoc.api;
+
+import com.sun.tools.javac.util.ClientCodeException;
+import java.util.Locale;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javadoc.Start;
+import java.util.Collections;
+
+/**
+ * Provides access to functionality specific to the JDK documentation tool,
+ * javadoc.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class JavadocTaskImpl implements DocumentationTask {
+ private final AtomicBoolean used = new AtomicBoolean();
+
+ private final Context context;
+ private Class<?> docletClass;
+ private Iterable<String> options;
+ private Iterable<? extends JavaFileObject> fileObjects;
+ private Locale locale;
+
+ public JavadocTaskImpl(Context context, Class<?> docletClass,
+ Iterable<String> options, Iterable<? extends JavaFileObject> fileObjects) {
+ this.context = context;
+ this.docletClass = docletClass;
+
+ this.options = (options == null) ? Collections.<String>emptySet()
+ : nullCheck(options);
+ this.fileObjects = (fileObjects == null) ? Collections.<JavaFileObject>emptySet()
+ : nullCheck(fileObjects);
+ setLocale(Locale.getDefault());
+ }
+
+ public void setLocale(Locale locale) {
+ if (used.get())
+ throw new IllegalStateException();
+ this.locale = locale;
+ }
+
+ public Boolean call() {
+ if (!used.getAndSet(true)) {
+ initContext();
+ Start jdoc = new Start(context);
+ try {
+ return jdoc.begin(docletClass, options, fileObjects);
+ } catch (ClientCodeException e) {
+ throw new RuntimeException(e.getCause());
+ }
+ } else {
+ throw new IllegalStateException("multiple calls to method 'call'");
+ }
+ }
+
+ private void initContext() {
+ //initialize compiler's default locale
+ context.put(Locale.class, locale);
+ }
+
+ private static <T> Iterable<T> nullCheck(Iterable<T> items) {
+ for (T item: items) {
+ if (item == null)
+ throw new NullPointerException();
+ }
+ return items;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/api/JavadocTool.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javadoc.api;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Locale;
+import java.util.Set;
+
+import javax.lang.model.SourceVersion;
+import javax.tools.DiagnosticListener;
+import javax.tools.DocumentationTool;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+
+import com.sun.tools.javac.api.ClientCodeWrapper;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.util.ClientCodeException;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javadoc.ToolOption;
+
+/**
+ * Provides access to functionality specific to the JDK documentation tool,
+ * javadoc.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk. This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public class JavadocTool implements DocumentationTool {
+ @Override
+ public DocumentationTask getTask(
+ Writer out,
+ JavaFileManager fileManager,
+ DiagnosticListener<? super JavaFileObject> diagnosticListener,
+ Class<?> docletClass,
+ Iterable<String> options,
+ Iterable<? extends JavaFileObject> compilationUnits) {
+ Context context = new Context();
+ return getTask(out, fileManager, diagnosticListener,
+ docletClass, options, compilationUnits, context);
+ }
+
+ public DocumentationTask getTask(
+ Writer out,
+ JavaFileManager fileManager,
+ DiagnosticListener<? super JavaFileObject> diagnosticListener,
+ Class<?> docletClass,
+ Iterable<String> options,
+ Iterable<? extends JavaFileObject> compilationUnits,
+ Context context) {
+ try {
+ ClientCodeWrapper ccw = ClientCodeWrapper.instance(context);
+
+ if (options != null) {
+ for (String option : options)
+ option.getClass(); // null check
+ }
+
+ if (compilationUnits != null) {
+ compilationUnits = ccw.wrapJavaFileObjects(compilationUnits); // implicit null check
+ for (JavaFileObject cu : compilationUnits) {
+ if (cu.getKind() != JavaFileObject.Kind.SOURCE) {
+ final String kindMsg = "All compilation units must be of SOURCE kind";
+ throw new IllegalArgumentException(kindMsg);
+ }
+ }
+ }
+
+ if (diagnosticListener != null)
+ context.put(DiagnosticListener.class, ccw.wrap(diagnosticListener));
+
+ if (out == null)
+ context.put(Log.outKey, new PrintWriter(System.err, true));
+ else if (out instanceof PrintWriter)
+ context.put(Log.outKey, ((PrintWriter) out));
+ else
+ context.put(Log.outKey, new PrintWriter(out, true));
+
+ if (fileManager == null)
+ fileManager = getStandardFileManager(diagnosticListener, null, null);
+ fileManager = ccw.wrap(fileManager);
+ context.put(JavaFileManager.class, fileManager);
+
+ return new JavadocTaskImpl(context, docletClass, options, compilationUnits);
+ } catch (ClientCodeException ex) {
+ throw new RuntimeException(ex.getCause());
+ }
+ }
+
+ // TODO: used shared static method in JavacFileManager
+ @Override
+ public StandardJavaFileManager getStandardFileManager(
+ DiagnosticListener<? super JavaFileObject> diagnosticListener,
+ Locale locale,
+ Charset charset) {
+ Context context = new Context();
+ context.put(Locale.class, locale);
+ if (diagnosticListener != null)
+ context.put(DiagnosticListener.class, diagnosticListener);
+ PrintWriter pw = (charset == null)
+ ? new PrintWriter(System.err, true)
+ : new PrintWriter(new OutputStreamWriter(System.err, charset), true);
+ context.put(Log.outKey, pw);
+ return new JavacFileManager(context, true, charset);
+ }
+
+ @Override
+ public int run(InputStream in, OutputStream out, OutputStream err, String... arguments) {
+ PrintWriter err_pw = new PrintWriter(err, true);
+ PrintWriter out_pw = new PrintWriter(out);
+ try {
+ String standardDocletName = "com.sun.tools.doclets.standard.Standard";
+ return com.sun.tools.javadoc.Main.execute(
+ "javadoc", err_pw, err_pw, out_pw, standardDocletName, arguments);
+ } finally {
+ err_pw.flush();
+ out_pw.flush();
+ }
+ }
+
+ @Override
+ public Set<SourceVersion> getSourceVersions() {
+ return Collections.unmodifiableSet(
+ EnumSet.range(SourceVersion.RELEASE_3, SourceVersion.latest()));
+ }
+
+ @Override
+ public int isSupportedOption(String option) {
+ if (option == null)
+ throw new NullPointerException();
+ for (ToolOption o: ToolOption.values()) {
+ if (o.opt.equals(option))
+ return o.hasArg ? 1 : 0;
+ }
+ return -1;
+ }
+
+}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2012, 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
@@ -64,7 +64,6 @@
main.incompatible.access.flags=More than one of -public, -private, -package, or -protected specified.
main.cant.read=cannot read {0}
main.Loading_source_files_for_package=Loading source files for package {0}...
-main.Loading_source_file_for_class=Loading source file for class {0}...
main.Loading_source_file=Loading source file {0}...
main.Building_tree=Constructing Javadoc information...
main.no_source_files_for_package=No source files for package {0}
@@ -96,13 +95,12 @@
tag.see.can_not_find_member=Tag {0}: can''t find {1} in {2}
tag.see.no_close_bracket_on_url=Tag {0}: missing final ''>'': "{1}"
tag.see.no_close_quote=Tag {0}: no final close quote: "{1}"
-tag.see.class_not_found=class {0} not found for @see tag: "{1}"
tag.see.class_not_specified=Tag {0}: class not specified: "{1}"
tag.see.illegal_character=Tag {0}:illegal character: "{1}" in "{2}"
tag.see.malformed_see_tag=Tag {0}: malformed: "{1}"
-tag.throws.exception_not_found={0} tag, class {1} not found.
tag.End_delimiter_missing_for_possible_SeeTag=End Delimiter } missing for possible See Tag in comment string: "{0}"
tag.Improper_Use_Of_Link_Tag=Missing closing ''}'' character for inline tag: "{0}"
+tag.serialField.illegal_character=illegal character {0} in @serialField tag: {1}.
javadoc.File_Read_Error=Error while reading file {0}
javadoc.Body_missing_from_html_file=Body tag missing from HTML file
javadoc.End_body_missing_from_html_file=Close body tag missing from HTML file
@@ -110,4 +108,8 @@
javadoc.class_not_found=Class {0} not found.
javadoc.error=error
javadoc.warning=warning
-tag.serialField.illegal_character=illegal character {0} in @serialField tag: {1}.
+
+javadoc.error.msg={0}: error - {1}
+javadoc.warning.msg={0}: warning - {1}
+javadoc.note.msg = {1}
+javadoc.note.pos.msg= {0}: {1}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/javax/tools/DocumentationTool.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2005, 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package javax.tools;
+
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.Locale;
+import java.util.concurrent.Callable;
+
+/**
+ * Interface to invoke Java™ programming language documentation tools from
+ * programs.
+ */
+public interface DocumentationTool extends Tool, OptionChecker {
+ /**
+ * Creates a future for a documentation task with the given
+ * components and arguments. The task might not have
+ * completed as described in the DocumentationTask interface.
+ *
+ * <p>If a file manager is provided, it must be able to handle all
+ * locations defined in {@link DocumentationTool.Location},
+ * as well as
+ * {@link StandardLocation#SOURCE_PATH},
+ * {@link StandardLocation#CLASS_PATH}, and
+ * {@link StandardLocation#PLATFORM_CLASS_PATH}.
+ *
+ * @param out a Writer for additional output from the tool;
+ * use {@code System.err} if {@code null}
+ *
+ * @param fileManager a file manager; if {@code null} use the
+ * tool's standard filemanager
+ *
+ * @param diagnosticListener a diagnostic listener; if {@code null}
+ * use the tool's default method for reporting diagnostics
+ *
+ * @param docletClass a class providing the necessary methods required
+ * of a doclet
+ *
+ * @param options documentation tool options and doclet options,
+ * {@code null} means no options
+ *
+ * @param compilationUnits the compilation units to compile, {@code
+ * null} means no compilation units
+ *
+ * @return an object representing the compilation
+ *
+ * @throws RuntimeException if an unrecoverable error
+ * occurred in a user supplied component. The
+ * {@linkplain Throwable#getCause() cause} will be the error in
+ * user code.
+ *
+ * @throws IllegalArgumentException if any of the given
+ * compilation units are of other kind than
+ * {@linkplain JavaFileObject.Kind#SOURCE source}
+ */
+ DocumentationTask getTask(Writer out,
+ JavaFileManager fileManager,
+ DiagnosticListener<? super JavaFileObject> diagnosticListener,
+ Class<?> docletClass,
+ Iterable<String> options,
+ Iterable<? extends JavaFileObject> compilationUnits);
+
+ /**
+ * Gets a new instance of the standard file manager implementation
+ * for this tool. The file manager will use the given diagnostic
+ * listener for producing any non-fatal diagnostics. Fatal errors
+ * will be signaled with the appropriate exceptions.
+ *
+ * <p>The standard file manager will be automatically reopened if
+ * it is accessed after calls to {@code flush} or {@code close}.
+ * The standard file manager must be usable with other tools.
+ *
+ * @param diagnosticListener a diagnostic listener for non-fatal
+ * diagnostics; if {@code null} use the compiler's default method
+ * for reporting diagnostics
+ *
+ * @param locale the locale to apply when formatting diagnostics;
+ * {@code null} means the {@linkplain Locale#getDefault() default locale}.
+ *
+ * @param charset the character set used for decoding bytes; if
+ * {@code null} use the platform default
+ *
+ * @return the standard file manager
+ */
+ StandardJavaFileManager getStandardFileManager(
+ DiagnosticListener<? super JavaFileObject> diagnosticListener,
+ Locale locale,
+ Charset charset);
+
+ /**
+ * Interface representing a future for a documentation task. The
+ * task has not yet started. To start the task, call
+ * the {@linkplain #call call} method.
+ *
+ * <p>Before calling the call method, additional aspects of the
+ * task can be configured, for example, by calling the
+ * {@linkplain #setLocale setLocale} method.
+ */
+ interface DocumentationTask extends Callable<Boolean> {
+ /**
+ * Set the locale to be applied when formatting diagnostics and
+ * other localized data.
+ *
+ * @param locale the locale to apply; {@code null} means apply no
+ * locale
+ * @throws IllegalStateException if the task has started
+ */
+ void setLocale(Locale locale);
+
+ /**
+ * Performs this documentation task. The task may only
+ * be performed once. Subsequent calls to this method throw
+ * IllegalStateException.
+ *
+ * @return true if and only all the files were processed without errors;
+ * false otherwise
+ *
+ * @throws RuntimeException if an unrecoverable error occurred
+ * in a user-supplied component. The
+ * {@linkplain Throwable#getCause() cause} will be the error
+ * in user code.
+ *
+ * @throws IllegalStateException if called more than once
+ */
+ Boolean call();
+ }
+
+ /**
+ * Locations specific to {@link DocumentationTool}.
+ *
+ * @see StandardLocation
+ */
+ enum Location implements JavaFileManager.Location {
+ /**
+ * Location of new documentation files.
+ */
+ DOCUMENTATION_OUTPUT,
+
+ /**
+ * Location to search for doclets.
+ */
+ DOCLET_PATH,
+
+ /**
+ * Location to search for taglets.
+ */
+ TAGLET_PATH;
+
+ public String getName() { return name(); }
+
+ public boolean isOutputLocation() {
+ switch (this) {
+ case DOCUMENTATION_OUTPUT:
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+
+}
--- a/langtools/src/share/classes/javax/tools/JavaCompiler.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/javax/tools/JavaCompiler.java Fri Nov 30 17:09:05 2012 -0800
@@ -266,7 +266,7 @@
* Gets a new instance of the standard file manager implementation
* for this tool. The file manager will use the given diagnostic
* listener for producing any non-fatal diagnostics. Fatal errors
- * will be signalled with the appropriate exceptions.
+ * will be signaled with the appropriate exceptions.
*
* <p>The standard file manager will be automatically reopened if
* it is accessed after calls to {@code flush} or {@code close}.
--- a/langtools/src/share/classes/javax/tools/ToolProvider.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/src/share/classes/javax/tools/ToolProvider.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -102,6 +102,19 @@
return instance().getSystemTool(JavaCompiler.class, defaultJavaCompilerName);
}
+ private static final String defaultDocumentationToolName
+ = "com.sun.tools.javadoc.api.JavadocTool";
+
+ /**
+ * Gets the Java™ programming language documentation tool provided
+ * with this platform.
+ * @return the documentation tool provided with this platform or
+ * {@code null} if no documentation tool is provided
+ */
+ public static DocumentationTool getSystemDocumentationTool() {
+ return instance().getSystemTool(DocumentationTool.class, defaultDocumentationToolName);
+ }
+
/**
* Returns the class loader for tools provided with this platform.
* This does not include user-installed tools. Use the
--- a/langtools/test/Makefile Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/Makefile Fri Nov 30 17:09:05 2012 -0800
@@ -146,10 +146,15 @@
endif
# Concurrency is the number of tests that can execute at once.
-# Supported for JCK, not supported for jtreg.
# On an otherwise empty machine, suggest setting to (#cpus + 2)
# If unset, the default is (#cpus)
### RFE: determine and use #cpus
+ifdef CONCURRENCY
+ JTREG_OPTIONS += -agentvm -concurrency:$(CONCURRENCY)
+else
+ JTREG_OPTIONS += -samevm
+endif
+
ifdef JCK_CONCURRENCY
JCK_OPTIONS += -concurrency:$(JCK_CONCURRENCY)
endif
@@ -266,7 +271,7 @@
@mkdir -p $(JTREG_OUTPUT_DIR)
JT_JAVA=$(JT_JAVA) $(JTREG) \
-J-Xmx512m \
- -a -samevm -ignore:quiet -v:fail,error,nopass \
+ -a -ignore:quiet -v:fail,error,nopass \
-r:$(JTREG_OUTPUT_DIR)/JTreport \
-w:$(JTREG_OUTPUT_DIR)/JTwork \
-jdk:$(TESTJAVA) \
--- a/langtools/test/com/sun/javadoc/MetaTag/MetaTag.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/com/sun/javadoc/MetaTag/MetaTag.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -24,9 +24,6 @@
import java.text.SimpleDateFormat;
import java.util.Date;
-import com.sun.tools.doclets.formats.html.ConfigurationImpl;
-import com.sun.tools.doclets.internal.toolkit.Configuration;
-
/*
* @test
* @bug 4034096 4764726 6235799
@@ -135,13 +132,7 @@
*/
public static void main(String[] args) {
MetaTag tester = new MetaTag();
- Configuration config = ConfigurationImpl.getInstance();
- boolean defaultKeywordsSetting = config.keywords;
- boolean defaultTimestampSetting = config.notimestamp;
run(tester, ARGS, TEST, NEGATED_TEST);
- //Variable needs to be reset because Configuration is a singleton.
- config.keywords = defaultKeywordsSetting;
- config.notimestamp = defaultTimestampSetting;
run(tester, ARGS_NO_TIMESTAMP_NO_KEYWORDS, TEST2, NEGATED_TEST2);
tester.printSummary();
}
--- a/langtools/test/com/sun/javadoc/testHtmlDocument/TestHtmlDocument.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/com/sun/javadoc/testHtmlDocument/TestHtmlDocument.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, 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
@@ -60,7 +60,7 @@
// Generate the HTML output using the HTML document generation within doclet.
public static String generateHtmlTree() {
// Document type for the HTML document
- DocType htmlDocType = DocType.Transitional();
+ DocType htmlDocType = DocType.TRANSITIONAL;
HtmlTree html = new HtmlTree(HtmlTag.HTML);
HtmlTree head = new HtmlTree(HtmlTag.HEAD);
HtmlTree title = new HtmlTree(HtmlTag.TITLE);
--- a/langtools/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/com/sun/javadoc/testHtmlTableTags/TestHtmlTableTags.java Fri Nov 30 17:09:05 2012 -0800
@@ -201,7 +201,15 @@
"<caption><span>Fields</span><span class=\"tabEnd\"> </span></caption>"
},
{BUG_ID + FS + "pkg1" + FS + "C1.html",
- "<caption><span>Methods</span><span class=\"tabEnd\"> </span></caption>"
+ "<caption><span id=\"t0\" class=\"activeTableTab\"><span>All " +
+ "Methods</span><span class=\"tabEnd\"> </span></span>" +
+ "<span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">" +
+ "Instance Methods</a></span><span class=\"tabEnd\"> </span></span>" +
+ "<span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">" +
+ "Concrete Methods</a></span><span class=\"tabEnd\"> </span></span>" +
+ "<span id=\"t5\" class=\"tableTab\"><span><a href=\"javascript:show(16);\">" +
+ "Deprecated Methods</a></span><span class=\"tabEnd\"> </span></span>" +
+ "</caption>"
},
{BUG_ID + FS + "pkg2" + FS + "C2.html",
"<caption><span>Nested Classes</span><span class=\"tabEnd\"> </span></caption>"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testMethodTypes/TestMethodTypes.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2012, 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 8002304
+ * @summary Test for various method types in the method summary table
+ * @author Bhavesh Patel
+ * @library ../lib/
+ * @build JavadocTester TestMethodTypes
+ * @run main TestMethodTypes
+ */
+
+public class TestMethodTypes extends JavadocTester {
+
+ //Test information.
+ private static final String BUG_ID = "8002304";
+
+ //Javadoc arguments.
+ private static final String[] ARGS = new String[] {
+ "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"
+ };
+
+ private static final String[][] TEST = {
+ {BUG_ID + FS + "pkg1" + FS + "A.html",
+ "var methods = {"
+ },
+
+ {BUG_ID + FS + "pkg1" + FS + "A.html",
+ "<caption><span id=\"t0\" class=\"activeTableTab\"><span>All " +
+ "Methods</span><span class=\"tabEnd\"> </span></span>" +
+ "<span id=\"t1\" class=\"tableTab\"><span><a href=\"javascript:show(1);\">" +
+ "Static Methods</a></span><span class=\"tabEnd\"> </span></span>" +
+ "<span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">" +
+ "Instance Methods</a></span><span class=\"tabEnd\"> </span></span>" +
+ "<span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">" +
+ "Concrete Methods</a></span><span class=\"tabEnd\"> </span></span>" +
+ "<span id=\"t5\" class=\"tableTab\"><span><a href=\"javascript:show(16);\">" +
+ "Deprecated Methods</a></span><span class=\"tabEnd\"> </span></span>" +
+ "</caption>"
+ },
+
+ {BUG_ID + FS + "pkg1" + FS + "A.html",
+ "<tr id=\"i0\" class=\"altColor\">"
+ },
+
+ {BUG_ID + FS + "pkg1" + FS + "B.html",
+ "<caption><span id=\"t0\" class=\"activeTableTab\"><span>All " +
+ "Methods</span><span class=\"tabEnd\"> </span></span>" +
+ "<span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">" +
+ "Instance Methods</a></span><span class=\"tabEnd\"> </span></span>" +
+ "<span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">" +
+ "Abstract Methods</a></span><span class=\"tabEnd\"> </span></span>" +
+ "</caption>"
+ },
+
+ {BUG_ID + FS + "pkg1" + FS + "D.html",
+ "var methods = {"
+ },
+
+ {BUG_ID + FS + "pkg1" + FS + "D.html",
+ "<caption><span id=\"t0\" class=\"activeTableTab\"><span>All " +
+ "Methods</span><span class=\"tabEnd\"> </span></span>" +
+ "<span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">" +
+ "Instance Methods</a></span><span class=\"tabEnd\"> </span></span>" +
+ "<span id=\"t3\" class=\"tableTab\"><span><a href=\"javascript:show(4);\">" +
+ "Abstract Methods</a></span><span class=\"tabEnd\"> </span></span>" +
+ "<span id=\"t4\" class=\"tableTab\"><span><a href=\"javascript:show(8);\">" +
+ "Concrete Methods</a></span><span class=\"tabEnd\"> </span></span>" +
+ "<span id=\"t5\" class=\"tableTab\"><span><a href=\"javascript:show(16);\">" +
+ "Deprecated Methods</a></span><span class=\"tabEnd\"> </span></span>" +
+ "</caption>"
+ },
+
+ {BUG_ID + FS + "pkg1" + FS + "D.html",
+ "<tr id=\"i0\" class=\"altColor\">"
+ },
+ };
+ private static final String[][] NEGATED_TEST = {
+ {BUG_ID + FS + "pkg1" + FS + "A.html",
+ "<caption><span>Methods</span><span class=\"tabEnd\"> </span>" +
+ "</caption>"
+ },
+
+ {BUG_ID + FS + "pkg1" + FS + "B.html",
+ "<caption><span>Methods</span><span class=\"tabEnd\"> </span>" +
+ "</caption>"
+ },
+
+ {BUG_ID + FS + "pkg" + FS + "D.html",
+ "<caption><span>Methods</span><span class=\"tabEnd\"> </span>" +
+ "</caption>"
+ },
+ };
+
+ /**
+ * The entry point of the test.
+ * @param args the array of command line arguments.
+ */
+ public static void main(String[] args) {
+ TestMethodTypes tester = new TestMethodTypes();
+ run(tester, ARGS, TEST, NEGATED_TEST);
+ tester.printSummary();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getBugId() {
+ return BUG_ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getBugName() {
+ return getClass().getName();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testMethodTypes/pkg1/A.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+package pkg1;
+
+/**
+ * This class has a mixture of different types of methods. The methods summary
+ * table should appear with "All Methods", "Static Methods", "Instance Methods",
+ * "Concrete Methods" and "Deprecated Methods".
+ */
+public class A {
+
+ /**
+ * This is the first concrete instance method.
+ */
+ public void readObject() {
+ }
+
+ /**
+ * This is the second concrete instance method.
+ */
+ public final void setStub() {
+ }
+
+ /**
+ * This is the third concrete instance method.
+ */
+ public String getParameter() {
+ return "test";
+ }
+
+ /**
+ * This is the first concrete instance deprecated method.
+ * @deprecated This is a deprecated method that should appear in the tab.
+ */
+ public void resize() {
+ }
+
+ /**
+ * This is the fourth concrete instance method.
+ */
+ public void showStatus() {
+ }
+
+ /**
+ * This is the first concrete static method.
+ */
+ public final static void staticMethod() {
+ }
+
+ /**
+ * This is the second concrete instance deprecated method.
+ */
+ @Deprecated
+ public void init() {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testMethodTypes/pkg1/B.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+package pkg1;
+
+/**
+ * This interface has different types of methods such as "Instance Methods" and
+ * "Abstract Methods". All the tabs will display same list of methods.
+ */
+public interface B {
+
+ /**
+ * This is the first abstract instance method.
+ */
+ public void setName();
+
+ /**
+ * This is the second abstract instance method.
+ */
+ public String getName();
+
+ /**
+ * This is the third abstract instance method.
+ */
+ public boolean addEntry();
+
+ /**
+ * This is the fourth abstract instance method.
+ */
+ public boolean removeEntry();
+
+ /**
+ * This is the fifth abstract instance method.
+ */
+ public String getPermissions();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testMethodTypes/pkg1/D.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+package pkg1;
+
+/**
+ * This class is marked as deprecated and has a mixture of different types of
+ * methods such as "Instance Methods", "Abstract Methods" and "Concrete
+ * Methods". None of the methods are marked as deprecated but since the class is
+ * deprecated, the methods will also be deprecated and "Deprecated Methods" tab
+ * will also be shown with all the methods.
+ */
+@Deprecated
+public abstract class D {
+
+ /**
+ * This is the first abstract instance method.
+ */
+ public abstract void readObject();
+
+ /**
+ * This is the first concrete instance method.
+ */
+ public final void setStub() {
+ }
+
+ /**
+ * This is the second concrete instance method.
+ */
+ public String getParameter() {
+ return "test";
+ }
+}
--- a/langtools/test/tools/javac/7132880/T7132880.out Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/7132880/T7132880.out Fri Nov 30 17:09:05 2012 -0800
@@ -1,4 +1,4 @@
T7132880.java:23:12: compiler.err.cant.apply.symbol: kindname.method, m1, java.lang.Integer, java.lang.String, kindname.class, Outer.Inner1, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer))
-T7132880.java:33:12: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.String,{(compiler.misc.inapplicable.method: kindname.method, Outer.Inner2, m1(java.lang.Double), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Double))),(compiler.misc.inapplicable.method: kindname.method, Outer.Inner2, m1(java.lang.Integer), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer)))}
+T7132880.java:33:12: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.String,{(compiler.misc.inapplicable.method: kindname.method, Outer.Inner2, m1(java.lang.Integer), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer))),(compiler.misc.inapplicable.method: kindname.method, Outer.Inner2, m1(java.lang.Double), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Double)))}
T7132880.java:43:12: compiler.err.ref.ambiguous: m2, kindname.method, m2(java.lang.Object,int), Outer.Inner3, kindname.method, m2(int,java.lang.Object), Outer.Inner3
3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8002286/T8002286.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8002286
+ * @summary Resolve should support nested resolution contexts
+ * @compile/fail/ref=T8002286.out -XDrawDiagnostics T8002286.java
+ */
+class T8002286 {
+ @Anno(nonExistent())
+ static class Test { }
+
+ @interface Anno { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8002286/T8002286.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+T8002286.java:8:22: compiler.err.cant.resolve.location.args: kindname.method, value, , , (compiler.misc.location: kindname.annotation, T8002286.Anno, null)
+T8002286.java:8:11: compiler.err.cant.resolve.location.args: kindname.method, nonExistent, , , (compiler.misc.location: kindname.class, T8002286, null)
+2 errors
--- a/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out Fri Nov 30 17:09:05 2012 -0800
@@ -1,4 +1,4 @@
-T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.type.captureof: 1, ?, T6799605<compiler.misc.type.captureof: 1, ?>))}
-T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 2, ?, compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
-T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 3, ?, compiler.misc.type.captureof: 3, ?,compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
+T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.type.captureof: 1, ?, T6799605<compiler.misc.type.captureof: 1, ?>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
+T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 2, ?, compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
+T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 3, ?, compiler.misc.type.captureof: 3, ?,compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?))}
3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2012, 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 8002157
+ * @author sogoel
+ * @summary Basic Syntax test for repeating annotations on all elements
+ * @build Helper
+ * @compile BasicSyntaxCombo.java
+ * @run main BasicSyntaxCombo
+ */
+
+
+import java.util.Arrays;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+import javax.tools.Diagnostic;
+
+/*
+ * Generate test src for element kinds with repeating annotations.
+ * The test uses Helper.java to get the template to create test src and
+ * compile the test src.
+ * The test passes if valid test src compile as expected and
+ * and invalid test src fail as expected.
+ */
+
+public class BasicSyntaxCombo extends Helper{
+ static int errors = 0;
+ static boolean exitMode = false;
+ static String TESTPKG = "testpkg";
+ static String srcContent = "";
+ static String pkgInfoContent = "";
+
+ static {
+ // If EXIT_ON_FAIL is set, the combo test will exit at the first error
+ String exitOnFail = System.getenv("EXIT_ON_FAIL");
+ if (exitOnFail == null || exitOnFail == "" ) {
+ exitMode = false;
+ }
+ else {
+ if (exitOnFail.equalsIgnoreCase("YES") ||
+ exitOnFail.equalsIgnoreCase("Y") ||
+ exitOnFail.equalsIgnoreCase("TRUE") ||
+ exitOnFail.equalsIgnoreCase("T")) {
+ exitMode = true;
+ }
+ }
+ }
+
+ enum TestElem {
+ ANNOTATION_TYPE(true),
+ PACKAGE(true),
+ CONSTRUCTOR(true),
+ FIELD(true),
+ LOCAL_VARIABLE(true),
+ METHOD(true),
+ TYPE(true),
+ PARAMETER(true),
+ INNER_CLASS(true),
+ STATIC_INI(false),
+ INSTANCE_INI(false);
+
+ TestElem(boolean compile) {
+ this.compile = compile;
+ }
+
+ boolean compile;
+ boolean shouldCompile() {
+ return compile;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ new BasicSyntaxCombo().runTest();
+ }
+
+ public void runTest() throws Exception {
+ boolean result = false;
+ Iterable<? extends JavaFileObject> files = null;
+ int testCtr = 0;
+ for (TestElem type : TestElem.values()) {
+ testCtr++;
+ String className = "BasicCombo_"+type;
+ files = getFileList(className, type);
+
+ boolean shouldCompile = type.shouldCompile();
+ result = getCompileResult(className, shouldCompile,files);
+
+ if (shouldCompile && !result) {
+ error(className + " did not compile as expected", srcContent);
+ if(!pkgInfoContent.isEmpty()) {
+ System.out.println("package-info.java contents: " + pkgInfoContent);
+ }
+ }
+
+ if (!shouldCompile && !result) {
+ error(className + " compiled unexpectedly", srcContent);
+ if(!pkgInfoContent.isEmpty()) {
+ System.out.println("package-info.java contents: " + pkgInfoContent);
+ }
+ }
+ }
+
+ System.out.println("Total number of tests run: " + testCtr);
+ System.out.println("Total number of errors: " + errors);
+
+ if (errors > 0)
+ throw new Exception(errors + " errors found");
+ }
+
+ private boolean getCompileResult(String className, boolean shouldCompile,
+ Iterable<? extends JavaFileObject> files) throws Exception {
+
+ DiagnosticCollector<JavaFileObject> diagnostics =
+ new DiagnosticCollector<JavaFileObject>();
+ boolean ok = Helper.compileCode(diagnostics,files);
+ if (!shouldCompile && !ok) {
+ checkErrorKeys(className, diagnostics);
+ }
+ return (shouldCompile == ok);
+ }
+
+ private void checkErrorKeys (
+ String className, DiagnosticCollector<JavaFileObject> diagnostics) throws Exception {
+ String expectedErrKey = "compiler.err.illegal.start.of.type";
+ for (Diagnostic<?> d : diagnostics.getDiagnostics()) {
+ if ((d.getKind() == Diagnostic.Kind.ERROR) &&
+ d.getCode().contains(expectedErrKey)) {
+ break; // Found the expected error
+ } else {
+ error("Incorrect error key, expected = "
+ + expectedErrKey + ", Actual = " + d.getCode()
+ + " for className = " + className, srcContent);
+ }
+ }
+ }
+
+ private Iterable<? extends JavaFileObject> getFileList(String className,
+ TestElem type ) {
+
+ String template = Helper.template;
+ String replaceStr = "/*"+type+"*/";
+ StringBuilder annoData = new StringBuilder();
+ annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal())
+ .append(Helper.ContentVars.CONTAINERFOR.getVal())
+ .append(Helper.ContentVars.CONTAINER.getVal())
+ .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.BASE.getVal());
+
+ JavaFileObject pkgInfoFile = null;
+
+ if (type.equals("PACKAGE")) {
+ srcContent = template.replace(replaceStr, "package testpkg;")
+ .replace("#ClassName", className);
+
+ String pkgInfoName = TESTPKG+"."+"package-info";
+ pkgInfoContent = Helper.ContentVars.REPEATABLEANNO.getVal()
+ + "package " + TESTPKG + ";"
+ + annoData;
+ pkgInfoFile = getFile(pkgInfoName, pkgInfoContent);
+ } else {
+ template = template.replace(replaceStr, Helper.ContentVars.REPEATABLEANNO.getVal())
+ .replace("#ClassName", className);
+ srcContent = annoData + template;
+ }
+
+ JavaFileObject srcFile = getFile(className, srcContent);
+
+ Iterable<? extends JavaFileObject> files = null;
+ if (pkgInfoFile != null) {
+ files = Arrays.asList(pkgInfoFile,srcFile);
+ }
+ else {
+ files = Arrays.asList(srcFile);
+ }
+ return files;
+ }
+
+ private void error(String msg, String... contents) throws Exception {
+ System.out.println("error: " + msg);
+ errors++;
+ if (contents.length == 1) {
+ System.out.println("Contents = " + contents[0]);
+ }
+ // Test exits as soon as it gets a failure
+ if (exitMode) throw new Exception();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2012, 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 8002157
+ * @author sogoel
+ * @summary Combo test to check for usage of Deprecated
+ * @build Helper
+ * @compile DeprecatedAnnoCombo.java
+ * @run main DeprecatedAnnoCombo
+ */
+
+import java.util.List;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+
+/*
+ * Generate test src for use of @Deprecated on base anno
+ * or container anno or on both. In all cases, test src should compile and a
+ * warning should be generated. Repeating annotations used only on class for
+ * these generated test src.
+ */
+
+public class DeprecatedAnnoCombo extends Helper {
+ static int errors = 0;
+
+ enum TestCases {
+ DeprecatedonBoth,
+ DeprecatedonContainer,
+ DeprecatedonBase;
+ }
+
+ public static void main(String[] args) throws Exception {
+ new DeprecatedAnnoCombo().runTest();
+ }
+
+ public void runTest() throws Exception {
+ boolean ok = false;
+ int testCtr = 0;
+
+ for (TestCases clName : TestCases.values()) {
+ testCtr++;
+
+ // Create test source content
+ String contents = getContent(clName.toString());
+
+ // Compile the generated source file
+ DiagnosticCollector<JavaFileObject> diagnostics =
+ new DiagnosticCollector<JavaFileObject>();
+ ok = compileCode(clName.toString(), contents, diagnostics);
+
+ String errorKey1 = "compiler.note.deprecated.filename";
+ String errorKey2 = "compiler.note.deprecated.recompile";
+ List<Diagnostic<? extends JavaFileObject>> diags = diagnostics.getDiagnostics();
+
+ //Check for deprecated warnings
+ if (ok) {
+ if (diags.size() == 0) {
+ error("Did not get any warnings for @Deprecated usage");
+ } else {
+ for (Diagnostic<?> d : diags) {
+ if (d.getKind() == Diagnostic.Kind.NOTE) {
+ if (d.getCode().contains(errorKey1)
+ || d.getCode().contains(errorKey2)) {
+ System.out.println("TestCase =" + clName + " passed as expected");
+ } else {
+ error("TestCase =" + clName + " did not give correct warnings" +
+ "Expected warning keys: " +
+ "errorKey1 = " + errorKey1 +
+ "errorKey2 = " + errorKey2 +
+ "actualErrorKey = " + d.getCode(), contents);
+ }
+ } else {
+ error("Diagnostic Kind is incorrect, expected = " +
+ Diagnostic.Kind.NOTE + "actual = " + d.getKind(), contents);
+ }
+ }
+ }
+ } else {
+ error("TestCase =" + clName + " did not compile as expected", contents);
+ }
+ }
+
+ System.out.println("Total number of tests run: " + testCtr);
+ System.out.println("Total number of errors: " + errors);
+ if (errors > 0)
+ throw new Exception(errors + " errors found");
+ }
+
+ private String getContent(String className) {
+ StringBuilder annoData = new StringBuilder();
+
+ switch(className) {
+ case "DeprecatedonBoth":
+ annoData.append(Helper.ContentVars.DEPRECATED.getVal())
+ .append(Helper.ContentVars.CONTAINERFOR.getVal())
+ .append(Helper.ContentVars.CONTAINER.getVal())
+ .append(Helper.ContentVars.DEPRECATED.getVal())
+ .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.BASE.getVal());
+ break;
+ case "DeprecatedonBase":
+ annoData.append(Helper.ContentVars.CONTAINERFOR.getVal())
+ .append(Helper.ContentVars.CONTAINER.getVal())
+ .append(Helper.ContentVars.DEPRECATED.getVal())
+ .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.BASE.getVal());
+ break;
+ case "DeprecatedonContainer":
+ annoData.append(Helper.ContentVars.DEPRECATED.getVal())
+ .append(Helper.ContentVars.CONTAINERFOR.getVal())
+ .append(Helper.ContentVars.CONTAINER.getVal())
+ .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.BASE.getVal());
+ break;
+ }
+
+ String contents = Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal()
+ + Helper.ContentVars.IMPORTDEPRECATED.getVal()
+ + annoData
+ + Helper.ContentVars.REPEATABLEANNO.getVal()
+ + "\nclass "+ className + "{}";
+ return contents;
+ }
+
+ private void error(String msg, String... contents) {
+ System.out.println("error: " + msg);
+ errors++;
+ if (contents.length == 1) {
+ System.out.println("Contents = " + contents[0]);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2012, 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 8002157
+ * @author sogoel
+ * @summary Positive combo test for use of Documented on baseAnno/containerAnno
+ * @build Helper
+ * @compile DocumentedAnnoCombo.java
+ * @run main DocumentedAnnoCombo
+ */
+
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+
+/*
+ * Generate valid test src for the use of @Documented on container anno
+ * or on both base anno and container anno. Both test src should compile.
+ * Repeating annotations used only on class for these generated test src.
+ */
+public class DocumentedAnnoCombo extends Helper {
+ static int errors = 0;
+
+ enum TestCases {
+ DocumentedonBothAnno(true),
+ DocumentedonContainer(true);
+
+ TestCases(boolean compile) {
+ this.compile = compile;
+ }
+
+ boolean compile;
+ boolean shouldCompile() {
+ return compile;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ new DocumentedAnnoCombo().runTest();
+ }
+
+ public void runTest() throws Exception {
+ boolean ok = false;
+ int testCtr = 0;
+
+ // Create test source content
+ for (TestCases className : TestCases.values()) {
+ testCtr++;
+ String contents = getContent(className.toString());
+
+ // Compile the generated source file
+ DiagnosticCollector<JavaFileObject> diagnostics =
+ new DiagnosticCollector<JavaFileObject>();
+ ok = compileCode(className.toString(), contents, diagnostics);
+ if (!ok) {
+ error("Class="+ className +" did not compile as expected", contents);
+ } else {
+ System.out.println("Test passed for className: " + className);
+ }
+ }
+
+ System.out.println("Total number of tests run: " + testCtr);
+ System.out.println("Total number of errors: " + errors);
+
+ if (errors > 0)
+ throw new Exception(errors + " errors found");
+ }
+
+ private String getContent(String className) {
+
+ StringBuilder annoData = new StringBuilder();
+ switch(className) {
+ case "DocumentedonBothAnno":
+ annoData.append(Helper.ContentVars.DOCUMENTED.getVal())
+ .append(Helper.ContentVars.CONTAINERFOR.getVal())
+ .append(Helper.ContentVars.CONTAINER.getVal())
+ .append(Helper.ContentVars.DOCUMENTED.getVal())
+ .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.BASE.getVal());
+ break;
+ case "DocumentedonContainer":
+ annoData.append(Helper.ContentVars.DOCUMENTED.getVal())
+ .append(Helper.ContentVars.CONTAINERFOR.getVal())
+ .append(Helper.ContentVars.CONTAINER.getVal())
+ .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.BASE.getVal());
+ break;
+ }
+
+ String contents = Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal()
+ + Helper.ContentVars.IMPORTDOCUMENTED.getVal()
+ + annoData
+ + Helper.ContentVars.REPEATABLEANNO.getVal()
+ + "\nclass "+ className + "{}";
+ return contents;
+ }
+
+ private void error(String msg, String... contents) {
+ System.out.println("error: " + msg);
+ errors++;
+ if (contents.length == 1) {
+ System.out.println("Contents = " + contents[0]);
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2012, 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.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+import javax.tools.JavaCompiler.CompilationTask;
+
+public class Helper {
+
+ enum ContentVars {
+ IMPORTCONTAINERSTMTS("\nimport java.lang.annotation.ContainedBy;\n" +
+ "\nimport java.lang.annotation.ContainerFor;\n"),
+ IMPORTDEPRECATED("import java.lang.Deprecated;\n"),
+ IMPORTDOCUMENTED("import java.lang.annotation.Documented;\n"),
+ IMPORTINHERITED("import java.lang.annotation.Inherited;\n"),
+ IMPORTRETENTION("import java.lang.annotation.Retention;\n" +
+ "\nimport java.lang.annotation.RetentionPolicy;\n"),
+ CONTAINEDBY("\n@ContainedBy(FooContainer.class)\n"),
+ CONTAINERFOR("@ContainerFor(Foo.class)\n"),
+ CONTAINER("@interface FooContainer {\n" +" Foo[] value();\n}\n"),
+ BASE("@interface Foo {}\n"),
+ REPEATABLEANNO("\n@Foo() @Foo()"),
+ DEPRECATED("\n@Deprecated"),
+ DOCUMENTED("\n@Documented"),
+ INHERITED("\n@Inherited"),
+ RETENTION("@Retention(RetentionPolicy.#VAL)\n");
+
+ private String val;
+
+
+ private ContentVars(String val) {
+ this.val = val;
+ }
+
+ public String getVal() {
+ return val;
+ }
+ }
+
+ /* String template where /*<TYPE>*/ /*gets replaced by repeating anno
+ * Used to generate test src for combo tests
+ * - BasicSyntaxCombo.java
+ * - TargetAnnoCombo.java
+ */
+ public static final String template =
+ "/*PACKAGE*/\n" +
+ "//pkg test;\n\n" +
+ "/*TYPE*/ //class\n" +
+ "class #ClassName {\n" +
+ " /*FIELD*/ //instance var\n" +
+ " public int x = 0;\n\n" +
+ " /*FIELD*/ //Enum constants\n" +
+ " TestEnum testEnum;\n\n" +
+ " /*FIELD*/ // Static field\n" +
+ " public static int num;\n\n" +
+ " /*STATIC_INI*/\n" +
+ " static { \n" + "num = 10; \n }\n\n" +
+ " /*CONSTRUCTOR*/\n" +
+ " #ClassName() {}\n\n" +
+ " /*INSTANCE_INI*/\n" +
+ " { \n x = 10; \n }" +
+ " /*INNER_CLASS*/\n" +
+ " class innerClass {}\n" +
+ " /*METHOD*/\n" +
+ " void bar(/*PARAMETER*/ int baz) {\n" +
+ " /*LOCAL_VARIABLE*/\n" +
+ " int y = 0;\n" +
+ " }\n" +
+ "}\n\n" +
+ "/*TYPE*/ //Enum\n" +
+ "enum TestEnum {}\n\n" +
+ "/*TYPE*/ //Interface\n" +
+ "interface TestInterface {}\n\n" +
+ "/*TYPE*/\n" +
+ "/*ANNOTATION_TYPE*/\n" +
+ "@interface TestAnnotationType{}\n";
+
+ // Create and compile FileObject using values for className and contents
+ public static boolean compileCode(String className, String contents,
+ DiagnosticCollector<JavaFileObject> diagnostics) {
+ boolean ok = false;
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ throw new RuntimeException("can't get javax.tools.JavaCompiler!");
+ }
+
+ JavaFileObject file = getFile(className, contents);
+ Iterable<? extends JavaFileObject> compilationUnit = Arrays.asList(file);
+
+ CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnit);
+ ok = task.call();
+ return ok;
+
+ }
+
+ // Compile a list of FileObjects
+ public static boolean compileCode(DiagnosticCollector<JavaFileObject> diagnostics, Iterable<? extends JavaFileObject> files) {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ throw new RuntimeException("can't get javax.tools.JavaCompiler!");
+ }
+
+ CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, files);
+ boolean ok = task.call();
+ return ok;
+ }
+
+ static JavaFileObject getFile(String name, String code) {
+ JavaFileObject o = null;
+ try {
+ o = new JavaStringFileObject(name, code);
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ return o;
+ }
+ static class JavaStringFileObject extends SimpleJavaFileObject {
+ final String theCode;
+ public JavaStringFileObject(String fileName, String theCode) throws URISyntaxException {
+ super(new URI("string:///" + fileName.replace('.','/') + ".java"), Kind.SOURCE);
+ this.theCode = theCode;
+ }
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return theCode;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012, 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 8002157
+ * @author sogoel
+ * @summary Positive combo test for use of Inherited on baseAnno/containerAnno
+ * @build Helper
+ * @compile InheritedAnnoCombo.java
+ * @run main InheritedAnnoCombo
+ */
+
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+
+/*
+ * Generate valid test src for the use of @Inherited on container anno
+ * or on both base anno and container anno. Both test src should compile.
+ * Repeating annotations used only on class for these generated test src.
+ */
+
+public class InheritedAnnoCombo extends Helper {
+ static int errors = 0;
+ enum TestCases {
+ InheritedonBothAnno(true),
+ InheritedonBase(true);
+
+ TestCases(boolean compile) {
+ this.compile = compile;
+ }
+
+ boolean compile;
+ boolean shouldCompile() {
+ return compile;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ new InheritedAnnoCombo().runTest();
+ }
+
+ public void runTest() throws Exception {
+ int testCtr = 0;
+ boolean ok = false;
+
+ // Create test source content
+ for (TestCases className : TestCases.values()) {
+ testCtr++;
+ String contents = getContent(className.toString());
+
+ // Compile the generated code
+ DiagnosticCollector<JavaFileObject> diagnostics =
+ new DiagnosticCollector<JavaFileObject>();
+ ok = compileCode(className.toString(), contents, diagnostics);
+
+ if (!ok) {
+ error("Class="+ className +" did not compile as expected", contents);
+ } else {
+ System.out.println("Test passed for className: " + className);
+ }
+ }
+
+ System.out.println("Total number of tests run: " + testCtr);
+ System.out.println("Total number of errors: " + errors);
+
+ if (errors > 0)
+ throw new Exception(errors + " errors found");
+ }
+
+ private String getContent(String className) {
+
+ StringBuilder annoData = new StringBuilder();
+ switch(className) {
+ case "InheritedonBothAnno":
+ annoData.append(Helper.ContentVars.INHERITED.getVal())
+ .append(Helper.ContentVars.CONTAINERFOR.getVal())
+ .append(Helper.ContentVars.CONTAINER.getVal())
+ .append(Helper.ContentVars.INHERITED.getVal())
+ .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.BASE.getVal());
+ break;
+ case "InheritedonBase":
+ annoData.append(Helper.ContentVars.INHERITED.getVal())
+ .append(Helper.ContentVars.CONTAINERFOR.getVal())
+ .append(Helper.ContentVars.CONTAINER.getVal())
+ .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(Helper.ContentVars.BASE.getVal());
+ break;
+ }
+
+ String contents = Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal()
+ + Helper.ContentVars.IMPORTINHERITED.getVal()
+ + annoData
+ + Helper.ContentVars.REPEATABLEANNO.getVal()
+ + "\nclass "+ className + "{}";
+ return contents;
+ }
+
+ private void error(String msg, String... contents) {
+ System.out.println("error: " + msg);
+ errors++;
+ if (contents.length == 1) {
+ System.out.println("Contents = " + contents[0]);
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2012, 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 8002157
+ * @author sogoel
+ * @summary Combo test for all possible combinations for Retention Values
+ * @build Helper
+ * @compile RetentionAnnoCombo.java
+ * @run main RetentionAnnoCombo
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+import javax.tools.Diagnostic;
+
+/*
+ * Generate all combinations for the use of @Retention on base anno or container
+ * anno or both. The test passes if valid test src compile as expected and
+ * and invalid test src fail as expected.
+ * Repeating annotations used only on class for these generated test src.
+ */
+
+public class RetentionAnnoCombo extends Helper {
+ static int errors = 0;
+ static boolean exitMode = false;
+ static {
+ String exitOnFail = System.getenv("EXIT_ON_FAIL");
+ if (exitOnFail == null || exitOnFail == "" ) {
+ exitMode = false;
+ }
+ else {
+ if (exitOnFail.equalsIgnoreCase("YES") ||
+ exitOnFail.equalsIgnoreCase("Y") ||
+ exitOnFail.equalsIgnoreCase("TRUE") ||
+ exitOnFail.equalsIgnoreCase("T")) {
+ exitMode = true;
+ }
+ }
+ }
+
+ public static void main(String args[]) throws Exception {
+ new RetentionAnnoCombo().runTest();
+ }
+
+ public void runTest() throws Exception {
+
+ /* 4x4 matrix for Retention values SOURCE, DEFAULT, CLASS, RUNTIME
+ * i -> Retention value on ContainerAnno
+ * j -> Retention value on BaseAnno
+ * 1 -> retention value combo should compile
+ */
+ int[][] retention = { {1, 0, 0, 0},
+ {1, 1, 1, 0},
+ {1, 1, 1, 0},
+ {1, 1, 1, 1} };
+
+ Map<Integer, String> retMap = setRetentionValMatrix();
+ String contents = "";
+ boolean result = false;
+ int testCtr = 0;
+ for (int i = 0; i < 4 ; i ++) {
+ for (int j = 0; j < 4; j++ ) {
+ testCtr++;
+ String className = "RetentionTest_"+i+"_"+j;
+ contents = getContent(className, retMap, i, j);
+ if (retention[i][j] == 1) {
+ // Code generated should compile
+ result = getCompileResult(contents,className, true);
+ if (!result) {
+ error("FAIL: " + className + " did not compile as expected!", contents);
+ }
+ } else {
+ result = getCompileResult(contents,className, false);
+ if (!result) {
+ error("FAIL: " + className + " compiled unexpectedly!", contents);
+ }
+ }
+ if (result) {
+ System.out.println("Test passed for className = " + className);
+ }
+ }
+ }
+
+ System.out.println("Total number of tests run: " + testCtr);
+ System.out.println("Total number of errors: " + errors);
+
+ if (errors > 0)
+ throw new Exception(errors + " errors found");
+ }
+
+ private boolean getCompileResult(String contents, String className,
+ boolean shouldCompile) throws Exception{
+
+ DiagnosticCollector<JavaFileObject> diagnostics =
+ new DiagnosticCollector<JavaFileObject>();
+ boolean ok = compileCode(className, contents, diagnostics);
+
+ String expectedErrKey = "compiler.err.invalid.containedby" +
+ ".annotation.retention";
+ if (!shouldCompile && !ok) {
+ for (Diagnostic<?> d : diagnostics.getDiagnostics()) {
+ if (!((d.getKind() == Diagnostic.Kind.ERROR) &&
+ d.getCode().contains(expectedErrKey))) {
+ error("FAIL: Incorrect error given, expected = "
+ + expectedErrKey + ", Actual = " + d.getCode()
+ + " for className = " + className, contents);
+ }
+ }
+ }
+
+ return (shouldCompile == ok);
+ }
+
+ private Map<Integer,String> setRetentionValMatrix() {
+ HashMap<Integer,String> hm = new HashMap<>();
+ hm.put(0,"SOURCE");
+ hm.put(1,"DEFAULT");
+ hm.put(2,"CLASS");
+ hm.put(3,"RUNTIME");
+ return hm;
+ }
+
+ private String getContent(String className, Map<Integer, String> retMap,
+ int i, int j) {
+
+ String retContainerVal = retMap.get(i).toString();
+ String retBaseVal = retMap.get(j).toString();
+ String replacedRetBaseVal = "", replacedRetCAVal = "";
+ String retention = Helper.ContentVars.RETENTION.getVal();
+
+ // @Retention is available as default for both base and container anno
+ if (retContainerVal.equalsIgnoreCase("DEFAULT")
+ && retBaseVal.equalsIgnoreCase("DEFAULT")) {
+ replacedRetBaseVal = "";
+ replacedRetCAVal = "";
+ // @Retention is available as default for container anno
+ } else if (retContainerVal.equalsIgnoreCase("DEFAULT")) {
+ replacedRetBaseVal = retention.replace("#VAL", retBaseVal);
+ replacedRetCAVal = "";
+ // @Retention is available as default for base anno
+ } else if (retBaseVal.equalsIgnoreCase("DEFAULT")) {
+ replacedRetBaseVal = "";
+ replacedRetCAVal = retention.replace("#VAL", retContainerVal);
+ // @Retention is not available as default for both base and container anno
+ } else {
+ replacedRetBaseVal = retention.replace("#VAL", retBaseVal);
+ replacedRetCAVal = retention.replace("#VAL", retContainerVal);
+ }
+
+ StringBuilder annoData = new StringBuilder();
+ annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal())
+ .append(Helper.ContentVars.IMPORTRETENTION.getVal())
+ .append(Helper.ContentVars.CONTAINERFOR.getVal())
+ .append(replacedRetCAVal)
+ .append(Helper.ContentVars.CONTAINER.getVal())
+ .append(Helper.ContentVars.CONTAINEDBY.getVal())
+ .append(replacedRetBaseVal)
+ .append(Helper.ContentVars.BASE.getVal());
+
+ String contents = annoData
+ + Helper.ContentVars.REPEATABLEANNO.getVal()
+ + "\nclass "+ className + "{}";
+ return contents;
+ }
+
+ private void error(String msg,String... contents) throws Exception {
+ System.out.println("error: " + msg);
+ errors++;
+ if (contents.length == 1) {
+ System.out.println("Contents = " + contents[0]);
+ }
+ // Test exits as soon as it gets a failure
+ if (exitMode) throw new Exception();
+ }
+}
+
--- a/langtools/test/tools/javac/classfiles/ClassVersionChecker.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/classfiles/ClassVersionChecker.java Fri Nov 30 17:09:05 2012 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 7157626
+ * @bug 7157626 8001112
* @summary Test major version for all legal combinations for -source and -target
* @author sgoel
*
@@ -57,14 +57,14 @@
* -1 => invalid combinations
*/
int[][] ver =
- {{51, -1, -1, -1, -1, -1, -1, -1},
- {48, 46, 47, 48, 49, 50, 51, 51},
- {48, 46, 47, 48, 49, 50, 51, 51},
- {48, -1, -1, 48, 49, 50, 51, 51},
- {51, -1, -1, -1, 49, 50, 51, 51},
- {51, -1, -1, -1, -1, 50, 51, 51},
- {51, -1, -1, -1, -1, -1, 51, 51},
- {51, -1, -1, -1, -1, -1, -1, 51}};
+ {{52, -1, -1, -1, -1, -1, -1, -1},
+ {48, 46, 47, 48, 49, 50, 51, 52},
+ {48, 46, 47, 48, 49, 50, 51, 52},
+ {48, -1, -1, 48, 49, 50, 51, 52},
+ {52, -1, -1, -1, 49, 50, 51, 52},
+ {52, -1, -1, -1, -1, 50, 51, 52},
+ {52, -1, -1, -1, -1, -1, 51, 52},
+ {52, -1, -1, -1, -1, -1, -1, 52}};
// Loop to run all possible combinations of source/target values
for (int i = 0; i< ver.length; i++) {
--- a/langtools/test/tools/javac/conditional/Conditional.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/conditional/Conditional.java Fri Nov 30 17:09:05 2012 -0800
@@ -27,8 +27,8 @@
* @summary Conditional operator applies assignment conversion
* @author Tim Hanson, BEA
*
- * @compile -XDallowPoly Conditional.java
- * @compile/fail Conditional.java
+ * @compile Conditional.java
+ * @compile/fail -source 7 Conditional.java
*/
import java.util.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethodExecution/DefaultMethodRegressionTests.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng DefaultMethodRegressionTests
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+/**
+ * This set of classes/interfaces (K/I/C) is specially designed to expose a
+ * bug in the JVM where it did not find some overloaded methods in some
+ * specific situations. (fixed by hotspot changeset ffb9316fd9ed)
+ */
+interface K {
+ int bbb(Long l);
+}
+
+interface I extends K {
+ default void aaa() {}
+ default void aab() {}
+ default void aac() {}
+
+ default int bbb(Integer i) { return 22; }
+ default int bbb(Float f) { return 33; }
+ default int bbb(Long l) { return 44; }
+ default int bbb(Double d) { return 55; }
+ default int bbb(String s) { return 66; }
+
+ default void caa() {}
+ default void cab() {}
+ default void cac() {}
+}
+
+class C implements I {}
+
+public class DefaultMethodRegressionTests {
+
+ @Test(groups = "vm")
+ public void testLostOverloadedMethod() {
+ C c = new C();
+ assertEquals(c.bbb(new Integer(1)), 22);
+ assertEquals(c.bbb(new Float(1.1)), 33);
+ assertEquals(c.bbb(new Long(1L)), 44);
+ assertEquals(c.bbb(new Double(0.01)), 55);
+ assertEquals(c.bbb(new String("")), 66);
+ }
+
+ // Test to ensure that the inference verifier accepts older classfiles
+ // with classes that implement interfaces with defaults.
+ @Test(groups = "vm")
+ public void testInferenceVerifier() {
+ // interface I { int m() default { return 99; } }
+ byte I_bytes[] = {
+ (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x33,
+ 0x00, 0x08, 0x07, 0x00, 0x06, 0x07, 0x00, 0x07,
+ 0x01, 0x00, 0x03, 0x66, 0x6f, 0x6f, 0x01, 0x00,
+ 0x03, 0x28, 0x29, 0x49, 0x01, 0x00, 0x04, 0x43,
+ 0x6f, 0x64, 0x65, 0x01, 0x00, 0x01, 0x49, 0x01,
+ 0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
+ 0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
+ 0x63, 0x74, 0x06, 0x00, 0x00, 0x01, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01,
+ 0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x03, 0x10, 0x63, (byte)0xac, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ // public class C implements I {} /* -target 1.5 */
+ byte C_bytes[] = {
+ (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x0c, 0x0a, 0x00, 0x03, 0x00, 0x08, 0x07,
+ 0x00, 0x09, 0x07, 0x00, 0x0a, 0x07, 0x00, 0x0b,
+ 0x01, 0x00, 0x06, 0x3c, 0x69, 0x6e, 0x69, 0x74,
+ 0x3e, 0x01, 0x00, 0x03, 0x28, 0x29, 0x56, 0x01,
+ 0x00, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x0c, 0x00,
+ 0x05, 0x00, 0x06, 0x01, 0x00, 0x01, 0x43, 0x01,
+ 0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
+ 0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
+ 0x63, 0x74, 0x01, 0x00, 0x01, 0x49, 0x00, 0x21,
+ 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x05,
+ 0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00,
+ 0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x05, 0x2a, (byte)0xb7, 0x00, 0x01, (byte)0xb1, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ ClassLoader cl = new ClassLoader() {
+ protected Class<?> findClass(String name) {
+ if (name.equals("I")) {
+ return defineClass("I", I_bytes, 0, I_bytes.length);
+ } else if (name.equals("C")) {
+ return defineClass("C", C_bytes, 0, C_bytes.length);
+ } else {
+ return null;
+ }
+ }
+ };
+ try {
+ Class.forName("C", true, cl);
+ } catch (Exception e) {
+ // unmodified verifier will throw VerifyError
+ fail("No exception should be thrown");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011, 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 check that default methods don't cause ClassReader to complete classes recursively
+ * @author Maurizio Cimadamore
+ * @compile pkg/Foo.java
+ * @compile ClassReaderTest.java
+ */
+
+abstract class ClassReaderTest implements pkg.Foo {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/pkg/Foo.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+package pkg;
+
+public interface Foo {
+ default void m1() { Impl.m1(this); }
+ default void m2() { Impl.m2(this); }
+}
+
+class Impl {
+ static void m1(Foo f) { }
+ static void m2(Foo f) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg01.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary negative test for ambiguous defaults
+ * @compile/fail/ref=Neg01.out -XDrawDiagnostics Neg01.java
+ */
+
+class Neg01 {
+ interface IA { default int m() { return Neg01.m1(this); } }
+ interface IB { default int m() { return Neg01.m2(this); } }
+
+ static class A implements IA {}
+ static class B implements IB {}
+
+ static class AB implements IA, IB {}
+
+ static int m1(IA a) { return 0; }
+ static int m2(IB b) { return 0; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg01.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+Neg01.java:14:12: compiler.err.types.incompatible.unrelated.defaults: kindname.class, Neg01.AB, m, , Neg01.IA, Neg01.IB
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg02.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,26 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that ill-formed MI hierarchies do not compile
+ * @compile/fail/ref=Neg02.out -XDrawDiagnostics Neg02.java
+ */
+
+class Neg02 {
+ interface A {
+ default void m() { Neg02.impl(this); }
+ }
+
+ interface B {
+ default void m() { Neg02.impl(this); }
+ }
+
+ static class X implements A, B { } //error
+
+ void test(X x) {
+ x.m();
+ ((A)x).m();
+ ((B)x).m();
+ }
+
+ static void impl(A a) { }
+ static void impl(B b) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg02.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+Neg02.java:16:13: compiler.err.types.incompatible.unrelated.defaults: kindname.class, Neg02.X, m, , Neg02.A, Neg02.B
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg03.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,38 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that re-abstraction works properly
+ * @compile/fail/ref=Neg03.out -XDrawDiagnostics Neg03.java
+ */
+
+class Neg03 {
+ interface A {
+ default void m() { Neg03.one(this); }
+ }
+
+ interface B {
+ default void m() { Neg03.two(this); }
+ }
+
+ interface C extends A, B {
+ default void m() { Neg03.one(this); }
+ }
+
+ static class X implements C, A { } //ok - ignore extraneous remix of A
+
+ interface D extends A, B {
+ void m(); // ok - m() is not reabstracted!
+ }
+
+ static class Y implements D, A { } // invalid - abstract D.m()
+
+ interface E extends A {
+ void m(); // reabstraction of m()
+ }
+
+ static class W implements D, E { } // invalid - abstracts D.m()/E.m()
+
+ static class Z implements D, A, B { } // invalid - abstract D.m()
+
+ static void one(Object a) { }
+ static void two(Object a) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg03.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,4 @@
+Neg03.java:26:12: compiler.err.does.not.override.abstract: Neg03.Y, m(), Neg03.D
+Neg03.java:32:12: compiler.err.does.not.override.abstract: Neg03.W, m(), Neg03.D
+Neg03.java:34:12: compiler.err.does.not.override.abstract: Neg03.Z, m(), Neg03.D
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg04.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default method must have most specific return type
+ * @compile/fail/ref=Neg04.out -XDrawDiagnostics Neg04.java
+ */
+
+class Neg04 {
+ interface IA1 { Integer m(); }
+ interface IA2 extends IA1 { default Number m() { return Neg04.m(this); } } //error
+
+ abstract class C implements IA1, IA2 {}
+
+ static int m(IA2 a) { return 0; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg04.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+Neg04.java:9:48: compiler.err.override.incompatible.ret: (compiler.misc.clashes.with: m(), Neg04.IA2, m(), Neg04.IA1), java.lang.Number, java.lang.Integer
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg05.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that abstract methods are compatible with inherited defaults
+ * @compile/fail/ref=Neg05.out -XDrawDiagnostics Neg05.java
+ */
+
+class Neg05 {
+ interface IA1 { default Number m() { return Neg05.m1(this); } }
+ interface IA2 extends IA1 { default Integer m() { return Neg05.m2(this); } }
+ interface IA3 extends IA2 { Number m(); } //error
+
+ static class C implements IA3{}
+
+ static int m1(IA1 a) { return 0; }
+ static int m2(IA2 b) { return 0; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg05.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+Neg05.java:10:40: compiler.err.override.incompatible.ret: (compiler.misc.clashes.with: m(), Neg05.IA3, m(), Neg05.IA2), java.lang.Number, java.lang.Integer
+Neg05.java:12:12: compiler.err.does.not.override.abstract: Neg05.C, m(), Neg05.IA3
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg06.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary flow analysis is not run on inlined default bodies
+ * @compile/fail/ref=Neg06.out -XDrawDiagnostics Neg06.java
+ */
+
+class Neg06 {
+
+ interface A {
+ default String m() { C.m(); }
+ }
+
+ static class C {
+ static String m() { return ""; }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg06.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+Neg06.java:10:37: compiler.err.missing.ret.stmt
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg07.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default overrides are properly type-checked
+ * @compile/fail/ref=Neg07.out -XDrawDiagnostics Neg07.java
+ */
+
+class Neg07 {
+ interface I {
+ default int m() { return 1; }
+ }
+
+ static class C1 {
+ public void m() { } //incompatible return
+ }
+
+ static class C2 extends C1 implements I { }
+
+ static class C3 implements I {
+ public void m() { } //incompatible return
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg07.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+Neg07.java:16:12: compiler.err.override.incompatible.ret: (compiler.misc.cant.implement: m(), Neg07.C1, m(), Neg07.I), void, int
+Neg07.java:19:21: compiler.err.override.incompatible.ret: (compiler.misc.cant.implement: m(), Neg07.C3, m(), Neg07.I), void, int
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg08.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default overrides are properly type-checked
+ * @compile/fail/ref=Neg08.out -XDrawDiagnostics Neg08.java
+ */
+class Neg08 {
+ interface I {
+ default void m() { }
+ }
+
+ static class C1 {
+ void m() { } //weaker modifier
+ }
+
+ static class C2 extends C1 implements I { }
+
+ static class C3 implements I {
+ void m() { } //weaker modifier
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg08.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+Neg08.java:15:12: compiler.err.override.weaker.access: (compiler.misc.cant.implement: m(), Neg08.C1, m(), Neg08.I), public
+Neg08.java:18:14: compiler.err.override.weaker.access: (compiler.misc.cant.implement: m(), Neg08.C3, m(), Neg08.I), public
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg09.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default overrides are properly type-checked
+ * @compile/fail/ref=Neg09.out -Werror -Xlint:unchecked -XDrawDiagnostics Neg09.java
+ */
+import java.util.List;
+
+class Neg09 {
+ interface I {
+ default List<String> m() { return null; }
+ }
+
+ static class C1 {
+ public List m() { return null; } //unchecked (return) override
+ }
+
+ static class C2 extends C1 implements I { }
+
+ static class C3 implements I {
+ public List m() { return null; } //unchecked (return) override
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg09.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,5 @@
+Neg09.java:17:12: compiler.warn.override.unchecked.ret: (compiler.misc.unchecked.implement: m(), Neg09.C1, m(), Neg09.I), java.util.List, java.util.List<java.lang.String>
+Neg09.java:20:21: compiler.warn.override.unchecked.ret: (compiler.misc.unchecked.implement: m(), Neg09.C3, m(), Neg09.I), java.util.List, java.util.List<java.lang.String>
+- compiler.err.warnings.and.werror
+1 error
+2 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg10.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default overrides are properly type-checked
+ * @compile/fail/ref=Neg10.out -Werror -Xlint:unchecked -XDrawDiagnostics Neg10.java
+ */
+class Neg10 {
+ interface I<X extends Exception> {
+ default void m() throws X { }
+ }
+
+ static class C1 {
+ public void m() throws Exception { } //unchecked (throws) override
+ }
+
+ static class C2<Z extends Exception> extends C1 implements I<Z> { }
+
+ static class C3<Z extends Exception> implements I<Z> {
+ public void m() throws Exception { } //unchecked (throws) override
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg10.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,5 @@
+Neg10.java:15:12: compiler.warn.override.unchecked.thrown: (compiler.misc.cant.implement: m(), Neg10.C1, m(), Neg10.I), java.lang.Exception
+Neg10.java:18:21: compiler.warn.override.unchecked.thrown: (compiler.misc.cant.implement: m(), Neg10.C3, m(), Neg10.I), java.lang.Exception
+- compiler.err.warnings.and.werror
+1 error
+2 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg11.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default overrides are properly type-checked
+ * @compile/fail/ref=Neg11.out -XDrawDiagnostics Neg11.java
+ */
+class Neg11 {
+ interface I {
+ default void m() { }
+ }
+
+ static class C1 {
+ public void m() throws Exception { } //bad throws
+ }
+
+ static class C2 extends C1 implements I { }
+
+ static class C3 implements I {
+ public void m() throws Exception { } //bad throws
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg11.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+Neg11.java:15:12: compiler.err.override.meth.doesnt.throw: (compiler.misc.cant.implement: m(), Neg11.C1, m(), Neg11.I), java.lang.Exception
+Neg11.java:18:21: compiler.err.override.meth.doesnt.throw: (compiler.misc.cant.implement: m(), Neg11.C3, m(), Neg11.I), java.lang.Exception
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg12.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,27 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that abstract methods are discarded in overload resolution diags
+ * @compile/fail/ref=Neg12.out -XDrawDiagnostics Neg12.java
+ */
+class Neg12 {
+
+ interface I1 {
+ default void m(String s) {};
+ }
+
+ interface I2 {
+ void m(String s);
+ }
+
+ static class B {
+ void m(Integer i) { }
+ }
+
+ static class C extends B implements I1 { }
+ static class D extends B implements I2 { }
+
+ void test(C c, D d) {
+ c.m();
+ d.m();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg12.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,4 @@
+Neg12.java:21:12: compiler.err.does.not.override.abstract: Neg12.D, m(java.lang.String), Neg12.I2
+Neg12.java:24:10: compiler.err.cant.apply.symbols: kindname.method, m, compiler.misc.no.args,{(compiler.misc.inapplicable.method: kindname.method, Neg12.I1, m(java.lang.String), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, Neg12.B, m(java.lang.Integer), (compiler.misc.arg.length.mismatch))}
+Neg12.java:25:10: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Integer, compiler.misc.no.args, kindname.class, Neg12.B, (compiler.misc.arg.length.mismatch)
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg13.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default method overriding object members are flagged as error
+ * @compile/fail/ref=Neg13.out -XDrawDiagnostics Neg13.java
+ */
+interface Neg13 {
+ default protected Object clone() { return null; } //protected not allowed here
+ default boolean equals(Object obj) { return false; }
+ default protected void finalize() { } //protected not allowed here
+ default Class<?> getClass() { return null; }
+ default int hashCode() { return 0; }
+ default void notify() { }
+ default void notifyAll() { }
+ default String toString() { return null; }
+ default void wait() { }
+ default void wait(long timeout) { }
+ default void wait(long timeout, int nanos) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg13.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,12 @@
+Neg13.java:7:30: compiler.err.mod.not.allowed.here: protected
+Neg13.java:9:28: compiler.err.mod.not.allowed.here: protected
+Neg13.java:8:21: compiler.err.default.overrides.object.member: equals, kindname.interface, Neg13
+Neg13.java:10:22: compiler.err.override.meth: (compiler.misc.cant.override: getClass(), Neg13, getClass(), java.lang.Object), final
+Neg13.java:11:17: compiler.err.default.overrides.object.member: hashCode, kindname.interface, Neg13
+Neg13.java:12:18: compiler.err.override.meth: (compiler.misc.cant.override: notify(), Neg13, notify(), java.lang.Object), final
+Neg13.java:13:18: compiler.err.override.meth: (compiler.misc.cant.override: notifyAll(), Neg13, notifyAll(), java.lang.Object), final
+Neg13.java:14:20: compiler.err.default.overrides.object.member: toString, kindname.interface, Neg13
+Neg13.java:15:18: compiler.err.override.meth: (compiler.misc.cant.override: wait(), Neg13, wait(), java.lang.Object), final
+Neg13.java:16:18: compiler.err.override.meth: (compiler.misc.cant.override: wait(long), Neg13, wait(long), java.lang.Object), final
+Neg13.java:17:18: compiler.err.override.meth: (compiler.misc.cant.override: wait(long,int), Neg13, wait(long,int), java.lang.Object), final
+11 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg14.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,11 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that a class cannot have two sibling interfaces with a default and abstract method
+ * @compile/fail/ref=Neg14.out -XDrawDiagnostics Neg14.java
+ */
+class Neg14 {
+ interface IA { int m(); }
+ interface IB { default int m() { return 1; } }
+
+ abstract class AB implements IA, IB {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg14.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+Neg14.java:10:14: compiler.err.types.incompatible.abstract.default: kindname.class, Neg14.AB, m, , Neg14.IB, Neg14.IA
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg15.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that level skipping in default super calls is correctly rejected
+ * @compile/fail/ref=Neg15.out -XDrawDiagnostics Neg15.java
+ */
+class Neg15 {
+ interface I { default void m() { } }
+ interface J extends I { default void m() { } }
+ interface K extends I {}
+
+ static class C implements J, K {
+ void foo() { K.super.m(); }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg15.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+Neg15.java:12:31: compiler.err.illegal.default.super.call: Neg15.K, (compiler.misc.overridden.default: m(), Neg15.J)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg16.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,13 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that level skipping in default super calls is correctly rejected
+ * @compile/fail/ref=Neg16.out -XDrawDiagnostics Neg16.java
+ */
+class Neg16 {
+ interface I { default void m() { } }
+ interface J extends I { default void m() { } }
+
+ static class C implements I, J {
+ void foo() { I.super.m(); }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg16.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+Neg16.java:11:23: compiler.err.illegal.default.super.call: Neg16.I, (compiler.misc.redundant.supertype: Neg16.I, Neg16.J)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos01.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011, 2012, 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 basic test for default methods
+ * @author Maurizio Cimadamore
+ */
+
+import java.util.*;
+
+public class Pos01 {
+
+ interface Mapper<T> {
+ T map(T in);
+ }
+
+ interface ExtendedList<T> extends List<T> {
+ default List<T> testMap(Mapper<T> r) {
+ return Pos01.<T>listMapper(this, r);
+ }
+ }
+
+ static class MyList<E> extends ArrayList<E> implements ExtendedList<E> {}
+
+ public static void main(String[] args) {
+ MyList<Integer> l = new MyList<Integer>();
+ l.add(1); l.add(2); l.add(3);
+ l.testMap((Integer x) -> x * x );
+ }
+
+ static <T> List<T> listMapper(List<T> l, Mapper<T> mapper) {
+ MyList<T> new_list = new MyList<T>();
+ for (T el : l) {
+ new_list.add(mapper.map(el));
+ }
+ return new_list;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos02.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 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 test for explicit resolution of ambiguous default methods
+ * @author Maurizio Cimadamore
+ * @compile Pos02.java
+ */
+
+class Pos02 {
+ interface IA { default int m() { return Pos02.m1(this); } }
+ interface IB { default int m() { return Pos02.m2(this); } }
+
+ static class A implements IA {}
+ static class B implements IB {}
+
+ static class AB implements IA, IB {
+ public int m() { return 0; }
+ void test() {
+ AB.this.m();
+ IA.super.m();
+ }
+ }
+
+ static int m1(IA a) { return 0; }
+ static int m2(IB b) { return 0; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos04.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 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 test for overriding with default method
+ * @author Maurizio Cimadamore
+ * @compile Pos04.java
+ */
+
+class Pos04 {
+ interface A { default int m() { return Pos04.m(this); } }
+ static abstract class B { public int m() { return 0; } }
+
+ static class C extends B implements A {
+ void test() {
+ C.this.m();
+ A.super.m();
+ }
+ }
+
+ static int m(A a) { return 0; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos05.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, 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 check that indirectly inherited default methods are discovered during resolution
+ * @author Maurizio Cimadamore
+ * @compile Pos05.java
+ */
+
+class Pos05 {
+ interface A {
+ default void m() { Pos05.impl(this); }
+ }
+
+ interface B extends A { }
+
+ static class E implements B { }
+
+ void test(E e) {
+ e.m();
+ }
+
+ static void impl(A a) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos06.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010, 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 check that well-formed MI hierarchies behaves well w.r.t. method resolution (i.e. no ambiguities)
+ * @author Maurizio Cimadamore
+ * @compile Pos06.java
+ */
+
+class Pos06 {
+ interface A {
+ default void m() { Pos06.impl(this); }
+ }
+
+ interface B extends A {
+ default void m() { Pos06.impl(this); }
+ }
+
+ static class X implements A, B { }
+
+ void test(X x) {
+ x.m();
+ ((A)x).m();
+ ((B)x).m();
+ }
+
+ static void impl(Object a) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos07.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010, 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 check that compilation order does not matter
+ * @author Maurizio Cimadamore
+ * @compile Pos07.java
+ */
+
+class Pos07 {
+ interface A {
+ default void foo() { Pos07.impl(this); }
+ default void bar() { Pos07.impl(this); }
+ }
+
+ static class C implements B, A {}
+
+ interface B extends A {
+ default void foo() { Pos07.impl(this); }
+ }
+
+ static void impl(A a) {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos08.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010, 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 check that common overrider solves default method conflicts
+ * @author Maurizio Cimadamore
+ * @compile Pos08.java
+ */
+
+class Pos08 {
+ interface A {
+ default void m() { Pos08.a(this); }
+ }
+
+ interface B {
+ default void m() { Pos08.b(this); }
+ }
+
+ interface C extends A, B {
+ default void m() { Pos08.b(this); }
+ }
+
+ static void a(A o) { }
+ static void b(B o) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos10.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010, 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 check that type-variables in generic extension decl can be accessed from default impl
+ * @author Maurizio Cimadamore
+ * @compile Pos10.java
+ */
+
+class Pos10 {
+ interface Function<X,Y> {
+ Y apply(X x);
+ }
+
+ interface A<T> {
+ default <R> void m(Function<T,R> f) { Impl.<T,R>m(this, f); }
+ }
+
+ static class Impl {
+ static <T,R> void m(A<T> a, Function<T,R> f) { }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos11.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010, 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 complex test with conflict resolution via overriding
+ * @author Brian Goetz
+ * @compile Pos11.java
+ */
+
+class Pos11 {
+ interface A {
+ default void get() { Pos11.one(this); }
+ }
+
+ interface B {
+ default void get() { Pos11.two(this); }
+ }
+
+ interface C extends A {
+ default void get() { Pos11.two(this); }
+ }
+
+ interface D extends A, B {
+ default void get() { Pos11.two(this); }
+ }
+
+ static class X implements C { }
+
+ static class Y implements C, A { }
+
+ static class Z implements D, A, B { }
+
+ static void one(Object a) { }
+ static void two(Object a) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos12.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 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 check that 'this' can be used from within an extension method
+ * @compile Pos12.java
+ */
+
+interface Pos12 {
+
+ default Object m() {
+ Object o = this;
+ f(this);
+ return this;
+ }
+
+ void f(Object o);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos13.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012, 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 qualified 'this' inside default method causes StackOverflowException
+ * @compile Pos13.java
+ */
+
+public class Pos13 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface Outer {
+ abstract void doSomething();
+
+ default void m() {
+ new SubOuter() {
+ public void doSomething() {
+ Outer.this.doSomething();
+ }
+ }.doSomething();
+ }
+ }
+
+ interface SubOuter extends Outer { }
+
+ static class E implements Outer {
+ public void doSomething() { assertTrue(true); }
+ }
+
+ public static void main(String[] args) {
+ new E().m();
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos14.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 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 check that overload resolution selects most specific signature
+ * @compile Pos14.java
+ */
+
+class Pos14 {
+ interface A { default Object m() { return null; } }
+ static abstract class B { abstract public String m(); }
+
+ static abstract class C extends B implements A {
+ void test() {
+ m().length();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos15.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 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 check that overload resolution selects most specific signature
+ * @compile Pos15.java
+ */
+
+class Pos15 {
+ interface A { default String m() { return null; } }
+ static abstract class B { abstract public Object m(); }
+
+ static abstract class C extends B implements A {
+ void test() {
+ m().length();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos16.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 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 'class wins' should not short-circuit overload resolution
+ * @compile Pos16.java
+ */
+
+class Pos16 {
+ interface I {
+ default String m(Integer i) { return ""; }
+ }
+
+ class C implements I {
+ Integer m(Object o) { return 1; }
+ }
+
+ void test(C c) {
+ c.m(1).length();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/TestDefaultBody.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2011, 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 check that code attributed for default methods is correctly generated
+ */
+
+import com.sun.tools.classfile.AccessFlags;
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool.*;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.Instruction;
+import com.sun.tools.classfile.Method;
+
+import com.sun.tools.classfile.Opcode;
+import java.io.*;
+
+public class TestDefaultBody {
+
+ interface TestInterface {
+ int no_default(int i);
+ default int yes_default(int i) { return impl(this, i); }
+ }
+
+ static int impl(TestInterface ti, int i) { return 0; }
+
+ static final String TARGET_CLASS_NAME = "TestDefaultBody";
+ static final String TARGET_NAME = "impl";
+ static final String TARGET_TYPE = "(LTestDefaultBody$TestInterface;I)I";
+ static final String SUBTEST_NAME = TestInterface.class.getName() + ".class";
+ static final String TEST_METHOD_NAME = "yes_default";
+
+ public static void main(String... args) throws Exception {
+ new TestDefaultBody().run();
+ }
+
+ public void run() throws Exception {
+ String workDir = System.getProperty("test.classes");
+ File compiledTest = new File(workDir, SUBTEST_NAME);
+ verifyDefaultBody(compiledTest);
+ }
+
+ void verifyDefaultBody(File f) {
+ System.err.println("verify: " + f);
+ try {
+ ClassFile cf = ClassFile.read(f);
+ Method testMethod = null;
+ Code_attribute codeAttr = null;
+ for (Method m : cf.methods) {
+ codeAttr = (Code_attribute)m.attributes.get(Attribute.Code);
+ String mname = m.getName(cf.constant_pool);
+ if (mname.equals(TEST_METHOD_NAME)) {
+ testMethod = m;
+ break;
+ } else {
+ codeAttr = null;
+ }
+ }
+ if (testMethod == null) {
+ throw new Error("Test method not found");
+ }
+ if (testMethod.access_flags.is(AccessFlags.ACC_ABSTRACT)) {
+ throw new Error("Test method is abstract");
+ }
+ if (codeAttr == null) {
+ throw new Error("Code attribute in test method not found");
+ }
+
+ boolean found = false;
+ for (Instruction instr : codeAttr.getInstructions()) {
+ if (instr.getOpcode() == Opcode.INVOKESTATIC) {
+ found = true;
+ int pc_index = instr.getShort(1);
+ CONSTANT_Methodref_info mref = (CONSTANT_Methodref_info)cf.constant_pool.get(pc_index);
+ String className = mref.getClassName();
+ String targetName = mref.getNameAndTypeInfo().getName();
+ String targetType = mref.getNameAndTypeInfo().getType();
+
+ if (!className.equals(TARGET_CLASS_NAME)) {
+ throw new Error("unexpected class in default method body " + className);
+ }
+ if (!targetName.equals(TARGET_NAME)) {
+ throw new Error("unexpected method name in default method body " + targetName);
+ }
+ if (!targetType.equals(TARGET_TYPE)) {
+ throw new Error("unexpected method type in default method body " + targetType);
+ }
+ break;
+ }
+ }
+
+ if (!found) {
+ throw new Error("no invokestatic found in default method body");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new Error("error reading " + f +": " + e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2011, 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
+ * @ignore awaits for VM support
+ * @summary check that javac does not generate bridge methods for defaults
+ */
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool.*;
+import com.sun.tools.classfile.Method;
+
+import java.io.*;
+
+public class TestNoBridgeOnDefaults {
+
+ interface A<X> {
+ default <Y> A<X> m(X x, Y y) { return Impl.<X,Y>m1(this, x, y); }
+ }
+
+ static abstract class B<X> implements A<X> { }
+
+ interface C<X> extends A<X> {
+ default <Y> C<X> m(X x, Y y) { return Impl.<X,Y>m2(this, x, y); }
+ }
+
+ static abstract class D<X> extends B<X> implements C<X> { }
+
+ static class Impl {
+ static <X, Y> A<X> m1(A<X> rec, X x, Y y) { return null; }
+ static <X, Y> C<X> m2(C<X> rec, X x, Y y) { return null; }
+ }
+
+ static final String[] SUBTEST_NAMES = { B.class.getName() + ".class", D.class.getName() + ".class" };
+ static final String TEST_METHOD_NAME = "m";
+
+ public static void main(String... args) throws Exception {
+ new TestNoBridgeOnDefaults().run();
+ }
+
+ public void run() throws Exception {
+ String workDir = System.getProperty("test.classes");
+ for (int i = 0 ; i < SUBTEST_NAMES.length ; i ++) {
+ File compiledTest = new File(workDir, SUBTEST_NAMES[i]);
+ checkNoBridgeOnDefaults(compiledTest);
+ }
+ }
+
+ void checkNoBridgeOnDefaults(File f) {
+ System.err.println("check: " + f);
+ try {
+ ClassFile cf = ClassFile.read(f);
+ for (Method m : cf.methods) {
+ String mname = m.getName(cf.constant_pool);
+ if (mname.equals(TEST_METHOD_NAME)) {
+ throw new Error("unexpected bridge method found " + m);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new Error("error reading " + f +": " + e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/crossCompile/Clinit.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+interface Clinit {
+ String s = Inner.m();
+
+ static class Inner {
+ static String m() { return ""; }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/crossCompile/CrossCompile.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 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 check that clinit in interface doesn't cause spurious default method diagnostics
+ * @compile -source 1.4 -target 1.4 Clinit.java
+ * @compile CrossCompile.java
+ */
+class CrossCompile {
+ void test() {
+ String s = Clinit.s;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/separate/Separate.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 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 smoke test for separate compilation of default methods
+ * @author Maurizio Cimadamore
+ * @compile pkg1/A.java
+ * @compile Separate.java
+ */
+
+import pkg1.A;
+
+class Separate {
+ interface B extends A.I {
+ default void m() { A.m(this); }
+ }
+
+ interface C extends A.I, B { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/separate/pkg1/A.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+package pkg1;
+
+public class A {
+ public interface I {
+ default void m() { A.m(this); }
+ }
+
+ public static void m(Object o) {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2012, 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 Automatic test for checking correctness of default super/this resolution
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+public class TestDefaultSuperCall {
+
+ static int checkCount = 0;
+
+ enum InterfaceKind {
+ DEFAULT("interface A extends B { default void m() { } }"),
+ ABSTRACT("interface A extends B { void m(); }"),
+ NONE("interface A extends B { }");
+
+ String interfaceStr;
+
+ InterfaceKind(String interfaceStr) {
+ this.interfaceStr = interfaceStr;
+ }
+
+ boolean methodDefined() {
+ return this == DEFAULT;
+ }
+ }
+
+ enum PruneKind {
+ NO_PRUNE("interface C { }"),
+ PRUNE("interface C extends A { }");
+
+ boolean methodDefined(InterfaceKind ik) {
+ return this == PRUNE &&
+ ik.methodDefined();
+ }
+
+ String interfaceStr;
+
+ PruneKind(String interfaceStr) {
+ this.interfaceStr = interfaceStr;
+ }
+ }
+
+ enum QualifierKind {
+ DIRECT_1("C"),
+ DIRECT_2("A"),
+ INDIRECT("B"),
+ UNRELATED("E"),
+ ENCLOSING_1(null),
+ ENCLOSING_2(null);
+
+ String qualifierStr;
+
+ QualifierKind(String qualifierStr) {
+ this.qualifierStr = qualifierStr;
+ }
+
+ String getQualifier(Shape sh) {
+ switch (this) {
+ case ENCLOSING_1: return sh.enclosingAt(0);
+ case ENCLOSING_2: return sh.enclosingAt(1);
+ default:
+ return qualifierStr;
+ }
+ }
+
+ boolean isEnclosing() {
+ return this == ENCLOSING_1 ||
+ this == ENCLOSING_2;
+ }
+
+ boolean allowSuperCall(InterfaceKind ik, PruneKind pk) {
+ switch (this) {
+ case DIRECT_1:
+ return pk.methodDefined(ik);
+ case DIRECT_2:
+ return ik.methodDefined() && pk == PruneKind.NO_PRUNE;
+ default:
+ return false;
+ }
+ }
+ }
+
+ enum ExprKind {
+ THIS("this"),
+ SUPER("super");
+
+ String exprStr;
+
+ ExprKind(String exprStr) {
+ this.exprStr = exprStr;
+ }
+ }
+
+ enum ElementKind {
+ INTERFACE("interface #N { #B }", true),
+ INTERFACE_EXTENDS("interface #N extends A, C { #B }", true),
+ CLASS("class #N { #B }", false),
+ CLASS_EXTENDS("abstract class #N implements A, C { #B }", false),
+ STATIC_CLASS("static class #N { #B }", true),
+ STATIC_CLASS_EXTENDS("abstract static class #N implements A, C { #B }", true),
+ ANON_CLASS("new Object() { #B };", false),
+ METHOD("void test() { #B }", false),
+ STATIC_METHOD("static void test() { #B }", true),
+ DEFAULT_METHOD("default void test() { #B }", false);
+
+ String templateDecl;
+ boolean isStatic;
+
+ ElementKind(String templateDecl, boolean isStatic) {
+ this.templateDecl = templateDecl;
+ this.isStatic = isStatic;
+ }
+
+ boolean isClassDecl() {
+ switch(this) {
+ case METHOD:
+ case STATIC_METHOD:
+ case DEFAULT_METHOD:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ boolean isAllowedEnclosing(ElementKind ek, boolean isTop) {
+ switch (this) {
+ case CLASS:
+ case CLASS_EXTENDS:
+ //class is implicitly static inside interface, so skip this combo
+ return ek.isClassDecl() &&
+ ek != INTERFACE && ek != INTERFACE_EXTENDS;
+ case ANON_CLASS:
+ return !ek.isClassDecl();
+ case METHOD:
+ return ek == CLASS || ek == CLASS_EXTENDS ||
+ ek == STATIC_CLASS || ek == STATIC_CLASS_EXTENDS ||
+ ek == ANON_CLASS;
+ case INTERFACE:
+ case INTERFACE_EXTENDS:
+ case STATIC_CLASS:
+ case STATIC_CLASS_EXTENDS:
+ case STATIC_METHOD:
+ return (isTop && (ek == CLASS || ek == CLASS_EXTENDS)) ||
+ ek == STATIC_CLASS || ek == STATIC_CLASS_EXTENDS;
+ case DEFAULT_METHOD:
+ return ek == INTERFACE || ek == INTERFACE_EXTENDS;
+ default:
+ throw new AssertionError("Bad enclosing element kind" + this);
+ }
+ }
+
+ boolean isAllowedTop() {
+ switch (this) {
+ case CLASS:
+ case CLASS_EXTENDS:
+ case INTERFACE:
+ case INTERFACE_EXTENDS:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ boolean hasSuper() {
+ return this == INTERFACE_EXTENDS ||
+ this == STATIC_CLASS_EXTENDS ||
+ this == CLASS_EXTENDS;
+ }
+ }
+
+ static class Shape {
+
+ String shapeStr;
+ List<ElementKind> enclosingElements;
+ List<String> enclosingNames;
+ List<String> elementsWithMethod;
+
+ Shape(ElementKind... elements) {
+ System.err.println("elements = " + Arrays.toString(elements));
+ enclosingElements = new ArrayList<>();
+ enclosingNames = new ArrayList<>();
+ elementsWithMethod = new ArrayList<>();
+ int count = 0;
+ String prevName = null;
+ for (ElementKind ek : elements) {
+ String name = "name"+count++;
+ if (ek.isStatic) {
+ enclosingElements = new ArrayList<>();
+ enclosingNames = new ArrayList<>();
+ }
+ if (ek.isClassDecl()) {
+ enclosingElements.add(ek);
+ enclosingNames.add(name);
+ } else {
+ elementsWithMethod.add(prevName);
+ }
+ String element = ek.templateDecl.replaceAll("#N", name);
+ shapeStr = shapeStr == null ? element : shapeStr.replaceAll("#B", element);
+ prevName = name;
+ }
+ }
+
+ String getShape(QualifierKind qk, ExprKind ek) {
+ String methName = ek == ExprKind.THIS ? "test" : "m";
+ String call = qk.getQualifier(this) + "." + ek.exprStr + "." + methName + "();";
+ return shapeStr.replaceAll("#B", call);
+ }
+
+ String enclosingAt(int index) {
+ return index < enclosingNames.size() ? enclosingNames.get(index) : "BAD";
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+
+ //create default shared JavaCompiler - reused across multiple compilations
+ JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+ for (InterfaceKind ik : InterfaceKind.values()) {
+ for (PruneKind pk : PruneKind.values()) {
+ for (ElementKind ek1 : ElementKind.values()) {
+ if (!ek1.isAllowedTop()) continue;
+ for (ElementKind ek2 : ElementKind.values()) {
+ if (!ek2.isAllowedEnclosing(ek1, true)) continue;
+ for (ElementKind ek3 : ElementKind.values()) {
+ if (!ek3.isAllowedEnclosing(ek2, false)) continue;
+ for (ElementKind ek4 : ElementKind.values()) {
+ if (!ek4.isAllowedEnclosing(ek3, false)) continue;
+ for (ElementKind ek5 : ElementKind.values()) {
+ if (!ek5.isAllowedEnclosing(ek4, false) || ek5.isClassDecl()) continue;
+ for (QualifierKind qk : QualifierKind.values()) {
+ for (ExprKind ek : ExprKind.values()) {
+ new TestDefaultSuperCall(ik, pk, new Shape(ek1, ek2, ek3, ek4, ek5), qk, ek).run(comp, fm);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ System.out.println("Total check executed: " + checkCount);
+ }
+
+ InterfaceKind ik;
+ PruneKind pk;
+ Shape sh;
+ QualifierKind qk;
+ ExprKind ek;
+ JavaSource source;
+ DiagnosticChecker diagChecker;
+
+ TestDefaultSuperCall(InterfaceKind ik, PruneKind pk, Shape sh, QualifierKind qk, ExprKind ek) {
+ this.ik = ik;
+ this.pk = pk;
+ this.sh = sh;
+ this.qk = qk;
+ this.ek = ek;
+ this.source = new JavaSource();
+ this.diagChecker = new DiagnosticChecker();
+ }
+
+ class JavaSource extends SimpleJavaFileObject {
+
+ String template = "interface E {}\n" +
+ "interface B { }\n" +
+ "#I\n" +
+ "#P\n" +
+ "#C";
+
+ String source;
+
+ public JavaSource() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ source = template.replaceAll("#I", ik.interfaceStr)
+ .replaceAll("#P", pk.interfaceStr)
+ .replaceAll("#C", sh.getShape(qk, ek));
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+ JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+ null, null, Arrays.asList(source));
+ try {
+ ct.analyze();
+ } catch (Throwable ex) {
+ throw new AssertionError("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
+ }
+ check();
+ }
+
+ void check() {
+ boolean errorExpected = false;
+
+ boolean badEnclosing = false;
+ boolean badThis = false;
+ boolean badSuper = false;
+
+ if (qk == QualifierKind.ENCLOSING_1 &&
+ sh.enclosingNames.size() < 1) {
+ errorExpected |= true;
+ badEnclosing = true;
+ }
+
+ if (qk == QualifierKind.ENCLOSING_2 &&
+ sh.enclosingNames.size() < 2) {
+ errorExpected |= true;
+ badEnclosing = true;
+ }
+
+ if (ek == ExprKind.THIS) {
+ boolean found = false;
+ for (int i = 0; i < sh.enclosingElements.size(); i++) {
+ if (sh.enclosingElements.get(i) == ElementKind.ANON_CLASS) continue;
+ if (sh.enclosingNames.get(i).equals(qk.getQualifier(sh))) {
+ found = sh.elementsWithMethod.contains(sh.enclosingNames.get(i));
+ break;
+ }
+ }
+ errorExpected |= !found;
+ if (!found) {
+ badThis = true;
+ }
+ }
+
+ if (ek == ExprKind.SUPER) {
+
+ int lastIdx = sh.enclosingElements.size() - 1;
+ boolean found = lastIdx == -1 ? false :
+ sh.enclosingElements.get(lastIdx).hasSuper() && qk.allowSuperCall(ik, pk);
+
+ errorExpected |= !found;
+ if (!found) {
+ badSuper = true;
+ }
+ }
+
+ checkCount++;
+ if (diagChecker.errorFound != errorExpected) {
+ throw new AssertionError("Problem when compiling source:\n" + source.getCharContent(true) +
+ "\nenclosingElems: " + sh.enclosingElements +
+ "\nenclosingNames: " + sh.enclosingNames +
+ "\nelementsWithMethod: " + sh.elementsWithMethod +
+ "\nbad encl: " + badEnclosing +
+ "\nbad this: " + badThis +
+ "\nbad super: " + badSuper +
+ "\nqual kind: " + qk +
+ "\nfound error: " + diagChecker.errorFound);
+ }
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ System.err.println(diagnostic.getMessage(Locale.getDefault()));
+ errorFound = true;
+ }
+ }
+ }
+}
--- a/langtools/test/tools/javac/defaultMethods/syntax/TestDefaultMethodsSyntax.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/defaultMethods/syntax/TestDefaultMethodsSyntax.java Fri Nov 30 17:09:05 2012 -0800
@@ -54,7 +54,7 @@
}
List<String> getOptions() {
- return Arrays.asList("-XDallowDefaultMethods", "-source", versionString);
+ return Arrays.asList("-source", versionString);
}
}
--- a/langtools/test/tools/javac/diags/CheckExamples.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/CheckExamples.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,9 +25,10 @@
* @test
* @bug 6968063 7127924
* @summary provide examples of code that generate diagnostics
- * @build Example CheckExamples
+ * @build Example CheckExamples DocCommentProcessor
* @run main/othervm CheckExamples
*/
+
/*
* See CR 7127924 for info on why othervm is used.
*/
--- a/langtools/test/tools/javac/diags/CheckResourceKeys.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java Fri Nov 30 17:09:05 2012 -0800
@@ -310,9 +310,8 @@
pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) {
String name = fo.getName();
// ignore resource files, and files which are not really part of javac
- if (name.contains("resources")
- || name.contains("Launcher.class")
- || name.contains("CreateSymbols.class"))
+ if (name.matches(".*resources.[A-Za-z_0-9]+\\.class.*")
+ || name.matches(".*CreateSymbols\\.class.*"))
continue;
scan(fo, results);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/DocCommentProcessor.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2012, 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.util.*;
+
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.doctree.ErroneousTree;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.DocTreeScanner;
+import com.sun.source.util.DocTrees;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.util.TreeScanner;
+import com.sun.tools.javac.tree.DocPretty;
+import java.io.PrintWriter;
+import javax.tools.Diagnostic;
+
+/**
+ * Standard annotation processor for use by examples to
+ * scan DocCommentTree nodes looking for ErroneousTree,
+ * on which to call {@code getMessage}.
+ */
+@SupportedAnnotationTypes("*")
+public class DocCommentProcessor extends AbstractProcessor {
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+
+ @Override
+ public void init(ProcessingEnvironment pEnv) {
+ super.init(pEnv);
+ trees = DocTrees.instance(pEnv);
+ messager = pEnv.getMessager();
+ }
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annos, RoundEnvironment rEnv) {
+ for (Element e : rEnv.getRootElements()) {
+ new DocCommentScanner().scan(e);
+ }
+ return true;
+ }
+
+ class DocCommentScanner extends TreePathScanner<Void,Void> {
+ public void scan(Element e) {
+ scan(trees.getPath(e), null);
+ }
+
+ @Override
+ public Void visitClass(ClassTree tree, Void ignore) {
+ check();
+ return super.visitClass(tree, ignore);
+ }
+
+ @Override
+ public Void visitMethod(MethodTree tree, Void ignore) {
+ check();
+ return super.visitMethod(tree, ignore);
+ }
+
+ @Override
+ public Void visitVariable(VariableTree tree, Void ignore) {
+ check();
+ return super.visitVariable(tree, ignore);
+ }
+
+ private void check() {
+ DocCommentTree dc = trees.getDocCommentTree(getCurrentPath());
+ if (dc == null)
+ return;
+
+ DocTreeScanner<Void, Void> s = new DocTreeScanner<Void, Void>() {
+ @Override
+ public Void visitErroneous(ErroneousTree tree, Void ignore) {
+ messager.printMessage(Diagnostic.Kind.NOTE, tree.getDiagnostic().getMessage(null));
+ return null;
+ }
+ };
+
+ s.scan(dc, null);
+ }
+
+ }
+
+ private DocTrees trees;
+ private Messager messager;
+}
--- a/langtools/test/tools/javac/diags/Example.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/Example.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, 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
@@ -209,6 +209,13 @@
opts.add("-classpath"); // avoid using -processorpath for now
opts.add(classesDir.getPath());
createAnnotationServicesFile(classesDir, procFiles);
+ } else if (options != null) {
+ int i = options.indexOf("-processor");
+ // check for built-in anno-processor(s)
+ if (i != -1 && options.get(i + 1).equals("DocCommentProcessor")) {
+ opts.add("-classpath");
+ opts.add(System.getProperty("test.classes"));
+ }
}
if (srcPathDir != null) {
--- a/langtools/test/tools/javac/diags/RunExamples.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/RunExamples.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,7 +25,7 @@
* @test
* @bug 6968063 7127924
* @summary provide examples of code that generate diagnostics
- * @build ArgTypeCompilerFactory Example HTMLWriter RunExamples
+ * @build ArgTypeCompilerFactory Example HTMLWriter RunExamples DocCommentProcessor
* @run main/othervm RunExamples
*/
/*
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Fri Nov 30 17:09:05 2012 -0800
@@ -3,6 +3,7 @@
compiler.err.annotation.value.not.allowable.type # cannot happen: precluded by complete type-specific tests
compiler.err.cant.read.file # (apt.JavaCompiler?)
compiler.err.cant.select.static.class.from.param.type
+compiler.err.dc.unterminated.string # cannot happen
compiler.err.illegal.char.for.encoding
compiler.err.invalid.containedby.annotation # should not happen
compiler.err.invalid.containedby.annotation.invalid.value # "can't" happen
@@ -105,3 +106,4 @@
compiler.warn.unexpected.archive.file # Paths: zip file with unknown extn
compiler.warn.unknown.enum.constant # in bad class file
compiler.warn.unknown.enum.constant.reason # in bad class file
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadEntity.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.bad.entity
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+/** & */
+class BadEntity { }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadGreaterThan.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.bad.gt
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+/** > */
+class BadGreaterThan { }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/BadInlineTag.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.bad.inline.tag
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+/** @inheritDoc */
+class BadInlineTag { }
+
--- a/langtools/test/tools/javac/diags/examples/CantAccessArgTypeInFunctionalDesc.java Fri Nov 30 12:39:37 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-// key: compiler.err.cant.access.arg.type.in.functional.desc
-// key: compiler.err.report.access
-// options: -XDallowLambda
-
-interface SAM_InaccessibleArg {
- void m(Foo.Bar bar);
- static class Foo { private class Bar { } }
-}
-
-class CantAccessArgTypeInFunctionalDesc {
- SAM_InaccessibleArg s = x-> { };
-}
--- a/langtools/test/tools/javac/diags/examples/CantAccessInnerClsConstr.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/CantAccessInnerClsConstr.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.cant.access.inner.cls.constr
// key: compiler.misc.invalid.mref
-// options: -XDallowMethodReferences
class CantAccessInnerClsConstructor {
--- a/langtools/test/tools/javac/diags/examples/CantAccessReturnTypeInFunctionalDesc.java Fri Nov 30 12:39:37 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-// key: compiler.err.cant.access.return.in.functional.desc
-// options: -XDallowLambda
-
-interface SAM_InaccessibleRet {
- Foo.Bar m();
- static class Foo { private class Bar { } }
-}
-
-class CantAccessReturnTypeInFunctionalDesc {
- SAM_InaccessibleRet s = ()->null;
-}
--- a/langtools/test/tools/javac/diags/examples/CantAccessThrownTypesInFunctionalDesc.java Fri Nov 30 12:39:37 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-// key: compiler.err.cant.access.thrown.in.functional.desc
-// options: -XDallowLambda
-
-interface SAM_InaccessibleThrown {
- void m() throws Foo.Bar;
- static class Foo { private class Bar extends Exception { } }
-}
-
-class CantAccessThrownTypesInFunctionalDesc {
- SAM_InaccessibleThrown s = ()-> { };
-}
--- a/langtools/test/tools/javac/diags/examples/CantApplySymbolFragment.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/CantApplySymbolFragment.java Fri Nov 30 17:09:05 2012 -0800
@@ -26,7 +26,6 @@
// key: compiler.misc.no.conforming.assignment.exists
// key: compiler.misc.cant.apply.symbol
// key: compiler.misc.invalid.mref
-// options: -XDallowMethodReferences
class CantApplySymbolFragment {
--- a/langtools/test/tools/javac/diags/examples/CantApplySymbolsFragment.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/CantApplySymbolsFragment.java Fri Nov 30 17:09:05 2012 -0800
@@ -28,7 +28,6 @@
// key: compiler.misc.inapplicable.method
// key: compiler.misc.cant.apply.symbols
// key: compiler.misc.invalid.mref
-// options: -XDallowMethodReferences
class CantApplySymbolsFragment {
--- a/langtools/test/tools/javac/diags/examples/CantRefNonEffectivelyFinalVar.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/CantRefNonEffectivelyFinalVar.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,6 @@
// key: compiler.err.cant.ref.non.effectively.final.var
// key: compiler.misc.inner.cls
// key: compiler.misc.lambda
-// options: -XDallowLambda -XDallowEffectivelyFinalInInnerClasses
class CantRefNonEffectivelyFinalVar {
void test() {
--- a/langtools/test/tools/javac/diags/examples/CantResolveLocationArgsFragment.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/CantResolveLocationArgsFragment.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,6 @@
// key: compiler.misc.cant.resolve.location.args
// key: compiler.misc.location
// key: compiler.err.invalid.mref
-// options: -XDallowMethodReferences
class CantResolveLocationArgsFragment {
--- a/langtools/test/tools/javac/diags/examples/CantResolveLocationArgsParamsFragment.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/CantResolveLocationArgsParamsFragment.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,6 @@
// key: compiler.misc.cant.resolve.location.args.params
// key: compiler.misc.location
// key: compiler.err.invalid.mref
-// options: -XDallowMethodReferences
class CantResolveLocationArgsParamsFragment {
--- a/langtools/test/tools/javac/diags/examples/CantReturnValueForVoid.java Fri Nov 30 12:39:37 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2010, 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.
- */
-
-// key: compiler.err.cant.ret.val.from.meth.decl.void
-
-class CantReturnValueForVoid {
- void m() {
- return 3;
- }
-}
--- a/langtools/test/tools/javac/diags/examples/CatchWithoutTry.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/CatchWithoutTry.java Fri Nov 30 17:09:05 2012 -0800
@@ -22,9 +22,6 @@
*/
// key: compiler.err.catch.without.try
-// key: compiler.err.expected
-// key: compiler.err.not.stmt
-// key: compiler.err.lambda.not.supported.in.source
class CatchWithoutTry {
void m() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ConditionalTargetCantBeVoid.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.prob.found.req
+// key: compiler.misc.incompatible.ret.type.in.lambda
+// key: compiler.misc.conditional.target.cant.be.void
+
+class ConditionalTargetCantBeVoid {
+
+ interface SAM {
+ void m();
+ }
+
+ void test(boolean cond, Object o1, Object o2) {
+ SAM s = ()-> cond ? o1 : o2;
+ }
+}
--- a/langtools/test/tools/javac/diags/examples/CyclicInference.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/CyclicInference.java Fri Nov 30 17:09:05 2012 -0800
@@ -23,7 +23,6 @@
// key: compiler.err.cant.apply.symbol
// key: compiler.misc.cyclic.inference
-// options: -XDallowLambda -XDallowPoly
class CyclicInference {
interface SAM<X> {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/DefaultOverridesObjectMember.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.default.overrides.object.member
+
+interface DefaultOverridesObjectMember {
+ default String toString() { return ""; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/GreaterThanExpected.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.gt.expected
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+class GreaterThanExpected {
+ /** @param <T */
+ <T> void m(T t) { }
+}
+
--- a/langtools/test/tools/javac/diags/examples/IncompatibleAbstracts.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/IncompatibleAbstracts.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.not.a.functional.intf.1
// key: compiler.misc.incompatible.abstracts
-// options: -XDallowLambda
class IncompatibleAbstracts {
--- a/langtools/test/tools/javac/diags/examples/IncompatibleArgTypesInLambda.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/IncompatibleArgTypesInLambda.java Fri Nov 30 17:09:05 2012 -0800
@@ -23,7 +23,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.incompatible.arg.types.in.lambda
-// options: -XDallowLambda -XDallowPoly
class IncompatibleArgTypesInLambda {
interface SAM {
--- a/langtools/test/tools/javac/diags/examples/IncompatibleDescsInFunctionalIntf.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/IncompatibleDescsInFunctionalIntf.java Fri Nov 30 17:09:05 2012 -0800
@@ -26,7 +26,6 @@
// key: compiler.misc.incompatible.descs.in.functional.intf
// key: compiler.misc.descriptor
// key: compiler.misc.descriptor.throws
-// options: -XDallowLambda
class IncompatibleDescsInFunctionalIntf {
interface A {
--- a/langtools/test/tools/javac/diags/examples/IncompatibleRetTypeInLambda.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/IncompatibleRetTypeInLambda.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.inconvertible.types
// key: compiler.misc.incompatible.ret.type.in.lambda
-// options: -XDallowLambda -XDallowPoly
class IncompatibleRetTypeInLambda {
interface SAM {
--- a/langtools/test/tools/javac/diags/examples/IncompatibleRetTypeInMref.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/IncompatibleRetTypeInMref.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.inconvertible.types
// key: compiler.misc.incompatible.ret.type.in.mref
-// options: -XDallowMethodReferences -XDallowPoly
class IncompatibleRetTypeInMref {
interface SAM {
--- a/langtools/test/tools/javac/diags/examples/IncompatibleThrownTypesInLambda.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/IncompatibleThrownTypesInLambda.java Fri Nov 30 17:09:05 2012 -0800
@@ -22,7 +22,6 @@
*/
// key: compiler.err.incompatible.thrown.types.in.lambda
-// options: -XDallowLambda
class IncompatibleThrownTypesInLambda {
interface SAM {
--- a/langtools/test/tools/javac/diags/examples/IncompatibleThrownTypesInMref.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/IncompatibleThrownTypesInMref.java Fri Nov 30 17:09:05 2012 -0800
@@ -22,7 +22,6 @@
*/
// key: compiler.err.incompatible.thrown.types.in.mref
-// options: -XDallowMethodReferences
class IncompatibleThrownTypesInMref {
interface SAM {
--- a/langtools/test/tools/javac/diags/examples/IncompatibleTypesInConditional.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/IncompatibleTypesInConditional.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.incompatible.type.in.conditional
// key: compiler.misc.inconvertible.types
-// options: -XDallowPoly
class IncompatibleTypesInConditional {
--- a/langtools/test/tools/javac/diags/examples/InvalidGenericDescInFunctionalInterface.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/InvalidGenericDescInFunctionalInterface.java Fri Nov 30 17:09:05 2012 -0800
@@ -23,7 +23,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.invalid.generic.desc.in.functional.intf
-// options: -XDallowLambda
class InvalidGenericDescInFunctionalIntf {
--- a/langtools/test/tools/javac/diags/examples/LocalVarNeedsFinal.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/LocalVarNeedsFinal.java Fri Nov 30 17:09:05 2012 -0800
@@ -22,6 +22,7 @@
*/
// key: compiler.err.local.var.accessed.from.icls.needs.final
+// options: -Xlint:-options -source 7
class LocalVarNeedsFinal {
Runnable m() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/MalformedHTML.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.malformed.html
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+/** <b */
+class MalformedHTML { }
--- a/langtools/test/tools/javac/diags/examples/MissingReturnValue.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/MissingReturnValue.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.missing.ret.val
+// key: compiler.err.prob.found.req
+// key: compiler.misc.missing.ret.val
class MissingReturnValue {
int m() {
--- a/langtools/test/tools/javac/diags/examples/MissingReturnValueFragment.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/MissingReturnValueFragment.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.incompatible.ret.type.in.lambda
// key: compiler.misc.missing.ret.val
-// options: -XDallowLambda
class MissingReturnValueFragment {
interface SAM {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/MissingSemicolon.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.missing.semicolon
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+/** < */
+class MissingSemicolon { }
+
--- a/langtools/test/tools/javac/diags/examples/NoAbstracts.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/NoAbstracts.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.not.a.functional.intf.1
// key: compiler.misc.no.abstracts
-// options: -XDallowLambda
class NoAbstracts {
--- a/langtools/test/tools/javac/diags/examples/NoSuitableFunctionalIntfInst.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/NoSuitableFunctionalIntfInst.java Fri Nov 30 17:09:05 2012 -0800
@@ -23,7 +23,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.no.suitable.functional.intf.inst
-// options: -XDallowLambda
class NoSuitableFunctionalIntfInst {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NoTagName.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.no.tag.name
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+/** @ */
+class NoTagName { }
+
--- a/langtools/test/tools/javac/diags/examples/NonStaticCantBeRefFragment.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/NonStaticCantBeRefFragment.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.non-static.cant.be.ref
// key: compiler.misc.invalid.mref
-// options: -XDallowMethodReferences
class NonStaticCantBeRefFragment {
--- a/langtools/test/tools/javac/diags/examples/NotAFunctionalIntf.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotAFunctionalIntf.java Fri Nov 30 17:09:05 2012 -0800
@@ -23,7 +23,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.not.a.functional.intf
-// options: -XDallowLambda
class NotAFunctionalIntf {
--- a/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessFragment.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/NotDefAccessClassIntfCantAccessFragment.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.not.def.access.class.intf.cant.access
// key: compiler.misc.invalid.mref
-// options: -XDallowMethodReferences
class NotDefAccessClassIntfCantAccessFragment {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/OverriddenDefault.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.illegal.default.super.call
+// key: compiler.misc.overridden.default
+
+class OverriddenDefault {
+ interface I { default void m() { } }
+ interface J extends I { default void m() { } }
+ interface K extends I {}
+
+ static class C implements J, K {
+ void foo() { K.super.m(); }
+ }
+}
--- a/langtools/test/tools/javac/diags/examples/PotentialLambdaFound.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/PotentialLambdaFound.java Fri Nov 30 17:09:05 2012 -0800
@@ -22,7 +22,7 @@
*/
// key: compiler.note.potential.lambda.found
-// options: -XDallowLambda -XDidentifyLambdaCandidate=true
+// options: -XDidentifyLambdaCandidate=true
class PotentialLambdaFound {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RedundantSupertype.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.illegal.default.super.call
+// key: compiler.misc.redundant.supertype
+
+class RedundantSupertype {
+ interface I { default void m() { } }
+ interface J extends I { default void m() { } }
+
+ static class C implements I, J {
+ void foo() { I.super.m(); }
+ }
+}
--- a/langtools/test/tools/javac/diags/examples/RefAmbiguousFragment.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/RefAmbiguousFragment.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,6 @@
// key: compiler.err.prob.found.req
// key: compiler.misc.ref.ambiguous
// key: compiler.misc.invalid.mref
-// options: -XDallowMethodReferences
class RefAmbiguousFragment {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RefBadParens.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.ref.bad.parens
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+/** @see #m((int)) */
+class RefBadParens { }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RefIdentifierExpected.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.identifier.expected
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+class IdentifierExpected2 {
+ /** @param 123 */
+ void m() { }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RefSyntaxError.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.ref.syntax.error
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+/** @see #m(int [) */
+class RefSyntaxError { }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RefUnexpectedInput.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.ref.unexpected.input
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+/** @see String#isEmpty% */
+class UnexpectedInput { }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TypesIncompatibleAbstractDefault.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.types.incompatible.abstract.default
+
+class TypesIncompatibleAbstractDefault {
+ interface A {
+ default void m() { }
+ }
+
+ interface B {
+ void m();
+ }
+
+ interface AB extends A, B { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TypesIncompatibleUnrelatedDefaults.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.types.incompatible.unrelated.defaults
+
+class TypesIncompatibleUnrelatedDefaults {
+ interface A {
+ default void m() { }
+ }
+
+ interface B {
+ default void m() { }
+ }
+
+ interface AB extends A, B { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/UnexpectedContent.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.unexpected.content
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+/** {@docRoot a} */
+class UnterminatedSignature { }
+
--- a/langtools/test/tools/javac/diags/examples/UnexpectedLambda.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/UnexpectedLambda.java Fri Nov 30 17:09:05 2012 -0800
@@ -22,7 +22,6 @@
*/
// key: compiler.err.unexpected.lambda
-// options: -XDallowLambda
class UnexpectedLambda {
{ (()-> { })++; }
--- a/langtools/test/tools/javac/diags/examples/UnexpectedMref.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/diags/examples/UnexpectedMref.java Fri Nov 30 17:09:05 2012 -0800
@@ -22,7 +22,6 @@
*/
// key: compiler.err.unexpected.mref
-// options: -XDallowMethodReferences
class UnexpectedLambda {
{ (Foo::bar)++; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/UnexpectedReturnValue.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.prob.found.req
+// key: compiler.misc.unexpected.ret.val
+
+class UnexpectedReturnValue {
+ void m() {
+ return 3;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/UnterminatedInlineTag.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.unterminated.inline.tag
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+/** {@code */
+class UnterminatedInlineTag { }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/UnterminatedSignature.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+// key: compiler.err.dc.unterminated.signature
+// key: compiler.note.note
+// key: compiler.note.proc.messager
+// run: backdoor
+// options: -processor DocCommentProcessor -proc:only
+
+/** @see String#equals( */
+class UnterminatedSignature { }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/AttrTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester AttrTest.java
+ */
+
+class AttrTest {
+ /**
+ * <a name=unquoted>foo</a>
+ */
+ void unquoted_attr() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ StartElement[START_ELEMENT, pos:1
+ name:a
+ attributes: 1
+ Attribute[ATTRIBUTE, pos:4
+ name: name
+ vkind: UNQUOTED
+ value: 1
+ Text[TEXT, pos:9, unquoted]
+ ]
+ ]
+ Text[TEXT, pos:18, foo]
+ EndElement[END_ELEMENT, pos:21, a]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * <a name="double_quoted">foo</a>
+ */
+ void double_quoted_attr() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ StartElement[START_ELEMENT, pos:1
+ name:a
+ attributes: 1
+ Attribute[ATTRIBUTE, pos:4
+ name: name
+ vkind: DOUBLE
+ value: 1
+ Text[TEXT, pos:10, double_quoted]
+ ]
+ ]
+ Text[TEXT, pos:25, foo]
+ EndElement[END_ELEMENT, pos:28, a]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * <a name='single_quoted'>foo</a>
+ */
+ void single_quoted_attr() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ StartElement[START_ELEMENT, pos:1
+ name:a
+ attributes: 1
+ Attribute[ATTRIBUTE, pos:4
+ name: name
+ vkind: SINGLE
+ value: 1
+ Text[TEXT, pos:10, single_quoted]
+ ]
+ ]
+ Text[TEXT, pos:25, foo]
+ EndElement[END_ELEMENT, pos:28, a]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * <hr size="3">
+ */
+ void numeric_attr() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ StartElement[START_ELEMENT, pos:1
+ name:hr
+ attributes: 1
+ Attribute[ATTRIBUTE, pos:5
+ name: size
+ vkind: DOUBLE
+ value: 1
+ Text[TEXT, pos:11, 3]
+ ]
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * <a href="{@docRoot}/index.html">
+ */
+ void docRoot_attr() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ StartElement[START_ELEMENT, pos:1
+ name:a
+ attributes: 1
+ Attribute[ATTRIBUTE, pos:4
+ name: href
+ vkind: DOUBLE
+ value: 2
+ DocRoot[DOC_ROOT, pos:10]
+ Text[TEXT, pos:20, /index.html]
+ ]
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * <a name="abc"def">
+ */
+ void entity_attr() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ StartElement[START_ELEMENT, pos:1
+ name:a
+ attributes: 1
+ Attribute[ATTRIBUTE, pos:4
+ name: name
+ vkind: DOUBLE
+ value: 3
+ Text[TEXT, pos:10, abc]
+ Entity[ENTITY, pos:13, quot]
+ Text[TEXT, pos:19, def]
+ ]
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * <hr noshade>
+ */
+ void no_value_attr() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ StartElement[START_ELEMENT, pos:1
+ name:hr
+ attributes: 1
+ Attribute[ATTRIBUTE, pos:5
+ name: noshade
+ vkind: EMPTY
+ value: null
+ ]
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc <hr size='3'/>
+ */
+ void self_closing_attr_1() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 2
+ Text[TEXT, pos:1, abc_]
+ StartElement[START_ELEMENT, pos:5
+ name:hr
+ attributes: 1
+ Attribute[ATTRIBUTE, pos:9
+ name: size
+ vkind: SINGLE
+ value: 1
+ Text[TEXT, pos:15, 3]
+ ]
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc <hr size=3 />
+ */
+ void self_closing_attr_2() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 2
+ Text[TEXT, pos:1, abc_]
+ StartElement[START_ELEMENT, pos:5
+ name:hr
+ attributes: 1
+ Attribute[ATTRIBUTE, pos:9
+ name: size
+ vkind: UNQUOTED
+ value: 1
+ Text[TEXT, pos:14, 3]
+ ]
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc <hr size="3
+ */
+ void unterminated_attr_eoi() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Erroneous[ERRONEOUS, pos:5
+ code: compiler.err.dc.malformed.html
+ body: <
+ ]
+ Text[TEXT, pos:6, hr_size="3]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc <hr size="3
+ * @author jjg
+ */
+ void unterminated_attr_block() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Erroneous[ERRONEOUS, pos:5
+ code: compiler.err.dc.malformed.html
+ body: <
+ ]
+ Text[TEXT, pos:6, hr_size="3]
+ body: empty
+ block tags: 1
+ Author[AUTHOR, pos:18
+ name: 1
+ Text[TEXT, pos:26, jjg]
+ ]
+]
+*/
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/AuthorTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester AuthorTest.java
+ */
+
+class AuthorTest {
+ /** abc @author jjg & others */
+ void standard() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 3
+ Text[TEXT, pos:0, abc_@author_jjg_]
+ Entity[ENTITY, pos:16, amp]
+ Text[TEXT, pos:21, _others]
+ body: empty
+ block tags: empty
+]
+*/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/BadTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester Bad.java
+ */
+
+class BadTest {
+
+ /**
+ * abc {@value java.awt.Color#RED junk}
+ */
+ int trailing_junk() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Erroneous[ERRONEOUS, pos:5
+ code: compiler.err.dc.unexpected.content
+ body: {@value_java.awt.Color#RED_j
+ ]
+ Text[TEXT, pos:33, unk}]
+ body: empty
+ block tags: empty
+]
+*/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/CodeTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester CodeTest.java
+ */
+
+class CodeTest {
+ /** {@code if (a < b) { }} */
+ void minimal() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 1
+ Literal[CODE, pos:0, if_(a_<_b)_{_}]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /** [{@code if (a < b) { }}] */
+ void in_brackets() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 3
+ Text[TEXT, pos:0, []
+ Literal[CODE, pos:1, if_(a_<_b)_{_}]
+ Text[TEXT, pos:23, ]]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /** [ {@code if (a < b) { }} ] */
+ void in_brackets_with_whitespace() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 3
+ Text[TEXT, pos:0, [_]
+ Literal[CODE, pos:2, if_(a_<_b)_{_}]
+ Text[TEXT, pos:24, _]]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * {@code {@code nested} }
+ */
+ void nested() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Literal[CODE, pos:1, {@code_nested}_]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * {@code if (a < b) {
+ * }
+ * }
+ */
+ void embedded_newline() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Literal[CODE, pos:1, if_(a_<_b)_{|________}|_]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /** {@code if (a < b) { } */
+ void unterminated_1() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 1
+ Erroneous[ERRONEOUS, pos:0
+ code: compiler.err.dc.unterminated.inline.tag
+ body: {@code_if_(a_<_b)_{_}
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * {@code if (a < b) { }
+ * @author jjg */
+ void unterminated_2() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Erroneous[ERRONEOUS, pos:1
+ code: compiler.err.dc.unterminated.inline.tag
+ body: {@code_if_(a_<_b)_{_}
+ ]
+ body: empty
+ block tags: 1
+ Author[AUTHOR, pos:24
+ name: 1
+ Text[TEXT, pos:32, jjg]
+ ]
+]
+*/
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/DeprecatedTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester DeprecatedTest.java
+ */
+
+class DeprecatedTest {
+ /**
+ * @deprecated
+ */
+ void deprecated() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Deprecated[DEPRECATED, pos:1
+ body: empty
+ ]
+]
+*/
+
+ /**
+ * @deprecated text
+ */
+ void deprecated_text() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Deprecated[DEPRECATED, pos:1
+ body: 1
+ Text[TEXT, pos:13, text]
+ ]
+]
+*/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/DocCommentTester.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,779 @@
+/*
+ * Copyright (c) 2012, 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.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.lang.model.element.Name;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+
+import com.sun.source.doctree.*;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.DocTreeScanner;
+import com.sun.source.util.DocTrees;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.tree.DCTree;
+import com.sun.tools.javac.tree.DCTree.DCDocComment;
+import com.sun.tools.javac.tree.DCTree.DCErroneous;
+import com.sun.tools.javac.tree.DocPretty;
+
+public class DocCommentTester {
+
+ public static void main(String... args) throws Exception {
+ new DocCommentTester().run(args);
+ }
+
+ public void run(String... args) throws Exception {
+ String testSrc = System.getProperty("test.src");
+
+ List<File> files = new ArrayList<File>();
+ for (String arg: args)
+ files.add(new File(testSrc, arg));
+
+ JavacTool javac = JavacTool.create();
+ StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null);
+
+ Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(files);
+
+ JavacTask t = javac.getTask(null, fm, null, null, null, fos);
+ final DocTrees trees = DocTrees.instance(t);
+
+ final Checker[] checkers = {
+ new ASTChecker(this, trees),
+ new PosChecker(this, trees),
+ new PrettyChecker(this, trees)
+ };
+
+ DeclScanner d = new DeclScanner() {
+ @Override
+ public Void visitCompilationUnit(CompilationUnitTree tree, Void ignore) {
+ for (Checker c: checkers)
+ c.visitCompilationUnit(tree);
+ return super.visitCompilationUnit(tree, ignore);
+ }
+
+ @Override
+ void visitDecl(Tree tree, Name name) {
+ TreePath path = getCurrentPath();
+ String dc = trees.getDocComment(path);
+ if (dc != null) {
+ for (Checker c : checkers) {
+ try {
+ System.err.println(path.getLeaf().getKind()
+ + " " + name
+ + " " + c.getClass().getSimpleName());
+
+ c.check(path, name);
+
+ System.err.println();
+ } catch (Exception e) {
+ error("Exception " + e);
+ e.printStackTrace(System.err);
+ }
+ }
+ }
+ }
+ };
+
+ Iterable<? extends CompilationUnitTree> units = t.parse();
+ for (CompilationUnitTree unit: units) {
+ d.scan(unit, null);
+ }
+
+ if (errors > 0)
+ throw new Exception(errors + " errors occurred");
+ }
+
+ static abstract class DeclScanner extends TreePathScanner<Void, Void> {
+ abstract void visitDecl(Tree tree, Name name);
+
+ @Override
+ public Void visitClass(ClassTree tree, Void ignore) {
+ super.visitClass(tree, ignore);
+ visitDecl(tree, tree.getSimpleName());
+ return null;
+ }
+
+ @Override
+ public Void visitMethod(MethodTree tree, Void ignore) {
+ super.visitMethod(tree, ignore);
+ visitDecl(tree, tree.getName());
+ return null;
+ }
+
+ @Override
+ public Void visitVariable(VariableTree tree, Void ignore) {
+ super.visitVariable(tree, ignore);
+ visitDecl(tree, tree.getName());
+ return null;
+ }
+ }
+
+ /**
+ * Base class for checkers to check the doc comment on a declaration
+ * (when present.)
+ */
+ abstract class Checker {
+ final DocTrees trees;
+
+ Checker(DocTrees trees) {
+ this.trees = trees;
+ }
+
+ void visitCompilationUnit(CompilationUnitTree tree) { }
+
+ abstract void check(TreePath tree, Name name) throws Exception;
+
+ void error(String msg) {
+ DocCommentTester.this.error(msg);
+ }
+ }
+
+ void error(String msg) {
+ System.err.println("Error: " + msg);
+ errors++;
+ }
+
+ int errors;
+
+ /**
+ * Verify the structure of the DocTree AST by comparing it against golden text.
+ */
+ static class ASTChecker extends Checker {
+ static final String NEWLINE = System.getProperty("line.separator");
+ Printer printer = new Printer();
+ String source;
+
+ ASTChecker(DocCommentTester test, DocTrees t) {
+ test.super(t);
+ }
+
+ @Override
+ void visitCompilationUnit(CompilationUnitTree tree) {
+ try {
+ source = tree.getSourceFile().getCharContent(true).toString();
+ } catch (IOException e) {
+ source = "";
+ }
+ }
+
+ void check(TreePath path, Name name) {
+ StringWriter out = new StringWriter();
+ DocCommentTree dc = trees.getDocCommentTree(path);
+ printer.print(dc, out);
+ out.flush();
+ String found = out.toString().replace(NEWLINE, "\n");
+
+ // Look for the first block comment after the first occurrence of name
+ int start = source.indexOf("\n/*\n", findName(source, name));
+ int end = source.indexOf("\n*/\n", start);
+ String expect = source.substring(start + 4, end + 1);
+ if (!found.equals(expect)) {
+ System.err.println("Expect:\n" + expect);
+ System.err.println("Found:\n" + found);
+ error("AST mismatch for " + name);
+ }
+ }
+
+ /**
+ * This main program is to set up the golden comments used by this
+ * checker.
+ * Usage:
+ * java DocCommentTester$ASTChecker -o dir file...
+ * The given files are written to the output directory with their
+ * golden comments updated. The intent is that the files should
+ * then be compared with the originals, e.g. with meld, and if the
+ * changes are approved, the new files can be used to replace the old.
+ */
+ public static void main(String... args) throws Exception {
+ List<File> files = new ArrayList<File>();
+ File o = null;
+ for (int i = 0; i < args.length; i++) {
+ String arg = args[i];
+ if (arg.equals("-o"))
+ o = new File(args[++i]);
+ else if (arg.startsWith("-"))
+ throw new IllegalArgumentException(arg);
+ else {
+ files.add(new File(arg));
+ }
+ }
+
+ if (o == null)
+ throw new IllegalArgumentException("no output dir specified");
+ final File outDir = o;
+
+ JavacTool javac = JavacTool.create();
+ StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null);
+ Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(files);
+
+ JavacTask t = javac.getTask(null, fm, null, null, null, fos);
+ final DocTrees trees = DocTrees.instance(t);
+
+ DeclScanner d = new DeclScanner() {
+ Printer p = new Printer();
+ String source;
+
+ @Override
+ public Void visitCompilationUnit(CompilationUnitTree tree, Void ignore) {
+ System.err.println("processing " + tree.getSourceFile().getName());
+ try {
+ source = tree.getSourceFile().getCharContent(true).toString();
+ } catch (IOException e) {
+ source = "";
+ }
+
+ // remove existing gold by removing all block comments after the first '{'.
+ int start = source.indexOf("{");
+ while ((start = source.indexOf("\n/*\n", start)) != -1) {
+ int end = source.indexOf("\n*/\n");
+ source = source.substring(0, start + 1) + source.substring(end + 4);
+ }
+
+ // process decls in compilation unit
+ super.visitCompilationUnit(tree, ignore);
+
+ // write the modified source
+ File f = new File(tree.getSourceFile().getName());
+ File outFile = new File(outDir, f.getName());
+ try {
+ FileWriter out = new FileWriter(outFile);
+ try {
+ out.write(source);
+ } finally {
+ out.close();
+ }
+ } catch (IOException e) {
+ System.err.println("Can't write " + tree.getSourceFile().getName()
+ + " to " + outFile + ": " + e);
+ }
+ return null;
+ }
+
+ @Override
+ void visitDecl(Tree tree, Name name) {
+ DocTree dc = trees.getDocCommentTree(getCurrentPath());
+ if (dc != null) {
+ StringWriter out = new StringWriter();
+ p.print(dc, out);
+ String found = out.toString();
+
+ // Look for the empty line after the first occurrence of name
+ int pos = source.indexOf("\n\n", findName(source, name));
+
+ // Insert the golden comment
+ source = source.substring(0, pos)
+ + "\n/*\n"
+ + found
+ + "*/"
+ + source.substring(pos);
+ }
+ }
+
+ };
+
+ Iterable<? extends CompilationUnitTree> units = t.parse();
+ for (CompilationUnitTree unit: units) {
+ d.scan(unit, null);
+ }
+ }
+
+ static int findName(String source, Name name) {
+ Pattern p = Pattern.compile("\\s" + name + "[(;]");
+ Matcher m = p.matcher(source);
+ if (!m.find())
+ throw new Error("cannot find " + name);
+ return m.start();
+ }
+
+ static class Printer implements DocTreeVisitor<Void, Void> {
+ PrintWriter out;
+
+ void print(DocTree tree, Writer out) {
+ this.out = (out instanceof PrintWriter)
+ ? (PrintWriter) out : new PrintWriter(out);
+ tree.accept(this, null);
+ this.out.flush();
+ }
+
+ public Void visitAttribute(AttributeTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("name", node.getName().toString());
+ print("vkind", node.getValueKind().toString());
+ print("value", node.getValue());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitAuthor(AuthorTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("name", node.getName());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitComment(CommentTree node, Void p) {
+ header(node, compress(node.getBody()));
+ return null;
+ }
+
+ public Void visitDeprecated(DeprecatedTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("body", node.getBody());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitDocComment(DocCommentTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("firstSentence", node.getFirstSentence());
+ print("body", node.getBody());
+ print("block tags", node.getBlockTags());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitDocRoot(DocRootTree node, Void p) {
+ header(node, "");
+ return null;
+ }
+
+ public Void visitEndElement(EndElementTree node, Void p) {
+ header(node, node.getName().toString());
+ return null;
+ }
+
+ public Void visitEntity(EntityTree node, Void p) {
+ header(node, node.getName().toString());
+ return null;
+ }
+
+ public Void visitErroneous(ErroneousTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("code", ((DCErroneous) node).diag.getCode());
+ print("body", compress(node.getBody()));
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitIdentifier(IdentifierTree node, Void p) {
+ header(node, compress(node.getName().toString()));
+ return null;
+ }
+
+ public Void visitInheritDoc(InheritDocTree node, Void p) {
+ header(node, "");
+ return null;
+ }
+
+ public Void visitLink(LinkTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("reference", node.getReference());
+ print("body", node.getLabel());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitLiteral(LiteralTree node, Void p) {
+ header(node, compress(node.getBody().getBody()));
+ return null;
+ }
+
+ public Void visitParam(ParamTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("name", node.getName());
+ print("description", node.getDescription());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitReference(ReferenceTree node, Void p) {
+ header(node, compress(node.getSignature()));
+ return null;
+ }
+
+ public Void visitReturn(ReturnTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("description", node.getDescription());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitSee(SeeTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("reference", node.getReference());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitSerial(SerialTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("description", node.getDescription());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitSerialData(SerialDataTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("description", node.getDescription());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitSerialField(SerialFieldTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("name", node.getName());
+ print("type", node.getType());
+ print("description", node.getDescription());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitSince(SinceTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("body", node.getBody());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitStartElement(StartElementTree node, Void p) {
+ header(node);
+ indent(+1);
+ indent();
+ out.println("name:" + node.getName());
+ print("attributes", node.getAttributes());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitText(TextTree node, Void p) {
+ header(node, compress(node.getBody()));
+ return null;
+ }
+
+ public Void visitThrows(ThrowsTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("exceptionName", node.getExceptionName());
+ print("description", node.getDescription());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitUnknownBlockTag(UnknownBlockTagTree node, Void p) {
+ header(node);
+ indent(+1);
+ indent();
+ out.println("tag:" + node.getTagName());
+ print("content", node.getContent());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitUnknownInlineTag(UnknownInlineTagTree node, Void p) {
+ header(node);
+ indent(+1);
+ indent();
+ out.println("tag:" + node.getTagName());
+ print("content", node.getContent());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitValue(ValueTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("reference", node.getReference());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitVersion(VersionTree node, Void p) {
+ header(node);
+ indent(+1);
+ print("body", node.getBody());
+ indent(-1);
+ indent();
+ out.println("]");
+ return null;
+ }
+
+ public Void visitOther(DocTree node, Void p) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ void header(DocTree node) {
+ indent();
+ out.println(simpleClassName(node) + "[" + node.getKind() + ", pos:" + ((DCTree) node).pos);
+ }
+
+ void header(DocTree node, String rest) {
+ indent();
+ out.println(simpleClassName(node) + "[" + node.getKind() + ", pos:" + ((DCTree) node).pos
+ + (rest.isEmpty() ? "" : ", " + rest)
+ + "]");
+ }
+
+ String simpleClassName(DocTree node) {
+ return node.getClass().getSimpleName().replaceAll("DC(.*)", "$1");
+ }
+
+ void print(String name, DocTree item) {
+ indent();
+ if (item == null)
+ out.println(name + ": null");
+ else {
+ out.println(name + ":");
+ indent(+1);
+ item.accept(this, null);
+ indent(-1);
+ }
+ }
+
+ void print(String name, String s) {
+ indent();
+ out.println(name + ": " + s);
+ }
+
+ void print(String name, List<? extends DocTree> list) {
+ indent();
+ if (list == null)
+ out.println(name + ": null");
+ else if (list.isEmpty())
+ out.println(name + ": empty");
+ else {
+ out.println(name + ": " + list.size());
+ indent(+1);
+ for (DocTree tree: list) {
+ tree.accept(this, null);
+ }
+ indent(-1);
+ }
+ }
+
+ int indent = 0;
+
+ void indent() {
+ for (int i = 0; i < indent; i++) {
+ out.print(" ");
+ }
+ }
+
+ void indent(int n) {
+ indent += n;
+ }
+
+ String compress(String s) {
+ s = s.replace("\n", "|").replace(" ", "_");
+ return (s.length() < 32)
+ ? s
+ : s.substring(0, 16) + "..." + s.substring(16);
+ }
+
+ String quote(String s) {
+ if (s.contains("\""))
+ return "'" + s + "'";
+ else if (s.contains("'") || s.contains(" "))
+ return '"' + s + '"';
+ else
+ return s;
+ }
+
+
+ }
+ }
+
+ /**
+ * Verify the reported tree positions by comparing the characters found
+ * at and after the reported position with the beginning of the pretty-
+ * printed text.
+ */
+ static class PosChecker extends Checker {
+ PosChecker(DocCommentTester test, DocTrees t) {
+ test.super(t);
+ }
+
+ @Override
+ void check(TreePath path, Name name) throws Exception {
+ JavaFileObject fo = path.getCompilationUnit().getSourceFile();
+ final CharSequence cs = fo.getCharContent(true);
+
+ final DCDocComment dc = (DCDocComment) trees.getDocCommentTree(path);
+ DCTree t = (DCTree) trees.getDocCommentTree(path);
+
+ DocTreeScanner scanner = new DocTreeScanner<Void,Void>() {
+ @Override
+ public Void scan(DocTree node, Void ignore) {
+ if (node != null) {
+ try {
+ String expect = getExpectText(node);
+ long pos = ((DCTree) node).getSourcePosition(dc);
+ String found = getFoundText(cs, (int) pos, expect.length());
+ if (!found.equals(expect)) {
+ System.err.println("expect: " + expect);
+ System.err.println("found: " + found);
+ error("mismatch");
+ }
+
+ } catch (StringIndexOutOfBoundsException e) {
+ error(node.getClass() + ": " + e.toString());
+ e.printStackTrace();
+ }
+ }
+ return super.scan(node, ignore);
+ }
+ };
+
+ scanner.scan(t, null);
+ }
+
+ String getExpectText(DocTree t) {
+ StringWriter sw = new StringWriter();
+ DocPretty p = new DocPretty(sw);
+ try { p.print(t); } catch (IOException never) { }
+ String s = sw.toString();
+ if (s.length() <= 1)
+ return s;
+ int ws = s.replaceAll("\\s+", " ").indexOf(" ");
+ if (ws != -1) s = s.substring(0, ws);
+ return (s.length() < 5) ? s : s.substring(0, 5);
+ }
+
+ String getFoundText(CharSequence cs, int pos, int len) {
+ return (pos == -1) ? "" : cs.subSequence(pos, Math.min(pos + len, cs.length())).toString();
+ }
+ }
+
+ /**
+ * Verify the pretty printed text against a normalized form of the
+ * original doc comment.
+ */
+ static class PrettyChecker extends Checker {
+
+ PrettyChecker(DocCommentTester test, DocTrees t) {
+ test.super(t);
+ }
+
+ @Override
+ void check(TreePath path, Name name) throws Exception {
+ String raw = trees.getDocComment(path);
+ String normRaw = normalize(raw);
+
+ StringWriter out = new StringWriter();
+ DocPretty dp = new DocPretty(out);
+ dp.print(trees.getDocCommentTree(path));
+ String pretty = out.toString();
+
+ if (!pretty.equals(normRaw)) {
+ error("mismatch");
+ System.err.println("*** expected:");
+ System.err.println(normRaw.replace(" ", "_"));
+ System.err.println("*** found:");
+ System.err.println(pretty.replace(" ", "_"));
+ // throw new Error();
+ }
+ }
+
+ /**
+ * Normalize white space in places where the tree does not preserve it.
+ */
+ String normalize(String s) {
+ return s.trim()
+ .replaceFirst("\\.\\s++([^@])", ". $1")
+ .replaceFirst("\\.\\s*\\n *@", ".\n@")
+ .replaceFirst("\\s+<(/?p|pre|h[1-6])>", " <$1>")
+ .replaceAll("\\{@docRoot\\s+\\}", "{@docRoot}")
+ .replaceAll("\\{@inheritDoc\\s+\\}", "{@inheritDoc}")
+ .replaceAll("(\\{@value\\s+[^}]+)\\s+(\\})", "$1$2")
+ .replaceAll("\n[ \t]+@", "\n@");
+ }
+
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/DocRootTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester DocRootTest.java
+ */
+
+class DocRootTest {
+ /** abc {@docRoot} */
+ void standard() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 2
+ Text[TEXT, pos:0, abc_]
+ DocRoot[DOC_ROOT, pos:4]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /** abc {@docRoot } */
+ void standard_ws1() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 2
+ Text[TEXT, pos:0, abc_]
+ DocRoot[DOC_ROOT, pos:4]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /** abc {@docRoot } */
+ void standard_ws2() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 2
+ Text[TEXT, pos:0, abc_]
+ DocRoot[DOC_ROOT, pos:4]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /** abc {@docRoot junk} */
+ void error() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 2
+ Text[TEXT, pos:0, abc_]
+ Erroneous[ERRONEOUS, pos:4
+ code: compiler.err.dc.unexpected.content
+ body: {@docRoot_junk}
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/ElementTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester ElementTest.java
+ */
+
+class ElementTest {
+ /**
+ * <p>para</p>
+ */
+ void simple() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: 3
+ StartElement[START_ELEMENT, pos:1
+ name:p
+ attributes: empty
+ ]
+ Text[TEXT, pos:4, para]
+ EndElement[END_ELEMENT, pos:8, p]
+ block tags: empty
+]
+*/
+
+ /**
+ * abc <hr/>
+ */
+ void self_closing() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 2
+ Text[TEXT, pos:1, abc_]
+ StartElement[START_ELEMENT, pos:5
+ name:hr
+ attributes: empty
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc < def
+ */
+ void bad_lt() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Erroneous[ERRONEOUS, pos:5
+ code: compiler.err.dc.malformed.html
+ body: <
+ ]
+ Text[TEXT, pos:6, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc > def
+ */
+ void bad_gt() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Erroneous[ERRONEOUS, pos:5
+ code: compiler.err.dc.bad.gt
+ body: >
+ ]
+ Text[TEXT, pos:6, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc <p 123> def
+ */
+ void bad_chars_start();
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 5
+ Text[TEXT, pos:1, abc_]
+ Erroneous[ERRONEOUS, pos:5
+ code: compiler.err.dc.malformed.html
+ body: <
+ ]
+ Text[TEXT, pos:6, p_123]
+ Erroneous[ERRONEOUS, pos:11
+ code: compiler.err.dc.bad.gt
+ body: >
+ ]
+ Text[TEXT, pos:12, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc </p 123> def
+ */
+ void bad_chars_end();
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 5
+ Text[TEXT, pos:1, abc_]
+ Erroneous[ERRONEOUS, pos:5
+ code: compiler.err.dc.malformed.html
+ body: <
+ ]
+ Text[TEXT, pos:6, /p_123]
+ Erroneous[ERRONEOUS, pos:12
+ code: compiler.err.dc.bad.gt
+ body: >
+ ]
+ Text[TEXT, pos:13, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc <hr
+ */
+ void unterminated_eoi() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Erroneous[ERRONEOUS, pos:5
+ code: compiler.err.dc.malformed.html
+ body: <
+ ]
+ Text[TEXT, pos:6, hr]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc <hr
+ * @author jjg
+ */
+ void unterminated_block() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Erroneous[ERRONEOUS, pos:5
+ code: compiler.err.dc.malformed.html
+ body: <
+ ]
+ Text[TEXT, pos:6, hr]
+ body: empty
+ block tags: 1
+ Author[AUTHOR, pos:10
+ name: 1
+ Text[TEXT, pos:18, jjg]
+ ]
+]
+*/
+
+
+ /**
+ * abc </p
+ */
+ void unterminated_end_eoi() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Erroneous[ERRONEOUS, pos:5
+ code: compiler.err.dc.malformed.html
+ body: <
+ ]
+ Text[TEXT, pos:6, /p]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc </p
+ * @author jjg
+ */
+ void unterminated_end_block() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Erroneous[ERRONEOUS, pos:5
+ code: compiler.err.dc.malformed.html
+ body: <
+ ]
+ Text[TEXT, pos:6, /p]
+ body: empty
+ block tags: 1
+ Author[AUTHOR, pos:10
+ name: 1
+ Text[TEXT, pos:18, jjg]
+ ]
+]
+*/
+
+ /**
+ * abc
+ * <!-- comment -->
+ * def
+ */
+ void comment() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc|_]
+ Comment[COMMENT, pos:6, <!--_comment_-->]
+ Text[TEXT, pos:22, |_def]
+ body: empty
+ block tags: empty
+]
+*/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/EntityTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester EntityTest.java
+ */
+
+class EntityTest {
+ /**
+ * abc < def
+ */
+ public void name() { }
+/*
+DocComment[DOC_COMMENT, pos:2
+ firstSentence: 3
+ Text[TEXT, pos:2, abc_]
+ Entity[ENTITY, pos:6, lt]
+ Text[TEXT, pos:10, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc   def
+ */
+ public void decimal_value() { }
+/*
+DocComment[DOC_COMMENT, pos:2
+ firstSentence: 3
+ Text[TEXT, pos:2, abc_]
+ Entity[ENTITY, pos:6, #160]
+ Text[TEXT, pos:12, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc   def
+ */
+ public void lower_hex_value() { }
+/*
+DocComment[DOC_COMMENT, pos:2
+ firstSentence: 3
+ Text[TEXT, pos:2, abc_]
+ Entity[ENTITY, pos:6, #xa0]
+ Text[TEXT, pos:12, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc   def
+ */
+ public void upper_hex_value() { }
+/*
+DocComment[DOC_COMMENT, pos:2
+ firstSentence: 3
+ Text[TEXT, pos:2, abc_]
+ Entity[ENTITY, pos:6, #XA0]
+ Text[TEXT, pos:12, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc & def
+ */
+ public void bad_amp() { }
+/*
+DocComment[DOC_COMMENT, pos:2
+ firstSentence: 3
+ Text[TEXT, pos:2, abc_]
+ Erroneous[ERRONEOUS, pos:6
+ code: compiler.err.dc.bad.entity
+ body: &
+ ]
+ Text[TEXT, pos:7, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc &1 def
+ */
+ public void bad_entity_name() { }
+/*
+DocComment[DOC_COMMENT, pos:2
+ firstSentence: 3
+ Text[TEXT, pos:2, abc_]
+ Erroneous[ERRONEOUS, pos:6
+ code: compiler.err.dc.bad.entity
+ body: &
+ ]
+ Text[TEXT, pos:7, 1_def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc .3; def
+ */
+ public void bad_entity_decimal_value() { }
+/*
+DocComment[DOC_COMMENT, pos:2
+ firstSentence: 3
+ Text[TEXT, pos:2, abc_]
+ Erroneous[ERRONEOUS, pos:6
+ code: compiler.err.dc.missing.semicolon
+ body: 
+ ]
+ Text[TEXT, pos:11, .3;_def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc Īzc; def
+ */
+ public void bad_entity_hex_value() { }
+/*
+DocComment[DOC_COMMENT, pos:2
+ firstSentence: 3
+ Text[TEXT, pos:2, abc_]
+ Erroneous[ERRONEOUS, pos:6
+ code: compiler.err.dc.missing.semicolon
+ body: Ī
+ ]
+ Text[TEXT, pos:13, zc;_def]
+ body: empty
+ block tags: empty
+]
+*/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/ExceptionTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester ExceptionTest.java
+ */
+
+class ExceptionTest {
+ /**
+ * @exception Exception
+ */
+ void exception() throws Exception { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Throws[EXCEPTION, pos:1
+ exceptionName:
+ Reference[REFERENCE, pos:12, Exception]
+ description: empty
+ ]
+]
+*/
+
+ /**
+ * @exception Exception text
+ */
+ void exception_text() throws Exception { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Throws[EXCEPTION, pos:1
+ exceptionName:
+ Reference[REFERENCE, pos:12, Exception]
+ description: 1
+ Text[TEXT, pos:22, text]
+ ]
+]
+*/
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/FirstSentenceTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester FirstSentenceTest.java
+ */
+
+class FirstSentenceTest {
+ /** */
+ void empty() { }
+/*
+DocComment[DOC_COMMENT, pos:-1
+ firstSentence: empty
+ body: empty
+ block tags: empty
+]
+*/
+
+ /** abc def ghi */
+ void no_terminator() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 1
+ Text[TEXT, pos:0, abc_def_ghi]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc def ghi.
+ */
+ void no_body() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc_def_ghi.]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc def ghi. jkl mno pqr.
+ */
+ void dot_space() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc_def_ghi.]
+ body: 1
+ Text[TEXT, pos:14, jkl_mno_pqr.]
+ block tags: empty
+]
+*/
+
+ /**
+ * abc def ghi.
+ * jkl mno pqr
+ */
+ void dot_newline() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc_def_ghi.]
+ body: 1
+ Text[TEXT, pos:15, jkl_mno_pqr]
+ block tags: empty
+]
+*/
+
+ /**
+ * abc def ghi
+ * <p>jkl mno pqr
+ */
+ void dot_p() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc_def_ghi]
+ body: 2
+ StartElement[START_ELEMENT, pos:14
+ name:p
+ attributes: empty
+ ]
+ Text[TEXT, pos:17, jkl_mno_pqr]
+ block tags: empty
+]
+*/
+
+ /**
+ * abc def ghi
+ * </p>jkl mno pqr
+ */
+ void dot_end_p() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc_def_ghi]
+ body: 2
+ EndElement[END_ELEMENT, pos:14, p]
+ Text[TEXT, pos:18, jkl_mno_pqr]
+ block tags: empty
+]
+*/
+
+ /**
+ * abc < ghi. jkl mno pqr.
+ */
+ void entity() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Entity[ENTITY, pos:5, lt]
+ Text[TEXT, pos:9, _ghi.]
+ body: 1
+ Text[TEXT, pos:15, jkl_mno_pqr.]
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@code code} ghi. jkl mno pqr.
+ */
+ void inline_tag() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Literal[CODE, pos:5, code]
+ Text[TEXT, pos:17, _ghi.]
+ body: 1
+ Text[TEXT, pos:23, jkl_mno_pqr.]
+ block tags: empty
+]
+*/
+
+ /**
+ * abc def ghi
+ * @author jjg
+ */
+ void block_tag() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc_def_ghi]
+ body: empty
+ block tags: 1
+ Author[AUTHOR, pos:14
+ name: 1
+ Text[TEXT, pos:22, jjg]
+ ]
+]
+*/
+
+ /**
+ * @author jjg
+ */
+ void just_tag() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Author[AUTHOR, pos:1
+ name: 1
+ Text[TEXT, pos:9, jjg]
+ ]
+]
+*/
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/InheritDocTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester InheritDocTest.java
+ */
+
+class InheritDocTest {
+ /** abc {@inheritDoc} */
+ void standard() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 2
+ Text[TEXT, pos:0, abc_]
+ InheritDoc[INHERIT_DOC, pos:4]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /** abc {@inheritDoc } */
+ void standard_ws1() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 2
+ Text[TEXT, pos:0, abc_]
+ InheritDoc[INHERIT_DOC, pos:4]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /** abc {@inheritDoc } */
+ void standard_ws2() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 2
+ Text[TEXT, pos:0, abc_]
+ InheritDoc[INHERIT_DOC, pos:4]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /** abc {@inheritDoc junk} */
+ void error() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 2
+ Text[TEXT, pos:0, abc_]
+ Erroneous[ERRONEOUS, pos:4
+ code: compiler.err.dc.unexpected.content
+ body: {@inheritDoc_junk}
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/LinkPlainTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester LinkPlainTest.java
+ */
+
+class LinkPlainTest {
+ /**
+ * abc {@linkplain String} def
+ */
+ void simple_name() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK_PLAIN, pos:5
+ reference:
+ Reference[REFERENCE, pos:17, String]
+ body: empty
+ ]
+ Text[TEXT, pos:24, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@linkplain String desc} def
+ */
+ void simple_name_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK_PLAIN, pos:5
+ reference:
+ Reference[REFERENCE, pos:17, String]
+ body: 1
+ Text[TEXT, pos:24, desc]
+ ]
+ Text[TEXT, pos:29, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@linkplain java.lang.String desc} def
+ */
+ void pkg_name_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK_PLAIN, pos:5
+ reference:
+ Reference[REFERENCE, pos:17, java.lang.String]
+ body: 1
+ Text[TEXT, pos:34, desc]
+ ]
+ Text[TEXT, pos:39, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@linkplain java.lang.String#isEmpty desc} def
+ */
+ void method_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK_PLAIN, pos:5
+ reference:
+ Reference[REFERENCE, pos:17, java.lang.String#isEmpty]
+ body: 1
+ Text[TEXT, pos:42, desc]
+ ]
+ Text[TEXT, pos:47, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@linkplain java.lang.String#isEmpty() desc} def
+ */
+ void method_0_args_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK_PLAIN, pos:5
+ reference:
+ Reference[REFERENCE, pos:17, java.lang.String#isEmpty()]
+ body: 1
+ Text[TEXT, pos:44, desc]
+ ]
+ Text[TEXT, pos:49, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@linkplain java.lang.String#substring(int) desc} def
+ */
+ void method_1_args_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK_PLAIN, pos:5
+ reference:
+ Reference[REFERENCE, pos:17, java.lang.String#substring(int)]
+ body: 1
+ Text[TEXT, pos:49, desc]
+ ]
+ Text[TEXT, pos:54, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@linkplain java.lang.String#substring(int, int) desc} def
+ */
+ void method_2_args_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK_PLAIN, pos:5
+ reference:
+ Reference[REFERENCE, pos:17, java.lang.String...#substring(int,_int)]
+ body: 1
+ Text[TEXT, pos:54, desc]
+ ]
+ Text[TEXT, pos:59, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@linkplain java.util.List<T> desc} def
+ */
+ void pkg_name_typarams_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK_PLAIN, pos:5
+ reference:
+ Reference[REFERENCE, pos:17, java.util.List<T>]
+ body: 1
+ Text[TEXT, pos:35, desc]
+ ]
+ Text[TEXT, pos:40, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/LinkTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester LinkTest.java
+ */
+
+class LinkTest {
+ /**
+ * abc {@link String} def
+ */
+ void simple_name() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK, pos:5
+ reference:
+ Reference[REFERENCE, pos:12, String]
+ body: empty
+ ]
+ Text[TEXT, pos:19, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@link String desc} def
+ */
+ void simple_name_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK, pos:5
+ reference:
+ Reference[REFERENCE, pos:12, String]
+ body: 1
+ Text[TEXT, pos:19, desc]
+ ]
+ Text[TEXT, pos:24, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@link java.lang.String desc} def
+ */
+ void pkg_name_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK, pos:5
+ reference:
+ Reference[REFERENCE, pos:12, java.lang.String]
+ body: 1
+ Text[TEXT, pos:29, desc]
+ ]
+ Text[TEXT, pos:34, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@link java.lang.String#isEmpty desc} def
+ */
+ void method_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK, pos:5
+ reference:
+ Reference[REFERENCE, pos:12, java.lang.String#isEmpty]
+ body: 1
+ Text[TEXT, pos:37, desc]
+ ]
+ Text[TEXT, pos:42, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@link java.lang.String#isEmpty() desc} def
+ */
+ void method_0_args_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK, pos:5
+ reference:
+ Reference[REFERENCE, pos:12, java.lang.String#isEmpty()]
+ body: 1
+ Text[TEXT, pos:39, desc]
+ ]
+ Text[TEXT, pos:44, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@link java.lang.String#substring(int) desc} def
+ */
+ void method_1_args_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK, pos:5
+ reference:
+ Reference[REFERENCE, pos:12, java.lang.String#substring(int)]
+ body: 1
+ Text[TEXT, pos:44, desc]
+ ]
+ Text[TEXT, pos:49, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@link java.lang.String#substring(int, int) desc} def
+ */
+ void method_2_args_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK, pos:5
+ reference:
+ Reference[REFERENCE, pos:12, java.lang.String...#substring(int,_int)]
+ body: 1
+ Text[TEXT, pos:49, desc]
+ ]
+ Text[TEXT, pos:54, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@link java.util.List<T> desc} def
+ */
+ void pkg_name_typarams_desc() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Link[LINK, pos:5
+ reference:
+ Reference[REFERENCE, pos:12, java.util.List<T>]
+ body: 1
+ Text[TEXT, pos:30, desc]
+ ]
+ Text[TEXT, pos:35, _def]
+ body: empty
+ block tags: empty
+]
+*/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/LiteralTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester LiteralTest.java
+ */
+
+class LiteralTest {
+ /** {@literal if (a < b) { }} */
+ void minimal() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 1
+ Literal[LITERAL, pos:0, if_(a_<_b)_{_}]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /** [{@literal if (a < b) { }}] */
+ void in_brackets() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 3
+ Text[TEXT, pos:0, []
+ Literal[LITERAL, pos:1, if_(a_<_b)_{_}]
+ Text[TEXT, pos:26, ]]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /** [ {@literal if (a < b) { }} ] */
+ void in_brackets_with_whitespace() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 3
+ Text[TEXT, pos:0, [_]
+ Literal[LITERAL, pos:2, if_(a_<_b)_{_}]
+ Text[TEXT, pos:27, _]]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * {@literal {@literal nested} }
+ */
+ void nested() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Literal[LITERAL, pos:1, {@literal_nested}_]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * {@literal if (a < b) {
+ * }
+ * }
+ */
+ void embedded_newline() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Literal[LITERAL, pos:1, if_(a_<_b)_{|________}|_]
+ body: empty
+ block tags: empty
+]
+*/
+
+
+ /** {@literal if (a < b) { } */
+ void unterminated_1() { }
+/*
+DocComment[DOC_COMMENT, pos:0
+ firstSentence: 1
+ Erroneous[ERRONEOUS, pos:0
+ code: compiler.err.dc.unterminated.inline.tag
+ body: {@literal_if_(a_<_b)_{_}
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * {@literal if (a < b) { }
+ * @author jjg */
+ void unterminated_2() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Erroneous[ERRONEOUS, pos:1
+ code: compiler.err.dc.unterminated.inline.tag
+ body: {@literal_if_(a_<_b)_{_}
+ ]
+ body: empty
+ block tags: 1
+ Author[AUTHOR, pos:27
+ name: 1
+ Text[TEXT, pos:35, jjg]
+ ]
+]
+*/
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/ParamTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester ParamTest.java
+ */
+
+class ParamTest {
+ /**
+ * @param x
+ */
+ void no_description(int x) { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Param[PARAM, pos:1
+ name:
+ Identifier[IDENTIFIER, pos:8, x]
+ description: empty
+ ]
+]
+*/
+
+ /**
+ * @param x description
+ */
+ void with_description(int x) { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Param[PARAM, pos:1
+ name:
+ Identifier[IDENTIFIER, pos:8, x]
+ description: 1
+ Text[TEXT, pos:10, description]
+ ]
+]
+*/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/ReferenceTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @summary check references in at-see and {at-link} tags
+ * @build ReferenceTest
+ * @compile -processor ReferenceTest -proc:only ReferenceTest.java
+ */
+
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.LinkTree;
+import com.sun.source.doctree.ReferenceTree;
+import com.sun.source.doctree.SeeTree;
+import com.sun.source.doctree.TextTree;
+import com.sun.source.util.DocTreeScanner;
+import com.sun.source.util.DocTrees;
+import com.sun.source.util.TreePath;
+
+import java.util.List;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic.Kind;
+
+/**
+ * {@link java.lang Package}
+ * {@link java.lang.ERROR Bad}
+ *
+ * {@link java.lang.String Class}
+ * {@link String Class}
+ * {@link java.lang.String#CASE_INSENSITIVE_ORDER Field}
+ * {@link java.lang.String#String Constructor}
+ * {@link java.lang.String#String(byte[]) Constructor}
+ * {@link java.lang.String#String(byte[] bytes) Constructor}
+ * {@link java.lang.String#String(byte[], String) Constructor}
+ * {@link java.lang.String#String(byte[] bytes, String charSetName) Constructor}
+ * {@link java.lang.String#isEmpty Method}
+ * {@link java.lang.String#isEmpty() Method}
+ * {@link java.lang.String#ERROR Bad}
+ * {@link java.lang.String#equals(Object) Method}
+ *
+ * {@link AbstractProcessor Class}
+ *
+ * {@link List#add(Object) Method}
+ *
+ * {@link #trees Field}
+ * {@link #getSupportedSourceVersion Method}
+ * {@link #init(ProcessingEnvironment Method}
+ *
+ * @see java.lang Package
+ * @see java.lang.ERROR Bad
+ *
+ * @see java.lang.String Class
+ * @see String Class
+ * @see java.lang.String#CASE_INSENSITIVE_ORDER Field
+ * @see java.lang.String#String Constructor
+ * @see java.lang.String#String(byte[]) Constructor
+ * @see java.lang.String#String(byte[] bytes) Constructor
+ * @see java.lang.String#String(byte[],String) Constructor
+ * @see java.lang.String#String(byte[] bytes, String charsetName) Constructor
+ * @see java.lang.String#isEmpty Method
+ * @see java.lang.String#isEmpty() Method
+ * @see java.lang.String#ERROR Bad
+ * @see java.lang.String#equals(Object) Method
+ *
+ * @see AbstractProcessor Class
+ *
+ * @see List#add(Object) Method
+ *
+ * @see #trees Field
+ * @see #getSupportedSourceVersion Method
+ * @see #init(ProcessingEnvironment) Method
+ *
+ * @see java.io.BufferedInputStream#BufferedInputStream(InputStream) Constructor
+ */
+@SupportedAnnotationTypes("*")
+public class ReferenceTest extends AbstractProcessor {
+ DocTrees trees;
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+
+ @Override
+ public void init(ProcessingEnvironment pEnv) {
+ super.init(pEnv);
+ trees = DocTrees.instance(pEnv);
+ }
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ for (Element e: roundEnv.getRootElements()) {
+ new DocCommentScanner(trees.getPath(e)).scan();
+ }
+ return true;
+ }
+
+ class DocCommentScanner extends DocTreeScanner<Void, Void> {
+ TreePath path;
+ DocCommentTree dc;
+
+ DocCommentScanner(TreePath path) {
+ this.path = path;
+ }
+
+ void scan() {
+ dc = trees.getDocCommentTree(path);
+ scan(dc, null);
+ }
+
+ @Override
+ public Void visitLink(LinkTree tree, Void ignore) {
+ checkReference(tree.getReference(), tree.getLabel());
+ return null;
+ }
+
+ @Override
+ public Void visitSee(SeeTree tree, Void ignore) {
+ List<? extends DocTree> refLabel = tree.getReference();
+ if (refLabel.size() > 1 && (refLabel.get(0) instanceof ReferenceTree)) {
+ ReferenceTree ref = (ReferenceTree) refLabel.get(0);
+ List<? extends DocTree> label = refLabel.subList(1, refLabel.size());
+ checkReference(ref, label);
+ }
+ return null;
+ }
+
+ void checkReference(ReferenceTree tree, List<? extends DocTree> label) {
+ String sig = tree.getSignature();
+
+ Element found = trees.getElement(path, tree);
+ if (found == null) {
+ System.err.println(sig + " NOT FOUND");
+ } else {
+ System.err.println(sig + " found " + found.getKind() + " " + found);
+ }
+
+ String expect = "UNKNOWN";
+ if (label.size() > 0 && label.get(0) instanceof TextTree)
+ expect = ((TextTree) label.get(0)).getBody();
+
+ if (!expect.equalsIgnoreCase(found == null ? "bad" : found.getKind().name())) {
+ error(tree, "Unexpected value found: " + found +", expected: " + expect);
+ }
+ }
+
+ void error(DocTree tree, String msg) {
+ trees.printMessage(Kind.ERROR, msg, tree, dc, path.getCompilationUnit());
+ }
+ }
+}
+
+/**
+ * @see ReferenceTestExtras Class
+ * @see #ReferenceTestExtras Field
+ * @see #ReferenceTestExtras() Constructor
+ *
+ * @see #X Field
+ * @see #X() Method
+ *
+ * @see #m Method
+ *
+ * @see #varargs(int...) Method
+ * @see #varargs(int... args) Method
+ * @see #varargs(int[]) Method
+ * @see #varargs(int[] args) Method
+ */
+class ReferenceTestExtras {
+ int ReferenceTestExtras; // field
+ ReferenceTestExtras() { } // constructor
+ void ReferenceTestExtras() { } // method
+
+ int X;
+ void X() { }
+ static class X { }
+
+ void m() { }
+ void m(int i) { }
+ void m(int i, int j) { }
+
+ void varargs(int... args) { }
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/ReturnTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester ReturnTest.java
+ */
+
+class ReturnTest {
+ /**
+ * @return something
+ */
+ int an_int() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Return[RETURN, pos:1
+ description: 1
+ Text[TEXT, pos:9, something]
+ ]
+]
+*/
+
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/SeeTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester SeeTest.java
+ */
+
+class SeeTest {
+ /**
+ * abc.
+ * @see "String"
+ */
+ void quoted_text() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc.]
+ body: empty
+ block tags: 1
+ Erroneous[ERRONEOUS, pos:7
+ code: compiler.err.dc.unexpected.content
+ body: @see_"String"
+ ]
+]
+*/
+
+ /**
+ * abc.
+ * @see <a href="url">url</a>
+ */
+ void url() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc.]
+ body: empty
+ block tags: 1
+ See[SEE, pos:7
+ reference: 3
+ StartElement[START_ELEMENT, pos:12
+ name:a
+ attributes: 1
+ Attribute[ATTRIBUTE, pos:15
+ name: href
+ vkind: DOUBLE
+ value: 1
+ Text[TEXT, pos:21, url]
+ ]
+ ]
+ Text[TEXT, pos:26, url]
+ EndElement[END_ELEMENT, pos:29, a]
+ ]
+]
+*/
+
+ /**
+ * abc.
+ * @see String text
+ */
+ void string() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc.]
+ body: empty
+ block tags: 1
+ See[SEE, pos:7
+ reference: 2
+ Reference[REFERENCE, pos:12, String]
+ Text[TEXT, pos:19, text]
+ ]
+]
+*/
+
+ /**
+ * abc.
+ * @see java.lang.String text
+ */
+ void j_l_string() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc.]
+ body: empty
+ block tags: 1
+ See[SEE, pos:7
+ reference: 2
+ Reference[REFERENCE, pos:12, java.lang.String]
+ Text[TEXT, pos:29, text]
+ ]
+]
+*/
+
+ /**
+ * abc.
+ * @see java.lang.String#length text
+ */
+ void j_l_string_length() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc.]
+ body: empty
+ block tags: 1
+ See[SEE, pos:7
+ reference: 2
+ Reference[REFERENCE, pos:12, java.lang.String#length]
+ Text[TEXT, pos:36, text]
+ ]
+]
+*/
+
+ /**
+ * abc.
+ * @see java.lang.String#matches(String regex) text
+ */
+ void j_l_string_matches() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc.]
+ body: empty
+ block tags: 1
+ See[SEE, pos:7
+ reference: 2
+ Reference[REFERENCE, pos:12, java.lang.String...#matches(String_regex)]
+ Text[TEXT, pos:51, text]
+ ]
+]
+*/
+
+ /**
+ * abc.
+ * @see 123 text
+ */
+ void bad_numeric() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc.]
+ body: empty
+ block tags: 1
+ Erroneous[ERRONEOUS, pos:7
+ code: compiler.err.dc.unexpected.content
+ body: @see_123_text
+ ]
+]
+*/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/SerialDataTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester SerialDataTest.java
+ */
+
+class SerialDataTest {
+ /**
+ * @serialData description
+ */
+ void writeObject(ObjectOutputStream stream) { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ SerialData[SERIAL_DATA, pos:1
+ description: 1
+ Text[TEXT, pos:13, description]
+ ]
+]
+*/
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/SerialFieldTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester SerialFieldTest.java
+ */
+
+class SerialFieldTest {
+
+ /**
+ * @serialField field String
+ */
+ String f1;
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ SerialField[SERIAL_FIELD, pos:1
+ name:
+ Identifier[IDENTIFIER, pos:14, field]
+ type:
+ Reference[REFERENCE, pos:20, String]
+ description: empty
+ ]
+]
+*/
+
+ /**
+ * @serialField field String f2 is a String
+ */
+ String f2;
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ SerialField[SERIAL_FIELD, pos:1
+ name:
+ Identifier[IDENTIFIER, pos:14, field]
+ type:
+ Reference[REFERENCE, pos:20, String]
+ description: 1
+ Text[TEXT, pos:27, f2_is_a_String]
+ ]
+]
+*/
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/SerialTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester SerialTest.java
+ */
+
+class SerialTest {
+ /**
+ * @serial include
+ */
+ void include() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Serial[SERIAL, pos:1
+ description: 1
+ Text[TEXT, pos:9, include]
+ ]
+]
+*/
+
+ /**
+ * @serial exclude
+ */
+ void exclude() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Serial[SERIAL, pos:1
+ description: 1
+ Text[TEXT, pos:9, exclude]
+ ]
+]
+*/
+
+ /**
+ * @serial description
+ */
+ void description() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Serial[SERIAL, pos:1
+ description: 1
+ Text[TEXT, pos:9, description]
+ ]
+]
+*/
+
+ /**
+ * @serial
+ */
+ void empty() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Serial[SERIAL, pos:1
+ description: empty
+ ]
+]
+*/
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/SimpleDocTreeVisitorTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ */
+
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.DocTreeVisitor;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.DocTreeScanner;
+import com.sun.source.util.DocTrees;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.SimpleDocTreeVisitor;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.tools.javac.api.JavacTool;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+import javax.lang.model.element.Name;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+
+public class SimpleDocTreeVisitorTest {
+ public static void main(String... args) throws Exception {
+ SimpleDocTreeVisitorTest t = new SimpleDocTreeVisitorTest();
+ t.run();
+ }
+
+ void run() throws Exception {
+ List<File> files = new ArrayList<File>();
+ File testSrc = new File(System.getProperty("test.src"));
+ for (File f: testSrc.listFiles()) {
+ if (f.isFile() && f.getName().endsWith(".java"))
+ files.add(f);
+ }
+
+ JavacTool javac = JavacTool.create();
+ StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null);
+
+ Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(files);
+
+ JavacTask t = javac.getTask(null, fm, null, null, null, fos);
+ DocTrees trees = DocTrees.instance(t);
+
+ Iterable<? extends CompilationUnitTree> units = t.parse();
+
+ Set<DocTree.Kind> found = EnumSet.noneOf(DocTree.Kind.class);
+ DeclScanner ds = new DeclScanner(trees, found);
+ for (CompilationUnitTree unit: units) {
+ ds.scan(unit, null);
+ }
+
+ for (DocTree.Kind k: DocTree.Kind.values()) {
+ if (!found.contains(k) && k != DocTree.Kind.OTHER)
+ error("not found: " + k);
+ }
+
+ if (errors > 0)
+ throw new Exception(errors + " errors occurred");
+ }
+
+ void error(String msg) {
+ System.err.println("Error: " + msg);
+ errors++;
+ }
+
+ int errors;
+
+ static class DeclScanner extends TreePathScanner<Void, Void> {
+ DocTrees trees;
+ DocTreeScanner<Void,Void> cs;
+
+ DeclScanner(DocTrees trees, final Set<DocTree.Kind> found) {
+ this.trees = trees;
+ cs = new CommentScanner(found);
+ }
+
+ @Override
+ public Void visitClass(ClassTree tree, Void ignore) {
+ super.visitClass(tree, ignore);
+ visitDecl(tree, tree.getSimpleName());
+ return null;
+ }
+
+ @Override
+ public Void visitMethod(MethodTree tree, Void ignore) {
+ super.visitMethod(tree, ignore);
+ visitDecl(tree, tree.getName());
+ return null;
+ }
+
+ @Override
+ public Void visitVariable(VariableTree tree, Void ignore) {
+ super.visitVariable(tree, ignore);
+ visitDecl(tree, tree.getName());
+ return null;
+ }
+
+ void visitDecl(Tree tree, Name name) {
+ TreePath path = getCurrentPath();
+ DocCommentTree dc = trees.getDocCommentTree(path);
+ if (dc != null)
+ cs.scan(dc, null);
+ }
+ }
+
+ static class CommentScanner extends DocTreeScanner<Void, Void> {
+ DocTreeVisitor<Void, Void> visitor;
+
+ CommentScanner(Set<DocTree.Kind> found) {
+ visitor = new Visitor(found);
+ }
+
+ @Override
+ public Void scan(DocTree tree, Void ignore) {
+ if (tree != null)
+ tree.accept(visitor, ignore);
+ return super.scan(tree, ignore);
+ }
+ }
+
+ static class Visitor extends SimpleDocTreeVisitor<Void, Void> {
+ Set<DocTree.Kind> found;
+
+ Visitor(Set<DocTree.Kind> found) {
+ this.found = found;
+ }
+
+ @Override
+ public Void defaultAction(DocTree tree, Void ignore) {
+ found.add(tree.getKind());
+ return null;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/SinceTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester SinceTest.java
+ */
+
+class SinceTest {
+ /**
+ * abc.
+ * @since then & now.
+ */
+ void standard() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Text[TEXT, pos:1, abc.]
+ body: empty
+ block tags: 1
+ Since[SINCE, pos:7
+ body: 3
+ Text[TEXT, pos:14, then_]
+ Entity[ENTITY, pos:19, amp]
+ Text[TEXT, pos:24, _now.]
+ ]
+]
+*/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/TagTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester TagTest.java
+ */
+
+class TagTest {
+ /**
+ * @author jjg
+ */
+ void simple_standard_block() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Author[AUTHOR, pos:1
+ name: 1
+ Text[TEXT, pos:9, jjg]
+ ]
+]
+*/
+
+ /**
+ * @ abc
+ */
+ void no_name_block() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Erroneous[ERRONEOUS, pos:1
+ code: compiler.err.dc.no.tag.name
+ body: @_abc
+ ]
+]
+*/
+
+ /**
+ * @abc def ghi
+ */
+ void unknown_name_block() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ UnknownBlockTag[UNKNOWN_BLOCK_TAG, pos:1
+ tag:abc
+ content: 1
+ Text[TEXT, pos:6, def_ghi]
+ ]
+]
+*/
+
+ /**
+ * {@link String}
+ */
+ void simple_standard_inline() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Link[LINK, pos:1
+ reference:
+ Reference[REFERENCE, pos:8, String]
+ body: empty
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * {@ abc}
+ */
+ void no_name_inline() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 2
+ Erroneous[ERRONEOUS, pos:1
+ code: compiler.err.dc.no.tag.name
+ body: {@
+ ]
+ Text[TEXT, pos:3, _abc}]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * {@abc def ghi}
+ */
+ void unknown_name_inline() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ UnknownInlineTag[UNKNOWN_INLINE_TAG, pos:1
+ tag:abc
+ content: 1
+ Text[TEXT, pos:7, def_ghi]
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * {@abc def ghi
+ */
+ void unterminated_standard_inline() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 1
+ Erroneous[ERRONEOUS, pos:1
+ code: compiler.err.dc.unterminated.inline.tag
+ body: {@abc_def_ghi
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/ThrowableTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester ThrowableTest.java
+ */
+
+class ThrowableTest {
+ /**
+ * @throws Exception
+ */
+ void exception() throws Exception { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Throws[THROWS, pos:1
+ exceptionName:
+ Reference[REFERENCE, pos:9, Exception]
+ description: empty
+ ]
+]
+*/
+
+ /**
+ * @throws Exception text
+ */
+ void exception_text() throws Exception { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Throws[THROWS, pos:1
+ exceptionName:
+ Reference[REFERENCE, pos:9, Exception]
+ description: 1
+ Text[TEXT, pos:19, text]
+ ]
+]
+*/
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/ValueTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester ValueTest.java
+ */
+
+class ValueTest {
+ /**
+ * abc {@value}
+ */
+ int no_ref() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 2
+ Text[TEXT, pos:1, abc_]
+ Value[VALUE, pos:5
+ reference: null
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@value java.awt.Color#RED}
+ */
+ int typical() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 2
+ Text[TEXT, pos:1, abc_]
+ Value[VALUE, pos:5
+ reference:
+ Reference[REFERENCE, pos:13, java.awt.Color#RED]
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@value java.awt.Color#RED }
+ */
+ int trailing_ws() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 2
+ Text[TEXT, pos:1, abc_]
+ Value[VALUE, pos:5
+ reference:
+ Reference[REFERENCE, pos:13, java.awt.Color#RED]
+ ]
+ body: empty
+ block tags: empty
+]
+*/
+
+ /**
+ * abc {@value java.awt.Color#RED junk}
+ */
+ int trailing_junk() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: 3
+ Text[TEXT, pos:1, abc_]
+ Erroneous[ERRONEOUS, pos:5
+ code: compiler.err.dc.unexpected.content
+ body: {@value_java.awt.Color#RED_j
+ ]
+ Text[TEXT, pos:33, unk}]
+ body: empty
+ block tags: empty
+]
+*/
+
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doctree/VersionTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 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 7021614
+ * @summary extend com.sun.source API to support parsing javadoc comments
+ * @build DocCommentTester
+ * @run main DocCommentTester VersionTest.java
+ */
+
+class VersionTest {
+ /**
+ * @version 1.2
+ */
+ void version() { }
+/*
+DocComment[DOC_COMMENT, pos:1
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Version[VERSION, pos:1
+ body: 1
+ Text[TEXT, pos:10, 1.2]
+ ]
+]
+*/
+
+}
+
+
--- a/langtools/test/tools/javac/generics/7022054/T7022054pos1.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/generics/7022054/T7022054pos1.java Fri Nov 30 17:09:05 2012 -0800
@@ -26,7 +26,8 @@
* @bug 7022054
*
* @summary Invalid compiler error on covariant overriding methods with the same erasure
- * @compile T7022054pos1.java
+ * @compile -source 7 T7022054pos1.java
+ * @compile/fail/ref=T7022054pos1.out -XDrawDiagnostics T7022054pos1.java
*
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/7022054/T7022054pos1.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+T7022054pos1.java:39:25: compiler.err.name.clash.same.erasure.no.override: <X>m(java.lang.String), T7022054pos1.B, m(java.lang.String), T7022054pos1.A, <X>m(java.lang.String), T7022054pos1.B
+1 error
--- a/langtools/test/tools/javac/generics/7022054/T7022054pos2.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/generics/7022054/T7022054pos2.java Fri Nov 30 17:09:05 2012 -0800
@@ -26,8 +26,8 @@
* @bug 7022054
*
* @summary Invalid compiler error on covariant overriding methods with the same erasure
- * @compile T7022054pos2.java
- *
+ * @compile -source 7 T7022054pos2.java
+ * @compile/fail/ref=T7022054pos2.out -XDrawDiagnostics T7022054pos2.java
*/
class T7022054pos2 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/7022054/T7022054pos2.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+T7022054pos2.java:38:32: compiler.err.name.clash.same.erasure.no.hide: <X>m(java.lang.String), T7022054pos2.B, m(java.lang.String), T7022054pos2.A
+1 error
--- a/langtools/test/tools/javac/generics/inference/6611449/T6611449.out Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/generics/inference/6611449/T6611449.out Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
-T6611449.java:18:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S))}
-T6611449.java:19:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.infer.arg.length.mismatch: T))}
+T6611449.java:18:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.infer.arg.length.mismatch: T))}
+T6611449.java:19:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, <T>T6611449(T,T), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S))}
T6611449.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, T, int, kindname.class, T6611449<S>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S)
T6611449.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, T,T, int,int, kindname.class, T6611449<S>, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S)
4 errors
--- a/langtools/test/tools/javac/generics/inference/7086601/T7086601a.out Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/generics/inference/7086601/T7086601a.out Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
-T7086601a.java:20:9: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m1(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m1(java.lang.Iterable<? super S>,java.lang.Iterable<? super S>), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String,java.lang.Object))}
-T7086601a.java:24:9: compiler.err.cant.apply.symbols: kindname.method, m2, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,java.lang.Iterable<java.lang.Double>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m2(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m2(java.lang.Iterable<? super S>,java.lang.Iterable<? super S>,java.lang.Iterable<? super S>), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String,java.lang.Object))}
-T7086601a.java:28:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m3(java.lang.Iterable<? super S>...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String,java.lang.Object))}
-T7086601a.java:32:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,java.lang.Iterable<java.lang.Double>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m3(java.lang.Iterable<? super S>...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String,java.lang.Object))}
+T7086601a.java:20:9: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m1(java.lang.Iterable<? super S>,java.lang.Iterable<? super S>), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String,java.lang.Object)),(compiler.misc.inapplicable.method: kindname.method, T7086601, m1(java.lang.Object), (compiler.misc.arg.length.mismatch))}
+T7086601a.java:24:9: compiler.err.cant.apply.symbols: kindname.method, m2, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,java.lang.Iterable<java.lang.Double>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m2(java.lang.Iterable<? super S>,java.lang.Iterable<? super S>,java.lang.Iterable<? super S>), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String,java.lang.Object)),(compiler.misc.inapplicable.method: kindname.method, T7086601, m2(java.lang.Object), (compiler.misc.arg.length.mismatch))}
+T7086601a.java:28:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m3(java.lang.Iterable<? super S>...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String,java.lang.Object)),(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch))}
+T7086601a.java:32:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable<java.lang.String>,java.lang.Iterable<java.lang.Integer>,java.lang.Iterable<java.lang.Double>,{(compiler.misc.inapplicable.method: kindname.method, T7086601, <S>m3(java.lang.Iterable<? super S>...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String,java.lang.Object)),(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch))}
4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/incompleteStatements/T8000484.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8000484
+ * @summary Bad error recovery when 'catch' without 'try' is found
+ * @compile/fail/ref=T8000484.out -XDrawDiagnostics T8000484.java
+ */
+
+public class T8000484 {
+ void m() {
+ catch (Exception e){}
+ else{}
+ finally{}
+ catch (Exception e) {catch (Exception e){}}
+ else{else{}}
+ finally{finally{}}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/incompleteStatements/T8000484.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,10 @@
+T8000484.java:10:9: compiler.err.catch.without.try
+T8000484.java:11:9: compiler.err.else.without.if
+T8000484.java:12:9: compiler.err.finally.without.try
+T8000484.java:13:30: compiler.err.catch.without.try
+T8000484.java:13:9: compiler.err.catch.without.try
+T8000484.java:14:14: compiler.err.else.without.if
+T8000484.java:14:9: compiler.err.else.without.if
+T8000484.java:15:17: compiler.err.finally.without.try
+T8000484.java:15:9: compiler.err.finally.without.try
+9 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadAccess.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,30 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that non-static variables are not accessible from static lambdas
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=BadAccess.out -XDrawDiagnostics BadAccess.java
+ */
+
+public class BadAccess {
+
+ int i;
+ static int I;
+
+ interface SAM {
+ int m();
+ }
+
+ static void test1() {
+ int l = 0; //effectively final
+ final int L = 0;
+ SAM s = ()-> i + I + l + L;
+ }
+
+ void test2() {
+ int l = 0; //effectively final
+ final int L = 0;
+ SAM s = ()-> i + I + l + L;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadAccess.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+BadAccess.java:22:22: compiler.err.non-static.cant.be.ref: kindname.variable, i
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadAccess02.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,31 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check lambda can access only effectively-final locals
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=BadAccess02.out -XDrawDiagnostics BadAccess02.java
+ */
+
+public class BadAccess02 {
+
+ interface SAM {
+ int m(int h);
+ }
+
+ static void test1() {
+ int l = 0; //effectively final
+ int j = 0; //non-effectively final
+ j = 2;
+ final int L = 0;
+ SAM s = (int h) -> { int k = 0; return h + j + l + L; };
+ }
+
+ void test2() {
+ int l = 0; //effectively final
+ int j = 0; //non-effectively final
+ j = 2;
+ final int L = 0;
+ SAM s = (int h) -> { int k = 0; return h + k + j + l + L; };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadAccess02.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+BadAccess02.java:21:52: compiler.err.cant.ref.non.effectively.final.var: j, (compiler.misc.lambda)
+BadAccess02.java:29:56: compiler.err.cant.ref.non.effectively.final.var: j, (compiler.misc.lambda)
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadAccess03.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check lambda cannot assign non-effectively final locals
+ * @compile/fail/ref=BadAccess03.out -XDrawDiagnostics BadAccess03.java
+ */
+
+class BadAccess03 {
+ void test() {
+ int k = 0;
+ int n = 2; //effectively final variable
+ Runnable r = ()-> { k = n; }; //error
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadAccess03.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+BadAccess03.java:13:29: compiler.err.cant.ref.non.effectively.final.var: k, (compiler.misc.lambda)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadBreakContinue.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,44 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that break/continue is disallowed in lambda expressions
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=BadBreakContinue.out -XDrawDiagnostics BadBreakContinue.java
+ */
+
+class BadBreakContinue {
+
+ static interface SAM {
+ void m();
+ }
+
+ SAM s1 = ()-> { break; };
+ SAM s2 = ()-> { continue; };
+ SAM s3 = ()-> {
+ SAM s3_1 = ()-> { break; };
+ SAM s3_2 = ()-> { continue; };
+ };
+
+ void testLabelled() {
+ loop: while (true) {
+ SAM s1 = ()-> { break loop; };
+ SAM s2 = ()-> { continue loop; };
+ SAM s3 = ()-> {
+ SAM s3_1 = ()-> { break loop; };
+ SAM s3_2 = ()-> { continue loop; };
+ };
+ }
+ }
+
+ void testNonLabelled() {
+ while (true) {
+ SAM s1 = ()-> { break; };
+ SAM s2 = ()-> { continue; };
+ SAM s3 = ()-> {
+ SAM s3_1 = ()-> { break; };
+ SAM s3_2 = ()-> { continue; };
+ };
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadBreakContinue.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,13 @@
+BadBreakContinue.java:16:21: compiler.err.break.outside.switch.loop
+BadBreakContinue.java:17:21: compiler.err.cont.outside.loop
+BadBreakContinue.java:19:27: compiler.err.break.outside.switch.loop
+BadBreakContinue.java:20:27: compiler.err.cont.outside.loop
+BadBreakContinue.java:25:29: compiler.err.undef.label: loop
+BadBreakContinue.java:26:29: compiler.err.undef.label: loop
+BadBreakContinue.java:28:35: compiler.err.undef.label: loop
+BadBreakContinue.java:29:35: compiler.err.undef.label: loop
+BadBreakContinue.java:36:29: compiler.err.break.outside.switch.loop
+BadBreakContinue.java:37:29: compiler.err.cont.outside.loop
+BadBreakContinue.java:39:35: compiler.err.break.outside.switch.loop
+BadBreakContinue.java:40:35: compiler.err.cont.outside.loop
+12 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadConv03.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * NPE while checking if subinterface is a SAM type
+ * @compile/fail/ref=BadConv03.out -XDrawDiagnostics BadConv03.java
+ */
+
+class BadConv03 {
+
+ interface A {
+ void a();
+ }
+
+ interface B extends A { //not a SAM (2 non-override equivalent abstracts!)
+ void a(int i);
+ }
+
+ B b = ()-> { };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadConv03.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+BadConv03.java:19:11: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, BadConv03.B))
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadConv04.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that ill-formed SAM type generates right diagnostic when SAM converted
+ * @compile/fail/ref=BadConv04.out -XDrawDiagnostics BadConv04.java
+ */
+
+class BadConv04 {
+
+ interface I1 {
+ int m();
+ }
+
+ interface I2 {
+ long m();
+ }
+
+ interface SAM extends I1, I2 {}
+
+ SAM s = ()-> { };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadConv04.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+BadConv04.java:19:5: compiler.err.types.incompatible.diff.ret: BadConv04.I2, BadConv04.I1, m()
+BadConv04.java:21:13: compiler.err.prob.found.req: (compiler.misc.incompatible.descs.in.functional.intf: kindname.interface, BadConv04.SAM,{(compiler.misc.descriptor: m, , long, ),(compiler.misc.descriptor: m, , int, )})
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadExpressionLambda.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that a conditonal can't be void
+ * @compile/fail/ref=BadExpressionLambda.out -XDrawDiagnostics BadExpressionLambda.java
+ */
+
+class BadExpressionLambda {
+
+ interface SAM {
+ void invoke();
+ }
+
+ public static void m() {}
+
+ void test() {
+ SAM sam1 = () -> m(); //ok
+ SAM sam2 = () -> true ? m() : m(); //not ok
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadExpressionLambda.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+BadExpressionLambda.java:19:31: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.conditional.target.cant.be.void))
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadLambdaExpr.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * compile crashes on partial lambda expressions
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+
+public class BadLambdaExpr {
+
+ static int checkCount = 0;
+
+ enum ParameterListKind {
+ ZERO_ARY("()"),
+ UNARY("(#P)"),
+ TWO_ARY("(#P, #P)"),
+ THREE_ARY("(#P, #P, #P)");
+
+ String parametersTemplateStr;
+
+ ParameterListKind(String parametersTemplateStr) {
+ this.parametersTemplateStr = parametersTemplateStr;
+ }
+
+ String getParameterString(ParameterKind pk) {
+ return parametersTemplateStr.replaceAll("#P", pk.parameterStr);
+ }
+ }
+
+ enum ParameterKind {
+ IMPLICIT("a"),
+ EXPLIICT("A a");
+
+ String parameterStr;
+
+ ParameterKind(String parameterStr) {
+ this.parameterStr = parameterStr;
+ }
+ }
+
+ enum ArrowKind {
+ NONE(""),
+ SEMI("-"),
+ FULL("->");
+
+ String arrowStr;
+
+ ArrowKind(String arrowStr) {
+ this.arrowStr = arrowStr;
+ }
+ }
+
+ enum ExprKind {
+ NONE("#P#A"),
+ METHOD_CALL("m(#P#A)"),
+ CONSTR_CALL("new Foo(#P#A)");
+
+ String expressionTemplate;
+
+ ExprKind(String expressionTemplate) {
+ this.expressionTemplate = expressionTemplate;
+ }
+
+ String expressionString(ParameterListKind plk, ParameterKind pk,
+ ArrowKind ak) {
+ return expressionTemplate.replaceAll("#P", plk.getParameterString(pk))
+ .replaceAll("#A", ak.arrowStr);
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+
+ //create default shared JavaCompiler - reused across multiple compilations
+ JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+ for (ParameterListKind plk : ParameterListKind.values()) {
+ for (ParameterKind pk : ParameterKind.values()) {
+ for (ArrowKind ak : ArrowKind.values()) {
+ for (ExprKind ek : ExprKind.values()) {
+ new BadLambdaExpr(plk, pk, ak, ek).run(comp, fm);
+ }
+ }
+ }
+ }
+ System.out.println("Total check executed: " + checkCount);
+ }
+
+ ParameterListKind plk;
+ ParameterKind pk;
+ ArrowKind ak;
+ ExprKind ek;
+ JavaSource source;
+ DiagnosticChecker diagChecker;
+
+ BadLambdaExpr(ParameterListKind plk, ParameterKind pk, ArrowKind ak, ExprKind ek) {
+ this.plk = plk;
+ this.pk = pk;
+ this.ak = ak;
+ this.ek = ek;
+ this.source = new JavaSource();
+ this.diagChecker = new DiagnosticChecker();
+ }
+
+ class JavaSource extends SimpleJavaFileObject {
+
+ String template = "class Test {\n" +
+ " SAM s = #E;\n" +
+ "}";
+
+ String source;
+
+ public JavaSource() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ source = template.replaceAll("#E", ek.expressionString(plk, pk, ak));
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+ JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+ null, null, Arrays.asList(source));
+ try {
+ ct.parse();
+ } catch (Throwable ex) {
+ throw new AssertionError("Error thron when parsing the following source:\n" + source.getCharContent(true));
+ }
+ check();
+ }
+
+ void check() {
+ boolean errorExpected =
+ ak != ArrowKind.NONE ||
+ plk != ParameterListKind.UNARY ||
+ pk != ParameterKind.IMPLICIT;
+ if (errorExpected != diagChecker.errorFound) {
+ throw new Error("bad diag for source:\n" +
+ source.getCharContent(true));
+ }
+ checkCount++;
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound;
+
+ @Override
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ errorFound = true;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadLambdaPos.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,31 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that lambda is only allowed in argument/cast/assignment context
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=BadLambdaPos.out -XDrawDiagnostics BadLambdaPos.java
+ */
+
+interface SAM {
+ void m(Integer x);
+}
+
+class Test {
+ void test(Object x) {}
+
+ void test1() {
+ test((int x)-> { } + (int x)-> { } );
+ test((int x)-> { } instanceof Object );
+ }
+
+ void test2() {
+ int i2 = (int x)-> { } + (int x)-> { };
+ boolean b = (int x)-> { } instanceof Object;
+ }
+
+ void test3() {
+ test((Object)(int x)-> { });
+ Object o = (Object)(int x)-> { };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadLambdaPos.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,9 @@
+BadLambdaPos.java:18:14: compiler.err.unexpected.lambda
+BadLambdaPos.java:18:30: compiler.err.unexpected.lambda
+BadLambdaPos.java:19:14: compiler.err.unexpected.lambda
+BadLambdaPos.java:23:18: compiler.err.unexpected.lambda
+BadLambdaPos.java:23:34: compiler.err.unexpected.lambda
+BadLambdaPos.java:24:21: compiler.err.unexpected.lambda
+BadLambdaPos.java:28:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+BadLambdaPos.java:29:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+8 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadMethodCall.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that diagnostics on nested erroneous deferred types are flushed
+ * @compile/fail/ref=BadMethodCall.out -XDrawDiagnostics BadMethodCall.java
+ */
+import java.util.*;
+
+class BadMethodCall {
+ <I> List<I> id(List<I> z) { return null; };
+
+ List<String> cons(String s, List<String> ls) { return null; }
+
+ void test(List<Object> lo) { Object t = cons(id(""),lo); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadMethodCall.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+BadMethodCall.java:15:50: compiler.err.cant.apply.symbol: kindname.method, id, java.util.List<I>, java.lang.String, kindname.class, BadMethodCall, (compiler.misc.infer.no.conforming.assignment.exists: I, (compiler.misc.inconvertible.types: java.lang.String, java.util.List<I>))
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadRecovery.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that recovery of speculative types is not attempted if receiver is erroneous
+ * @compile/fail/ref=BadRecovery.out -XDrawDiagnostics BadRecovery.java
+ */
+class BadRecovery {
+
+ interface SAM1 {
+ void m(Object o);
+ }
+
+ void m(SAM1 m) { };
+
+ void test() {
+ m((receiver, t) -> { receiver.someMemberOfReceiver(()->{ Object x = f; }); });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadRecovery.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+BadRecovery.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, BadRecovery.SAM1, @369, kindname.class, BadRecovery, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.lambda))
+BadRecovery.java:17:77: compiler.err.cant.resolve.location: kindname.variable, f, , , (compiler.misc.location: kindname.class, BadRecovery, null)
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadReturn.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,38 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that incompatible return types in lambdas are flagged with error
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=BadReturn.out -XDrawDiagnostics BadReturn.java
+ */
+
+class BadReturn {
+
+ interface SAM {
+ Comparable<?> m();
+ }
+
+ static void testNeg1() {
+ SAM s = ()-> {
+ if (true) {
+ return "";
+ } else {
+ return System.out.println("");
+ }};
+ }
+
+ static void testNeg2() {
+ SAM s = ()-> { return System.out.println(""); };
+ }
+
+ static void testPos() {
+ SAM s = ()-> {
+ if (false) {
+ return 10;
+ }
+ else {
+ return true;
+ }};
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadReturn.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+BadReturn.java:21:42: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: void, java.lang.Comparable<?>))
+BadReturn.java:26:49: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: void, java.lang.Comparable<?>))
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadStatementInLambda.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that the compiler emits meaningful diagnostics when the lambda body contains bad statements
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=BadStatementInLambda.out -XDrawDiagnostics BadStatementInLambda.java
+ */
+
+class BadStatementInLambda {
+
+ interface SAM{
+ Object m();
+ }
+
+ SAM t1 = ()-> { null; };
+ SAM t2 = ()-> { 1; };
+ SAM t3 = ()-> { 1 + 5; };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadStatementInLambda.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,4 @@
+BadStatementInLambda.java:16:21: compiler.err.not.stmt
+BadStatementInLambda.java:17:21: compiler.err.not.stmt
+BadStatementInLambda.java:18:23: compiler.err.not.stmt
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadStatementInLambda02.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that the compiler emits meaningful diagnostics when the lambda body contains bad statements
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=BadStatementInLambda02.out -XDrawDiagnostics BadStatementInLambda02.java
+ */
+
+class BadStatementInLambda02 {
+
+ interface SAM {
+ void m();
+ }
+
+ { call(()-> { System.out.println(new NonExistentClass() + ""); }); }
+
+ void call(SAM s) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadStatementInLambda02.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+BadStatementInLambda02.java:16:42: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, BadStatementInLambda02, null)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadTargetType.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,23 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that only SAM are allowed as target types for lambda expressions
+ * @author Jan Lahoda
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=BadTargetType.out -XDrawDiagnostics BadTargetType.java
+ */
+
+class BadTargetType {
+
+ static void m1(Object o) {}
+ void m2(Object o) {}
+
+ static Object l1 = (int pos)-> { };
+ Object l2 = (int pos)-> { };
+
+ {
+ m1((int pos)-> { });
+ m2((int pos)-> { });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/BadTargetType.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,5 @@
+BadTargetType.java:16:24: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+BadTargetType.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+BadTargetType.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, java.lang.Object, @460, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf))
+BadTargetType.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, java.lang.Object, @489, kindname.class, BadTargetType, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf))
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/Conditional01.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * conditional and varargs
+ * @compile -XDcomplexinference Conditional01.java
+ */
+
+import java.util.*;
+
+class Conditional01 {
+ void varargs(Object ... args) { }
+
+ void test(boolean flag, List<String> ls) {
+ varargs(flag ? "" : ls);
+ varargs(null, flag ? "" : ls);
+ varargs(flag ? "" : ls());
+ varargs(null, flag ? "" : ls());
+ }
+
+ List<String> ls() { return null; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/Conditional02.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * inference and conditionals
+ * @compile -XDcomplexinference Conditional02.java
+ */
+
+class Conditional02 {
+
+ <Z> void m1(Z z) { }
+ <Z> void m2(Z... z) { }
+
+ void test(boolean flag) {
+ m1(flag ? "" : "");
+ m2(flag ? "" : "");
+ m2("", flag ? "" : "");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/Conditional03.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * conditionals and boxing
+ * @compile -XDcomplexinference Conditional03.java
+ */
+
+class Conditional03 {
+
+ void m1(Object o) { }
+ void m2(int i) { }
+
+ void test(boolean cond) {
+ m1((cond ? 1 : 1));
+ m1((cond ? box(1) : box(1)));
+ }
+
+ Integer box(int i) { return i; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/Conformance01.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * lambda compiler regression with uninferred type-variables in generic constructor call
+ * @compile Conformance01.java
+ */
+
+class Conformance01 {
+ <T1, T2> Conformance01(T1 t) { }
+
+ Conformance01 c01 = new Conformance01(null);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/Defender01.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * routine that checks for SAM types should skip defender methods in extended interfaces
+ * @author Maurizio Cimadamore
+ * @compile Defender01.java
+ */
+
+class Defender01 {
+
+ interface A{
+ Object m();
+ default void n() { E.n(this); }
+ }
+
+ static class E{
+ static void n(A a){};
+ }
+
+ A t = ()-> null;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/DisjunctiveTypeTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that subtyping between disjunctive and non disjunctive type works
+ * @author Maurizio Cimadamore
+ * @compile DisjunctiveTypeTest.java
+ */
+
+class DisjunctiveTypeTest {
+
+ static class A extends IllegalArgumentException {
+ A(String a) { super(a); }
+ }
+
+ class B extends IllegalArgumentException {
+ B(String b) { super(b); }
+ }
+
+ void m() throws A,B {}
+
+ void test() {
+ try {
+ m();
+ } catch (A|B e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/EffectivelyFinal01.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * effectively final check fails on method parameter
+ * @compile/fail/ref=EffectivelyFinal01.out -XDrawDiagnostics EffectivelyFinal01.java
+ */
+class EffectivelyFinal01 {
+
+ interface SAM {
+ Integer m(Integer i);
+ }
+
+ void test(Integer nefPar) {
+ SAM s = (Integer h) -> { Integer k = 0; return k + h + nefPar; };
+ nefPar++; //non-effectively final
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/EffectivelyFinal01.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+EffectivelyFinal01.java:15:65: compiler.err.cant.ref.non.effectively.final.var: nefPar, (compiler.misc.lambda)
+1 error
--- a/langtools/test/tools/javac/lambda/EffectivelyFinalTest.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/lambda/EffectivelyFinalTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,30 +1,9 @@
/*
- * Copyright (c) 2012, 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 Integrate efectively final check with DA/DU analysis
- * @compile/fail/ref=EffectivelyFinalTest01.out -XDallowEffectivelyFinalInInnerClasses -XDrawDiagnostics EffectivelyFinalTest.java
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Integrate effectively final check with DA/DU analysis
+ * @compile/fail/ref=EffectivelyFinalTest01.out -XDrawDiagnostics EffectivelyFinalTest.java
* @compile/fail/ref=EffectivelyFinalTest02.out -source 7 -Xlint:-options -XDrawDiagnostics EffectivelyFinalTest.java
*/
class EffectivelyFinalTest {
@@ -62,7 +41,7 @@
void m6(int x) {
new Object() { { System.out.println(x+1); } }; //error - x not EF
- x++;
+ x++; // Illegal: x is not effectively final.
}
void m7(int x) {
--- a/langtools/test/tools/javac/lambda/EffectivelyFinalTest01.out Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/lambda/EffectivelyFinalTest01.out Fri Nov 30 17:09:05 2012 -0800
@@ -1,6 +1,6 @@
-EffectivelyFinalTest.java:46:47: compiler.err.var.might.not.have.been.initialized: y
-EffectivelyFinalTest.java:60:47: compiler.err.cant.ref.non.effectively.final.var: y, (compiler.misc.inner.cls)
-EffectivelyFinalTest.java:64:45: compiler.err.cant.ref.non.effectively.final.var: x, (compiler.misc.inner.cls)
-EffectivelyFinalTest.java:69:45: compiler.err.cant.ref.non.effectively.final.var: x, (compiler.misc.inner.cls)
-EffectivelyFinalTest.java:74:45: compiler.err.cant.ref.non.effectively.final.var: y, (compiler.misc.inner.cls)
+EffectivelyFinalTest.java:25:47: compiler.err.var.might.not.have.been.initialized: y
+EffectivelyFinalTest.java:39:47: compiler.err.cant.ref.non.effectively.final.var: y, (compiler.misc.inner.cls)
+EffectivelyFinalTest.java:43:45: compiler.err.cant.ref.non.effectively.final.var: x, (compiler.misc.inner.cls)
+EffectivelyFinalTest.java:48:45: compiler.err.cant.ref.non.effectively.final.var: x, (compiler.misc.inner.cls)
+EffectivelyFinalTest.java:53:45: compiler.err.cant.ref.non.effectively.final.var: y, (compiler.misc.inner.cls)
5 errors
--- a/langtools/test/tools/javac/lambda/EffectivelyFinalTest02.out Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/lambda/EffectivelyFinalTest02.out Fri Nov 30 17:09:05 2012 -0800
@@ -1,14 +1,14 @@
-EffectivelyFinalTest.java:46:47: compiler.err.var.might.not.have.been.initialized: y
-EffectivelyFinalTest.java:34:45: compiler.err.local.var.accessed.from.icls.needs.final: x
-EffectivelyFinalTest.java:34:47: compiler.err.local.var.accessed.from.icls.needs.final: y
-EffectivelyFinalTest.java:40:45: compiler.err.local.var.accessed.from.icls.needs.final: x
-EffectivelyFinalTest.java:40:47: compiler.err.local.var.accessed.from.icls.needs.final: y
-EffectivelyFinalTest.java:46:45: compiler.err.local.var.accessed.from.icls.needs.final: x
-EffectivelyFinalTest.java:53:45: compiler.err.local.var.accessed.from.icls.needs.final: x
-EffectivelyFinalTest.java:53:47: compiler.err.local.var.accessed.from.icls.needs.final: y
-EffectivelyFinalTest.java:60:45: compiler.err.local.var.accessed.from.icls.needs.final: x
-EffectivelyFinalTest.java:60:47: compiler.err.local.var.accessed.from.icls.needs.final: y
-EffectivelyFinalTest.java:64:45: compiler.err.local.var.accessed.from.icls.needs.final: x
-EffectivelyFinalTest.java:69:45: compiler.err.local.var.accessed.from.icls.needs.final: x
-EffectivelyFinalTest.java:74:45: compiler.err.local.var.accessed.from.icls.needs.final: y
+EffectivelyFinalTest.java:25:47: compiler.err.var.might.not.have.been.initialized: y
+EffectivelyFinalTest.java:13:45: compiler.err.local.var.accessed.from.icls.needs.final: x
+EffectivelyFinalTest.java:13:47: compiler.err.local.var.accessed.from.icls.needs.final: y
+EffectivelyFinalTest.java:19:45: compiler.err.local.var.accessed.from.icls.needs.final: x
+EffectivelyFinalTest.java:19:47: compiler.err.local.var.accessed.from.icls.needs.final: y
+EffectivelyFinalTest.java:25:45: compiler.err.local.var.accessed.from.icls.needs.final: x
+EffectivelyFinalTest.java:32:45: compiler.err.local.var.accessed.from.icls.needs.final: x
+EffectivelyFinalTest.java:32:47: compiler.err.local.var.accessed.from.icls.needs.final: y
+EffectivelyFinalTest.java:39:45: compiler.err.local.var.accessed.from.icls.needs.final: x
+EffectivelyFinalTest.java:39:47: compiler.err.local.var.accessed.from.icls.needs.final: y
+EffectivelyFinalTest.java:43:45: compiler.err.local.var.accessed.from.icls.needs.final: x
+EffectivelyFinalTest.java:48:45: compiler.err.local.var.accessed.from.icls.needs.final: x
+EffectivelyFinalTest.java:53:45: compiler.err.local.var.accessed.from.icls.needs.final: y
13 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/ErroneousArg.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,36 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * speculative cache mismatches between Resolve.access and Attr.checkId leads to compiler crashes
+ * @compile/fail/ref=ErroneousArg.out -XDrawDiagnostics ErroneousArg.java
+ */
+class ErroneousArg {
+
+ private static class Foo {
+ static int j() { return 1; }
+ }
+
+ static Foo foo = new Foo();
+
+ static void m(String s) { }
+ static void m(Integer i) { }
+
+ static int f(String s) { return 1; }
+
+ static int g(String s) { return 1; }
+ static int g(Double s) { return 1; }
+
+ int h() { return 1; }
+}
+
+class TestErroneousArg extends ErroneousArg {
+ static void test() {
+ m(unknown()); //method not found
+ m(f(1)); //inapplicable method
+ m(g(1)); //inapplicable methods
+ m(g(null)); //ambiguous
+ m(h()); //static error
+ m(foo.j()); //inaccessible method
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/ErroneousArg.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,7 @@
+ErroneousArg.java:29:11: compiler.err.cant.resolve.location.args: kindname.method, unknown, , , (compiler.misc.location: kindname.class, TestErroneousArg, null)
+ErroneousArg.java:30:11: compiler.err.cant.apply.symbol: kindname.method, f, java.lang.String, int, kindname.class, ErroneousArg, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))
+ErroneousArg.java:31:11: compiler.err.cant.apply.symbols: kindname.method, g, int,{(compiler.misc.inapplicable.method: kindname.method, ErroneousArg, g(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))),(compiler.misc.inapplicable.method: kindname.method, ErroneousArg, g(java.lang.Double), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.Double)))}
+ErroneousArg.java:32:11: compiler.err.ref.ambiguous: g, kindname.method, g(java.lang.String), ErroneousArg, kindname.method, g(java.lang.Double), ErroneousArg
+ErroneousArg.java:33:11: compiler.err.non-static.cant.be.ref: kindname.method, h()
+ErroneousArg.java:34:14: compiler.err.not.def.access.class.intf.cant.access: j(), ErroneousArg.Foo
+6 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/ErroneousLambdaExpr.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * stale state after speculative attribution round leads to missing classfiles
+ */
+public class ErroneousLambdaExpr<T> {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM1<X> {
+ X m(X t, String s);
+ }
+
+ interface SAM2 {
+ void m(String s, int i);
+ }
+
+ interface SAM3<X> {
+ X m(X t, String s, int i);
+ }
+
+ void call(SAM1<T> s1) { assertTrue(true); }
+
+ void call(SAM2 s2) { assertTrue(false); }
+
+ void call(SAM3<T> s3) { assertTrue(false); }
+
+ public static void main(String[] args) {
+ ErroneousLambdaExpr<StringBuilder> test =
+ new ErroneousLambdaExpr<>();
+
+ test.call((builder, string) -> { builder.append(string); return builder; });
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/InnerConstructor.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * Regression test JDK-8003306 inner class constructor in lambda
+ * @author Robert Field
+ */
+
+public class InnerConstructor {
+
+ public static void main(String... args) {
+ InnerConstructor ic = new InnerConstructor();
+ String res = ic.seq1().m().toString();
+ if (!res.equals("Cbl.toString")) {
+ throw new AssertionError(String.format("Unexpected result: %s", res));
+ }
+ }
+
+ Ib1 seq1() {
+ return () -> new Cbl();
+ }
+
+ class Cbl {
+ Cbl() { }
+ public String toString() {
+ return "Cbl.toString";
+ }
+ }
+
+ interface Ib1 {
+ Object m();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaCapture01.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * basic test for capture of non-mutable locals
+ * @author Brian Goetz
+ * @author Maurizio Cimadamore
+ * @run main LambdaCapture01
+ */
+
+public class LambdaCapture01 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface Tester {
+ void test();
+ }
+
+ interface TU<T, U> {
+ public T foo(U u);
+ }
+
+ public static <T, U> T exec(TU<T, U> lambda, U x) {
+ return lambda.foo(x);
+ }
+
+ public int n = 5;
+
+ //Simple local capture
+ void test1() {
+ final int N = 1;
+ int res = LambdaCapture01.<Integer,Integer>exec((Integer x) -> x + N, 3);
+ assertTrue(4 == res);
+ }
+
+ //Local capture with multiple scopes (anon class)
+ void test2() {
+ final int N = 1;
+ new Tester() {
+ public void test() {
+ final int M = 2;
+ int res = LambdaCapture01.<Integer,Integer>exec((Integer x) -> x + N + M, 3);
+ assertTrue(6 == res);
+ }
+ }.test();
+ }
+
+ //Local capture with multiple scopes (local class)
+ void test3() {
+ final int N = 1;
+ class MyTester implements Tester {
+ public void test() {
+ final int M = 2;
+ int res = LambdaCapture01.<Integer,Integer>exec((Integer x) -> x + N + M, 3);
+ assertTrue(6 == res);
+ }
+ }
+ new MyTester().test();
+ }
+
+ //access to field from enclosing scope
+ void test4() {
+ final int N = 4;
+ int res1 = LambdaCapture01.<Integer,Integer>exec((Integer x) -> x + n + N, 3);
+ assertTrue(12 == res1);
+ int res2 = LambdaCapture01.<Integer,Integer>exec((Integer x) -> x + LambdaCapture01.this.n + N, 3);
+ assertTrue(12 == res2);
+ }
+
+ public static void main(String[] args) {
+ LambdaCapture01 t = new LambdaCapture01();
+ t.test1();
+ t.test2();
+ t.test3();
+ t.test4();
+ assertTrue(assertionCount == 5);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaCapture02.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * basic test for capture of non-mutable locals
+ * @author Brian Goetz
+ * @author Maurizio Cimadamore
+ * @run main LambdaCapture02
+ */
+
+public class LambdaCapture02 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface Tester {
+ void test();
+ }
+
+ interface TU<T, U> {
+ public T foo(U u);
+ }
+
+ public static <T, U> T exec(TU<T, U> lambda, U x) {
+ return lambda.foo(x);
+ }
+
+ public Integer n = 5;
+
+ //Simple local capture
+ void test1() {
+ final Integer N = 1;
+ int res = LambdaCapture02.<Integer,Integer>exec((Integer x) -> x + N, 3);
+ assertTrue(4 == res);
+ }
+
+ //Local capture with multiple scopes (anon class)
+ void test2() {
+ final Integer N = 1;
+ new Tester() {
+ public void test() {
+ final Integer M = 2;
+ int res = LambdaCapture02.<Integer,Integer>exec((Integer x) -> x + N + M, 3);
+ assertTrue(6 == res);
+ }
+ }.test();
+ }
+
+ //Local capture with multiple scopes (local class)
+ void test3() {
+ final Integer N = 1;
+ class MyTester implements Tester {
+ public void test() {
+ final Integer M = 2;
+ int res = LambdaCapture02.<Integer,Integer>exec((Integer x) -> x + N + M, 3);
+ assertTrue(6 == res);
+ }
+ }
+ new MyTester().test();
+ }
+
+ //access to field from enclosing scope
+ void test4() {
+ final Integer N = 4;
+ int res1 = LambdaCapture02.<Integer,Integer>exec((Integer x) -> x + n + N, 3);
+ assertTrue(12 == res1);
+ int res2 = LambdaCapture02.<Integer,Integer>exec((Integer x) -> x + LambdaCapture02.this.n + N, 3);
+ assertTrue(12 == res2);
+ }
+
+ public static void main(String[] args) {
+ LambdaCapture02 t = new LambdaCapture02();
+ t.test1();
+ t.test2();
+ t.test3();
+ t.test4();
+ assertTrue(assertionCount == 5);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaCapture03.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * test for capture of non-mutable locals/outer fields in multiple scopes
+ * @author Maurizio Cimadamore
+ * @run main LambdaCapture03
+ */
+
+public class LambdaCapture03 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface Tester {
+ void test();
+ }
+
+ interface TU<T, U> {
+ public T foo(U u);
+ }
+
+ public static <T, U> T exec(TU<T, U> lambda, U x) {
+ return lambda.foo(x);
+ }
+
+ Integer n1 = 10;
+
+ void test1() {
+ final Integer N1 = 1;
+ class A {
+ Integer n2 = 20;
+ void test() {
+ final Integer N2 = 2;
+ class B {
+ void test() {
+ final Integer N3 = 3;
+ int res = LambdaCapture03.exec((Integer x) -> x + n1 + n2 + N1 + N2 + N3, 30);
+ assertTrue(res == 66);
+ }
+ }
+ new B().test();
+ }
+ }
+ new A().test();
+ }
+
+ void test2() {
+ final Integer N1 = 1;
+ new Tester() {
+ Integer n2 = 20;
+ public void test() {
+ final Integer N2 = 2;
+ new Tester() {
+ public void test() {
+ final Integer N3 = 3;
+ int res = LambdaCapture03.exec((Integer x) -> x + n1 + n2 + N1 + N2 + N3, 30);
+ assertTrue(res == 66);
+ }
+ }.test();
+ }
+ }.test();
+ }
+
+ public static void main(String[] args) {
+ LambdaCapture03 t = new LambdaCapture03();
+ t.test1();
+ t.test2();
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaCapture04.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * test for capture of non-mutable locals/outer fields in multiple scopes
+ * @author Maurizio Cimadamore
+ * @run main LambdaCapture04
+ */
+
+public class LambdaCapture04 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface Tester {
+ void test();
+ }
+
+ interface TU<U> {
+ public void foo(U u);
+ }
+
+ public static <U> void exec(TU<U> lambda, U x) {
+ lambda.foo(x);
+ }
+
+ Integer n1 = 10;
+
+ void test1() {
+ final Integer N1 = 1;
+ class A {
+ Integer n2 = 20;
+ void test() {
+ final Integer N2 = 2;
+ class B {
+ void test() {
+ final Integer N3 = 3;
+ exec((final Integer x) -> new Tester() { public void test() { assertTrue(x + n1 + n2 + N1 + N2 + N3 == 66); } }.test(),30);
+ }
+ }
+ new B().test();
+ }
+ }
+ new A().test();
+ }
+
+ void test2() {
+ final Integer N1 = 1;
+ class A {
+ Integer n2 = 20;
+ void test() {
+ final Integer N2 = 2;
+ class B {
+ void test() {
+ final Integer N3 = 3;
+ exec((final Integer x) -> {
+ class LocTester implements Tester {
+ public void test() { assertTrue(x + n1 + n2 + N1 + N2 + N3 == 66); }
+ };
+ new LocTester().test();
+ },30);
+ }
+ }
+ new B().test();
+ }
+ }
+ new A().test();
+ }
+
+ void test3() {
+ final Integer N1 = 1;
+ new Tester() {
+ Integer n2 = 20;
+ public void test() {
+ final Integer N2 = 2;
+ new Tester() {
+ public void test() {
+ final Integer N3 = 3;
+ exec((final Integer x) -> new Tester() { public void test() { assertTrue(x + n1 + n2 + N1 + N2 + N3 == 66); } }.test(),30);
+ }
+ }.test();
+ }
+ }.test();
+ }
+
+ void test4() {
+ final Integer N1 = 1;
+ new Tester() {
+ Integer n2 = 20;
+ public void test() {
+ final Integer N2 = 2;
+ new Tester() {
+ public void test() {
+ final Integer N3 = 3;
+ exec((final Integer x) -> {
+ class LocTester implements Tester {
+ public void test() { assertTrue(x + n1 + n2 + N1 + N2 + N3 == 66); }
+ };
+ new LocTester().test();
+ },30);
+ }
+ }.test();
+ }
+ }.test();
+ }
+
+ public static void main(String[] args) {
+ LambdaCapture04 t = new LambdaCapture04();
+ t.test1();
+ t.test2();
+ t.test3();
+ t.test4();
+ assertTrue(assertionCount == 4);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaCapture05.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * test for capture in nested lambda expressions
+ * @author Maurizio Cimadamore
+ * @run main LambdaCapture05
+ */
+
+public class LambdaCapture05 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface TU<T, U> {
+ public T foo(U u);
+ }
+
+ public static <T, U> T exec(TU<T, U> lambda, U x) {
+ return lambda.foo(x);
+ }
+
+ int i = 40;
+
+ void test1(final int a0) {
+ exec((final Integer a1) -> {
+ final Integer x2 = 10; exec((final Integer a2) -> {
+ final Integer x3 = 20;
+ exec((final Integer a3) -> { assertTrue(106 == (a0 + a1 + a2 + a3 + x2 + x3 + i)); return null; }, 3);
+ return null;
+ },2);
+ return null;
+ },1);
+ }
+
+ static void test2(final int a0) {
+ exec((final Integer a1) -> {
+ final Integer x2 = 10; exec((final Integer a2) -> {
+ final Integer x3 = 20;
+ exec((final Integer a3) -> { assertTrue(66 == (a0 + a1 + a2 + a3 + x2 + x3)); return null; }, 3);
+ return null;
+ }, 2);
+ return null;
+ }, 1);
+ }
+
+ public static void main(String[] args) {
+ LambdaCapture05 t = new LambdaCapture05();
+ t.test1(30);
+ test2(30);
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaCapture06.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 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
+ * @ignore investigate as to whether code generation fails
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Compiler crash when local inner class nested inside lambda captures local variables from enclosing scope
+ */
+public class LambdaCapture06 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM {
+ void m(int n);
+ }
+
+ public static void main(String[] args) {
+ int n = 5;
+ SAM s = k -> {
+ new Object() {
+ void test() { int j = n; assertTrue(j == 5); }
+ }.test();
+ };
+ s.m(42);
+ assertTrue(assertionCount == 1);
+ }
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv01.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * basic test for lambda conversion
+ * @author Brian Goetz
+ * @author Maurizio Cimadamore
+ * @run main LambdaConv01
+ */
+
+public class LambdaConv01 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface IntToInt {
+ public int foo(int x);
+ }
+
+ interface IntToVoid {
+ public void foo(int x);
+ }
+
+ interface VoidToInt {
+ public int foo();
+ }
+
+ interface TU<T, U> {
+ public T foo(U u);
+ }
+
+ public static <T, U> T exec(TU<T, U> lambda, U x) {
+ return lambda.foo(x);
+ }
+
+ static {
+ //Assignment conversion:
+ VoidToInt f1 = ()-> 3;
+ assertTrue(3 == f1.foo());
+ //Covariant returns:
+ TU<Number, Integer> f2 = (Integer x) -> x;
+ assertTrue(3 == f2.foo(3));
+ //Method resolution with boxing:
+ int res = LambdaConv01.<Integer,Integer>exec((Integer x) -> x, 3);
+ assertTrue(3 == res);
+ //Runtime exception transparency:
+ try {
+ LambdaConv01.<Integer,Object>exec((Object x) -> x.hashCode(), null);
+ }
+ catch (RuntimeException e) {
+ assertTrue(true);
+ }
+ }
+
+ {
+ //Assignment conversion:
+ VoidToInt f1 = ()-> 3;
+ assertTrue(3 == f1.foo());
+ //Covariant returns:
+ TU<Number, Integer> f2 = (Integer x) -> x;
+ assertTrue(3 == f2.foo(3));
+ //Method resolution with boxing:
+ int res = LambdaConv01.<Integer,Integer>exec((Integer x) -> x, 3);
+ assertTrue(3 == res);
+ //Runtime exception transparency:
+ try {
+ LambdaConv01.<Integer,Object>exec((Object x) -> x.hashCode(), null);
+ }
+ catch (RuntimeException e) {
+ assertTrue(true);
+ }
+ }
+
+ public static void test1() {
+ //Assignment conversion:
+ VoidToInt f1 = ()-> 3;
+ assertTrue(3 == f1.foo());
+ //Covariant returns:
+ TU<Number, Integer> f2 = (Integer x) -> x;
+ assertTrue(3 == f2.foo(3));
+ //Method resolution with boxing:
+ int res = LambdaConv01.<Integer,Integer>exec((Integer x) -> x, 3);
+ assertTrue(3 == res);
+ //Runtime exception transparency:
+ try {
+ LambdaConv01.<Integer,Object>exec((Object x) -> x.hashCode(), null);
+ }
+ catch (RuntimeException e) {
+ assertTrue(true);
+ }
+ }
+
+ public void test2() {
+ //Assignment conversion:
+ VoidToInt f1 = ()-> 3;
+ assertTrue(3 == f1.foo());
+ //Covariant returns:
+ TU<Number, Integer> f2 = (Integer x) -> x;
+ assertTrue(3 == f2.foo(3));
+ //Method resolution with boxing:
+ int res = LambdaConv01.<Integer,Integer>exec((Integer x) -> x, 3);
+ assertTrue(3 == res);
+ //Runtime exception transparency:
+ try {
+ LambdaConv01.<Integer,Object>exec((Object x) -> x.hashCode(), null);
+ }
+ catch (RuntimeException e) {
+ assertTrue(true);
+ }
+ }
+
+ public static void main(String[] args) {
+ test1();
+ new LambdaConv01().test2();
+ assertTrue(assertionCount == 16);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv03.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * SAM types and method type inference
+ * @author Brian Goetz
+ * @author Maurizio Cimadamore
+ * @run main LambdaConv03
+ */
+
+public class LambdaConv03 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface TU<T, U> {
+ public T foo(U u);
+ }
+
+ public static <T, U> T exec(TU<T, U> lambda, U x) {
+ return lambda.foo(x);
+ }
+
+ static {
+ //Covariant returns:
+ int i1 = exec((Integer x) -> { return x; }, 3);
+ assertTrue(3 == i1);
+ //Method resolution with boxing:
+ int i2 = exec((Integer x) -> { return x; }, 3);
+ assertTrue(3 == i2);
+ //Runtime exception transparency:
+ try {
+ exec((Object x) -> { return x.hashCode(); }, null);
+ }
+ catch (RuntimeException e) {
+ assertTrue(true);
+ }
+ }
+
+ {
+ //Covariant returns:
+ int i1 = exec((Integer x) -> { return x; }, 3);
+ assertTrue(3 == i1);
+ //Method resolution with boxing:
+ int i2 = exec((Integer x) -> { return x; }, 3);
+ assertTrue(3 == i2);
+ //Runtime exception transparency:
+ try {
+ exec((Object x) -> { return x.hashCode(); }, null);
+ }
+ catch (RuntimeException e) {
+ assertTrue(true);
+ }
+ }
+
+ public static void test1() {
+ //Covariant returns:
+ int i1 = exec((Integer x) -> { return x; }, 3);
+ assertTrue(3 == i1);
+ //Method resolution with boxing:
+ int i2 = exec((Integer x) -> { return x; }, 3);
+ assertTrue(3 == i2);
+ //Runtime exception transparency:
+ try {
+ exec((Object x) -> { return x.hashCode(); }, null);
+ }
+ catch (RuntimeException e) {
+ assertTrue(true);
+ }
+ }
+
+ public void test2() {
+ //Covariant returns:
+ int i1 = exec((Integer x) -> { return x; }, 3);
+ assertTrue(3 == i1);
+ //Method resolution with boxing:
+ int i2 = exec((Integer x) -> { return x; }, 3);
+ assertTrue(3 == i2);
+ //Runtime exception transparency:
+ try {
+ exec((Object x) -> { return x.hashCode(); }, null);
+ }
+ catch (RuntimeException e) {
+ assertTrue(true);
+ }
+ }
+
+ public static void main(String[] args) {
+ test1();
+ new LambdaConv03().test2();
+ assertTrue(assertionCount == 12);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv05.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * function type and method type inference
+ * @author Alex Buckley
+ * @author Maurizio Cimadamore
+ * @run main LambdaConv05
+ */
+
+import java.util.*;
+
+public class LambdaConv05 {
+
+ static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ int count = 0;
+
+ void sort(List<String> data) {
+ Collections.sort(data,
+ (String a, String b) -> { LambdaConv05.this.count++; return a.length()-b.length(); });
+ }
+
+ public static void main(String[] args) {
+ ArrayList<String> arr = new ArrayList<>();
+ arr.add("Three");
+ arr.add("Four");
+ arr.add("One");
+ LambdaConv05 sorter = new LambdaConv05();
+ sorter.sort(arr);
+ assertTrue(arr.get(0).equals("One"));
+ assertTrue(arr.get(1).equals("Four"));
+ assertTrue(arr.get(2).equals("Three"));
+ assertTrue(sorter.count == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv06.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * ensure that definite assignment analysis doesn't mess up with lambda attribution
+ * @author Jan Lahoda
+ * @author Maurizio Cimadamore
+ * @compile LambdaConv06.java
+ */
+
+class LambdaConv06 {
+
+ private int t() {
+ return a((final Object indexed) -> {
+ return b(new R() {
+ public String build(final Object index) {
+ return "";
+ }
+ });
+ });
+ }
+
+ private int a(R r) {return 0;}
+ private String b(R r) {return null;}
+
+ public static interface R {
+ public String build(Object o);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv08.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that SAM conversion handles covarinat return types correctly
+ * @author Peter Levart
+ * @author Maurizio Cimadamore
+ * @run main LambdaConv08
+ */
+
+public class LambdaConv08 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ public interface ObjectF { Object invoke(); }
+ public interface StringF extends ObjectF { String invoke(); }
+
+ public static void call(StringF stringFunc) {
+ assertTrue(true);
+ }
+
+ public static void call(ObjectF objectFunc) { }
+
+ public static void main(String[] args) {
+ call(()-> "Hello");
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv09.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,50 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that SAM conversion handles Object members correctly
+ * @author Alex Buckley
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=LambdaConv09.out -XDrawDiagnostics LambdaConv09.java
+ */
+
+class LambdaConv09 {
+
+ // Not a SAM type; not enough abstract methods
+ interface Foo1 {}
+
+ // SAM type; Foo has no abstract methods
+ interface Foo2 { boolean equals(Object object); }
+
+
+ // Not a SAM type; Foo still has no abstract methods
+ interface Foo3 extends Foo2 { public abstract String toString(); }
+
+ // SAM type; Bar has one abstract non-Object method
+ interface Foo4<T> extends Foo2 { int compare(T o1, T o2); }
+
+ // Not a SAM type; still no valid abstract methods
+ interface Foo5 {
+ boolean equals(Object object);
+ String toString();
+ }
+
+ // SAM type; Foo6 has one abstract non-Object method
+ interface Foo6<T> {
+ boolean equals(Object obj);
+ int compare(T o1, T o2);
+ }
+
+ // SAM type; Foo6 has one abstract non-Object method
+ interface Foo7<T> extends Foo2, Foo6<T> { }
+
+ void test() {
+ Foo1 f1 = ()-> { };
+ Foo2 f2 = ()-> { };
+ Foo3 f3 = x -> true;
+ Foo4 f4 = (x, y) -> 1;
+ Foo5 f5 = x -> true;
+ Foo6 f6 = (x, y) -> 1;
+ Foo7 f7 = (x, y) -> 1;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv09.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,5 @@
+LambdaConv09.java:42:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo1))
+LambdaConv09.java:43:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo2))
+LambdaConv09.java:44:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo3))
+LambdaConv09.java:46:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, LambdaConv09.Foo5))
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv10.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that lambda conversion does not allow boxing of lambda parameters
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=LambdaConv10.out -XDrawDiagnostics LambdaConv10.java
+ */
+
+class LambdaConv10 {
+
+ interface Method1<R, A1> { public R call( A1 a1 ); }
+
+ public static void main( final String... notUsed ) {
+ Method1<Integer,Integer> m1 = (int i) -> 2 * i;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv10.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+LambdaConv10.java:15:39: compiler.err.prob.found.req: (compiler.misc.incompatible.arg.types.in.lambda)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv11.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * issues with lambda conversion involving generic class hierarchies
+ * @author Maurizio Cimadamore
+ * @compile LambdaConv11.java
+ */
+
+import java.util.Comparator;
+
+class LambdaConv11<T> {
+
+ interface SAM<X> extends Comparator<X> {
+ public int compare(X left, X right);
+ }
+
+ SAM<T> y = (l, r) -> 0;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv12.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * instance creation expression should allow lambda expressions as constrcutor arguments
+ * @author Maurizio Cimadamore
+ * @compile LambdaConv12.java
+ */
+
+class LambdaConv12 {
+
+ LambdaConv12(SAM s) {}
+
+ interface SAM {
+ public abstract void m();
+ }
+
+ void test() {
+ new LambdaConv12(()-> { });
+ new LambdaConv12(()-> { }) {};
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv13.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * interface methods in diamond shaped inheritance trees shouldn't be counted twice
+ * @author Maurizio Cimadamore
+ * @compile LambdaConv13.java
+ */
+
+class LambdaConv13 {
+
+ interface I {
+ void m();
+ }
+
+ interface A extends I {}
+ interface B extends I {}
+ interface C extends A, B {}
+ interface D extends A, I {}
+ interface E extends B, I {}
+
+ C c = ()-> { };
+ D d = ()-> { };
+ D e = ()-> { };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv16.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * SAM conversion and raw types in argument/return types
+ * @author Maurizio Cimadamore
+ * @run main LambdaConv16
+ */
+
+import java.util.*;
+
+public class LambdaConv16 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface A {
+ Iterable m(List<String> ls);
+ }
+
+ interface B {
+ Iterable<String> m(List l);
+ }
+
+ interface AB extends A, B {} //SAM type ([List], Iterable<String>, {})
+
+ static void test(AB ab, List l) { ab.m(l); }
+
+ public static void main(String[] args) {
+ AB ab = (List list) -> { assertTrue(true); return new ArrayList<String>(); };
+ ab.m(null);
+ test((List list) -> { assertTrue(true); return new ArrayList<String>(); }, null);
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv17.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * lambda compiler crashes if lambda has try-with-resources
+ * @compile LambdaConv17.java
+ */
+
+class LambdaConv17 {
+ interface SAM {
+ void m() throws Exception;
+ }
+
+ SAM s = ()-> { try (AutoCloseable ac = null){ } };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv18.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,24 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * simple test for lambda candidate check
+ * @compile/fail/ref=LambdaConv18.out -XDrawDiagnostics -XDidentifyLambdaCandidate=true LambdaConv18.java
+ */
+
+class LambdaConv18 {
+
+ interface SAM {
+ void m();
+ }
+
+ interface NonSAM {
+ void m1();
+ void m2();
+ }
+
+ SAM s1 = new SAM() { public void m() {} };
+ NonSAM s2 = new NonSAM() { public void m1() {}
+ public void m2() {} };
+ NonExistent s3 = new NonExistent() { public void m() {} };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv18.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,4 @@
+LambdaConv18.java:23:5: compiler.err.cant.resolve.location: kindname.class, NonExistent, , , (compiler.misc.location: kindname.class, LambdaConv18, null)
+LambdaConv18.java:20:24: compiler.note.potential.lambda.found
+LambdaConv18.java:23:26: compiler.err.cant.resolve.location: kindname.class, NonExistent, , , (compiler.misc.location: kindname.class, LambdaConv18, null)
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv19.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that redundant cast warnings are not generated for SAM conversions
+ * @compile -Xlint:cast -Werror LambdaConv19.java
+ */
+
+class LambdaConv19 {
+
+ interface SAM {
+ void m();
+ }
+
+ SAM s = (SAM)()-> { };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv20.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that synthetic casts are added when erased type of lambda body
+ * ends up being too general
+ * @run main LambdaConv20
+ */
+
+import java.util.*;
+
+public class LambdaConv20 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM<X> {
+ X m(List<X> l);
+ }
+
+ public static void main(String[] args) {
+ SAM<Integer> si1 = l -> l.get(0);
+ assertTrue(si1.m(Arrays.asList(1)) == 1);
+ SAM<Integer> si2 = l -> { return l.get(0); };
+ assertTrue(si2.m(Arrays.asList(1)) == 1);
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv21.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,38 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that code generation handles void-compatibility correctly
+ * @compile/fail/ref=LambdaConv21.out -XDrawDiagnostics LambdaConv21.java
+ */
+
+class LambdaConv21 {
+
+ interface SAM_void<X> {
+ void m();
+ }
+
+ interface SAM_java_lang_Void {
+ Void m();
+ }
+
+ static void m_void() { }
+
+ static Void m_java_lang_Void() { return null; }
+
+ static void testExpressionLambda() {
+ SAM_void s1 = ()->m_void(); //ok
+ SAM_java_lang_Void s2 = ()->m_void(); //no - incompatible target
+ SAM_void s3 = ()->m_java_lang_Void(); //no - incompatible target
+ SAM_java_lang_Void s4 = ()->m_java_lang_Void(); //ok
+ }
+
+ static void testStatementLambda() {
+ SAM_void s1 = ()-> { m_void(); }; //ok
+ SAM_java_lang_Void s2 = ()-> { m_void(); }; //no - missing return value
+ SAM_void s3 = ()-> { return m_java_lang_Void(); }; //no - unexpected return value
+ SAM_java_lang_Void s4 = ()-> { return m_java_lang_Void(); }; //ok
+ SAM_void s5 = ()-> { m_java_lang_Void(); }; //ok
+ SAM_java_lang_Void s6 = ()-> { m_java_lang_Void(); }; //no - missing return value
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv21.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,6 @@
+LambdaConv21.java:25:43: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: void, java.lang.Void))
+LambdaConv21.java:26:43: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Void, void))
+LambdaConv21.java:32:33: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.Void))
+LambdaConv21.java:33:53: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val))
+LambdaConv21.java:36:33: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.Void))
+5 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv22.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * inner class translator fails with spurious method clash errors
+ * @compile LambdaConv22.java
+ */
+
+class LambdaConv22<U> {
+
+ interface Factory<T> { T make(); }
+
+ U make() { return null; }
+
+ void test(U u) {
+ Factory<U> fu1 = () -> u;
+ Factory<U> fu2 = this::make;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv23.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check super varargs reference is handled correctly
+ * @run main LambdaConv23
+ */
+public class LambdaConv23 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM { void m(Integer a, Integer b); }
+
+ static class Super {
+ void m(Object... vi) { assertTrue(true); }
+ }
+
+
+ static class Sub extends Super {
+
+ void m(Object... vi) { assertTrue(false); }
+
+ public void test() {
+ SAM q = super::m;
+ q.m(1, 2);
+ }
+ }
+
+ public static void main(String[] args) {
+ new Sub().test();
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConv24.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that lambda inside 'this' call is handled properly
+ * @run main LambdaConv24
+ */
+public class LambdaConv24 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM<X> {
+ boolean m(X x);
+ }
+
+ LambdaConv24(SAM<String> p) {
+ assertTrue(p.m("42"));
+ }
+
+ LambdaConv24(int i) {
+ this(s->true);
+ }
+
+ LambdaConv24(int i1, int i2) {
+ this(LambdaConv24::m);
+ }
+
+ static boolean m(String s) { return true; }
+
+ public static void main(String[] args) {
+ new LambdaConv24(1);
+ new LambdaConv24(1,2);
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaConversionTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * perform several automated checks in lambda conversion, esp. around accessibility
+ * @author Maurizio Cimadamore
+ * @run main LambdaConversionTest
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+public class LambdaConversionTest {
+
+ enum PackageKind {
+ NO_PKG(""),
+ PKG_A("a");
+
+ String pkg;
+
+ PackageKind(String pkg) {
+ this.pkg = pkg;
+ }
+
+ String getPkgDecl() {
+ return this == NO_PKG ?
+ "" :
+ "package " + pkg + ";";
+ }
+
+ String getImportStat() {
+ return this == NO_PKG ?
+ "" :
+ "import " + pkg + ".*;";
+ }
+ }
+
+ enum SamKind {
+ CLASS("public class Sam { }"),
+ ABSTACT_CLASS("public abstract class Sam { }"),
+ ANNOTATION("public @interface Sam { }"),
+ ENUM("public enum Sam { }"),
+ INTERFACE("public interface Sam { \n #METH; \n }");
+
+ String sam_str;
+
+ SamKind(String sam_str) {
+ this.sam_str = sam_str;
+ }
+
+ String getSam(String methStr) {
+ return sam_str.replaceAll("#METH", methStr);
+ }
+ }
+
+ enum ModifierKind {
+ PUBLIC("public"),
+ PACKAGE("");
+
+ String modifier_str;
+
+ ModifierKind(String modifier_str) {
+ this.modifier_str = modifier_str;
+ }
+
+ boolean stricterThan(ModifierKind that) {
+ return this.ordinal() > that.ordinal();
+ }
+ }
+
+ enum TypeKind {
+ EXCEPTION("Exception"),
+ PKG_CLASS("PackageClass");
+
+ String typeStr;
+
+ private TypeKind(String typeStr) {
+ this.typeStr = typeStr;
+ }
+ }
+
+ enum MethodKind {
+ NONE(""),
+ NON_GENERIC("public #R m(#ARG s) throws #T;"),
+ GENERIC("public <X> #R m(#ARG s) throws #T;");
+
+ String methodTemplate;
+
+ private MethodKind(String methodTemplate) {
+ this.methodTemplate = methodTemplate;
+ }
+
+ String getMethod(TypeKind retType, TypeKind argType, TypeKind thrownType) {
+ return methodTemplate.replaceAll("#R", retType.typeStr).
+ replaceAll("#ARG", argType.typeStr).
+ replaceAll("#T", thrownType.typeStr);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ for (PackageKind samPkg : PackageKind.values()) {
+ for (ModifierKind modKind : ModifierKind.values()) {
+ for (SamKind samKind : SamKind.values()) {
+ for (MethodKind meth : MethodKind.values()) {
+ for (TypeKind retType : TypeKind.values()) {
+ for (TypeKind argType : TypeKind.values()) {
+ for (TypeKind thrownType : TypeKind.values()) {
+ new LambdaConversionTest(samPkg, modKind, samKind,
+ meth, retType, argType, thrownType).test();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ PackageKind samPkg;
+ ModifierKind modKind;
+ SamKind samKind;
+ MethodKind meth;
+ TypeKind retType;
+ TypeKind argType;
+ TypeKind thrownType;
+
+ SourceFile samSourceFile = new SourceFile("Sam.java", "#P \n #C") {
+ public String toString() {
+ return template.replaceAll("#P", samPkg.getPkgDecl()).
+ replaceAll("#C", samKind.getSam(meth.getMethod(retType, argType, thrownType)));
+ }
+ };
+
+ SourceFile pkgClassSourceFile = new SourceFile("PackageClass.java",
+ "#P\n #M class PackageClass extends Exception { }") {
+ public String toString() {
+ return template.replaceAll("#P", samPkg.getPkgDecl()).
+ replaceAll("#M", modKind.modifier_str);
+ }
+ };
+
+ SourceFile clientSourceFile = new SourceFile("Client.java",
+ "#I\n class Client { Sam s = x -> null; }") {
+ public String toString() {
+ return template.replaceAll("#I", samPkg.getImportStat());
+ }
+ };
+
+ LambdaConversionTest(PackageKind samPkg, ModifierKind modKind, SamKind samKind,
+ MethodKind meth, TypeKind retType, TypeKind argType, TypeKind thrownType) {
+ this.samPkg = samPkg;
+ this.modKind = modKind;
+ this.samKind = samKind;
+ this.meth = meth;
+ this.retType = retType;
+ this.argType = argType;
+ this.thrownType = thrownType;
+ }
+
+ void test() throws Exception {
+ final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+ DiagnosticChecker dc = new DiagnosticChecker();
+ JavacTask ct = (JavacTask)tool.getTask(null, null, dc,
+ null, null, Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
+ ct.analyze();
+ if (dc.errorFound == checkSamConversion()) {
+ throw new AssertionError(samSourceFile + "\n\n" + pkgClassSourceFile + "\n\n" + clientSourceFile);
+ }
+ }
+
+ boolean checkSamConversion() {
+ if (samKind != SamKind.INTERFACE) {
+ //sam type must be an interface
+ return false;
+ } else if (meth != MethodKind.NON_GENERIC) {
+ //target method must be non-generic
+ return false;
+ } else if (samPkg != PackageKind.NO_PKG &&
+ modKind != ModifierKind.PUBLIC &&
+ (retType == TypeKind.PKG_CLASS ||
+ argType == TypeKind.PKG_CLASS ||
+ thrownType == TypeKind.PKG_CLASS)) {
+ //target must not contain inaccessible types
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ abstract class SourceFile extends SimpleJavaFileObject {
+
+ protected String template;
+
+ public SourceFile(String filename, String template) {
+ super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
+ this.template = template;
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return toString();
+ }
+
+ public abstract String toString();
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound = false;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ errorFound = true;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaEffectivelyFinalTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,60 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Integrate efectively final check with DA/DU analysis
+ * @compile/fail/ref=LambdaEffectivelyFinalTest.out -XDrawDiagnostics LambdaEffectivelyFinalTest.java
+ */
+class LambdaEffectivelyFinalTest {
+
+ interface SAM {
+ int m();
+ }
+
+ void foo(LambdaEffectivelyFinalTest.SAM s) { }
+
+ void m1(int x) {
+ int y = 1;
+ foo(() -> x+y); // Legal: x and y are both effectively final.
+ }
+
+ void m2(int x) {
+ int y;
+ y = 1;
+ foo(() -> x+y); // Legal: x and y are both effectively final.
+ }
+
+ void m3(int x, boolean cond) {
+ int y;
+ if (cond) y = 1;
+ foo(() -> x+y); // Illegal: y is effectively final, but not definitely assigned.
+ }
+
+ void m4(int x, boolean cond) {
+ int y;
+ if (cond) y = 1;
+ else y = 2;
+ foo(() -> x+y); // Legal: x and y are both effectively final.
+ }
+
+ void m5(int x, boolean cond) {
+ int y;
+ if (cond) y = 1;
+ y = 2;
+ foo(() -> x+y); // Illegal: y is not effectively final.t EF
+ }
+
+ void m6(int x) {
+ foo(() -> x+1);
+ x++; // Illegal: x is not effectively final.
+ }
+
+ void m7(int x) {
+ foo(() -> x=1); // Illegal: x in the assignment does not denote a variable (see 6.5.6.1)
+ }
+
+ void m8() {
+ int y;
+ foo(() -> y=1); // Illegal: y in the assignment does not denote a variable (see 6.5.6.1)
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaEffectivelyFinalTest.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,6 @@
+LambdaEffectivelyFinalTest.java:30:21: compiler.err.var.might.not.have.been.initialized: y
+LambdaEffectivelyFinalTest.java:44:21: compiler.err.cant.ref.non.effectively.final.var: y, (compiler.misc.lambda)
+LambdaEffectivelyFinalTest.java:48:19: compiler.err.cant.ref.non.effectively.final.var: x, (compiler.misc.lambda)
+LambdaEffectivelyFinalTest.java:53:19: compiler.err.cant.ref.non.effectively.final.var: x, (compiler.misc.lambda)
+LambdaEffectivelyFinalTest.java:58:19: compiler.err.cant.ref.non.effectively.final.var: y, (compiler.misc.lambda)
+5 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr01.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * basic test for simple lambda expressions in multiple scopes
+ * @author Brian Goetz
+ * @author Maurizio Cimadamore
+ * @run main LambdaExpr01
+ */
+
+public class LambdaExpr01 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface S_int {
+ int m();
+ }
+
+ interface S_Integer {
+ Integer m();
+ }
+
+ interface S_int_int {
+ int m(int i);
+ }
+
+ interface S_Integer_int {
+ int m(Integer i);
+ }
+
+ interface S_int_Integer {
+ Integer m(int i);
+ }
+
+ interface S_Integer_Integer {
+ Integer m(Integer i);
+ }
+
+ static {
+ S_int s_i = ()-> 3;
+ assertTrue(3 == s_i.m());
+ S_Integer s_I = ()-> 3;
+ assertTrue(3 == s_I.m());
+ S_int_int s_i_i = (int x)-> x+1;
+ assertTrue(4 == s_i_i.m(3));
+ S_int_Integer s_i_I = (int x)-> x+1;
+ assertTrue(4 == s_i_I.m(3));
+ S_Integer_int s_I_i = (Integer x) -> x.intValue() + 1;
+ assertTrue(4 == s_I_i.m(3));
+ S_Integer_Integer s_I_I = (Integer x) -> x.intValue() + 1;
+ assertTrue(4 == s_I_I.m(3));
+ }
+
+ {
+ S_int s_i = ()-> 3;
+ assertTrue(3 == s_i.m());
+ S_Integer s_I = ()-> 3;
+ assertTrue(3 == s_I.m());
+ S_int_int s_i_i = (int x)-> x+1;
+ assertTrue(4 == s_i_i.m(3));
+ S_int_Integer s_i_I = (int x)-> x+1;
+ assertTrue(4 == s_i_I.m(3));
+ S_Integer_int s_I_i = (Integer x) -> x.intValue() + 1;
+ assertTrue(4 == s_I_i.m(3));
+ S_Integer_Integer s_I_I = (Integer x) -> x.intValue() + 1;
+ assertTrue(4 == s_I_I.m(3));
+ }
+
+ static void test1() {
+ S_int s_i = ()-> 3;
+ assertTrue(3 == s_i.m());
+ S_Integer s_I = ()-> 3;
+ assertTrue(3 == s_I.m());
+ S_int_int s_i_i = (int x)-> x+1;
+ assertTrue(4 == s_i_i.m(3));
+ S_int_Integer s_i_I = (int x)-> x+1;
+ assertTrue(4 == s_i_I.m(3));
+ S_Integer_int s_I_i = (Integer x) -> x.intValue() + 1;
+ assertTrue(4 == s_I_i.m(3));
+ S_Integer_Integer s_I_I = (Integer x) -> x.intValue() + 1;
+ assertTrue(4 == s_I_I.m(3));
+ }
+
+ void test2() {
+ S_int s_i = ()-> 3;
+ assertTrue(3 == s_i.m());
+ S_Integer s_I = ()-> 3;
+ assertTrue(3 == s_I.m());
+ S_int_int s_i_i = (int x)-> x+1;
+ assertTrue(4 == s_i_i.m(3));
+ S_int_Integer s_i_I = (int x)-> x+1;
+ assertTrue(4 == s_i_I.m(3));
+ S_Integer_int s_I_i = (Integer x) -> x.intValue() + 1;
+ assertTrue(4 == s_I_i.m(3));
+ S_Integer_Integer s_I_I = (Integer x) -> x.intValue() + 1;
+ assertTrue(4 == s_I_I.m(3));
+ }
+
+ public static void main(String[] args) {
+ test1();
+ new LambdaExpr01().test2();
+ assertTrue(assertionCount == 24);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr02.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * basic test for simple lambda expressions in multiple scopes
+ * @author Brian Goetz
+ * @author Maurizio Cimadamore
+ * @run main LambdaExpr01
+ */
+
+public class LambdaExpr02 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface S_int {
+ int m();
+ }
+
+ interface S_Integer {
+ Integer m();
+ }
+
+ interface S_int_int {
+ int m(int i);
+ }
+
+ interface S_Integer_int {
+ int m(Integer i);
+ }
+
+ interface S_int_Integer {
+ Integer m(int i);
+ }
+
+ interface S_Integer_Integer {
+ Integer m(Integer i);
+ }
+
+ static {
+ S_int s_i = ()-> { return 3; };
+ assertTrue(3 == s_i.m());
+ S_Integer s_I = ()-> { return 3; };
+ assertTrue(3 == s_I.m());
+ S_int_int s_i_i = (int x) -> { return x + 1; };
+ assertTrue(4 == s_i_i.m(3));
+ S_int_Integer s_i_I = (int x) -> { return x + 1; };
+ assertTrue(4 == s_i_I.m(3));
+ S_Integer_int s_I_i = (Integer x) -> { return x.intValue() + 1; };
+ assertTrue(4 == s_I_i.m(3));
+ S_Integer_Integer s_I_I = (Integer x) -> { return x.intValue() + 1; };
+ assertTrue(4 == s_I_I.m(3));
+ }
+
+ {
+ S_int s_i = ()-> { return 3; };
+ assertTrue(3 == s_i.m());
+ S_Integer s_I = ()-> { return 3; };
+ assertTrue(3 == s_I.m());
+ S_int_int s_i_i = (int x) -> { return x + 1; };
+ assertTrue(4 == s_i_i.m(3));
+ S_int_Integer s_i_I = (int x) -> { return x + 1; };
+ assertTrue(4 == s_i_I.m(3));
+ S_Integer_int s_I_i = (Integer x) -> { return x.intValue() + 1; };
+ assertTrue(4 == s_I_i.m(3));
+ S_Integer_Integer s_I_I = (Integer x) -> { return x.intValue() + 1; };
+ assertTrue(4 == s_I_I.m(3));
+ }
+
+ static void test1() {
+ S_int s_i = ()-> { return 3; };
+ assertTrue(3 == s_i.m());
+ S_Integer s_I = ()-> { return 3; };
+ assertTrue(3 == s_I.m());
+ S_int_int s_i_i = (int x) -> { return x + 1; };
+ assertTrue(4 == s_i_i.m(3));
+ S_int_Integer s_i_I = (int x) -> { return x + 1; };
+ assertTrue(4 == s_i_I.m(3));
+ S_Integer_int s_I_i = (Integer x) -> { return x.intValue() + 1; };
+ assertTrue(4 == s_I_i.m(3));
+ S_Integer_Integer s_I_I = (Integer x) -> { return x.intValue() + 1; };
+ assertTrue(4 == s_I_I.m(3));
+ }
+
+ void test2() {
+ S_int s_i = ()-> { return 3; };
+ assertTrue(3 == s_i.m());
+ S_Integer s_I = ()-> { return 3; };
+ assertTrue(3 == s_I.m());
+ S_int_int s_i_i = (int x) -> { return x + 1; };
+ assertTrue(4 == s_i_i.m(3));
+ S_int_Integer s_i_I = (int x) -> { return x + 1; };
+ assertTrue(4 == s_i_I.m(3));
+ S_Integer_int s_I_i = (Integer x) -> { return x.intValue() + 1; };
+ assertTrue(4 == s_I_i.m(3));
+ S_Integer_Integer s_I_I = (Integer x) -> { return x.intValue() + 1; };
+ assertTrue(4 == s_I_I.m(3));
+ }
+
+ public static void main(String[] args) {
+ test1();
+ new LambdaExpr02().test2();
+ assertTrue(assertionCount == 24);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr04.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that lambda initializers compile w/o problems
+ * @author Jan Lahoda
+ * @author Maurizio Cimadamore
+ * @compile LambdaExpr04.java
+ */
+
+class LambdaExpr04 {
+
+ interface SAM {
+ void m(int i);
+ }
+ static SAM lambda_01 = (int pos) -> { };
+
+ static final SAM lambda_02 = (int pos) -> { };
+
+ SAM lambda_03 = (int pos) -> { };
+
+ final SAM lambda_04 = (int pos) -> { };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr05.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that binary expression in lambda expression is parsed correctly
+ * @author Maurizio Cimadamore
+ * @compile LambdaExpr05.java
+ */
+
+class LambdaExpr05 {
+
+ interface SAM { int foo(int i); }
+
+ SAM s1 = i -> i * 2;
+ SAM s2 = i -> 2 * i;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr06.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * parser test for nested parenthesized lambda expression
+ * @run main LambdaExpr06
+ */
+
+public class LambdaExpr06 {
+
+ static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface A {
+ int m();
+ }
+
+ interface B {
+ int dup(int i);
+ }
+
+ public static void main(String[] args) {
+ A a = ()-> ((B)i -> i * 2).dup(3);
+ assertTrue(a.m() == 6);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr07.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check access to effectively final local variable from doubly nested lambda
+ * @run main LambdaExpr07
+ */
+
+public class LambdaExpr07 {
+
+ interface Block<A, R> {
+ R apply(A x);
+ }
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ String S = "A";
+
+ void test() {
+ Block<String, Block<String, String>> o = s1 -> s2 -> S + s1 + s2;
+ assertTrue(o.apply("B").apply("C").equals("ABC"));
+ }
+
+ public static void main(String[] args) {
+ new LambdaExpr07().test();
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr08.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that reference to local final variable w/o initializer is accepted
+ * @compile LambdaExpr08.java
+ */
+
+class LambdaExpr08 {
+
+ interface SAM {
+ String m();
+ }
+
+ void test() {
+ final String s;
+ s = "";
+ SAM sam = () -> s;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr09.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that lambda in array initializers is correctly accepted
+ * @compile LambdaExpr09.java
+ */
+
+class LambdaExpr09 {
+
+ interface Block<T> {
+ void m(T t);
+ }
+
+ void apply(Object[] obj_arr) { }
+
+ void test1() {
+ Block<?>[] arr1 = { t -> { }, t -> { } };
+ Block<?>[][] arr2 = { { t -> { }, t -> { } }, { t -> { }, t -> { } } };
+ }
+
+ void test2() {
+ Block<?>[] arr1 = new Block<?>[]{ t -> { }, t -> { } };
+ Block<?>[][] arr2 = new Block<?>[][]{ { t -> { }, t -> { } }, { t -> { }, t -> { } } };
+ }
+
+ void test3() {
+ apply(new Block<?>[]{ t -> { }, t -> { } });
+ apply(new Block<?>[][]{ { t -> { }, t -> { } }, { t -> { }, t -> { } } });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr10.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,37 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that lambda in array initializers (with wrong type) are correctly rejected
+ * @compile/fail/ref=LambdaExpr10.out -XDrawDiagnostics LambdaExpr10.java
+ */
+
+class LambdaExpr10 {
+
+ interface Block<T> {
+ void m(T t);
+ }
+
+ void apply(Object[] obj_arr) { }
+
+ void test1() {
+ Object[] arr1 = { t -> { } };
+ Object[][] arr2 = { { t -> { } } };
+ }
+
+ void test2() {
+ Object[] arr1 = new Object[]{ t -> { } };
+ Object[][] arr2 = new Object[][]{ { t -> { } } };
+ }
+
+ void test3() {
+ apply(new Object[]{ t -> { } });
+ apply(new Object[][]{ { t -> { } } });
+ }
+
+ void test4() {
+ Block<?>[] arr1 = { t -> t };
+ Block<?>[] arr2 = new Block<?>[]{ t -> t };
+ apply(new Block<?>[]{ t -> { }, t -> { } });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr10.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,9 @@
+LambdaExpr10.java:18:28: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+LambdaExpr10.java:19:32: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+LambdaExpr10.java:23:40: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+LambdaExpr10.java:24:46: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+LambdaExpr10.java:28:29: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+LambdaExpr10.java:29:33: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+LambdaExpr10.java:33:35: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, void))
+LambdaExpr10.java:34:49: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, void))
+8 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr11.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that creating an inner class from a lambda does add a captured this
+ * @run main LambdaExpr11
+ */
+public class LambdaExpr11 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ class Inner {
+ Inner() { assertTrue(true); }
+ }
+
+ void test() {
+ Runnable r1 = ()-> { new Inner(); };
+ r1.run();
+ Runnable r2 = ()-> { new Inner() {}; };
+ r2.run();
+ Runnable r3 = ()-> { class SubInner extends Inner {}; new SubInner(); };
+ r3.run();
+ Runnable r4 = ()-> { class SubInner extends Inner {}; new SubInner() {}; };
+ r4.run();
+ new Inner2().test();
+ }
+
+ class Inner2 {
+ void test() {
+ Runnable r1 = ()-> { new Inner(); };
+ r1.run();
+ Runnable r2 = ()-> { new Inner() {}; };
+ r2.run();
+ Runnable r3 = ()-> { class SubInner extends Inner {}; new SubInner(); };
+ r3.run();
+ Runnable r4 = ()-> { class SubInner extends Inner {}; new SubInner() {}; };
+ r4.run();
+ new Inner3().test();
+ }
+
+ class Inner3 {
+ void test() {
+ Runnable r1 = ()-> { new Inner(); };
+ r1.run();
+ Runnable r2 = ()-> { new Inner() {}; };
+ r2.run();
+ Runnable r3 = ()-> { class SubInner extends Inner {}; new SubInner(); };
+ r3.run();
+ Runnable r4 = ()-> { class SubInner extends Inner {}; new SubInner() {}; };
+ r4.run();
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ new LambdaExpr11().test();
+ assertTrue(assertionCount == 12);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr12.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that creating an inner class from a lambda does add a captured this
+ * @run main LambdaExpr12
+ */
+
+public class LambdaExpr12 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface Getter<X> {
+ X get();
+ }
+
+
+ interface Mapper<X,Y> {
+ Y map(X x);
+ }
+
+ void test() {
+ Mapper<String, Getter<Character>> mapper =
+ (final String s) -> new Getter<Character>() {
+ @Override
+ public Character get() {
+ return s.charAt(0);
+ }
+ };
+ assertTrue(mapper.map("First").get() == 'F');
+ }
+
+ public static void main(String[] args) {
+ new LambdaExpr12().test();
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr13.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that recursive lambda (through field ref) is accepted in all contexts
+ * @compile LambdaExpr13.java
+ */
+
+class LambdaExpr13 {
+
+ Runnable ir = () -> { ir.run(); };;
+ static Runnable sr = () -> { sr.run(); };
+
+ { ir = () -> { ir.run(); }; }
+ static { sr = () -> { sr.run(); }; }
+
+ static void m1() {
+ sr = () -> { sr.run(); };
+ }
+
+ void m2() {
+ ir = () -> { ir.run(); };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr14.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that recursion from doubly nested lambda is handled correctly
+ */
+
+public class LambdaExpr14 {
+
+ interface SAM {
+ SAM invoke();
+ }
+
+ static SAM local;
+
+ public static void main(String[] args) {
+ local = () -> () -> local.invoke();
+ local.invoke().invoke(); // Not a recursive lambda - exec should terminate
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr15.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, 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
+ * @ignore investigate as to whether code generation fails
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that nested inner class in statement lambdas don't get corrupted return statements
+ * @run main LambdaExpr15
+ */
+public class LambdaExpr15 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface Block<T> {
+ void apply(T t);
+ }
+
+ public static void main(String[] args) {
+ //anon class
+ Block<Object> ba1 = t -> {
+ new Object() {
+ String get() { return ""; }
+ };
+ assertTrue(t == 1);
+ };
+ ba1.apply(1);
+
+ //local class
+ Block<Object> ba2 = t -> {
+ class A {
+ String get() { return ""; }
+ };
+ new A();
+ assertTrue(t == 2);
+ };
+ ba2.apply(2);
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr16.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that super inside lambda is handled correctly
+ * @run main LambdaExpr16
+ */
+public class LambdaExpr16 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface A { void m(); }
+
+ static class Sup {
+ void m() {
+ assertTrue(true);
+ }
+ }
+
+ static class Sub extends Sup {
+ void testLambda1() {
+ A a = ()->{ super.m(); };
+ a.m();
+ }
+ void testLambda2() {
+ A a = () -> { A a1 = () -> { super.m(); }; a1.m(); };
+ a.m();
+ }
+ void testRef1() {
+ A a = () -> { A a1 = super::m; a1.m(); };
+ a.m();
+ }
+ void testRef2() {
+ A a = () -> { A a1 = () -> { A a2 = super::m; a2.m(); }; a1.m(); };
+ a.m();
+ }
+ }
+
+ public static void main(String[] args) {
+ Sub s = new Sub();
+ s.testLambda1();
+ s.testLambda2();
+ s.testRef1();
+ s.testRef2();
+ assertTrue(assertionCount == 4);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr17.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that super in argument position inside lambda is handled correctly
+ * @run main LambdaExpr17
+ */
+public class LambdaExpr17 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM {
+ void m();
+ }
+
+ static class Sup {
+ protected String m() {
+ assertTrue(true);
+ return "Hello!";
+ }
+ }
+
+ static class Sub extends Sup {
+ void test() {
+ SAM s = () -> { System.out.println(super.m()); };
+ s.m();
+ }
+ }
+
+ public static void main(String[] args) {
+ new Sub().test();
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr18.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that synthetic casts from outer environment are not inserted twice
+ * @run main LambdaExpr18
+ */
+public class LambdaExpr18 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM<R> {
+ R eval();
+ }
+
+ static void test(){
+ SAM<Integer> sam1 = () -> {
+ assertTrue(true);
+ SAM<String> sam2 = () -> {
+ assertTrue(true);
+ return "";
+ };
+ sam2.eval();
+ return 1;
+ };
+ sam1.eval();
+ }
+
+ public static void main(String[] args) {
+ test();
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr19.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,53 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that inner scopes are left after a lambda check exception has been thrown
+ * @compile/fail/ref=LambdaExpr19.out -XDrawDiagnostics LambdaExpr19.java
+ */
+class LambdaExpr19 {
+
+ interface SAM {
+ String m();
+ }
+
+ void m(SAM s) { }
+
+ void testTry() {
+ m(() -> {
+ try { return 1; }
+ catch (Exception e) { }
+ });
+ }
+
+ void testTryWithResources() {
+ m(() -> {
+ try (AutoCloseable c = null) { return 1; }
+ catch (Exception e) { }
+ });
+ }
+
+ void testSwitch() {
+ m(() -> {
+ switch (1) {
+ default: return 1;
+ }
+ });
+ }
+
+ void testFor() {
+ m(() -> {
+ for (;;) {
+ return 1;
+ }
+ });
+ }
+
+ void testForeach() {
+ m(() -> {
+ for (Object o : new Object[] { null , null }) {
+ return 1;
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr19.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,6 @@
+LambdaExpr19.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, LambdaExpr19.SAM, @363, kindname.class, LambdaExpr19, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, java.lang.String)))
+LambdaExpr19.java:24:9: compiler.err.cant.apply.symbol: kindname.method, m, LambdaExpr19.SAM, @512, kindname.class, LambdaExpr19, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, java.lang.String)))
+LambdaExpr19.java:31:9: compiler.err.cant.apply.symbol: kindname.method, m, LambdaExpr19.SAM, @676, kindname.class, LambdaExpr19, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, java.lang.String)))
+LambdaExpr19.java:39:9: compiler.err.cant.apply.symbol: kindname.method, m, LambdaExpr19.SAM, @824, kindname.class, LambdaExpr19, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, java.lang.String)))
+LambdaExpr19.java:47:9: compiler.err.cant.apply.symbol: kindname.method, m, LambdaExpr19.SAM, @965, kindname.class, LambdaExpr19, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, java.lang.String)))
+5 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExpr20.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that default super call from lambda expression is compiled successfully
+ * @compile LambdaExpr20.java
+ */
+
+class LambdaExpr20 {
+
+ interface K {
+ default void m() { }
+ }
+
+ static class Test implements K {
+ @Override
+ public void m() {
+ Runnable r = () -> { K.super.m(); };
+ r.run();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExprNotVoid.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that lambda expression body (when not a block) cannot be void
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=LambdaExprNotVoid.out -XDlambdaInferenceDiags=false -XDrawDiagnostics LambdaExprNotVoid.java
+ */
+
+class LambdaExpr05 {
+
+ interface SAM { void foo(int i); }
+
+ SAM s1 = i -> i * 2;
+ SAM s2 = i -> 2 * i;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaExprNotVoid.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+LambdaExprNotVoid.java:14:21: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, void))
+LambdaExprNotVoid.java:15:21: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, void))
+2 errors
--- a/langtools/test/tools/javac/lambda/LambdaParserTest.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaParserTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,9 @@
/*
* @test
* @bug 7115050
- * @summary Add parser support for lambda expressions
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Add parser support for lambda expressions
*/
import com.sun.source.util.JavacTask;
@@ -234,7 +236,7 @@
void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
- Arrays.asList("-XDallowLambda"), null, Arrays.asList(source));
+ null, null, Arrays.asList(source));
try {
ct.parse();
} catch (Throwable ex) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaScope01.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * basic test for capture of non-mutable locals
+ * @author Brian Goetz
+ * @author Maurizio Cimadamore
+ * @run main LambdaScope01
+ */
+
+public class LambdaScope01 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface TU<T, U> {
+ public T foo(U u);
+ }
+
+ public static <T, U> T exec(TU<T, U> lambda, U x) {
+ return lambda.foo(x);
+ }
+
+ public int n = 5;
+
+ public int hashCode() {
+ throw new RuntimeException();
+ }
+
+ public void test1() {
+ try {
+ int res = LambdaScope01.<Integer,Integer>exec((Integer x) -> x * hashCode(), 3);
+ }
+ catch (RuntimeException e) {
+ assertTrue(true); //should throw
+ }
+ }
+
+ public void test2() {
+ final int n = 10;
+ int res = LambdaScope01.<Integer,Integer>exec((Integer x) -> x + n, 3);
+ assertTrue(13 == res);
+ }
+
+ public static void main(String[] args) {
+ LambdaScope01 t = new LambdaScope01();
+ t.test1();
+ t.test2();
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaScope02.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that Object members are accessible as expected
+ * @author Maurizio Cimadamore
+ * @run main LambdaScope02
+ */
+
+public class LambdaScope02 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ @Override
+ public String toString() {
+ return "Callable1";
+ }
+
+ interface Callable {
+ void call();
+ }
+
+ static void call(Callable c) { c.call(); }
+
+ void test() {
+ call(()-> { assertTrue(LambdaScope02.this.toString().equals("Callable1")); });
+ call(()-> { assertTrue(toString().equals("Callable1")); });
+ }
+
+ public static void main(String[] args) {
+ new LambdaScope02().test();
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaScope03.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that unqualified Object members are accessed as expected
+ * @author Maurizio Cimadamore
+ * @run main LambdaScope03
+ */
+
+public class LambdaScope03 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM {
+ void m();
+ }
+
+ static void call(SAM s) { s.m(); }
+
+ void test() {
+ call(()-> { assertTrue(LambdaScope03.this.getClass().equals(getClass())); });
+ call(()-> { assertTrue(LambdaScope03.this.getClass().equals(this.getClass())); });
+ call(()-> { assertTrue(LambdaScope03.this.hashCode() == hashCode()); });
+ call(()-> { assertTrue(LambdaScope03.this.hashCode() == this.hashCode()); });
+ call(()-> { assertTrue(LambdaScope03.this.toString().equals(toString())); });
+ call(()-> { assertTrue(LambdaScope03.this.toString().equals(this.toString())); });
+ call(()-> { assertTrue(LambdaScope03.this.equals(this)); });
+ call(()-> { assertTrue(equals(LambdaScope03.this)); });
+ }
+
+ public static void main(String[] args) {
+ new LambdaScope03().test();
+ assertTrue(assertionCount == 8);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaScope04.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,163 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that lambda cannot shadow variables from enclosing scope
+ * @compile/fail/ref=LambdaScope04.out -XDrawDiagnostics LambdaScope04.java
+ */
+
+class LambdaScope04 {
+
+ interface SAM {
+ void m(Object o);
+ }
+
+ static SAM field1 = field1->{}; //ok
+ static SAM field2 = param->{ Object field2 = null; }; //ok
+
+ SAM field3 = field3->{}; //ok
+ SAM field4 = param->{ Object field4 = null; }; //ok
+
+ {
+ Object local = null;
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ }
+
+ static {
+ Object local = null;
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+
+ void testLocalInstance() {
+ Object local = null;
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+
+ static void testLocalStatic() {
+ Object local = null;
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+
+ void testParamInstance(Object local) {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+
+ static void testParamStatic(Object local) {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+
+ void testForInstance() {
+ for (int local = 0; local != 0 ; local++) {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+ }
+
+ static void testForStatic(Iterable<Object> elems) {
+ for (int local = 0; local != 0 ; local++) {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+ }
+
+ void testForEachInstance(Iterable<Object> elems) {
+ for (Object local : elems) {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+ }
+
+ static void testForEachStatic(Iterable<Object> elems) {
+ for (Object local : elems) {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+ }
+
+ void testCatchInstance() {
+ try { } catch (Throwable local) {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+ }
+
+ static void testCatchStatic(Iterable<Object> elems) {
+ try { } catch (Throwable local) {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+ }
+
+ void testTWRInstance(AutoCloseable res) {
+ try (AutoCloseable local = res) {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ } finally { }
+ }
+
+ static void testTWRStatic(AutoCloseable res) {
+ try (AutoCloseable local = res) {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ } finally { }
+ }
+
+ void testBlockLocalInstance() {
+ Object local = null;
+ {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+ }
+
+ static void testBlockLocalStatic() {
+ Object local = null;
+ {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+ }
+
+ void testSwitchLocalInstance(int i) {
+ switch (i) {
+ case 0: Object local = null;
+ default: {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+ }
+ }
+
+ static void testSwitchLocalStatic(int i) {
+ switch (i) {
+ case 0: Object local = null;
+ default: {
+ SAM s1 = local->{}; //error
+ SAM s2 = param->{ Object local = null; }; //error
+ SAM s3 = field1->{ Object field_2 = null; }; //ok
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LambdaScope04.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,37 @@
+LambdaScope04.java:23:18: compiler.err.already.defined.in.clinit: kindname.variable, local, kindname.instance.init, kindname.class, LambdaScope04
+LambdaScope04.java:24:34: compiler.err.already.defined.in.clinit: kindname.variable, local, kindname.instance.init, kindname.class, LambdaScope04
+LambdaScope04.java:29:18: compiler.err.already.defined.in.clinit: kindname.variable, local, kindname.static.init, kindname.class, LambdaScope04
+LambdaScope04.java:30:34: compiler.err.already.defined.in.clinit: kindname.variable, local, kindname.static.init, kindname.class, LambdaScope04
+LambdaScope04.java:36:18: compiler.err.already.defined: kindname.variable, local, kindname.method, testLocalInstance()
+LambdaScope04.java:37:34: compiler.err.already.defined: kindname.variable, local, kindname.method, testLocalInstance()
+LambdaScope04.java:43:18: compiler.err.already.defined: kindname.variable, local, kindname.method, testLocalStatic()
+LambdaScope04.java:44:34: compiler.err.already.defined: kindname.variable, local, kindname.method, testLocalStatic()
+LambdaScope04.java:49:18: compiler.err.already.defined: kindname.variable, local, kindname.method, testParamInstance(java.lang.Object)
+LambdaScope04.java:50:34: compiler.err.already.defined: kindname.variable, local, kindname.method, testParamInstance(java.lang.Object)
+LambdaScope04.java:55:18: compiler.err.already.defined: kindname.variable, local, kindname.method, testParamStatic(java.lang.Object)
+LambdaScope04.java:56:34: compiler.err.already.defined: kindname.variable, local, kindname.method, testParamStatic(java.lang.Object)
+LambdaScope04.java:62:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testForInstance()
+LambdaScope04.java:63:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testForInstance()
+LambdaScope04.java:70:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testForStatic(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:71:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testForStatic(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:78:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testForEachInstance(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:79:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testForEachInstance(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:86:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testForEachStatic(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:87:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testForEachStatic(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:94:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testCatchInstance()
+LambdaScope04.java:95:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testCatchInstance()
+LambdaScope04.java:102:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testCatchStatic(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:103:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testCatchStatic(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:110:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testTWRInstance(java.lang.AutoCloseable)
+LambdaScope04.java:111:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testTWRInstance(java.lang.AutoCloseable)
+LambdaScope04.java:118:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testTWRStatic(java.lang.AutoCloseable)
+LambdaScope04.java:119:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testTWRStatic(java.lang.AutoCloseable)
+LambdaScope04.java:127:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testBlockLocalInstance()
+LambdaScope04.java:128:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testBlockLocalInstance()
+LambdaScope04.java:136:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testBlockLocalStatic()
+LambdaScope04.java:137:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testBlockLocalStatic()
+LambdaScope04.java:146:26: compiler.err.already.defined: kindname.variable, local, kindname.method, testSwitchLocalInstance(int)
+LambdaScope04.java:147:42: compiler.err.already.defined: kindname.variable, local, kindname.method, testSwitchLocalInstance(int)
+LambdaScope04.java:157:26: compiler.err.already.defined: kindname.variable, local, kindname.method, testSwitchLocalStatic(int)
+LambdaScope04.java:158:42: compiler.err.already.defined: kindname.variable, local, kindname.method, testSwitchLocalStatic(int)
+36 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/LocalBreakAndContinue.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that local break/continue is allowed in lambda expressions
+ * @author Maurizio Cimadamore
+ * @compile LocalBreakAndContinue.java
+ */
+
+class LocalBreakAndContinue {
+
+ static interface SAM {
+ void m();
+ }
+
+ SAM s1 = ()-> { while (true) break; };
+ SAM s2 = ()-> { while (true) continue; };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference01.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2010, 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 8003280
+ * @summary Add lambda tests
+ * use method reference to sort list elements by field
+ * @author Brian Goetz
+ * @author Maurizio Cimadamore
+ * @run main MethodReference01
+ */
+
+import java.util.*;
+
+public class MethodReference01 {
+
+ interface Getter<U, T> {
+ public U get(T t);
+ }
+
+ static class Foo {
+ private Integer a;
+ private String b;
+
+ Foo(Integer a, String b) {
+ this.a = a;
+ this.b = b;
+ }
+
+ static Integer getA(Foo f) { return f.a; }
+ static String getB(Foo f) { return f.b; }
+ }
+
+ public static <T, U extends Comparable<? super U>>
+ void sortBy(List<T> s, final Getter<U, T> getter) {
+ Collections.sort(s, new Comparator<T>() {
+ public int compare(T t1, T t2) {
+ return getter.get(t1).compareTo(getter.get(t2));
+ }
+ });
+ };
+
+ public static void main(String[] args) {
+ List<Foo> c = new ArrayList<Foo>();
+ c.add(new Foo(2, "Hello3!"));
+ c.add(new Foo(3, "Hello1!"));
+ c.add(new Foo(1, "Hello2!"));
+ checkSortByA(c);
+ checkSortByB(c);
+ }
+
+ static void checkSortByA(List<Foo> l) {
+ sortBy(l, Foo::getA);
+ int oldA = -1;
+ for (Foo foo : l) {
+ if (foo.a.compareTo(oldA) < 1) {
+ throw new AssertionError();
+ }
+ }
+ }
+
+ static void checkSortByB(List<Foo> l) {
+ sortBy(l, Foo::getB);
+ String oldB = "";
+ for (Foo foo : l) {
+ if (foo.b.compareTo(oldB) < 1) {
+ throw new AssertionError();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference02.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that seemingly ambiguous method references are resolved properly
+ * @author Maurizio Cimadamore
+ * @compile MethodReference02.java
+ */
+
+class MethodReference02 {
+ static interface SAM {
+ void m(Integer i);
+ }
+
+ void m(Integer i) {}
+ void m(Double d) {}
+
+ SAM s = this::m; //use target type to disambiguate
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference03.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, 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 8003280
+ * @summary Add lambda tests
+ * check that most specific method is selected as expected
+ * @author Maurizio Cimadamore
+ * @run main MethodReference03
+ */
+
+public class MethodReference03 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM {
+ void m(Integer i);
+ }
+
+ static void m(Number i) {}
+ static void m(Integer d) { assertTrue(true); }
+
+ public static void main(String[] args) {
+ SAM s = MethodReference03::m;
+ s.m(1);
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference04.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that target type of a method ref is a SAM type
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=MethodReference04.out -XDrawDiagnostics MethodReference04.java
+ */
+
+class MethodReference04 {
+ void m(Integer i) {}
+
+ Object o = this::m; //fail - not a valid target type
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference04.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+MethodReference04.java:13:16: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference05.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, 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 8003280
+ * @summary Add lambda tests
+ * check that non-static method refernces from static context are handled correctly
+ * @author Maurizio Cimadamore
+ * @run main MethodReference05
+ */
+
+public class MethodReference05 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM {
+ void m(MethodReference05 receiver, Integer i);
+ }
+
+ void m(Integer i) { assertTrue(this != null); }
+
+ public static void main(String[] args) {
+ SAM s = MethodReference05::m;
+ s.m(new MethodReference05(), 1);
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference06.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * method references and super
+ * @author Maurizio Cimadamore
+ * @run main MethodReference06
+ */
+
+public class MethodReference06 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM { //works if SAM is an abstract class
+ abstract void meth(int i);
+ }
+
+ static class A {
+ void m(int i) { assertTrue(true); }
+ }
+
+ static class B extends A {
+ void m(int i) {
+ SAM mh = super::m;
+ mh.meth(i);
+ }
+ }
+
+ public static void main(String[] args) {
+ new B().m(10);
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference07.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, 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 8003280
+ * @summary Add lambda tests
+ * check that syntax for selecting generic receiver works
+ * @author Maurizio Cimadamore
+ * @compile MethodReference07.java
+ */
+
+class MethodReference07 {
+ interface SAM {
+ String m(Foo<String> f);
+ }
+
+ static class Foo<X> {
+ String getX() { return null; }
+
+ static void test() {
+ SAM s = Foo<String>::getX;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference08.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,24 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that syntax for selecting generic receiver works
+ * @author Maurizio Cimadamore
+ *
+ * @compile MethodReference08.java
+ * @compile/fail/ref=MethodReference08.out -Werror -Xlint:rawtypes -XDrawDiagnostics MethodReference08.java
+ */
+
+class MethodReference08 {
+ interface SAM {
+ String m(Foo f);
+ }
+
+ static class Foo<X> {
+ String getX() { return null; }
+
+ static void test() {
+ SAM s = Foo::getX;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference08.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,5 @@
+MethodReference08.java:14:17: compiler.warn.raw.class.use: MethodReference08.Foo, MethodReference08.Foo<X>
+MethodReference08.java:21:19: compiler.warn.raw.class.use: MethodReference08.Foo, MethodReference08.Foo<X>
+- compiler.err.warnings.and.werror
+1 error
+2 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference09.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that non static members cannot be referenced from a method reference qualifier
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=MethodReference09.out -XDrawDiagnostics MethodReference09.java
+ */
+
+class MethodReference09 {
+ interface SAM {
+ String m(Foo f);
+ }
+
+ static class Foo<X> {
+ String getX() { return null; }
+
+ Foo<X> getThis() { return this; }
+
+ static void test() {
+ SAM s1 = Foo.getThis()::getX;
+ SAM s2 = this::getX;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference09.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,4 @@
+MethodReference09.java:21:23: compiler.err.non-static.cant.be.ref: kindname.method, getThis()
+MethodReference09.java:21:20: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, getX, compiler.misc.no.args, MethodReference09.Foo, kindname.class, MethodReference09.Foo<X>, (compiler.misc.arg.length.mismatch)))
+MethodReference09.java:22:20: compiler.err.non-static.cant.be.ref: kindname.variable, this
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference10.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2010, 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 8003280
+ * @summary Add lambda tests
+ * check that non static selectors in method refs are handled correctly
+ * @author Maurizio Cimadamore
+ * @compile MethodReference10.java
+ */
+
+import java.util.*;
+
+class MethodReference10 {
+
+ interface Getter<U, T> {
+ public U get(T t);
+ }
+
+ public static <T, U extends Comparable<? super U>>
+ void sortBy(Collection<T> s, Getter<U, T> getter) {};
+
+ static class Foo {
+ private String a;
+ String getA(Foo f) { return f.a; }
+ }
+
+ public static void main(String[] args) {
+ Collection<Foo> c = new ArrayList<Foo>();
+ sortBy(c, new Foo()::getA);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference11.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010, 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 8003280
+ * @summary Add lambda tests
+ * check that static vs. non-static selection logic in method references works
+ * @author Maurizio Cimadamore
+ * @run main MethodReference11
+ */
+
+import java.util.*;
+
+public class MethodReference11 {
+ public static void main(String[] args) {
+ String[] strings = new String[] { "D", "C", "B", "A" };
+ Arrays.sort( strings, String.CASE_INSENSITIVE_ORDER::compare );
+ String last = "1";
+ for (String s : strings) {
+ if (String.CASE_INSENSITIVE_ORDER.compare(last, s) > 0) {
+ throw new AssertionError();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference12.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that Object methods are dispatched accordingly
+ * @author Maurizio Cimadamore
+ * @run main MethodReference12
+ */
+
+public class MethodReference12 {
+
+ interface SAM { void foo(int i); }
+
+ static void print(int i) {
+ System.out.println(i);
+ }
+
+ public static void main(String[] args) {
+ try {
+ test(MethodReference12::print);
+ test(i -> { System.out.println(i); } );
+ }
+ catch (Throwable t) {
+ t.printStackTrace();
+ throw new AssertionError("An error occurred");
+ }
+ }
+
+ static void test(SAM s) throws Throwable {
+ s.hashCode();
+ s.equals(null);
+ s.toString();
+ try {
+ s.notify(); //will throw IllegalMonitorStateException
+ }
+ catch (final IllegalMonitorStateException e) { }
+ try {
+ s.notifyAll(); //will throw IllegalMonitorStateException
+ }
+ catch (final IllegalMonitorStateException e) { }
+ try {
+ s.wait(1); //will throw IllegalMonitorStateException
+ }
+ catch (final IllegalMonitorStateException | InterruptedException e) { }
+ try {
+ s.wait(1,1); //will throw IllegalMonitorStateException
+ }
+ catch (final IllegalMonitorStateException | InterruptedException e) { }
+ try {
+ s.wait(); //will throw IllegalMonitorStateException
+ }
+ catch (final IllegalMonitorStateException | InterruptedException e) { }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference13.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that equals() on Proxied objects is handled accordingly
+ * @author Maurizio Cimadamore
+ * @compile -XDuseProxy MethodReference13.java
+ * @run main MethodReference13
+ */
+
+public class MethodReference13 {
+
+ static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM {
+ void m();
+ }
+
+ static void m() { }
+
+ public static void main(String[] args) {
+ SAM s = MethodReference13::m;
+ assertTrue(s.equals(s));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference14.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check casting a method reference to a SAM type does not result in a CCE
+ * @author Maurizio Cimadamore
+ * @run main MethodReference14
+ */
+
+public class MethodReference14 {
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static int assertionCount = 0;
+
+ interface SAM {
+ void m();
+ }
+
+ static void m() { assertTrue(true); }
+
+ public static void main(String[] args) {
+ SAM s = (SAM)MethodReference14::m;
+ s.m();
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference15.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that assignments involving method references do not trigger transitional 292 warnings
+ * @author Maurizio Cimadamore
+ * @compile -Werror MethodReference15.java
+ */
+
+public class MethodReference15 {
+
+ interface SAM {
+ void m();
+ }
+
+ static void m() { }
+
+ static void test() {
+ SAM s = MethodReference15::m;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference16.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * semantics of statically qualified method reference should not depend on the context
+ * @author Maurizio Cimadamore
+ * @run main MethodReference16
+ */
+
+public class MethodReference16 {
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static int assertionCount = 0;
+
+ interface SAM {
+ void m(MethodReference16 receiver);
+ }
+
+ void m() { assertTrue(true); }
+
+ void test() {
+ SAM s = (SAM)MethodReference16::m;
+ s.m(this);
+ }
+
+ public static void main(String[] args) {
+ MethodReference16 rec = new MethodReference16();
+ SAM s = (SAM)MethodReference16::m;
+ s.m(rec);
+ rec.test();
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference17.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * basic test for constructor references
+ * @author Maurizio Cimadamore
+ * @run main MethodReference17
+ */
+
+public class MethodReference17 {
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static int assertionCount = 0;
+
+ MethodReference17() {
+ assertTrue(true);
+ }
+
+ interface SAM {
+ MethodReference17 m();
+ }
+
+ static void test(SAM s) {
+ s.m();
+ }
+
+ public static void main(String[] args) {
+ SAM s = MethodReference17::new;
+ s.m();
+ test(MethodReference17::new);
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference18.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * basic test for constructor references
+ * @author Maurizio Cimadamore
+ * @run main MethodReference18
+ */
+
+public class MethodReference18 {
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static int assertionCount = 0;
+
+ MethodReference18(Object o) {
+ assertTrue(true);
+ }
+
+ MethodReference18(Number n) {
+ assertTrue(false);
+ }
+
+ interface SAM {
+ MethodReference18 m(Object o);
+ }
+
+ static void test(SAM s, Object arg) {
+ s.m(arg);
+ }
+
+ public static void main(String[] args) {
+ SAM s = MethodReference18::new;
+ s.m("");
+ test(MethodReference18::new, "");
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference19.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * basic test for constructor references and generic classes
+ * @author Maurizio Cimadamore
+ * @run main MethodReference19
+ */
+
+public class MethodReference19<X> {
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static int assertionCount = 0;
+
+ MethodReference19(X x) {
+ assertTrue(true);
+ }
+
+ interface SAM<Z> {
+ MethodReference19<Z> m(Z z);
+ }
+
+ static <Y> void test(SAM<Y> s, Y arg) {
+ s.m(arg);
+ }
+
+ public static void main(String[] args) {
+ SAM<String> s = MethodReference19<String>::new;
+ s.m("");
+ test(MethodReference19<String>::new, "");
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference20.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,24 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * basic test for constructor references and generic classes
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=MethodReference20.out -XDrawDiagnostics MethodReference20.java
+ */
+
+class MethodReference20<X> {
+
+ MethodReference20(X x) { }
+
+ interface SAM<Z> {
+ MethodReference20<Z> m(Z z);
+ }
+
+ static void test(SAM<Integer> s) { }
+
+ public static void main(String[] args) {
+ SAM<Integer> s = MethodReference20<String>::new;
+ test(MethodReference20<String>::new);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference20.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+MethodReference20.java:21:26: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, MethodReference20, java.lang.String, java.lang.Integer, kindname.class, MethodReference20<X>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Integer, java.lang.String))))
+MethodReference20.java:22:9: compiler.err.cant.apply.symbol: kindname.method, test, MethodReference20.SAM<java.lang.Integer>, @549, kindname.class, MethodReference20<X>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, MethodReference20, java.lang.String, java.lang.Integer, kindname.class, MethodReference20<X>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Integer, java.lang.String)))))
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference21.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,23 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that erroneous method references are flagged with errors as expected
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=MethodReference21.out -XDrawDiagnostics MethodReference21.java
+ */
+
+class MethodReference21 {
+
+ interface SAM {
+ void m();
+ }
+
+ void call(SAM s) {}
+
+ SAM s = NonExistentType::m;
+
+ {
+ call(NonExistentType::m);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference21.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+MethodReference21.java:18:13: compiler.err.cant.resolve.location: kindname.variable, NonExistentType, , , (compiler.misc.location: kindname.class, MethodReference21, null)
+MethodReference21.java:21:14: compiler.err.cant.resolve.location: kindname.variable, NonExistentType, , , (compiler.misc.location: kindname.class, MethodReference21, null)
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference22.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,67 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that pair of bound/non-bound method references checked correctly
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=MethodReference22.out -XDrawDiagnostics MethodReference22.java
+ */
+
+class MethodReference22 {
+
+ void m1(String x) { }
+ void m1(MethodReference22 rec, String x) { }
+
+ static void m2(String x) { }
+ static void m2(MethodReference22 rec, String x) { }
+
+ static void m3(String x) { }
+ void m3(MethodReference22 rec, String x) { }
+
+ void m4(String x) { }
+ static void m4(MethodReference22 rec, String x) { }
+
+ interface SAM1 {
+ void m(String x);
+ }
+
+ interface SAM2 {
+ void m(MethodReference22 rec, String x);
+ }
+
+ static void call1(SAM1 s) { }
+
+ static void call2(SAM2 s) { }
+
+ static void call3(SAM1 s) { }
+ static void call3(SAM2 s) { }
+
+ static void test1() {
+ SAM1 s1 = MethodReference22::m1; //fail
+ call1(MethodReference22::m1); //fail
+ SAM1 s2 = MethodReference22::m2; //ok
+ call1(MethodReference22::m2); //ok
+ SAM1 s3 = MethodReference22::m3; //ok
+ call1(MethodReference22::m3); //ok
+ SAM1 s4 = MethodReference22::m4; //fail
+ call1(MethodReference22::m4); //fail
+ }
+
+ static void test2() {
+ SAM2 s1 = MethodReference22::m1; //ok
+ call2(MethodReference22::m1); //ok
+ SAM2 s2 = MethodReference22::m2; //ok
+ call2(MethodReference22::m2); //ok
+ SAM2 s3 = MethodReference22::m3; //fail
+ call2(MethodReference22::m3); //fail
+ SAM2 s4 = MethodReference22::m4; //fail
+ call2(MethodReference22::m4); //fail
+ }
+
+ static void test3() {
+ call3(MethodReference22::m1); //ok
+ call3(MethodReference22::m2); //ambiguous
+ call3(MethodReference22::m3); //ok
+ call3(MethodReference22::m4); //fail
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference22.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,11 @@
+MethodReference22.java:40:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String)))
+MethodReference22.java:41:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @999, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String))))
+MethodReference22.java:46:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String)))
+MethodReference22.java:47:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @1270, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String))))
+MethodReference22.java:55:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m3(MethodReference22,java.lang.String)))
+MethodReference22.java:56:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1574, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m3(MethodReference22,java.lang.String))))
+MethodReference22.java:57:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22))
+MethodReference22.java:58:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1667, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22)))
+MethodReference22.java:63:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
+MethodReference22.java:65:9: compiler.err.cant.apply.symbols: kindname.method, call3, @1881,{(compiler.misc.inapplicable.method: kindname.method, MethodReference22, call3(MethodReference22.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String))))),(compiler.misc.inapplicable.method: kindname.method, MethodReference22, call3(MethodReference22.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22))))}
+10 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference23.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,74 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that pair of bound/non-bound constructor references is flagged as ambiguous
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=MethodReference23.out -XDrawDiagnostics MethodReference23.java
+ */
+
+class MethodReference23 {
+
+ class Inner1 {
+ Inner1(MethodReference23 outer) {};
+ Inner1() {};
+ }
+
+ static class Inner2 {
+ Inner2(MethodReference23 outer) {};
+ Inner2() {};
+ }
+
+ interface SAM11 {
+ Inner1 m(MethodReference23 rec);
+ }
+
+ interface SAM12 {
+ Inner1 m();
+ }
+
+ interface SAM21 {
+ Inner2 m(MethodReference23 rec);
+ }
+
+ interface SAM22 {
+ Inner2 m();
+ }
+
+ static void call11(SAM11 s) { }
+
+ static void call12(SAM12 s) { }
+
+ static void call21(SAM21 s) { }
+
+ static void call22(SAM22 s) { }
+
+ static void call3(SAM11 s) { }
+ static void call3(SAM12 s) { }
+ static void call3(SAM21 s) { }
+ static void call3(SAM22 s) { }
+
+ static void test11() {
+ SAM11 s = MethodReference23.Inner1::new; //ok
+ call11(MethodReference23.Inner1::new); //ok
+ }
+
+ static void test12() {
+ SAM12 s = MethodReference23.Inner1::new; //fail
+ call12(MethodReference23.Inner1::new); //fail
+ }
+
+ static void test21() {
+ SAM21 s = MethodReference23.Inner2::new; //ok
+ call21(MethodReference23.Inner2::new); //ok
+ }
+
+ static void test22() {
+ SAM22 s = MethodReference23.Inner2::new; //ok
+ call22(MethodReference23.Inner2::new); //ok
+ }
+
+ static void test3() {
+ call3(MethodReference23.Inner2::new); //ambiguous
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference23.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,6 @@
+MethodReference23.java:52:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23))
+MethodReference23.java:53:9: compiler.err.cant.apply.symbol: kindname.method, call11, MethodReference23.SAM11, @1140, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23)))
+MethodReference23.java:57:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23))
+MethodReference23.java:58:9: compiler.err.cant.apply.symbol: kindname.method, call12, MethodReference23.SAM12, @1282, kindname.class, MethodReference23, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23)))
+MethodReference23.java:72:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference23.SAM21), MethodReference23, kindname.method, call3(MethodReference23.SAM22), MethodReference23
+5 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference24.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that non-boxing method references conversion has the precedence
+ * @run main MethodReference24
+ */
+
+public class MethodReference24 {
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static int assertionCount = 0;
+
+ static void m(int i) { assertTrue(true); }
+ static void m(Integer i) { assertTrue(false); }
+
+ interface SAM {
+ void m(int x);
+ }
+
+ static void call(SAM s) { s.m(42); }
+
+ public static void main(String[] args) {
+ SAM s = MethodReference24::m; //resolves to m(int)
+ s.m(42);
+ call(MethodReference24::m); //resolves to m(int)
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference25.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that non-boxing method references conversion has the precedence
+ * @run main MethodReference25
+ */
+
+public class MethodReference25 {
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static int assertionCount = 0;
+
+ static void m(Integer i) { assertTrue(true); }
+
+ interface SAM1 {
+ void m(int x);
+ }
+
+ interface SAM2 {
+ void m(Integer x);
+ }
+
+ static void call(int i, SAM1 s) { s.m(i); assertTrue(false); }
+ static void call(int i, SAM2 s) { s.m(i); }
+
+ public static void main(String[] args) {
+ call(1, MethodReference25::m); //resolves to call(int, SAM2)
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference26.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,23 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check strict method conversion does not allow loose method reference conversion
+ * @compile/fail/ref=MethodReference26.out -XDrawDiagnostics MethodReference26.java
+ */
+
+class MethodReference26 {
+
+ static void m(Integer i) { }
+
+ interface SAM {
+ void m(int x);
+ }
+
+ static void call(int i, SAM s) { }
+ static void call(Integer i, SAM s) { }
+
+ static void test() {
+ call(1, MethodReference26::m); //ambiguous
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference26.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+MethodReference26.java:21:9: compiler.err.ref.ambiguous: call, kindname.method, call(int,MethodReference26.SAM), MethodReference26, kindname.method, call(java.lang.Integer,MethodReference26.SAM), MethodReference26
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference27.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that non-boxing method references conversion has the precedence
+ * @run main MethodReference27
+ */
+
+public class MethodReference27 {
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static int assertionCount = 0;
+
+ interface SAM {
+ void m(int i1, int i2);
+ }
+
+ static void m1(int i1, int i2) { assertTrue(true); }
+ static void m1(Integer i1, int i2) { assertTrue(false); }
+ static void m1(int i1, Integer i2) { assertTrue(false); }
+ static void m1(Integer i1, Integer i2) { assertTrue(false); }
+ static void m1(Integer... is) { assertTrue(false); }
+
+ static void m2(int... is) { assertTrue(true); }
+ static void m2(double... ds) { assertTrue(false); }
+
+ public static void main(String[] args) {
+ SAM s1 = MethodReference27::m1;
+ s1.m(42,42);
+ SAM s2 = MethodReference27::m2;
+ s2.m(42,42);
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference28.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,56 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that non-compatible method references are rejected
+ * @compile/fail/ref=MethodReference28.out -XDrawDiagnostics MethodReference28.java
+ */
+
+class MethodReference28 {
+
+ interface SAM1 {
+ void m(int i);
+ }
+
+ interface SAM2 {
+ void m(MethodReference28 rec, int i);
+ }
+
+ static void static_m1(Integer i) { } //ok - boxing
+ static void static_m2(Integer i1, Integer i2) { } //wrong arity
+ static void static_m3(String s) { } //type mismatch
+ static void static_m4(String... ss) { } //type mismatch - varargs
+
+ void m1(Integer i) { } //ok - boxing
+ void m2(Integer i1, Integer i2) { } //wrong arity
+ void m3(String s) { } //type mismatch
+ void m4(String... ss) { } //type mismatch - varargs
+
+ static void testStatic() {
+ SAM1 s1 = MethodReference28::static_m1;
+ SAM1 s2 = MethodReference28::static_m2;
+ SAM1 s3 = MethodReference28::static_m3;
+ SAM1 s4 = MethodReference28::static_m4;
+ }
+
+ void testBadMember() {
+ SAM1 s1 = MethodReference28::m1;
+ SAM1 s2 = MethodReference28::m2;
+ SAM1 s3 = MethodReference28::m3;
+ SAM1 s4 = MethodReference28::m4;
+ }
+
+ void testMember() {
+ SAM1 s1 = this::m1;
+ SAM1 s2 = this::m2;
+ SAM1 s3 = this::m3;
+ SAM1 s4 = this::m4;
+ }
+
+ static void testUnbound() {
+ SAM2 s1 = MethodReference28::m1;
+ SAM2 s2 = MethodReference28::m2;
+ SAM2 s3 = MethodReference28::m3;
+ SAM2 s4 = MethodReference28::m4;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference28.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,14 @@
+MethodReference28.java:31:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, static_m2, java.lang.Integer,java.lang.Integer, int, kindname.class, MethodReference28, (compiler.misc.arg.length.mismatch)))
+MethodReference28.java:32:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, static_m3, java.lang.String, int, kindname.class, MethodReference28, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))))
+MethodReference28.java:33:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, static_m4, java.lang.String[], int, kindname.class, MethodReference28, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: int, java.lang.String))))
+MethodReference28.java:37:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.Integer)))
+MethodReference28.java:38:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m2, java.lang.Integer,java.lang.Integer, int, kindname.class, MethodReference28, (compiler.misc.arg.length.mismatch)))
+MethodReference28.java:39:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m3, java.lang.String, int, kindname.class, MethodReference28, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))))
+MethodReference28.java:40:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m4, java.lang.String[], int, kindname.class, MethodReference28, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: int, java.lang.String))))
+MethodReference28.java:45:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m2, java.lang.Integer,java.lang.Integer, int, kindname.class, MethodReference28, (compiler.misc.arg.length.mismatch)))
+MethodReference28.java:46:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m3, java.lang.String, int, kindname.class, MethodReference28, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))))
+MethodReference28.java:47:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m4, java.lang.String[], int, kindname.class, MethodReference28, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: int, java.lang.String))))
+MethodReference28.java:52:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m2, java.lang.Integer,java.lang.Integer, MethodReference28,int, kindname.class, MethodReference28, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: MethodReference28, java.lang.Integer))))
+MethodReference28.java:53:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m3, java.lang.String, MethodReference28,int, kindname.class, MethodReference28, (compiler.misc.arg.length.mismatch)))
+MethodReference28.java:54:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m4, java.lang.String[], MethodReference28,int, kindname.class, MethodReference28, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: MethodReference28, java.lang.String))))
+13 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference29.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * reference to super leads to compiler crash when 292 translation scheme is enabled
+ */
+
+public class MethodReference29 {
+
+ interface SAM {
+ void m(Integer i);
+ }
+
+ static class A {
+ void m(int i) { }
+ }
+
+ static class B extends A {
+ void test() {
+ SAM s = super::m;
+ s.m(42);
+ }
+
+ void m(int i) { throw new AssertionError(); }
+ }
+
+ public static void main(String[] args) {
+ new B().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference30.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that non-static qualifier of static method reference is eagerly evaluated
+ */
+
+public class MethodReference30 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM {
+ void m();
+ }
+
+ MethodReference30() {
+ assertTrue(true);
+ }
+
+ static void m() { }
+
+ public static void main(String[] args) {
+ SAM s = new MethodReference30()::m;
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference31.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that boxing of return-type works as expected
+ */
+
+public class MethodReference31 {
+
+ static class Success extends RuntimeException { }
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM<X> {
+ X m();
+ }
+
+ interface SAM_byte {
+ byte m();
+ }
+
+ interface SAM_short {
+ short m();
+ }
+
+ interface SAM_int {
+ int m();
+ }
+
+ interface SAM_long {
+ long m();
+ }
+
+ interface SAM_float {
+ float m();
+ }
+
+ interface SAM_double {
+ double m();
+ }
+
+ static <Z> Z test() {
+ assertTrue(true);
+ throw new Success();
+ }
+
+ static byte test_byte() {
+ assertTrue(true);
+ return 0;
+ }
+
+ static short test_short() {
+ assertTrue(true);
+ return 0;
+ }
+
+ static int test_int() {
+ assertTrue(true);
+ return 0;
+ }
+
+ static long test_long() {
+ assertTrue(true);
+ return 0;
+ }
+
+ static float test_float() {
+ assertTrue(true);
+ return 0;
+ }
+
+ static double test_double() {
+ assertTrue(true);
+ return 0;
+ }
+
+ static void testByte() {
+ SAM<Byte> s1 = MethodReference31::test_byte;
+ s1.m();
+ SAM_byte s2 = MethodReference31::test_byte;
+ s2.m();
+ SAM<Byte> s3 = MethodReference31::<Byte>test;
+ try {
+ s3.m();
+ }
+ catch (RuntimeException ex) { }
+ SAM_byte s4 = MethodReference31::<Byte>test;
+ try {
+ s4.m();
+ }
+ catch (RuntimeException ex) { }
+ }
+
+ static void testShort() {
+ SAM<Short> s1 = MethodReference31::test_short;
+ s1.m();
+ SAM_short s2 = MethodReference31::test_short;
+ s2.m();
+ SAM<Short> s3 = MethodReference31::<Short>test;
+ try {
+ s3.m();
+ }
+ catch (RuntimeException ex) { }
+ SAM_short s4 = MethodReference31::<Short>test;
+ try {
+ s4.m();
+ }
+ catch (RuntimeException ex) { }
+ }
+
+ static void testInteger() {
+ SAM<Integer> s1 = MethodReference31::test_int;
+ s1.m();
+ SAM_int s2 = MethodReference31::test_int;
+ s2.m();
+ SAM<Integer> s3 = MethodReference31::<Integer>test;
+ try {
+ s3.m();
+ }
+ catch (RuntimeException ex) { }
+ SAM_int s4 = MethodReference31::<Integer>test;
+ try {
+ s4.m();
+ }
+ catch (RuntimeException ex) { }
+ }
+
+ static void testLong() {
+ SAM<Long> s1 = MethodReference31::test_long;
+ s1.m();
+ SAM_long s2 = MethodReference31::test_long;
+ s2.m();
+ SAM<Long> s3 = MethodReference31::<Long>test;
+ try {
+ s3.m();
+ }
+ catch (RuntimeException ex) { }
+ SAM_long s4 = MethodReference31::<Long>test;
+ try {
+ s4.m();
+ }
+ catch (RuntimeException ex) { }
+ }
+
+ static void testFloat() {
+ SAM<Float> s1 = MethodReference31::test_float;
+ s1.m();
+ SAM_float s2 = MethodReference31::test_float;
+ s2.m();
+ SAM<Float> s3 = MethodReference31::<Float>test;
+ try {
+ s3.m();
+ }
+ catch (RuntimeException ex) { }
+ SAM_float s4 = MethodReference31::<Float>test;
+ try {
+ s4.m();
+ }
+ catch (RuntimeException ex) { }
+ }
+
+ static void testDouble() {
+ SAM<Double> s1 = MethodReference31::test_double;
+ s1.m();
+ SAM_double s2 = MethodReference31::test_double;
+ s2.m();
+ SAM<Double> s3 = MethodReference31::<Double>test;
+ try {
+ s3.m();
+ }
+ catch (RuntimeException ex) { }
+ SAM_double s4 = MethodReference31::<Double>test;
+ try {
+ s4.m();
+ }
+ catch (RuntimeException ex) { }
+ }
+
+ public static void main(String[] args) {
+ testByte();
+ testShort();
+ testInteger();
+ testLong();
+ testFloat();
+ testDouble();
+ assertTrue(assertionCount == 24);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference32.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that varargs warnings are generated during SAM conversion
+ * @compile/fail/ref=MethodReference32.out -Xlint:unchecked -Werror -XDrawDiagnostics MethodReference32.java
+ */
+
+import java.util.*;
+
+class MethodReference32 {
+
+ interface SAM {
+ MethodReference32 m(List<Integer> l1, List<Integer> l2);
+ }
+
+ MethodReference32 meth(List<Integer>... lli) { return null; }
+ MethodReference32(List<Integer>... lli) { }
+
+ SAM s1 = this::meth;
+ SAM s2 = MethodReference32::new;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference32.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,7 @@
+MethodReference32.java:17:45: compiler.warn.unchecked.varargs.non.reifiable.type: java.util.List<java.lang.Integer>
+MethodReference32.java:18:40: compiler.warn.unchecked.varargs.non.reifiable.type: java.util.List<java.lang.Integer>
+MethodReference32.java:20:14: compiler.warn.unchecked.generic.array.creation: java.util.List<java.lang.Integer>[]
+MethodReference32.java:21:14: compiler.warn.unchecked.generic.array.creation: java.util.List<java.lang.Integer>[]
+- compiler.err.warnings.and.werror
+1 error
+4 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference33.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * test bridged constructor references
+ */
+
+public class MethodReference33 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ class Foo {
+ Foo(Integer i) { assertTrue(true); }
+ Foo() { assertTrue(true); }
+ }
+
+ interface BridgeSAMBound<X> {
+ X m(int i);
+ }
+
+ interface NonBridgeSAMBound<X> {
+ X m();
+ }
+
+ void test() {
+ BridgeSAMBound<Foo> b1 = Foo::new;
+ b1.m(1);
+ NonBridgeSAMBound<Foo> b2 = Foo::new;
+ b2.m();
+ }
+
+ public static void main(String[] args) {
+ MethodReference33 test = new MethodReference33();
+ test.test();
+ assertTrue(assertionCount == 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference34.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that code generation handles void-compatibility correctly
+ * @run main MethodReference34
+ */
+
+public class MethodReference34 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM_void<X> {
+ void m();
+ }
+
+ interface SAM_java_lang_Void<X> {
+ void m();
+ }
+
+ static void m_void() { assertTrue(true); }
+
+ static Void m_java_lang_Void() { assertTrue(true); return null; }
+
+ public static void main(String[] args) {
+ SAM_void s1 = MethodReference34::m_void;
+ s1.m();
+ SAM_java_lang_Void s2 = MethodReference34::m_void;
+ s2.m();
+ SAM_void s3 = MethodReference34::m_java_lang_Void;
+ s3.m();
+ SAM_java_lang_Void s4 = MethodReference34::m_java_lang_Void;
+ s4.m();
+ assertTrue(assertionCount == 4);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference35.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that lambda/method references are valid method reference qualifiers
+ * @run main MethodReference35
+ */
+
+public class MethodReference35 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM {
+ MethodReference35 invoke();
+ }
+
+ MethodReference35() {
+ assertTrue(true);
+ }
+
+ static MethodReference35 m() {
+ assertTrue(true);
+ return null;
+ }
+
+ public static void main(String[] args) {
+ SAM sam1 = ((SAM)() -> { assertTrue(true); return null; })::invoke;
+ sam1.invoke();
+ SAM sam2 = ((SAM)MethodReference35::new)::invoke;
+ sam1.invoke();
+ SAM sam3 = ((SAM)MethodReference35::m)::invoke;
+ sam1.invoke();
+ assertTrue(assertionCount == 3);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference36.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that method reference handles varargs conversion properly
+ * @run main MethodReference36
+ */
+
+public class MethodReference36 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SamC { void m(char[] a); }
+ interface SamZ { void m(boolean[] a); }
+ interface SamB { void m(byte[] a); }
+ interface SamS { void m(short[] a); }
+ interface SamI { void m(int[] a); }
+ interface SamL { void m(long[] a); }
+ interface SamF { void m(float[] a); }
+ interface SamD { void m(double[] a); }
+ interface SamO { void m(Object[] a); }
+
+
+ static void m(Object... vi) {
+ assertTrue(true);
+ }
+
+ public void test() {
+
+ SamC sc = MethodReference36::m;
+ sc.m(new char[] { 'a', 'b' } );
+
+ SamZ sz = MethodReference36::m;
+ sz.m(new boolean[] { true, false } );
+
+ SamB sb = MethodReference36::m;
+ sb.m(new byte[] { 0, 1 } );
+
+ SamS ss = MethodReference36::m;
+ ss.m(new short[] { 0, 1 } );
+
+ SamI si = MethodReference36::m;
+ si.m(new int[] { 0, 1 } );
+
+ SamL sl = MethodReference36::m;
+ sl.m(new long[] { 0, 1 } );
+
+ SamF sf = MethodReference36::m;
+ sf.m(new float[] { 0, 1 } );
+
+ SamD sd = MethodReference36::m;
+ sd.m(new double[] { 0, 1 } );
+
+ SamO so = MethodReference36::m;
+ so.m(new Object[] { null, null } );
+ }
+
+ public static void main(String[] args) {
+ new MethodReference36().test();
+ assertTrue(assertionCount == 9);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference37.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * spurious exceptions when checking references to inner constructors where
+ * the enclosing class is not defined in any outer context
+ * @compile/fail/ref=MethodReference37.out -XDrawDiagnostics MethodReference37.java
+ */
+
+class MethodReference37 {
+
+ interface SAM1<R> {
+ R invoke();
+ }
+
+ interface SAM2<R, A> {
+ R invoke(A a);
+ }
+
+ static class Outer {
+ class Inner { }
+
+ static void test1() {
+ SAM2<Inner, Outer> sam = Inner::new;
+ }
+
+ void test2() {
+ SAM1<Inner> sam0 = Inner::new;
+ SAM2<Inner, Outer> sam1 = Inner::new;
+ }
+ }
+
+ static void test1() {
+ SAM2<Outer.Inner, Outer> sam = Outer.Inner::new;
+ }
+
+ void test2() {
+ SAM2<Outer.Inner, Outer> sam1 = Outer.Inner::new;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference37.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,5 @@
+MethodReference37.java:24:38: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, compiler.misc.no.args, MethodReference37.Outer, kindname.class, MethodReference37.Outer.Inner, (compiler.misc.arg.length.mismatch)))
+MethodReference37.java:29:39: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, compiler.misc.no.args, MethodReference37.Outer, kindname.class, MethodReference37.Outer.Inner, (compiler.misc.arg.length.mismatch)))
+MethodReference37.java:34:40: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, compiler.misc.no.args, MethodReference37.Outer, kindname.class, MethodReference37.Outer.Inner, (compiler.misc.arg.length.mismatch)))
+MethodReference37.java:38:41: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, compiler.misc.no.args, MethodReference37.Outer, kindname.class, MethodReference37.Outer.Inner, (compiler.misc.arg.length.mismatch)))
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference38.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,29 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * The qualifier type of a constructor reference must be a concrete class
+ * @compile/fail/ref=MethodReference38.out -XDrawDiagnostics MethodReference38.java
+ */
+
+class MethodReference38 {
+
+ interface SAM<R> {
+ R invoke();
+ }
+
+ @interface A { }
+
+ interface I { }
+
+ static abstract class AC { }
+
+ enum E { }
+
+ void test() {
+ SAM s1 = A::new;
+ SAM s2 = I::new;
+ SAM s3 = AC::new;
+ SAM s4 = E::new;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference38.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,5 @@
+MethodReference38.java:24:18: compiler.err.abstract.cant.be.instantiated
+MethodReference38.java:25:18: compiler.err.abstract.cant.be.instantiated
+MethodReference38.java:26:18: compiler.err.abstract.cant.be.instantiated
+MethodReference38.java:27:18: compiler.err.enum.cant.be.instantiated
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference39.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that bad enclosing class parameter type is discarded accordingly
+ * @compile/fail/ref=MethodReference39.out -XDrawDiagnostics MethodReference39.java
+ */
+class MethodReference39 {
+
+ static class Sup {}
+
+
+ static class Sub extends Sup {
+
+ interface SAM { Sup m(Sup x, String str); }
+
+ class Inner extends Sup {
+ Inner(String val) { }
+ }
+
+ void test() {
+ SAM var = Sub.Inner::new;;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference39.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+MethodReference39.java:22:23: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, java.lang.String, MethodReference39.Sup,java.lang.String, kindname.class, MethodReference39.Sub.Inner, (compiler.misc.arg.length.mismatch)))
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference40.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,24 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that unbound constructor reference are not accepted
+ * @compile/fail/ref=MethodReference40.out -XDrawDiagnostics MethodReference40.java
+ */
+class MethodReference40 {
+
+ static class Sup {
+ class Inner {
+ Inner(String val) { }
+ }
+ }
+
+ static class Sub extends Sup {
+
+ interface SAM { Sup.Inner m(Sub x, String str); }
+
+ void test() {
+ SAM var = Sub.Inner::new;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference40.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+MethodReference40.java:21:23: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, java.lang.String, MethodReference40.Sub,java.lang.String, kindname.class, MethodReference40.Sup.Inner, (compiler.misc.arg.length.mismatch)))
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference41.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that diamond inference is applied when using raw constructor reference qualifier
+ * @run main MethodReference41
+ */
+public class MethodReference41 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM1 {
+ void m(String s);
+ }
+
+ interface SAM2 {
+ void m(Integer s);
+ }
+
+ interface SAM3 {
+ void m(Object o);
+ }
+
+ static class Foo<X extends Number> {
+ Foo(X x) { }
+ }
+
+
+ static void m(SAM1 s) { assertTrue(false); }
+ static void m(SAM2 s) { assertTrue(true); }
+ static void m(SAM3 s) { assertTrue(false); }
+
+ public static void main(String[] args) {
+ m(Foo::new);
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference42.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that diamond inference is applied when using raw constructor reference qualifier
+ * @run main MethodReference42
+ */
+public class MethodReference42 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static class SuperFoo<X> { }
+
+ static class Foo<X extends Number> extends SuperFoo<X> { }
+
+ interface SAM1 {
+ SuperFoo<String> m();
+ }
+
+ interface SAM2 {
+ SuperFoo<Integer> m();
+ }
+
+ interface SAM3 {
+ SuperFoo<Object> m();
+ }
+
+ static void m(SAM1 s) { assertTrue(false); }
+ static void m(SAM2 s) { assertTrue(true); }
+ static void m(SAM3 s) { assertTrue(false); }
+
+ public static void main(String[] args) {
+ m(Foo::new);
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference43.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that diamond inference is applied when using raw constructor reference qualifier
+ * @run main MethodReference43
+ */
+public class MethodReference43 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM1 {
+ Foo<?> m(String s);
+ }
+
+ interface SAM2 {
+ Foo<?> m(Integer s);
+ }
+
+ interface SAM3 {
+ Foo<?> m(Object o);
+ }
+
+ interface SAM4 {
+ Foo<Number> m(Integer o);
+ }
+
+ static class Foo<X extends Number> {
+ Foo(X x) { }
+ }
+
+
+ static void m(SAM1 s) { assertTrue(false); }
+ static void m(SAM2 s) { assertTrue(true); }
+ static void m(SAM3 s) { assertTrue(false); }
+ static void m(SAM4 s) { assertTrue(false); }
+
+ public static void main(String[] args) {
+ m(Foo::new);
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference44.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that generic method reference is inferred when type parameters are omitted
+ * @run main MethodReference44
+ */
+public class MethodReference44 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static class SuperFoo<X> { }
+
+ static class Foo<X extends Number> extends SuperFoo<X> { }
+
+ interface SAM1 {
+ SuperFoo<String> m();
+ }
+
+ interface SAM2 {
+ SuperFoo<Integer> m();
+ }
+
+ interface SAM3 {
+ SuperFoo<Object> m();
+ }
+
+ static <X extends Number> Foo<X> m() { return null; }
+
+ static void g(SAM1 s) { assertTrue(false); }
+ static void g(SAM2 s) { assertTrue(true); }
+ static void g(SAM3 s) { assertTrue(false); }
+
+ public static void main(String[] args) {
+ g(MethodReference44::m);
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference45.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that generic method reference is inferred when type parameters are omitted
+ * @compile/fail/ref=MethodReference45.out -XDrawDiagnostics MethodReference45.java
+ */
+public class MethodReference45 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static class SuperFoo<X> { }
+
+ static class Foo<X extends Number> extends SuperFoo<X> { }
+
+ interface SAM1 {
+ void m();
+ }
+
+ interface SAM2 {
+ void m();
+ }
+
+ static <X extends Number> Foo<X> m() { return null; }
+
+ static void g1(SAM1 s) { }
+ static void g2(SAM1 s) { }
+ static void g2(SAM2 s) { }
+
+ void test() {
+ g1(MethodReference45::m);
+ g2(MethodReference45::m);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference45.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+MethodReference45.java:38:9: compiler.err.ref.ambiguous: g2, kindname.method, g2(MethodReference45.SAM1), MethodReference45, kindname.method, g2(MethodReference45.SAM2), MethodReference45
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference46.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that generic method reference is inferred when type parameters are omitted
+ * @run main MethodReference46
+ */
+public class MethodReference46 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM1 {
+ void m(String s);
+ }
+
+ interface SAM2 {
+ void m(Integer s);
+ }
+
+ interface SAM3 {
+ void m(Object o);
+ }
+
+ static class Foo<X extends Number> {
+ Foo(X x) { }
+ }
+
+ static <X extends Number> void m(X fx) { }
+
+ static void g(SAM1 s) { assertTrue(false); }
+ static void g(SAM2 s) { assertTrue(true); }
+ static void g(SAM3 s) { assertTrue(false); }
+
+ public static void main(String[] args) {
+ g(MethodReference46::m);
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference47.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,40 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that generic method reference is inferred when type parameters are omitted
+ * @compile/fail/ref=MethodReference47.out -XDrawDiagnostics MethodReference47.java
+ */
+public class MethodReference47 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface SAM1 {
+ void m(Integer s);
+ }
+
+ interface SAM2 {
+ void m(Integer s);
+ }
+
+ static class Foo<X extends Number> {
+ Foo(X x) { }
+ }
+
+ static <X extends Number> void m(X fx) { }
+
+ static void g1(SAM1 s) { }
+ static void g2(SAM1 s) { }
+ static void g2(SAM2 s) { }
+
+ public static void main(String[] args) {
+ g1(MethodReference46::m);
+ g2(MethodReference46::m);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference47.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+MethodReference47.java:38:9: compiler.err.ref.ambiguous: g2, kindname.method, g2(MethodReference47.SAM1), MethodReference47, kindname.method, g2(MethodReference47.SAM2), MethodReference47
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference48.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that raw qualifier in unbound method reference is inferred from descriptor
+ * @run main MethodReference48
+ */
+public class MethodReference48 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static class Foo<X> {
+ X m() { return null; };
+ }
+
+ interface SAM1 {
+ Foo<Object> m(Foo<String> fs);
+ }
+
+ interface SAM2 {
+ Integer m(Foo<Integer> fi);
+ }
+
+ interface SAM3 {
+ Object m(Foo<Integer> fi);
+ }
+
+ static void g(SAM1 s) { assertTrue(false); } //return type not compatible
+ static void g(SAM2 s) { assertTrue(true); } //ok
+ static void g(SAM3 s) { assertTrue(false); } //ok but less specific
+
+ public static void main(String[] args) {
+ g(Foo::m);
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference49.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that an array type can be used as a qualifier of an unbound method reference
+ * @run main MethodReference49
+ */
+public class MethodReference49 {
+
+ interface SAM {
+ Object m(int[] i);
+ }
+
+ public static void main(String[] args) {
+ SAM s = int[]::clone;
+ int[] iarr = { 1, 2, 3 };
+ int[] iarr2 = (int[])s.m(iarr);
+ if (iarr == iarr2) {
+ throw new AssertionError();
+ }
+ for (int i = 0 ; i < iarr.length ; i ++) {
+ if (iarr[i] != iarr2[i]) {
+ throw new AssertionError();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference50.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that erroneous method references are flagged with errors as expected
+ * @compile/fail/ref=MethodReference50.out -XDrawDiagnostics MethodReference50.java
+ */
+
+class MethodReference50 {
+
+ interface SAM1 {
+ void m();
+ }
+
+ interface SAM2 {
+ void m();
+ }
+
+ void call(SAM1 s) {}
+ void call(SAM2 s) {}
+
+ {
+ call(NonExistentType::m);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference50.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+MethodReference50.java:23:14: compiler.err.cant.resolve.location: kindname.variable, NonExistentType, , , (compiler.misc.location: kindname.class, MethodReference50, null)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference51.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,46 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * certain cases of erroneous member reference lookup are not handled by Attr.visitReference
+ * @compile/fail/ref=MethodReference51.out -XDrawDiagnostics MethodReference51.java
+ */
+class MethodReference51 {
+
+ private static class Foo {
+ static int j(int i) { return i; }
+ }
+
+ static Foo foo = new Foo();
+
+ static void m(String s) { }
+ static void m(Integer i) { }
+
+ static int f(String s) { return 1; }
+
+ static int g(Integer i, Number n) { return 1; }
+ static int g(Number n, Integer i) { return 1; }
+
+ int h(int i) { return i; }
+}
+
+class TestMethodReference51 {
+
+ interface IntSam {
+ int m(int i);
+ }
+
+ interface IntegerIntegerSam {
+ int m(Integer i1, Integer i2);
+ }
+
+
+ static void test() {
+ IntSam s1 = MethodReference51::unknown; //method not found
+ IntSam s2 = MethodReference51::f; //inapplicable method
+ IntSam s3 = MethodReference51::g; //inapplicable methods
+ IntegerIntegerSam s4 = MethodReference51::g; //ambiguous
+ IntSam s5 = MethodReference51::h; //static error
+ IntSam s6 = MethodReference51.foo::j; //inaccessible method
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference51.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,7 @@
+MethodReference51.java:39:21: compiler.err.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, unknown, , int, (compiler.misc.location: kindname.class, MethodReference51, null))
+MethodReference51.java:40:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, f, java.lang.String, int, kindname.class, MethodReference51, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String))))
+MethodReference51.java:41:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, g, int,{(compiler.misc.inapplicable.method: kindname.method, MethodReference51, g(java.lang.Integer,java.lang.Number), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, MethodReference51, g(java.lang.Number,java.lang.Integer), (compiler.misc.arg.length.mismatch))}))
+MethodReference51.java:42:32: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: g, kindname.method, g(java.lang.Integer,java.lang.Number), MethodReference51, kindname.method, g(java.lang.Number,java.lang.Integer), MethodReference51))
+MethodReference51.java:43:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, h(int)))
+MethodReference51.java:44:21: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.not.def.access.class.intf.cant.access: j(int), MethodReference51.Foo))
+6 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference52.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,39 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * special cases of method references (getClass()/Array.clone()) not handled properly
+ * @compile/fail/ref=MethodReference52.out -XDrawDiagnostics MethodReference52.java
+ */
+import java.util.*;
+
+class MethodReference52 {
+
+ interface Clone1 {
+ int[] m();
+ }
+
+ interface Clone2 {
+ Object m();
+ }
+
+ interface WrongClone {
+ long[] m();
+ }
+
+ interface GetClass {
+ Class<? extends List> m();
+ }
+
+ interface WrongGetClass {
+ Class<List<String>> m();
+ }
+
+ void test(int[] iarr, List<String> ls) {
+ Clone1 c1 = iarr::clone; //ok
+ Clone2 c2 = iarr::clone; //ok - type more generic
+ WrongClone c3 = iarr::clone; //bad return type
+ GetClass c4 = ls::getClass; //ok
+ WrongGetClass c5 = ls::getClass; //bad return type
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference52.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+MethodReference52.java:35:25: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: int[], long[]))
+MethodReference52.java:37:28: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: java.lang.Class<? extends java.util.List>, java.lang.Class<java.util.List<java.lang.String>>))
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference53.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,24 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * the case in which no member reference is found is now treated as a normal error (not dependent on target-type)
+ * @compile/fail/ref=MethodReference53.out -XDrawDiagnostics MethodReference53.java
+ */
+class MethodReference53 {
+
+ interface SAM1 {
+ void m(int i);
+ }
+
+ interface SAM2 {
+ void m(long i);
+ }
+
+ void m(SAM1 s1) { }
+ void m(SAM2 s1) { }
+
+ void test() {
+ m(this::unknown); //should not generate outer resolution diagnostic
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference53.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+MethodReference53.java:22:11: compiler.err.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, unknown, , , (compiler.misc.location: kindname.class, MethodReference53, null))
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference54.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * method call with bad qualifier generates NPE if argument is a method reference
+ * @compile/fail/ref=MethodReference54.out -XDrawDiagnostics MethodReference54.java
+ */
+class MethodReference54 {
+
+ interface SAM {
+ void m();
+ }
+
+ void test() {
+ nonExistent.m(MethodReference54::get);
+ }
+
+ static String get() { return ""; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference54.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+MethodReference54.java:15:9: compiler.err.cant.resolve.location: kindname.variable, nonExistent, , , (compiler.misc.location: kindname.class, MethodReference54, null)
+1 error
--- a/langtools/test/tools/javac/lambda/MethodReferenceParserTest.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReferenceParserTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -24,7 +24,9 @@
/*
* @test
* @bug 7115052
- * @summary Add parser support for method references
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Add parser support for method references
*/
import com.sun.source.util.JavacTask;
@@ -227,7 +229,7 @@
void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
- Arrays.asList("-XDallowMethodReferences"), null, Arrays.asList(source));
+ null, null, Arrays.asList(source));
try {
ct.parse();
} catch (Throwable ex) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific01.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check correctness of structural most specific test routine
+ * @compile/fail/ref=MostSpecific01.out -XDrawDiagnostics MostSpecific01.java
+ */
+
+class Test {
+
+ interface IntMapper {
+ int map();
+ }
+
+ interface LongMapper {
+ long map();
+ }
+
+ void m(IntMapper im, String s) { }
+ void m(LongMapper lm, Integer s) { }
+
+ void test() {
+ m(()->1, null);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific01.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+MostSpecific01.java:23:9: compiler.err.ref.ambiguous: m, kindname.method, m(Test.IntMapper,java.lang.String), Test, kindname.method, m(Test.LongMapper,java.lang.Integer), Test
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific02.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check correctness of structural most specific test routine
+ * @compile/fail/ref=MostSpecific02.out -XDrawDiagnostics MostSpecific02.java
+ */
+
+class Test {
+
+ interface IntMapper {
+ int map();
+ }
+
+ interface LongMapper {
+ long map();
+ }
+
+ void m(IntMapper im, LongMapper s) { }
+ void m(LongMapper lm, IntMapper s) { }
+
+ void test() {
+ m(()->1, ()->1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific02.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+MostSpecific02.java:23:9: compiler.err.ref.ambiguous: m, kindname.method, m(Test.IntMapper,Test.LongMapper), Test, kindname.method, m(Test.LongMapper,Test.IntMapper), Test
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific03.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,63 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check correctness of structural most specific test routine
+ * @compile/fail/ref=MostSpecific03.out -XDrawDiagnostics MostSpecific03.java
+ */
+
+class Test {
+
+ interface IntMapper {
+ int map();
+ }
+
+ interface LongMapper {
+ long map();
+ }
+
+ void m(IntMapper... im) { }
+ void m(LongMapper... lm) { }
+
+ void m2(IntMapper im1, IntMapper... im) { }
+ void m2(LongMapper... lm) { }
+
+ void test1() {
+ m(); //ambiguous
+ m(()->1); //ok
+ m(()->1, ()->1); //ok
+ m(()->1, ()->1, ()->1); //ok
+ }
+
+ void test2() {
+ m(null, null); //ambiguous
+ m(()->1, null); //ambiguous
+ m(null, ()->1); //ambiguous
+ m(()->1L, null); //ok
+ m(null, ()->1L); //ok
+ }
+
+ void test3() {
+ m2(); //ok
+ m2(()->1); //ambiguous
+ m2(()->1, ()->1); //ok
+ m2(()->1, ()->1, ()->1); //ok
+ }
+
+ void test4() {
+ m2(null, null, null); //ambiguous
+ m2(()->1, null, null); //ambiguous
+ m2(null, ()->1, null); //ambiguous
+ m2(null, null, ()->1); //ambiguous
+ m2(()->1, ()->1, null); //ambiguous
+ m2(null, ()->1, ()->1); //ambiguous
+ m2(()->1, null, ()->1); //ambiguous
+
+ m2(()->1L, null, null); //ok
+ m2(null, ()->1L, null); //ok
+ m2(null, null, ()->1L); //ok
+ m2(()->1L, ()->1L, null); //ok
+ m2(null, ()->1L, ()->1L); //ok
+ m2(()->1L, null, ()->1L); //ok
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific03.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,13 @@
+MostSpecific03.java:26:9: compiler.err.ref.ambiguous: m, kindname.method, m(Test.IntMapper...), Test, kindname.method, m(Test.LongMapper...), Test
+MostSpecific03.java:33:9: compiler.err.ref.ambiguous: m, kindname.method, m(Test.IntMapper...), Test, kindname.method, m(Test.LongMapper...), Test
+MostSpecific03.java:34:9: compiler.err.ref.ambiguous: m, kindname.method, m(Test.IntMapper...), Test, kindname.method, m(Test.LongMapper...), Test
+MostSpecific03.java:35:9: compiler.err.ref.ambiguous: m, kindname.method, m(Test.IntMapper...), Test, kindname.method, m(Test.LongMapper...), Test
+MostSpecific03.java:42:9: compiler.err.ref.ambiguous: m2, kindname.method, m2(Test.IntMapper,Test.IntMapper...), Test, kindname.method, m2(Test.LongMapper...), Test
+MostSpecific03.java:48:9: compiler.err.ref.ambiguous: m2, kindname.method, m2(Test.IntMapper,Test.IntMapper...), Test, kindname.method, m2(Test.LongMapper...), Test
+MostSpecific03.java:49:9: compiler.err.ref.ambiguous: m2, kindname.method, m2(Test.IntMapper,Test.IntMapper...), Test, kindname.method, m2(Test.LongMapper...), Test
+MostSpecific03.java:50:9: compiler.err.ref.ambiguous: m2, kindname.method, m2(Test.IntMapper,Test.IntMapper...), Test, kindname.method, m2(Test.LongMapper...), Test
+MostSpecific03.java:51:9: compiler.err.ref.ambiguous: m2, kindname.method, m2(Test.IntMapper,Test.IntMapper...), Test, kindname.method, m2(Test.LongMapper...), Test
+MostSpecific03.java:52:9: compiler.err.ref.ambiguous: m2, kindname.method, m2(Test.IntMapper,Test.IntMapper...), Test, kindname.method, m2(Test.LongMapper...), Test
+MostSpecific03.java:53:9: compiler.err.ref.ambiguous: m2, kindname.method, m2(Test.IntMapper,Test.IntMapper...), Test, kindname.method, m2(Test.LongMapper...), Test
+MostSpecific03.java:54:9: compiler.err.ref.ambiguous: m2, kindname.method, m2(Test.IntMapper,Test.IntMapper...), Test, kindname.method, m2(Test.LongMapper...), Test
+12 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific04.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * Structural most specific doesn't handle cases with wildcards in functional interfaces
+ */
+public class MostSpecific04 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface DoubleMapper<T> {
+ double map(T t);
+ }
+
+ interface LongMapper<T> {
+ long map(T t);
+ }
+
+ static class MyList<E> {
+ void map(DoubleMapper<? super E> m) { assertTrue(false); }
+ void map(LongMapper<? super E> m) { assertTrue(true); }
+ }
+
+ public static void main(String[] args) {
+ MyList<String> ls = new MyList<String>();
+ ls.map(e->e.length());
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific05.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * Structural most specific doesn't handle cases with wildcards in functional interfaces
+ */
+public class MostSpecific05 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface ObjectConverter<T extends Object> {
+ T map(Object o);
+ }
+
+ interface NumberConverter<T extends Number> {
+ T map(Object o);
+ }
+
+ static class MyMapper<A extends Object, B extends Number> {
+ void map(ObjectConverter<? extends A> m) { assertTrue(false); }
+ void map(NumberConverter<? extends B> m) { assertTrue(true); }
+ }
+
+ public static void main(String[] args) {
+ MyMapper<Number, Double> mm = new MyMapper<Number, Double>();
+ mm.map(e->1.0);
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific06.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,30 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * most specific resolution crashes on stuck lambdas
+ * @compile/fail/ref=MostSpecific06.out -XDrawDiagnostics MostSpecific06.java
+ */
+import java.util.*;
+
+class MostSpecific06 {
+
+ interface Predicate<X> {
+ boolean accept(X x);
+ }
+
+ interface ExtPredicate<X> extends Predicate<X> { }
+
+
+
+ void test(boolean cond, ArrayList<String> als) {
+ m(u -> true, als, als);
+ m((u -> true), als, als);
+ m(cond ? u -> true : u -> false, als, als);
+ }
+
+ <U> U m(Predicate<U> p, List<U> lu, ArrayList<U> au) { return null; }
+
+
+ <U> U m(ExtPredicate<U> ep, ArrayList<U> au, List<U> lu) { return null; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific06.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,4 @@
+MostSpecific06.java:21:9: compiler.err.ref.ambiguous: m, kindname.method, <U>m(MostSpecific06.Predicate<U>,java.util.List<U>,java.util.ArrayList<U>), MostSpecific06, kindname.method, <U>m(MostSpecific06.ExtPredicate<U>,java.util.ArrayList<U>,java.util.List<U>), MostSpecific06
+MostSpecific06.java:22:9: compiler.err.ref.ambiguous: m, kindname.method, <U>m(MostSpecific06.Predicate<U>,java.util.List<U>,java.util.ArrayList<U>), MostSpecific06, kindname.method, <U>m(MostSpecific06.ExtPredicate<U>,java.util.ArrayList<U>,java.util.List<U>), MostSpecific06
+MostSpecific06.java:23:9: compiler.err.ref.ambiguous: m, kindname.method, <U>m(MostSpecific06.Predicate<U>,java.util.List<U>,java.util.ArrayList<U>), MostSpecific06, kindname.method, <U>m(MostSpecific06.ExtPredicate<U>,java.util.ArrayList<U>,java.util.List<U>), MostSpecific06
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific07.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,31 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * speculative cache contents are overwritten by deferred type-checking of nested stuck expressions
+ * @compile/fail/ref=MostSpecific07.out -XDrawDiagnostics MostSpecific07.java
+ */
+import java.util.*;
+
+class MostSpecific07 {
+
+ interface Predicate<X, Y> {
+ Y accept(X x);
+ }
+
+ interface VoidMapper {
+ void accept();
+ }
+
+ interface ExtPredicate<X, Y> extends Predicate<X, Y> { }
+
+ void test(boolean cond, ArrayList<String> als, VoidMapper vm) {
+ m(u -> ()->{}, als, als, vm);
+ m((u -> ()->{}), als, als, vm);
+ m(cond ? u -> ()->{} : u -> ()->{}, als, als, vm);
+ }
+
+ <U, V> U m(Predicate<U, V> p, List<U> lu, ArrayList<U> au, V v) { return null; }
+
+ <U, V> U m(ExtPredicate<U, V> ep, ArrayList<U> au, List<U> lu, V v) { return null; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MostSpecific07.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,4 @@
+MostSpecific07.java:23:9: compiler.err.ref.ambiguous: m, kindname.method, <U,V>m(MostSpecific07.Predicate<U,V>,java.util.List<U>,java.util.ArrayList<U>,V), MostSpecific07, kindname.method, <U,V>m(MostSpecific07.ExtPredicate<U,V>,java.util.ArrayList<U>,java.util.List<U>,V), MostSpecific07
+MostSpecific07.java:24:9: compiler.err.ref.ambiguous: m, kindname.method, <U,V>m(MostSpecific07.Predicate<U,V>,java.util.List<U>,java.util.ArrayList<U>,V), MostSpecific07, kindname.method, <U,V>m(MostSpecific07.ExtPredicate<U,V>,java.util.ArrayList<U>,java.util.List<U>,V), MostSpecific07
+MostSpecific07.java:25:9: compiler.err.ref.ambiguous: m, kindname.method, <U,V>m(MostSpecific07.Predicate<U,V>,java.util.List<U>,java.util.ArrayList<U>,V), MostSpecific07, kindname.method, <U,V>m(MostSpecific07.ExtPredicate<U,V>,java.util.ArrayList<U>,java.util.List<U>,V), MostSpecific07
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/NakedThis.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * basic test for capture of non-mutable locals
+ * @author Brian Goetz
+ * @author Maurizio Cimadamore
+ * @compile NakedThis.java
+ */
+
+class NakedThis {
+
+ interface SAM {
+ NakedThis m(int x);
+ }
+
+ SAM s1 = (int x) -> this;
+ SAM s2 = (int x) -> NakedThis.this;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/SourceLevelTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,23 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that lambda features are not enabled with source < 8
+ * @compile/fail/ref=SourceLevelTest.out -XDrawDiagnostics -source 7 SourceLevelTest.java
+ */
+
+class SourceLevelTest {
+ interface I {
+ default void m() { SourceLevelTest.impl(this); }
+ }
+
+ interface SAM {
+ void m();
+ }
+
+ SAM s1 = () -> { };
+ SAM s2 = this::m;
+
+ static void impl(I i) {}
+ void m() {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/SourceLevelTest.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,6 @@
+- compiler.warn.source.no.bootclasspath: 1.7
+SourceLevelTest.java:11:9: compiler.err.default.methods.not.supported.in.source: 1.7
+SourceLevelTest.java:18:17: compiler.err.lambda.not.supported.in.source: 1.7
+SourceLevelTest.java:19:20: compiler.err.method.references.not.supported.in.source: 1.7
+3 errors
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType01.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check nested case of overload resolution and lambda parameter inference
+ * @author Maurizio Cimadamore
+ * @compile TargetType01.java
+ */
+
+class TargetType01 {
+
+ interface Func<A,B> {
+ B call(A a);
+ }
+
+ interface F_I_I extends Func<Integer,Integer> {}
+ interface F_S_S extends Func<String,String> {}
+
+ static Integer M(F_I_I f){ return null; }
+ static String M(F_S_S f){ return null; }
+
+ static {
+ //ambiguity here - the compiler does not try all the combinations!
+ M(x1 -> { return M( x2 -> { return x1 + x2; });});
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType02.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check overload resolution and target type inference w.r.t. generic methods
+ * @author Maurizio Cimadamore
+ * @run main TargetType02
+ */
+
+public class TargetType02 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface S1<X extends Number> {
+ X m(Integer x);
+ }
+
+ interface S2<X extends String> {
+ abstract X m(Integer x);
+ }
+
+ static <Z extends Number> void call(S1<Z> s) { s.m(1); assertTrue(true); }
+ static <Z extends String> void call(S2<Z> s) { s.m(2); assertTrue(false); }
+
+ void test() {
+ call(i -> { toString(); return i; });
+ }
+
+ public static void main(String[] args) {
+ new TargetType02().test();
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType03.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check overload resolution and target type inference w.r.t. generic methods
+ * @author Maurizio Cimadamore
+ * @run main TargetType03
+ */
+import java.util.*;
+
+public class TargetType03 {
+
+ interface Mapper<X,Y> {
+ Y myMap(X a);
+ }
+
+ static class MapperList<A> extends ArrayList<A> {
+ public <B> List<B> myMap(Mapper<A, B> mapper) {
+ ArrayList<B> mappedList = new ArrayList<>();
+ for (A elem : this) {
+ mappedList.add(mapper.myMap(elem));
+ }
+ return mappedList;
+ };
+ }
+
+ public static void main(String[] args) {
+ MapperList<Integer> numbers = new MapperList<>();
+ numbers.add(1);
+ numbers.add(2);
+ numbers.add(3);
+ numbers.add(4);
+ numbers.add(5);
+ List<Integer> sqNumbers = numbers.myMap(a -> a * a);
+ //check invariants
+ if (numbers.size() != sqNumbers.size()) {
+ throw new AssertionError();
+ }
+ for (int i = 0; i < numbers.size() ; i ++) {
+ if (sqNumbers.get(i) != Math.pow(numbers.get(i), 2)) {
+ throw new AssertionError();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType04.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * target typing in assignment context
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=TargetType04.out -XDrawDiagnostics TargetType04.java
+ */
+class TargetType04 {
+
+ interface S<X extends Number, Y extends Number> {
+ Y m(X x);
+ }
+
+ S<Integer, Integer> s1 = i -> { return i; }; //ok
+ S<Double, Integer> s2 = i -> { return i; }; //no
+ S<Integer, Double> s3 = i -> { return i; }; //no
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType04.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+TargetType04.java:16:43: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Double, java.lang.Integer))
+TargetType04.java:17:43: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Integer, java.lang.Double))
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType05.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * test recursion through SAM type
+ * @author Maurizio Cimadamore
+ * @run main TargetType05
+ */
+public class TargetType05 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface Func<A,R> {
+ R call(A a);
+ }
+
+ static Func<Integer, Integer> f;
+
+ public static void main(String[] args) {
+ f = i -> { return i == 1 ? 1 : f.call(i-1) * i; };
+ assertTrue(f.call(5) == 120);
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType06.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,27 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check complex case of target typing
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=TargetType06.out -XDrawDiagnostics TargetType06.java
+ */
+
+import java.util.List;
+
+class TargetType06 {
+
+ class Foo {
+ Foo getFoo() { return null; }
+ }
+
+ interface Function<A,R> {
+ R invoke(A a);
+ }
+
+ static <B> List<B> map(Function<B, B> function) { return null; }
+
+ void test() {
+ List<Foo> l = map(foo -> foo.getFoo());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType06.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TargetType06.java:25:23: compiler.err.cant.apply.symbol: kindname.method, map, TargetType06.Function<B,B>, @510, kindname.class, TargetType06, (compiler.misc.cyclic.inference: B)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType07.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that explicit generic target type parses w/o problems
+ * @author Peter Levart
+ * @author Maurizio Cimadamore
+ * @compile TargetType07.java
+ */
+
+class TargetType07 {
+
+ public interface SAM1<X> { X m(); }
+ public interface SAM2<X> { X m(); }
+
+ public static <X> void call(SAM1<X> s) { }
+ public static <X> void call(SAM2<X> s) { }
+
+ public static void main(String[] args) {
+ call((SAM1<Integer>)()-> 1 );
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType08.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that explicit non-generic target type parses w/o problems
+ * @author Peter Levart
+ * @author Maurizio Cimadamore
+ * @compile TargetType08.java
+ */
+
+class TargetType07 {
+
+ public interface SAM1 { String m(); }
+ public interface SAM2 { Comparable<?> m(); }
+
+ public static void call(SAM1 s) { }
+ public static void call(SAM2 s) { }
+
+ public static void main(String[] args) {
+ call((SAM1)()-> "Hello!" );
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType10.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that wildcards in the target method of a lambda conversion is handled correctly
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=TargetType10.out -XDrawDiagnostics TargetType10.java
+ */
+
+class TargetType10 {
+ interface Function<A,R> {
+ R apply(A a);
+ }
+
+ static class Test {
+ <A,B,C> Function<A,C> compose(Function<B,C> g, Function<A,? extends B> f) { return null; }
+ { compose(x -> "a" + x, x -> x + "b"); }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType10.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TargetType10.java:17:11: compiler.err.cant.apply.symbol: kindname.method, compose, TargetType10.Function<B,C>,TargetType10.Function<A,? extends B>, @500,@515, kindname.class, TargetType10.Test, (compiler.misc.cyclic.inference: B,A)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType11.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that wildcards in the target method of a lambda conversion is handled correctly
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=TargetType11.out -Xlint:unchecked -XDrawDiagnostics TargetType11.java
+ */
+
+class TargetType11 {
+ interface Predicate<X> {
+ boolean apply(X c);
+ }
+
+ static class Test {
+ public <T> Predicate<T> and(Predicate<? super T>... first) { return null; }
+ public Predicate<Character> forPredicate(Predicate<? super Character> predicate) { return null; }
+
+ Predicate<Character> c2 = forPredicate(c -> c.compareTo('e') < 0);
+ Predicate<Integer> k = and(i -> i > 0, i -> i % 2 == 0);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType11.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,4 @@
+TargetType11.java:16:61: compiler.warn.unchecked.varargs.non.reifiable.type: TargetType11.Predicate<? super T>
+TargetType11.java:20:32: compiler.err.cant.apply.symbol: kindname.method, and, TargetType11.Predicate<? super T>[], @706,@718, kindname.class, TargetType11.Test, (compiler.misc.cyclic.inference: T)
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType12.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Flow should not analyze lambda body that contains errors due to partially specified parameter types
+ * @author Maurizio Cimadamore
+ * @compile TargetType12.java
+ */
+
+import java.util.*;
+
+class TargetType12 {
+
+ interface Extractor<X,Y> {
+ Y get(X x);
+ }
+
+ static <T, U extends Comparable<? super U>> void sortBy2(T[] array, Extractor<T, U> extractor) {
+ Comparator<T> comparator = (left,right) -> extractor.get(left).compareTo(extractor.get(right));
+ Arrays.sort(array, comparator);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType13.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * failure to infer exception thrown types from lambda body causes checked exception to be skipped
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=TargetType13.out -XDlambdaInferenceDiags=false -XDrawDiagnostics TargetType13.java
+ */
+
+class TargetType13 {
+
+ interface SAM<E extends Throwable> {
+ void m(Integer x) throws E;
+ }
+
+ static <E extends Throwable> void call(SAM<E> s) throws E { }
+
+ void test() {
+ call(i -> { if (i == 2) throw new Exception(); return; });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType13.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TargetType13.java:19:13: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType14.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that return type is inferred from target type when cyclic inference found
+ * @author Maurizio Cimadamore
+ * @compile/fail/ref=TargetType14.out -XDrawDiagnostics TargetType14.java
+ */
+
+class TargetType14 {
+
+ interface SAM<X> {
+ X m(int i, int j);
+ }
+
+ static void test() {
+ SAM<Integer> s1 = (i, j) -> i + j;
+ m((i, j) -> i + j);
+ SAM<Integer> s2 = m2((i, j) -> i + j); //ok
+ SAM<Integer> s3 = m2((i, j) -> "" + i + j); //no
+ }
+
+ static void m(SAM<Integer> s) { }
+ static <X> SAM<X> m2(SAM<X> s) { return null; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType14.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TargetType14.java:20:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: TargetType14.SAM<java.lang.String>, TargetType14.SAM<java.lang.Integer>)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType15.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * bad target-type inference lead to compiler crash
+ * @author Maurizio Cimadamore
+ * @compile TargetType15.java
+ */
+
+class TargetType15 {
+
+ interface SAM<T> {
+ T foo(T a, T b);
+ }
+
+ void m1(SAM<? extends String> f_1) {}
+ void m2(SAM<? super String> f_2) {}
+ void m3(SAM<?> f_3) {}
+
+ SAM<? extends String> f_1 = (a, b) -> a;
+ SAM<? super String> f_2 = (a, b) -> a;
+ SAM<?> f_3 = (a, b) -> a;
+
+ {
+ m1((a, b) -> a);
+ m2((a, b) -> a);
+ m3((a, b) -> a);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType16.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Check void-compatibility in strict vs. loose conversion contexts
+ * @compile/fail/ref=TargetType16.out -XDrawDiagnostics TargetType16.java
+ */
+
+class TargetType16 {
+
+ interface SAM1 {
+ void m1();
+ }
+
+ interface SAM2<X> {
+ X m2();
+ }
+
+ static void m(SAM1 s1) { }
+ static <T> void m(SAM2<T> s2) { }
+
+ public static void main(String[] args) {
+ m(() -> { throw new AssertionError(); }); //ambiguous
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType16.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TargetType16.java:23:9: compiler.err.ref.ambiguous: m, kindname.method, m(TargetType16.SAM1), TargetType16, kindname.method, <T>m(TargetType16.SAM2<T>), TargetType16
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType17.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that javac recovers succesfully from bad cast conversion to primitive type
+ * @compile/fail/ref=TargetType17.out -XDrawDiagnostics TargetType17.java
+ */
+
+class TargetType17 {
+ interface SAM<X> {
+ boolean m(X x);
+ }
+
+ byte b = (byte) ()-> true;
+ short s = (short) ()-> 1;
+ int i = (int) ()-> 1;
+ long l = (long) ()-> 1L;
+ float f = (float) ()-> 1.0F;
+ double d = (double) ()-> 1.0;
+ char c = (char) ()-> 'c';
+ boolean z = (boolean) ()-> true;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType17.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,9 @@
+TargetType17.java:14:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType17.java:15:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType17.java:16:19: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType17.java:17:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType17.java:18:23: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType17.java:19:25: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType17.java:20:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType17.java:21:27: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+8 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType18.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that javac doesn't crash if implicit lambda parameter is involved in cast
+ * @compile TargetType18.java
+ */
+
+class TargetType18 {
+
+ interface Folder<T> {
+ public T fold(T a, T b);
+ }
+
+
+ public static <T> Folder<T> max() {
+ return (a, b) -> (((Comparable)a).compareTo(b)<0)? b: a;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType19.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * complex case of generic method call with lambda argument where target
+ * is a wildcard SAM
+ * @compile TargetType19.java
+ */
+import java.util.List;
+
+class TargetType19 {
+
+ interface SAM<X> {
+ void f(List<? extends X> i);
+ }
+
+ <Z> void call(SAM<? extends Z> s, Z z) { }
+
+ { call((List<? extends String> p) -> { }, 1); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType19.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TargetType19.java:40:10: compiler.err.invalid.inferred.types: (compiler.misc.no.conforming.assignment.exists: TargetType19.SAM<java.lang.String>, TargetType19.SAM<? extends java.lang.Integer>)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType20.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * complex case of lambda return type that depends on generic method
+ * inference variable
+ * @compile/fail/ref=TargetType20.out -XDrawDiagnostics TargetType20.java
+ */
+import java.util.*;
+
+class TargetType20 {
+
+ interface SAM2<X> {
+ List<X> f();
+ }
+
+ class Test {
+ <Z> void call(SAM2<Z> x, SAM2<Z> y) { }
+ { call(() -> Collections.emptyList(), () -> new ArrayList<String>()); }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType20.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TargetType20.java:19:10: compiler.err.cant.apply.symbol: kindname.method, call, TargetType20.SAM2<Z>,TargetType20.SAM2<Z>, @428,@459, kindname.class, TargetType20.Test, (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.String, java.lang.String,java.lang.Object)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType21.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,33 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that candidates with cyclic type-inference are removed from the
+ * set of applicable methods
+ * @compile/fail/ref=TargetType21.out -XDrawDiagnostics TargetType21.java
+ */
+
+class TargetType21 {
+ interface SAM1 {
+ String m1(Integer n) throws Exception;
+ }
+
+ interface SAM2 {
+ void m2(Integer n);
+ }
+
+ interface SAM3<R,A> {
+ R m3(A n);
+ }
+
+ void call(SAM1 sam) { }
+ void call(SAM2 sam) { }
+ <R,A> void call(SAM3<R,A> sam) { }
+
+ void test() {
+ call(x -> { throw new Exception(); }); //ok - resolves to call(SAM1)
+ call(x -> { System.out.println(""); }); //ok - resolves to call(SAM2)
+ call(x -> { return (Object) null; }); //error - call(SAM3) is not applicable because of cyclic inference
+ call(x -> { return null; }); ////ok - resolves to call(SAM1)
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType21.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+TargetType21.java:28:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, call(TargetType21.SAM2), TargetType21
+TargetType21.java:30:9: compiler.err.cant.apply.symbols: kindname.method, call, @755,{(compiler.misc.inapplicable.method: kindname.method, TargetType21, call(TargetType21.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.String)))),(compiler.misc.inapplicable.method: kindname.method, TargetType21, call(TargetType21.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val)))),(compiler.misc.inapplicable.method: kindname.method, TargetType21, <R,A>call(TargetType21.SAM3<R,A>), (compiler.misc.cyclic.inference: A))}
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType22.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,44 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that candidates with incompatible SAM descriptor args length
+ are removed from the set of applicable methods
+ * @compile/fail/ref=TargetType22.out -Xlint:unchecked -XDrawDiagnostics TargetType22.java
+ */
+
+class TargetType22 {
+
+ interface Sam0 {
+ void m();
+ }
+
+ interface Sam1<A> {
+ void m(A a);
+ }
+
+ interface Sam2<A> {
+ void m(A a1, A a2);
+ }
+
+ interface Sam3<A> {
+ void m(A a1, A a2, A a3);
+ }
+
+ interface SamX<A> {
+ void m(A... as);
+ }
+
+ void call(Sam0 s) { }
+ void call(Sam1<String> s) { }
+ void call(Sam2<String> s) { }
+ void call(Sam3<String> s) { }
+ void call(SamX<String> s) { }
+
+ void test() {
+ call(() -> { });
+ call(a1 -> { }); //ambiguous - both call(Sam1) and call(SamX) match
+ call((a1, a2) -> { });
+ call((a1, a2, a3) -> { });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType22.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,4 @@
+TargetType22.java:29:21: compiler.warn.unchecked.varargs.non.reifiable.type: A
+TargetType22.java:40:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType22.Sam1<java.lang.String>), TargetType22, kindname.method, call(TargetType22.SamX<java.lang.String>), TargetType22
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType23.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,37 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check case of ambiguous method call with lambda whose body cannot
+ complete normally
+ * @compile/fail/ref=TargetType23.out -XDrawDiagnostics TargetType23.java
+ */
+
+class TargetType23 {
+
+ interface Sam0 {
+ void m();
+ }
+
+ interface Sam1 {
+ int m();
+ }
+
+ interface Sam2 {
+ String m();
+ }
+
+ interface Sam3<A> {
+ A m();
+ }
+
+
+ void call(Sam0 s) { }
+ void call(Sam1 s) { }
+ void call(Sam2 s) { }
+ <Z> void call(Sam3<Z> s) { }
+
+ void test() {
+ call(()-> { throw new RuntimeException(); }); //ambiguous - both call(Sam0), call(Sam2), call(Sam3) match
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType23.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TargetType23.java:35:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType23.Sam2), TargetType23, kindname.method, <Z>call(TargetType23.Sam3<Z>), TargetType23
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType24.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,39 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check case of nested method calls with lambda expression
+ * @compile/fail/ref=TargetType24.out -XDrawDiagnostics TargetType24.java
+ */
+
+class TargetType24 {
+
+ interface F<A, B> {
+ B f(A a);
+ }
+
+ interface FSub<A, B> extends F<A,B> { }
+
+ static class Array<A> {
+ boolean forAll(final F<A, Boolean> f) {
+ return false;
+ }
+
+ String forAll(final FSub<A, String> f) {
+ return "";
+ }
+
+ String forAll2(final FSub<A, String> f) {
+ return "";
+ }
+ }
+
+ void test(Array<String> as, final Array<Character> ac) {
+ final boolean b1 = as.forAll(s -> ac.forAll(c -> false)); //ok
+ final String s1 = as.forAll2(s -> ac.forAll2(c -> "")); //ok
+ final boolean b2 = as.forAll(s -> ac.forAll(c -> "" )); //fail
+ final String s2 = as.forAll2(s -> ac.forAll2(c -> false)); //fail
+ final boolean b3 = as.forAll((F<String, Boolean>)s -> ac.forAll((F<Character, Boolean>)c -> "")); //fail
+ final String s3 = as.forAll((FSub<String, String>)s -> ac.forAll((FSub<Character, String>)c -> false)); //fail
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType24.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,5 @@
+TargetType24.java:34:37: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, boolean)
+TargetType24.java:35:45: compiler.err.cant.apply.symbol: kindname.method, forAll2, TargetType24.FSub<java.lang.Character,java.lang.String>, @945, kindname.class, TargetType24.Array<A>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String)))
+TargetType24.java:36:101: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Boolean))
+TargetType24.java:37:104: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: boolean, java.lang.String))
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType25.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that lambda expression can appear in
+ * @compile TargetType25.java
+ */
+
+class TargetType25 {
+
+ interface F<A, B> {
+ B f(A a);
+ }
+
+ <Z> void m1(F<String, Z> f) { }
+ <Z> void m2(F<String, F<String, Z>> f) { }
+ <Z> void m3(F<String, F<String, F<String, Z>>> f) { }
+
+ void testExprLambdaInMethodContext() {
+ m1(s1 -> 1);
+ m2(s1 -> s2 -> 1);
+ m3(s1 -> s2 -> s3 -> 1);
+ }
+
+ void testExprLambdaInAssignmentContext() {
+ F<String, Integer> fn1 = s1 -> 1;
+ F<String, F<String, Integer>> fn2 = s1 -> s2 -> 1;
+ F<String, F<String, F<String, Integer>>> fn3 = s1 -> s2 -> s3 -> 1;
+ }
+
+ void testStatementLambdaInMethodContext() {
+ m1(s1 -> { return 1; });
+ m2(s1 -> { return s2 -> { return 1; }; });
+ m3(s1 -> { return s2 -> { return s3 -> { return 1; }; }; });
+ }
+
+ void testStatementLambdaInAssignmentContext() {
+ F<String, Integer> fn1 = s1 -> { return 1; };
+ F<String, F<String, Integer>> fn2 = s1 -> { return s2 -> { return 1; }; };
+ F<String, F<String, F<String, Integer>>> fn3 = s1 -> { return s2 -> { return s3 -> { return 1; }; }; };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType26.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * case of cyclic type inference (lambda passed where inference var expected)
+ * @compile/fail/ref=TargetType26.out -XDrawDiagnostics TargetType26.java
+ */
+
+class TargetType26 {
+ interface SAM {
+ void m();
+ }
+
+ <Z> void call(Z z) { }
+
+ { call(() -> { }); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType26.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TargetType26.java:16:7: compiler.err.cant.apply.symbol: kindname.method, call, Z, @340, kindname.class, TargetType26, (compiler.misc.cyclic.inference: Z)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType27.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * complex case of cyclic type inference (lambda returned where inference var expected)
+ * @compile/fail/ref=TargetType27.out -XDrawDiagnostics TargetType27.java
+ * @compile/fail/ref=TargetType27.out -XDrawDiagnostics -XDcomplexinference TargetType27.java
+ */
+
+class TargetType27 {
+ interface F<X, Y> {
+ Y f(X a);
+ }
+
+ <A, R> F<A, R> m(F<A, R> f) { return null; }
+
+ void test() {
+ m((String s1) -> (String s2) -> new Integer(1));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType27.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TargetType27.java:18:9: compiler.err.cant.apply.symbol: kindname.method, m, TargetType27.F<A,R>, @490, kindname.class, TargetType27, (compiler.misc.cyclic.inference: R)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType28.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,23 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * target type inference in a case where lambda expression returns diamond
+ * @compile/fail/ref=TargetType28.out -XDrawDiagnostics TargetType28.java
+ */
+
+class TargetType28 {
+ static class SuperFoo<X> {}
+
+ static class Foo<X extends Number> extends SuperFoo<X> {}
+
+ interface A<X, Y> {
+ SuperFoo<Y> m(X x);
+ }
+
+ <Z, R> SuperFoo<R> apply(A<Z, R> ax, Z x) { return null; }
+
+ SuperFoo<String> ls = apply(x-> new Foo<>(), 1);
+ SuperFoo<Integer> li = apply(x-> new Foo<>(), 1);
+ SuperFoo<?> lw = apply(x-> new Foo<>(), 1);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType28.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+TargetType28.java:20:32: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: TargetType28.SuperFoo<java.lang.Number>, TargetType28.SuperFoo<java.lang.String>)
+TargetType28.java:21:33: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: TargetType28.SuperFoo<java.lang.Number>, TargetType28.SuperFoo<java.lang.Integer>)
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType29.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check type-substitution in SAM type wildcards inference
+ * @compile TargetType29.java
+ */
+
+import java.util.*;
+
+class TargetType29 {
+ interface Reducer<E, V> {
+ public V reduce(E element, V value);
+ }
+
+ private static <E> int reduce(Iterable<? extends E> iterable, Reducer<? super E, Integer> reducer) { return 0; }
+
+ void test(List<Integer> li) {
+ reduce(li, (e, v) -> e + v);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType30.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that target type is propagated through parenthesized expressions
+ * @compile TargetType30.java
+ */
+
+class TargetType30 {
+
+ interface SAM {
+ void m(int x);
+ }
+
+ void m(SAM s) { }
+
+ void testAssignmentContext() {
+ SAM s1 = (x-> { System.out.println("Hello!"); });
+ SAM s2 = ((x-> { System.out.println("Hello!"); }));
+ SAM s3 = (((x-> { System.out.println("Hello!"); })));
+ }
+
+ void testMethodContext() {
+ m((x-> { System.out.println("Hello!"); }));
+ m(((x-> { System.out.println("Hello!"); })));
+ m((((x-> { System.out.println("Hello!"); }))));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType31.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * check that target type of a cast is propagated through parenthesized expressions
+ * @compile TargetType31.java
+ */
+
+class TargetType31 {
+
+ interface SAM {
+ void m(int x);
+ }
+
+ void m(SAM s) { }
+
+ void testAssignmentContext() {
+ SAM s1 = (SAM)(x-> { System.out.println("Hello!"); });
+ SAM s2 = (SAM)((x-> { System.out.println("Hello!"); }));
+ SAM s3 = (SAM)(((x-> { System.out.println("Hello!"); })));
+ }
+
+ void testMethodContext() {
+ m((SAM)(x-> { System.out.println("Hello!"); }));
+ m((SAM)((x-> { System.out.println("Hello!"); })));
+ m((SAM)(((x-> { System.out.println("Hello!"); }))));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType32.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * target-typing and conditional operator
+ */
+
+public class TargetType32 {
+
+ interface A<X> {
+ X m();
+ }
+
+ interface B<X> extends A<X> {}
+
+ void m(A<Integer> a) { }
+ void m(B<String> b) { }
+
+ <Z extends Integer> void m2(A<Z> a) { }
+ <Z extends String> void m2(B<Z> b) { }
+
+ void m3(A<TargetType32> a) { }
+ void m3(B<String> b) { }
+
+ <Z> void m4(A<Z> a) { }
+ <Z extends String> void m4(B<Z> b) { }
+
+ int intRes() { return 42; }
+
+ void testLambda(boolean flag) {
+ A<Integer> c = flag ? (() -> 23) : (() -> 42);
+ m(flag ? (() -> 23) : (() -> 42));
+ m2(flag ? (() -> 23) : (() -> 23));
+ }
+
+ void testMethodRef(boolean flag) {
+ A<Integer> c = flag ? this::intRes : this::intRes;
+ m(flag ? this::intRes : this::intRes);
+ m2(flag ? this::intRes : this::intRes);
+ }
+
+ void testConstrRef(boolean flag) {
+ A<TargetType32> c = flag ? TargetType32::new : TargetType32::new;
+ m3(flag ? TargetType32::new : TargetType32::new);
+ m4(flag ? TargetType32::new : TargetType32::new);
+ }
+
+ public static void main(String[] args) {
+ TargetType32 test = new TargetType32();
+ test.testLambda(true);
+ test.testMethodRef(true);
+ test.testConstrRef(true);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType33.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * crash when incompatible method reference is found in conditional expression
+ * @compile/fail/ref=TargetType33.out -XDrawDiagnostics TargetType33.java
+ */
+
+class TargetType33 {
+
+ interface A<X> {
+ X m();
+ }
+
+ void m(A<Integer> a) { }
+ <Z> void m2(A<Z> a) { }
+
+ int intRes(Object o) { return 42; }
+
+ void testMethodRef(boolean flag) {
+ A<Integer> c = flag ? this::intRes : this::intRes;
+ m(flag ? this::intRes : this::intRes);
+ m2(flag ? this::intRes : this::intRes);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType33.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,5 @@
+TargetType33.java:21:31: compiler.err.prob.found.req: (compiler.misc.incompatible.type.in.conditional: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, intRes, java.lang.Object, compiler.misc.no.args, kindname.class, TargetType33, (compiler.misc.arg.length.mismatch))))
+TargetType33.java:21:46: compiler.err.prob.found.req: (compiler.misc.incompatible.type.in.conditional: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, intRes, java.lang.Object, compiler.misc.no.args, kindname.class, TargetType33, (compiler.misc.arg.length.mismatch))))
+TargetType33.java:22:9: compiler.err.cant.apply.symbol: kindname.method, m, TargetType33.A<java.lang.Integer>, @509, kindname.class, TargetType33, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.type.in.conditional: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, intRes, java.lang.Object, compiler.misc.no.args, kindname.class, TargetType33, (compiler.misc.arg.length.mismatch)))))
+TargetType33.java:23:9: compiler.err.cant.apply.symbol: kindname.method, m2, TargetType33.A<Z>, @557, kindname.class, TargetType33, (compiler.misc.infer.no.conforming.assignment.exists: Z, (compiler.misc.incompatible.type.in.conditional: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, intRes, java.lang.Object, compiler.misc.no.args, kindname.class, TargetType33, (compiler.misc.arg.length.mismatch)))))
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType34.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * spurious resolution diagnostics when diamond constructor contains poly expression
+ * @compile -XDcomplexinference TargetType34.java
+ */
+
+class TargetType34<X> {
+
+ TargetType34(X x) {}
+
+ Object next;
+
+ void test() {
+ new TargetType34<>(next==null ? null : null);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType35.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * missing erasure on intersection supertype of generated lambda class
+ */
+public class TargetType35 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface A {}
+
+ interface B {}
+
+ static class C implements A, B {}
+
+ static class D implements A, B {}
+
+ interface SAM<Y, X> {
+ Y invoke(X arg);
+ }
+
+ static class Sup {
+ <Z> Z m(Z z) { return z; }
+ }
+
+ static class Sub extends Sup {
+ <Z> Z m(Z z) { return z; }
+
+ void test(C c, D d) {
+ choose(c, d, x->x);
+ choose(c, d, this::m);
+ choose(c, d, super::m);
+ }
+
+ <T> void choose(T t1, T t2, SAM<T, T> t3) {
+ assertTrue(true);
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new Sub().test(null, null);
+ assertTrue(assertionCount == 3);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType36.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 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
+ * @ignore
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that target type of cast is propagated to conditional subexpressions
+ * @compile TargetType36.java
+ */
+class TargetType36 { //awaits spec wording on cast vs. poly
+
+ interface SAM {
+ int m(int i, int j);
+ }
+
+ void test() {
+ SAM s1 = (SAM)((a,b)->a+b);
+ SAM s2 = (SAM)(true? (SAM)((a,b)->a+b) : (SAM)((a,b)->a+b));
+ SAM s3 = (SAM)(true? (a,b)->a+b : (a,b)->a+b);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType37.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that cast conversion context is propagated to conditional subexpressions
+ * @compile TargetType37.java
+ */
+class TargetType37 {
+
+ interface I { }
+
+ void test(Object o, boolean cond) {
+ I i = (I)(cond ? o : o);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType38.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that cast conversion context does not affect compatibility of lambda
+ * @compile/fail/ref=TargetType38.out -XDrawDiagnostics TargetType38.java
+ */
+class TargetType38 {
+
+ interface I { }
+
+ interface SAM {
+ I m();
+ }
+
+ static Object m() { return null; }
+
+ void test() {
+ Object o1 = (SAM)()->new Object();
+ Object o2 = (SAM)TargetType38::m;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType38.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+TargetType38.java:19:30: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, TargetType38.I))
+TargetType38.java:20:26: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: java.lang.Object, TargetType38.I))
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType39.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that type-checking fails because of recursive analysis of stuck expressions
+ * @compile/fail/ref=TargetType39.out -XDrawDiagnostics TargetType39.java
+ */
+class TargetType39 {
+
+ interface I { }
+
+ interface SAM<A, R> {
+ R m(A a);
+ }
+
+ <U, V> void call(SAM<U, V> s) { }
+
+ void test(boolean cond, SAM<String, Void> ssv) {
+ call(cond ? x-> null : ssv);
+ call((String s)-> cond ? x-> null : ssv);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType39.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+TargetType39.java:19:9: compiler.err.cant.apply.symbol: kindname.method, call, TargetType39.SAM<U,V>, @442, kindname.class, TargetType39, (compiler.misc.cyclic.inference: U)
+TargetType39.java:20:9: compiler.err.cant.apply.symbol: kindname.method, call, TargetType39.SAM<U,V>, @479, kindname.class, TargetType39, (compiler.misc.cyclic.inference: V)
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType40.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * compiler silently crashes when void method is passed as argument in overloaded call site
+ * @compile/fail/ref=TargetType40.out -XDrawDiagnostics TargetType40.java
+ */
+
+class TargetType40 {
+ void m(String s) { }
+ void m(Integer i) { }
+
+ void void_method() {}
+
+ void test() {
+ m(void_method());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType40.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TargetType40.java:16:21: compiler.err.void.not.allowed.here
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType41.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * out-of-order method checking should check as many arguments as possible
+ * @compile/fail/ref=TargetType41.out -XDrawDiagnostics TargetType41.java
+ */
+
+class TargetType41 {
+ <X> void m(String s, java.util.List<String> lx) { }
+
+ void test() {
+ m(1, new java.util.ArrayList<>());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType41.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TargetType41.java:13:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.String,java.util.List<java.lang.String>, int,java.util.ArrayList<java.lang.Object>, kindname.class, TargetType41, (compiler.misc.infer.no.conforming.assignment.exists: X, (compiler.misc.inconvertible.types: int, java.lang.String))
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType42.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * effects of speculative attribution are undone on a per-argument basis rather than on a per-resolution basis
+ * @compile TargetType42.java
+ */
+class TargetType42 {
+
+ interface SAM<X, Y> {
+ Y f(X x);
+ }
+
+ <Z> void m(SAM<String, SAM<Z, Object>> s, Z z) { }
+
+ void test(Object obj) {
+ m((x)->{ class Foo { }; return (x2)-> { new Foo(); return null; }; }, obj);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType43.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * recovery attribution step for unchecked arguments
+ * @compile/fail/ref=TargetType43.out -XDrawDiagnostics TargetType43.java
+ */
+class TargetType43 {
+
+ void m(Object o) { }
+
+ void test(Object obj) {
+ Object o = x-> { new NonExistentClass(x); return 5; };
+ m(x-> { new NonExistentClass(x); return 5; });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType43.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,5 @@
+TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+TargetType43.java:13:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
+TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf))
+TargetType43.java:14:21: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType44.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,27 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * compiler throw AssertionError while backtracing from speculative attribution round
+ * @compile/fail/ref=TargetType44.out -XDrawDiagnostics TargetType44.java
+ */
+class TargetType44 {
+
+ interface Unary {
+ void m(int i1);
+ }
+
+ interface Binary {
+ void m(int i1, int i2);
+ }
+
+ void m(Unary u) { }
+ void m(Binary u) { }
+
+ void test() {
+ m(()-> { new Object() { }; }); //fail
+ m(x -> { new Object() { }; }); //ok
+ m((x, y) -> { new Object() { }; }); //ok
+ m((x, y, z) -> { new Object() { }; }); //fail
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType44.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+TargetType44.java:22:9: compiler.err.cant.apply.symbols: kindname.method, m, @458,{(compiler.misc.inapplicable.method: kindname.method, TargetType44, m(TargetType44.Unary), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.lambda))),(compiler.misc.inapplicable.method: kindname.method, TargetType44, m(TargetType44.Binary), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.lambda)))}
+TargetType44.java:25:9: compiler.err.cant.apply.symbols: kindname.method, m, @597,{(compiler.misc.inapplicable.method: kindname.method, TargetType44, m(TargetType44.Unary), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.lambda))),(compiler.misc.inapplicable.method: kindname.method, TargetType44, m(TargetType44.Binary), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.lambda)))}
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType45.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,29 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * compiler crashes during flow analysis as it fails to report diagnostics during attribution
+ * @compile/fail/ref=TargetType45.out -XDrawDiagnostics TargetType45.java
+ */
+class TargetType45 {
+
+ interface Predicate<X> {
+ boolean apply(X x);
+ }
+
+ interface Mapper<X, Y> {
+ Y apply(X x);
+ }
+
+ class Foo<X> {
+ Foo<X> filter(Predicate<? super X> p) { return null; }
+ }
+
+ static <U, V> Predicate<U> compose(Predicate<? super V> pi, Mapper<? super U, ? extends V> m) { return null; }
+
+ static Predicate<Integer> isOdd = i -> i % 2 != 0;
+
+ void top10Counties(Foo<String> foos) {
+ foos.filter(compose(isOdd, (String e) -> e.length()));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType45.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TargetType45.java:27:28: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: U,V, (compiler.misc.inconvertible.types: TargetType45.Mapper<java.lang.String,java.lang.Integer>, TargetType45.Mapper<? super java.lang.Object,? extends java.lang.Integer>))
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType46.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,29 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * compiler doesn't report accessibility problem due to inaccessible target
+ * @compile/fail/ref=TargetType46.out -XDrawDiagnostics TargetType46.java
+ */
+import java.util.*;
+
+class TargetType46Outer {
+
+ private interface PI {
+ void m();
+ }
+
+ void m(PI p) { }
+ void m(List<PI> p) { }
+}
+
+class TargetType46 {
+ void test(TargetType46Outer outer) {
+ outer.m(()->{}); //access error
+ outer.m(this::g); //access error
+ outer.m(new ArrayList<>()); //ok
+ outer.m(Collections.emptyList()); //ok
+ }
+
+ void g() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType46.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+TargetType46.java:22:17: compiler.err.report.access: TargetType46Outer.PI, private, TargetType46Outer
+TargetType46.java:23:17: compiler.err.report.access: TargetType46Outer.PI, private, TargetType46Outer
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType47.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * spurious functional interface conversion errors with default methods in target type
+ * @compile TargetType47.java
+ */
+
+class TargetType47 {
+ interface A {
+ void a();
+ void b();
+ default void c() { };
+ }
+
+ interface B extends A {
+ default void b() { };
+ }
+
+ B b = ()-> {};
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType48.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * spurious functional interface conversion errors with default methods in target type
+ * @compile TargetType48.java
+ */
+
+class TargetType48 {
+ interface I1 {
+ void a();
+ void b();
+ void c();
+ }
+
+ interface I2 extends I1 {
+ default void a() { }
+ }
+
+ interface I3 extends I2 {
+ default void b() { }
+ }
+
+ I3 i3 = ()->{ };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType49.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * javac accepts ill-formed lambda/method reference targets
+ * @compile/fail/ref=TargetType49.out -XDrawDiagnostics TargetType49.java
+ */
+class TargetType49 {
+
+ interface F {
+ default Object clone() { return null; }
+ void m();
+ }
+
+ F f1 = ()->{};
+ F f2 = this::g;
+
+ void g() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType49.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+TargetType49.java:15:12: compiler.err.override.weaker.access: (compiler.misc.cant.implement: clone(), java.lang.Object, clone(), TargetType49.F), public
+TargetType49.java:16:12: compiler.err.override.weaker.access: (compiler.misc.cant.implement: clone(), java.lang.Object, clone(), TargetType49.F), public
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType50.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,28 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * bad stuck check for method reference leads to javac crash
+ * @compile/fail/ref=TargetType50.out -XDrawDiagnostics TargetType50.java
+ */
+import java.util.*;
+
+class TargetType50 {
+
+ interface Factory<F> {
+ F make();
+ }
+
+ static class Sink<T> {
+ static <Z> Sink<Z> make() { return null; }
+ }
+
+ <Y, S extends Sink<Y>> List<Y> m(Factory<S> factory) { }
+
+ void test() {
+ List<?> l1 = m(Sink::new);
+ List<?> l2 = m(Sink::make);
+ List<String> l3 = m(Sink::new);
+ List<String> l4 = m(Sink::make);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TargetType50.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+TargetType50.java:25:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.String, java.lang.String,java.lang.Object)
+TargetType50.java:26:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.String, java.lang.String,java.lang.Object)
+2 errors
--- a/langtools/test/tools/javac/lambda/TestInvokeDynamic.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/lambda/TestInvokeDynamic.java Fri Nov 30 17:09:05 2012 -0800
@@ -25,7 +25,9 @@
* @test
* @bug 7194586
*
- * @summary Add back-end support for invokedynamic
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Add back-end support for invokedynamic
*
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/TestSelfRef.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * Check that self/forward references from lambda expressions behave
+ * consistently w.r.t. local inner classes
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+public class TestSelfRef {
+
+ static int checkCount = 0;
+
+ enum RefKind {
+ SELF_LAMBDA("SAM s = x->{ System.out.println(s); };", true, false),
+ FORWARD_LAMBDA("SAM s = x->{ System.out.println(f); };\nObject f = null;", false, true),
+ SELF_ANON("Object s = new Object() { void test() { System.out.println(s); } };", true, false),
+ FORWARD_ANON("Object s = new Object() { void test() { System.out.println(f); } }; Object f = null;", false, true);
+
+ String refStr;
+ boolean selfRef;
+ boolean forwardRef;
+
+ private RefKind(String refStr, boolean selfRef, boolean forwardRef) {
+ this.refStr = refStr;
+ this.selfRef = selfRef;
+ this.forwardRef = forwardRef;
+ }
+ }
+
+ enum EnclosingKind {
+ TOPLEVEL("class C { #S }"),
+ MEMBER_INNER("class Outer { class C { #S } }"),
+ NESTED_INNER("class Outer { static class C { #S } }");
+
+ String enclStr;
+
+ private EnclosingKind(String enclStr) {
+ this.enclStr = enclStr;
+ }
+ }
+
+ enum InnerKind {
+ NONE("#R"),
+ LOCAL_NONE("class Local { #R }"),
+ LOCAL_MTH("class Local { void test() { #R } }"),
+ ANON_NONE("new Object() { #R };"),
+ ANON_MTH("new Object() { void test() { #R } };");
+
+ String innerStr;
+
+ private InnerKind(String innerStr) {
+ this.innerStr = innerStr;
+ }
+
+ boolean inMethodContext(SiteKind sk) {
+ switch (this) {
+ case LOCAL_MTH:
+ case ANON_MTH: return true;
+ case NONE: return sk != SiteKind.NONE;
+ default:
+ return false;
+ }
+ }
+ }
+
+ enum SiteKind {
+ NONE("#I"),
+ STATIC_INIT("static { #I }"),
+ INSTANCE_INIT("{ #I }"),
+ CONSTRUCTOR("C() { #I }"),
+ METHOD("void test() { #I }");
+
+ String siteStr;
+
+ private SiteKind(String siteStr) {
+ this.siteStr = siteStr;
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+
+ //create default shared JavaCompiler - reused across multiple compilations
+ JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+ for (EnclosingKind ek : EnclosingKind.values()) {
+ for (SiteKind sk : SiteKind.values()) {
+ if (sk == SiteKind.STATIC_INIT && ek == EnclosingKind.MEMBER_INNER)
+ continue;
+ for (InnerKind ik : InnerKind.values()) {
+ if (ik != InnerKind.NONE && sk == SiteKind.NONE)
+ break;
+ for (RefKind rk : RefKind.values()) {
+ new TestSelfRef(ek, sk, ik, rk).run(comp, fm);
+ }
+ }
+ }
+ }
+ System.out.println("Total check executed: " + checkCount);
+ }
+
+ EnclosingKind ek;
+ SiteKind sk;
+ InnerKind ik;
+ RefKind rk;
+ JavaSource source;
+ DiagnosticChecker diagChecker;
+
+ TestSelfRef(EnclosingKind ek, SiteKind sk, InnerKind ik, RefKind rk) {
+ this.ek = ek;
+ this.sk = sk;
+ this.ik = ik;
+ this.rk = rk;
+ this.source = new JavaSource();
+ this.diagChecker = new DiagnosticChecker();
+ }
+
+ class JavaSource extends SimpleJavaFileObject {
+
+ String bodyTemplate = "interface SAM { void test(Object o); }\n#B";
+ String source;
+
+ public JavaSource() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ source = bodyTemplate.replace("#B",
+ ek.enclStr.replace("#S", sk.siteStr.replace("#I", ik.innerStr.replace("#R", rk.refStr))));
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+ JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+ null, null, Arrays.asList(source));
+ try {
+ ct.analyze();
+ } catch (Throwable ex) {
+ throw new AssertionError("Error thron when compiling the following code:\n" + source.getCharContent(true));
+ }
+ check();
+ }
+
+ void check() {
+ //illegal forward ref
+ boolean errorExpected = ik.inMethodContext(sk) &&
+ (rk.selfRef || rk.forwardRef);
+ if (diagChecker.errorFound != errorExpected) {
+ throw new Error("invalid diagnostics for source:\n" +
+ source.getCharContent(true) +
+ "\nFound error: " + diagChecker.errorFound +
+ "\nExpected error: " + errorExpected);
+ }
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ errorFound = true;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/VoidCompatibility.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,26 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * check that that void compatibility affects overloading as expected
+ * @compile/fail/ref=VoidCompatibility.out -XDrawDiagnostics VoidCompatibility.java
+ */
+class VoidCompatibility {
+
+ interface Runnable { void run(); } //1
+ interface Thunk<T> { T get(); } //2
+
+ void schedule(Runnable r) { }
+ void schedule(Thunk<?> t) { }
+
+ void test() {
+ schedule(() -> System.setProperty("done", "true")); //2
+ schedule(() -> { System.setProperty("done", "true"); }); //1
+ schedule(() -> { return System.setProperty("done", "true"); }); //2
+ schedule(() -> System.out.println("done")); //1
+ schedule(() -> { System.out.println("done"); }); //1
+ schedule(Thread::yield); //1
+ schedule(Thread::getAllStackTraces); //ambiguous
+ schedule(Thread::interrupted); //1 (most specific)
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/VoidCompatibility.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+VoidCompatibility.java:23:9: compiler.err.ref.ambiguous: schedule, kindname.method, schedule(VoidCompatibility.Runnable), VoidCompatibility, kindname.method, schedule(VoidCompatibility.Thunk<?>), VoidCompatibility
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/abort/Abort.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * check that all diagnostics are dumped to output when compiler exits abruptly
+ */
+
+import com.sun.source.util.JavacTask;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URL;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+public class Abort {
+
+ public static void main(String... args) throws Exception {
+
+ String SCRATCH_DIR = System.getProperty("user.dir");
+ JavaCompiler javacTool = ToolProvider.getSystemJavaCompiler();
+ java.io.File testDir = new java.io.File(SCRATCH_DIR);
+
+ sourceA.dumpTo(testDir);
+ sourceB.dumpTo(testDir);
+
+ DiagnosticChecker diagChecker = new DiagnosticChecker();
+ JavacTask ct = (JavacTask)javacTool.getTask(null, null, diagChecker,
+ Arrays.asList("-XDrawDiagnostics", "-cp", testDir.getAbsolutePath()),
+ null, Arrays.asList(sourceA.asJFO(testDir)));
+ try {
+ ct.analyze();
+ } catch (Throwable ex) {
+ //ignore abort exception thrown by javac
+ }
+
+ if (!diagChecker.errorFound) {
+ throw new AssertionError("Missing diagnostic");
+ }
+ }
+
+ static class JavaSource {
+ String contents;
+ String filename;
+
+ public JavaSource(String filename, String contents) {
+ this.filename = filename;
+ this.contents = contents;
+ }
+
+ void dumpTo(java.io.File loc) throws Exception {
+ java.io.File file = new java.io.File(loc, filename);
+ java.io.BufferedWriter bw = new java.io.BufferedWriter(new java.io.FileWriter(file));
+ bw.append(contents);
+ bw.close();
+ }
+
+ SimpleJavaFileObject asJFO(java.io.File dir) {
+ return new SimpleJavaFileObject(new java.io.File(dir, filename).toURI(), JavaFileObject.Kind.SOURCE) {
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ return contents;
+ }
+ };
+ }
+ }
+
+ static JavaSource sourceA = new JavaSource("Abort.java", "public class Abort {\n" +
+ " public static void main(String[] args) {\n" +
+ " System.out.println(C.m());\n" +
+ " }\n" +
+ "}");
+
+ static JavaSource sourceB = new JavaSource("C.java", "package com.example;\n" +
+ "public class C {\n" +
+ " public static String m() { return null; }\n" +
+ "}");
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
+ diagnostic.getCode().contains("compiler.err.cant.access")) {
+ errorFound = true;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/badMemberRefBytecode/Main.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,9 @@
+import java.util.Collections;
+
+public class Main {
+
+ public static void main(String[] args) {
+ Collections.<String>sort(null, String::compareTo);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/badMemberRefBytecode/TestBadMemberRefBytecode.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010, 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 8003280
+ * @summary Add lambda tests
+ * check that classfiles with member ref CP entries are read correctly
+ * @author Jan Lahoda
+ * @compile Main.java
+ * @compile Use.java
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/badMemberRefBytecode/Use.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+public class Use {
+ private Main m;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/Helper.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+
+/*SAM types:
+ 1. An interface that has a single abstract method
+ 2. Having more than one distinct methods, but only one is "real", the others are overriden public methods in Object - example: Comparator<T>
+ 3. Having more than one methods due to inheritance, but they have the same signature
+ 4. Having more than one methods due to inheritance, but one of them has a subsignature of all other methods
+ a) parameter types compatible
+ b) return type substitutable
+ c) thrown type not conflicting with the thrown clause of any other method
+ d) mixed up
+ 5. Type-dependent SAM types
+ non-SAM types:
+ 6. An interface that has a single abstract method, which is also public method in Object
+ 7. Having more than one methods due to inheritance, and none of them has a subsignature of all other methods
+*/
+
+import java.util.List;
+import java.util.Collection;
+import java.sql.SQLException;
+import java.sql.SQLTransientException;
+import java.util.concurrent.TimeoutException;
+import java.io.*;
+
+interface A {int getOldest(List<Number> list);}
+interface B {int getOldest(List list);}
+interface C {int getOldest(List<?> list);}
+interface D {int getOldest(List<Integer> list);}
+interface E {int getOldest(Collection<?> collection);}
+//Not SAM type, case #7
+interface DE extends D, E {}
+
+interface Foo {int getAge(Number n);}
+interface Bar {int getAge(Integer i);}
+//Not SAM type, case #7
+interface FooBar extends Foo, Bar {}
+
+//Not SAM type, case #6
+interface Planet {boolean equals(Object o);}
+
+// SAM type interfaces:
+// type #2:
+//only one abstract non-Ojbect method getAge()
+interface Mars<T> extends Planet {int getAge(T t);}
+//only one abstract non-Ojbect method increment()
+interface Jupiter {
+ boolean equals(Object o);
+ String toString();
+ int increment(int i);
+}
+
+// type #3:
+interface X {int getTotal(List<String> arg);}
+interface Y {int getTotal(List<String> strs);}
+//SAM type ([List<String>], int, {})
+interface XY extends X, Y {}
+//SAM type ([List<String>], int, {})
+interface XYZ extends X, Y, XY {}
+
+// type #4 a):
+//SAM type ([List], int, {})
+interface AB extends A, B {}
+
+// type #4 b):
+interface F {Number getValue(String str);}
+interface G {Integer getValue(String str);}
+interface H {Serializable getValue(String str);}
+interface I {Object getValue(String str);}
+//SAM type ([String], Integer, {})
+interface FGHI extends F, G, H, I {}
+
+interface J {List<Number> getAll(String str);}
+interface K {List<?> getAll(String str);}
+interface L {List getAll(String str);}
+interface M {Collection getAll(String str);}
+//SAM type ([String], List<Number>/List, {}) - the return type is flexible to some degree
+interface JK extends J, K {}
+//SAM type ([String], List<Number>/List, {})
+interface JL extends J, L {}
+//SAM type ([String], List<Number>/List, {})
+interface JKL extends J, K, L {}
+//SAM type ([String], List<Number>/List, {})
+interface JKLM extends J, K, L, M {}
+
+// type #4 c):
+interface N {String getText(File f) throws IOException;}
+interface O {String getText(File f) throws FileNotFoundException;}
+interface P {String getText(File f) throws NullPointerException;}
+//SAM type ([File], String, {FileNotFoundException})
+interface NO extends N, O {}
+//SAM type ([File], String, {})
+interface NOP extends N, O, P {}
+
+interface Boo {int getAge(String s) throws IOException;}
+interface Doo {int getAge(String s) throws SQLException;}
+//SAM type ([String], int, {})
+interface BooDoo extends Boo, Doo {}
+
+// type #4 d):
+interface Q {Iterable m(Iterable<String> arg);}
+interface R {Iterable<String> m(Iterable arg);}
+//SAM type ([Iterable], Iterable<String>/Iterable, {})
+interface QR extends Q, R {}
+
+interface U {Collection foo(List<String> arg) throws IOException, SQLTransientException;}
+interface V {List<?> foo(List<String> arg) throws EOFException, SQLException, TimeoutException;}
+interface W {List<String> foo(List arg) throws Exception;}
+//SAM type ([List<String>], List<String>/List, {EOFException, SQLTransientException})
+interface UV extends U, V {}
+// SAM type ([List], List<String>/List, {EOFException, SQLTransientException})
+interface UVW extends U, V, W {}
+
+// type #5:
+// Not a SAM because sam-ness depends on instantiation of type-variables
+interface Qoo<T> {void m(T arg);}
+interface Roo<S extends Number> {void m(S arg);}
+interface QooRoo<T1, T2 extends Number, T3> extends Qoo<T1>, Roo<T2> {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest1.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * This test is for lambda expressions
+ * @compile LambdaTest1.java
+ * @run main LambdaTest1
+ */
+
+import java.util.Collections;
+import java.util.List;
+import java.util.ArrayList;
+
+public class LambdaTest1 {
+ public static void main(String[] args) {
+
+ LambdaTest1 test = new LambdaTest1();
+
+ test.method2((int n) -> { });
+ test.method2((int n) -> { });
+ test.method2((int n) -> { return; }); // ";" is mandatory here
+ test.method2((int n) -> { System.out.println(n); }); // ";" is optional here
+ test.method2(n -> { System.out.println(n); }); //warning, explict type required for n?
+
+ test.method3(()-> { System.out.println("implementing VoidVoid.vvMethod()"); });
+ test.method3(() -> {});
+
+ test.method4(()-> 42);
+ test.method4(()-> { return 42; });//";" is mandatory here
+
+ test.method5((int n)-> n+1);
+ test.method5((int n) -> 42);
+ test.method5((int n) -> { return 42; });
+ test.method5(
+ (int n) -> { //"{" optional here
+ if(n > 0)
+ return n++;
+ else
+ return n--;
+ }
+ );
+
+ Runnable r = ()-> { System.out.println("Runnable.run() method implemented"); };
+ r.run();
+ ((Runnable)()-> { System.out.println("Runnable.run() method implemented"); }).run();
+ }
+
+ void method2(VoidInt a) {
+ System.out.println("method2()");
+ final int N = 1;
+ int n = 2; //effectively final variable
+ System.out.println("method2() \"this\":" + this);
+ ((Runnable)
+ ()->{
+ System.out.println("inside lambda \"this\":" + this);
+ System.out.println("inside lambda accessing final variable N:" + N);
+ System.out.println("inside lambda accessing effectively final variable n:" + n);
+ }
+ ).run();
+ //n++; //compile error if n is modified
+ a.viMethod(2);
+ }
+
+ void method3(VoidVoid a) {
+ System.out.println("method3()");
+ a.vvMethod();
+ }
+
+ void method4(IntVoid a) {
+ System.out.println("method4()");
+ System.out.println(a.ivMethod());
+ }
+
+ void method5(IntInt a) {
+ System.out.println("method5()");
+ System.out.println(a.iiMethod(5));
+ }
+
+
+ //SAM type interfaces
+ interface VoidInt {
+ void viMethod(int n);
+ }
+
+ interface VoidVoid {
+ void vvMethod();
+ }
+
+ interface IntVoid {
+ int ivMethod();
+ }
+
+ interface IntInt {
+ int iiMethod(int n);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest1_neg1.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * This test is to verify invalid lambda expressions
+ * @compile/fail/ref=LambdaTest1_neg1.out -XDrawDiagnostics LambdaTest1_neg1.java
+ */
+
+import java.util.Comparator;
+
+public class LambdaTest1_neg1 {
+ void method() {
+ Comparator<Number> c = (Number n1, Number n2) -> { 42; } //compile error, not a statement
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest1_neg1.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+LambdaTest1_neg1.java:13:60: compiler.err.not.stmt
+LambdaTest1_neg1.java:13:65: compiler.err.expected: ';'
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest1_neg2.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * This test is to verify mis-use of accessing "this" from within lambda expression
+ * @compile/fail/ref=LambdaTest1_neg2.out -XDrawDiagnostics LambdaTest1_neg2.java
+ */
+
+public class LambdaTest1_neg2 {
+ static void method() {
+ ((Runnable)
+ ()-> {
+ Object o = this; //use "this" inside lambda expression which is inside a static method, not allowed
+ }
+ ).run();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest1_neg2.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+LambdaTest1_neg2.java:13:28: compiler.err.non-static.cant.be.ref: kindname.variable, this
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest1_neg3.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * This test is to verify mis-use of capturing local variable within lambda expression
+ * @compile/fail/ref=LambdaTest1_neg3.out -XDrawDiagnostics LambdaTest1_neg3.java
+ */
+
+public class LambdaTest1_neg3 {
+ void method() {
+ int n = 2; //effectively final variable
+ ((Runnable)
+ ()-> {
+ int n2 = n; //inside lambda accessing effectively final variable;
+ }
+ ).run();
+ n++; //compile error if n is modified
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest1_neg3.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+LambdaTest1_neg3.java:14:26: compiler.err.cant.ref.non.effectively.final.var: n, (compiler.misc.lambda)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_SAM1.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * This test is for identifying SAM types 2 and 3, see Helper.java for SAM types
+ * @compile LambdaTest2_SAM1.java Helper.java
+ * @run main LambdaTest2_SAM1
+ */
+
+import java.util.Collections;
+import java.util.List;
+import java.util.ArrayList;
+import java.io.*;
+
+public class LambdaTest2_SAM1 {
+ private static List<String> strs = new ArrayList<String>();
+ private static List<File> files = new ArrayList<File>();
+
+ public static void main(String[] args) {
+ strs.add("copy");
+ strs.add("paste");
+ strs.add("delete");
+ strs.add("rename");
+
+ files.add(new File("a.txt"));
+ files.add(new File("c.txt"));
+ files.add(new File("b.txt"));
+
+ //type #2: Comparator<T>
+ Collections.sort(files, (File f1, File f2) -> f1.getName().compareTo(f2.getName()));
+ for(File f : files)
+ System.out.println(f.getName());
+ System.out.println();
+ Collections.sort(files, (File f1, File f2) -> (int)(f1.length() - f2.length()));
+ for(File f : files)
+ System.out.println(f.getName() + " " + f.length());
+ System.out.println();
+
+ LambdaTest2_SAM1 test = new LambdaTest2_SAM1();
+
+ //type #2:
+ test.methodMars((File f) -> {
+ System.out.println("implementing Mars<File>.getAge(File f)...");
+ return (int)f.length();
+ });
+ test.methodJupiter((int n) -> n+1);
+
+ //type #3:
+ test.methodXY((List<String> strList) -> strList.size() );
+ test.methodXYZ((List<String> strList) -> 20 );
+ }
+
+ //type #2:
+ void methodMars(Mars<File> m) {
+ System.out.println("methodMars(): SAM type interface Mars object instantiated: " + m);
+ System.out.println(m.getAge(new File("a.txt")));
+ }
+
+ //type #2:
+ void methodJupiter(Jupiter j) {
+ System.out.println("methodJupiter(): SAM type interface Jupiter object instantiated: " + j);
+ System.out.println(j.increment(33));
+ }
+
+ //type #3:
+ void methodXY(XY xy) {
+ System.out.println("methodXY(): SAM type interface XY object instantiated: " + xy);
+ System.out.println(xy.getTotal(strs));
+ }
+
+ //type #3:
+ void methodXYZ(XYZ xyz) {
+ System.out.println("methodXYZ(): SAM type interface XYZ object instantiated: " + xyz);
+ System.out.println(xyz.getTotal(strs));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_SAM2.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * This test is for identifying SAM types #4, see Helper.java for SAM types
+ * @compile LambdaTest2_SAM2.java Helper.java
+ * @run main LambdaTest2_SAM2
+ */
+
+import java.util.Collection;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.concurrent.TimeoutException;
+import java.io.*;
+import java.sql.SQLException;
+import java.sql.SQLTransientException;
+
+public class LambdaTest2_SAM2 {
+ private static List<String> strs = new ArrayList<String>();
+
+ public static void main(String[] args) {
+ strs.add("copy");
+ strs.add("paste");
+ strs.add("delete");
+ strs.add("rename");
+
+ LambdaTest2_SAM2 test = new LambdaTest2_SAM2();
+
+ //type #4 a):
+ test.methodAB((List list) -> 100);
+
+ //type #4 b):
+ test.methodFGHI((String s) -> new Integer(22));
+ //type #4 b):
+ test.methodJK((String s) -> new ArrayList<Number>());
+ test.methodJK((String s) -> new ArrayList());
+ //type #4 b):
+ test.methodJL((String s) -> new ArrayList<Number>());
+ test.methodJL((String s) -> new ArrayList());
+ //type #4 b):
+ test.methodJKL((String s) -> new ArrayList<Number>());
+ test.methodJKL((String s) -> new ArrayList());
+ //type #4 b):
+ test.methodJKLM((String s) -> new ArrayList<Number>());
+ test.methodJKLM((String s) -> new ArrayList());
+
+ // tyep #4 c):
+ test.methodNO((File f) -> {
+ String temp = null;
+ StringBuffer sb = new StringBuffer();
+ try
+ {
+ BufferedReader br = new BufferedReader(new FileReader(f));
+ while((temp=br.readLine()) != null)
+ sb.append(temp).append("\n");
+ }
+ catch(FileNotFoundException fne){throw fne;}
+ catch(IOException e){e.printStackTrace();}
+ return sb.toString();
+ });
+ // tyep #4 c):
+ test.methodNOP((File f) -> {
+ String temp = null;
+ StringBuffer sb = new StringBuffer();
+ try
+ {
+ BufferedReader br = new BufferedReader(new FileReader(f));
+ while((temp=br.readLine()) != null)
+ sb.append(temp).append("\n");
+ }
+ catch(IOException e){e.printStackTrace();}
+ return sb.toString();
+ });
+ // type #4 c):
+ test.methodBooDoo((String s) -> s.length());
+
+ //type #4 d):
+ test.methodQR((Iterable i) -> new ArrayList<String>());
+ test.methodQR((Iterable i) -> new ArrayList());
+ //type #4 d):
+ test.methodUV((List<String> list) -> {
+ test.exceptionMethod1();
+ test.exceptionMethod2();
+ return new ArrayList<String>();
+ });
+ test.methodUV((List<String> list) -> {
+ test.exceptionMethod1();
+ test.exceptionMethod2();
+ return new ArrayList();
+ });
+ //type #4 d):
+ test.methodUVW((List list) -> {
+ test.exceptionMethod1();
+ test.exceptionMethod2();
+ return new ArrayList<String>();
+ });
+ test.methodUVW((List list) -> {
+ test.exceptionMethod1();
+ test.exceptionMethod2();
+ return new ArrayList();
+ });
+ }
+
+ private void exceptionMethod1() throws EOFException{
+ }
+
+ private void exceptionMethod2() throws SQLTransientException{
+ }
+
+ //type #4 a): SAM type ([List], int, {})
+ void methodAB (AB ab) {
+ System.out.println("methodAB(): SAM type interface AB object instantiated: " + ab);
+ System.out.println(ab.getOldest(strs));
+ }
+
+ //type #4 b): SAM type ([String], Integer, {})
+ void methodFGHI(FGHI f) {
+ System.out.println("methodFGHI(): SAM type interface FGHI object instantiated: " + f);
+ System.out.println(f.getValue("str"));
+ }
+
+ //type #4 b): SAM type ([String], List<Number>, {})
+ void methodJK(JK jk) {
+ System.out.println("methodJK(): SAM type interface JK object instantiated: " + jk);
+ for(Number n : jk.getAll("in"))
+ System.out.println(n);
+ }
+
+ //type #4 b): SAM type ([String], List<Number>, {})
+ void methodJL(JL jl) {
+ System.out.println("methodJL(): SAM type interface JL object instantiated: " + jl);
+ for(Number n : ((J)jl).getAll("in")) //cast should be redundant - see 7062745
+ System.out.println(n);
+ }
+
+ //type #4 b): SAM type ([String], List<Number>, {})
+ void methodJKL(JKL jkl) { //commented - see 7062745
+ System.out.println("methodJKL(): SAM type interface JKL object instantiated: " + jkl);
+ for(Number n : ((J)jkl).getAll("in"))
+ System.out.println(n);
+ }
+
+ //type #4 b): SAM type ([String], List<Number>, {})
+ void methodJKLM(JKLM jklm) { //commented - see 7062745
+ System.out.println("methodJKLM(): SAM type interface JKLM object instantiated: " + jklm);
+ for(Number n : ((J)jklm).getAll("in"))
+ System.out.println(n);
+ }
+
+ //type #4 c): SAM type ([File], String, {FileNotFoundException})
+ void methodNO(NO no) {
+ System.out.println("methodNO(): SAM type interface \"NO\" object instantiated: " + no);
+ try {
+ System.out.println("text=" + no.getText(new File("a.txt")));
+ System.out.println("got here, no exception thrown");
+ }
+ catch(FileNotFoundException e){e.printStackTrace();}
+ }
+
+ //type #4 c): SAM type ([File]), String, {})
+ void methodNOP(NOP nop) {
+ System.out.println("methodNOP(): SAM type interface \"NOP\" object instantiated: " + nop);
+ System.out.println("text=" + nop.getText(new File("a.txt")));
+ }
+
+ //type #4 c): SAM type ([String], int, {})
+ void methodBooDoo(BooDoo bd) {
+ System.out.println("methodBooDoo(): SAM type interface BooDoo object instantiated: " + bd);
+ System.out.println("result=" + bd.getAge("lambda"));
+ }
+
+ //type #4 d): SAM type ([Iterable], Iterable<String>, {})
+ void methodQR(QR qr) {
+ System.out.println("methodQR(): SAM type interface QR object instantiated: " + qr);
+ System.out.println("Iterable returned: " + qr.m(new SQLException()));
+ }
+
+ //type #4 d): SAM type ([List<String>], List<String>/List, {EOFException, SQLTransientException})
+ void methodUV(UV uv) {
+ System.out.println("methodUV(): SAM type interface UV object instantiated: " + uv);
+ try{
+ System.out.println("result returned: " + uv.foo(strs));
+ }catch(EOFException e){
+ System.out.println(e.getMessage());
+ }catch(SQLTransientException ex){
+ System.out.println(ex.getMessage());
+ }
+ }
+
+ //type #4 d): SAM type ([List], List<String>/List, {EOFException, SQLTransientException})
+ void methodUVW(UVW uvw) {
+ System.out.println("methodUVW(): SAM type interface UVW object instantiated: " + uvw);
+ try{
+ System.out.println("passing List<String>: " + uvw.foo(strs));
+ System.out.println("passing List: " + uvw.foo(new ArrayList()));
+ }catch(EOFException e){
+ System.out.println(e.getMessage());
+ }catch(SQLTransientException ex){
+ System.out.println(ex.getMessage());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_SAM3.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * This test is for identifying SAM types #5 and instantiating non-SAM types #7 through inner class,
+ see Helper.java for SAM types
+ * @compile LambdaTest2_SAM3.java Helper.java
+ * @run main LambdaTest2_SAM3
+ */
+
+import java.util.Collection;
+import java.util.List;
+import java.util.ArrayList;
+
+public class LambdaTest2_SAM3 {
+ private static List<String> strs = new ArrayList<String>();
+ private static List<Integer> integers = new ArrayList<Integer>();
+
+ public static void main(String[] args) {
+ LambdaTest2_SAM3 test = new LambdaTest2_SAM3();
+
+ //type #7, Not SAM-convertible, through inner class only:
+ test.methodFooBar(new FooBar() {
+ public int getAge(Number n) {
+ System.out.println("getAge(Number n) called");
+ return 100;
+ }
+ public int getAge(Integer i) {
+ System.out.println("getAge(Integer i) called");
+ return 200;
+ }
+ }
+ );
+
+ //type #7:
+ test.methodDE(new DE(){
+ public int getOldest(List<Integer > list) {
+ System.out.println("getOldest(List<Integer> list) called");
+ return 100;
+ }
+ public int getOldest(Collection<?> collection) {
+ System.out.println("getOldest(Collection<?> collection) called");
+ return 200;
+ }
+ }
+ );
+
+ }
+
+ //type #7: Not SAM type
+ void methodFooBar(FooBar fb) {
+ System.out.println("methodFooBar(): interface FooBar object instantiated: " + fb);
+ System.out.println("result=" + fb.getAge(new Byte("10")));
+ System.out.println("result=" + fb.getAge(new Integer(10)));
+ }
+
+ //type #7: Not SAM type
+ void methodDE (DE de) {
+ System.out.println("methodDE(): interface DE object instantiated: " + de);
+ System.out.println(de.getOldest(integers));
+ System.out.println(de.getOldest(strs));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_neg1.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * This test is for identifying SAM types #5 and instantiating non-SAM types #7 through inner class,
+ see Helper.java for SAM types
+ * @compile/fail/ref=LambdaTest2_neg1.out -XDrawDiagnostics LambdaTest2_neg1.java Helper.java
+ */
+
+public class LambdaTest2_neg1 {
+
+ public static void main(String[] args) {
+ LambdaTest2_neg1 test = new LambdaTest2_neg1();
+ //not convertible - QooRoo is not a SAM
+ test.methodQooRoo((Integer i) -> { });
+ }
+
+ void methodQooRoo(QooRoo<Integer, Integer, Void> qooroo) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/LambdaTest2_neg1.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+LambdaTest2_neg1.java:15:13: compiler.err.cant.apply.symbol: kindname.method, methodQooRoo, QooRoo<java.lang.Integer,java.lang.Integer,java.lang.Void>, @531, kindname.class, LambdaTest2_neg1, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, QooRoo)))
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM1.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * This test is for identifying a non-SAM type 6: An interface that has a single abstract method, which is also public method in Object
+ * @compile/fail/ref=NonSAM1.out -XDrawDiagnostics NonSAM1.java Helper.java
+ */
+
+public class NonSAM1 {
+ void method() {
+ Planet n = (Object o) -> true;
+ System.out.println("never reach here " + n);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM1.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+NonSAM1.java:11:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, Planet))
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM2.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * This test is for identifying a non-SAM type: Having more than one methods due to inheritance, and none of them has a subsignature of all other methods
+ * @compile/fail/ref=NonSAM2.out -XDrawDiagnostics NonSAM2.java Helper.java
+ */
+
+import java.util.List;
+
+interface Foo1 { int getAge(String s);}
+interface Bar1 { Integer getAge(String s);}
+interface Foo1Bar1 extends Foo1, Bar1 {} //types Bar1 and Foo1 are incompatible; both define getAge(String), but with unrelated return types
+
+interface AC extends A, C {} //name clash: getOldest(List<?>) in C and getOldest(List<Number>) in A have the same erasure, yet neither overrides the other
+interface ABC extends A, B, C {} //name clash: getOldest(List<?>) in C and getOldest(List<Number>) in A have the same erasure, yet neither overrides the other
+interface AD extends A, D {} //name clash: getOldest(List<Integer>) in D and getOldest(List<Number>) in A have the same erasure, yet neither overrides the other
+
+interface Foo2<T> { void m(T arg);}
+interface Bar2<S> { void m(S arg);}
+interface Foo2Bar2<T1, T2> extends Foo2<T1>, Bar2<T2> {} //name clash: m(S) in Bar and m(T) in Foo have the same erasure, yet neither overrides the other
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM2.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,6 @@
+NonSAM2.java:13:1: compiler.err.types.incompatible.diff.ret: Bar1, Foo1, getAge(java.lang.String)
+NonSAM2.java:15:1: compiler.err.name.clash.same.erasure.no.override: getOldest(java.util.List<?>), C, getOldest(java.util.List<java.lang.Number>), A
+NonSAM2.java:16:1: compiler.err.name.clash.same.erasure.no.override: getOldest(java.util.List<?>), C, getOldest(java.util.List<java.lang.Number>), A
+NonSAM2.java:17:1: compiler.err.name.clash.same.erasure.no.override: getOldest(java.util.List<java.lang.Integer>), D, getOldest(java.util.List<java.lang.Number>), A
+NonSAM2.java:21:1: compiler.err.name.clash.same.erasure.no.override: m(S), Bar2, m(T), Foo2
+5 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM3.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,24 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * This test is for identifying a non-SAM type: Having overloaded methods due to inheritance
+ * @compile/fail/ref=NonSAM3.out -XDrawDiagnostics NonSAM3.java Helper.java
+ */
+
+import java.util.Collection;
+import java.util.List;
+
+public class NonSAM3 {
+ void method() {
+ //all of the following will have compile error: "the target type of a lambda conversion has multiple non-overriding abstract methods"
+ FooBar fb = (Number n) -> 100;
+ FooBar fb2 = (Integer i) -> 100;
+ DE de = (List<Integer> list) -> 100;
+ DE de2 = (List<?> list) -> 100;
+ DE de3 = (List list) -> 100;
+ DE de4 = (Collection<Integer> collection) -> 100;
+ DE de5 = (Collection<?> collection) -> 100;
+ DE de6 = (Collection collection) -> 100;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM3.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,9 @@
+NonSAM3.java:15:21: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
+NonSAM3.java:16:22: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, FooBar))
+NonSAM3.java:17:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:18:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:19:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:20:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:21:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+NonSAM3.java:22:18: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.incompatible.abstracts: kindname.interface, DE))
+8 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/InInterface.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng InInterface
+ */
+
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+interface LTII {
+
+ interface ILsp1 {
+ String m();
+ }
+
+ interface ILsp2 {
+ String m(String x);
+ }
+
+ default ILsp1 t1() {
+ return () -> { return "yo"; };
+ }
+
+ default ILsp2 t2() {
+ return (x) -> { return "snur" + x; };
+ }
+
+}
+
+@Test
+public class InInterface implements LTII {
+
+ public void testLambdaInDefaultMethod() {
+ assertEquals(t1().m(), "yo");
+ assertEquals(t2().m("p"), "snurp");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/InnerConstructor.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng InnerConstructor
+ */
+
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+@Test
+public class InnerConstructor {
+
+ public void testLambdaWithInnerConstructor() {
+ assertEquals(seq1().m().toString(), "Cbl:nada");
+ assertEquals(seq2().m("rats").toString(), "Cbl:rats");
+ }
+
+ Ib1 seq1() {
+ return () -> { return new Cbl(); };
+ }
+
+ Ib2 seq2() {
+ return (x) -> { return new Cbl(x); };
+ }
+
+ class Cbl {
+ String val;
+
+ Cbl() {
+ this.val = "nada";
+ }
+
+ Cbl(String z) {
+ this.val = z;
+ }
+
+ public String toString() {
+ return "Cbl:" + val;
+ }
+ }
+
+ interface Ib1 {
+ Object m();
+ }
+
+ interface Ib2 {
+ Object m(String x);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/LambdaTranslationTest1.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng LambdaTranslationTest1
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class LambdaTranslationTest1 extends LT1Sub {
+
+ String cntxt = "blah";
+
+ private static final ThreadLocal<Object> result = new ThreadLocal<>();
+
+ private static void setResult(Object s) { result.set(s); }
+ private static void appendResult(Object s) { result.set(result.get().toString() + s); }
+
+ private static void assertResult(String expected) {
+ assertEquals(result.get().toString(), expected);
+ }
+
+ static Integer count(String s) {
+ return s.length();
+ }
+
+ static int icount(String s) {
+ return s.length();
+ }
+
+ static void eye(Integer i) {
+ setResult(String.format("I:%d", i));
+ }
+
+ static void ieye(int i) {
+ setResult(String.format("i:%d", i));
+ }
+
+ static void deye(double d) {
+ setResult(String.format("d:%f", d));
+ }
+
+ public void testLambdas() {
+ TBlock<Object> b = t -> {setResult("Sink0::" + t);};
+ b.apply("Howdy");
+ assertResult("Sink0::Howdy");
+
+ TBlock<String> b1 = t -> {setResult("Sink1::" + t);};
+ b1.apply("Rowdy");
+ assertResult("Sink1::Rowdy");
+
+ for (int i = 5; i < 10; ++i) {
+ TBlock<Integer> b2 = t -> {setResult("Sink2::" + t);};
+ b2.apply(i);
+ assertResult("Sink2::" + i);
+ }
+
+ TBlock<Integer> b3 = t -> {setResult("Sink3::" + t);};
+ for (int i = 900; i > 0; i -= 100) {
+ b3.apply(i);
+ assertResult("Sink3::" + i);
+ }
+
+ cntxt = "blah";
+ TBlock<String> b4 = t -> {setResult(String.format("b4: %s .. %s", cntxt, t));};
+ b4.apply("Yor");
+ assertResult("b4: blah .. Yor");
+
+ String flaw = "flaw";
+ TBlock<String> b5 = t -> {setResult(String.format("b5: %s .. %s", flaw, t));};
+ b5.apply("BB");
+ assertResult("b5: flaw .. BB");
+
+ cntxt = "flew";
+ TBlock<String> b6 = t -> {setResult(String.format("b6: %s .. %s .. %s", t, cntxt, flaw));};
+ b6.apply("flee");
+ assertResult("b6: flee .. flew .. flaw");
+
+ TBlock<String> b7 = t -> {setResult(String.format("b7: %s %s", t, this.protectedSuperclassMethod()));};
+ b7.apply("this:");
+ assertResult("b7: this: instance:flew");
+
+ TBlock<String> b8 = t -> {setResult(String.format("b8: %s %s", t, super.protectedSuperclassMethod()));};
+ b8.apply("super:");
+ assertResult("b8: super: I'm the sub");
+
+ TBlock<String> b7b = t -> {setResult(String.format("b9: %s %s", t, protectedSuperclassMethod()));};
+ b7b.apply("implicit this:");
+ assertResult("b9: implicit this: instance:flew");
+
+ TBlock<Object> b10 = t -> {setResult(String.format("b10: new LT1Thing: %s", (new LT1Thing(t)).str));};
+ b10.apply("thing");
+ assertResult("b10: new LT1Thing: thing");
+
+ TBlock<Object> b11 = t -> {setResult(String.format("b11: %s", (new LT1Thing(t) {
+ String get() {
+ return "*" + str.toString() + "*";
+ }
+ }).get()));};
+ b11.apply(999);
+ assertResult("b11: *999*");
+ }
+
+ public void testMethodRefs() {
+ LT1IA ia = LambdaTranslationTest1::eye;
+ ia.doit(1234);
+ assertResult("I:1234");
+
+ LT1IIA iia = LambdaTranslationTest1::ieye;
+ iia.doit(1234);
+ assertResult("i:1234");
+
+ LT1IA da = LambdaTranslationTest1::deye;
+ da.doit(1234);
+ assertResult("d:1234.000000");
+
+ LT1SA a = LambdaTranslationTest1::count;
+ assertEquals((Integer) 5, a.doit("howdy"));
+
+ a = LambdaTranslationTest1::icount;
+ assertEquals((Integer) 6, a.doit("shower"));
+ }
+
+ public void testInner() throws Exception {
+ (new In()).doInner();
+ }
+
+ protected String protectedSuperclassMethod() {
+ return "instance:" + cntxt;
+ }
+
+ private class In {
+
+ private int that = 1234;
+
+ void doInner() {
+ TBlock<String> i4 = t -> {setResult(String.format("i4: %d .. %s", that, t));};
+ i4.apply("=1234");
+ assertResult("i4: 1234 .. =1234");
+
+ TBlock<String> i5 = t -> {setResult(""); appendResult(t); appendResult(t);};
+ i5.apply("fruit");
+ assertResult("fruitfruit");
+
+ cntxt = "human";
+ TBlock<String> b4 = t -> {setResult(String.format("b4: %s .. %s", cntxt, t));};
+ b4.apply("bin");
+ assertResult("b4: human .. bin");
+
+ final String flaw = "flaw";
+
+/**
+ Callable<String> c5 = () -> "["+flaw+"]" ;
+ System.out.printf("c5: %s\n", c5.call() );
+ **/
+
+ TBlock<String> b5 = t -> {setResult(String.format("b5: %s .. %s", flaw, t));};
+ b5.apply("BB");
+ assertResult("b5: flaw .. BB");
+
+ cntxt = "borg";
+ TBlock<String> b6 = t -> {setResult(String.format("b6: %s .. %s .. %s", t, cntxt, flaw));};
+ b6.apply("flee");
+ assertResult("b6: flee .. borg .. flaw");
+
+ TBlock<String> b7b = t -> {setResult(String.format("b7b: %s %s", t, protectedSuperclassMethod()));};
+ b7b.apply("implicit outer this");
+ assertResult("b7b: implicit outer this instance:borg");
+
+ /**
+ TBlock<Object> b9 = t -> { System.out.printf("New: %s\n", (new LT1Thing(t)).str); };
+ b9.apply("thing");
+
+ TBlock<Object> ba = t -> { System.out.printf("Def: %s\n", (new LT1Thing(t) { String get() { return "*" + str.toString() +"*";}}).get() ); };
+ ba.apply(999);
+
+ */
+ }
+ }
+}
+
+class LT1Sub {
+ protected String protectedSuperclassMethod() {
+ return "I'm the sub";
+ }
+}
+
+class LT1Thing {
+ final Object str;
+
+ LT1Thing(Object s) {
+ str = s;
+ }
+}
+
+interface LT1SA {
+ Integer doit(String s);
+}
+
+interface LT1IA {
+ void doit(int i);
+}
+
+interface LT1IIA {
+ void doit(Integer i);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/LambdaTranslationTest2.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng LambdaTranslationTest2
+ */
+
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * LambdaTranslationTest2 -- end-to-end smoke tests for lambda evaluation
+ */
+
+@Test
+public class LambdaTranslationTest2 {
+
+ final String dummy = "dummy";
+
+ public void testLambdas() {
+ TPredicate<String> isEmpty = s -> s.isEmpty();
+ assertTrue(isEmpty.test(""));
+ assertTrue(!isEmpty.test("foo"));
+
+ TPredicate<Object> oIsEmpty = s -> ((String) s).isEmpty();
+ assertTrue(oIsEmpty.test(""));
+ assertTrue(!oIsEmpty.test("foo"));
+
+ TPredicate<Object> alwaysTrue = o -> true;
+ assertTrue(alwaysTrue.test(""));
+ assertTrue(alwaysTrue.test(null));
+
+ TPredicate<Object> alwaysFalse = o -> false;
+ assertTrue(!alwaysFalse.test(""));
+ assertTrue(!alwaysFalse.test(null));
+
+ // tests local capture
+ String foo = "foo";
+ TPredicate<String> equalsFoo = s -> s.equals(foo);
+ assertTrue(!equalsFoo.test(""));
+ assertTrue(equalsFoo.test("foo"));
+
+ // tests instance capture
+ TPredicate<String> equalsDummy = s -> s.equals(dummy);
+ assertTrue(!equalsDummy.test(""));
+ assertTrue(equalsDummy.test("dummy"));
+
+ TMapper<Object, Object> ident = s -> s;
+
+ assertEquals("blarf", ident.map("blarf"));
+ assertEquals("wooga", ident.map("wooga"));
+ assertTrue("wooga" == ident.map("wooga"));
+
+ // constant capture
+ TMapper<Object, Object> prefixer = s -> "p" + s;
+ assertEquals("pblarf", prefixer.map("blarf"));
+ assertEquals("pwooga", prefixer.map("wooga"));
+
+ // instance capture
+ TMapper<Object, Object> prefixer2 = s -> dummy + s;
+ assertEquals("dummyblarf", prefixer2.map("blarf"));
+ assertEquals("dummywooga", prefixer2.map("wooga"));
+ }
+
+ interface Factory<T> {
+ T make();
+ }
+
+ interface StringFactory extends Factory<String> { }
+
+ interface StringFactory2 extends Factory<String> {
+ String make();
+ }
+
+ public void testBridges() {
+ Factory<String> of = () -> "y";
+ Factory<?> ef = () -> "z";
+
+ assertEquals("y", of.make());
+ assertEquals("y", ((Factory<?>) of).make());
+ assertEquals("y", ((Factory) of).make());
+
+ assertEquals("z", ef.make());
+ assertEquals("z", ((Factory) ef).make());
+ }
+
+ public void testBridgesImplicitSpecialization() {
+ StringFactory sf = () -> "x";
+
+ assertEquals("x", sf.make());
+ assertEquals("x", ((Factory<String>) sf).make());
+ assertEquals("x", ((Factory<?>) sf).make());
+ assertEquals("x", ((Factory) sf).make());
+ }
+
+ public void testBridgesExplicitSpecialization() {
+ StringFactory2 sf = () -> "x";
+
+ assertEquals("x", sf.make());
+ assertEquals("x", ((Factory<String>) sf).make());
+ assertEquals("x", ((Factory<?>) sf).make());
+ assertEquals("x", ((Factory) sf).make());
+ }
+
+ public void testSuperCapture() {
+ class A {
+ String make() { return "x"; }
+ }
+
+ class B extends A {
+ void testSuperCapture() {
+ StringFactory sf = () -> super.make();
+ assertEquals("x", sf.make());
+ }
+ }
+
+ new B().testSuperCapture();
+ }
+
+ interface WidenD {
+ public String m(float a0, double a1);
+ }
+
+ interface WidenS {
+ public String m(byte a0, short a1);
+ }
+
+ interface WidenI {
+ public String m(byte a0, short a1, char a2, int a3);
+ }
+
+ interface WidenL {
+ public String m(byte a0, short a1, char a2, int a3, long a4);
+ }
+
+ interface Box {
+ public String m(byte a0, short a1, char a2, int a3, long a4, boolean a5, float a6, double a7);
+ }
+
+ static String pb(Byte a0, Short a1, Character a2, Integer a3, Long a4, Boolean a5, Float a6, Double a7) {
+ return String.format("b%d s%d c%c i%d j%d z%b f%f d%f", a0, a1, a2, a3, a4, a5, a6, a7);
+ }
+
+ static String pwI1(int a0, int a1, int a2, int a3) {
+ return String.format("b%d s%d c%d i%d", a0, a1, a2, a3);
+ }
+
+ static String pwI2(Integer a0, Integer a1, Integer a2, Integer a3) {
+ return String.format("b%d s%d c%d i%d", a0, a1, a2, a3);
+ }
+
+ static String pwL1(long a0, long a1, long a2, long a3, long a4) {
+ return String.format("b%d s%d c%d i%d j%d", a0, a1, a2, a3, a4);
+ }
+
+ static String pwL2(Long a0, Long a1, Long a2, Long a3, Long a4) {
+ return String.format("b%d s%d c%d i%d j%d", a0, a1, a2, a3, a4);
+ }
+
+ static String pwS1(short a0, short a1) {
+ return String.format("b%d s%d", a0, a1);
+ }
+
+ static String pwS2(Short a0, Short a1) {
+ return String.format("b%d s%d", a0, a1);
+ }
+
+ static String pwD1(double a0, double a1) {
+ return String.format("f%f d%f", a0, a1);
+ }
+
+ static String pwD2(Double a0, Double a1) {
+ return String.format("f%f d%f", a0, a1);
+ }
+
+ public void testPrimitiveWidening() {
+ WidenS ws1 = LambdaTranslationTest2::pwS1;
+ assertEquals("b1 s2", ws1.m((byte) 1, (short) 2));
+
+ WidenD wd1 = LambdaTranslationTest2::pwD1;
+ assertEquals("f1.000000 d2.000000", wd1.m(1.0f, 2.0));
+
+ WidenI wi1 = LambdaTranslationTest2::pwI1;
+ assertEquals("b1 s2 c3 i4", wi1.m((byte) 1, (short) 2, (char) 3, 4));
+
+ WidenL wl1 = LambdaTranslationTest2::pwL1;
+ assertEquals("b1 s2 c3 i4 j5", wl1.m((byte) 1, (short) 2, (char) 3, 4, 5L));
+
+ // @@@ TODO: clarify spec on widen+box conversion
+ }
+
+ interface Unbox {
+ public String m(Byte a0, Short a1, Character a2, Integer a3, Long a4, Boolean a5, Float a6, Double a7);
+ }
+
+ static String pu(byte a0, short a1, char a2, int a3, long a4, boolean a5, float a6, double a7) {
+ return String.format("b%d s%d c%c i%d j%d z%b f%f d%f", a0, a1, a2, a3, a4, a5, a6, a7);
+ }
+
+ public void testUnboxing() {
+ Unbox u = LambdaTranslationTest2::pu;
+ assertEquals("b1 s2 cA i4 j5 ztrue f6.000000 d7.000000", u.m((byte)1, (short) 2, 'A', 4, 5L, true, 6.0f, 7.0));
+ }
+
+ public void testBoxing() {
+ Box b = LambdaTranslationTest2::pb;
+ assertEquals("b1 s2 cA i4 j5 ztrue f6.000000 d7.000000", b.m((byte) 1, (short) 2, 'A', 4, 5L, true, 6.0f, 7.0));
+ }
+
+ static boolean cc(Object o) {
+ return ((String) o).equals("foo");
+ }
+
+ public void testArgCastingAdaptation() {
+ TPredicate<String> p = LambdaTranslationTest2::cc;
+ assertTrue(p.test("foo"));
+ assertTrue(!p.test("bar"));
+ }
+
+ interface SonOfPredicate<T> extends TPredicate<T> { }
+
+ public void testExtendsSAM() {
+ SonOfPredicate<String> p = s -> s.isEmpty();
+ assertTrue(p.test(""));
+ assertTrue(!p.test("foo"));
+ }
+
+ public void testConstructorRef() {
+ Factory<List<String>> lf = ArrayList<String>::new;
+ List<String> list = lf.make();
+ assertTrue(list instanceof ArrayList);
+ assertTrue(list != lf.make());
+ list.add("a");
+ assertEquals("[a]", list.toString());
+ }
+
+ private static String privateMethod() {
+ return "private";
+ }
+
+ public void testPrivateMethodRef() {
+ Factory<String> sf = LambdaTranslationTest2::privateMethod;
+ assertEquals("private", sf.make());
+ }
+
+ private interface PrivateIntf {
+ String make();
+ }
+
+ public void testPrivateIntf() {
+ PrivateIntf p = () -> "foo";
+ assertEquals("foo", p.make());
+ }
+
+ interface Op<T> {
+ public T op(T a, T b);
+ }
+
+ public void testBoxToObject() {
+ Op<Integer> maxer = Math::max;
+ for (int i=-100000; i < 100000; i += 100)
+ for (int j=-100000; j < 100000; j += 99) {
+ assertEquals((int) maxer.op(i,j), Math.max(i,j));
+ }
+ }
+
+ protected static String protectedMethod() {
+ return "protected";
+ }
+
+ public void testProtectedMethodRef() {
+ Factory<String> sf = LambdaTranslationTest2::protectedMethod;
+ assertEquals("protected", sf.make());
+ }
+
+ class Inner1 {
+ String m1() {
+ return "Inner1.m1()";
+ }
+
+ class Inner2 {
+ public String m1() {
+ return "Inner1.Inner2.m1()";
+ }
+
+ protected String m2() {
+ return "Inner1.Inner2.m2()";
+ }
+
+ String m3() {
+ return "Inner1.Inner2.m3()";
+ }
+
+ class Inner3<T> {
+ T t = null;
+ Inner3(T t) {
+ this.t = t;
+ }
+ T m1() {
+ return t;
+ }
+ }
+ }
+ }
+
+ public void testInnerClassMethodRef() {
+ Factory<String> fs = new Inner1()::m1;
+ assertEquals("Inner1.m1()", fs.make());
+
+ fs = new Inner1().new Inner2()::m1;
+ assertEquals("Inner1.Inner2.m1()", fs.make());
+
+ fs = new Inner1().new Inner2()::m2;
+ assertEquals("Inner1.Inner2.m2()", fs.make());
+
+ fs = new Inner1().new Inner2()::m3;
+ assertEquals("Inner1.Inner2.m3()", fs.make());
+
+ fs = new Inner1().new Inner2().new Inner3<String>("Inner1.Inner2.Inner3")::m1;
+ assertEquals("Inner1.Inner2.Inner3", fs.make());
+
+ Factory<Integer> fsi = new Inner1().new Inner2().new Inner3<Integer>(100)::m1;
+ assertEquals(100, (int)fsi.make());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/TBlock.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,36 @@
+/**
+ * Performs operations upon an input object which may modify that object and/or
+ * external state (other objects).
+ *
+ * <p>All block implementations are expected to:
+ * <ul>
+ * <li>When used for aggregate operations upon many elements blocks
+ * should not assume that the {@code apply} operation will be called upon
+ * elements in any specific order.</li>
+ * </ul>
+ *
+ * @param <T> The type of input objects to {@code apply}.
+ */
+public interface TBlock<T> {
+
+ /**
+ * Performs operations upon the provided object which may modify that object
+ * and/or external state.
+ *
+ * @param t an input object
+ */
+ void apply(T t);
+
+ /**
+ * Returns a Block which performs in sequence the {@code apply} methods of
+ * multiple Blocks. This Block's {@code apply} method is performed followed
+ * by the {@code apply} method of the specified Block operation.
+ *
+ * @param other an additional Block which will be chained after this Block
+ * @return a Block which performs in sequence the {@code apply} method of
+ * this Block and the {@code apply} method of the specified Block operation
+ */
+ public default TBlock<T> chain(TBlock<? super T> other) {
+ return (T t) -> { apply(t); other.apply(t); };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/TMapper.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2010, 2011, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Given an input object maps to an appropriate output object. A mapper may
+ * variously provide a mapping between types, object instances or keys and
+ * values or any other form of transformation upon the input.
+ *
+ * <p/>All mapper implementations are expected to:
+ * <ul>
+ * <li>Provide stable results such that for any {@code t} the result of two
+ * {@code map} operations are always equivalent. ie.<pre>
+ * Foo one = mapper.map(a);
+ * Foo two = mapper.map(a);
+ *
+ * assert one.equals(two) && two.equals(one);
+ * </pre></li>
+ * <li>Equivalent input objects should map to equivalent output objects. ie.<pre>
+ * assert a.equals(b); // a and b are equivalent
+ *
+ * Foo x = mapper.map(a);
+ * Foo y = mapper.map(b);
+ *
+ * assert x.equals(y); // their mapped results should be as equivalent.
+ * </pre></li>
+ * <li>The mapper should not modify the input object in any way that would
+ * change the mapping.</li>
+ * <li>When used for aggregate operations upon many elements mappers
+ * should not assume that the {@code map} operation will be called upon elements
+ * in any specific order.</li>
+ * </ul>
+ *
+ * @param <R> the type of output objects from {@code map} operation. May be the
+ * @param <T> the type of input objects provided to the {@code map} operation.
+ * same type as {@code <T>}.
+ */
+public interface TMapper<R, T> {
+
+ /**
+ * Map the provided input object to an appropriate output object.
+ *
+ * @param t the input object to be mapped.
+ * @return the mapped output object.
+ */
+ R map(T t);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExecution/TPredicate.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010, 2011, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Determines if the input object matches some criteria.
+ *
+ * <p>All predicate implementations are expected to:
+ * <ul>
+ * <li>Provide stable results such that for any {@code t} the result of two
+ * {@code eval} operations are always equivalent. ie.<pre>
+ * boolean one = predicate.test(a);
+ * boolean two = predicate.test(a);
+ *
+ * assert one == two;
+ * </pre></li>
+ * <li>Equivalent input objects should map to equivalent output objects. ie.<pre>
+ * assert a.equals(b); // a and b are equivalent
+ *
+ * boolean x = predicate.test(a);
+ * boolean y = predicate.test(ab;
+ *
+ * assert x == y; // their test results should be the same.
+ * </pre></li>
+ * <li>The predicate should not modify the input object in any way that would
+ * change the evaluation.</li>
+ * <li>When used for aggregate operations upon many elements predicates
+ * should not assume that the {@code test} operation will be called upon
+ * elements in any specific order.</li>
+ * </ul>
+ *
+ * @param <T> the type of input objects provided to {@code test}.
+ */
+public interface TPredicate<T> {
+
+ /**
+ * Return {@code true} if the input object matches some criteria.
+ *
+ * @param t the input object.
+ * @return {@code true} if the input object matched some criteria.
+ */
+ boolean test(T t);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/AbstractClass_neg.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Test that lambda conversion is only for SAM interface, not abstract class
+ * @compile/fail/ref=AbstractClass_neg.out -XDrawDiagnostics AbstractClass_neg.java
+ */
+
+public class AbstractClass_neg {
+
+ abstract class SAM {
+ abstract int m();
+ }
+
+ void test() {
+ SAM s = ()-> 6;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/AbstractClass_neg.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+AbstractClass_neg.java:16:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/AccessNonStatic_neg.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,26 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Test accessing non-static variable from lambda expressions in static context
+ * @compile/fail/ref=AccessNonStatic_neg.out -XDrawDiagnostics AccessNonStatic_neg.java
+ */
+
+public class AccessNonStatic_neg {
+
+ private int n = 0;
+
+ static {
+ ((Runnable) ()-> {
+ System.out.println(this);
+ System.out.println(n);
+ }).run();
+ }
+
+ public static void test() {
+ ((Runnable) ()-> {
+ Object o = this;
+ n++;
+ }).run();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/AccessNonStatic_neg.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,5 @@
+AccessNonStatic_neg.java:15:32: compiler.err.non-static.cant.be.ref: kindname.variable, this
+AccessNonStatic_neg.java:16:32: compiler.err.non-static.cant.be.ref: kindname.variable, n
+AccessNonStatic_neg.java:22:24: compiler.err.non-static.cant.be.ref: kindname.variable, this
+AccessNonStatic_neg.java:23:13: compiler.err.non-static.cant.be.ref: kindname.variable, n
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/EffectivelyFinal_neg.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Negative test of capture of "effectively final" local variable in lambda expressions
+ * @compile/fail/ref=EffectivelyFinal_neg.out -XDrawDiagnostics EffectivelyFinal_neg.java
+ */
+
+public class EffectivelyFinal_neg {
+
+ void test() {
+ String s = "a";
+ String s2 = "a";
+ int n = 1;
+ ((Runnable)
+ ()-> {
+ s2 = "b"; //re-assign illegal here
+ System.out.println(n);
+ System.out.println(s);
+ s = "b"; // not effectively final
+ }
+ ).run();
+ n = 2; // not effectively final
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/EffectivelyFinal_neg.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,5 @@
+EffectivelyFinal_neg.java:17:17: compiler.err.cant.ref.non.effectively.final.var: s2, (compiler.misc.lambda)
+EffectivelyFinal_neg.java:18:36: compiler.err.cant.ref.non.effectively.final.var: n, (compiler.misc.lambda)
+EffectivelyFinal_neg.java:19:36: compiler.err.cant.ref.non.effectively.final.var: s, (compiler.misc.lambda)
+EffectivelyFinal_neg.java:20:17: compiler.err.cant.ref.non.effectively.final.var: s, (compiler.misc.lambda)
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression1.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Test invalid lambda expressions
+ * @compile/fail/ref=InvalidExpression1.out -XDrawDiagnostics InvalidExpression1.java
+ */
+
+import java.util.Comparator;
+
+public class InvalidExpression1 {
+
+ void test() {
+ Comparator<Number> c = (Number n1, Number n2)-> { 42; }; //not a statement
+ Comparator<Number> c = (Number n1, Number n2)-> { return 42 }; //";" expected
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression1.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+InvalidExpression1.java:14:59: compiler.err.not.stmt
+InvalidExpression1.java:15:68: compiler.err.expected: ';'
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression3.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Test invalid lambda expressions
+ * @compile/fail/ref=InvalidExpression3.out -XDrawDiagnostics InvalidExpression3.java
+ */
+
+import java.util.Comparator;
+
+public class InvalidExpression3 {
+
+ void test() {
+ Comparator<Integer> c2 = (Integer i1, Integer i2) -> { return "0"; }; //return type need to match
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression3.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+InvalidExpression3.java:14:71: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.String, int))
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression4.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Test invalid lambda expressions
+ * @compile/fail/ref=InvalidExpression4.out -XDrawDiagnostics InvalidExpression4.java
+ */
+
+public class InvalidExpression4 {
+
+ interface SAM {
+ void m(int i);
+ }
+
+ void test() {
+ SAM s = (Integer i) -> { }; //parameters not match, boxing not allowed here
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression4.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+InvalidExpression4.java:16:17: compiler.err.prob.found.req: (compiler.misc.incompatible.arg.types.in.lambda)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression5.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Test invalid lambda expressions
+ * @compile/fail/ref=InvalidExpression5.out -XDrawDiagnostics InvalidExpression5.java
+ */
+
+public class InvalidExpression5 {
+
+ void test() {
+ Object o = (int n) -> { }; // Invalid target type
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression5.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+InvalidExpression5.java:12:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression6.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Test invalid lambda expressions
+ * @compile/fail/ref=InvalidExpression6.out -XDrawDiagnostics InvalidExpression6.java
+ */
+
+public class InvalidExpression6 {
+
+ interface SAM {
+ void m(int i);
+ }
+
+ void test() {
+ SAM s = (int n) -> { break; }; //break not allowed
+ s = (int n) -> { continue; }; //continue not allowed
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/InvalidExpression6.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,3 @@
+InvalidExpression6.java:16:30: compiler.err.break.outside.switch.loop
+InvalidExpression6.java:17:26: compiler.err.cont.outside.loop
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest1.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test lambda expressions for existing SAM interfaces like Runnable and Comparator<T>
+ * @compile LambdaTest1.java
+ * @run main LambdaTest1
+ */
+
+import java.util.Collections;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Date;
+
+public class LambdaTest1 {
+
+ private static String assertionStr = "";
+
+ private static void assertTrue(boolean b) {
+ if(!b)
+ throw new AssertionError();
+ }
+
+ private static void test1(Runnable r) {
+ r.run();
+ }
+
+ void test2(Object o) {
+ if(o instanceof Runnable)
+ ((Runnable)o).run();
+ }
+
+ Runnable test3() {
+ return ()-> { assertionStr += "Runnable6"; };
+ }
+
+ public static void main(String[] args) {
+
+ //lambda expressions for SAM interface Runnable:
+ //assign:
+ Runnable r = ()-> { assertionStr += "Runnable1 "; };
+ r.run();
+
+ //cast:
+ ((Runnable)()-> { assertionStr += "Runnable2 "; }).run();
+
+ Object o = (Runnable)()-> {};
+
+ o = (Runnable)()-> {
+ switch (assertionStr) {
+ case "Runnable1 Runnable2 ":
+ assertionStr += "Runnable3 ";
+ break;
+ default:
+ throw new AssertionError();
+ }
+ return;
+ };
+
+ //method parameter:
+ test1(()-> { assertionStr += "Runnable4 "; return; });
+
+ LambdaTest1 test = new LambdaTest1();
+ test.test2((Runnable)()-> { assertionStr += "Runnable5 "; });
+
+ //return type:
+ r = test.test3();
+ r.run();
+
+ assertTrue(assertionStr.equals("Runnable1 Runnable2 Runnable4 Runnable5 Runnable6"));
+
+ //lambda expressions for SAM interface Comparator<T>:
+ List<Integer> list = new ArrayList<Integer>();
+ list.add(4);
+ list.add(10);
+ list.add(-5);
+ list.add(100);
+ list.add(9);
+ Collections.sort(list, (Integer i1, Integer i2)-> i2 - i1);
+ String result = "";
+ for(int i : list)
+ result += i + " ";
+ assertTrue(result.equals("100 10 9 4 -5 "));
+
+ Collections.sort(list,
+ (i1, i2) -> {
+ String s1 = i1.toString();
+ String s2 = i2.toString();
+ return s1.length() - s2.length();
+ });
+ result = "";
+ for(int i : list)
+ result += i + " ";
+ assertTrue(result.equals("9 4 10 -5 100 "));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest2.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test lambda expressions for different method signatures (parameter and return type)
+ * @compile LambdaTest2.java
+ * @run main LambdaTest2
+ */
+
+public class LambdaTest2 {
+
+ private static int count = 0;
+
+ private static void assertTrue(boolean b) {
+ if(!b)
+ throw new AssertionError();
+ }
+
+ public static void main(String[] args) {
+ LambdaTest2 test = new LambdaTest2();
+
+ test.method2((int n) -> { ; });
+ test.method2(n -> { }); // "int" is optional here
+ test.method2((int n) -> { }); // ";" is optional here
+ test.method2((int n) -> { return; }); // ";" is mandatory here
+ test.method2((int n) -> { count += n; });
+ assertTrue(count == 10);
+
+ VoidInt vi = (int i) -> {
+ switch (i) {
+ case 0:
+ System.out.println("normal");
+ break;
+ default:
+ System.out.println("invalid");
+ }
+ };
+
+ test.method3(()-> { count++; });
+ test.method3(() -> {});
+ assertTrue(count == 11);
+
+ VoidVoid vv = ()-> { while(true)
+ if(false)
+ break;
+ else
+ continue;
+ };
+
+ IntVoid iv1 = () -> 42;
+ IntVoid iv2 = () -> { return 43; };//";" is mandatory here
+ assertTrue(iv1.ivMethod() == 42);
+ assertTrue(iv2.ivMethod() == 43);
+
+ IntInt ii1 = (int n) -> n+1;
+ IntInt ii2 = n -> 42;
+ IntInt ii3 = n -> { return 43; };
+ IntInt ii4 =
+ (int n) -> {
+ if(n > 0)
+ return n+1;
+ else
+ return n-1;
+ };
+ assertTrue(ii1.iiMethod(1) == 2);
+ assertTrue(ii2.iiMethod(1) == 42);
+ assertTrue(ii3.iiMethod(1) == 43);
+ assertTrue(ii4.iiMethod(-1) == -2);
+ }
+
+ void method2(VoidInt a) {
+ a.viMethod(10);
+ }
+
+ void method3(VoidVoid a) {
+ a.vvMethod();
+ }
+
+ //SAM type interfaces
+ interface VoidInt {
+ void viMethod(int n);
+ }
+
+ interface VoidVoid {
+ void vvMethod();
+ }
+
+ interface IntVoid {
+ int ivMethod();
+ }
+
+ interface IntInt {
+ int iiMethod(int n);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest3.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test capture of "effectively final" local variable in lambda expressions
+ * @compile LambdaTest3.java
+ * @run main LambdaTest3
+ */
+
+public class LambdaTest3 {
+
+ private static int count = 0;
+
+ private static void assertTrue(boolean b) {
+ if(!b)
+ throw new AssertionError();
+ }
+
+ public static void main(String[] args) {
+ final int N = 100;
+ int n = 2; //effectively final variable
+
+ Runnable r = ((Runnable)
+ () -> {
+ count += N;
+ count += n;
+ }
+ );
+ assertTrue(count == 0);
+ r.run();
+ assertTrue(count == 102);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest4.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test accessing "this" in lambda expressions
+ * @compile LambdaTest4.java
+ * @run main LambdaTest4
+ */
+
+public class LambdaTest4 {
+
+ private String thisStr;
+ private static int count = 0;
+
+ {
+ ((Runnable)
+ ()-> {
+ this.init();
+ assertTrue(this.toString().equals(thisStr));
+ count++;
+ }
+ ).run();
+ }
+
+ private static void assertTrue(boolean b) {
+ if(!b)
+ throw new AssertionError();
+ }
+
+ private void init() {
+ thisStr = this.toString();
+ }
+
+ private void m() {
+ String s1 = this.toString();
+ ((Runnable)
+ ()-> {
+ assertTrue(this.toString().equals(thisStr));
+ assertTrue(this.toString().equals(s1));
+ }
+ ).run();
+ }
+
+ public static void main(String[] args) {
+ LambdaTest4 test = new LambdaTest4();
+ assertTrue(count == 1);
+ test.m();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest5.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test lambda expressions inside lambda expressions
+ * @compile LambdaTest5.java
+ * @run main LambdaTest5
+ */
+
+public class LambdaTest5 {
+
+ interface A {
+ int m();
+ }
+
+ interface B {
+ int make (int i);
+ }
+
+ private static int count = 0;
+
+ private static void assertTrue(boolean b) {
+ if(!b)
+ throw new AssertionError();
+ }
+
+ static A a;
+ static A a2;
+ static A a3;
+ static A a4;
+
+ public static void main(String[] args) {
+ B b = (int i) -> ((A)()-> 5).m();
+ assertTrue(b.make(0) == 5);
+
+ a = () -> ((A)()-> { return 6; }).m(); //self reference
+ assertTrue(a.m() == 6);
+
+ a2 = ()-> {
+ A an = ()-> { return 7; }; //self reference
+ return an.m();
+ };
+ assertTrue(a2.m() == 7);
+
+ a3 = () -> a3.m(); //self reference
+ try {
+ a3.m();
+ } catch(StackOverflowError e) {
+ count++;
+ }
+ assertTrue(count==1);
+
+ a4 = ()-> ((B)(int i)-> ((A)()-> 9).m() ).make(0);
+ assertTrue(a4.m() == 9);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest6.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test bridge methods for certain SAM conversions
+ * @compile LambdaTest6.java
+ * @run main LambdaTest6
+ */
+
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+
+public class LambdaTest6<T> {
+
+ interface H {Object m();}
+
+ interface K<U> {void m(U element);}
+
+ interface L extends K<String> {} //generic substitution
+
+ interface M {void m(String s);}
+
+ interface KM extends K<String>, M{} //generic substitution
+
+ interface N extends H {String m();} //covariant return
+
+ private static void assertTrue(boolean b) {
+ if(!b)
+ throw new AssertionError();
+ }
+
+ private Set<String> setOfStringObject() {
+ Set<String> s = new HashSet<>();
+ s.add("java.lang.String");
+ s.add("java.lang.Object");
+ return s;
+ }
+
+ private void test1()
+ {
+ L la = s -> { };
+ la.m("hi");
+ Class<? extends L> c1 = la.getClass();
+ Method[] methods = c1.getDeclaredMethods();
+ Set<String> types = setOfStringObject();
+ for(Method m : methods) {
+ assertTrue(m.getName().equals("m"));
+ Class[] parameterTypes = m.getParameterTypes();
+ assertTrue(parameterTypes.length == 1);
+ assertTrue(types.remove(parameterTypes[0].getName()));
+ }
+ assertTrue(types.isEmpty() || (types.size() == 1 && types.contains("java.lang.String")));
+ }
+
+ private void test2()
+ {
+ KM km = s -> { };
+ //km.m("hi");
+ Class<? extends KM> c2 = km.getClass();
+ Method[] methods = c2.getDeclaredMethods();
+ Set<String> types = setOfStringObject();
+ for(Method m : methods) {
+ assertTrue(m.getName().equals("m"));
+ Class[] parameterTypes = m.getParameterTypes();
+ assertTrue(parameterTypes.length == 1);
+ assertTrue(types.remove(parameterTypes[0].getName()));
+ }
+ assertTrue(types.isEmpty());
+ }
+
+ private void test3()
+ {
+ N na = ()-> "hi";
+ assertTrue( na.m().equals("hi") );
+ assertTrue( ((H)na).m().equals("hi") );
+ Class<? extends N> c3 = na.getClass();
+ Method[] methods = c3.getDeclaredMethods();
+ Set<String> types = setOfStringObject();
+ for(Method m : methods) {
+ assertTrue(m.getName().equals("m"));
+ Class returnType = m.getReturnType();
+ assertTrue(types.remove(returnType.getName()));
+ }
+ assertTrue(types.isEmpty());
+ }
+
+
+ public static void main(String[] args) {
+ LambdaTest6 test = new LambdaTest6();
+ test.test1();
+ test.test2();
+ test.test3();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/SamConversion.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test SAM conversion of lambda expressions in context of assignment, method call, return statement and cast.
+ * @compile SamConversion.java
+ * @run main SamConversion
+ */
+
+public class SamConversion {
+
+ static interface Foo {
+ Integer m(int i);
+ }
+
+ static interface Bar {
+ int m(Integer i) throws Exception;
+ }
+
+ private static String assertionStr = "";
+
+ private static void assertTrue(boolean b) {
+ if(!b)
+ throw new AssertionError();
+ }
+
+ private static void test1(Foo foo) {
+ assertTrue(foo.m(1) == 2);
+ }
+
+ private static void test2(Bar bar) {
+ try {
+ assertTrue(bar.m(1) == 2);
+ } catch (Exception e){
+ assertTrue(false);
+ }
+ }
+
+ private static Bar test3(int i) {
+ switch (i) {
+ case 0:
+ return n -> n + 1;
+ case 1:
+ return (Integer n) -> 2 * n;
+ case 2:
+ return (Integer n) -> {return new Integer(n-1);};
+ case 3:
+ return n -> {throw new Exception();};
+ default:
+ return null;
+ }
+ }
+
+ public static void main(String[] args) {
+
+ //assign:
+ Foo foo = (int n) -> n + 1; //explicit type and boxing
+ assertTrue(foo.m(1) == 2);
+
+ foo = n -> n + 1; //type inferrred and boxing
+ assertTrue(foo.m(1) == 2);
+
+ Bar bar = (Integer n) -> n + 1; //explicit type and unboxing
+ try {
+ assertTrue(bar.m(1) == 2);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+
+ bar = (Integer n) -> new Integer(n+1); //explicit type and unboxing twice
+ try {
+ assertTrue(bar.m(1) == 2);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+
+ bar = n -> n.intValue() + 1; //type inferred
+ try {
+ assertTrue(bar.m(1) == 2);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+
+ bar = n -> n + 1; // type inferred and unboxing
+ try {
+ assertTrue(bar.m(1) == 2);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+
+ //cast:
+ assertTrue(((Foo)n -> {return n+1;}).m(1) == 2); //statement (instead of expression) in lambda body
+ try {
+ assertTrue(((Bar)n -> {return n+1;}).m(1) == 2); //statement in lambda body
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+
+ //method parameter:
+ test1((int n) -> new Integer(n+1)); //explicit type
+ test2((Integer n) -> n.intValue() + 1); //explicit type
+
+ //return statement:
+ bar = test3(0);
+ try {
+ assertTrue(bar.m(1) == 2);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ bar = test3(1);
+ try {
+ assertTrue(bar.m(3) == 6);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ bar = test3(2);
+ try {
+ assertTrue(bar.m(10) == 9);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ bar = test3(3);
+ try {
+ bar.m(10);
+ assertTrue(false);
+ } catch (Exception e) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/lambdaExpression/SamConversionComboTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test SAM conversion of lambda expressions in combinations of different contexts,
+ * lambda body types(statement/expression), explict/implicit target type etc, to verify
+ * SAM conversion being conducted successfully as expected.
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+public class SamConversionComboTest {
+
+ enum FInterface {
+ A("A", "interface A { Integer m(int i); }"),
+ B("B", "interface B { int m(Integer i); }"),
+ C("C", "interface C { int m(Integer i) throws Exception; }");
+
+ String interfaceType;
+ String interfaceDef;
+
+ FInterface(String interfaceType, String interfaceDef) {
+ this.interfaceType = interfaceType;
+ this.interfaceDef = interfaceDef;
+ }
+
+ String getParameterType() {
+ switch(this) {
+ case A:
+ return "int";
+ case B:
+ case C:
+ return "Integer";
+ default:
+ return null;
+ }
+ }
+ }
+
+ enum Context {
+ ASSIGNMENT("#FType f = #LBody;"),
+ METHOD_CALL("void method1(#FType f) { }\n" +
+ " void method2() {\n" +
+ " method1(#LBody);\n" +
+ " }"),
+ CONSTRUCTOR("X x = new X(#LBody);"),
+ RETURN_OF_METHOD("#FType method1() {\n" +
+ " return #LBody;\n" +
+ "}"),
+ ARRAY_INITIALIZER("Object[] oarray = {\"a\", 1, (#FType)#LBody};"),
+ LAMBDA_BODY("#FType f = n -> ((#FType)#LBody).m(n);"),
+ CAST("void test() throws Exception { int n = ((#FType)#LBody).m(1); }"),
+ CONDITIONAL_EXPRESSION("#FType f = 2 > 1 ? #LBody : null;");
+
+ String context;
+
+ Context(String context) {
+ this.context = context;
+ }
+
+ String getContext(FInterface f, LambdaKind lk, LambdaBody lb, ReturnValue rv) {
+ return context.replace("#FType", f.interfaceType).replace("#LBody", lb.getLambdaBody(f, lk, rv));
+ }
+ }
+
+ enum LambdaKind {
+ EXPRESSION("#VAL"),
+ STATEMENT("{return #VAL;}"),
+ EXCEPTION_STMT("{throw new Exception();}");
+
+ String stmt;
+
+ LambdaKind(String stmt) {
+ this.stmt = stmt;
+ }
+ }
+
+ enum ReturnValue {
+ INT("i + 1"),
+ INTEGER("new Integer(i+1)"),
+ INT2("i.intValue() + 1"),
+ STRING("i + \"\""),
+ DOUBLE("i * 1.0");
+
+ String rValue;
+
+ ReturnValue(String rValue) {
+ this.rValue = rValue;
+ }
+ }
+
+ enum LambdaBody {
+ IMPLICIT("i -> #RET"),//type inferred
+ EXPLICIT("(#Type i) -> #RET");//explicit type
+
+ String bodyStr;
+
+ LambdaBody(String bodyStr) {
+ this.bodyStr = bodyStr;
+ }
+
+ String getLambdaBody(FInterface fi, LambdaKind lk, ReturnValue rv) {
+ return bodyStr.replace("#Type", fi.getParameterType()).replace("#RET", lk.stmt.replace("#VAL", rv.rValue));
+ }
+ }
+
+ boolean checkSamConversion() {
+ if(lambdaKind != LambdaKind.EXCEPTION_STMT && (returnValue == ReturnValue.DOUBLE || returnValue == ReturnValue.STRING)) //return type mismatch
+ return false;
+ if(context != Context.CONSTRUCTOR) {//context other than construcotr argument
+ if(fInterface != FInterface.C && lambdaKind == LambdaKind.EXCEPTION_STMT)
+ return false;
+ if(fInterface == FInterface.A && returnValue == ReturnValue.INT2)
+ return false;
+ }
+ else { //constructor argument context
+ //match X(A a) or X(B b) or X(C c)
+ if (lambdaKind == LambdaKind.EXCEPTION_STMT) {
+ return false; //ambiguous target type
+ }
+ else if(lambdaBody == LambdaBody.IMPLICIT) {
+ if(returnValue != ReturnValue.INTEGER) //ambiguous target type
+ return false;
+ }
+ else { //explicit parameter type
+ if(fInterface.getParameterType().equals("Integer")) //ambiguous target type
+ //e.g. X x = new X((Integer i) -> i + 1);
+ return false;
+ if(returnValue == ReturnValue.INT2)
+ //e.g. X x = new X(int i -> i.intValue() + 1);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ SourceFile samSourceFile = new SourceFile("FInterface.java", "#C") {
+ public String toString() {
+ String interfaces = "";
+ for(FInterface fi : FInterface.values())
+ interfaces += fi.interfaceDef + "\n";
+ return template.replace("#C", interfaces);
+ }
+ };
+
+ String clientTemplate = "class Client {\n" +
+ " #Context\n" +
+ "}\n\n" +
+
+ "class X {\n" +
+ " int value = 0;\n\n" +
+
+ " X(A a) {\n" +
+ " value = a.m(6);\n" +
+ " }\n\n" +
+
+ " X(B b) {\n" +
+ " value = b.m(7);\n" +
+ " }\n\n" +
+
+ " X(C c) {\n" +
+ " try {\n" +
+ " value = c.m(8);\n" +
+ " } catch (Exception e){}\n" +
+ " }\n" +
+ "}";
+ SourceFile clientSourceFile = new SourceFile("Client.java", clientTemplate) {
+ public String toString() {
+ return template.replace("#Context", context.getContext(fInterface, lambdaKind, lambdaBody, returnValue));
+ }
+ };
+
+ void test() throws Exception {
+ System.out.println("\n====================================");
+ System.out.println(fInterface + ", " + context + ", " + lambdaKind + ", " + lambdaBody + ", " + returnValue);
+ System.out.println(samSourceFile + "\n");
+ String clientFileStr = clientSourceFile.toString();
+ System.out.println(clientFileStr.substring(0, clientFileStr.indexOf("\n\n")));
+
+ final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+ DiagnosticChecker dc = new DiagnosticChecker();
+ JavacTask ct = (JavacTask)tool.getTask(null, null, dc, null, null, Arrays.asList(samSourceFile, clientSourceFile));
+ ct.analyze();
+ if (dc.errorFound == checkSamConversion()) {
+ throw new AssertionError(samSourceFile + "\n\n" + clientSourceFile);
+ }
+ count++;
+ }
+
+ abstract class SourceFile extends SimpleJavaFileObject {
+
+ protected String template;
+
+ public SourceFile(String filename, String template) {
+ super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
+ this.template = template;
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return toString();
+ }
+
+ public abstract String toString();
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound = false;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ errorFound = true;
+ }
+ }
+ }
+
+ FInterface fInterface;
+ Context context;
+ LambdaBody lambdaBody;
+ LambdaKind lambdaKind;
+ ReturnValue returnValue;
+ static int count = 0;
+
+ SamConversionComboTest(FInterface f, Context c, LambdaBody lb, LambdaKind lk, ReturnValue rv) {
+ fInterface = f;
+ context = c;
+ lambdaKind = lk;
+ lambdaBody = lb;
+ returnValue = rv;
+ }
+
+ public static void main(String[] args) throws Exception {
+ for(Context ct : Context.values()) {
+ for (FInterface fi : FInterface.values()) {
+ for (LambdaKind lk: LambdaKind.values()) {
+ for (LambdaBody lb : LambdaBody.values()) {
+ for(ReturnValue rv : ReturnValue.values()) {
+ new SamConversionComboTest(fi, ct, lb, lk, rv).test();
+ }
+ }
+ }
+ }
+ }
+ System.out.println("total tests: " + count);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/BridgeMethod.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test bridge methods in certain SAM conversion
+ * @compile BridgeMethod.java
+ * @run main BridgeMethod
+ */
+
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+
+public class BridgeMethod {
+
+ interface H {Object m();}
+
+ interface K<T> {void m(T t);}
+
+ interface L extends K<String> {} //generic substitution
+
+ interface M {void m(String s);}
+
+ interface KM extends K<String>, M{} //generic substitution
+
+ interface N extends H {String m();} //covariant return
+
+ private static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static void bar(String s) {
+ System.out.println("BridgeMethod.bar(String) " + s);
+ }
+
+ String moo() {
+ return "moo";
+ }
+
+ private static Set<String> setOfStringObject() {
+ Set<String> s = new HashSet<>();
+ s.add("java.lang.String");
+ s.add("java.lang.Object");
+ return s;
+ }
+
+ public static void main(String[] args) {
+ L la = BridgeMethod::bar; //static reference
+ la.m("hi");
+ Class<? extends L> c1 = la.getClass();
+ Method[] methods = c1.getDeclaredMethods();
+ Set<String> types = setOfStringObject();
+ System.out.println("methods in SAM conversion of L:");
+ for(Method m : methods) {
+ System.out.println(m.toGenericString());
+ assertTrue(m.getName().equals("m"));
+ Class[] parameterTypes = m.getParameterTypes();
+ assertTrue(parameterTypes.length == 1);
+ assertTrue(types.remove(parameterTypes[0].getName()));
+ }
+ assertTrue(types.isEmpty() || (types.size() == 1 && types.contains("java.lang.String")));
+
+ KM km = BridgeMethod::bar;
+ //km.m("hi"); //will be uncommented when CR7028808 fixed
+ Class<? extends KM> c2 = km.getClass();
+ methods = c2.getDeclaredMethods();
+ types = setOfStringObject();
+ System.out.println("methods in SAM conversion of KM:");
+ for(Method m : methods) {
+ System.out.println(m.toGenericString());
+ assertTrue(m.getName().equals("m"));
+ Class<?>[] parameterTypes = m.getParameterTypes();
+ assertTrue(parameterTypes.length == 1);
+ assertTrue(types.remove(parameterTypes[0].getName()));
+ }
+ assertTrue(types.isEmpty());
+
+ N n = new BridgeMethod()::moo; //instance reference
+ assertTrue( n.m().equals("moo") );
+ assertTrue( ((H)n).m().equals("moo") );
+ Class<? extends N> c3 = n.getClass();
+ methods = c3.getDeclaredMethods();
+ types = setOfStringObject();
+ System.out.println("methods in SAM conversion of N:");
+ for(Method m : methods) {
+ System.out.println(m.toGenericString());
+ assertTrue(m.getName().equals("m"));
+ Class<?> returnType = m.getReturnType();
+ assertTrue(types.remove(returnType.getName()));
+ }
+ assertTrue(types.isEmpty());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/MethodRef1.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test static method reference
+ * @compile MethodRef1.java
+ * @run main MethodRef1
+ */
+
+public class MethodRef1 {
+
+ static interface A {void m();}
+
+ static interface B {void m(int i);}
+
+ static interface C {String m(String s);}
+
+ private static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static void foo(int x) {
+ System.out.println("MethodRef1.foo(int) " + x);
+ }
+
+ static void bar() {
+ System.out.println("MethodRef1.bar()");
+ }
+
+ static void bar(int x) {
+ System.out.println("MethodRef1.bar(int) " + x);
+ }
+
+ static String bar(String s) {
+ return "MethodRef1.bar(String) " + s;
+ }
+
+ public static void main(String[] args) {
+
+ A a = MethodRef1::bar; //static reference to bar()
+ a.m();
+
+ B b = MethodRef1::foo; //static reference to foo(int), (int) omitted because method foo is not overloaded
+ b.m(1);
+
+ b = MethodRef1::foo; //static reference to foo(int)
+ b.m(1);
+
+ b = new MethodRef1()::foo; //instance reference to static methods, supported for now
+ b.m(1);
+
+ b = MethodRef1::bar; //static reference to bar(int)
+ b.m(2);
+
+ C c = MethodRef1::bar; //static reference to bar(String)
+ assertTrue( c.m("hi").equals("MethodRef1.bar(String) hi") );
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/MethodRef2.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test instance method reference
+ * @compile MethodRef2.java
+ * @run main MethodRef2
+ */
+
+public class MethodRef2 {
+
+ static interface A {String m();}
+
+ static interface B {String m(int i);}
+
+ private static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ String moo() {
+ return "moo";
+ }
+
+ String wahoo() {
+ return "wahoo";
+ }
+
+ String wahoo(int x) {
+ return "wahoo " + x;
+ }
+
+ public static void main(String[] args) {
+
+ MethodRef2 mr = new MethodRef2();
+
+ A a = mr::moo; //instance reference to moo()
+ assertTrue( a.m().equals("moo") );
+
+ a = new MethodRef2()::wahoo; //instance reference to wahoo()
+ assertTrue( a.m().equals("wahoo") );
+
+ B b = mr::wahoo; //instance reference to wahoo(int)
+ assertTrue( b.m(4).equals("wahoo 4") );
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/MethodRef3.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test unbound method reference
+ * @compile MethodRef3.java
+ * @run main MethodRef3
+ */
+
+public class MethodRef3 {
+
+ static interface A { String m(MethodRef3 mr); }
+
+ static interface B { String m(MethodRef3 mr, String s); }
+
+ private static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ String moo() {
+ return "moo";
+ }
+
+ String wahoo(String s) {
+ return "wahoo " + s;
+ }
+
+ public static void main(String[] args) {
+
+ MethodRef3 mr = new MethodRef3();
+ A a = MethodRef3::moo; //unbound reference to moo()
+ assertTrue( a.m(mr).equals("moo") );
+ B b = MethodRef3::wahoo; //unbound reference to wahoo()
+ assertTrue( b.m(mr, "hi").equals("wahoo hi") );
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/MethodRef4.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test constructor reference
+ * @compile MethodRef4.java
+ * @run main MethodRef4
+ */
+
+public class MethodRef4 {
+
+ static interface A {Fee<String> m();}
+
+ static interface B {Fee<String> m(String s);}
+
+ static interface C {Object m();}
+
+ static class Fee<T> {
+
+ private T t;
+
+ public Fee() {
+ System.out.println("Fee<T> instantiated");
+ }
+
+ public Fee(T t) {
+ this.t = t;
+ System.out.println("Fee<T> instantiated: " + t);
+ }
+
+ public void make() {
+ System.out.println(this + ": make()");
+ }
+ }
+
+ private static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ public static void main(String[] args) {
+
+ A a = Fee<String>::new; //constructor reference to Fee<T>()
+ a.m().make();
+
+ B b = Fee<String>::new; //constructor reference to Fee<T>(String)
+ b.m("hi").make();
+
+ C c = MethodRef4::new; //constructor reference to MethodRef4()
+ assertTrue( c.m() instanceof MethodRef4 );
+ c = MethodRef4::new; //constructor reference to MethodRef4()
+ assertTrue( c.m() instanceof MethodRef4 );
+ c = Fee<String>::new; //constructor reference to Fee<T>()
+ assertTrue( c.m() instanceof Fee );
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/MethodRef5.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test method reference with SAM interface Comparator<T>
+ * @compile MethodRef5.java
+ * @run main MethodRef5
+ */
+
+import java.util.Collections;
+import java.util.List;
+import java.util.ArrayList;
+
+public class MethodRef5 {
+
+ static class Person {
+
+ private String firstName;
+ private String lastName;
+ private int age;
+
+ public Person() { }
+
+ public Person(String fn, String ln, int a) {
+ firstName = fn;
+ lastName = ln;
+ age = a;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ //the following 2 methods are signature-compatible with Comparator<Person>.compare():
+ public static int compareByAge(Person a, Person b) {
+ return a.age - b.age;
+ }
+
+ public int compareByLastName(Person a, Person b) {
+ return a.lastName.compareToIgnoreCase(b.lastName);
+ }
+ }
+
+ private static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ public static void main(String[] args) {
+
+ List<Person> persons = new ArrayList<Person>();
+ persons.add(new Person("John", "Smith", 49));
+ persons.add(new Person("Abraham", "Lincoln", 30));
+ persons.add(new Person("George", "Washington", 29));
+ persons.add(new Person("Peter", "Derby", 50));
+ Collections.sort(persons, Person::compareByAge);//static method reference to compareByAge(Person, Person)
+ String age = "";
+ for (Person p : persons) {
+ age += p.getAge() + " ";
+ }
+ assertTrue( (age.equals("29 30 49 50 ")) );
+ Collections.sort(persons, new Person()::compareByLastName);//instance method reference to compareByLastName(Person, Person)
+ String lastName = "";
+ for (Person p : persons) {
+ lastName += p.getLastName() + " ";
+ }
+ assertTrue( lastName.equals("Derby Lincoln Smith Washington ") );
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/MethodRef6.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test that the most specific reference is selected when method parameters are elided
+ * @compile MethodRef6.java
+ * @run main MethodRef6
+ */
+
+public class MethodRef6 {
+
+ static interface A { String make(Integer i); }
+
+ static interface B { String make(Number i); }
+
+ private static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static String m(Object o) {
+ return "Object " + o;
+ }
+
+ static String m(Number n) {
+ return "Number " + n;
+ }
+
+ static String m(Integer i) {
+ return "Integer " + i;
+ }
+
+ static String m(int i) {
+ return "int " + i;
+ }
+
+ public static void main(String[] args) {
+ A a = MethodRef6::m;
+ assertTrue(a.make(1).equals("Integer 1"));//method parameter type inferred from SAM descriptor, boxing applied
+ B b = MethodRef6::m;
+ assertTrue(b.make(1).equals("Number 1"));//method parameter type inferred from SAM descriptor, boxing and widen applied
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/MethodRef7.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Test that parameter types are inferred from SAM descriptor when method parameters are elided,
+ with different types of method references
+ * @compile MethodRef7.java
+ * @run main MethodRef7
+ */
+
+public class MethodRef7 {
+
+ static interface A {void m();}
+
+ static interface A2 {void m(int n);}
+
+ static interface B {String m();}
+
+ static interface B2 {String m(int n);}
+
+ static interface C {String m(MethodRef7 mr);}
+
+ static interface C2 {String m(MethodRef7 mr, int n);}
+
+ static interface D {Fee<String> m();}
+
+ static interface D2 {Fee<String> m(String s);}
+
+ static class Fee<T> {
+
+ public Fee() {
+ System.out.println("Fee<T> instantiated");
+ }
+
+ public Fee(String s) {
+ System.out.println("Fee<T> instantiated: " + s);
+ }
+ }
+
+ private static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ static void bar() {
+ System.out.println("MethodRef_neg1.bar()");
+ }
+
+ static void bar(int x) {
+ System.out.println("MethodRef_neg1.bar(int) " + x);
+ }
+
+ String wahoo() {
+ return "wahoo";
+ }
+
+ String wahoo(int x) {
+ return "wahoo " + x;
+ }
+
+ public static void main(String[] args) {
+
+ A a = MethodRef7::bar; //static reference to bar()
+ a.m();
+ A2 a2 = MethodRef7::bar; //static reference to bar(int x)
+ a2.m(10);
+
+ MethodRef7 mr = new MethodRef7();
+ B b = mr::wahoo; //instance reference to wahoo()
+ assertTrue(b.m().equals("wahoo"));
+ B2 b2 = mr::wahoo; //instance reference to wahoo(int x)
+ assertTrue(b2.m(1).equals("wahoo 1"));
+
+ C c = MethodRef7::wahoo; //unbound reference to wahoo()
+ assertTrue(c.m(mr).equals("wahoo"));
+ C2 c2 = MethodRef7::wahoo; //unbound reference to wahoo(int x)
+ assertTrue(c2.m(mr, 2).equals("wahoo 2"));
+
+ D d = Fee<String>::new; //constructor reference to Fee()
+ D2 d2 = Fee<String>::new; //constructor reference to Fee(String s)
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/MethodRef_neg.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,36 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * This is negative test for wrong parameter/return type in method references
+ * @compile/fail/ref=MethodRef_neg.out -XDrawDiagnostics MethodRef_neg.java
+ */
+
+public class MethodRef_neg {
+
+ static interface A {void m(Integer i);}
+
+ static interface B {void m(String s);}
+
+ static interface C {Integer m();}
+
+ static interface D {String m();}
+
+
+ static void bar(int x) { }
+
+ int foo() {
+ return 5;
+ }
+
+ static void make() { }
+
+ void method() {
+ A a = MethodRef_neg::bar; //boxing on parameter type is ok
+ B b = MethodRef_neg::bar; //wrong parameter type, required: String, actual: int
+ C c = this::foo; //boxing on return type is ok
+ D d = this::foo; //wrong return type, required: String, actual: int
+ a = MethodRef_neg::make; //missing parameter
+ c = MethodRef_neg::make; //missing return type
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/MethodRef_neg.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,5 @@
+MethodRef_neg.java:30:15: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, bar, int, java.lang.String, kindname.class, MethodRef_neg, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, int))))
+MethodRef_neg.java:32:15: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: int, java.lang.String))
+MethodRef_neg.java:33:13: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, make, compiler.misc.no.args, java.lang.Integer, kindname.class, MethodRef_neg, (compiler.misc.arg.length.mismatch)))
+MethodRef_neg.java:34:13: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: void, java.lang.Integer))
+4 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/SamConversion.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * Test SAM conversion of method references in contexts of assignment, method/constructor argument,
+ * return statement, array initializer, lambda expression body, conditional expression and cast.
+ * @compile SamConversion.java
+ * @run main SamConversion
+ */
+
+public class SamConversion {
+
+ static int assertionCount = 0;
+
+ static interface Foo {
+ Integer m(int i);
+ }
+
+ static interface Bar {
+ int m(Integer i) throws MyException;
+ }
+
+ private static void assertTrue(boolean b) {
+ assertionCount++;
+ if(!b)
+ throw new AssertionError();
+ }
+
+ private static int test1(Foo foo) {
+ return foo.m(1);
+ }
+
+ private static void test2(Bar bar, int result) {
+ try {
+ assertTrue(bar.m(1) == result);
+ } catch (Exception e){
+ assertTrue(false);
+ }
+ }
+
+ private static Bar test3(int i) {
+ switch (i) {
+ case 0:
+ return A::method1;
+ case 1:
+ return new A()::method2;
+ case 2:
+ return A::method3;
+ case 3:
+ return new A()::method4;
+ case 4:
+ return new A()::method5;
+ case 5:
+ return A::method6;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Test SAM conversion of method reference in assignment context
+ */
+ private static void testAssignment() {
+ Foo foo = A::method1; //static reference, parameter type matching and return type matching
+ assertTrue(foo.m(1) == 2);
+
+ foo = new A()::method2; //instance reference, parameter type unboxing and return type boxing
+ assertTrue(foo.m(1) == 3);
+
+ foo = A::method3; //static reference, parameter type matching and return type boxing
+ assertTrue(foo.m(1) == 4);
+
+ foo = new A()::method4; //instance reference, parameter type unboxing and return type matching
+ assertTrue(foo.m(1) == 5);
+
+ foo = new A()::method5; //instance reference, parameter type unboxing and return type matching
+ assertTrue(foo.m(1) == 6);
+
+ Bar bar = A::method1;
+ try {
+ assertTrue(bar.m(1) == 2);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+
+ bar = new A()::method2;
+ try {
+ assertTrue(bar.m(1) == 3);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+
+ bar = A::method3;
+ try {
+ assertTrue(bar.m(1) == 4);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+
+ bar = new A()::method4;
+ try {
+ assertTrue(bar.m(1) == 5);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+
+ bar = new A()::method5;
+ try {
+ assertTrue(bar.m(1) == 6);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+
+ bar = new A()::method6;
+ try {
+ bar.m(1);
+ assertTrue(false);
+ } catch (MyException e) {
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ }
+
+ /**
+ * Test SAM conversion of method reference in method/constructor argument context
+ */
+ private static void testMethodArgument() {
+ assertTrue(test1(A::method1) == 2);
+ assertTrue(test1(new A()::method2) == 3);
+ assertTrue(test1(A::method3) == 4);
+ assertTrue(test1(new A()::method4) == 5);
+ assertTrue(test1(new A()::method5) == 6);
+ test2(A::method1, 2);
+ test2(new A()::method2, 3);
+ test2(A::method3, 4);
+ test2(new A()::method4, 5);
+ test2(new A()::method5, 6);
+ A a = new A(A::method1); //A(Foo f) called
+ assertTrue(a.method2(1) == 11);
+ assertTrue(a.method4(1) == 11);
+ assertTrue(a.method5(1) == 11);
+ A a2 = new A(new A()::method2); //A(Bar b) called
+ assertTrue(a2.method2(1) == 12);
+ assertTrue(a2.method4(1) == 12);
+ assertTrue(a2.method5(1) == 12);
+ }
+
+ /**
+ * Test SAM conversion of method reference in return statement context
+ */
+ private static void testReturnStatement() {
+ Bar bar = test3(0);
+ try {
+ assertTrue(bar.m(1) == 2);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ bar = test3(1);
+ try {
+ assertTrue(bar.m(1) == 3);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ bar = test3(2);
+ try {
+ assertTrue(bar.m(1) == 4);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ bar = test3(3);
+ try {
+ assertTrue(bar.m(1) == 5);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ bar = test3(4);
+ try {
+ assertTrue(bar.m(1) == 6);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ bar = test3(5);
+ try {
+ bar.m(1);
+ assertTrue(false);
+ } catch (MyException e) {
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ }
+
+ /**
+ * Test SAM conversion of method reference in cast context
+ */
+ private static void testCast() {
+ assertTrue(((Foo)A::method1).m(1) == 2);
+ try {
+ assertTrue(((Bar)new A()::method2).m(1) == 3);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ }
+
+ /**
+ * Test SAM conversion of method reference in array initializer context
+ */
+ private static void testArrayInitializer() {
+ Object[] oarray = {"a", 1, (Foo)A::method3}; //last element need a cast
+ Object[] oarray2 = {"a", 1, (Bar)new A()::method4}; //last element need a cast
+ Foo[] farray = {A::method1, new A()::method2, A::method3, new A()::method4, new A()::method5};
+ Bar[] barray = {A::method1, new A()::method2, A::method3, new A()::method4, new A()::method5, A::method6};
+ }
+
+ /**
+ * Test SAM conversion of method reference in conditional expression context
+ */
+ private static void testConditionalExpression(boolean b) {
+ Foo f = b ? A::method3 : new A()::method5;
+ if(b)
+ assertTrue(f.m(1) == 4);
+ else
+ assertTrue(f.m(1) == 6);
+
+ Bar bar = b ? A::method1 : A::method6;
+ if(b) {
+ try {
+ assertTrue(bar.m(1) == 2);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ }
+ else {
+ try {
+ bar.m(1);
+ assertTrue(false);
+ } catch (MyException e) {
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ }
+ }
+
+ /**
+ * Test SAM conversion of method reference in lambda expression body
+ */
+ private static void testLambdaExpressionBody() {
+ Foo f = n -> ((Foo)A::method3).m(n);
+ assertTrue(f.m(1) == 4);
+
+ Bar b = n -> { return ((Foo)new A()::method5).m(n); };
+ try {
+ assertTrue(b.m(1) == 6);
+ } catch (Exception e) {
+ assertTrue(false);
+ }
+ }
+
+ public static void main(String[] args) {
+ testAssignment();
+ testMethodArgument();
+ testReturnStatement();
+ testCast();
+ testArrayInitializer();
+ testConditionalExpression(true);
+ testConditionalExpression(false);
+ testLambdaExpressionBody();
+
+ assertTrue(assertionCount == 38);
+ }
+
+ static class MyException extends Exception {}
+
+ static class A {
+
+ int value = 0;
+
+ A() {
+ }
+
+ A(Foo f) {
+ value = f.m(9);
+ }
+
+ A(Bar b) {
+ try {
+ value = b.m(9);
+ } catch (MyException e){}
+ }
+
+ static Integer method1(int n) {
+ return n + 1;
+ }
+
+ int method2(Integer n) {
+ return value == 0 ? n + 2 : n + value;
+ }
+
+ static int method3(int n) {
+ return n + 3;
+ }
+
+ Integer method4(Integer n) {
+ return value == 0 ? n + 4 : n + value;
+ }
+
+ Integer method5(Integer n) {
+ return value == 0 ? new Integer(n + 5) : new Integer(n + value);
+ }
+
+ static int method6(Integer n) throws MyException{
+ throw new MyException();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/SamConversionComboTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * Test SAM conversion of method references in combinations of different contexts,
+ * lambda body types(statement/expression), boxing/unboxing etc, to verify
+ * SAM conversion being conducted successfully as expected.
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+import javax.tools.StandardJavaFileManager;
+
+public class SamConversionComboTest {
+
+ enum FInterface {
+ A("A", "interface A { Integer m(int i); }"),
+ B("B", "interface B { int m(Integer i); }"),
+ C("C", "interface C { int m(int i) throws Exception; }");
+
+ String interfaceType;
+ String interfaceDef;
+
+ FInterface(String interfaceType, String interfaceDef) {
+ this.interfaceType = interfaceType;
+ this.interfaceDef = interfaceDef;
+ }
+ }
+
+ enum Context {
+ ASSIGNMENT("#FType f = #MR;"),
+ METHOD_CALL("void method1(#FType f) { }\n" +
+ "void method2() {\n" +
+ " method1(#MR);\n" +
+ "}"),
+ CONSTRUCTOR("X x = new X(#MR);"),
+ RETURN_OF_METHOD("#FType method1() {\n" +
+ " return #MR;\n" +
+ "}"),
+ ARRAY_INITIALIZER("#FType[] oarray = {#MR};"),
+ LAMBDA_BODY("#FType f = n -> ((#FType)#MR).m(n);"),
+ CAST("void test() throws Exception { int n = ((#FType)#MR).m(1); }"),
+ CONDITIONAL_EXPRESSION("#FType f = 2 > 1 ? #MR : null;");
+
+ String context;
+
+ Context(String context) {
+ this.context = context;
+ }
+
+ String getContext(FInterface f, MethodReference mr) {
+ return context.replace("#FType", f.interfaceType).replace("#MR", mr.mrValue);
+ }
+ }
+
+ enum MethodReference {
+ METHOD1("X::method1"),
+ METHOD2("new X()::method2"),
+ METHOD3("X::method3"),
+ METHOD4("new X()::method4"),
+ METHOD5("new X()::method5"),
+ METHOD6("X::method6"),
+ METHOD7("X::method7"),
+ METHOD8("X::method8");
+
+ String mrValue;
+
+ MethodReference(String mr) {
+ mrValue = mr;
+ }
+ }
+
+ enum MethodDef {
+ METHOD1(" static Integer method1(int n) {\n" +
+ " return n + 1;\n" +
+ " }\n", 0),
+ METHOD2(" int method2(Integer n) {\n" +
+ " return value == 0 ? n + 2 : n + value;\n" +
+ " }\n", 1),
+ METHOD3(" static int method3(int n) {\n" +
+ " return n + 3;\n" +
+ " }\n", 2),
+ METHOD4(" Integer method4(Integer n) {\n" +
+ " return value == 0 ? n + 4 : n + value;\n" +
+ " }\n", 3),
+ METHOD5(" Integer method5(Integer n) {\n" +
+ " return value == 0 ? new Integer(n + 5) : new Integer(n + value);\n" +
+ " }\n", 4),
+ METHOD6(" static int method6(Integer n) throws Exception{\n" +
+ " throw new Exception();\n" +
+ " }\n", 5),
+ METHOD7(" static int method7(String s){\n" +
+ " return s.length();\n" +
+ " }\n", 6),
+ METHOD8(" static String method8(Integer n){\n" +
+ " return n + \"\";\n" +
+ " }\n", 7);
+
+ String methodStr;
+ int index;
+
+ MethodDef(String ms, int i) {
+ methodStr = ms;
+ index = i;
+ }
+
+ MethodReference getMethodReference() {
+ return MethodReference.values()[index];
+ }
+ }
+
+ SourceFile samSourceFile = new SourceFile("FInterface.java", "#C") {
+ public String toString() {
+ String interfaces = "";
+ for(FInterface fi : FInterface.values())
+ interfaces += fi.interfaceDef + "\n";
+ return template.replace("#C", interfaces);
+ }
+ };
+
+ String clientTemplate = "class Client {\n" +
+ " #Context\n" +
+ "}\n\n" +
+
+ "class X {\n" +
+ " int value = 0;\n\n" +
+
+ " X() {\n" +
+ " }\n\n" +
+
+ " X(A a) {\n" +
+ " value = a.m(9);\n" +
+ " }\n\n" +
+
+ " X(B b) {\n" +
+ " value = b.m(9);\n" +
+ " }\n\n" +
+
+ " X(C c) {\n" +
+ " try {\n" +
+ " value = c.m(9);\n" +
+ " } catch (Exception e){}\n" +
+ " }\n\n" +
+
+ "#MethodDef" +
+ "}";
+
+ SourceFile clientSourceFile = new SourceFile("Client.java", clientTemplate) {
+ public String toString() {
+ return template.replace("#Context", context.getContext(fInterface, methodReference)).replace("#MethodDef", methodDef.methodStr);
+ }
+ };
+
+ boolean checkSamConversion() {
+ if(methodDef == MethodDef.METHOD7 || methodDef == MethodDef.METHOD8)//method signature mismatch
+ return false;
+ if(context != Context.CONSTRUCTOR && fInterface != FInterface.C && methodDef == MethodDef.METHOD6)
+ //method that throws exceptions not thrown by the interface method is a mismatch
+ return false;
+ if(context == Context.CONSTRUCTOR &&
+ methodReference != MethodReference.METHOD1 &&
+ methodReference != MethodReference.METHOD2 &&
+ methodReference != MethodReference.METHOD3)//ambiguous reference
+ return false;
+ return true;
+ }
+
+ void test() throws Exception {
+ System.out.println("\n====================================");
+ System.out.println(fInterface + ", " + context + ", " + methodReference);
+ System.out.println(samSourceFile + "\n" + clientSourceFile);
+
+ DiagnosticChecker dc = new DiagnosticChecker();
+ JavacTask ct = (JavacTask)comp.getTask(null, fm, dc, null, null, Arrays.asList(samSourceFile, clientSourceFile));
+ ct.analyze();
+ if (dc.errorFound == checkSamConversion()) {
+ throw new AssertionError(samSourceFile + "\n\n" + clientSourceFile);
+ }
+ count++;
+ }
+
+ abstract class SourceFile extends SimpleJavaFileObject {
+
+ protected String template;
+
+ public SourceFile(String filename, String template) {
+ super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
+ this.template = template;
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return toString();
+ }
+
+ public abstract String toString();
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound = false;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ errorFound = true;
+ }
+ }
+ }
+
+ FInterface fInterface;
+ Context context;
+ MethodDef methodDef;
+ MethodReference methodReference;
+ static int count = 0;
+
+ static JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+ static StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+ SamConversionComboTest(FInterface f, Context c, MethodDef md) {
+ fInterface = f;
+ context = c;
+ methodDef = md;
+ methodReference = md.getMethodReference();
+ }
+
+ public static void main(String[] args) throws Exception {
+ for(Context ct : Context.values()) {
+ for (FInterface fi : FInterface.values()) {
+ for (MethodDef md: MethodDef.values()) {
+ new SamConversionComboTest(fi, ct, md).test();
+ }
+ }
+ }
+ System.out.println("total tests: " + count);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestFDCCE.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestFDCCE
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/**
+ * Method references and raw types.
+ * @author Robert Field
+ */
+
+@Test
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class MethodReferenceTestFDCCE {
+
+ static void assertCCE(Throwable t) {
+ assertEquals(t.getClass().getName(), "java.lang.ClassCastException");
+ }
+
+ interface Pred<T> { boolean accept(T x); }
+
+ interface Ps { boolean accept(short x); }
+
+ interface Oo { Object too(int x); }
+
+ interface Reto<T> { T m(); }
+
+ class A {}
+ class B extends A {}
+
+ static boolean isMinor(int x) {
+ return x < 18;
+ }
+
+ static boolean tst(A x) {
+ return true;
+ }
+
+ static Object otst(Object x) {
+ return x;
+ }
+
+ static boolean stst(Short x) {
+ return x < 18;
+ }
+
+ static short ritst() {
+ return 123;
+ }
+
+ public void testMethodReferenceFDPrim1() {
+ Pred<Byte> p = MethodReferenceTestFDCCE::isMinor;
+ Pred p2 = p;
+ assertTrue(p2.accept((Byte)(byte)15));
+ }
+
+ public void testMethodReferenceFDPrim2() {
+ Pred<Byte> p = MethodReferenceTestFDCCE::isMinor;
+ Pred p2 = p;
+ assertTrue(p2.accept((byte)15));
+ }
+
+ public void testMethodReferenceFDPrimICCE() {
+ Pred<Byte> p = MethodReferenceTestFDCCE::isMinor;
+ Pred p2 = p;
+ try {
+ p2.accept(15); // should throw CCE
+ fail("Exception should have been thrown");
+ } catch (Throwable t) {
+ assertCCE(t);
+ }
+ }
+
+ public void testMethodReferenceFDPrimOCCE() {
+ Pred<Byte> p = MethodReferenceTestFDCCE::isMinor;
+ Pred p2 = p;
+ try {
+ p2.accept(new Object()); // should throw CCE
+ fail("Exception should have been thrown");
+ } catch (Throwable t) {
+ assertCCE(t);
+ }
+ }
+
+ public void testMethodReferenceFDRef() {
+ Pred<B> p = MethodReferenceTestFDCCE::tst;
+ Pred p2 = p;
+ assertTrue(p2.accept(new B()));
+ }
+
+ public void testMethodReferenceFDRefCCE() {
+ Pred<B> p = MethodReferenceTestFDCCE::tst;
+ Pred p2 = p;
+ try {
+ p2.accept(new A()); // should throw CCE
+ fail("Exception should have been thrown");
+ } catch (Throwable t) {
+ assertCCE(t);
+ }
+ }
+
+ public void testMethodReferenceFDPrimPrim() {
+ Ps p = MethodReferenceTestFDCCE::isMinor;
+ assertTrue(p.accept((byte)15));
+ }
+
+ public void testMethodReferenceFDPrimBoxed() {
+ Ps p = MethodReferenceTestFDCCE::stst;
+ assertTrue(p.accept((byte)15));
+ }
+
+ public void testMethodReferenceFDPrimRef() {
+ Oo p = MethodReferenceTestFDCCE::otst;
+ assertEquals(p.too(15).getClass().getName(), "java.lang.Integer");
+ }
+
+ public void testMethodReferenceFDRet1() {
+ Reto<Short> p = MethodReferenceTestFDCCE::ritst;
+ assertEquals(p.m(), (Short)(short)123);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestInnerDefault.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestInnerDefault
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+interface IDSs { String m(String a); }
+
+interface InDefA {
+ default String xsA__(String s) {
+ return "A__xsA:" + s;
+ }
+
+ default String xsAB_(String s) {
+ return "AB_xsA:" + s;
+ }
+
+}
+
+interface InDefB extends InDefA {
+
+ default String xsAB_(String s) {
+ return "AB_xsB:" + s;
+ }
+
+ default String xs_B_(String s) {
+ return "_B_xsB:" + s;
+ }
+}
+
+@Test
+public class MethodReferenceTestInnerDefault implements InDefB {
+
+ public void testMethodReferenceInnerDefault() {
+ (new In()).testMethodReferenceInnerDefault();
+ }
+
+ class In {
+
+ public void testMethodReferenceInnerDefault() {
+ IDSs q;
+
+ q = MethodReferenceTestInnerDefault.this::xsA__;
+ assertEquals(q.m("*"), "A__xsA:*");
+
+ q = MethodReferenceTestInnerDefault.this::xsAB_;
+ assertEquals(q.m("*"), "AB_xsB:*");
+
+ q = MethodReferenceTestInnerDefault.this::xs_B_;
+ assertEquals(q.m("*"), "_B_xsB:*");
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestInnerInstance.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestInnerInstance
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestInnerInstance {
+
+ public void testMethodReferenceInnerInstance() {
+ cia().cib().testMethodReferenceInstance();
+ }
+
+ public void testMethodReferenceInnerExternal() {
+ cia().cib().testMethodReferenceExternal();
+ }
+
+ interface SI {
+ String m(Integer a);
+ }
+
+ class CIA {
+
+ String xI(Integer i) {
+ return "xI:" + i;
+ }
+
+ public class CIB {
+
+ public void testMethodReferenceInstance() {
+ SI q;
+
+ q = CIA.this::xI;
+ assertEquals(q.m(55), "xI:55");
+ }
+
+ public void testMethodReferenceExternal() {
+ SI q;
+
+ q = (new E())::xI;
+ assertEquals(q.m(77), "ExI:77");
+ }
+ }
+
+ CIB cib() {
+ return new CIB();
+ }
+
+ class E {
+
+ String xI(Integer i) {
+ return "ExI:" + i;
+ }
+ }
+
+ }
+
+ CIA cia() {
+ return new CIA();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestInnerVarArgsThis.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestInnerVarArgsThis
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestInnerVarArgsThis {
+
+ interface NsII {
+
+ String m(Integer a, Integer b);
+ }
+
+ interface Nsiii {
+
+ String m(int a, int b, int c);
+ }
+
+ interface Nsi {
+
+ String m(int a);
+ }
+
+ interface NsaO {
+
+ String m(Object[] a);
+ }
+
+ interface Nsai {
+
+ String m(int[] a);
+ }
+
+ interface Nsvi {
+
+ String m(int... va);
+ }
+
+ class CIA {
+
+ String xvI(Integer... vi) {
+ StringBuilder sb = new StringBuilder("xvI:");
+ for (Integer i : vi) {
+ sb.append(i);
+ sb.append("-");
+ }
+ return sb.toString();
+ }
+
+ String xIvI(Integer f, Integer... vi) {
+ StringBuilder sb = new StringBuilder("xIvI:");
+ sb.append(f);
+ for (Integer i : vi) {
+ sb.append(i);
+ sb.append("-");
+ }
+ return sb.toString();
+ }
+
+ String xvi(int... vi) {
+ int sum = 0;
+ for (int i : vi) {
+ sum += i;
+ }
+ return "xvi:" + sum;
+ }
+
+ String xIvi(Integer f, int... vi) {
+ int sum = 0;
+ for (int i : vi) {
+ sum += i;
+ }
+ return "xIvi:(" + f + ")" + sum;
+ }
+
+ String xvO(Object... vi) {
+ StringBuilder sb = new StringBuilder("xvO:");
+ for (Object i : vi) {
+ if (i.getClass().isArray()) {
+ sb.append("[");
+ int len = Array.getLength(i);
+ for (int x = 0; x < len; ++x) {
+ sb.append(Array.get(i, x));
+ sb.append(",");
+ }
+ sb.append("]");
+
+ } else {
+ sb.append(i);
+ }
+ sb.append("*");
+ }
+ return sb.toString();
+ }
+
+ public class CIB {
+
+ // These should be processed as var args
+ public void testVarArgsNsSuperclass() {
+ NsII q;
+
+ q = CIA.this::xvO;
+ assertEquals(q.m(55, 66), "xvO:55*66*");
+ }
+
+ public void testVarArgsNsArray() {
+ Nsai q;
+
+ q = CIA.this::xvO;
+ assertEquals(q.m(new int[]{55, 66}), "xvO:[55,66,]*");
+ }
+
+ public void testVarArgsNsII() {
+ NsII q;
+
+ q = CIA.this::xvI;
+ assertEquals(q.m(33, 7), "xvI:33-7-");
+
+ q = CIA.this::xIvI;
+ assertEquals(q.m(50, 40), "xIvI:5040-");
+
+ q = CIA.this::xvi;
+ assertEquals(q.m(100, 23), "xvi:123");
+
+ q = CIA.this::xIvi;
+ assertEquals(q.m(9, 21), "xIvi:(9)21");
+ }
+
+ public void testVarArgsNsiii() {
+ Nsiii q;
+
+ q = CIA.this::xvI;
+ assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
+
+ q = CIA.this::xIvI;
+ assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
+
+ q = CIA.this::xvi;
+ assertEquals(q.m(900, 80, 7), "xvi:987");
+
+ q = CIA.this::xIvi;
+ assertEquals(q.m(333, 27, 72), "xIvi:(333)99");
+ }
+
+ public void testVarArgsNsi() {
+ Nsi q;
+
+ q = CIA.this::xvI;
+ assertEquals(q.m(3), "xvI:3-");
+
+ q = CIA.this::xIvI;
+ assertEquals(q.m(888), "xIvI:888");
+
+ q = CIA.this::xvi;
+ assertEquals(q.m(900), "xvi:900");
+
+ q = CIA.this::xIvi;
+ assertEquals(q.m(333), "xIvi:(333)0");
+ }
+
+ // These should NOT be processed as var args
+ public void testVarArgsNsaO() {
+ NsaO q;
+
+ q = CIA.this::xvO;
+ assertEquals(q.m(new String[]{"yo", "there", "dude"}), "xvO:yo*there*dude*");
+ }
+ }
+
+ CIB cib() {
+ return new CIB();
+ }
+
+ class E {
+
+ String xI(Integer i) {
+ return "ExI:" + i;
+ }
+ }
+ }
+
+ CIA cia() {
+ return new CIA();
+ }
+
+ // These should be processed as var args
+ public void testVarArgsNsSuperclass() {
+ cia().cib().testVarArgsNsSuperclass();
+ }
+
+ public void testVarArgsNsArray() {
+ cia().cib().testVarArgsNsArray();
+ }
+
+ public void testVarArgsNsII() {
+ cia().cib().testVarArgsNsII();
+ }
+
+ public void testVarArgsNsiii() {
+ cia().cib().testVarArgsNsiii();
+ }
+
+ public void testVarArgsNsi() {
+ cia().cib().testVarArgsNsi();
+ }
+
+ // These should NOT be processed as var args
+
+ public void testVarArgsNsaO() {
+ cia().cib().testVarArgsNsaO();
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestInstance.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestInstance
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+class MethodReferenceTestInstance_E {
+ String xI(Integer i) {
+ return "ExI:" + i;
+ }
+}
+
+@Test
+public class MethodReferenceTestInstance {
+
+ interface SI { String m(Integer a); }
+
+ String xI(Integer i) {
+ return "xI:" + i;
+ }
+
+ public void testMethodReferenceInstance() {
+ SI q;
+
+ q = this::xI;
+ assertEquals(q.m(55), "xI:55");
+ }
+
+ public void testMethodReferenceExternal() {
+ SI q;
+
+ q = (new MethodReferenceTestInstance_E())::xI;
+ assertEquals(q.m(77), "ExI:77");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestKinds.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestKinds
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestKinds extends MethodReferenceTestKindsSup {
+
+ interface S0 { String get(); }
+ interface S1 { String get(MethodReferenceTestKinds x); }
+ interface S2 { String get(MethodReferenceTestKinds x, MethodReferenceTestKinds y); }
+
+ interface SXN0 { MethodReferenceTestKindsBase make(MethodReferenceTestKinds x); }
+ interface SXN1 { MethodReferenceTestKindsBase make(MethodReferenceTestKinds x, String str); }
+
+ interface SN0 { MethodReferenceTestKindsBase make(); }
+ interface SN1 { MethodReferenceTestKindsBase make(String x); }
+
+ class In extends MethodReferenceTestKindsBase {
+ In(String val) {
+ this.val = val;
+ }
+
+ In() {
+ this("blank");
+ }
+ }
+
+ String instanceMethod0() { return "IM:0-" + this; }
+ String instanceMethod1(MethodReferenceTestKinds x) { return "IM:1-" + this + x; }
+
+ static String staticMethod0() { return "SM:0"; }
+ static String staticMethod1(MethodReferenceTestKinds x) { return "SM:1-" + x; }
+
+ MethodReferenceTestKinds(String val) {
+ super(val);
+ }
+
+ MethodReferenceTestKinds() {
+ super("blank");
+ }
+
+ MethodReferenceTestKinds inst(String val) {
+ return new MethodReferenceTestKinds(val);
+ }
+
+ public void testMRBound() {
+ S0 var = this::instanceMethod0;
+ assertEquals(var.get(), "IM:0-MethodReferenceTestKinds(blank)");
+ }
+
+ public void testMRBoundArg() {
+ S1 var = this::instanceMethod1;
+ assertEquals(var.get(inst("arg")), "IM:1-MethodReferenceTestKinds(blank)MethodReferenceTestKinds(arg)");
+ }
+
+ public void testMRUnbound() {
+ S1 var = MethodReferenceTestKinds::instanceMethod0;
+ assertEquals(var.get(inst("rcvr")), "IM:0-MethodReferenceTestKinds(rcvr)");
+ }
+
+ public void testMRUnboundArg() {
+ S2 var = MethodReferenceTestKinds::instanceMethod1;
+ assertEquals(var.get(inst("rcvr"), inst("arg")), "IM:1-MethodReferenceTestKinds(rcvr)MethodReferenceTestKinds(arg)");
+ }
+
+ public void testMRSuper() {
+ S0 var = super::instanceMethod0;
+ assertEquals(var.get(), "SIM:0-MethodReferenceTestKinds(blank)");
+ }
+
+ public void testMRSuperArg() {
+ S1 var = super::instanceMethod1;
+ assertEquals(var.get(inst("arg")), "SIM:1-MethodReferenceTestKinds(blank)MethodReferenceTestKinds(arg)");
+ }
+
+ public void testMRStatic() {
+ S0 var = MethodReferenceTestKinds::staticMethod0;
+ assertEquals(var.get(), "SM:0");
+ }
+
+ public void testMRStaticArg() {
+ S1 var = MethodReferenceTestKinds::staticMethod1;
+ assertEquals(var.get(inst("arg")), "SM:1-MethodReferenceTestKinds(arg)");
+ }
+
+ public void testMRStaticEval() {
+ MethodReferenceTestKinds evalCheck;
+ S0 var = (evalCheck = inst("discard"))::staticMethod0;
+ assertEquals(evalCheck.toString(), "MethodReferenceTestKinds(discard)");
+ assertEquals(var.get(), "SM:0");
+ }
+
+ public void testMRStaticEvalArg() {
+ MethodReferenceTestKinds evalCheck;
+ S1 var = (evalCheck = inst("discard"))::staticMethod1;
+ assertEquals(evalCheck.toString(), "MethodReferenceTestKinds(discard)");
+ assertEquals(var.get(inst("arg")), "SM:1-MethodReferenceTestKinds(arg)");
+ }
+
+ public void testMRTopLevel() {
+ SN0 var = MethodReferenceTestKindsBase::new;
+ assertEquals(var.make().toString(), "MethodReferenceTestKindsBase(blank)");
+ }
+
+ public void testMRTopLevelArg() {
+ SN1 var = MethodReferenceTestKindsBase::new;
+ assertEquals(var.make("name").toString(), "MethodReferenceTestKindsBase(name)");
+ }
+/* unbound inner case not supported anymore (dropped by EG)
+ public void testMRUnboundInner() {
+ SXN0 var = MethodReferenceTestKinds.In::new;
+ assertEquals(var.make(inst("out")).toString(), "In(blank)");
+ }
+
+ public void testMRUnboundInnerArg() {
+ SXN1 var = MethodReferenceTestKinds.In::new;
+ assertEquals(var.make(inst("out"), "name").toString(), "In(name)");
+ }
+*/
+ public void testMRImplicitInner() {
+ SN0 var = MethodReferenceTestKinds.In::new;
+ assertEquals(var.make().toString(), "In(blank)");
+ }
+
+ public void testMRImplicitInnerArg() {
+ SN1 var = MethodReferenceTestKinds.In::new;
+ assertEquals(var.make("name").toString(), "In(name)");
+ }
+
+}
+
+
+class MethodReferenceTestKindsBase {
+ String val = "unset";
+
+ public String toString() {
+ return getClass().getSimpleName() + "(" + val + ")";
+ }
+
+ MethodReferenceTestKindsBase(String val) {
+ this.val = val;
+ }
+
+ MethodReferenceTestKindsBase() {
+ this("blank");
+ }
+
+}
+
+class MethodReferenceTestKindsSup extends MethodReferenceTestKindsBase {
+ String instanceMethod0() { return "SIM:0-" + this; }
+ String instanceMethod1(MethodReferenceTestKinds x) { return "SIM:1-" + this + x; }
+
+ MethodReferenceTestKindsSup(String val) {
+ super(val);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestNew.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestNew
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestNew {
+
+ interface M0<T> {
+
+ T m();
+ }
+
+ static class N0 {
+
+ N0() {
+ }
+ }
+
+ interface M1<T> {
+
+ T m(Integer a);
+ }
+
+ static class N1 {
+
+ int i;
+
+ N1(int i) {
+ this.i = i;
+ }
+ }
+
+ interface M2<T> {
+
+ T m(Integer n, String o);
+ }
+
+ static class N2 {
+
+ Number n;
+ Object o;
+
+ N2(Number n, Object o) {
+ this.n = n;
+ this.o = o;
+ }
+
+ public String toString() {
+ return "N2(" + n + "," + o + ")";
+ }
+ }
+
+ interface MV {
+
+ NV m(Integer ai, int i);
+ }
+
+ static class NV {
+
+ int i;
+
+ NV(int... v) {
+ i = 0;
+ for (int x : v) {
+ i += x;
+ }
+ }
+
+ public String toString() {
+ return "NV(" + i + ")";
+ }
+ }
+
+ public void testConstructorReference0() {
+ M0<N0> q;
+
+ q = N0::new;
+ assertEquals(q.m().getClass().getSimpleName(), "N0");
+ }
+
+ public void testConstructorReference1() {
+ M1<N1> q;
+
+ q = N1::new;
+ assertEquals(q.m(14).getClass().getSimpleName(), "N1");
+ }
+
+ public void testConstructorReference2() {
+ M2<N2> q;
+
+ q = N2::new;
+ assertEquals(q.m(7, "hi").toString(), "N2(7,hi)");
+ }
+
+ public void testConstructorReferenceVarArgs() {
+ MV q;
+
+ q = NV::new;
+ assertEquals(q.m(5, 45).toString(), "NV(50)");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestNewInner.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestNewInner
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestNewInner {
+
+ String note = "NO NOTE";
+
+ interface M0<T> {
+
+ T m();
+ }
+
+ interface MP<T> {
+
+ T m(MethodReferenceTestNewInner m);
+ }
+
+ class N0 {
+
+ N0() {
+ }
+ }
+
+ interface M1<T> {
+
+ T m(Integer a);
+ }
+
+ class N1 {
+
+ int i;
+
+ N1(int i) {
+ this.i = i;
+ }
+ }
+
+ interface M2<T> {
+
+ T m(Integer n, String o);
+ }
+
+ class N2 {
+
+ Number n;
+ Object o;
+
+ N2(Number n, Object o) {
+ this.n = n;
+ this.o = o;
+ }
+
+ public String toString() {
+ return note + ":N2(" + n + "," + o + ")";
+ }
+ }
+
+ interface MV {
+
+ NV m(Integer ai, int i);
+ }
+
+ class NV {
+
+ int i;
+
+ NV(int... v) {
+ i = 0;
+ for (int x : v) {
+ i += x;
+ }
+ }
+
+ public String toString() {
+ return note + ":NV(" + i + ")";
+ }
+ }
+
+/* unbound constructor case not supported anymore (dropped by EG)
+ public static void testConstructorReferenceP() {
+ MP<N0> q;
+
+ q = N0::new;
+ assertEquals(q.m(new MethodReferenceTestNewInner()).getClass().getSimpleName(), "N0");
+ }
+*/
+ public void testConstructorReference0() {
+ M0<N0> q;
+
+ q = N0::new;
+ assertEquals(q.m().getClass().getSimpleName(), "N0");
+ }
+
+ public void testConstructorReference1() {
+ M1<N1> q;
+
+ q = N1::new;
+ assertEquals(q.m(14).getClass().getSimpleName(), "N1");
+ }
+
+ public void testConstructorReference2() {
+ M2<N2> q;
+
+ note = "T2";
+ q = N2::new;
+ assertEquals(q.m(7, "hi").toString(), "T2:N2(7,hi)");
+ }
+
+ /***
+ public void testConstructorReferenceVarArgs() {
+ MV q;
+
+ note = "TVA";
+ q = NV::new;
+ assertEquals(q.m(5, 45).toString(), "TNV:NV(50)");
+ }
+ ***/
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestSueCase1.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestSueCase1
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestSueCase1 {
+
+ public interface Sam2<T> { public String get(T target, String s); }
+
+ String instanceMethod(String s) { return "2"; }
+ Sam2<MethodReferenceTestSueCase1> var = MethodReferenceTestSueCase1::instanceMethod;
+
+ String m() { return var.get(new MethodReferenceTestSueCase1(), ""); }
+
+ public void testSueCase1() {
+ assertEquals(m(), "2");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestSueCase2.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestSueCase2
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestSueCase2 {
+
+ public interface Sam2<T> { public String get(T target, String s); }
+
+ String instanceMethod(String s) { return "2"; }
+ static Sam2<MethodReferenceTestSueCase2> var = MethodReferenceTestSueCase2::instanceMethod;
+
+ String m() { return var.get(new MethodReferenceTestSueCase2(), ""); }
+
+ public void testSueCase2() {
+ assertEquals(m(), "2");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestSueCase4.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestSueCase4
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestSueCase4 {
+
+ public interface Sam2<T> { public String get(T target, String s); }
+
+ Sam2<Target> var = new Object().equals(new Object()) ? Target::instanceMethod : Target::instanceMethod;
+
+ String m() {
+ return var.get(new Target(), "");
+ }
+
+ static class Target {
+ String instanceMethod(String s) { return "2"; }
+ }
+
+ public void testSueCase4() {
+ assertEquals(m(), "2");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestSuper.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestSuper
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+interface SPRI { String m(String a); }
+
+class SPRA {
+ String xsA__(String s) {
+ return "A__xsA:" + s;
+ }
+
+ String xsA_M(String s) {
+ return "A_MxsA:" + s;
+ }
+
+ String xsAB_(String s) {
+ return "AB_xsA:" + s;
+ }
+
+ String xsABM(String s) {
+ return "ABMxsA:" + s;
+ }
+
+}
+
+class SPRB extends SPRA {
+
+ String xsAB_(String s) {
+ return "AB_xsB:" + s;
+ }
+
+ String xsABM(String s) {
+ return "ABMxsB:" + s;
+ }
+
+ String xs_B_(String s) {
+ return "_B_xsB:" + s;
+ }
+
+ String xs_BM(String s) {
+ return "_BMxsB:" + s;
+ }
+
+}
+
+@Test
+public class MethodReferenceTestSuper extends SPRB {
+
+ String xsA_M(String s) {
+ return "A_MxsM:" + s;
+ }
+
+
+ String xsABM(String s) {
+ return "ABMxsM:" + s;
+ }
+
+ String xs_BM(String s) {
+ return "_BMxsM:" + s;
+ }
+
+ public void testMethodReferenceSuper() {
+ SPRI q;
+
+ q = super::xsA__;
+ assertEquals(q.m("*"), "A__xsA:*");
+
+ q = super::xsA_M;
+ assertEquals(q.m("*"), "A_MxsA:*");
+
+ q = super::xsAB_;
+ assertEquals(q.m("*"), "AB_xsB:*");
+
+ q = super::xsABM;
+ assertEquals(q.m("*"), "ABMxsB:*");
+
+ q = super::xs_B_;
+ assertEquals(q.m("*"), "_B_xsB:*");
+
+ q = super::xs_BM;
+ assertEquals(q.m("*"), "_BMxsB:*");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestSuperDefault.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestSuperDefault
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+interface DSPRI { String m(String a); }
+
+interface DSPRA {
+ default String xsA__(String s) {
+ return "A__xsA:" + s;
+ }
+
+ default String xsAB_(String s) {
+ return "AB_xsA:" + s;
+ }
+
+}
+
+interface DSPRB extends DSPRA {
+
+ default String xsAB_(String s) {
+ return "AB_xsB:" + s;
+ }
+
+ default String xs_B_(String s) {
+ return "_B_xsB:" + s;
+ }
+
+}
+
+@Test
+public class MethodReferenceTestSuperDefault implements DSPRB {
+
+ public void testMethodReferenceSuper() {
+ DSPRI q;
+
+ q = DSPRB.super::xsA__;
+ assertEquals(q.m("*"), "A__xsA:*");
+
+ q = DSPRB.super::xsAB_;
+ assertEquals(q.m("*"), "AB_xsB:*");
+
+ q = DSPRB.super::xs_B_;
+ assertEquals(q.m("*"), "_B_xsB:*");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestTypeConversion.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestTypeConversion
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+class MethodReferenceTestTypeConversion_E<T> {
+ T xI(T t) { return t; }
+}
+
+@Test
+public class MethodReferenceTestTypeConversion {
+
+ interface ISi { int m(Short a); }
+
+ interface ICc { char m(Character a); }
+
+ public void testUnboxObjectToNumberWiden() {
+ ISi q = (new MethodReferenceTestTypeConversion_E<Short>())::xI;
+ assertEquals(q.m((short)77), (short)77);
+ }
+
+ public void testUnboxObjectToChar() {
+ ICc q = (new MethodReferenceTestTypeConversion_E<Character>())::xI;
+ assertEquals(q.m('@'), '@');
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestVarArgs.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestVarArgs
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestVarArgs {
+
+ interface SII {
+
+ String m(Integer a, Integer b);
+ }
+
+ interface Siii {
+
+ String m(int a, int b, int c);
+ }
+
+ interface Si {
+
+ String m(int a);
+ }
+
+ interface SaO {
+
+ String m(Object[] a);
+ }
+
+ interface Sai {
+
+ String m(int[] a);
+ }
+
+ interface Svi {
+
+ String m(int... va);
+ }
+
+ // These should be processed as var args
+
+ static String xvI(Integer... vi) {
+ StringBuilder sb = new StringBuilder("xvI:");
+ for (Integer i : vi) {
+ sb.append(i);
+ sb.append("-");
+ }
+ return sb.toString();
+ }
+
+ static String xIvI(Integer f, Integer... vi) {
+ StringBuilder sb = new StringBuilder("xIvI:");
+ sb.append(f);
+ for (Integer i : vi) {
+ sb.append(i);
+ sb.append("-");
+ }
+ return sb.toString();
+ }
+
+ static String xvi(int... vi) {
+ int sum = 0;
+ for (int i : vi) {
+ sum += i;
+ }
+ return "xvi:" + sum;
+ }
+
+ static String xIvi(Integer f, int... vi) {
+ int sum = 0;
+ for (int i : vi) {
+ sum += i;
+ }
+ return "xIvi:(" + f + ")" + sum;
+ }
+
+ static String xvO(Object... vi) {
+ StringBuilder sb = new StringBuilder("xvO:");
+ for (Object i : vi) {
+ if (i.getClass().isArray()) {
+ sb.append("[");
+ int len = Array.getLength(i);
+ for (int x = 0; x < len; ++x) {
+ sb.append(Array.get(i, x));
+ sb.append(",");
+ }
+ sb.append("]");
+
+ } else {
+ sb.append(i);
+ }
+ sb.append("*");
+ }
+ return sb.toString();
+ }
+
+ public void testVarArgsSuperclass() {
+ SII q;
+
+ q = MethodReferenceTestVarArgs::xvO;
+ assertEquals(q.m(55,66), "xvO:55*66*");
+ }
+
+ public void testVarArgsArray() {
+ Sai q;
+
+ q = MethodReferenceTestVarArgs::xvO;
+ assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
+ }
+
+ public void testVarArgsII() {
+ SII q;
+
+ q = MethodReferenceTestVarArgs::xvI;
+ assertEquals(q.m(33,7), "xvI:33-7-");
+
+ q = MethodReferenceTestVarArgs::xIvI;
+ assertEquals(q.m(50,40), "xIvI:5040-");
+
+ q = MethodReferenceTestVarArgs::xvi;
+ assertEquals(q.m(100,23), "xvi:123");
+
+ q = MethodReferenceTestVarArgs::xIvi;
+ assertEquals(q.m(9,21), "xIvi:(9)21");
+ }
+
+ public void testVarArgsiii() {
+ Siii q;
+
+ q = MethodReferenceTestVarArgs::xvI;
+ assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
+
+ q = MethodReferenceTestVarArgs::xIvI;
+ assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
+
+ q = MethodReferenceTestVarArgs::xvi;
+ assertEquals(q.m(900,80,7), "xvi:987");
+
+ q = MethodReferenceTestVarArgs::xIvi;
+ assertEquals(q.m(333,27, 72), "xIvi:(333)99");
+ }
+
+ public void testVarArgsi() {
+ Si q;
+
+ q = MethodReferenceTestVarArgs::xvI;
+ assertEquals(q.m(3), "xvI:3-");
+
+ q = MethodReferenceTestVarArgs::xIvI;
+ assertEquals(q.m(888), "xIvI:888");
+
+ q = MethodReferenceTestVarArgs::xvi;
+ assertEquals(q.m(900), "xvi:900");
+
+ q = MethodReferenceTestVarArgs::xIvi;
+ assertEquals(q.m(333), "xIvi:(333)0");
+ }
+
+ // These should NOT be processed as var args
+
+ public void testVarArgsaO() {
+ SaO q;
+
+ q = MethodReferenceTestVarArgs::xvO;
+ assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestVarArgsExt.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestVarArgsExt
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+interface NXII { String m(Integer a, Integer b); }
+
+interface NXiii { String m(int a, int b, int c); }
+
+interface NXi { String m(int a); }
+
+interface NXaO { String m(Object[] a); }
+
+interface NXai { String m(int[] a); }
+
+interface NXvi { String m(int... va); }
+
+@Test
+public class MethodReferenceTestVarArgsExt {
+
+ // These should be processed as var args
+
+ public void testVarArgsNXSuperclass() {
+ NXII q;
+
+ q = (new Ext())::xvO;
+ assertEquals(q.m(55,66), "xvO:55*66*");
+ }
+
+ public void testVarArgsNXArray() {
+ NXai q;
+
+ q = (new Ext())::xvO;
+ assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
+ }
+
+ public void testVarArgsNXII() {
+ NXII q;
+
+ q = (new Ext())::xvI;
+ assertEquals(q.m(33,7), "xvI:33-7-");
+
+ q = (new Ext())::xIvI;
+ assertEquals(q.m(50,40), "xIvI:5040-");
+
+ q = (new Ext())::xvi;
+ assertEquals(q.m(100,23), "xvi:123");
+
+ q = (new Ext())::xIvi;
+ assertEquals(q.m(9,21), "xIvi:(9)21");
+ }
+
+ public void testVarArgsNXiii() {
+ NXiii q;
+
+ q = (new Ext())::xvI;
+ assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
+
+ q = (new Ext())::xIvI;
+ assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
+
+ q = (new Ext())::xvi;
+ assertEquals(q.m(900,80,7), "xvi:987");
+
+ q = (new Ext())::xIvi;
+ assertEquals(q.m(333,27, 72), "xIvi:(333)99");
+ }
+
+ public void testVarArgsNXi() {
+ NXi q;
+
+ q = (new Ext())::xvI;
+ assertEquals(q.m(3), "xvI:3-");
+
+ q = (new Ext())::xIvI;
+ assertEquals(q.m(888), "xIvI:888");
+
+ q = (new Ext())::xvi;
+ assertEquals(q.m(900), "xvi:900");
+
+ q = (new Ext())::xIvi;
+ assertEquals(q.m(333), "xIvi:(333)0");
+ }
+
+ // These should NOT be processed as var args
+
+ public void testVarArgsNXaO() {
+ NXaO q;
+
+ q = (new Ext())::xvO;
+ assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
+ }
+
+
+}
+
+class Ext {
+
+ String xvI(Integer... vi) {
+ StringBuilder sb = new StringBuilder("xvI:");
+ for (Integer i : vi) {
+ sb.append(i);
+ sb.append("-");
+ }
+ return sb.toString();
+ }
+
+ String xIvI(Integer f, Integer... vi) {
+ StringBuilder sb = new StringBuilder("xIvI:");
+ sb.append(f);
+ for (Integer i : vi) {
+ sb.append(i);
+ sb.append("-");
+ }
+ return sb.toString();
+ }
+
+ String xvi(int... vi) {
+ int sum = 0;
+ for (int i : vi) {
+ sum += i;
+ }
+ return "xvi:" + sum;
+ }
+
+ String xIvi(Integer f, int... vi) {
+ int sum = 0;
+ for (int i : vi) {
+ sum += i;
+ }
+ return "xIvi:(" + f + ")" + sum;
+ }
+
+ String xvO(Object... vi) {
+ StringBuilder sb = new StringBuilder("xvO:");
+ for (Object i : vi) {
+ if (i.getClass().isArray()) {
+ sb.append("[");
+ int len = Array.getLength(i);
+ for (int x = 0; x < len; ++x) {
+ sb.append(Array.get(i, x));
+ sb.append(",");
+ }
+ sb.append("]");
+
+ } else {
+ sb.append(i);
+ }
+ sb.append("*");
+ }
+ return sb.toString();
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestVarArgsSuper.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestVarArgsSuper
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+class MethodReferenceTestVarArgsSuper_Sub {
+
+ String xvI(Integer... vi) {
+ StringBuilder sb = new StringBuilder("xvI:");
+ for (Integer i : vi) {
+ sb.append(i);
+ sb.append("-");
+ }
+ return sb.toString();
+ }
+
+ String xIvI(Integer f, Integer... vi) {
+ StringBuilder sb = new StringBuilder("xIvI:");
+ sb.append(f);
+ for (Integer i : vi) {
+ sb.append(i);
+ sb.append("-");
+ }
+ return sb.toString();
+ }
+
+ String xvi(int... vi) {
+ int sum = 0;
+ for (int i : vi) {
+ sum += i;
+ }
+ return "xvi:" + sum;
+ }
+
+ String xIvi(Integer f, int... vi) {
+ int sum = 0;
+ for (int i : vi) {
+ sum += i;
+ }
+ return "xIvi:(" + f + ")" + sum;
+ }
+
+ String xvO(Object... vi) {
+ StringBuilder sb = new StringBuilder("xvO:");
+ for (Object i : vi) {
+ if (i.getClass().isArray()) {
+ sb.append("[");
+ int len = Array.getLength(i);
+ for (int x = 0; x < len; ++x) {
+ sb.append(Array.get(i, x));
+ sb.append(",");
+ }
+ sb.append("]");
+
+ } else {
+ sb.append(i);
+ }
+ sb.append("*");
+ }
+ return sb.toString();
+ }
+}
+
+@Test
+public class MethodReferenceTestVarArgsSuper extends MethodReferenceTestVarArgsSuper_Sub {
+
+ interface SPRII { String m(Integer a, Integer b); }
+
+ interface SPRiii { String m(int a, int b, int c); }
+
+ interface SPRi { String m(int a); }
+
+ interface SPRaO { String m(Object[] a); }
+
+ interface SPRai { String m(int[] a); }
+
+ interface SPRvi { String m(int... va); }
+
+ String xvI(Integer... vi) {
+ return "ERROR";
+ }
+
+ String xIvI(Integer f, Integer... vi) {
+ return "ERROR";
+ }
+
+ String xvi(int... vi) {
+ return "ERROR";
+ }
+
+ String xIvi(Integer f, int... vi) {
+ return "ERROR";
+ }
+
+ String xvO(Object... vi) {
+ return "ERROR";
+ }
+
+ // These should be processed as var args
+
+ public void testVarArgsSPRSuperclass() {
+ SPRII q;
+
+ q = super::xvO;
+ assertEquals(q.m(55,66), "xvO:55*66*");
+ }
+
+ public void testVarArgsSPRArray() {
+ SPRai q;
+
+ q = super::xvO;
+ assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
+ }
+
+ public void testVarArgsSPRII() {
+ SPRII q;
+
+ q = super::xvI;
+ assertEquals(q.m(33,7), "xvI:33-7-");
+
+ q = super::xIvI;
+ assertEquals(q.m(50,40), "xIvI:5040-");
+
+ q = super::xvi;
+ assertEquals(q.m(100,23), "xvi:123");
+
+ q = super::xIvi;
+ assertEquals(q.m(9,21), "xIvi:(9)21");
+ }
+
+ public void testVarArgsSPRiii() {
+ SPRiii q;
+
+ q = super::xvI;
+ assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
+
+ q = super::xIvI;
+ assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
+
+ q = super::xvi;
+ assertEquals(q.m(900,80,7), "xvi:987");
+
+ q = super::xIvi;
+ assertEquals(q.m(333,27, 72), "xIvi:(333)99");
+ }
+
+ public void testVarArgsSPRi() {
+ SPRi q;
+
+ q = super::xvI;
+ assertEquals(q.m(3), "xvI:3-");
+
+ q = super::xIvI;
+ assertEquals(q.m(888), "xIvI:888");
+
+ q = super::xvi;
+ assertEquals(q.m(900), "xvi:900");
+
+ q = super::xIvi;
+ assertEquals(q.m(333), "xIvi:(333)0");
+ }
+
+ // These should NOT be processed as var args
+
+ public void testVarArgsSPRaO() {
+ SPRaO q;
+
+ q = super::xvO;
+ assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestVarArgsSuperDefault.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestVarArgsSuperDefault
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+interface MethodReferenceTestVarArgsSuperDefault_I {
+
+ default String xvI(Integer... vi) {
+ StringBuilder sb = new StringBuilder("xvI:");
+ for (Integer i : vi) {
+ sb.append(i);
+ sb.append("-");
+ }
+ return sb.toString();
+ }
+
+ default String xIvI(Integer f, Integer... vi) {
+ StringBuilder sb = new StringBuilder("xIvI:");
+ sb.append(f);
+ for (Integer i : vi) {
+ sb.append(i);
+ sb.append("-");
+ }
+ return sb.toString();
+ }
+
+ default String xvi(int... vi) {
+ int sum = 0;
+ for (int i : vi) {
+ sum += i;
+ }
+ return "xvi:" + sum;
+ }
+
+ default String xIvi(Integer f, int... vi) {
+ int sum = 0;
+ for (int i : vi) {
+ sum += i;
+ }
+ return "xIvi:(" + f + ")" + sum;
+ }
+
+ default String xvO(Object... vi) {
+ StringBuilder sb = new StringBuilder("xvO:");
+ for (Object i : vi) {
+ if (i.getClass().isArray()) {
+ sb.append("[");
+ int len = Array.getLength(i);
+ for (int x = 0; x < len; ++x) {
+ sb.append(Array.get(i, x));
+ sb.append(",");
+ }
+ sb.append("]");
+
+ } else {
+ sb.append(i);
+ }
+ sb.append("*");
+ }
+ return sb.toString();
+ }
+}
+
+@Test
+public class MethodReferenceTestVarArgsSuperDefault implements MethodReferenceTestVarArgsSuperDefault_I {
+
+ interface DSPRII { String m(Integer a, Integer b); }
+
+ interface DSPRiii { String m(int a, int b, int c); }
+
+ interface DSPRi { String m(int a); }
+
+ interface DSPRaO { String m(Object[] a); }
+
+ interface DSPRai { String m(int[] a); }
+
+ interface DSPRvi { String m(int... va); }
+
+ // These should be processed as var args
+
+ public void testVarArgsSPRSuperclass() {
+ DSPRII q;
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xvO;
+ assertEquals(q.m(55,66), "xvO:55*66*");
+ }
+
+ public void testVarArgsSPRArray() {
+ DSPRai q;
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xvO;
+ assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
+ }
+
+ public void testVarArgsSPRII() {
+ DSPRII q;
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xvI;
+ assertEquals(q.m(33,7), "xvI:33-7-");
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvI;
+ assertEquals(q.m(50,40), "xIvI:5040-");
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xvi;
+ assertEquals(q.m(100,23), "xvi:123");
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvi;
+ assertEquals(q.m(9,21), "xIvi:(9)21");
+ }
+
+ public void testVarArgsSPRiii() {
+ DSPRiii q;
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xvI;
+ assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvI;
+ assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xvi;
+ assertEquals(q.m(900,80,7), "xvi:987");
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvi;
+ assertEquals(q.m(333,27, 72), "xIvi:(333)99");
+ }
+
+ public void testVarArgsSPRi() {
+ DSPRi q;
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xvI;
+ assertEquals(q.m(3), "xvI:3-");
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvI;
+ assertEquals(q.m(888), "xIvI:888");
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xvi;
+ assertEquals(q.m(900), "xvi:900");
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xIvi;
+ assertEquals(q.m(333), "xIvi:(333)0");
+ }
+
+ // These should NOT be processed as var args
+
+ public void testVarArgsSPRaO() {
+ DSPRaO q;
+
+ q = MethodReferenceTestVarArgsSuperDefault_I.super::xvO;
+ assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestVarArgsThis.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng MethodReferenceTestVarArgsThis
+ */
+
+import org.testng.annotations.Test;
+import java.lang.reflect.Array;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Robert Field
+ */
+
+interface NsII { String m(Integer a, Integer b); }
+
+interface Nsiii { String m(int a, int b, int c); }
+
+interface Nsi { String m(int a); }
+
+interface NsaO { String m(Object[] a); }
+
+interface Nsai { String m(int[] a); }
+
+interface Nsvi { String m(int... va); }
+
+@Test
+public class MethodReferenceTestVarArgsThis {
+
+ // These should be processed as var args
+
+ String xvI(Integer... vi) {
+ StringBuilder sb = new StringBuilder("xvI:");
+ for (Integer i : vi) {
+ sb.append(i);
+ sb.append("-");
+ }
+ return sb.toString();
+ }
+
+ String xIvI(Integer f, Integer... vi) {
+ StringBuilder sb = new StringBuilder("xIvI:");
+ sb.append(f);
+ for (Integer i : vi) {
+ sb.append(i);
+ sb.append("-");
+ }
+ return sb.toString();
+ }
+
+ String xvi(int... vi) {
+ int sum = 0;
+ for (int i : vi) {
+ sum += i;
+ }
+ return "xvi:" + sum;
+ }
+
+ String xIvi(Integer f, int... vi) {
+ int sum = 0;
+ for (int i : vi) {
+ sum += i;
+ }
+ return "xIvi:(" + f + ")" + sum;
+ }
+
+ String xvO(Object... vi) {
+ StringBuilder sb = new StringBuilder("xvO:");
+ for (Object i : vi) {
+ if (i.getClass().isArray()) {
+ sb.append("[");
+ int len = Array.getLength(i);
+ for (int x = 0; x < len; ++x) {
+ sb.append(Array.get(i, x));
+ sb.append(",");
+ }
+ sb.append("]");
+
+ } else {
+ sb.append(i);
+ }
+ sb.append("*");
+ }
+ return sb.toString();
+ }
+
+ public void testVarArgsNsSuperclass() {
+ NsII q;
+
+ q = this::xvO;
+ assertEquals(q.m(55,66), "xvO:55*66*");
+ }
+
+ public void testVarArgsNsArray() {
+ Nsai q;
+
+ q = this::xvO;
+ assertEquals(q.m(new int[] { 55,66 } ), "xvO:[55,66,]*");
+ }
+
+ public void testVarArgsNsII() {
+ NsII q;
+
+ q = this::xvI;
+ assertEquals(q.m(33,7), "xvI:33-7-");
+
+ q = this::xIvI;
+ assertEquals(q.m(50,40), "xIvI:5040-");
+
+ q = this::xvi;
+ assertEquals(q.m(100,23), "xvi:123");
+
+ q = this::xIvi;
+ assertEquals(q.m(9,21), "xIvi:(9)21");
+ }
+
+ public void testVarArgsNsiii() {
+ Nsiii q;
+
+ q = this::xvI;
+ assertEquals(q.m(3, 2, 1), "xvI:3-2-1-");
+
+ q = this::xIvI;
+ assertEquals(q.m(888, 99, 2), "xIvI:88899-2-");
+
+ q = this::xvi;
+ assertEquals(q.m(900,80,7), "xvi:987");
+
+ q = this::xIvi;
+ assertEquals(q.m(333,27, 72), "xIvi:(333)99");
+ }
+
+ public void testVarArgsNsi() {
+ Nsi q;
+
+ q = this::xvI;
+ assertEquals(q.m(3), "xvI:3-");
+
+ q = this::xIvI;
+ assertEquals(q.m(888), "xIvI:888");
+
+ q = this::xvi;
+ assertEquals(q.m(900), "xvi:900");
+
+ q = this::xIvi;
+ assertEquals(q.m(333), "xIvi:(333)0");
+ }
+
+ // These should NOT be processed as var args
+
+ public void testVarArgsNsaO() {
+ NsaO q;
+
+ q = this::xvO;
+ assertEquals(q.m(new String[] { "yo", "there", "dude" }), "xvO:yo*there*dude*");
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * Automatic test for checking correctness of structural most specific test routine
+ * @run main/timeout=360 StructuralMostSpecificTest
+ */
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.ClientCodeWrapper;
+import com.sun.tools.javac.util.JCDiagnostic;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+public class StructuralMostSpecificTest {
+
+ static int checkCount = 0;
+
+ enum RetTypeKind {
+ SHORT("short"),
+ INT("int"),
+ OBJECT("Object"),
+ INTEGER("Integer"),
+ VOID("void"),
+ J_L_VOID("Void");
+
+ String retTypeStr;
+
+ RetTypeKind(String retTypeStr) {
+ this.retTypeStr = retTypeStr;
+ }
+
+ boolean moreSpecificThan(RetTypeKind rk) {
+ return moreSpecificThan[this.ordinal()][rk.ordinal()];
+ }
+
+ static boolean[][] moreSpecificThan = {
+ // SHORT | INT | OBJECT | INTEGER | VOID | J_L_VOID
+ /* SHORT */ { true , true , true , false , false , false },
+ /* INT */ { false , true , true , true , false , false },
+ /* OBJECT */ { false , false , true , false , false , false },
+ /* INTEGER */ { false , false , true , true , false , false },
+ /* VOID */ { false , false , false , false , true , true },
+ /* J_L_VOID */{ false , false , true , false , false , true } };
+ }
+
+ enum ArgTypeKind {
+ SHORT("short"),
+ INT("int"),
+ BOOLEAN("boolean"),
+ OBJECT("Object"),
+ INTEGER("Integer"),
+ DOUBLE("Double");
+
+ String argTypeStr;
+
+ ArgTypeKind(String typeStr) {
+ this.argTypeStr = typeStr;
+ }
+ }
+
+ enum ExceptionKind {
+ NONE(""),
+ EXCEPTION("throws Exception"),
+ SQL_EXCEPTION("throws java.sql.SQLException"),
+ IO_EXCEPTION("throws java.io.IOException");
+
+ String exceptionStr;
+
+ ExceptionKind(String exceptionStr) {
+ this.exceptionStr = exceptionStr;
+ }
+ }
+
+ enum LambdaReturnKind {
+ VOID("return;"),
+ SHORT("return (short)0;"),
+ INT("return 0;"),
+ INTEGER("return (Integer)null"),
+ NULL("return null;");
+
+ String retStr;
+
+ LambdaReturnKind(String retStr) {
+ this.retStr = retStr;
+ }
+
+ boolean compatibleWith(RetTypeKind rk) {
+ return compatibleWith[rk.ordinal()][ordinal()];
+ }
+
+ static boolean[][] compatibleWith = {
+ // VOID | SHORT | INT | INTEGER | NULL
+ /* SHORT */ { false , true , false , false , false },
+ /* INT */ { false , true , true , true , false },
+ /* OBJECT */ { false , true , true , true , true },
+ /* INTEGER */ { false , false , true , true , true },
+ /* VOID */ { true , false , false , false , false },
+ /* J_L_VOID */{ false , false , false , false , true } };
+
+ boolean needsConversion(RetTypeKind rk) {
+ return needsConversion[rk.ordinal()][ordinal()];
+ }
+
+ static boolean[][] needsConversion = {
+ // VOID | SHORT | INT | INTEGER | NULL
+ /* SHORT */ { false , false , false , false , false },
+ /* INT */ { false , false , false , true , false },
+ /* OBJECT */ { false , true , true , false , false },
+ /* INTEGER */ { false , false , true , false , false },
+ /* VOID */ { false , false , false , false , false },
+ /* J_L_VOID */{ true , false , false , false , false } };
+ }
+
+ public static void main(String... args) throws Exception {
+
+ //create default shared JavaCompiler - reused across multiple compilations
+ JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+ for (LambdaReturnKind lrk : LambdaReturnKind.values()) {
+ for (RetTypeKind rk1 : RetTypeKind.values()) {
+ for (RetTypeKind rk2 : RetTypeKind.values()) {
+ for (ExceptionKind ek1 : ExceptionKind.values()) {
+ for (ExceptionKind ek2 : ExceptionKind.values()) {
+ for (ArgTypeKind ak11 : ArgTypeKind.values()) {
+ for (ArgTypeKind ak12 : ArgTypeKind.values()) {
+ new StructuralMostSpecificTest(lrk, rk1, rk2, ek1, ek2, ak11, ak12).run(comp, fm);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ System.out.println("Total check executed: " + checkCount);
+ }
+
+ LambdaReturnKind lrk;
+ RetTypeKind rt1, rt2;
+ ArgTypeKind ak1, ak2;
+ ExceptionKind ek1, ek2;
+ JavaSource source;
+ DiagnosticChecker diagChecker;
+
+ StructuralMostSpecificTest(LambdaReturnKind lrk, RetTypeKind rt1, RetTypeKind rt2,
+ ExceptionKind ek1, ExceptionKind ek2, ArgTypeKind ak1, ArgTypeKind ak2) {
+ this.lrk = lrk;
+ this.rt1 = rt1;
+ this.rt2 = rt2;
+ this.ek1 = ek1;
+ this.ek2 = ek2;
+ this.ak1 = ak1;
+ this.ak2 = ak2;
+ this.source = new JavaSource();
+ this.diagChecker = new DiagnosticChecker();
+ }
+
+ class JavaSource extends SimpleJavaFileObject {
+
+ String template = "interface SAM1 {\n" +
+ " #R1 m(#A1 a1) #E1;\n" +
+ "}\n" +
+ "interface SAM2 {\n" +
+ " #R2 m(#A2 a1) #E2;\n" +
+ "}\n" +
+ "class Test {\n" +
+ " void m(SAM1 s) { }\n" +
+ " void m(SAM2 s) { }\n" +
+ " { m(x->{ #LR }); }\n" +
+ "}\n";
+
+ String source;
+
+ public JavaSource() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ source = template.replaceAll("#LR", lrk.retStr)
+ .replaceAll("#R1", rt1.retTypeStr)
+ .replaceAll("#R2", rt2.retTypeStr)
+ .replaceAll("#A1", ak1.argTypeStr)
+ .replaceAll("#A2", ak2.argTypeStr)
+ .replaceAll("#E1", ek1.exceptionStr)
+ .replaceAll("#E2", ek2.exceptionStr);
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+ JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+ Arrays.asList("-XDverboseResolution=all,-predef,-internal,-object-init"),
+ null, Arrays.asList(source));
+ try {
+ ct.analyze();
+ } catch (Throwable ex) {
+ throw new AssertionError("Error thron when analyzing the following source:\n" + source.getCharContent(true));
+ }
+ check();
+ }
+
+ void check() {
+ checkCount++;
+
+ if (!lrk.compatibleWith(rt1) || !lrk.compatibleWith(rt2))
+ return;
+
+ if (lrk.needsConversion(rt1) != lrk.needsConversion(rt2))
+ return;
+
+ boolean m1MoreSpecific = moreSpecific(rt1, rt2, ek1, ek2, ak1, ak2);
+ boolean m2MoreSpecific = moreSpecific(rt2, rt1, ek2, ek1, ak2, ak1);
+
+ boolean ambiguous = (m1MoreSpecific == m2MoreSpecific);
+
+ if (ambiguous != diagChecker.ambiguityFound) {
+ throw new Error("invalid diagnostics for source:\n" +
+ source.getCharContent(true) +
+ "\nAmbiguity found: " + diagChecker.ambiguityFound +
+ "\nm1 more specific: " + m1MoreSpecific +
+ "\nm2 more specific: " + m2MoreSpecific +
+ "\nexpected ambiguity: " + ambiguous);
+ }
+
+ if (!ambiguous) {
+ String sigToCheck = m1MoreSpecific ? "m(SAM1)" : "m(SAM2)";
+ if (!sigToCheck.equals(diagChecker.mostSpecificSig)) {
+ throw new Error("invalid most specific method selected:\n" +
+ source.getCharContent(true) +
+ "\nMost specific found: " + diagChecker.mostSpecificSig +
+ "\nm1 more specific: " + m1MoreSpecific +
+ "\nm2 more specific: " + m2MoreSpecific);
+ }
+ }
+ }
+
+ boolean moreSpecific(RetTypeKind rk1, RetTypeKind rk2, ExceptionKind ek1, ExceptionKind ek2,
+ ArgTypeKind ak1, ArgTypeKind ak2) {
+ if (!rk1.moreSpecificThan(rk2))
+ return false;
+
+ if (ak1 != ak2)
+ return false;
+
+ return true;
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean ambiguityFound;
+ String mostSpecificSig;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ try {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
+ diagnostic.getCode().equals("compiler.err.ref.ambiguous")) {
+ ambiguityFound = true;
+ } else if (diagnostic.getKind() == Diagnostic.Kind.NOTE &&
+ diagnostic.getCode().equals("compiler.note.verbose.resolve.multi")) {
+ ClientCodeWrapper.DiagnosticSourceUnwrapper dsu =
+ (ClientCodeWrapper.DiagnosticSourceUnwrapper)diagnostic;
+ JCDiagnostic.MultilineDiagnostic mdiag = (JCDiagnostic.MultilineDiagnostic)dsu.d;
+ int mostSpecificIndex = (Integer)mdiag.getArgs()[2];
+ mostSpecificSig = ((JCDiagnostic)mdiag.getSubdiagnostics().get(mostSpecificIndex)).getArgs()[1].toString();
+ }
+ } catch (RuntimeException t) {
+ t.printStackTrace();
+ throw t;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/speculative/A.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+public class A {
+ public A(NonExistentClass nec) {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/speculative/DiamondFinder.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 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 8003280
+ * @summary Add lambda tests
+ * spurious crashes when running in 'diamond finder' mode
+ * @compile -XDfindDiamond DiamondFinder.java
+ */
+import java.util.*;
+
+class DiamondFinder {
+ Collection<String> f = new HashSet<String>(Arrays.asList("a"));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/speculative/Main.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * On-demand symbol completion during speculative attribution round fails to report error messages
+ * @compile/fail/ref=Main.out -XDrawDiagnostics Main.java
+ */
+class Main {
+ void test() {
+ m(new A(new Object()));
+ m(new A(null));
+ }
+
+ void m(Object o) {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/speculative/Main.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+A.java:25:14: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, A, null)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest11.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * This test is for self referential and recursive lambda expression that have type inference
+ * @compile InferenceTest11.java
+ * @run main InferenceTest11
+ */
+
+public class InferenceTest11 {
+
+ private static void assertTrue(boolean b) {
+ if(!b)
+ throw new AssertionError();
+ }
+
+ static Func<Integer, Integer> f1;
+ static Func<Integer, ? extends Number> f2;
+
+ public static void main(String[] args) {
+
+ f1 = n -> {
+ if(n <= 0)
+ return 0;
+ if(n == 1)
+ return 1;
+ return f1.m(n-1) + f1.m(n-2);
+ };
+ assertTrue(f1.m(-1) == 0);
+ assertTrue(f1.m(0) == 0);
+ assertTrue(f1.m(10) == 55);
+
+ f2 = n -> {
+ if(n <= 1)
+ return 1.0;
+ return 2 * (Double)f2.m(n-1) + 1;
+ };
+ assertTrue(f2.m(4).doubleValue() == 15.0);
+ }
+
+ interface Func<T, V> {
+ V m(T t);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest2.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2011, 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.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.io.Serializable;
+import java.io.File;
+
+/**
+ * @test
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Parameter types inferred from target type in generics without wildcard
+ * @compile InferenceTest2.java
+ * @run main InferenceTest2
+ */
+
+public class InferenceTest2 {
+
+ private static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ public static void main(String[] args) {
+
+ InferenceTest2 test = new InferenceTest2();
+
+ //test SAM1<T>
+ SAM1<String> sam1 = para -> { String result = "";
+ for(String s : para)
+ if(s.compareTo(result) > 0)
+ result = s;
+ return result; };
+ List<String> list = Arrays.asList("a", "b", "c");
+ assertTrue(sam1.m1(list).equals("c"));
+
+ test.method1(para -> para.get(0));
+
+ //test SAM2<T>
+ SAM2<String> sam2 = para -> {para = para.substring(0);};
+ SAM2<Double> sam2_2 = para -> {};
+ SAM2<File> sam2_3 = para -> { if(para.isDirectory())
+ System.out.println("directory");
+ };
+
+ //test SAM3<T>
+ SAM3<String> sam3 = para -> para[0].substring(0, para[0].length()-1);
+ assertTrue(sam3.m3("hello+").equals("hello"));
+
+ SAM3<Integer> sam3_2 = para -> para[0] - para[1];
+ assertTrue(sam3_2.m3(1, -1) == 2);
+
+ SAM3<Double> sam3_3 = para -> para[0] + para[1] + para[2] + para[3];
+ assertTrue(sam3_3.m3(1.0, 2.0, 3.0, 4.0) == 10.0);
+
+ test.method3(para -> para[0] + 1);
+
+ //test SAM6<T>
+ SAM6<String> sam6 = (para1, para2) -> para1.concat(para2);
+ assertTrue(sam6.m6("hello", "world").equals("helloworld"));
+
+ test.method6((para1, para2) -> para1 >= para2? para1 : para2);
+ }
+
+ void method1(SAM1<Integer> sam1) {
+ List<Integer> list = Arrays.asList(3,2,1);
+ assertTrue(sam1.m1(list) == 3);
+ }
+
+ void method3(SAM3<Double> sam3) {
+ assertTrue(sam3.m3(2.5) == 3.5);
+ }
+
+ void method6(SAM6<Long> sam6) {
+ assertTrue(sam6.m6(5L, -5L) == 5);
+ }
+
+ interface SAM1<T> {
+ T m1(List<T> x);
+ }
+
+ interface SAM2<T extends Serializable> {
+ void m2(T x);
+ }
+
+ interface SAM3<T> {
+ T m3(T... x);
+ }
+
+ interface SAM6<T> {
+ T m6(T a, T b);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest2b.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011, 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.util.*;
+
+/**
+ * @test
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Parameter types inferred from target type in generics with wildcard
+ * @compile InferenceTest2b.java
+ * @run main InferenceTest2b
+ */
+
+public class InferenceTest2b {
+
+ private static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ public static void main(String[] args) {
+
+ InferenceTest2b test = new InferenceTest2b();
+
+ test.m1((a, b) -> {return a;});
+ test.m2((a, b) -> {return a;});
+ test.m3((a, b) -> a);
+ }
+
+ interface SAM6<T> {
+ T m6(T a, T b);
+ }
+
+ void m1(SAM6<? super List<?>> s) {
+ System.out.println("m1()");
+ Stack<String> a = new Stack<String>();
+ ArrayList<String> b = new ArrayList<String>();
+ assertTrue(s.m6(a, b) == a);
+
+ Vector<?> c = null;
+ assertTrue(s.m6(c, b) == c);
+ }
+
+ void m2(SAM6<? super Integer> s) {
+ System.out.println("m2()");
+ assertTrue(s.m6(1, 2) == 1);
+ }
+
+ void m3(SAM6<? super Calendar> s) {
+ System.out.println("m3()");
+ Calendar gc = Calendar.getInstance();
+ GregorianCalendar gc2 = new GregorianCalendar();
+ assertTrue(s.m6(gc, gc2) == gc);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest3.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * Interface inheritance, sub-interface resolves the type of the super interface.
+ * @compile InferenceTest3.java
+ * @run main InferenceTest3
+ */
+
+import java.io.File;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+public class InferenceTest3 {
+
+ private static void assertTrue(boolean cond) {
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ public static void main(String[] args) {
+ InferenceTest3 test = new InferenceTest3();
+ test.m1(a -> a.getTime());
+ test.m2(a -> a.toString());
+
+ C<String, Integer> c = a -> a.length();
+ assertTrue(c.m("lambda") == 6);
+
+ E<Double, String> e = a -> Double.toHexString(a);
+ assertTrue(e.m(Double.MAX_VALUE).equals("0x1.fffffffffffffp1023"));
+ assertTrue(e.m(Double.MIN_VALUE).equals("0x0.0000000000001p-1022"));
+ assertTrue(e.m(1.0).equals("0x1.0p0"));
+ }
+
+ private void m1(C<Date, Long> c) {
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ cal.set(1970, 0, 1, 0, 0, 0);
+ cal.set(Calendar.MILLISECOND, 0);
+ Date date = cal.getTime();
+ assertTrue(c.m(date) == 0L);
+ }
+
+ private void m2(E<Integer, String> e) {
+ assertTrue(e.m(2).equals("2"));
+ }
+
+ interface A<T extends Serializable, U> {
+ U m(T t);
+ }
+
+ interface C<X extends Serializable, Y extends Number> extends A<X,Y> {}
+
+ interface E<X extends Serializable, Y extends String> extends A<X,Y> {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest4.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * This test is for generic methods whose type is the same as the type
+ of the generic SAM interface that is taken as the parameter of the
+ generic method; the type can be inferred from the value of the other
+ type arguments
+ * @compile InferenceTest4.java
+ * @run main InferenceTest4
+ */
+
+import java.util.List;
+import java.util.ArrayList;
+
+public class InferenceTest4 {
+
+ private static void assertTrue(boolean b) {
+ if(!b)
+ throw new AssertionError();
+ }
+
+ public static void main(String[] args) {
+ InferenceTest4 test = new InferenceTest4();
+ test.method1(n -> n.size(), "abc", "java.lang.String");
+ test.method1(n -> n.size(), 'c', "java.lang.Character");
+ test.method1(n -> n.size(), 0, "java.lang.Integer");
+ test.method1(n -> n.size(), 0.1, "java.lang.Double");
+ test.method1(n -> n.size(), 0.1f, "java.lang.Float");
+ test.method1(n -> n.size(), 0L, "java.lang.Long");
+ test.method1(n -> n.size(), (short)0, "java.lang.Short");
+ test.method1(n -> n.size(), (byte)0, "java.lang.Byte");
+ test.method1(n -> n.size(), true, "java.lang.Boolean");
+ test.method1(n -> n.size(), new int[]{1, 2, 3}, "[I");
+ test.method1(n -> n.size(), new double[]{1.0}, "[D");
+ test.method1(n -> n.size(), new String[]{}, "[Ljava.lang.String;");
+ }
+
+ <T> void method1(SAM1<T> s, T t, String className) {
+ List<T> list = new ArrayList<T>();
+ System.out.println(className + "-" + t.getClass().getName());
+ assertTrue(t.getClass().getName().equals(className));
+ list.add(t);
+ assertTrue(s.m1(list) == 1);
+ }
+
+ interface SAM1<T> {
+ int m1(List<T> x);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest5.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * This test is for overloaded methods, verify that the specific method is
+ selected when type inference occurs
+ * @compile InferenceTest5.java
+ * @run main InferenceTest5
+ */
+
+import java.util.List;
+import java.io.File;
+
+public class InferenceTest5 {
+
+ private static void assertTrue(boolean b) {
+ if(!b)
+ throw new AssertionError();
+ }
+
+ public static void main(String[] args) {
+ InferenceTest5 test = new InferenceTest5();
+ int n = test.method1((a, b) -> {} );
+ assertTrue(n == 1);
+
+ n = test.method1(() -> null);
+ assertTrue(n == 2);
+
+ n = test.method1(a -> null);
+ assertTrue(n == 3);
+
+ n = test.method1(a -> {});
+ assertTrue(n == 4);
+
+ n = test.method1(() -> {});
+ assertTrue(n == 5);
+
+ n = test.method1((a, b) -> 0);
+ assertTrue(n == 6);
+
+ n = test.method1((a, b) -> null);
+ assertTrue(n == 6);
+
+ n = test.method1((a, b) -> null, (a, b) -> null);
+ assertTrue(n == 7);
+ }
+
+ int method1(SAM1<String> s) {
+ return 1;
+ }
+
+ int method1(SAM2 s) {
+ return 2;
+ }
+
+ int method1(SAM3 s) {
+ return 3;
+ }
+
+ int method1(SAM4 s) {
+ return 4;
+ }
+
+ int method1(SAM5 s) {
+ return 5;
+ }
+
+ int method1(SAM6<?, ? super Integer> s) {
+ return 6;
+ }
+
+ int method1(SAM6<?, ?>... s) {
+ return 7;
+ }
+
+ static interface SAM1<T> {
+ void foo(List<T> a, List<T> b);
+ }
+
+ static interface SAM2 {
+ List<String> foo();
+ }
+
+ static interface SAM3 {
+ String foo(int a);
+ }
+
+ static interface SAM4 {
+ void foo(List<File> a);
+ }
+
+ static interface SAM5 {
+ void foo();
+ }
+
+ static interface SAM6<T, V> {
+ V get(T t, T t2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest789.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2011, 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.io.Serializable;
+import java.util.Calendar;
+
+/**
+ * @test
+ * @bug 8003280
+ * @summary Add lambda tests
+ * This test is for when lambda return type is inferred from target type
+ * @compile InferenceTest789.java
+ * @run main InferenceTest789
+ */
+
+public class InferenceTest789 {
+
+ private static void assertTrue(boolean b) {
+ if(!b)
+ throw new AssertionError();
+ }
+
+ public static void main(String[] args) {
+ InferenceTest789 test = new InferenceTest789();
+ test.method1(() -> 1);
+ SAM1<? extends Number> sam1 = () -> 1.0;
+ SAM1<? extends Serializable> sam1_2 = () -> "a";
+ SAM1<? extends Comparable<?>> sam1_3 = () -> Calendar.getInstance();
+ SAM1<?> sam1_4 = () -> 1.5f;
+
+ SAM2<Number> sam2 = a -> 1;
+ SAM2<? extends Serializable> sam2_2 = a -> 1;
+ }
+
+ void method1(SAM1<?> s) {
+ System.out.println("s.m1()=" + s.m1() + " s.m1().getClass()=" + s.m1().getClass());
+ assertTrue(s.m1().equals(new Integer(1)));
+ }
+
+ interface SAM1<T> {
+ T m1();
+ }
+
+ interface SAM2<T extends Serializable> {
+ T m2(T t);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg1_2.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,58 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Overloaded methods take raw SAM types that have type inference according to SAM descriptor
+ should have ambiguous resolution of method
+ * @compile/fail/ref=InferenceTest_neg1_2.out -XDrawDiagnostics InferenceTest_neg1_2.java
+ */
+
+public class InferenceTest_neg1_2 {
+
+ public static void main(String[] args) {
+ InferenceTest_neg1_2 test = new InferenceTest_neg1_2();
+ test.method(n -> null); //method 1-5 all match
+ test.method(n -> "a"); //method 2, 4 match
+ test.method(n -> 0); //method 1, 3, 5 match
+ }
+
+ void method(SAM1 s) { //method 1
+ Integer i = s.foo("a");
+ }
+
+ void method(SAM2 s) { //method 2
+ String str = s.foo(0);
+ }
+
+ void method(SAM3<Integer> s) { //method 3
+ Integer i = s.get(0);
+ }
+
+ void method(SAM4<Double, String> s) { //method 4
+ String str = s.get(0.0);
+ }
+
+ void method(SAM5<Integer> s) { //method 5
+ Integer i = s.get(0.0);
+ }
+
+ interface SAM1 {
+ Integer foo(String a);
+ }
+
+ interface SAM2 {
+ String foo(Integer a);
+ }
+
+ interface SAM3<T> {
+ T get(T t);
+ }
+
+ interface SAM4<T, V> {
+ V get(T t);
+ }
+
+ interface SAM5<T> {
+ T get(Double i);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg1_2.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,4 @@
+InferenceTest_neg1_2.java:14:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM4<java.lang.Double,java.lang.String>), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5<java.lang.Integer>), InferenceTest_neg1_2
+InferenceTest_neg1_2.java:15:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM2), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM4<java.lang.Double,java.lang.String>), InferenceTest_neg1_2
+InferenceTest_neg1_2.java:16:13: compiler.err.ref.ambiguous: method, kindname.method, method(InferenceTest_neg1_2.SAM3<java.lang.Integer>), InferenceTest_neg1_2, kindname.method, method(InferenceTest_neg1_2.SAM5<java.lang.Integer>), InferenceTest_neg1_2
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,26 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8003280
+ * @summary Add lambda tests
+ * Missing cast to SAM type that causes type inference to not work.
+ * @compile/fail/ref=InferenceTest_neg5.out -XDrawDiagnostics InferenceTest_neg5.java
+ */
+
+import java.util.*;
+
+public class InferenceTest_neg5 {
+ public static void main(String[] args) {
+ InferenceTest_neg5 test = new InferenceTest_neg5();
+ test.method1(n -> {});
+ test.method1((SAM1<String>)n -> {});
+ test.method1((SAM1<Integer>)n -> {n++;});
+ test.method1((SAM1<Comparator<String>>)n -> {List<String> list = Arrays.asList("string1", "string2"); Collections.sort(list,n);});
+ test.method1((SAM1<Thread>)n -> {n.start();});
+ }
+
+ interface SAM1<X> {
+ void m1(X arg);
+ }
+
+ <X> void method1(SAM1<X> s) {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest_neg5.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+InferenceTest_neg5.java:14:13: compiler.err.cant.apply.symbol: kindname.method, method1, InferenceTest_neg5.SAM1<X>, @419, kindname.class, InferenceTest_neg5, (compiler.misc.cyclic.inference: X)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2011, 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 8003280
+ * @summary Add lambda tests
+ * perform automated checks in type inference in lambda expressions in different contexts
+ * @compile TypeInferenceComboTest.java
+ * @run main/timeout=360 TypeInferenceComboTest
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+import javax.tools.StandardJavaFileManager;
+
+public class TypeInferenceComboTest {
+ enum Context {
+ ASSIGNMENT("SAM#Type s = #LBody;"),
+ METHOD_CALL("#GenericDeclKind void method1(SAM#Type s) { }\n" +
+ "void method2() {\n" +
+ " method1(#LBody);\n" +
+ "}"),
+ RETURN_OF_METHOD("SAM#Type method1() {\n" +
+ " return #LBody;\n" +
+ "}"),
+ LAMBDA_RETURN_EXPRESSION("SAM2 s2 = () -> {return (SAM#Type)#LBody;};\n"),
+ ARRAY_INITIALIZER("Object[] oarray = {\"a\", 1, (SAM#Type)#LBody};");
+
+ String context;
+
+ Context(String context) {
+ this.context = context;
+ }
+
+ String getContext(SamKind sk, TypeKind samTargetT, Keyword kw, TypeKind parameterT, TypeKind returnT, LambdaKind lk, ParameterKind pk, GenericDeclKind gdk, LambdaBody lb) {
+ String result = context;
+ if (sk == SamKind.GENERIC) {
+ if(this == Context.METHOD_CALL) {
+ result = result.replaceAll("#GenericDeclKind", gdk.getGenericDeclKind(samTargetT));
+ if(gdk == GenericDeclKind.NON_GENERIC)
+ result = result.replaceAll("#Type", "<" + samTargetT.typeStr + ">");
+ else //#GenericDeclKind is <T> or <T extends xxx>
+ result = result.replaceAll("#Type", "<T>");
+ }
+ else {
+ if(kw == Keyword.VOID)
+ result = result.replaceAll("#Type", "<" + samTargetT.typeStr + ">");
+ else
+ result = result.replaceAll("#Type", "<? " + kw.keyStr + " " + samTargetT.typeStr + ">");
+ }
+ }
+ else
+ result = result.replaceAll("#Type", "").replaceAll("#GenericDeclKind", "");
+
+ return result.replaceAll("#LBody", lb.getLambdaBody(samTargetT, parameterT, returnT, lk, pk));
+ }
+ }
+
+ enum SamKind {
+ GENERIC("interface SAM<T> { #R m(#ARG); }"),
+ NON_GENERIC("interface SAM { #R m(#ARG); }");
+
+ String sam_str;
+
+ SamKind(String sam_str) {
+ this.sam_str = sam_str;
+ }
+
+ String getSam(TypeKind parameterT, TypeKind returnT) {
+ return sam_str.replaceAll("#ARG", parameterT == TypeKind.VOID ? "" : parameterT.typeStr + " arg")
+ .replaceAll("#R", returnT.typeStr);
+ }
+ }
+
+ enum TypeKind {
+ VOID("void", ""),
+ STRING("String", "\"hello\""),
+ INTEGER("Integer", "1"),
+ INT("int", "0"),
+ COMPARATOR("java.util.Comparator<String>", "(java.util.Comparator<String>)(a, b) -> a.length()-b.length()"),
+ SAM("SAM2", "null"),
+ GENERIC("T", null);
+
+ String typeStr;
+ String valStr;
+
+ TypeKind(String typeStr, String valStr) {
+ this.typeStr = typeStr;
+ this.valStr = valStr;
+ }
+ }
+
+ enum LambdaKind {
+ EXPRESSION("#VAL"),
+ STATEMENT("{return #VAL;}");
+
+ String stmt;
+
+ LambdaKind(String stmt) {
+ this.stmt = stmt;
+ }
+ }
+
+ enum ParameterKind {
+ EXPLICIT("#TYPE"),
+ IMPLICIT("");
+
+ String paramTemplate;
+
+ ParameterKind(String paramTemplate) {
+ this.paramTemplate = paramTemplate;
+ }
+ }
+
+ enum Keyword {
+ SUPER("super"),
+ EXTENDS("extends"),
+ VOID("");
+
+ String keyStr;
+
+ Keyword(String keyStr) {
+ this.keyStr = keyStr;
+ }
+ }
+
+ enum LambdaBody {
+ RETURN_VOID("() -> #RET"),//no parameters, return type is one of the TypeKind
+ RETURN_ARG("(#PK arg) -> #RET");//has parameters, return type is one of the TypeKind
+
+ String bodyStr;
+
+ LambdaBody(String bodyStr) {
+ this.bodyStr = bodyStr;
+ }
+
+ String getLambdaBody(TypeKind samTargetT, TypeKind parameterT, TypeKind returnT, LambdaKind lk, ParameterKind pk) {
+ String result = bodyStr.replaceAll("#PK", pk.paramTemplate);
+
+ if(result.contains("#TYPE")) {
+ if (parameterT == TypeKind.GENERIC && this != RETURN_VOID)
+ result = result.replaceAll("#TYPE", samTargetT == null? "": samTargetT.typeStr);
+ else
+ result = result.replaceAll("#TYPE", parameterT.typeStr);
+ }
+ if (this == RETURN_ARG && parameterT == returnT)
+ return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL", "arg"));
+ else {
+ if(returnT != TypeKind.GENERIC)
+ return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL", (returnT==TypeKind.VOID && lk==LambdaKind.EXPRESSION)? "{}" : returnT.valStr));
+ else
+ return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL", samTargetT.valStr));
+ }
+ }
+ }
+
+ enum GenericDeclKind {
+ NON_GENERIC(""),
+ GENERIC_NOBOUND("<T>"),
+ GENERIC_BOUND("<T extends #ExtendedType>");
+ String typeStr;
+
+ GenericDeclKind(String typeStr) {
+ this.typeStr = typeStr;
+ }
+
+ String getGenericDeclKind(TypeKind et) {
+ return typeStr.replaceAll("#ExtendedType", et==null? "":et.typeStr);
+ }
+ }
+
+ boolean checkTypeInference() {
+ if (parameterType == TypeKind.VOID) {
+ if (lambdaBodyType != LambdaBody.RETURN_VOID)
+ return false;
+ }
+ else if (lambdaBodyType != LambdaBody.RETURN_ARG)
+ return false;
+ if ( genericDeclKind == GenericDeclKind.GENERIC_NOBOUND || genericDeclKind == GenericDeclKind.GENERIC_BOUND ) {
+ if ( parameterType == TypeKind.GENERIC && parameterKind == ParameterKind.IMPLICIT) //cyclic inference
+ return false;
+ }
+ return true;
+ }
+
+ String templateStr = "#C\n" +
+ "interface SAM2 {\n" +
+ " SAM m();\n" +
+ "}\n";
+ SourceFile samSourceFile = new SourceFile("Sam.java", templateStr) {
+ public String toString() {
+ return template.replaceAll("#C", samKind.getSam(parameterType, returnType));
+ }
+ };
+
+ SourceFile clientSourceFile = new SourceFile("Client.java",
+ "class Client { \n" +
+ " #Context\n" +
+ "}") {
+ public String toString() {
+ return template.replaceAll("#Context", context.getContext(samKind, samTargetType, keyword, parameterType, returnType, lambdaKind, parameterKind, genericDeclKind, lambdaBodyType));
+ }
+ };
+
+ void test() throws Exception {
+ System.out.println("kk:");
+ StringBuilder sb = new StringBuilder("SamKind:");
+ sb.append(samKind).append(" SamTargetType:").append(samTargetType).append(" ParameterType:").append(parameterType)
+ .append(" ReturnType:").append(returnType).append(" Context:").append(context).append(" LambdaKind:").append(lambdaKind)
+ .append(" LambdaBodyType:").append(lambdaBodyType).append(" ParameterKind:").append(parameterKind).append(" Keyword:").append(keyword);
+ System.out.println(sb);
+ DiagnosticChecker dc = new DiagnosticChecker();
+ JavacTask ct = (JavacTask)comp.getTask(null, fm, dc, null, null, Arrays.asList(samSourceFile, clientSourceFile));
+ ct.analyze();
+ if (dc.errorFound == checkTypeInference()) {
+ throw new AssertionError(samSourceFile + "\n\n" + clientSourceFile + "\n" + parameterType + " " + returnType);
+ }
+ }
+
+ abstract class SourceFile extends SimpleJavaFileObject {
+
+ protected String template;
+
+ public SourceFile(String filename, String template) {
+ super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
+ this.template = template;
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return toString();
+ }
+
+ public abstract String toString();
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound = false;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ errorFound = true;
+ }
+ }
+ }
+
+ SamKind samKind;
+ TypeKind samTargetType;
+ TypeKind parameterType;
+ TypeKind returnType;
+ Context context;
+ LambdaBody lambdaBodyType;
+ LambdaKind lambdaKind;
+ ParameterKind parameterKind;
+ Keyword keyword;
+ GenericDeclKind genericDeclKind;
+
+ static JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+ static StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+ TypeInferenceComboTest(SamKind sk, TypeKind samTargetT, TypeKind parameterT, TypeKind returnT, LambdaBody lb, Context c, LambdaKind lk, ParameterKind pk, Keyword kw, GenericDeclKind gdk) {
+ samKind = sk;
+ samTargetType = samTargetT;
+ parameterType = parameterT;
+ returnType = returnT;
+ context = c;
+ lambdaKind = lk;
+ parameterKind = pk;
+ keyword = kw;
+ lambdaBodyType = lb;
+ genericDeclKind = gdk;
+ }
+
+ public static void main(String[] args) throws Exception {
+ for(Context ct : Context.values()) {
+ for (TypeKind returnT : TypeKind.values()) {
+ for (TypeKind parameterT : TypeKind.values()) {
+ for(LambdaBody lb : LambdaBody.values()) {
+ for (ParameterKind parameterK : ParameterKind.values()) {
+ for(LambdaKind lambdaK : LambdaKind.values()) {
+ for (SamKind sk : SamKind.values()) {
+ if (sk == SamKind.NON_GENERIC) {
+ if(parameterT != TypeKind.GENERIC && returnT != TypeKind.GENERIC )
+ new TypeInferenceComboTest(sk, null, parameterT, returnT, lb, ct, lambdaK, parameterK, null, null).test();
+ }
+ else if (sk == SamKind.GENERIC) {
+ for (Keyword kw : Keyword.values()) {
+ for (TypeKind samTargetT : TypeKind.values()) {
+ if(samTargetT != TypeKind.VOID && samTargetT != TypeKind.INT && samTargetT != TypeKind.GENERIC
+ && (parameterT == TypeKind.GENERIC || returnT == TypeKind.GENERIC)) {
+ if(ct != Context.METHOD_CALL) {
+ new TypeInferenceComboTest(sk, samTargetT, parameterT, returnT, lb, ct, lambdaK, parameterK, kw, null).test();
+ }
+ else {//Context.METHOD_CALL
+ for (GenericDeclKind gdk : GenericDeclKind.values())
+ new TypeInferenceComboTest(sk, samTargetT, parameterT, returnT, lb, ct, lambdaK, parameterK, kw, gdk).test();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/TEST.properties Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,2 @@
+TestNG.dirs = tools/javac/lambdaShapes
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/javac/FDTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+package org.openjdk.tests.javac;
+
+import org.openjdk.tests.shapegen.*;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.util.Pair;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.*;
+
+public class FDTest {
+
+ public enum TestKind {
+ POSITIVE,
+ NEGATIVE;
+
+ Collection<Hierarchy> getHierarchy(HierarchyGenerator hg) {
+ return this == POSITIVE ?
+ hg.getOK() : hg.getErr();
+ }
+ }
+
+ public static JavaCompiler comp;
+ public static StandardJavaFileManager fm;
+
+ @BeforeSuite
+ static void init() {
+ // create default shared JavaCompiler - reused across multiple
+ // compilations
+
+ comp = ToolProvider.getSystemJavaCompiler();
+ fm = comp.getStandardFileManager(null, null, null);
+ }
+
+ public static void main(String[] args) throws Exception {
+ init();
+
+ for (Pair<TestKind,Hierarchy> fdtest : generateCases()) {
+ runTest(fdtest.fst, fdtest.snd, comp, fm);
+ }
+ }
+
+ @Test(dataProvider = "fdCases")
+ public void testOneCase(TestKind tk, Hierarchy hs)
+ throws Exception {
+ FDTest.runTest(tk, hs, comp, fm);
+ }
+
+ @DataProvider(name = "fdCases")
+ public Object[][] caseGenerator() {
+ List<Pair<TestKind, Hierarchy>> cases = generateCases();
+ Object[][] fdCases = new Object[cases.size()][];
+ for (int i = 0; i < cases.size(); ++i) {
+ fdCases[i] = new Object[2];
+ fdCases[i][0] = cases.get(i).fst;
+ fdCases[i][1] = cases.get(i).snd;
+ }
+ return fdCases;
+ }
+
+ public static List<Pair<TestKind, Hierarchy>> generateCases() {
+ ArrayList<Pair<TestKind,Hierarchy>> list = new ArrayList<>();
+ HierarchyGenerator hg = new HierarchyGenerator();
+ for (TestKind tk : TestKind.values()) {
+ for (Hierarchy hs : tk.getHierarchy(hg)) {
+ list.add(new Pair<>(tk, hs));
+ }
+ }
+ return list;
+ }
+
+ public static void runTest(TestKind tk, Hierarchy hs,
+ JavaCompiler comp, StandardJavaFileManager fm) throws Exception {
+ new FDTest(tk, hs).run(comp, fm);
+ }
+
+ TestKind tk;
+ Hierarchy hs;
+ DefenderTestSource source;
+ DiagnosticChecker diagChecker;
+
+ public FDTest() {}
+
+ FDTest(TestKind tk, Hierarchy hs) {
+ this.tk = tk;
+ this.hs = hs;
+ this.source = new DefenderTestSource();
+ this.diagChecker = new DiagnosticChecker();
+ }
+
+ void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+ JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+ null, null, Arrays.asList(source));
+ try {
+ ct.analyze();
+ } catch (Throwable ex) {
+ fail("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
+ }
+ check();
+ }
+
+ void check() {
+ boolean errorExpected = tk == TestKind.NEGATIVE;
+ if (errorExpected != diagChecker.errorFound) {
+ fail("problem in source: \n" +
+ "\nerror found = " + diagChecker.errorFound +
+ "\nerror expected = " + errorExpected +
+ "\n" + dumpHierarchy() +
+ "\n" + source.getCharContent(true));
+ }
+ }
+
+ String dumpHierarchy() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("root = " + hs.root + "\n");
+ for (ClassCase cc : hs.all) {
+ buf.append(" class name = " + cc.getName() + "\n");
+ buf.append(" class OK = " + cc.get_OK() + "\n");
+ buf.append(" prov = " + cc.get_mprov() + "\n");
+
+ }
+ return buf.toString();
+ }
+
+ class DefenderTestSource extends SimpleJavaFileObject {
+
+ String source;
+
+ public DefenderTestSource() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ StringBuilder buf = new StringBuilder();
+ List<ClassCase> defaultRef = new ArrayList<>();
+ for (ClassCase cc : hs.all) {
+ Hierarchy.genClassDef(buf, cc, null, defaultRef);
+ }
+ source = buf.toString();
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ errorFound = true;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/AttributeInjector.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.separate;
+
+import java.io.*;
+
+public class AttributeInjector implements ClassFilePreprocessor {
+
+ private String attributeName;
+ private byte[] attributeData;
+
+ public AttributeInjector(String attributeName, byte[] attributeData) {
+ this.attributeName = attributeName;
+ this.attributeData = attributeData;
+ }
+
+ public byte[] preprocess(String name, byte[] cf) {
+ ClassFile classfile = new ClassFile(cf);
+
+ short cpIndex = (short)classfile.constant_pool.size();
+
+ ClassFile.CpUtf8 entry = new ClassFile.CpUtf8();
+ entry.bytes = new byte[attributeName.length()];
+ for (int i = 0; i < attributeName.length(); ++i) {
+ entry.bytes[i] = (byte)attributeName.charAt(i);
+ }
+
+ classfile.constant_pool.add(entry);
+
+ ClassFile.Attribute attr = new ClassFile.Attribute();
+ attr.attribute_name_index = cpIndex;
+ attr.info = attributeData;
+
+ classfile.attributes.add(attr);
+ return classfile.toByteArray();
+ }
+
+/*
+ public static void main(String argv[]) throws Exception {
+ File input = new File(argv[0]);
+ byte[] buffer = new byte[(int)input.length()];
+ new FileInputStream(input).read(buffer);
+
+ ClassFilePreprocessor cfp =
+ new AttributeInjector("RequiresBridges", new byte[0]);
+ byte[] cf = cfp.preprocess(argv[0], buffer);
+ new FileOutputStream(argv[0] + ".mod").write(cf);
+ }
+*/
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/ClassFile.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,454 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.separate;
+
+import java.io.*;
+import java.util.*;
+
+class CfInputStream extends ByteArrayInputStream {
+ private int ct;
+ public CfInputStream(byte[] input) {
+ super(input);
+ }
+
+ byte u1() { return (byte)read(); }
+ short u2() {
+ int b0 = read() << 8;
+ int b1 = read();
+ return (short)(b0 | b1);
+ }
+ int u4() {
+ int b0 = read() << 24;
+ int b1 = read() << 16;
+ int b2 = read() << 8;
+ int b3 = read();
+ return b0 | b1 | b2 | b3;
+ }
+ byte[] array(int count) {
+ byte[] ret = new byte[count];
+ read(ret, 0, count);
+ return ret;
+ }
+};
+
+class CfOutputStream extends ByteArrayOutputStream {
+ void u1(byte b) { write((int)b); }
+ void u2(short s) {
+ write((s >> 8) & 0xff);
+ write(s & 0xff);
+ }
+ void u4(int i) {
+ write((i >> 24) & 0xff);
+ write((i >> 16) & 0xff);
+ write((i >> 8) & 0xff);
+ write(i & 0xff);
+ }
+ void array(byte[] a) {
+ write(a, 0, a.length);
+ }
+
+ public byte[] toByteArray() { return super.toByteArray(); }
+};
+
+// A quick and dirty class file parser and representation
+public class ClassFile {
+
+ int magic;
+ short minor_version;
+ short major_version;
+ ArrayList<CpEntry> constant_pool;
+ short access_flags;
+ short this_class;
+ short super_class;
+ ArrayList<Interface> interfaces;
+ ArrayList<Field> fields;
+ ArrayList<Method> methods;
+ ArrayList<Attribute> attributes;
+
+ ClassFile(byte[] cf) {
+ CfInputStream in = new CfInputStream(cf);
+
+ magic = in.u4();
+ minor_version = in.u2();
+ major_version = in.u2();
+
+ short cpCount = in.u2();
+ constant_pool = new ArrayList<>();
+ constant_pool.add(new CpNull());
+ for (int i = 1; i < cpCount; ++i) {
+ constant_pool.add(CpEntry.newCpEntry(in));
+ }
+
+ access_flags = in.u2();
+ this_class = in.u2();
+ super_class = in.u2();
+
+ short ifaceCount = in.u2();
+ interfaces = new ArrayList<>();
+ for (int i = 0; i < ifaceCount; ++i) {
+ interfaces.add(new Interface(in));
+ }
+
+ short fieldCount = in.u2();
+ fields = new ArrayList<>();
+ for (int i = 0; i < fieldCount; ++i) {
+ fields.add(new Field(in));
+ }
+
+ short methodCount = in.u2();
+ methods = new ArrayList<>();
+ for (int i = 0; i < methodCount; ++i) {
+ methods.add(new Method(in));
+ }
+
+ short attributeCount = in.u2();
+ attributes = new ArrayList<>();
+ for (int i = 0; i < attributeCount; ++i) {
+ attributes.add(new Attribute(in));
+ }
+ }
+
+ byte[] toByteArray() {
+ CfOutputStream out = new CfOutputStream();
+
+ out.u4(magic);
+ out.u2(minor_version);
+ out.u2(major_version);
+
+ out.u2((short)(constant_pool.size()));
+ for (CpEntry cp : constant_pool) {
+ cp.write(out);
+ }
+
+ out.u2(access_flags);
+ out.u2(this_class);
+ out.u2(super_class);
+
+ out.u2((short)interfaces.size());
+ for (Interface iface : interfaces) {
+ iface.write(out);
+ }
+
+ out.u2((short)fields.size());
+ for (Field field : fields) {
+ field.write(out);
+ }
+
+ out.u2((short)methods.size());
+ for (Method method : methods) {
+ method.write(out);
+ }
+
+ out.u2((short)attributes.size());
+ for (Attribute attribute : attributes) {
+ attribute.write(out);
+ }
+
+ return out.toByteArray();
+ }
+
+ static abstract class CpEntry {
+ byte tag;
+
+ CpEntry(byte t) { tag = t; }
+ void write(CfOutputStream out) {
+ out.u1(tag);
+ }
+
+ static CpEntry newCpEntry(CfInputStream in) {
+ byte tag = in.u1();
+ switch (tag) {
+ case CpUtf8.TAG: return new CpUtf8(in);
+ case CpInteger.TAG: return new CpInteger(in);
+ case CpFloat.TAG: return new CpFloat(in);
+ case CpLong.TAG: return new CpLong(in);
+ case CpDouble.TAG: return new CpDouble(in);
+ case CpClass.TAG: return new CpClass(in);
+ case CpString.TAG: return new CpString(in);
+ case CpFieldRef.TAG: return new CpFieldRef(in);
+ case CpMethodRef.TAG: return new CpMethodRef(in);
+ case CpInterfaceMethodRef.TAG:
+ return new CpInterfaceMethodRef(in);
+ case CpNameAndType.TAG: return new CpNameAndType(in);
+ case CpMethodHandle.TAG: return new CpMethodHandle(in);
+ case CpMethodType.TAG: return new CpMethodType(in);
+ case CpInvokeDynamic.TAG: return new CpInvokeDynamic(in);
+ default: throw new RuntimeException("Bad cp entry tag: " + tag);
+ }
+ }
+ }
+
+ static class CpNull extends CpEntry {
+ CpNull() { super((byte)0); }
+ CpNull(CfInputStream in) { super((byte)0); }
+ void write(CfOutputStream out) {}
+ }
+
+ static class CpUtf8 extends CpEntry {
+ static final byte TAG = 1;
+ byte[] bytes;
+
+ CpUtf8() { super(TAG); }
+ CpUtf8(CfInputStream in) {
+ this();
+ short length = in.u2();
+ bytes = in.array(length);
+ }
+ void write(CfOutputStream out) {
+ super.write(out);
+ out.u2((short)bytes.length);
+ out.array(bytes);
+ }
+ }
+
+ static class CpU4Constant extends CpEntry {
+ byte[] bytes;
+
+ CpU4Constant(byte tag) { super(tag); }
+ CpU4Constant(byte tag, CfInputStream in) {
+ this(tag);
+ bytes = in.array(4);
+ }
+ void write(CfOutputStream out) { super.write(out); out.array(bytes); }
+ }
+ static class CpInteger extends CpU4Constant {
+ static final byte TAG = 3;
+ CpInteger() { super(TAG); }
+ CpInteger(CfInputStream in) { super(TAG, in); }
+ }
+ static class CpFloat extends CpU4Constant {
+ static final byte TAG = 4;
+ CpFloat() { super(TAG); }
+ CpFloat(CfInputStream in) { super(TAG, in); }
+ }
+
+ static class CpU8Constant extends CpEntry {
+ byte[] bytes;
+
+ CpU8Constant(byte tag) { super(tag); }
+ CpU8Constant(byte tag, CfInputStream in) {
+ this(tag);
+ bytes = in.array(8);
+ }
+ void write(CfOutputStream out) { super.write(out); out.array(bytes); }
+ }
+ static class CpLong extends CpU8Constant {
+ static final byte TAG = 5;
+ CpLong() { super(TAG); }
+ CpLong(CfInputStream in) { super(TAG, in); }
+ }
+ static class CpDouble extends CpU8Constant {
+ static final byte TAG = 6;
+ CpDouble() { super(TAG); }
+ CpDouble(CfInputStream in) { super(TAG, in); }
+ }
+
+ static class CpClass extends CpEntry {
+ static final byte TAG = 7;
+ short name_index;
+
+ CpClass() { super(TAG); }
+ CpClass(CfInputStream in) { super(TAG); name_index = in.u2(); }
+ void write(CfOutputStream out) {
+ super.write(out);
+ out.u2(name_index);
+ }
+ }
+
+ static class CpString extends CpEntry {
+ static final byte TAG = 8;
+ short string_index;
+
+ CpString() { super(TAG); }
+ CpString(CfInputStream in) { super(TAG); string_index = in.u2(); }
+ void write(CfOutputStream out) {
+ super.write(out);
+ out.u2(string_index);
+ }
+ }
+
+ static class CpRef extends CpEntry {
+ short class_index;
+ short name_and_type_index;
+
+ CpRef(byte tag) { super(tag); }
+ CpRef(byte tag, CfInputStream in) {
+ this(tag);
+ class_index = in.u2();
+ name_and_type_index = in.u2();
+ }
+ void write(CfOutputStream out) {
+ super.write(out);
+ out.u2(class_index);
+ out.u2(name_and_type_index);
+ }
+ }
+ static class CpFieldRef extends CpRef {
+ static final byte TAG = 9;
+ CpFieldRef() { super(TAG); }
+ CpFieldRef(CfInputStream in) { super(TAG, in); }
+ }
+ static class CpMethodRef extends CpRef {
+ static final byte TAG = 10;
+ CpMethodRef() { super(TAG); }
+ CpMethodRef(CfInputStream in) { super(TAG, in); }
+ }
+ static class CpInterfaceMethodRef extends CpRef {
+ static final byte TAG = 11;
+ CpInterfaceMethodRef() { super(TAG); }
+ CpInterfaceMethodRef(CfInputStream in) { super(TAG, in); }
+ }
+
+ static class CpNameAndType extends CpEntry {
+ static final byte TAG = 12;
+ short name_index;
+ short descriptor_index;
+
+ CpNameAndType() { super(TAG); }
+ CpNameAndType(CfInputStream in) {
+ this();
+ name_index = in.u2();
+ descriptor_index = in.u2();
+ }
+ void write(CfOutputStream out) {
+ super.write(out);
+ out.u2(name_index);
+ out.u2(descriptor_index);
+ }
+ }
+
+ static class CpMethodHandle extends CpEntry {
+ static final byte TAG = 15;
+ byte reference_kind;
+ short reference_index;
+
+ CpMethodHandle() { super(TAG); }
+ CpMethodHandle(CfInputStream in) {
+ this();
+ reference_kind = in.u1();
+ reference_index = in.u2();
+ }
+ void write(CfOutputStream out) {
+ super.write(out);
+ out.u1(reference_kind);
+ out.u2(reference_index);
+ }
+ }
+
+ static class CpMethodType extends CpEntry {
+ static final byte TAG = 16;
+ short descriptor_index;
+
+ CpMethodType() { super(TAG); }
+ CpMethodType(CfInputStream in) {
+ this();
+ descriptor_index = in.u2();
+ }
+ void write(CfOutputStream out) {
+ super.write(out);
+ out.u2(descriptor_index);
+ }
+ }
+
+ static class CpInvokeDynamic extends CpEntry {
+ static final byte TAG = 18;
+ short bootstrap_index;
+ short name_and_type_index;
+
+ CpInvokeDynamic() { super(TAG); }
+ CpInvokeDynamic(CfInputStream in) {
+ this();
+ bootstrap_index = in.u2();
+ name_and_type_index = in.u2();
+ }
+ void write(CfOutputStream out) {
+ super.write(out);
+ out.u2(bootstrap_index);
+ out.u2(name_and_type_index);
+ }
+ }
+
+ static class Interface {
+ short index;
+
+ Interface() {}
+ Interface(CfInputStream in) { index = in.u2(); }
+ void write(CfOutputStream out) { out.u2(index); }
+ }
+
+ static class FieldOrMethod {
+ short access_flags;
+ short name_index;
+ short descriptor_index;
+ ArrayList<Attribute> attributes;
+
+ FieldOrMethod() { attributes = new ArrayList<>(); }
+ FieldOrMethod(CfInputStream in) {
+ access_flags = in.u2();
+ name_index = in.u2();
+ descriptor_index = in.u2();
+
+ short attrCount = in.u2();
+ attributes = new ArrayList<>();
+ for (int i = 0; i < attrCount; ++i) {
+ attributes.add(new Attribute(in));
+ }
+ }
+ void write(CfOutputStream out) {
+ out.u2(access_flags);
+ out.u2(name_index);
+ out.u2(descriptor_index);
+ out.u2((short)attributes.size());
+ for (Attribute attribute : attributes) { attribute.write(out); }
+ }
+ }
+
+ static class Field extends FieldOrMethod {
+ Field() {}
+ Field(CfInputStream in) { super(in); }
+ }
+ static class Method extends FieldOrMethod {
+ Method() {}
+ Method(CfInputStream in) { super(in); }
+ }
+
+ static class Attribute {
+ short attribute_name_index;
+ byte[] info;
+
+ Attribute() { info = new byte[0]; }
+ Attribute(CfInputStream in) {
+ attribute_name_index = in.u2();
+ int length = in.u4();
+ info = in.array(length);
+ }
+ void write(CfOutputStream out) {
+ out.u2(attribute_name_index);
+ out.u4(info.length);
+ out.array(info);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/ClassFilePreprocessor.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.separate;
+
+public interface ClassFilePreprocessor {
+ public byte[] preprocess(String name, byte[] classfile);
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/ClassToInterfaceConverter.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.separate;
+
+import java.io.*;
+import java.util.*;
+
+public class ClassToInterfaceConverter implements ClassFilePreprocessor {
+
+ private String whichClass;
+
+ public ClassToInterfaceConverter(String className) {
+ this.whichClass = className;
+ }
+
+ private boolean utf8Matches(ClassFile.CpEntry entry, String v) {
+ if (!(entry instanceof ClassFile.CpUtf8)) {
+ return false;
+ }
+ ClassFile.CpUtf8 utf8 = (ClassFile.CpUtf8)entry;
+ if (v.length() != utf8.bytes.length) {
+ return false;
+ }
+ for (int i = 0; i < v.length(); ++i) {
+ if (v.charAt(i) != utf8.bytes[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void convertToInterface(ClassFile cf) {
+ cf.access_flags = 0x0601; // ACC_INTERFACE | ACC_ABSTRACT | ACC_PUBLIC
+ ArrayList<ClassFile.Method> new_methods = new ArrayList<>();
+ // Find <init> method and delete it
+ for (int i = 0; i < cf.methods.size(); ++i) {
+ ClassFile.Method method = cf.methods.get(i);
+ ClassFile.CpEntry name = cf.constant_pool.get(method.name_index);
+ if (!utf8Matches(name, "<init>")) {
+ new_methods.add(method);
+ }
+ }
+ cf.methods = new_methods;
+ }
+
+ public byte[] preprocess(String classname, byte[] bytes) {
+ ClassFile cf = new ClassFile(bytes);
+
+ ClassFile.CpEntry entry = cf.constant_pool.get(cf.this_class);
+ ClassFile.CpEntry name = cf.constant_pool.get(
+ ((ClassFile.CpClass)entry).name_index);
+ if (utf8Matches(name, whichClass)) {
+ convertToInterface(cf);
+ return cf.toByteArray();
+ } else {
+ return bytes; // unmodified
+ }
+ }
+
+/*
+ public static void main(String argv[]) throws Exception {
+ File input = new File(argv[0]);
+ byte[] buffer = new byte[(int)input.length()];
+ new FileInputStream(input).read(buffer);
+
+ ClassFilePreprocessor cfp = new ClassToInterfaceConverter("Hello");
+ byte[] cf = cfp.preprocess(argv[0], buffer);
+ new FileOutputStream(argv[0] + ".mod").write(cf);
+ }
+*/
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/Compiler.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.separate;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.ConcurrentHashMap;
+import java.io.*;
+import java.net.URI;
+import javax.tools.*;
+
+import com.sun.source.util.JavacTask;
+
+import static org.openjdk.tests.separate.SourceModel.Type;
+import static org.openjdk.tests.separate.SourceModel.Class;
+import static org.openjdk.tests.separate.SourceModel.Extends;
+import static org.openjdk.tests.separate.SourceModel.SourceProcessor;
+
+public class Compiler {
+
+ public enum Flags {
+ VERBOSE, // Prints out files as they are compiled
+ USECACHE // Keeps results around for reuse. Only use this is
+ // you're sure that each compilation name maps to the
+ // same source code
+ };
+
+ private static final AtomicInteger counter = new AtomicInteger();
+ private static final String targetDir = "gen-separate";
+ private static final File root = new File(targetDir);
+ private static ConcurrentHashMap<String,File> cache =
+ new ConcurrentHashMap<>();
+
+ Set<Flags> flags;
+
+ private JavaCompiler systemJavaCompiler;
+ private StandardJavaFileManager fm;
+ private List<File> tempDirs;
+ private List<ClassFilePreprocessor> postprocessors;
+
+ private static class SourceFile extends SimpleJavaFileObject {
+ private final String content;
+
+ public SourceFile(String name, String content) {
+ super(URI.create("myfo:/" + name + ".java"), Kind.SOURCE);
+ this.content = content;
+ }
+
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return toString();
+ }
+
+ public String toString() { return this.content; }
+ }
+
+ public Compiler(Flags ... flags) {
+ setFlags(flags);
+ this.tempDirs = new ArrayList<>();
+ this.postprocessors = new ArrayList<>();
+ this.systemJavaCompiler = ToolProvider.getSystemJavaCompiler();
+ this.fm = systemJavaCompiler.getStandardFileManager(null, null, null);
+ }
+
+ public void setFlags(Flags ... flags) {
+ this.flags = new HashSet<Flags>(Arrays.asList(flags));
+ }
+
+ public void addPostprocessor(ClassFilePreprocessor cfp) {
+ this.postprocessors.add(cfp);
+ }
+
+ /**
+ * Compile hierarchies starting with each of the 'types' and return
+ * a ClassLoader that can be used to load the compiled classes.
+ */
+ public ClassLoader compile(Type ... types) {
+ ClassFilePreprocessor[] cfps = this.postprocessors.toArray(
+ new ClassFilePreprocessor[0]);
+
+ DirectedClassLoader dcl = new DirectedClassLoader(cfps);
+
+ for (Type t : types) {
+ for (Map.Entry<String,File> each : compileHierarchy(t).entrySet()) {
+ dcl.setLocationFor(each.getKey(), each.getValue());
+ }
+ }
+ return dcl;
+ }
+
+ /**
+ * Compiles and loads a hierarchy, starting at 'type'
+ */
+ public java.lang.Class<?> compileAndLoad(Type type)
+ throws ClassNotFoundException {
+
+ ClassLoader loader = compile(type);
+ return java.lang.Class.forName(type.getName(), false, loader);
+ }
+
+ /**
+ * Compiles a hierarchy, starting at 'type' and return a mapping of the
+ * name to the location where the classfile for that type resides.
+ */
+ private Map<String,File> compileHierarchy(Type type) {
+ HashMap<String,File> outputDirs = new HashMap<>();
+
+ File outDir = compileOne(type);
+ outputDirs.put(type.getName(), outDir);
+
+ Class superClass = type.getSuperclass();
+ if (superClass != null) {
+ for( Map.Entry<String,File> each : compileHierarchy(superClass).entrySet()) {
+ outputDirs.put(each.getKey(), each.getValue());
+ }
+ }
+ for (Extends ext : type.getSupertypes()) {
+ Type iface = ext.getType();
+ for( Map.Entry<String,File> each : compileHierarchy(iface).entrySet()) {
+ outputDirs.put(each.getKey(), each.getValue());
+ }
+ }
+
+ return outputDirs;
+ }
+
+ private File compileOne(Type type) {
+ if (this.flags.contains(Flags.USECACHE)) {
+ File dir = cache.get(type.getName());
+ if (dir != null) {
+ return dir;
+ }
+ }
+ List<JavaFileObject> files = new ArrayList<>();
+ SourceProcessor accum =
+ (name, src) -> { files.add(new SourceFile(name, src)); };
+
+ for (Type dep : type.typeDependencies()) {
+ dep.generateAsDependency(accum, type.methodDependencies());
+ }
+
+ type.generate(accum);
+
+ JavacTask ct = (JavacTask)this.systemJavaCompiler.getTask(
+ null, this.fm, null, null, null, files);
+ File destDir = null;
+ do {
+ int value = counter.incrementAndGet();
+ destDir = new File(root, Integer.toString(value));
+ } while (destDir.exists());
+
+ if (this.flags.contains(Flags.VERBOSE)) {
+ System.out.println("Compilation unit for " + type.getName() +
+ " : compiled into " + destDir);
+ for (JavaFileObject jfo : files) {
+ System.out.println(jfo.toString());
+ }
+ }
+
+ try {
+ destDir.mkdirs();
+ this.fm.setLocation(
+ StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir));
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "IOException encountered during compilation");
+ }
+ Boolean result = ct.call();
+ if (result == Boolean.FALSE) {
+ throw new RuntimeException(
+ "Compilation failure in " + type.getName() + " unit");
+ }
+ if (this.flags.contains(Flags.USECACHE)) {
+ File existing = cache.putIfAbsent(type.getName(), destDir);
+ if (existing != null) {
+ deleteDir(destDir);
+ return existing;
+ }
+ } else {
+ this.tempDirs.add(destDir);
+ }
+ return destDir;
+ }
+
+ private static void deleteDir(File dir) {
+ for (File f : dir.listFiles()) {
+ f.delete();
+ };
+ dir.delete();
+ }
+
+ public void cleanup() {
+ if (!this.flags.contains(Flags.USECACHE)) {
+ for (File d : tempDirs) {
+ deleteDir(d);
+ };
+ tempDirs = new ArrayList<>();
+ }
+ }
+
+ // Removes all of the elements in the cache and deletes the associated
+ // output directories. This may not actually empty the cache if there
+ // are concurrent users of it.
+ public static void purgeCache() {
+ for (Map.Entry<String,File> entry : cache.entrySet()) {
+ cache.remove(entry.getKey());
+ deleteDir(entry.getValue());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/DirectedClassLoader.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.separate;
+
+import java.util.HashMap;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+class DirectedClassLoader extends ClassLoader {
+
+ private HashMap<String,File> loadLocations;
+ private File defaultLocation;
+ private ClassFilePreprocessor[] preprocessors;
+
+ public DirectedClassLoader(
+ HashMap<String,File> locations, File fallback,
+ ClassFilePreprocessor ... preprocessors) {
+ loadLocations = new HashMap<>(locations);
+ defaultLocation = fallback;
+ this.preprocessors = preprocessors;
+ }
+
+ public DirectedClassLoader(
+ File fallback, ClassFilePreprocessor ... preprocessors) {
+ loadLocations = new HashMap<>();
+ defaultLocation = fallback;
+ this.preprocessors = preprocessors;
+ }
+
+ public DirectedClassLoader(ClassFilePreprocessor ... preprocessors) {
+ this((File)null, preprocessors);
+ }
+
+ public void setDefaultLocation(File dir) { this.defaultLocation = dir; }
+ public void setLocationFor(String name, File dir) {
+ loadLocations.put(name, dir);
+ }
+
+ @Override
+ protected Class<?> findClass(String name) {
+ String path = name.replace(".", File.separator) + ".class";
+
+ File location = loadLocations.get(name);
+ if (location == null || !(new File(location, path)).exists()) {
+ File def = new File(defaultLocation, path);
+ if (def.exists()) {
+ return defineFrom(name, new File(location, path));
+ }
+ } else {
+ return defineFrom(name, new File(location, path));
+ }
+ return null;
+ }
+
+ private Class<?> defineFrom(String name, File file) {
+ FileInputStream fis = null;
+ try {
+ try {
+ fis = new FileInputStream(file);
+ byte[] bytes = new byte[fis.available()];
+ int read = fis.read(bytes);
+ if (read != bytes.length) {
+ return null;
+ }
+ if (preprocessors != null) {
+ for (ClassFilePreprocessor cfp : preprocessors) {
+ bytes = cfp.preprocess(name, bytes);
+ }
+ }
+ return defineClass(name, bytes, 0, bytes.length);
+ } finally {
+ fis.close();
+ }
+ } catch (IOException e) {}
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/SourceModel.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,582 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.separate;
+
+import java.util.*;
+import java.io.StringWriter;
+import java.io.PrintWriter;
+
+public class SourceModel {
+
+ public static final String stdMethodName = "m";
+
+ public static interface SourceProcessor {
+ // Called with a generated source file
+ void process(String name, String content);
+ }
+
+ public static abstract class Element {
+
+ protected abstract void generate(PrintWriter pw);
+
+ public String toString() {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ generate(pw);
+ return sw.toString();
+ }
+ };
+
+ public static class AccessFlag extends Element {
+ private String flag;
+
+ public AccessFlag(String name) { flag = name; }
+
+ protected void generate(PrintWriter pw) {
+ pw.print(flag);
+ }
+
+ public String toString() { return flag; }
+
+ public static final AccessFlag PUBLIC = new AccessFlag("public");
+ public static final AccessFlag PRIVATE = new AccessFlag("private");
+ public static final AccessFlag PROTECTED = new AccessFlag("protected");
+ public static final AccessFlag STATIC = new AccessFlag("static");
+ public static final AccessFlag FINAL = new AccessFlag("final");
+ public static final AccessFlag SYNCHRONIZED = new AccessFlag("synchronized");
+ public static final AccessFlag VOLATILE = new AccessFlag("volatile");
+ public static final AccessFlag NATIVE = new AccessFlag("native");
+ public static final AccessFlag ABSTRACT = new AccessFlag("abstract");
+ public static final AccessFlag STRICTFP = new AccessFlag("strictfp");
+ public static final AccessFlag DEFAULT = new AccessFlag("default");
+ }
+
+ public static class TypeParameter extends Element {
+ private String parameter;
+
+ public TypeParameter(String str) {
+ this.parameter = str;
+ }
+
+ protected void generate(PrintWriter pw) {
+ pw.print(parameter);
+ }
+ }
+
+ public static class TypeArgument extends Element {
+ private String argument;
+
+ public TypeArgument(String str) {
+ this.argument = str;
+ }
+
+ protected void generate(PrintWriter pw) {
+ pw.print(argument);
+ }
+ }
+
+ public static class MethodParameter extends Element {
+ private String type;
+ private String name;
+
+ public MethodParameter(String type, String name) {
+ this.type = type;
+ this.name = name;
+ }
+
+ protected void generate(PrintWriter pw) {
+ pw.printf("%s %s", this.type, this.name);
+ }
+
+ public String toString() { return type + " " + name; }
+ }
+
+ public static abstract class Type extends Element {
+ private String name;
+ private List<AccessFlag> accessFlags;
+ private List<TypeParameter> parameters;
+ private List<Extends> supertypes;
+ private List<Method> methods;
+
+ // methods from superclasses that are required for compilation
+ // (and thus will be present in stubs)
+ private Set<Method> methodDependencies;
+ private List<Type> typeDependencies;
+
+ protected Type(String name,
+ List<AccessFlag> flags, List<TypeParameter> params,
+ List<Extends> ifaces, List<Method> methods) {
+ this.name = name;
+ this.accessFlags = flags == null ? new ArrayList<>() : flags;
+ this.parameters = params == null ? new ArrayList<>() : params;
+ this.supertypes = ifaces == null ? new ArrayList<>() : ifaces;
+ this.methods = methods == null ? new ArrayList<>() : methods;
+ this.methodDependencies = new HashSet<>();
+ this.typeDependencies = new ArrayList<>();
+ }
+
+ public String getName() { return this.name; }
+ public List<AccessFlag> getAccessFlags() { return this.accessFlags; }
+ public List<TypeParameter> getParameters() { return this.parameters; }
+ public List<Extends> getSupertypes() { return this.supertypes; }
+ public List<Method> getMethods() { return this.methods; }
+ public Set<Method> methodDependencies() {
+ return this.methodDependencies;
+ }
+
+ public Class getSuperclass() { return null; }
+ protected abstract void setSuperClass(Extends supertype);
+
+ public void addSuperType(Extends sup) {
+ assert sup.getType() instanceof Interface : "Must be an interface";
+ this.supertypes.add(sup);
+ }
+ public void addSuperType(Interface iface) {
+ this.supertypes.add(new Extends(iface));
+ }
+
+ public void addMethod(Method m) {
+ this.methods.add(m);
+ }
+
+ public void addAccessFlag(AccessFlag f) {
+ this.accessFlags.add(f);
+ }
+
+ // Convenience method for creation. Parameters are interpreted
+ // according to their type. Class (or Extends with a Class type) is
+ // considered a superclass (only one allowed). TypeParameters are
+ // generic parameter names. Interface (or Extends with an Interface
+ // type) is an implemented supertype. Methods are methods (duh!).
+ protected void addComponent(Element p) {
+ if (p instanceof Class) {
+ setSuperClass(new Extends((Class)p));
+ } else if (p instanceof Extends) {
+ Extends ext = (Extends)p;
+ if (ext.supertype instanceof Class) {
+ setSuperClass(ext);
+ } else if (ext.supertype instanceof Interface) {
+ addSuperType(ext);
+ } else {
+ assert false : "What is this thing?";
+ }
+ } else if (p instanceof Interface) {
+ addSuperType((Interface)p);
+ } else if (p instanceof TypeParameter) {
+ this.parameters.add((TypeParameter)p);
+ } else if (p instanceof Method) {
+ addMethod((Method)p);
+ } else if (p instanceof AccessFlag) {
+ addAccessFlag((AccessFlag)p);
+ } else {
+ assert false : "What is this thing?";
+ }
+ }
+
+ // Find and return the first method that has name 'name'
+ public Method findMethod(String name) {
+ for (Method m : methods) {
+ if (m.name.equals(name)) {
+ return m;
+ }
+ }
+ return null;
+ }
+
+ public void addCompilationDependency(Type t) {
+ typeDependencies.add(t);
+ }
+
+ public void addCompilationDependency(Method m) {
+ methodDependencies.add(m);
+ }
+
+ // Convenience method for creating an Extends object using this
+ // class and specified type arguments.
+ public Extends with(String ... args) {
+ return new Extends(this, args);
+ }
+
+ public abstract void generate(SourceProcessor sp);
+ public abstract void generateAsDependency(
+ SourceProcessor sp, Set<Method> neededMethods);
+
+ protected void generateName(PrintWriter pw) {
+ pw.print(this.name);
+ toJoinedString(this.parameters, ",", "<", ">", "");
+ pw.print(toJoinedString(this.parameters, ",", "<", ">", ""));
+ pw.print(" ");
+ }
+
+ protected void generateBody(PrintWriter pw, String superSpec) {
+ pw.print(toJoinedString(this.supertypes, ",", superSpec + " ", " ", ""));
+ pw.println("{ ");
+ pw.print(toJoinedString(this.methods, "\n ", "\n ", "\n", ""));
+ pw.println("}");
+ }
+
+ protected void generateAccessFlags(PrintWriter pw) {
+ pw.print(toJoinedString(this.accessFlags, " ", "", " "));
+ }
+
+ protected void generateBodyAsDependency(
+ PrintWriter pw, Set<Method> neededMethods) {
+ pw.println(" {");
+ for (Method m : this.methods) {
+ if (neededMethods.contains(m)) {
+ pw.print(" ");
+ m.generate(pw);
+ pw.println();
+ }
+ }
+ pw.println("}");
+ }
+
+ public Collection<Type> typeDependencies() {
+ HashMap<String,Type> dependencies = new HashMap<>();
+ Type superclass = getSuperclass();
+ if (superclass != null) {
+ dependencies.put(superclass.getName(), superclass);
+ }
+ for (Extends e : getSupertypes())
+ dependencies.put(e.getType().getName(), e.getType());
+ // Do these last so that they override
+ for (Type t : this.typeDependencies)
+ dependencies.put(t.getName(), t);
+ return dependencies.values();
+ }
+ }
+
+ public static class Class extends Type {
+ private Extends superClass;
+
+ public Class(String name, List<AccessFlag> flags,
+ List<TypeParameter> params, Extends sprClass,
+ List<Extends> interfaces, List<Method> methods) {
+ super(name, flags, params, interfaces, methods);
+ this.superClass = sprClass;
+ addAccessFlag(AccessFlag.PUBLIC); // should remove this
+ }
+
+ public Class(String name, Element ... components) {
+ super(name, null, null, null, null);
+ this.superClass = null;
+
+ for (Element p : components) {
+ addComponent(p);
+ }
+ addAccessFlag(AccessFlag.PUBLIC); // should remove this
+ }
+
+ public boolean isAbstract() {
+ for (AccessFlag flag : getAccessFlags()) {
+ if (flag == AccessFlag.ABSTRACT) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void setSuperClass(Extends ext) {
+ assert this.superClass == null : "Multiple superclasses defined";
+ assert ext.getType() instanceof Class : "Must be a class";
+ this.superClass = ext;
+ }
+
+ public void setSuperClass(Class c) {
+ setSuperClass(new Extends(c));
+ }
+
+ @Override
+ public Class getSuperclass() {
+ return superClass == null ? null : (Class)superClass.supertype;
+ }
+
+ public void generate(SourceProcessor processor) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ generate(pw);
+ processor.process(getName(), sw.toString());
+ }
+
+ public void generate(PrintWriter pw) {
+ generateAccessFlags(pw);
+ pw.print("class ");
+ generateName(pw);
+ if (superClass != null) {
+ pw.print("extends ");
+ superClass.generate(pw);
+ pw.print(" ");
+ }
+ generateBody(pw, "implements");
+ }
+
+ public void generateAsDependency(
+ SourceProcessor processor, Set<Method> neededMethods) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ generateAccessFlags(pw);
+ pw.print("class ");
+ generateName(pw);
+ pw.print(" ");
+ generateBodyAsDependency(pw, neededMethods);
+
+ processor.process(getName(), sw.toString());
+ }
+ }
+
+ public static class Interface extends Type {
+
+ public Interface(String name,
+ List<AccessFlag> flags, List<TypeParameter> params,
+ List<Extends> interfaces, List<Method> methods) {
+ super(name, flags, params, interfaces, methods);
+ }
+
+ public Interface(String name, Element ... components) {
+ super(name, null, null, null, null);
+ for (Element c : components) {
+ addComponent(c);
+ }
+ }
+
+ protected void setSuperClass(Extends ext) {
+ assert false : "Interfaces cannot have Class supertypes";
+ }
+
+ public void generate(SourceProcessor processor) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ generate(pw);
+ processor.process(getName(), sw.toString());
+ }
+
+ public void generate(PrintWriter pw) {
+ generateAccessFlags(pw);
+ pw.print("interface ");
+ generateName(pw);
+ pw.print(" ");
+ generateBody(pw, "extends");
+ }
+
+ public void generateAsDependency(
+ SourceProcessor processor, Set<Method> neededMethods) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+
+ generateAccessFlags(pw);
+ pw.print("interface ");
+ generateName(pw);
+ pw.print(" ");
+ generateBodyAsDependency(pw, neededMethods);
+
+ processor.process(getName(), sw.toString());
+ }
+ }
+
+ /**
+ * Represents a type extension that might contain type arguments
+ */
+ public static class Extends extends Element {
+ private final Type supertype;
+ private final List<TypeArgument> arguments;
+
+ public Type getType() { return supertype; }
+ public List<TypeArgument> getArguments() {
+ return arguments;
+ }
+
+ public Extends(Type supertype, String ... args) {
+ assert supertype != null : "Null supertype";
+ this.supertype = supertype;
+ this.arguments = new ArrayList<>();
+ for (String arg : args) {
+ this.arguments.add(new TypeArgument(arg));
+ }
+ }
+
+ public void generate(PrintWriter pw) {
+ pw.print(supertype.getName());
+ pw.print(toJoinedString(getArguments(), ",", "<", ">", ""));
+ }
+ }
+
+ public static abstract class Method extends Element {
+ private String name;
+ private String returnType;
+ private List<AccessFlag> accessFlags;
+ private List<MethodParameter> parameters;
+ private boolean emitSuppressWarnings;
+
+ protected Method(String ret, String name, Element ... params) {
+ this.name = name;
+ this.returnType = ret;
+ this.accessFlags = new ArrayList<>();
+ this.parameters = new ArrayList<>();
+ this.emitSuppressWarnings = false;
+
+ for (Element e : params) {
+ if (e instanceof MethodParameter) {
+ this.parameters.add((MethodParameter) e);
+ } else if (e instanceof AccessFlag) {
+ this.accessFlags.add((AccessFlag) e);
+ }
+ }
+ assert accessFlags.size() + parameters.size() == params.length :
+ "Non method parameters or access flags in constructor";
+ }
+
+ public String getName() { return this.name; }
+ public String getReturnType() { return this.returnType; }
+ public List<MethodParameter> getParameters() {
+ return this.parameters;
+ }
+ public List<AccessFlag> getAccessFlags() {
+ return this.accessFlags;
+ }
+ public Element[] getElements() {
+ ArrayList<Element> elements = new ArrayList<>();
+ elements.addAll(getParameters());
+ elements.addAll(getAccessFlags());
+ return elements.toArray(new Element[0]);
+ }
+
+ public void suppressWarnings() { this.emitSuppressWarnings = true; }
+
+ public void generateWarningSuppression(PrintWriter pw) {
+ if (this.emitSuppressWarnings) {
+ pw.printf("@SuppressWarnings(\"unchecked\")\n ");
+ }
+ }
+
+ protected void generateDecl(PrintWriter pw) {
+ generateWarningSuppression(pw);
+ pw.print(toJoinedString(this.accessFlags, " ", "", " "));
+ pw.printf("%s %s(", returnType, name);
+ pw.print(toJoinedString(parameters, ","));
+ pw.print(")");
+ }
+ }
+
+ public static class AbstractMethod extends Method {
+ public AbstractMethod(
+ String ret, String name, Element ... params) {
+ super(ret, name, params);
+ this.getAccessFlags().add(AccessFlag.ABSTRACT);
+ }
+
+ public void generate(PrintWriter pw) {
+ generateDecl(pw);
+ pw.print(";");
+ }
+
+ public static AbstractMethod std() {
+ return new AbstractMethod(
+ "int", SourceModel.stdMethodName, AccessFlag.PUBLIC);
+ }
+ }
+
+ public static class ConcreteMethod extends Method {
+ protected String body;
+
+ public ConcreteMethod(String ret, String name,
+ String body, Element ... params) {
+ super(ret, name, params);
+ this.body = body;
+ }
+
+ public void generate(PrintWriter pw) {
+ generateDecl(pw);
+ pw.printf(" { %s }", this.body);
+ }
+
+ public static ConcreteMethod std(String value) {
+ return new ConcreteMethod(
+ "int", SourceModel.stdMethodName, "return " + value + ";",
+ AccessFlag.PUBLIC);
+ }
+ }
+
+ // When the default method flag gets moved into the traditional
+ // access flags location, we can remove this class completely and
+ // use a ConcreteMethod with an AccessFlag("default") in the constructor
+ public static class DefaultMethod extends Method {
+ protected String body;
+
+ public DefaultMethod(String ret, String name, String body,
+ Element ... params) {
+ super(ret, name, params);
+ this.body = body;
+ this.getAccessFlags().add(AccessFlag.DEFAULT);
+ }
+
+ public void generate(PrintWriter pw) {
+ generateDecl(pw);
+ pw.printf(" { %s }", this.body);
+ }
+
+ public static DefaultMethod std(String value) {
+ return new DefaultMethod(
+ "int", SourceModel.stdMethodName, "return " + value + ";");
+ }
+ }
+
+ private static <T> String toJoinedString(List<T> list, String... p) {
+ StringBuilder sb = new StringBuilder();
+ String sep = "";
+ String init = "";
+ String end = "";
+ String empty = null;
+ switch (p.length) {
+ case 4:
+ empty = p[3];
+ /*fall-through*/
+ case 3:
+ end = p[2];
+ /*fall-through*/
+ case 2:
+ init = p[1];
+ /*fall-through*/
+ case 1:
+ sep = p[0];
+ break;
+ }
+ if (empty != null && list.isEmpty()) {
+ return empty;
+ } else {
+ sb.append(init);
+ for (T x : list) {
+ if (sb.length() != init.length()) {
+ sb.append(sep);
+ }
+ sb.append(x.toString());
+ }
+ sb.append(end);
+ return sb.toString();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/separate/TestHarness.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.separate;
+
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+import static org.openjdk.tests.separate.SourceModel.Class;
+import static org.openjdk.tests.separate.SourceModel.*;
+import static org.testng.Assert.*;
+
+public class TestHarness {
+
+ /**
+ * Creates a per-thread persistent compiler object to allow as much
+ * sharing as possible, but still allows for parallel execution of tests.
+ */
+ protected ThreadLocal<Compiler> compilerLocal = new ThreadLocal<Compiler>(){
+ protected synchronized Compiler initialValue() {
+ return new Compiler();
+ }
+ };
+
+ protected ThreadLocal<Boolean> verboseLocal = new ThreadLocal<Boolean>() {
+ protected synchronized Boolean initialValue() {
+ return Boolean.FALSE;
+ }
+ };
+
+ protected boolean verbose;
+ protected boolean canUseCompilerCache;
+ public static final String stdMethodName = SourceModel.stdMethodName;
+
+ private TestHarness() {
+ }
+
+ protected TestHarness(boolean verbose, boolean canUseCompilerCache) {
+ this.verbose = verbose;
+ this.canUseCompilerCache = canUseCompilerCache;
+ }
+
+ public void setTestVerbose() {
+ verboseLocal.set(Boolean.TRUE);
+ }
+
+ @AfterMethod
+ public void reset() {
+ if (!this.verbose) {
+ verboseLocal.set(Boolean.FALSE);
+ }
+ }
+
+ public Compiler.Flags[] compilerFlags() {
+ HashSet<Compiler.Flags> flags = new HashSet<>();
+ if (verboseLocal.get() == Boolean.TRUE) {
+ flags.add(Compiler.Flags.VERBOSE);
+ }
+ if (this.canUseCompilerCache) {
+ flags.add(Compiler.Flags.USECACHE);
+ }
+ return flags.toArray(new Compiler.Flags[0]);
+ }
+
+ @AfterMethod
+ public void printError(ITestResult result) {
+ if (result.getStatus() == ITestResult.FAILURE) {
+ String clsName = result.getTestClass().getName();
+ clsName = clsName.substring(clsName.lastIndexOf(".") + 1);
+ System.out.println("Test " + clsName + "." +
+ result.getName() + " FAILED");
+ }
+ }
+
+ private static final ConcreteMethod stdCM = ConcreteMethod.std("-1");
+ private static final AbstractMethod stdAM =
+ new AbstractMethod("int", stdMethodName);
+
+ /**
+ * Returns a class which has a static method with the same name as
+ * 'method', whose body creates an new instance of 'specimen' and invokes
+ * 'method' upon it via an invokevirtual instruction with 'args' as
+ * function call parameters.
+ *
+ * 'returns' is a dummy return value that need only match 'methods'
+ * return type (it is only used in the dummy class when compiling IV).
+ */
+ private Class invokeVirtualHarness(
+ Class specimen, ConcreteMethod method,
+ String returns, String ... args) {
+ Method cm = new ConcreteMethod(
+ method.getReturnType(), method.getName(),
+ "return " + returns + ";", method.getElements());
+ Class stub = new Class(specimen.getName(), cm);
+
+ String params = toJoinedString(args, ", ");
+
+ ConcreteMethod sm = new ConcreteMethod(
+ method.getReturnType(), method.getName(),
+ String.format("return (new %s()).%s(%s);",
+ specimen.getName(), method.getName(), params),
+ new AccessFlag("public"), new AccessFlag("static"));
+
+ Class iv = new Class("IV_" + specimen.getName(), sm);
+
+ iv.addCompilationDependency(stub);
+ iv.addCompilationDependency(cm);
+
+ return iv;
+ }
+
+ /**
+ * Returns a class which has a static method with the same name as
+ * 'method', whose body creates an new instance of 'specimen', casts it
+ * to 'iface' (including the type parameters) and invokes
+ * 'method' upon it via an invokeinterface instruction with 'args' as
+ * function call parameters.
+ */
+ private Class invokeInterfaceHarness(Class specimen, Extends iface,
+ AbstractMethod method, String ... args) {
+ Interface istub = new Interface(
+ iface.getType().getName(), iface.getType().getAccessFlags(),
+ iface.getType().getParameters(),
+ null, Arrays.asList((Method)method));
+ Class cstub = new Class(specimen.getName());
+
+ String params = toJoinedString(args, ", ");
+
+ ConcreteMethod sm = new ConcreteMethod(
+ "int", SourceModel.stdMethodName,
+ String.format("return ((%s)(new %s())).%s(%s);", iface.toString(),
+ specimen.getName(), method.getName(), params),
+ new AccessFlag("public"), new AccessFlag("static"));
+ sm.suppressWarnings();
+
+ Class ii = new Class("II_" + specimen.getName() + "_" +
+ iface.getType().getName(), sm);
+ ii.addCompilationDependency(istub);
+ ii.addCompilationDependency(cstub);
+ ii.addCompilationDependency(method);
+ return ii;
+ }
+
+
+ /**
+ * Uses 'loader' to load class 'clzz', and calls the static method
+ * 'method'. If the return value does not equal 'value' (or if an
+ * exception is thrown), then a test failure is indicated.
+ *
+ * If 'value' is null, then no equality check is performed -- the assertion
+ * fails only if an exception is thrown.
+ */
+ protected void assertStaticCallEquals(
+ ClassLoader loader, Class clzz, String method, Object value) {
+ java.lang.Class<?> cls = null;
+ try {
+ cls = java.lang.Class.forName(clzz.getName(), true, loader);
+ } catch (ClassNotFoundException e) {}
+ assertNotNull(cls);
+
+ java.lang.reflect.Method m = null;
+ try {
+ m = cls.getMethod(method);
+ } catch (NoSuchMethodException e) {}
+ assertNotNull(m);
+
+ try {
+ Object res = m.invoke(null);
+ assertNotNull(res);
+ if (value != null) {
+ assertEquals(res, value);
+ }
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ fail("Unexpected exception thrown: " + e.getCause());
+ }
+ }
+
+ /**
+ * Creates a class which calls target::method(args) via invokevirtual,
+ * compiles and loads both the new class and 'target', and then invokes
+ * the method. If the returned value does not match 'value' then a
+ * test failure is indicated.
+ */
+ public void assertInvokeVirtualEquals(
+ Object value, Class target, ConcreteMethod method,
+ String returns, String ... args) {
+
+ Compiler compiler = compilerLocal.get();
+ compiler.setFlags(compilerFlags());
+
+ Class iv = invokeVirtualHarness(target, method, returns, args);
+ ClassLoader loader = compiler.compile(iv, target);
+
+ assertStaticCallEquals(loader, iv, method.getName(), value);
+ compiler.cleanup();
+ }
+
+ /**
+ * Convenience method for above, which assumes stdMethodName,
+ * a return type of 'int', and no arguments.
+ */
+ public void assertInvokeVirtualEquals(int value, Class target) {
+ assertInvokeVirtualEquals(
+ new Integer(value), target, stdCM, "-1");
+ }
+
+ /**
+ * Creates a class which calls target::method(args) via invokeinterface
+ * through 'iface', compiles and loads both it and 'target', and
+ * then invokes the method. If the returned value does not match
+ * 'value' then a test failure is indicated.
+ */
+ public void assertInvokeInterfaceEquals(Object value, Class target,
+ Extends iface, AbstractMethod method, String ... args) {
+
+ Compiler compiler = compilerLocal.get();
+ compiler.setFlags(compilerFlags());
+
+ Class ii = invokeInterfaceHarness(target, iface, method, args);
+ ClassLoader loader = compiler.compile(ii, target);
+
+ assertStaticCallEquals(loader, ii, method.getName(), value);
+ compiler.cleanup();
+ }
+
+ /**
+ * Convenience method for above, which assumes stdMethodName,
+ * a return type of 'int', and no arguments.
+ */
+ public void assertInvokeInterfaceEquals(
+ int value, Class target, Interface iface) {
+
+ Compiler compiler = compilerLocal.get();
+ compiler.setFlags(compilerFlags());
+
+ assertInvokeInterfaceEquals(
+ new Integer(value), target, new Extends(iface), stdAM);
+
+ compiler.cleanup();
+ }
+
+ /**
+ * Creates a class which calls target::method(args) via invokevirtual,
+ * compiles and loads both the new class and 'target', and then invokes
+ * the method. If an exception of type 'exceptionType' is not thrown,
+ * then a test failure is indicated.
+ */
+ public void assertThrows(java.lang.Class<?> exceptionType, Class target,
+ ConcreteMethod method, String returns, String ... args) {
+
+ Compiler compiler = compilerLocal.get();
+ compiler.setFlags(compilerFlags());
+
+ Class iv = invokeVirtualHarness(target, method, returns, args);
+ ClassLoader loader = compiler.compile(iv, target);
+
+ java.lang.Class<?> cls = null;
+ try {
+ cls = java.lang.Class.forName(iv.getName(), true, loader);
+ } catch (ClassNotFoundException e) {}
+ assertNotNull(cls);
+
+ java.lang.reflect.Method m = null;
+ try {
+ m = cls.getMethod(method.getName());
+ } catch (NoSuchMethodException e) {}
+ assertNotNull(m);
+
+ try {
+ m.invoke(null);
+ fail("Exception should have been thrown");
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ if (verboseLocal.get() == Boolean.TRUE) {
+ System.out.println(e.getCause());
+ }
+ assertEquals(e.getCause().getClass(), exceptionType);
+ }
+ compiler.cleanup();
+ }
+
+ /**
+ * Convenience method for above, which assumes stdMethodName,
+ * a return type of 'int', and no arguments.
+ */
+ public void assertThrows(java.lang.Class<?> exceptionType, Class target) {
+ assertThrows(exceptionType, target, stdCM, "-1");
+ }
+
+ private static <T> String toJoinedString(T[] a, String... p) {
+ return toJoinedString(Arrays.asList(a), p);
+ }
+
+ private static <T> String toJoinedString(List<T> list, String... p) {
+ StringBuilder sb = new StringBuilder();
+ String sep = "";
+ String init = "";
+ String end = "";
+ String empty = null;
+ switch (p.length) {
+ case 4:
+ empty = p[3];
+ /*fall-through*/
+ case 3:
+ end = p[2];
+ /*fall-through*/
+ case 2:
+ init = p[1];
+ /*fall-through*/
+ case 1:
+ sep = p[0];
+ break;
+ }
+ if (empty != null && list.isEmpty()) {
+ return empty;
+ } else {
+ sb.append(init);
+ for (T x : list) {
+ if (sb.length() != init.length()) {
+ sb.append(sep);
+ }
+ sb.append(x.toString());
+ }
+ sb.append(end);
+ return sb.toString();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/ClassCase.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.shapegen;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class ClassCase {
+
+ public enum Kind {
+ IVAC (true, "v"),
+ IPRESENT (true, "p"),
+ IDEFAULT (true, "d"),
+ CNONE (false, "n"),
+ CABSTRACT (false, "a"),
+ CCONCRETE (false, "c");
+
+ private final String prefix;
+ public final boolean isInterface;
+
+ Kind(boolean isInterface, String prefix) {
+ this.isInterface = isInterface;
+ this.prefix = prefix;
+ }
+
+ public String getPrefix() { return prefix; }
+ }
+
+ public final Kind kind;
+ private final ClassCase superclass;
+ private final List<ClassCase> supertypes;
+
+ private String name;
+ private boolean _OK;
+ private boolean _HasClassMethod;
+ private Set<ClassCase> _mprov;
+ private boolean _IsConcrete;
+ private boolean _HasDefault;
+ private ClassCase _mres;
+ private ClassCase _mdefend;
+
+ private Set<RuleGroup> executed = new HashSet<RuleGroup>();
+
+ public ClassCase(Kind kind, ClassCase superclass, List<ClassCase> interfaces) {
+ this.kind = kind;
+ this.superclass = superclass;
+
+ // Set supertypes from superclass (if any) and interfaces
+ List<ClassCase> lc;
+ if (superclass == null) {
+ lc = interfaces;
+ } else {
+ lc = new ArrayList<>();
+ lc.add(superclass);
+ lc.addAll(interfaces);
+ }
+ this.supertypes = lc;
+ }
+
+ public final boolean isInterface() { return kind.isInterface; }
+ public final boolean isClass() { return !kind.isInterface; }
+
+ public Set<ClassCase> get_mprov() {
+ exec(RuleGroup.PROVENENCE);
+ return _mprov;
+ }
+
+ public void set_mprov(ClassCase cc) {
+ Set<ClassCase> s = new HashSet<>();
+ s.add(cc);
+ _mprov = s;
+ }
+
+ public void set_mprov(Set<ClassCase> s) {
+ _mprov = s;
+ }
+
+ public ClassCase get_mres() {
+ exec(RuleGroup.RESOLUTION);
+ return _mres;
+ }
+
+ public void set_mres(ClassCase cc) {
+ _mres = cc;
+ }
+
+ public ClassCase get_mdefend() {
+ exec(RuleGroup.DEFENDER);
+ return _mdefend;
+ }
+
+ public void set_mdefend(ClassCase cc) {
+ _mdefend = cc;
+ }
+
+ public boolean get_HasClassMethod() {
+ exec(RuleGroup.PROVENENCE);
+ return _HasClassMethod;
+ }
+
+ public void set_HasClassMethod(boolean bool) {
+ _HasClassMethod = bool;
+ }
+
+ public boolean get_HasDefault() {
+ exec(RuleGroup.MARKER);
+ return _HasDefault;
+ }
+
+ public void set_HasDefault(boolean bool) {
+ _HasDefault = bool;
+ }
+
+ public boolean get_IsConcrete() {
+ exec(RuleGroup.MARKER);
+ return _IsConcrete;
+ }
+
+ public void set_IsConcrete(boolean bool) {
+ _IsConcrete = bool;
+ }
+
+ public boolean get_OK() {
+ exec(RuleGroup.CHECKING);
+ return _OK;
+ }
+
+ public void set_OK(boolean bool) {
+ _OK = bool;
+ }
+
+ public boolean isMethodDefined() {
+ for (ClassCase cc : supertypes) {
+ if (cc.isMethodDefined()) {
+ return true;
+ }
+ }
+ switch (kind) {
+ case CCONCRETE:
+ case CABSTRACT:
+ case IPRESENT:
+ case IDEFAULT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isAbstract() {
+ return isMethodDefined() && (get_mres()==null);
+ }
+
+ public boolean hasSuperclass() {
+ return superclass != null;
+ }
+
+ public ClassCase getSuperclass() {
+ return superclass;
+ }
+
+ public List<ClassCase> getSupertypes() {
+ return supertypes;
+ }
+
+ public List<ClassCase> getInterfaces() {
+ if (superclass != null) {
+ if (supertypes.get(0) != superclass) {
+ throw new AssertionError("superclass missing from supertypes");
+ }
+ return supertypes.subList(1, supertypes.size());
+ } else {
+ return supertypes;
+ }
+ }
+
+ public boolean isSubtypeOf(ClassCase cc) {
+ // S-Refl
+ if (cc.equals(this)) {
+ return true;
+ }
+
+ // S-Def
+ for (ClassCase sp : getSupertypes()) {
+ if (cc.equals(sp)) {
+ return true;
+ }
+ }
+
+ // _S-Trans
+ for (ClassCase sp : getSupertypes()) {
+ if (sp.isSubtypeOf(cc)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void init(Map<String, Integer> namingContext) {
+ if (name != null) {
+ return; // Already inited
+ }
+
+ for (ClassCase sup : supertypes) {
+ sup.init(namingContext);
+ }
+
+ // Build name
+ StringBuilder sb = new StringBuilder();
+ if (!supertypes.isEmpty()) {
+ sb.append(isInterface() ? "I" : "C");
+ for (ClassCase cc : supertypes) {
+ sb.append(cc.getName());
+ }
+ sb.append(kind.isInterface ? "i" : "c");
+ }
+ sb.append(kind.prefix);
+ String pname = sb.toString();
+ Integer icnt = namingContext.get(pname);
+ int cnt = icnt == null ? 0 : icnt;
+ ++cnt;
+ namingContext.put(pname, cnt);
+ if (cnt > 1) {
+ sb.append(cnt);
+ }
+ this.name = sb.toString();
+ }
+
+ public boolean isa(Kind... kinds) {
+ for (Kind k : kinds) {
+ if (kind == k) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void exec(RuleGroup rg ) {
+ if (!executed.contains(rg)) {
+ rg.exec(this);
+ executed.add(rg);
+ }
+ }
+
+ public void collectClasses(Set<ClassCase> seen) {
+ seen.add(this);
+ for (ClassCase cc : supertypes) {
+ cc.collectClasses(seen);
+ }
+ }
+
+ public String getID() {
+ if (name == null) {
+ throw new Error("Access to uninitialized ClassCase");
+ } else {
+ return name;
+ }
+ }
+
+ public final String getName() {
+ if (name == null) {
+ return "ClassCase uninited@" + hashCode();
+ } else {
+ return name;
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof ClassCase && getID().equals(((ClassCase)obj).getID());
+ }
+
+ @Override
+ public int hashCode() {
+ return getID().hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/Hierarchy.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.shapegen;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class Hierarchy {
+
+ public final ClassCase root;
+ public final Set<ClassCase> all;
+
+ public Hierarchy(ClassCase root) {
+ this.root = root;
+ root.init(new HashMap<String,Integer>());
+ Set<ClassCase> allClasses = new HashSet<>();
+ root.collectClasses(allClasses);
+ this.all = allClasses;
+ }
+
+ public boolean anyDefaults() {
+ for (ClassCase cc : all) {
+ if (cc.kind == IDEFAULT) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean get_OK() {
+ return root.get_OK();
+ }
+
+ public String testName() {
+ return root + "Test";
+ }
+
+ private static void genInterfaceList(StringBuilder buf, String prefix, List<ClassCase> interfaces) {
+ if (!interfaces.isEmpty()) {
+ buf.append(" ");
+ buf.append(prefix);
+ buf.append(" ");
+ buf.append(interfaces.get(0));
+ for (int i = 1; i < interfaces.size(); ++i) {
+ buf.append(", " + interfaces.get(i));
+ }
+ }
+ }
+
+ public static void genClassDef(StringBuilder buf, ClassCase cc, String implClass, List<ClassCase> defaultRef) {
+ if (cc.isInterface()) {
+ buf.append("interface ");
+ buf.append(cc.getName() + " ");
+ genInterfaceList(buf, "extends", cc.getInterfaces());
+ buf.append(" {\n");
+
+ switch (cc.kind) {
+ case IDEFAULT:
+ buf.append(" default String m() { return \"\"; }\n");
+ defaultRef.add(cc);
+ break;
+ case IPRESENT:
+ buf.append(" String m();\n");
+ break;
+ case IVAC:
+ break;
+ default:
+ throw new AssertionError("Unexpected kind");
+ }
+ buf.append("}\n\n");
+ } else {
+ buf.append((cc.isAbstract()? "abstract " : ""));
+ buf.append(" class " + cc.getName());
+ if (cc.getSuperclass() != null) {
+ buf.append(" extends " + cc.getSuperclass());
+ }
+
+ genInterfaceList(buf, "implements", cc.getInterfaces());
+ buf.append(" {\n");
+
+ switch (cc.kind) {
+ case CCONCRETE:
+ buf.append(" public String m() { return \"\"; }\n");
+ break;
+ case CABSTRACT:
+ buf.append(" public abstract String m();\n");
+ break;
+ case CNONE:
+ break;
+ default:
+ throw new AssertionError("Unexpected kind");
+ }
+ buf.append("}\n\n");
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof Hierarchy && root.getID().equals(((Hierarchy)obj).root.getID());
+ }
+
+ @Override
+ public int hashCode() {
+ return root.getID().hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return root.getName();
+ }
+
+ private static String classNames[] = {
+ "C", "D", "E", "F", "G", "H", "S", "T", "U", "V"
+ };
+
+ private static String interfaceNames[] = {
+ "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R"
+ };
+
+ private static int CLASS_INDEX = 0;
+ private static int INTERFACE_INDEX = 1;
+ private static int NUM_INDICIES = 2;
+
+ public List<String> getDescription() {
+ Map<ClassCase,String> nameMap = new HashMap<>();
+ assignNames(root, new int[NUM_INDICIES], nameMap);
+
+ ArrayList<String> res = new ArrayList<>();
+ if (root.getSupertypes().size() == 0) {
+ res.add(nameMap.get(root) + root.kind.getPrefix() + "()");
+ } else {
+ genCaseDescription(root, res, new HashSet<ClassCase>(), nameMap);
+ }
+ return res;
+ }
+
+ private static void assignNames(
+ ClassCase cc, int indices[], Map<ClassCase,String> names) {
+ String name = names.get(cc);
+ if (name == null) {
+ if (cc.isInterface()) {
+ names.put(cc, interfaceNames[indices[INTERFACE_INDEX]++]);
+ } else {
+ names.put(cc, classNames[indices[CLASS_INDEX]++]);
+ }
+ for (int i = 0; i < cc.getSupertypes().size(); ++i) {
+ assignNames(cc.getSupertypes().get(i), indices, names);
+ }
+ }
+ }
+
+ private static void genCaseDescription(
+ ClassCase cc, List<String> res, Set<ClassCase> alreadyDone,
+ Map<ClassCase,String> nameMap) {
+ if (!alreadyDone.contains(cc)) {
+ if (cc.getSupertypes().size() > 0) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(nameMap.get(cc));
+ sb.append(cc.kind.getPrefix());
+ sb.append("(");
+ for (int i = 0; i < cc.getSupertypes().size(); ++i) {
+ ClassCase supertype = cc.getSupertypes().get(i);
+ if (i != 0) {
+ sb.append(",");
+ }
+ genCaseDescription(supertype, res, alreadyDone, nameMap);
+ sb.append(nameMap.get(supertype));
+ sb.append(supertype.kind.getPrefix());
+ }
+ sb.append(")");
+ res.add(sb.toString());
+ }
+ }
+ alreadyDone.add(cc);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/HierarchyGenerator.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.shapegen;
+
+import org.openjdk.tests.shapegen.ClassCase.Kind;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
+
+import static java.lang.Math.pow;
+
+/**
+ *
+ * @author Robert Field
+ */
+public final class HierarchyGenerator {
+
+ private int okcnt = 0;
+ private int errcnt = 0;
+ private Set<Hierarchy> uniqueOK = new HashSet<>();
+ private Set<Hierarchy> uniqueErr = new HashSet<>();
+
+ /**
+ * @param args the command line arguments
+ */
+ public HierarchyGenerator() {
+ organize("exhaustive interface", iExhaustive(2));
+ organize("exhaustive class", cExhaustive());
+ organize("shapes interface", iShapes());
+ organize("shapes class/interface", ciShapes());
+
+ System.out.printf("\nExpect OK: %d -- unique %d", okcnt, uniqueOK.size());
+ System.out.printf("\nExpect Error: %d -- unique %d\n", errcnt, uniqueErr.size());
+ }
+
+ public Collection<Hierarchy> getOK() {
+ return uniqueOK;
+ }
+
+ public Collection<Hierarchy> getErr() {
+ return uniqueErr;
+ }
+
+ private void organize(String tname, List<Hierarchy> totest) {
+ System.out.printf("\nGenerating %s....\n", tname);
+ int nodefault = 0;
+ List<Hierarchy> ok = new ArrayList<>();
+ List<Hierarchy> err = new ArrayList<>();
+ for (Hierarchy cc : totest) {
+ if (cc.anyDefaults()) {
+ //System.out.printf(" %s\n", cc);
+ if (cc.get_OK()) {
+ ok.add(cc);
+ } else {
+ err.add(cc);
+ }
+ } else {
+ ++nodefault;
+ }
+ }
+
+ errcnt += err.size();
+ okcnt += ok.size();
+ uniqueErr.addAll(err);
+ uniqueOK.addAll(ok);
+
+ System.out.printf(" %5d No default\n %5d Error\n %5d OK\n %5d Total\n",
+ nodefault, err.size(), ok.size(), totest.size());
+ }
+
+ public List<Hierarchy> iExhaustive(int idepth) {
+ List<ClassCase> current = new ArrayList<>();
+ for (int i = 0; i < idepth; ++i) {
+ current = ilayer(current);
+ }
+ return wrapInClassAndHierarchy(current);
+ }
+
+ private List<ClassCase> ilayer(List<ClassCase> srcLayer) {
+ List<ClassCase> lay = new ArrayList<>();
+ for (int i = (int) pow(2, srcLayer.size()) - 1; i >= 0; --i) {
+ List<ClassCase> itfs = new ArrayList<>();
+ for (int b = srcLayer.size() - 1; b >= 0; --b) {
+ if ((i & (1<<b)) != 0) {
+ itfs.add(srcLayer.get(b));
+ }
+ }
+ lay.add(new ClassCase(IVAC, null, itfs));
+ lay.add(new ClassCase(IPRESENT, null, itfs));
+ lay.add(new ClassCase(IDEFAULT, null, itfs));
+ lay.add(new ClassCase(IDEFAULT, null, itfs));
+ }
+ return lay;
+ }
+
+ public List<Hierarchy> cExhaustive() {
+ final Kind[] iKinds = new Kind[]{IDEFAULT, IVAC, IPRESENT, null};
+ final Kind[] cKinds = new Kind[]{CNONE, CABSTRACT, CCONCRETE};
+ List<Hierarchy> totest = new ArrayList<>();
+ for (int i1 = 0; i1 < iKinds.length; ++i1) {
+ for (int i2 = 0; i2 < iKinds.length; ++i2) {
+ for (int i3 = 0; i3 < iKinds.length; ++i3) {
+ for (int c1 = 0; c1 < cKinds.length; ++c1) {
+ for (int c2 = 0; c2 < cKinds.length; ++c2) {
+ for (int c3 = 0; c3 < cKinds.length; ++c3) {
+ totest.add( new Hierarchy(
+ new ClassCase(cKinds[c1],
+ new ClassCase(cKinds[c2],
+ new ClassCase(cKinds[c3],
+ null,
+ iList(iKinds[i1])
+ ),
+ iList(iKinds[i2])
+ ),
+ iList(iKinds[i3])
+ )));
+ }
+ }
+ }
+ }
+ }
+ }
+ return totest;
+ }
+
+ public static final List<ClassCase> EMPTY_LIST = new ArrayList<>();
+
+ private List<ClassCase> iList(Kind kind) {
+ if (kind == null) {
+ return EMPTY_LIST;
+ } else {
+ List<ClassCase> itfs = new ArrayList<>();
+ itfs.add(new ClassCase(kind, null, EMPTY_LIST));
+ return itfs;
+ }
+ }
+
+ public List<Hierarchy> ciShapes() {
+ return wrapInHierarchy(TTShape.allCases(true));
+ }
+
+ public List<Hierarchy> iShapes() {
+ return wrapInClassAndHierarchy(TTShape.allCases(false));
+ }
+
+ public List<Hierarchy> wrapInClassAndHierarchy(List<ClassCase> ihs) {
+ List<Hierarchy> totest = new ArrayList<>();
+ for (ClassCase cc : ihs) {
+ List<ClassCase> interfaces = new ArrayList<>();
+ interfaces.add(cc);
+ totest.add(new Hierarchy(new ClassCase(CNONE, null, interfaces)));
+ }
+ return totest;
+ }
+
+ public List<Hierarchy> wrapInHierarchy(List<ClassCase> ihs) {
+ List<Hierarchy> totest = new ArrayList<>();
+ for (ClassCase cc : ihs) {
+ totest.add(new Hierarchy(cc));
+ }
+ return totest;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/Rule.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.shapegen;
+
+/**
+ *
+ * @author Robert Field
+ */
+public abstract class Rule {
+
+ public final String name;
+
+ public Rule(String name) {
+ this.name = name;
+ }
+
+ abstract boolean guard(ClassCase cc);
+
+ abstract void eval(ClassCase cc);
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/RuleGroup.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.shapegen;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class RuleGroup {
+
+ final String name;
+ private final Rule[] rules;
+
+ public RuleGroup(String name, Rule[] rules) {
+ this.name = name;
+ this.rules = rules;
+ }
+
+ public boolean exec(ClassCase cc) {
+ boolean found = false;
+ for (Rule rule : rules) {
+ if (rule.guard(cc)) {
+ if (found) {
+ throw new RuntimeException("Bad rules -- multiple matches " + toString() + " for " + cc);
+ } else {
+ rule.eval(cc);
+ found = true;
+ }
+ }
+ }
+ return found;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ public static RuleGroup PROVENENCE = new RuleGroup("Provenence", new Rule[] {
+ new Rule("P-CDeclare") {
+ boolean guard(ClassCase cc) {
+ return cc.isa(CCONCRETE, CABSTRACT);
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_mprov(cc);
+ cc.set_HasClassMethod(true);
+ }
+ },
+
+ new Rule("P-IDeclare") {
+ boolean guard(ClassCase cc) {
+ return cc.isa(IDEFAULT, IPRESENT);
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_mprov(cc);
+ }
+ },
+
+ new Rule("P-IntfInh") {
+ boolean guard(ClassCase cc) {
+ return cc.isa(IVAC, CNONE) && !(cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod());
+ }
+
+ void eval(ClassCase cc) {
+ Set<ClassCase> _S = new HashSet<>();
+ for (ClassCase t : cc.getSupertypes()) {
+ _S.addAll(t.get_mprov());
+ }
+ Set<ClassCase> tops = new HashSet<>();
+ for (ClassCase _W : _S) {
+ for (ClassCase _V : _S) {
+ if (_V.equals(_W) || !(_V.isSubtypeOf(_W))) {
+ tops.add(_W);
+ }
+ }
+ }
+ cc.set_mprov(tops);
+ }
+ },
+
+ new Rule("P-ClassInh") {
+ boolean guard(ClassCase cc) {
+ return cc.isa(CNONE) && (cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod());
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_mprov(cc.getSuperclass());
+ cc.set_HasClassMethod(true);
+ }
+ },
+
+ });
+
+ public static RuleGroup MARKER = new RuleGroup("Marker", new Rule[] {
+ new Rule("M-Default") {
+ boolean guard(ClassCase cc) {
+ return cc.isa(IDEFAULT);
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_HasDefault(true);
+ }
+ },
+
+ new Rule("M-Conc") {
+ boolean guard(ClassCase cc) {
+ return cc.isa(CCONCRETE);
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_IsConcrete(true);
+ }
+ },
+
+ });
+
+ public static RuleGroup RESOLUTION = new RuleGroup("Resolution", new Rule[] {
+ new Rule("R-Resolve") {
+ boolean guard(ClassCase cc) {
+ if (!(cc.isClass() && cc.get_mprov().size() == 1)) {
+ return false;
+ }
+ ClassCase _V = cc.get_mprov().iterator().next();
+ return _V.get_IsConcrete() || _V.get_HasDefault();
+ }
+
+ void eval(ClassCase cc) {
+ ClassCase _V = cc.get_mprov().iterator().next();
+ cc.set_mres(_V);
+ }
+ },
+
+ });
+
+ public static RuleGroup DEFENDER = new RuleGroup("Defender", new Rule[] {
+ new Rule("D-Defend") {
+ boolean guard(ClassCase cc) {
+ ClassCase mresSuper = cc.hasSuperclass() ? cc.getSuperclass().get_mres() : null;
+ boolean eq = cc.get_mres() == null ? mresSuper == null : cc.get_mres().equals(mresSuper);
+ return cc.isa(CNONE) && !eq;
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_mdefend(cc.get_mres());
+ }
+ },
+
+ });
+
+ public static RuleGroup CHECKING = new RuleGroup("Checking", new Rule[] {
+ new Rule("C-Check") {
+ boolean guard(ClassCase cc) {
+ for (ClassCase t : cc.getSupertypes()) {
+ if (! t.get_OK()) {
+ return false;
+ }
+ }
+ int defenderCount = 0;
+ int provCount = 0;
+ for (ClassCase prov : cc.get_mprov()) {
+ if (prov.get_HasDefault()) {
+ defenderCount++;
+ }
+ provCount++;
+ }
+ return provCount <= 1 || defenderCount == 0;
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_OK(true);
+ }
+ },
+
+ });
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/TTNode.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.shapegen;
+
+import org.openjdk.tests.shapegen.ClassCase.Kind;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import static org.openjdk.tests.shapegen.ClassCase.Kind.*;
+
+/**
+ * Type Template Node
+ *
+ * @author Robert Field
+ */
+public class TTNode {
+
+ final List<TTNode> supertypes;
+ final boolean canBeClass;
+
+ private int currentKindIndex;
+ private Kind[] kinds;
+
+ public TTNode(List<TTNode> subtypes, boolean canBeClass) {
+ this.supertypes = subtypes;
+ this.canBeClass = canBeClass;
+ }
+
+ public void start(boolean includeClasses) {
+ kinds =
+ supertypes.isEmpty()?
+ (new Kind[]{IDEFAULT, IPRESENT})
+ : ((includeClasses && canBeClass)?
+ new Kind[]{CNONE, IVAC, IDEFAULT, IPRESENT}
+ : new Kind[]{IVAC, IDEFAULT, IPRESENT});
+ currentKindIndex = 0;
+
+ for (TTNode sub : supertypes) {
+ sub.start(includeClasses);
+ }
+ }
+
+ public boolean next() {
+ ++currentKindIndex;
+ if (currentKindIndex >= kinds.length) {
+ currentKindIndex = 0;
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ public void collectAllSubtypes(Set<TTNode> subs) {
+ subs.add(this);
+ for (TTNode n : supertypes) {
+ n.collectAllSubtypes(subs);
+ }
+ }
+
+ private Kind getKind() {
+ return kinds[currentKindIndex];
+ }
+
+ boolean isInterface() {
+ return getKind().isInterface;
+ }
+
+ boolean isClass() {
+ return !isInterface();
+ }
+
+ boolean hasDefault() {
+ return getKind() == IDEFAULT;
+ }
+
+ public boolean isValid() {
+ for (TTNode n : supertypes) {
+ if (!n.isValid() || (isInterface() && n.isClass())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public ClassCase genCase() {
+ ClassCase subclass;
+ List<TTNode> ttintfs;
+ if (isClass() && !supertypes.isEmpty() && supertypes.get(0).isClass()) {
+ subclass = supertypes.get(0).genCase();
+ ttintfs = supertypes.subList(1, supertypes.size());
+ } else {
+ subclass = null;
+ ttintfs = supertypes;
+ }
+ List<ClassCase> intfs = new ArrayList<>();
+ for (TTNode node : ttintfs) {
+ intfs.add(node.genCase());
+ }
+ return new ClassCase(getKind(), subclass, intfs);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/TTParser.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.shapegen;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.StringReader;
+
+import static java.lang.Character.isLetter;
+import static java.lang.Character.isUpperCase;
+import static java.lang.Character.isWhitespace;
+
+/**
+ * Parse a type template definition string
+ *
+ * input :: classDef
+ * classDef :: letter [ ( classDef* ) ]
+ *
+ * @author Robert Field
+ */
+public class TTParser extends StringReader {
+
+ private Map<Character, TTNode> letterMap = new HashMap<>();
+ private char ch;
+
+ private final String def;
+
+ public TTParser(String s) {
+ super(s);
+ this.def = s;
+ }
+
+ private void advance() throws IOException {
+ do {
+ ch = (char)read();
+ } while (isWhitespace(ch));
+ }
+
+ public TTNode parse() {
+ try {
+ advance();
+ return classDef();
+ } catch (IOException t) {
+ throw new RuntimeException(t);
+ }
+ }
+
+ private TTNode classDef() throws IOException {
+ if (!isLetter(ch)) {
+ if (ch == (char)-1) {
+ throw new IOException("Unexpected end of type template in " + def);
+ } else {
+ throw new IOException("Unexpected character in type template: " + (Character)ch + " in " + def);
+ }
+ }
+ char nodeCh = ch;
+ TTNode node = letterMap.get(nodeCh);
+ boolean canBeClass = isUpperCase(nodeCh);
+ advance();
+ if (node == null) {
+ List<TTNode> subtypes = new ArrayList<>();
+ if (ch == '(') {
+ advance();
+ while (ch != ')') {
+ subtypes.add(classDef());
+ }
+ advance();
+ }
+ node = new TTNode(subtypes, canBeClass);
+ letterMap.put(nodeCh, node);
+ }
+ return node;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/shapegen/TTShape.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2012, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.shapegen;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class TTShape {
+
+ private final TTNode root;
+ private final TTNode[] nodes;
+
+ TTShape(TTNode root) {
+ this.root = root;
+ Set<TTNode> subs = new HashSet<>();
+ root.collectAllSubtypes(subs);
+ nodes = subs.toArray(new TTNode[subs.size()]);
+ }
+
+ private List<ClassCase> toCases(boolean includeClasses) {
+ List<ClassCase> ccs = new ArrayList<>();
+ root.start(includeClasses);
+ int i;
+ outer:
+ while (true) {
+ if (root.isValid()) {
+ ClassCase cc = root.genCase();
+ //System.out.println(cc);
+ ccs.add(cc);
+ }
+
+ i = 0;
+ do {
+ if (i >= nodes.length) {
+ break outer;
+ }
+ } while(!nodes[i++].next());
+ }
+ return ccs;
+ }
+
+ public static List<ClassCase> allCases(boolean includeClasses) {
+ List<ClassCase> ccs = new ArrayList<>();
+ for (TTShape shape : SHAPES) {
+ ccs.addAll(shape.toCases(includeClasses));
+ }
+ return ccs;
+ }
+
+ public static TTShape parse(String s) {
+ return new TTShape(new TTParser(s).parse());
+ }
+
+ public static final TTShape[] SHAPES = new TTShape[] {
+ parse("a"),
+ parse("a(b)"),
+ parse("A(bb)"),
+ parse("A(B(d)c(d))"),
+ parse("A(b(c))"),
+ parse("A(B(cd)d)"),
+ parse("A(B(c)c)"),
+ parse("A(B(Ce)d(e))"),
+ parse("A(B(C)d(e))"),
+ parse("A(Bc(d))"),
+ parse("A(B(d)dc)"),
+ parse("A(B(dc)dc)"),
+ parse("A(B(c(d))d)"),
+ parse("A(B(C(d))d)"),
+ parse("A(B(C(e)d(e))e)"),
+ parse("A(B(c(d))c)"),
+ parse("A(B(dc(d))c)"),
+ parse("A(B(C(d))d)"),
+ };
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,826 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.vm;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.io.File;
+import java.io.IOException;
+
+import org.testng.annotations.Test;
+import org.openjdk.tests.separate.*;
+import org.openjdk.tests.separate.Compiler;
+
+import static org.testng.Assert.*;
+import static org.openjdk.tests.separate.SourceModel.*;
+import static org.openjdk.tests.separate.SourceModel.Class;
+
+@Test(groups = "vm")
+public class DefaultMethodsTest extends TestHarness {
+ public DefaultMethodsTest() {
+ super(false, false);
+ }
+
+ /**
+ * class C { public int m() { return 22; } }
+ *
+ * TEST: C c = new C(); c.m() == 22
+ */
+ public void testHarnessInvokeVirtual() {
+ Class C = new Class("C", ConcreteMethod.std("22"));
+ assertInvokeVirtualEquals(22, C);
+ }
+
+ /**
+ * interface I { int m(); }
+ * class C implements I { public int m() { return 33; } }
+ *
+ * TEST: I i = new C(); i.m() == 33;
+ */
+ public void testHarnessInvokeInterface() {
+ Interface I = new Interface("I", AbstractMethod.std());
+ Class C = new Class("C", I, ConcreteMethod.std("33"));
+ assertInvokeInterfaceEquals(33, C, I);
+ }
+
+ /**
+ * class C {}
+ *
+ * TEST: C c = new C(); c.m() throws NoSuchMethod
+ */
+ public void testHarnessThrows() {
+ Class C = new Class("C");
+ assertThrows(NoSuchMethodError.class, C);
+ }
+
+ /**
+ * interface I { int m() default { return 44; } }
+ * class C implements I {}
+ *
+ * TEST: C c = new C(); c.m() == 44;
+ * TEST: I i = new C(); i.m() == 44;
+ */
+ public void testBasicDefault() {
+ Interface I = new Interface("I", DefaultMethod.std("44"));
+ Class C = new Class("C", I);
+
+ assertInvokeVirtualEquals(44, C);
+ assertInvokeInterfaceEquals(44, C, I);
+ }
+
+ /**
+ * interface I { default int m() { return 44; } }
+ * interface J extends I {}
+ * interface K extends J {}
+ * class C implements K {}
+ *
+ * TEST: C c = new C(); c.m() == 44;
+ * TEST: I i = new C(); i.m() == 44;
+ */
+ public void testFarDefault() {
+ Interface I = new Interface("I", DefaultMethod.std("44"));
+ Interface J = new Interface("J", I);
+ Interface K = new Interface("K", J);
+ Class C = new Class("C", K);
+
+ assertInvokeVirtualEquals(44, C);
+ assertInvokeInterfaceEquals(44, C, K);
+ }
+
+ /**
+ * interface I { int m(); }
+ * interface J extends I { default int m() { return 44; } }
+ * interface K extends J {}
+ * class C implements K {}
+ *
+ * TEST: C c = new C(); c.m() == 44;
+ * TEST: K k = new C(); k.m() == 44;
+ */
+ public void testOverrideAbstract() {
+ Interface I = new Interface("I", AbstractMethod.std());
+ Interface J = new Interface("J", I, DefaultMethod.std("44"));
+ Interface K = new Interface("K", J);
+ Class C = new Class("C", K);
+
+ assertInvokeVirtualEquals(44, C);
+ assertInvokeInterfaceEquals(44, C, K);
+ }
+
+ /**
+ * interface I { int m() default { return 44; } }
+ * class C implements I { public int m() { return 55; } }
+ *
+ * TEST: C c = new C(); c.m() == 55;
+ * TEST: I i = new C(); i.m() == 55;
+ */
+ public void testExisting() {
+ Interface I = new Interface("I", DefaultMethod.std("44"));
+ Class C = new Class("C", I, ConcreteMethod.std("55"));
+
+ assertInvokeVirtualEquals(55, C);
+ assertInvokeInterfaceEquals(55, C, I);
+ }
+
+ /**
+ * interface I { default int m() { return 99; } }
+ * class B implements I {}
+ * class C extends B {}
+ *
+ * TEST: C c = new C(); c.m() == 99;
+ * TEST: I i = new C(); i.m() == 99;
+ */
+ public void testInherited() {
+ Interface I = new Interface("I", DefaultMethod.std("99"));
+ Class B = new Class("B", I);
+ Class C = new Class("C", B);
+
+ assertInvokeVirtualEquals(99, C);
+ assertInvokeInterfaceEquals(99, C, I);
+ }
+
+ /**
+ * interface I { default int m() { return 99; } }
+ * class C { public int m() { return 11; } }
+ * class D extends C implements I {}
+ *
+ * TEST: D d = new D(); d.m() == 11;
+ * TEST: I i = new D(); i.m() == 11;
+ */
+ public void testExistingInherited() {
+ Interface I = new Interface("I", DefaultMethod.std("99"));
+ Class C = new Class("C", ConcreteMethod.std("11"));
+ Class D = new Class("D", C, I);
+
+ assertInvokeVirtualEquals(11, D);
+ assertInvokeInterfaceEquals(11, D, I);
+ }
+
+ /**
+ * interface I { default int m() { return 44; } }
+ * class C implements I { public int m() { return 11; } }
+ * class D extends C { public int m() { return 22; } }
+ *
+ * TEST: D d = new D(); d.m() == 22;
+ * TEST: I i = new D(); i.m() == 22;
+ */
+ void testExistingInheritedOverride() {
+ Interface I = new Interface("I", DefaultMethod.std("99"));
+ Class C = new Class("C", I, ConcreteMethod.std("11"));
+ Class D = new Class("D", C, ConcreteMethod.std("22"));
+
+ assertInvokeVirtualEquals(22, D);
+ assertInvokeInterfaceEquals(22, D, I);
+ }
+
+ /**
+ * interface I { default int m() { return 99; } }
+ * interface J { defaultint m() { return 88; } }
+ * class C implements I { public int m() { return 11; } }
+ * class D extends C { public int m() { return 22; } }
+ * class E extends D implements J {}
+ *
+ * TEST: E e = new E(); e.m() == 22;
+ * TEST: J j = new E(); j.m() == 22;
+ */
+ public void testExistingInheritedPlusDefault() {
+ Interface I = new Interface("I", DefaultMethod.std("99"));
+ Interface J = new Interface("J", DefaultMethod.std("88"));
+ Class C = new Class("C", I, ConcreteMethod.std("11"));
+ Class D = new Class("D", C, ConcreteMethod.std("22"));
+ Class E = new Class("E", D, J);
+
+ assertInvokeVirtualEquals(22, E);
+ assertInvokeInterfaceEquals(22, E, J);
+ }
+
+ /**
+ * interface I { default int m() { return 99; } }
+ * class B implements I {}
+ * class C extends B { public int m() { return 77; } }
+ *
+ * TEST: C c = new C(); c.m() == 77;
+ * TEST: I i = new C(); i.m() == 77;
+ */
+ public void testInheritedWithConcrete() {
+ Interface I = new Interface("I", DefaultMethod.std("99"));
+ Class B = new Class("B", I);
+ Class C = new Class("C", B, ConcreteMethod.std("77"));
+
+ assertInvokeVirtualEquals(77, C);
+ assertInvokeInterfaceEquals(77, C, I);
+ }
+
+ /**
+ * interface I { default int m() { return 99; } }
+ * class B implements I {}
+ * class C extends B implements I { public int m() { return 66; } }
+ *
+ * TEST: C c = new C(); c.m() == 66;
+ * TEST: I i = new C(); i.m() == 66;
+ */
+ public void testInheritedWithConcreteAndImpl() {
+ Interface I = new Interface("I", DefaultMethod.std("99"));
+ Class B = new Class("B", I);
+ Class C = new Class("C", B, I, ConcreteMethod.std("66"));
+
+ assertInvokeVirtualEquals(66, C);
+ assertInvokeInterfaceEquals(66, C, I);
+ }
+
+ /**
+ * interface I { default int m() { return 99; } }
+ * interface J { default int m() { return 88; } }
+ * class C implements I, J {}
+ *
+ * TEST: C c = new C(); c.m() throws AME
+ */
+ public void testConflict() {
+ // debugTest();
+ Interface I = new Interface("I", DefaultMethod.std("99"));
+ Interface J = new Interface("J", DefaultMethod.std("88"));
+ Class C = new Class("C", I, J);
+
+ assertThrows(AbstractMethodError.class, C);
+ }
+
+ /**
+ * interface I { int m(); }
+ * interface J { default int m() { return 88; } }
+ * class C implements I, J {}
+ *
+ * TEST: C c = new C(); c.m() throws AME
+ */
+ public void testAmbiguousReabstract() {
+ Interface I = new Interface("I", AbstractMethod.std());
+ Interface J = new Interface("J", DefaultMethod.std("88"));
+ Class C = new Class("C", I, J);
+
+ assertThrows(AbstractMethodError.class, C);
+ }
+
+ /**
+ * interface I { default int m() { return 99; } }
+ * interface J extends I { }
+ * interface K extends I { }
+ * class C implements J, K {}
+ *
+ * TEST: C c = new C(); c.m() == 99
+ * TEST: J j = new C(); j.m() == 99
+ * TEST: K k = new C(); k.m() == 99
+ * TEST: I i = new C(); i.m() == 99
+ */
+ public void testDiamond() {
+ Interface I = new Interface("I", DefaultMethod.std("99"));
+ Interface J = new Interface("J", I);
+ Interface K = new Interface("K", I);
+ Class C = new Class("C", J, K);
+
+ assertInvokeVirtualEquals(99, C);
+ assertInvokeInterfaceEquals(99, C, J);
+ assertInvokeInterfaceEquals(99, C, K);
+ assertInvokeInterfaceEquals(99, C, I);
+ }
+
+ /**
+ * interface I { default int m() { return 99; } }
+ * interface J extends I { }
+ * interface K extends I { }
+ * interface L extends I { }
+ * interface M extends I { }
+ * class C implements I, J, K, L, M {}
+ *
+ * TEST: C c = new C(); c.m() == 99
+ * TEST: J j = new C(); j.m() == 99
+ * TEST: K k = new C(); k.m() == 99
+ * TEST: I i = new C(); i.m() == 99
+ * TEST: L l = new C(); l.m() == 99
+ * TEST: M m = new C(); m.m() == 99
+ */
+ public void testExpandedDiamond() {
+ Interface I = new Interface("I", DefaultMethod.std("99"));
+ Interface J = new Interface("J", I);
+ Interface K = new Interface("K", I);
+ Interface L = new Interface("L", I);
+ Interface M = new Interface("M", L);
+ Class C = new Class("C", I, J, K, L, M);
+
+ assertInvokeVirtualEquals(99, C);
+ assertInvokeInterfaceEquals(99, C, J);
+ assertInvokeInterfaceEquals(99, C, K);
+ assertInvokeInterfaceEquals(99, C, I);
+ assertInvokeInterfaceEquals(99, C, L);
+ assertInvokeInterfaceEquals(99, C, M);
+ }
+
+ /**
+ * interface I { int m() default { return 99; } }
+ * interface J extends I { int m(); }
+ * class C implements J {}
+ *
+ * TEST: C c = new C(); c.m() throws AME
+ */
+ public void testReabstract() {
+ Interface I = new Interface("I", DefaultMethod.std("99"));
+ Interface J = new Interface("J", I, AbstractMethod.std());
+ Class C = new Class("C", J);
+
+ assertThrows(AbstractMethodError.class, C);
+ }
+
+ /**
+ * interface I { default int m() { return 88; } }
+ * interface J extends I { default int m() { return 99; } }
+ * class C implements J {}
+ *
+ * TEST: C c = new C(); c.m() == 99;
+ * TEST: J j = new C(); j.m() == 99;
+ * TEST: I i = new C(); i.m() == 99;
+ */
+ public void testShadow() {
+ Interface I = new Interface("I", DefaultMethod.std("88"));
+ Interface J = new Interface("J", I, DefaultMethod.std("99"));
+ Class C = new Class("C", J);
+
+ assertInvokeVirtualEquals(99, C);
+ assertInvokeInterfaceEquals(99, C, J);
+ assertInvokeInterfaceEquals(99, C, I);
+ }
+
+ /**
+ * interface I { default int m() { return 88; } }
+ * interface J extends I { default int m() { return 99; } }
+ * class C implements I, J {}
+ *
+ * TEST: C c = new C(); c.m() == 99;
+ * TEST: J j = new C(); j.m() == 99;
+ * TEST: I i = new C(); i.m() == 99;
+ */
+ public void testDisqualified() {
+ Interface I = new Interface("I", DefaultMethod.std("88"));
+ Interface J = new Interface("J", I, DefaultMethod.std("99"));
+ Class C = new Class("C", I, J);
+
+ assertInvokeVirtualEquals(99, C);
+ assertInvokeInterfaceEquals(99, C, J);
+ assertInvokeInterfaceEquals(99, C, I);
+ }
+
+ /**
+ * interface I<T> { default int m(T t) { return 99; } }
+ * Class C implements I<String> { public int m() { return 88; } }
+ *
+ * TEST: C c = new C(); c.m() == 88;
+ * TEST: I i = new C(); i.m() == 88;
+ */
+ public void testSelfFill() {
+ // This test ensures that a concrete method overrides a default method
+ // that matches at the language-level, but has a different method
+ // signature due to erasure.
+
+ // debugTest();
+
+ DefaultMethod dm = new DefaultMethod(
+ "int", "m", "return 99;", new MethodParameter("T", "t"));
+ ConcreteMethod cm = new ConcreteMethod(
+ "int", "m", "return 88;", AccessFlag.PUBLIC,
+ new MethodParameter("String", "s"));
+
+ Interface I = new Interface("I", new TypeParameter("T"), dm);
+ Class C = new Class("C", I.with("String"), cm);
+
+ AbstractMethod pm = new AbstractMethod(
+ "int", "m", new MethodParameter("T", "t"));
+
+ assertInvokeVirtualEquals(new Integer(88), C, cm, "-1", "\"string\"");
+ assertInvokeInterfaceEquals(
+ new Integer(88), C, I.with("String"), pm, "\"string\"");
+ }
+
+ /**
+ * interface I { default int m() { return 99; } }
+ * class C implements I {}
+ *
+ * TEST: C.class.getMethod("m").invoke(new C()) == 99
+ */
+ public void testReflectCall() {
+ Interface I = new Interface("I", DefaultMethod.std("99"));
+ Class C = new Class("C", I);
+
+ Compiler.Flags[] flags = this.verbose ?
+ new Compiler.Flags[] { Compiler.Flags.VERBOSE } :
+ new Compiler.Flags[] {};
+ Compiler compiler = new Compiler(flags);
+ java.lang.Class<?> cls = null;
+ try {
+ cls = compiler.compileAndLoad(C);
+ } catch (ClassNotFoundException e) {
+ fail("Could not load class");
+ }
+
+ java.lang.reflect.Method method = null;
+ try {
+ method = cls.getMethod(stdMethodName);
+ } catch (NoSuchMethodException e) {
+ fail("Could not find method in class");
+ }
+ assertNotNull(method);
+
+ Object c = null;
+ try {
+ c = cls.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ fail("Could not create instance of class");
+ }
+ assertNotNull(c);
+
+ Integer res = null;
+ try {
+ res = (Integer)method.invoke(c);
+ } catch (IllegalAccessException |
+ java.lang.reflect.InvocationTargetException e) {
+ fail("Could not invoke default instance method");
+ }
+ assertNotNull(res);
+
+ assertEquals(res.intValue(), 99);
+
+ compiler.cleanup();
+ }
+
+ /**
+ * interface I<T,V,W> { default int m(T t, V v, W w) { return 99; } }
+ * interface J<T,V> extends I<String,T,V> { int m(T t, V v, String w); } }
+ * interface K<T> extends J<String,T> { int m(T t, String v, String w); } }
+ * class C implements K<String> {
+ * public int m(String t, String v, String w) { return 88; }
+ * }
+ *
+ * TEST: I<String,String,String> i = new C(); i.m("A","B","C") == 88;
+ * TEST: J<String,String> j = new C(); j.m("A","B","C") == 88;
+ * TEST: K<String> k = new C(); k.m("A","B","C") == 88;
+ */
+ public void testBridges() {
+ DefaultMethod dm = new DefaultMethod("int", stdMethodName, "return 99;",
+ new MethodParameter("T", "t"), new MethodParameter("V", "v"),
+ new MethodParameter("W", "w"));
+
+ AbstractMethod pm0 = new AbstractMethod("int", stdMethodName,
+ new MethodParameter("T", "t"), new MethodParameter("V", "v"),
+ new MethodParameter("W", "w"));
+
+ AbstractMethod pm1 = new AbstractMethod("int", stdMethodName,
+ new MethodParameter("T", "t"), new MethodParameter("V", "v"),
+ new MethodParameter("String", "w"));
+
+ AbstractMethod pm2 = new AbstractMethod("int", stdMethodName,
+ new MethodParameter("T", "t"), new MethodParameter("String", "v"),
+ new MethodParameter("String", "w"));
+
+ ConcreteMethod cm = new ConcreteMethod("int",stdMethodName,"return 88;",
+ AccessFlag.PUBLIC,
+ new MethodParameter("String", "t"),
+ new MethodParameter("String", "v"),
+ new MethodParameter("String", "w"));
+
+ Interface I = new Interface("I", new TypeParameter("T"),
+ new TypeParameter("V"), new TypeParameter("W"), dm);
+ Interface J = new Interface("J",
+ new TypeParameter("T"), new TypeParameter("V"),
+ I.with("String", "T", "V"), pm1);
+ Interface K = new Interface("K", new TypeParameter("T"),
+ J.with("String", "T"), pm2);
+ Class C = new Class("C", K.with("String"), cm);
+
+ String[] args = new String[] { "\"A\"", "\"B\"", "\"C\"" };
+ assertInvokeInterfaceEquals(new Integer(88), C,
+ I.with("String", "String", "String"), pm0, args);
+ assertInvokeInterfaceEquals(new Integer(88), C,
+ J.with("String", "String"), pm1, args);
+ assertInvokeInterfaceEquals(new Integer(88), C,
+ K.with("String"), pm2, args);
+ }
+
+ /**
+ * interface J { default int m() { return 88; } }
+ * interface I extends J { default int m() { return J.super.m(); } }
+ * class C implements I {}
+ *
+ * TEST: C c = new C(); c.m() == 88;
+ * TEST: I i = new C(); i.m() == 88;
+ */
+ public void testSuperBasic() {
+ // debugTest();
+
+ Interface J = new Interface("J", DefaultMethod.std("88"));
+ Interface I = new Interface("I", J, new DefaultMethod(
+ "int", stdMethodName, "return J.super.m();"));
+ I.addCompilationDependency(J.findMethod(stdMethodName));
+ Class C = new Class("C", I);
+
+ assertInvokeVirtualEquals(88, C);
+ assertInvokeInterfaceEquals(88, C, I);
+ }
+
+ /**
+ * interface K { int m() default { return 99; } }
+ * interface L { int m() default { return 101; } }
+ * interface J extends K, L {}
+ * interface I extends J, K { int m() default { J.super.m(); } }
+ * class C implements I {}
+ *
+ * TEST: C c = new C(); c.m() throws AME
+ * TODO: add case for K k = new C(); k.m() throws AME
+ */
+ public void testSuperConflict() {
+ // debugTest();
+
+ Interface K = new Interface("K", DefaultMethod.std("99"));
+ Interface L = new Interface("L", DefaultMethod.std("101"));
+ Interface J = new Interface("J", K, L);
+ Interface I = new Interface("I", J, K, new DefaultMethod(
+ "int", stdMethodName, "return J.super.m();"));
+ Interface Jstub = new Interface("J", DefaultMethod.std("-1"));
+ I.addCompilationDependency(Jstub);
+ I.addCompilationDependency(Jstub.findMethod(stdMethodName));
+ Class C = new Class("C", I);
+
+ assertThrows(AbstractMethodError.class, C);
+ }
+
+ /**
+ * interface I { default int m() { return 99; } }
+ * interface J extends I { default int m() { return 55; } }
+ * class C implements I, J { public int m() { return I.super.m(); } }
+ *
+ * TEST: C c = new C(); c.m() throws AME
+ * TODO: add case for J j = new C(); j.m() throws AME
+ */
+ public void testSuperDisqual() {
+ Interface I = new Interface("I", DefaultMethod.std("99"));
+ Interface J = new Interface("J", I, DefaultMethod.std("55"));
+ Class C = new Class("C", I, J,
+ new ConcreteMethod("int", stdMethodName, "return I.super.m();",
+ AccessFlag.PUBLIC));
+ C.addCompilationDependency(I.findMethod(stdMethodName));
+
+ assertThrows(AbstractMethodError.class, C);
+ }
+
+ /**
+ * interface J { int m(); }
+ * interface I extends J { default int m() { return J.super.m(); } }
+ * class C implements I {}
+ *
+ * TEST: C c = new C(); c.m() throws AME
+ * TODO: add case for I i = new C(); i.m() throws AME
+ */
+ public void testSuperNull() {
+ Interface J = new Interface("J", AbstractMethod.std());
+ Interface I = new Interface("I", J, new DefaultMethod(
+ "int", stdMethodName, "return J.super.m();"));
+ Interface Jstub = new Interface("J", DefaultMethod.std("99"));
+ I.addCompilationDependency(Jstub);
+ I.addCompilationDependency(Jstub.findMethod(stdMethodName));
+ Class C = new Class("C", I);
+
+ assertThrows(AbstractMethodError.class, C);
+ }
+
+ /**
+ * interface J<T> { default int m(T t) { return 88; } }
+ * interface I extends J<String> {
+ * int m(String s) default { return J.super.m(); }
+ * }
+ * class C implements I {}
+ *
+ * TEST: I i = new C(); i.m("") == 88;
+ */
+ public void testSuperGeneric() {
+ Interface J = new Interface("J", new TypeParameter("T"),
+ new DefaultMethod("int", stdMethodName, "return 88;",
+ new MethodParameter("T", "t")));
+ Interface I = new Interface("I", J.with("String"),
+ new DefaultMethod("int", stdMethodName, "return J.super.m(s);",
+ new MethodParameter("String", "s")));
+ I.addCompilationDependency(J.findMethod(stdMethodName));
+ Class C = new Class("C", I);
+
+ AbstractMethod pm = new AbstractMethod("int", stdMethodName,
+ new MethodParameter("String", "s"));
+
+ assertInvokeInterfaceEquals(
+ new Integer(88), C, new Extends(I), pm, "\"\"");
+ }
+
+ /**
+ * interface I<T> { int m(T t) default { return 44; } }
+ * interface J extends I<String> { int m(String s) default { return 55; } }
+ * class C implements I<String>, J {
+ * public int m(String s) { return I.super.m(s); }
+ * }
+ *
+ * TEST: C c = new C(); c.m("string") throws AME
+ */
+ public void testSuperGenericDisqual() {
+ MethodParameter t = new MethodParameter("T", "t");
+ MethodParameter s = new MethodParameter("String", "s");
+
+ Interface I = new Interface("I", new TypeParameter("T"),
+ new DefaultMethod("int", stdMethodName, "return 44;", t));
+ Interface J = new Interface("J", I.with("String"),
+ new DefaultMethod("int", stdMethodName, "return 55;", s));
+ Class C = new Class("C", I.with("String"), J,
+ new ConcreteMethod("int", stdMethodName,
+ "return I.super.m(s);", AccessFlag.PUBLIC, s));
+ C.addCompilationDependency(I.findMethod(stdMethodName));
+
+ assertThrows(AbstractMethodError.class, C,
+ new ConcreteMethod(
+ "int", stdMethodName, "return -1;", AccessFlag.PUBLIC, s),
+ "-1", "\"string\"");
+ }
+
+ /**
+ * interface I { default Integer m() { return new Integer(88); } }
+ * class C { Number m() { return new Integer(99); } }
+ * class D extends C implements I {}
+ * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger;
+ * TEST: S s = new S(); s.foo() == new Integer(99)
+ */
+ public void testCovarBridge() {
+ Interface I = new Interface("I", new DefaultMethod(
+ "Integer", "m", "return new Integer(88);"));
+ Class C = new Class("C", new ConcreteMethod(
+ "Number", "m", "return new Integer(99);", AccessFlag.PUBLIC));
+ Class D = new Class("D", I, C);
+
+ ConcreteMethod DstubMethod = new ConcreteMethod(
+ "Integer", "m", "return null;", AccessFlag.PUBLIC);
+ Class Dstub = new Class("D", DstubMethod);
+
+ ConcreteMethod toCall = new ConcreteMethod(
+ "Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC);
+ Class S = new Class("S", D, toCall);
+ S.addCompilationDependency(Dstub);
+ S.addCompilationDependency(DstubMethod);
+
+ assertInvokeVirtualEquals(new Integer(99), S, toCall, "null");
+ }
+
+ /**
+ * interface I { default Integer m() { return new Integer(88); } }
+ * class C { int m() { return 99; } }
+ * class D extends C implements I {}
+ * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger;
+ * TEST: S s = new S(); s.foo() == new Integer(88)
+ */
+ public void testNoCovarNoBridge() {
+ Interface I = new Interface("I", new DefaultMethod(
+ "Integer", "m", "return new Integer(88);"));
+ Class C = new Class("C", new ConcreteMethod(
+ "int", "m", "return 99;", AccessFlag.PUBLIC));
+ Class D = new Class("D", I, C);
+
+ ConcreteMethod DstubMethod = new ConcreteMethod(
+ "Integer", "m", "return null;", AccessFlag.PUBLIC);
+ Class Dstub = new Class("D", DstubMethod);
+
+ ConcreteMethod toCall = new ConcreteMethod(
+ "Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC);
+ Class S = new Class("S", D, toCall);
+ S.addCompilationDependency(Dstub);
+ S.addCompilationDependency(DstubMethod);
+
+ assertInvokeVirtualEquals(new Integer(88), S, toCall, "null");
+ }
+
+ /**
+ * interface J { int m(); }
+ * interface I extends J { default int m() { return 99; } }
+ * class B implements J {}
+ * class C extends B implements I {}
+ * TEST: C c = new C(); c.m() == 99
+ *
+ * The point of this test is that B does not get default method analysis,
+ * and C does not generate any new miranda methods in the vtable.
+ * It verifies that default method analysis occurs when mirandas have been
+ * inherited and the supertypes don't have any overpass methods.
+ */
+ public void testNoNewMiranda() {
+ Interface J = new Interface("J", AbstractMethod.std());
+ Interface I = new Interface("I", J, DefaultMethod.std("99"));
+ Class B = new Class("B", J);
+ Class C = new Class("C", B, I);
+ assertInvokeVirtualEquals(99, C);
+ }
+
+ /**
+ * interface I<T,V,W> { int m(T t, V v, W w); }
+ * interface J<T,V> implements I<T,V,String> { int m(T t, V v, String w); }
+ * interface K<T> implements J<T,String> {
+ * int m(T t, String v, String w); { return 99; } }
+ * class C implements K<String> {
+ * public int m(Object t, Object v, String w) { return 77; }
+ * }
+ * TEST C = new C(); ((I)c).m(Object,Object,Object) == 99
+ * TEST C = new C(); ((J)c).m(Object,Object,String) == 77
+ * TEST C = new C(); ((K)c).m(Object,String,String) == 99
+ *
+ * Test that a erased-signature-matching method does not implement
+ * non-language-level matching methods
+ */
+ public void testNonConcreteFill() {
+ AbstractMethod ipm = new AbstractMethod("int", "m",
+ new MethodParameter("T", "t"),
+ new MethodParameter("V", "s"),
+ new MethodParameter("W", "w"));
+ Interface I = new Interface("I",
+ new TypeParameter("T"),
+ new TypeParameter("V"),
+ new TypeParameter("W"), ipm);
+
+ AbstractMethod jpm = new AbstractMethod("int", "m",
+ new MethodParameter("T", "t"),
+ new MethodParameter("V", "s"),
+ new MethodParameter("String", "w"));
+ Interface J = new Interface("J",
+ new TypeParameter("T"),
+ new TypeParameter("V"),
+ I.with("T", "V", "String"), jpm);
+
+ AbstractMethod kpm = new AbstractMethod("int", "m",
+ new MethodParameter("T", "t"),
+ new MethodParameter("String", "s"),
+ new MethodParameter("String", "w"));
+ Interface K = new Interface("K",
+ new TypeParameter("T"),
+ J.with("T", "String"),
+ new DefaultMethod("int", "m", "return 99;",
+ new MethodParameter("T", "t"),
+ new MethodParameter("String", "v"),
+ new MethodParameter("String", "w")));
+
+ Class C = new Class("C",
+ K.with("String"),
+ new ConcreteMethod("int", "m", "return 77;",
+ AccessFlag.PUBLIC,
+ new MethodParameter("Object", "t"),
+ new MethodParameter("Object", "v"),
+ new MethodParameter("String", "w")));
+
+ String a = "\"\"";
+ assertInvokeInterfaceEquals(99, C,
+ K.with("String"), kpm, a, a, a);
+ assertInvokeInterfaceEquals(77, C,
+ J.with("String", "String"), jpm, a, a, a);
+ assertInvokeInterfaceEquals(99, C,
+ I.with("String", "String", "String"), ipm, a, a, a);
+ }
+
+ public void testStrictfpDefault() {
+ try {
+ java.lang.Class.forName("org.openjdk.tests.vm.StrictfpDefault");
+ } catch (Exception e) {
+ fail("Could not load class", e);
+ }
+ }
+
+ public void testSynchronizedDefault() {
+ try {
+ java.lang.Class.forName("org.openjdk.tests.vm.SynchronizedDefault");
+ } catch (Exception e) {
+ fail("Could not load class", e);
+ }
+ }
+}
+
+interface StrictfpDefault {
+ default strictfp void m() {}
+}
+
+interface SynchronizedDefault {
+ default synchronized void m() {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/FDSeparateCompilationTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2012 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.tests.vm;
+
+import java.util.*;
+
+import org.testng.ITestResult;
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterSuite;
+
+import org.openjdk.tests.separate.*;
+import org.openjdk.tests.separate.Compiler;
+
+import org.openjdk.tests.shapegen.Hierarchy;
+import org.openjdk.tests.shapegen.HierarchyGenerator;
+import org.openjdk.tests.shapegen.ClassCase;
+
+import static org.testng.Assert.*;
+import static org.openjdk.tests.separate.SourceModel.*;
+import static org.openjdk.tests.separate.SourceModel.Class;
+import static org.openjdk.tests.separate.SourceModel.Method;
+import static org.openjdk.tests.separate.SourceModel.Type;
+
+public class FDSeparateCompilationTest extends TestHarness {
+
+ private static String EMPTY = "\"\"";
+
+ public FDSeparateCompilationTest() {
+ super(false, true);
+ }
+
+ @DataProvider(name = "allShapes", parallel = true)
+ public Object[][] hierarchyGenerator() {
+ ArrayList<Object[]> allCases = new ArrayList<>();
+
+ HierarchyGenerator hg = new HierarchyGenerator();
+ for (Object x : hg.getOK()) {
+ allCases.add(new Object[]{x});
+ }
+ for (Object x : hg.getErr()) {
+ allCases.add(new Object[]{x});
+ }
+ return allCases.toArray(new Object[0][]);
+ }
+
+ // The expected value obtained when invoking the method from the specified
+ // class. If returns null, then an AbstractMethodError is expected.
+ private static String getExpectedResult(ClassCase cc) {
+ Set<ClassCase> provs = cc.get_mprov();
+ if (cc.get_mres() != null) {
+ return cc.get_mres().getName();
+ } else if (provs != null && provs.size() == 1) {
+ ClassCase cand = provs.iterator().next();
+ switch (cand.kind) {
+ case CCONCRETE:
+ case IDEFAULT:
+ return cand.getName();
+ case CNONE:
+ case IVAC:
+ return getExpectedResult(cand);
+ }
+ }
+ return null;
+ }
+
+ private static final ConcreteMethod canonicalMethod = new ConcreteMethod(
+ "String", "m", "returns " + EMPTY + ";", AccessFlag.PUBLIC);
+
+ @Test(groups = "vm", dataProvider = "allShapes")
+ public void separateCompilationTest(Hierarchy hs) {
+ ClassCase cc = hs.root;
+ Type type = sourceTypeFrom(hs.root);
+
+ Class specimen = null;
+ if (type instanceof Class) {
+ Class ctype = (Class)type;
+ if (ctype.isAbstract()) {
+ specimen = new Class("Test" + ctype.getName(), ctype);
+ } else {
+ specimen = ctype;
+ }
+ } else {
+ specimen = new Class("Test" + type.getName(), (Interface)type);
+ }
+
+ String value = getExpectedResult(cc);
+ if (value != null) {
+ assertInvokeVirtualEquals(value, specimen, canonicalMethod, EMPTY);
+ } else {
+ assertThrows(AbstractMethodError.class, specimen,
+ canonicalMethod, EMPTY);
+ }
+ }
+
+ @AfterMethod
+ public void printCaseError(ITestResult result) {
+ if (result.getStatus() == ITestResult.FAILURE) {
+ Hierarchy hs = (Hierarchy)result.getParameters()[0];
+ System.out.println("Separate compilation case " + hs);
+ printCaseDetails(hs);
+ }
+ }
+
+ @AfterSuite
+ public void cleanupCompilerCache() {
+ Compiler.purgeCache();
+ }
+
+ private void printCaseDetails(Hierarchy hs) {
+ String exp = getExpectedResult(hs.root);
+ for (String s : hs.getDescription()) {
+ System.out.println(" " + s);
+ }
+ if (exp != null) {
+ System.out.println(" Expected \"" + exp + "\"");
+ } else {
+ System.out.println(" Expected AbstractMethodError");
+ }
+ }
+
+ private Type sourceTypeFrom(ClassCase cc) {
+ Type type = null;
+
+ if (cc.isInterface()) {
+ Interface iface = new Interface(cc.getName());
+ for (ClassCase scc : cc.getInterfaces()) {
+ Interface supertype = (Interface)sourceTypeFrom(scc);
+ iface.addSuperType(supertype);
+ }
+ type = iface;
+ } else {
+ Class cls = new Class(cc.getName());
+ if (cc.hasSuperclass()) {
+ Class superc = (Class)sourceTypeFrom(cc.getSuperclass());
+ cls.setSuperClass(superc);
+ }
+ for (ClassCase scc : cc.getInterfaces()) {
+ Interface supertype = (Interface)sourceTypeFrom(scc);
+ cls.addSuperType(supertype);
+ }
+ if (cc.isAbstract()) {
+ cls.getAccessFlags().add(AccessFlag.ABSTRACT);
+ }
+ type = cls;
+ }
+ Method method = methodFrom(cc);
+ if (method != null) {
+ type.addMethod(method);
+ }
+ return type;
+ }
+
+ private Method methodFrom(ClassCase cc) {
+ switch (cc.kind) {
+ case IVAC:
+ case CNONE: return null;
+ case IPRESENT:
+ case CABSTRACT:
+ return new AbstractMethod("String", "m", AccessFlag.PUBLIC);
+ case IDEFAULT:
+ return new DefaultMethod(
+ "String", "m", "return \"" + cc.getName() + "\";");
+ case CCONCRETE:
+ return new ConcreteMethod(
+ "String", "m", "return \"" + cc.getName() + "\";",
+ AccessFlag.PUBLIC);
+ default:
+ fail("Unknown method type in class");
+ return null;
+ }
+ }
+}
--- a/langtools/test/tools/javac/nativeHeaders/NativeHeaderTest.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/nativeHeaders/NativeHeaderTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 7150368
+ * @bug 7150368 8003412
* @summary javac should include basic ability to generate native headers
*/
@@ -125,7 +125,7 @@
}
@Test
- void annoTest(RunKind rk, GenKind gk) throws Exception {
+ void oldAnnoTest(RunKind rk, GenKind gk) throws Exception {
List<File> files = new ArrayList<File>();
files.add(createFile("p/C.java",
"@javax.tools.annotation.GenerateNativeHeader class C { }"));
@@ -136,10 +136,33 @@
}
@Test
+ void annoTest(RunKind rk, GenKind gk) throws Exception {
+ List<File> files = new ArrayList<File>();
+ files.add(createFile("p/C.java",
+ "class C { @java.lang.annotation.Native public static final int i = 1907; }"));
+
+ Set<String> expect = createSet("C.h");
+
+ test(rk, gk, files, expect);
+ }
+
+ @Test
+ void oldAnnoNestedClassTest(RunKind rk, GenKind gk) throws Exception {
+ List<File> files = new ArrayList<File>();
+ files.add(createFile("p/C.java",
+ "class C { @javax.tools.annotation.GenerateNativeHeader class Inner { } }"));
+
+ Set<String> expect = createSet("C_Inner.h");
+ if (gk == GenKind.FULL) expect.add("C.h");
+
+ test(rk, gk, files, expect);
+ }
+
+ @Test
void annoNestedClassTest(RunKind rk, GenKind gk) throws Exception {
List<File> files = new ArrayList<File>();
files.add(createFile("p/C.java",
- "class C { @javax.tools.annotation.GenerateNativeHeader class Inner { } }"));
+ "class C { class Inner { @java.lang.annotation.Native public static final int i = 1907; } }"));
Set<String> expect = createSet("C_Inner.h");
if (gk == GenKind.FULL) expect.add("C.h");
--- a/langtools/test/tools/javac/nativeHeaders/javahComparison/CompareTest.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/nativeHeaders/javahComparison/CompareTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 7150368
+ * @bug 7150368 8003412
* @summary javac should include basic ability to generate native headers
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass4.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007, 2012, 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.Native;
+
+public class TestClass4 {
+ @Native
+ public static final byte b = 1;
+
+ @Native
+ public static final short s = 2;
+
+ @Native
+ public static final int i = 3;
+
+ @Native
+ public static final long l = 4;
+
+ @Native
+ public static final float f = 5.0f;
+
+ @Native
+ public static final double d = 6.0;
+
+ @Native
+ public static final Object o = null;
+
+ @Native
+ public static final String t = "8";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/nativeHeaders/javahComparison/TestClass5.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2007, 2012, 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.Native;
+
+public class TestClass5 {
+ @Native
+ public static final int tc5 = 1;
+
+ public class Inner1 {
+ @Native
+ public static final int tc5i1 = 2;
+
+ public class Inner1A {
+ @Native
+ public static final int tc5i1i1a = 3;
+ }
+
+ public class Inner1B {
+ @Native
+ public static final int tc5i1i1b = 4;
+ }
+ }
+
+ public class Inner2 {
+ @Native
+ public static final int tc521 = 5;
+
+ public class Inner2A {
+ @Native
+ public static final int tc5i2i2a = 6;
+ }
+
+ public class Inner2B {
+ @Native
+ public static final int tc5i2i2b = 7;
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/options/T6949443.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010, 2012, 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 6949443
+ * @summary VisitTree assertion triggered using -Xjcov on small sample program
+ * @compile -Xjcov T6949443.java
+ */
+
+public class T6949443 {
+ public static void main(String[] args) {
+ Integer i = 0;
+ i++;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/plugin/showtype/Identifiers.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,7 @@
+/* /nodynamiccopyright */
+
+public class Identifiers {
+ public double E = Math.E;
+ public double PI = Math.PI;
+ public double PIE = PI + E;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/plugin/showtype/Identifiers.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,21 @@
+Identifiers.java:3: Note: type is ()void
+public class Identifiers {
+ ^
+Identifiers.java:4: Note: type is double
+ public double E = Math.E;
+ ^
+Identifiers.java:4: Note: type is java.lang.Math
+ public double E = Math.E;
+ ^
+Identifiers.java:5: Note: type is double
+ public double PI = Math.PI;
+ ^
+Identifiers.java:5: Note: type is java.lang.Math
+ public double PI = Math.PI;
+ ^
+Identifiers.java:6: Note: type is double
+ public double PIE = PI + E;
+ ^
+Identifiers.java:6: Note: type is double
+ public double PIE = PI + E;
+ ^
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/plugin/showtype/Identifiers_PI.out Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,6 @@
+Identifiers.java:5: Note: type is double
+ public double PI = Math.PI;
+ ^
+Identifiers.java:6: Note: type is double
+ public double PIE = PI + E;
+ ^
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/plugin/showtype/ShowTypePlugin.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2012, 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 com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.IdentifierTree;
+import com.sun.source.tree.MemberSelectTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.Plugin;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.util.Trees;
+import java.util.regex.Pattern;
+import javax.lang.model.type.TypeMirror;
+import javax.tools.Diagnostic.Kind;
+
+public class ShowTypePlugin implements Plugin {
+
+ public String getName() {
+ return "showtype";
+ }
+
+ public void call(JavacTask task, String... args) {
+ Pattern pattern = null;
+ if (args.length == 1)
+ pattern = Pattern.compile(args[0]);
+ task.addTaskListener(new PostAnalyzeTaskListener(task, pattern));
+ }
+
+ private static class PostAnalyzeTaskListener implements TaskListener {
+ private final ShowTypeTreeVisitor visitor;
+
+ PostAnalyzeTaskListener(JavacTask task, Pattern pattern) {
+ visitor = new ShowTypeTreeVisitor(task, pattern);
+ }
+
+ @Override
+ public void started(TaskEvent taskEvent) { }
+
+ @Override
+ public void finished(TaskEvent taskEvent) {
+ if (taskEvent.getKind().equals(TaskEvent.Kind.ANALYZE)) {
+ CompilationUnitTree compilationUnit = taskEvent.getCompilationUnit();
+ visitor.scan(compilationUnit, null);
+ }
+ }
+ }
+
+ private static class ShowTypeTreeVisitor extends TreePathScanner<Void, Void> {
+ private final Trees trees;
+ private final Pattern pattern;
+ private CompilationUnitTree currCompUnit;
+
+ ShowTypeTreeVisitor(JavacTask task, Pattern pattern) {
+ trees = Trees.instance(task);
+ this.pattern = pattern;
+ }
+
+ @Override
+ public Void visitCompilationUnit(CompilationUnitTree tree, Void ignore) {
+ currCompUnit = tree;
+ return super.visitCompilationUnit(tree, ignore);
+ }
+
+ @Override
+ public Void visitIdentifier(IdentifierTree tree, Void ignore) {
+ show(tree, tree.getName());
+ return super.visitIdentifier(tree, ignore);
+ }
+
+ @Override
+ public Void visitMemberSelect(MemberSelectTree tree, Void ignore) {
+ show(tree, tree.getIdentifier());
+ return super.visitMemberSelect(tree, ignore);
+ }
+
+ void show(Tree tree, CharSequence name) {
+ if (pattern == null || pattern.matcher(name).matches()) {
+ TypeMirror type = trees.getTypeMirror(getCurrentPath());
+ trees.printMessage(Kind.NOTE, "type is " + type, tree, currCompUnit);
+ }
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/plugin/showtype/Test.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,171 @@
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+/*
+ * Copyright (c) 2012, 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 8001098
+ * @summary Provide a simple light-weight "plug-in" mechanism for javac
+ */
+
+public class Test {
+ public static void main(String... args) throws Exception {
+ new Test().run();
+ }
+
+ final File testSrc;
+ final File pluginSrc;
+ final File pluginClasses ;
+ final File pluginJar;
+ final List<String> ref1;
+ final List<String> ref2;
+ final JavaCompiler compiler;
+ final StandardJavaFileManager fm;
+
+ Test() throws Exception {
+ testSrc = new File(System.getProperty("test.src"));
+ pluginSrc = new File(testSrc, "ShowTypePlugin.java");
+ pluginClasses = new File("plugin");
+ pluginJar = new File("plugin.jar");
+ ref1 = readFile(testSrc, "Identifiers.out");
+ ref2 = readFile(testSrc, "Identifiers_PI.out");
+ compiler = ToolProvider.getSystemJavaCompiler();
+ fm = compiler.getStandardFileManager(null, null, null);
+ }
+
+ void run() throws Exception {
+ // compile the plugin explicitly, to a non-standard directory
+ // so that we don't find it on the wrong path by accident
+ pluginClasses.mkdirs();
+ compile("-d", pluginClasses.getPath(), pluginSrc.getPath());
+ writeFile(new File(pluginClasses, "META-INF/services/com.sun.source.util.Plugin"),
+ "ShowTypePlugin\n");
+ jar("cf", pluginJar.getPath(), "-C", pluginClasses.getPath(), ".");
+
+ testCommandLine("-Xplugin:showtype", ref1);
+ testCommandLine("-Xplugin:showtype PI", ref2);
+ testAPI("-Xplugin:showtype", ref1);
+ testAPI("-Xplugin:showtype PI", ref2);
+
+ if (errors > 0)
+ throw new Exception(errors + " errors occurred");
+ }
+
+ void testAPI(String opt, List<String> ref) throws Exception {
+ File identifiers = new File(testSrc, "Identifiers.java");
+ fm.setLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH, Arrays.asList(pluginJar));
+ fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File(".")));
+ List<String> options = Arrays.asList(opt);
+ Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(identifiers);
+
+ System.err.println("test api: " + options + " " + files);
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ boolean ok = compiler.getTask(pw, fm, null, options, null, files).call();
+ String out = sw.toString();
+ System.err.println(out);
+ if (!ok)
+ error("testCommandLine: compilation failed");
+ checkOutput(out, ref);
+ }
+
+ void testCommandLine(String opt, List<String> ref) {
+ File identifiers = new File(testSrc, "Identifiers.java");
+ String[] args = {
+ "-d", ".",
+ "-processorpath", pluginJar.getPath(),
+ opt,
+ identifiers.getPath() };
+
+ System.err.println("test command line: " + Arrays.asList(args));
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ int rc = com.sun.tools.javac.Main.compile(args, pw);
+ String out = sw.toString();
+ System.err.println(out);
+ if (rc != 0)
+ error("testCommandLine: compilation failed");
+ checkOutput(out, ref);
+ }
+
+ private void checkOutput(String out, List<String> ref) {
+ List<String> lines = Arrays.asList(out
+ .replaceAll(".*?([A-Za-z.]+:[0-9]+: .*)", "$1") // remove file directory
+ .split("[\r\n]+")); // allow for newline formats
+ if (!lines.equals(ref)) {
+ error("unexpected output");
+ }
+ }
+
+ private void compile(String... args) throws Exception {
+ System.err.println("compile: " + Arrays.asList(args));
+ int rc = com.sun.tools.javac.Main.compile(args);
+ if (rc != 0)
+ throw new Exception("compiled failed, rc=" + rc);
+ }
+
+ private void jar(String... args) throws Exception {
+ System.err.println("jar: " + Arrays.asList(args));
+ boolean ok = new sun.tools.jar.Main(System.out, System.err, "jar").run(args);
+ if (!ok)
+ throw new Exception("jar failed");
+ }
+
+ private List<String> readFile(File dir, String name) throws IOException {
+ return Files.readAllLines(new File(dir, name).toPath(), Charset.defaultCharset());
+ }
+
+ private void writeFile(File f, String body) throws IOException {
+ f.getParentFile().mkdirs();
+ try (FileWriter out = new FileWriter(f)) {
+ out.write(body);
+ }
+ }
+
+ private void error(String msg) {
+ System.err.println(msg);
+ errors++;
+ }
+
+ int errors;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/resolve/tests/AmbiguityPrecedence.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+@TraceResolve(keys={"compiler.err.ref.ambiguous"})
+class AmbiguityPrecedence {
+
+ @Candidate(applicable=Phase.BASIC)
+ static void m1(long l, int i) {}
+ @Candidate(applicable=Phase.BASIC)
+ static void m1(int i, long l) {}
+ @Candidate
+ static void m1(Integer i1, Integer i2) {}
+
+ @Candidate(applicable=Phase.BOX)
+ static void m2(Object o, Integer i) {}
+ @Candidate(applicable=Phase.BOX)
+ static void m2(Integer i, Object o) {}
+ @Candidate
+ static void m2(Integer... o) {}
+
+ {
+ m1(1, 1);
+ m2(1, 1);
+ }
+}
--- a/langtools/test/tools/javac/scope/7046348/EagerInterfaceCompletionTest.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/scope/7046348/EagerInterfaceCompletionTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -30,6 +30,7 @@
import java.io.File;
import java.net.URI;
import java.util.Arrays;
+import java.util.List;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
@@ -43,13 +44,15 @@
JavaCompiler javacTool;
File testDir;
+ VersionKind versionKind;
HierarchyKind hierarchyKind;
TestKind testKind;
ActionKind actionKind;
- EagerInterfaceCompletionTest(JavaCompiler javacTool, File testDir,
+ EagerInterfaceCompletionTest(JavaCompiler javacTool, File testDir, VersionKind versionKind,
HierarchyKind hierarchyKind, TestKind testKind, ActionKind actionKind) {
this.javacTool = javacTool;
+ this.versionKind = versionKind;
this.hierarchyKind = hierarchyKind;
this.testDir = testDir;
this.testKind = testKind;
@@ -62,7 +65,7 @@
actionKind.doAction(this);
DiagnosticChecker dc = new DiagnosticChecker();
compile(dc, testKind.source);
- if (testKind.completionFailure(actionKind, hierarchyKind) != dc.errorFound) {
+ if (testKind.completionFailure(versionKind, actionKind, hierarchyKind) != dc.errorFound) {
if (dc.errorFound) {
error("Unexpected completion failure" +
"\nhierarhcyKind " + hierarchyKind +
@@ -80,7 +83,8 @@
void compile(DiagnosticChecker dc, JavaSource... sources) {
try {
CompilationTask ct = javacTool.getTask(null, null, dc,
- Arrays.asList("-d", testDir.getAbsolutePath(), "-cp", testDir.getAbsolutePath()),
+ Arrays.asList("-d", testDir.getAbsolutePath(), "-cp",
+ testDir.getAbsolutePath(), versionKind.optsArr[0], versionKind.optsArr[1]),
null, Arrays.asList(sources));
ct.call();
}
@@ -108,12 +112,25 @@
boolean errorFound = false;
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
- errorFound = true;
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ errorFound = true;
+ }
}
}
//global declarations
+ enum VersionKind {
+ PRE_LAMBDA("-source", "7"),
+ LAMBDA("-source", "8");
+
+ String[] optsArr;
+
+ VersionKind(String... optsArr) {
+ this.optsArr = optsArr;
+ }
+ }
+
enum HierarchyKind {
INTERFACE("interface A { boolean f = false; void m(); }\n" +
"class B implements A { public void m() {} }"),
@@ -157,13 +174,14 @@
this.source = new JavaSource("Test2.java", code);
}
- boolean completionFailure(ActionKind ak, HierarchyKind hk) {
+ boolean completionFailure(VersionKind vk, ActionKind ak, HierarchyKind hk) {
switch (this) {
case ACCESS_ONLY:
case CONSTR: return ak == ActionKind.REMOVE_B;
case FIELD:
case SUPER: return true;
- case METHOD: return hk != HierarchyKind.INTERFACE || ak == ActionKind.REMOVE_B;
+ case METHOD: return hk != HierarchyKind.INTERFACE || ak == ActionKind.REMOVE_B ||
+ (hk == HierarchyKind.INTERFACE && ak == ActionKind.REMOVE_A && vk == VersionKind.LAMBDA);
default: throw new AssertionError("Unexpected test kind " + this);
}
}
@@ -173,12 +191,15 @@
String SCRATCH_DIR = System.getProperty("user.dir");
JavaCompiler javacTool = ToolProvider.getSystemJavaCompiler();
int n = 0;
- for (HierarchyKind hierarchyKind : HierarchyKind.values()) {
- for (TestKind testKind : TestKind.values()) {
- for (ActionKind actionKind : ActionKind.values()) {
- File testDir = new File(SCRATCH_DIR, "test"+n);
- new EagerInterfaceCompletionTest(javacTool, testDir, hierarchyKind, testKind, actionKind).test();
- n++;
+ for (VersionKind versionKind : VersionKind.values()) {
+ for (HierarchyKind hierarchyKind : HierarchyKind.values()) {
+ for (TestKind testKind : TestKind.values()) {
+ for (ActionKind actionKind : ActionKind.values()) {
+ File testDir = new File(SCRATCH_DIR, "test"+n);
+ new EagerInterfaceCompletionTest(javacTool, testDir, versionKind,
+ hierarchyKind, testKind, actionKind).test();
+ n++;
+ }
}
}
}
--- a/langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.out Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/typeAnnotations/newlocations/BasicTest.out Fri Nov 30 17:09:05 2012 -0800
@@ -10,7 +10,6 @@
BasicTest.java:52:31: compiler.err.expected: ';'
BasicTest.java:52:37: compiler.err.expected: token.identifier
BasicTest.java:53:30: compiler.err.expected: token.identifier
-BasicTest.java:53:32: compiler.err.lambda.not.supported.in.source: 1.8
BasicTest.java:53:31: compiler.err.expected: ->
BasicTest.java:56:23: compiler.err.expected: token.identifier
BasicTest.java:56:24: compiler.err.expected2: '(', '['
@@ -59,4 +58,4 @@
BasicTest.java:74:25: compiler.err.illegal.start.of.type
BasicTest.java:74:33: compiler.err.expected: ';'
BasicTest.java:77:2: compiler.err.premature.eof
-61 errors
+60 errors
--- a/langtools/test/tools/javac/versions/check.sh Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javac/versions/check.sh Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2012, 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
@@ -22,7 +22,7 @@
#
# @test
-# @bug 4981566 5028634 5094412 6304984 7025786 7025789
+# @bug 4981566 5028634 5094412 6304984 7025786 7025789 8001112
# @summary Check interpretation of -target and -source options
# @build CheckClassFileVersion
# @run shell check.sh
@@ -47,32 +47,39 @@
"$JC" ${TESTTOOLVMOPTS} -d $TC $* $TC/X.java && "$J" $CFV $TC/X.class $V || exit 2
}
+# check for all combinations of target values
+check_target() {
+ check $1 -source $2 -target $3
+ check $1 -source $2 -target 1.${3}
+}
+# check for all combinations of source and target values
+check_source_target() {
+ check_target $1 $2 $3
+ check_target $1 1.${2} $3
+}
+
check 48.0 -source 1.4
check 49.0 -source 1.4 -target 1.5
check 49.0 -source 1.5 -target 1.5
-check 50.0 -source 1.4 -target 1.6
-check 50.0 -source 1.5 -target 1.6
-check 50.0 -source 1.6 -target 1.6
-check 50.0 -source 1.6 -target 6
-check 50.0 -source 6 -target 1.6
-check 50.0 -source 6 -target 6
+check_target 50.0 1.4 6
+check_target 50.0 1.5 6
+check_source_target 50.0 6 6
+
+check_target 51.0 1.4 7
+check_target 51.0 1.5 7
+check_source_target 51.0 6 7
+check_source_target 51.0 7 7
-check 51.0
-check 51.0 -source 1.5
-check 51.0 -source 1.6
-check 51.0 -source 6
-check 51.0 -source 1.7
-check 51.0 -source 7
-check 51.0 -source 7 -target 1.7
-check 51.0 -source 7 -target 7
+check_target 52.0 1.4 8
+check_target 52.0 1.5 8
+check_source_target 52.0 6 8
+check_source_target 52.0 7 8
+check_source_target 52.0 8 8
-# Update when class file version is revved
-check 51.0 -source 1.8
-check 51.0 -source 8
-check 51.0 -target 1.8
-check 51.0 -target 8
+# and finally the default with no options
+check 52.0
# Check source versions
--- a/langtools/test/tools/javadoc/6958836/Test.java Fri Nov 30 12:39:37 2012 +0000
+++ b/langtools/test/tools/javadoc/6958836/Test.java Fri Nov 30 17:09:05 2012 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6958836
+ * @bug 6958836 8002168
* @summary javadoc should support -Xmaxerrs and -Xmaxwarns
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/CheckResourceKeys.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2010, 2012, 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 8000612
+ * @summary need test program to validate javadoc resource bundles
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.tools.*;
+import com.sun.tools.classfile.*;
+
+/**
+ * Compare string constants in javadoc classes against keys in javadoc resource bundles.
+ */
+public class CheckResourceKeys {
+ /**
+ * Main program.
+ * Options:
+ * -finddeadkeys
+ * look for keys in resource bundles that are no longer required
+ * -findmissingkeys
+ * look for keys in resource bundles that are missing
+ *
+ * @throws Exception if invoked by jtreg and errors occur
+ */
+ public static void main(String... args) throws Exception {
+ CheckResourceKeys c = new CheckResourceKeys();
+ if (c.run(args))
+ return;
+
+ if (is_jtreg())
+ throw new Exception(c.errors + " errors occurred");
+ else
+ System.exit(1);
+ }
+
+ static boolean is_jtreg() {
+ return (System.getProperty("test.src") != null);
+ }
+
+ /**
+ * Main entry point.
+ */
+ boolean run(String... args) throws Exception {
+ boolean findDeadKeys = false;
+ boolean findMissingKeys = false;
+
+ if (args.length == 0) {
+ if (is_jtreg()) {
+ findDeadKeys = true;
+ findMissingKeys = true;
+ } else {
+ System.err.println("Usage: java CheckResourceKeys <options>");
+ System.err.println("where options include");
+ System.err.println(" -finddeadkeys find keys in resource bundles which are no longer required");
+ System.err.println(" -findmissingkeys find keys in resource bundles that are required but missing");
+ return true;
+ }
+ } else {
+ for (String arg: args) {
+ if (arg.equalsIgnoreCase("-finddeadkeys"))
+ findDeadKeys = true;
+ else if (arg.equalsIgnoreCase("-findmissingkeys"))
+ findMissingKeys = true;
+ else
+ error("bad option: " + arg);
+ }
+ }
+
+ if (errors > 0)
+ return false;
+
+ Set<String> codeKeys = getCodeKeys();
+ Set<String> resourceKeys = getResourceKeys();
+
+ System.err.println("found " + codeKeys.size() + " keys in code");
+ System.err.println("found " + resourceKeys.size() + " keys in resource bundles");
+
+ if (findDeadKeys)
+ findDeadKeys(codeKeys, resourceKeys);
+
+ if (findMissingKeys)
+ findMissingKeys(codeKeys, resourceKeys);
+
+ return (errors == 0);
+ }
+
+ /**
+ * Find keys in resource bundles which are probably no longer required.
+ * A key is required if there is a string in the code that is a resource key,
+ * or if the key is well-known according to various pragmatic rules.
+ */
+ void findDeadKeys(Set<String> codeKeys, Set<String> resourceKeys) {
+ for (String rk: resourceKeys) {
+ if (codeKeys.contains(rk))
+ continue;
+
+ error("Resource key not found in code: " + rk);
+ }
+ }
+
+ /**
+ * For all strings in the code that look like they might be
+ * a resource key, verify that a key exists.
+ */
+ void findMissingKeys(Set<String> codeKeys, Set<String> resourceKeys) {
+ for (String ck: codeKeys) {
+ if (resourceKeys.contains(ck))
+ continue;
+ error("No resource for \"" + ck + "\"");
+ }
+ }
+
+ /**
+ * Get the set of strings from (most of) the javadoc classfiles.
+ */
+ Set<String> getCodeKeys() throws IOException {
+ Set<String> results = new TreeSet<String>();
+ JavaCompiler c = ToolProvider.getSystemJavaCompiler();
+ JavaFileManager fm = c.getStandardFileManager(null, null, null);
+ JavaFileManager.Location javadocLoc = findJavadocLocation(fm);
+ String[] pkgs = {
+ "com.sun.tools.doclets",
+ "com.sun.tools.javadoc"
+ };
+ for (String pkg: pkgs) {
+ for (JavaFileObject fo: fm.list(javadocLoc,
+ pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) {
+ String name = fo.getName();
+ // ignore resource files
+ if (name.matches(".*resources.[A-Za-z_0-9]+\\.class.*"))
+ continue;
+ scan(fo, results);
+ }
+ }
+
+ // special handling for code strings synthesized in
+ // com.sun.tools.doclets.internal.toolkit.util.Util.getTypeName
+ String[] extras = {
+ "AnnotationType", "Class", "Enum", "Error", "Exception", "Interface"
+ };
+ for (String s: extras) {
+ if (results.contains("doclet." + s))
+ results.add("doclet." + s.toLowerCase());
+ }
+
+ // special handling for code strings synthesized in
+ // com.sun.tools.javadoc.Messager
+ results.add("javadoc.error.msg");
+ results.add("javadoc.note.msg");
+ results.add("javadoc.note.pos.msg");
+ results.add("javadoc.warning.msg");
+
+ return results;
+ }
+
+ // depending on how the test is run, javadoc may be on bootclasspath or classpath
+ JavaFileManager.Location findJavadocLocation(JavaFileManager fm) {
+ JavaFileManager.Location[] locns =
+ { StandardLocation.PLATFORM_CLASS_PATH, StandardLocation.CLASS_PATH };
+ try {
+ for (JavaFileManager.Location l: locns) {
+ JavaFileObject fo = fm.getJavaFileForInput(l,
+ "com.sun.tools.javadoc.Main", JavaFileObject.Kind.CLASS);
+ if (fo != null) {
+ System.err.println("found javadoc in " + l);
+ return l;
+ }
+ }
+ } catch (IOException e) {
+ throw new Error(e);
+ }
+ throw new IllegalStateException("Cannot find javadoc");
+ }
+
+ /**
+ * Get the set of strings from a class file.
+ * Only strings that look like they might be a resource key are returned.
+ */
+ void scan(JavaFileObject fo, Set<String> results) throws IOException {
+ //System.err.println("scan " + fo.getName());
+ InputStream in = fo.openInputStream();
+ try {
+ ClassFile cf = ClassFile.read(in);
+ for (ConstantPool.CPInfo cpinfo: cf.constant_pool.entries()) {
+ if (cpinfo.getTag() == ConstantPool.CONSTANT_Utf8) {
+ String v = ((ConstantPool.CONSTANT_Utf8_info) cpinfo).value;
+ if (v.matches("(doclet|main|javadoc|tag)\\.[A-Za-z0-9-_.]+"))
+ results.add(v);
+ }
+ }
+ } catch (ConstantPoolException ignore) {
+ } finally {
+ in.close();
+ }
+ }
+
+ /**
+ * Get the set of keys from the javadoc resource bundles.
+ */
+ Set<String> getResourceKeys() {
+ String[] names = {
+ "com.sun.tools.doclets.formats.html.resources.standard",
+ "com.sun.tools.doclets.internal.toolkit.resources.doclets",
+ "com.sun.tools.javadoc.resources.javadoc",
+ };
+ Set<String> results = new TreeSet<String>();
+ for (String name : names) {
+ ResourceBundle b = ResourceBundle.getBundle(name);
+ results.addAll(b.keySet());
+ }
+ return results;
+ }
+
+ /**
+ * Report an error.
+ */
+ void error(String msg) {
+ System.err.println("Error: " + msg);
+ errors++;
+ }
+
+ int errors;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/APITest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2012, 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.io.File;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+
+
+/*
+ * Superclass with utility methods for API tests.
+ */
+class APITest {
+ protected APITest() { }
+
+ /** Marker annotation for test cases. */
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface Test { }
+
+ /** Invoke all methods annotated with @Test. */
+ protected void run() throws Exception {
+ for (Method m: getClass().getDeclaredMethods()) {
+ Annotation a = m.getAnnotation(Test.class);
+ if (a != null) {
+ testCount++;
+ testName = m.getName();
+ System.err.println("test: " + testName);
+ try {
+ m.invoke(this, new Object[] { });
+ } catch (InvocationTargetException e) {
+ Throwable cause = e.getCause();
+ throw (cause instanceof Exception) ? ((Exception) cause) : e;
+ }
+ System.err.println();
+ }
+ }
+
+ if (testCount == 0)
+ error("no tests found");
+
+ StringBuilder summary = new StringBuilder();
+ if (testCount != 1)
+ summary.append(testCount).append(" tests");
+ if (errorCount > 0) {
+ if (summary.length() > 0) summary.append(", ");
+ summary.append(errorCount).append(" errors");
+ }
+ System.err.println(summary);
+ if (errorCount > 0)
+ throw new Exception(errorCount + " errors found");
+ }
+
+ /**
+ * Create a directory in which to store generated doc files.
+ * Avoid using the default (current) directory, so that we can
+ * be sure that javadoc is writing in the intended location,
+ * not a default location.
+ */
+ protected File getOutDir() {
+ File dir = new File(testName);
+ dir.mkdirs();
+ return dir;
+ }
+
+ /**
+ * Create a directory in which to store generated doc files.
+ * Avoid using the default (current) directory, so that we can
+ * be sure that javadoc is writing in the intended location,
+ * not a default location.
+ */
+ protected File getOutDir(String path) {
+ File dir = new File(testName, path);
+ dir.mkdirs();
+ return dir;
+ }
+
+ protected JavaFileObject createSimpleJavaFileObject() {
+ return createSimpleJavaFileObject("pkg/C", "package pkg; public class C { }");
+ }
+
+ protected JavaFileObject createSimpleJavaFileObject(final String binaryName, final String content) {
+ return new SimpleJavaFileObject(
+ URI.create("myfo:///" + binaryName + ".java"), JavaFileObject.Kind.SOURCE) {
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncoding) {
+ return content;
+ }
+ };
+ }
+
+ protected void checkFiles(File dir, Set<String> expectFiles) {
+ Set<File> files = new HashSet<File>();
+ listFiles(dir, files);
+ Set<String> foundFiles = new HashSet<String>();
+ URI dirURI = dir.toURI();
+ for (File f: files)
+ foundFiles.add(dirURI.relativize(f.toURI()).getPath());
+ checkFiles(foundFiles, expectFiles, dir);
+ }
+
+ protected void checkFiles(Path dir, Set<String> expectFiles) throws IOException {
+ Set<Path> files = new HashSet<Path>();
+ listFiles(dir, files);
+ Set<String> foundFiles = new HashSet<String>();
+ for (Path f: files) {
+ foundFiles.add(dir.relativize(f).toString().replace(f.getFileSystem().getSeparator(), "/"));
+ }
+ checkFiles(foundFiles, expectFiles, dir);
+ }
+
+ private void checkFiles(Set<String> foundFiles, Set<String> expectFiles, Object where) {
+ if (!foundFiles.equals(expectFiles)) {
+ Set<String> missing = new TreeSet<String>(expectFiles);
+ missing.removeAll(foundFiles);
+ if (!missing.isEmpty())
+ error("the following files were not found in " + where + ": " + missing);
+ Set<String> unexpected = new TreeSet<String>(foundFiles);
+ unexpected.removeAll(expectFiles);
+ if (!unexpected.isEmpty())
+ error("the following unexpected files were found in " + where + ": " + unexpected);
+ }
+ }
+
+ protected void listFiles(File dir, Set<File> files) {
+ for (File f: dir.listFiles()) {
+ if (f.isDirectory())
+ listFiles(f, files);
+ else if (f.isFile())
+ files.add(f);
+ }
+ }
+
+ private void listFiles(Path dir, Set<Path> files) throws IOException {
+ for (Path f: Files.newDirectoryStream(dir)) {
+ if (Files.isDirectory(f))
+ listFiles(f, files);
+ else if (Files.isRegularFile(f))
+ files.add(f);
+ }
+ }
+
+ protected void error(String msg) {
+ System.err.println("Error: " + msg);
+ errorCount++;
+ }
+
+ protected int testCount;
+ protected int errorCount;
+
+ protected String testName;
+
+ /**
+ * Standard files generated by processing a documented class pkg.C.
+ */
+ protected static Set<String> standardExpectFiles = new HashSet<String>(Arrays.asList(
+ "allclasses-frame.html",
+ "allclasses-noframe.html",
+ "constant-values.html",
+ "deprecated-list.html",
+ "help-doc.html",
+ "index-all.html",
+ "index.html",
+ "overview-tree.html",
+ "package-list",
+ "pkg/C.html",
+ "pkg/package-frame.html",
+ "pkg/package-summary.html",
+ "pkg/package-tree.html",
+ "resources/background.gif",
+ "resources/tab.gif",
+ "resources/activetitlebar_end.gif",
+ "resources/activetitlebar.gif",
+ "resources/titlebar_end.gif",
+ "resources/titlebar.gif",
+ "script.js",
+ "stylesheet.css"
+ ));
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/DocletPathTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2012, 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 6493690
+ * @summary javadoc should have a javax.tools.Tool service provider
+ * @build APITest
+ * @run main DocletPathTest
+ */
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+/**
+ * Tests for locating a doclet via the file manager's DOCLET_PATH.
+ */
+public class DocletPathTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new DocletPathTest().run();
+ }
+
+ /**
+ * Verify that an alternate doclet can be specified, and located via
+ * the file manager's DOCLET_PATH.
+ */
+ @Test
+ public void testDocletPath() throws Exception {
+ JavaFileObject docletSrc =
+ createSimpleJavaFileObject("DocletOnDocletPath", docletSrcText);
+ File docletDir = getOutDir("classes");
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager cfm = compiler.getStandardFileManager(null, null, null);
+ cfm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(docletDir));
+ Iterable<? extends JavaFileObject> cfiles = Arrays.asList(docletSrc);
+ if (!compiler.getTask(null, cfm, null, null, null, cfiles).call())
+ throw new Exception("cannot compile doclet");
+
+ JavaFileObject srcFile = createSimpleJavaFileObject();
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir("api");
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ fm.setLocation(DocumentationTool.Location.DOCLET_PATH, Arrays.asList(docletDir));
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ Iterable<String> options = Arrays.asList("-doclet", "DocletOnDocletPath");
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ DocumentationTask t = tool.getTask(pw, fm, null, null, options, files);
+ boolean ok = t.call();
+ String out = sw.toString();
+ System.err.println(">>" + out + "<<");
+ if (ok) {
+ if (out.contains(TEST_STRING)) {
+ System.err.println("doclet executed as expected");
+ } else {
+ error("test string not found in doclet output");
+ }
+ } else {
+ error("task failed");
+ }
+ }
+
+ private static final String TEST_STRING = "DocletOnDocletPath found and running";
+
+ private static final String docletSrcText =
+ "import com.sun.javadoc.*;\n" +
+ "public class DocletOnDocletPath {\n" +
+ " public static boolean start(RootDoc doc) {\n" +
+ " doc.printNotice(\"" + TEST_STRING + "\");\n" +
+ " return true;\n" +
+ " }\n" +
+ " public static int optionLength(String option) { return 0; }\n" +
+ " public static boolean validOptions(String options[][],\n" +
+ " DocErrorReporter reporter) { return true; }\n" +
+ " public static LanguageVersion languageVersion() {\n" +
+ " return LanguageVersion.JAVA_1_1;\n" +
+ " }\n" +
+ "}\n";
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/GetSourceVersionsTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, 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 6493690
+ * @summary javadoc should have a javax.tools.Tool service provider
+ * @build APITest
+ * @run main GetSourceVersionsTest
+ */
+
+import java.util.EnumSet;
+import java.util.Set;
+import javax.lang.model.SourceVersion;
+import javax.tools.DocumentationTool;
+import javax.tools.ToolProvider;
+
+/**
+ * Tests for DocumentationTool.getSourceVersions method.
+ */
+public class GetSourceVersionsTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new GetSourceVersionsTest().run();
+ }
+
+ /**
+ * Verify getSourceVersions.
+ */
+ @Test
+ public void testRun() throws Exception {
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ Set<SourceVersion> found = tool.getSourceVersions();
+ Set<SourceVersion> expect = EnumSet.range(SourceVersion.RELEASE_3, SourceVersion.latest());
+ if (!expect.equals(found)) {
+ System.err.println("expect: " + expect);
+ System.err.println(" found: " + expect);
+ error("unexpected versions");
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/GetTask_DiagListenerTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, 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 6493690
+ * @summary javadoc should have a javax.tools.Tool service provider
+ * @build APITest
+ * @run main GetTask_DiagListenerTest
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+/**
+ * Tests for DocumentationTool.getTask diagnosticListener parameter.
+ */
+public class GetTask_DiagListenerTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new GetTask_DiagListenerTest().run();
+ }
+
+ /**
+ * Verify that a diagnostic listener can be specified.
+ * Note that messages from the tool and doclet are imperfectly modeled
+ * because the DocErrorReporter API works in terms of localized strings
+ * and file:line positions. Therefore, messages reported via DocErrorReporter
+ * and simply wrapped and passed through.
+ */
+ @Test
+ public void testDiagListener() throws Exception {
+ JavaFileObject srcFile = createSimpleJavaFileObject("pkg/C", "package pkg; public error { }");
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<JavaFileObject>();
+ DocumentationTask t = tool.getTask(null, fm, dc, null, null, files);
+ if (t.call()) {
+ throw new Exception("task succeeded unexpectedly");
+ } else {
+ List<String> diagCodes = new ArrayList<String>();
+ for (Diagnostic d: dc.getDiagnostics()) {
+ System.err.println(d);
+ diagCodes.add(d.getCode());
+ }
+ List<String> expect = Arrays.asList(
+ "javadoc.note.msg", // Loading source file
+ "compiler.err.expected3", // class, interface, or enum expected
+ "javadoc.note.msg"); // 1 error
+ if (!diagCodes.equals(expect))
+ throw new Exception("unexpected diagnostics occurred");
+ System.err.println("diagnostics received as expected");
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/GetTask_DocletClassTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2012, 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 6493690
+ * @summary javadoc should have a javax.tools.Tool service provider
+ * @build APITest
+ * @run main GetTask_DocletClassTest
+ */
+
+import com.sun.javadoc.DocErrorReporter;
+import com.sun.javadoc.LanguageVersion;
+import com.sun.javadoc.RootDoc;
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Random;
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+/**
+ * Tests for DocumentationTool.getTask docletClass parameter.
+ */
+public class GetTask_DocletClassTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new GetTask_DocletClassTest().run();
+ }
+
+ /**
+ * Verify that an alternate doclet can be specified.
+ *
+ * There is no standard interface or superclass for a doclet;
+ * the only requirement is that it provides static methods that
+ * can be invoked via reflection. So, for now, the doclet is
+ * specified as a class.
+ * Because we cannot create and use a unique instance of the class,
+ * we verify that the doclet has been called by having it record
+ * (in a static field!) the comment from the last time it was invoked,
+ * which is randomly generated each time the test is run.
+ */
+ @Test
+ public void testDoclet() throws Exception {
+ Random r = new Random();
+ int key = r.nextInt();
+ JavaFileObject srcFile = createSimpleJavaFileObject(
+ "pkg/C",
+ "package pkg; /** " + key + "*/ public class C { }");
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ DocumentationTask t = tool.getTask(null, fm, null, TestDoclet.class, null, files);
+ if (t.call()) {
+ System.err.println("task succeeded");
+ if (TestDoclet.lastCaller.equals(String.valueOf(key)))
+ System.err.println("found expected key: " + key);
+ else
+ error("Expected key not found");
+ checkFiles(outDir, Collections.<String>emptySet());
+ } else {
+ throw new Exception("task failed");
+ }
+ }
+
+ public static class TestDoclet {
+ static String lastCaller;
+ public static boolean start(RootDoc root) {
+ lastCaller = root.classNamed("pkg.C").commentText().trim();
+ return true;
+ }
+
+ public static int optionLength(String option) {
+ return 0; // default is option unknown
+ }
+
+ public static boolean validOptions(String options[][],
+ DocErrorReporter reporter) {
+ return true; // default is options are valid
+ }
+
+ public static LanguageVersion languageVersion() {
+ return LanguageVersion.JAVA_1_1;
+ }
+ }
+
+ /**
+ * Verify that exceptions from a doclet are thrown as expected.
+ */
+ @Test
+ public void testBadDoclet() throws Exception {
+ JavaFileObject srcFile = createSimpleJavaFileObject();
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ DocumentationTask t = tool.getTask(null, fm, null, BadDoclet.class, null, files);
+ try {
+ t.call();
+ error("call completed without exception");
+ } catch (RuntimeException e) {
+ Throwable c = e.getCause();
+ if (c.getClass() == UnexpectedError.class)
+ System.err.println("exception caught as expected: " + c);
+ else
+ throw e;
+ }
+ }
+
+ public static class UnexpectedError extends Error { }
+
+ public static class BadDoclet {
+ public static boolean start(RootDoc root) {
+ throw new UnexpectedError();
+ }
+
+ public static int optionLength(String option) {
+ return 0; // default is option unknown
+ }
+
+ public static boolean validOptions(String options[][],
+ DocErrorReporter reporter) {
+ return true; // default is options are valid
+ }
+
+ public static LanguageVersion languageVersion() {
+ return LanguageVersion.JAVA_1_1;
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/GetTask_FileManagerTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2012, 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 6493690
+ * @summary javadoc should have a javax.tools.Tool service provider
+ * @build APITest
+ * @run main GetTask_FileManagerTest
+ */
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Set;
+
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.ToolProvider;
+
+import com.sun.tools.javac.nio.JavacPathFileManager;
+import com.sun.tools.javac.nio.PathFileManager;
+import com.sun.tools.javac.util.Context;
+
+/**
+ * Tests for DocumentationTool.getTask fileManager parameter.
+ */
+public class GetTask_FileManagerTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new GetTask_FileManagerTest().run();
+ }
+
+ /**
+ * Verify that an alternate file manager can be specified:
+ * in this case, a PathFileManager.
+ */
+ @Test
+ public void testFileManager() throws Exception {
+ JavaFileObject srcFile = createSimpleJavaFileObject();
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ PathFileManager fm = new JavacPathFileManager(new Context(), false, null);
+ Path outDir = getOutDir().toPath();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ DocumentationTask t = tool.getTask(null, fm, null, null, null, files);
+ if (t.call()) {
+ System.err.println("task succeeded");
+ checkFiles(outDir, standardExpectFiles);
+ } else {
+ throw new Exception("task failed");
+ }
+ }
+
+ /**
+ * Verify that exceptions from a bad file manager are thrown as expected.
+ */
+ @Test
+ public void testBadFileManager() throws Exception {
+ JavaFileObject srcFile = createSimpleJavaFileObject();
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ PathFileManager fm = new JavacPathFileManager(new Context(), false, null) {
+ @Override
+ public Iterable<JavaFileObject> list(Location location,
+ String packageName,
+ Set<Kind> kinds,
+ boolean recurse)
+ throws IOException {
+ throw new UnexpectedError();
+ }
+ };
+ Path outDir = getOutDir().toPath();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ DocumentationTask t = tool.getTask(null, fm, null, null, null, files);
+ try {
+ t.call();
+ error("call completed without exception");
+ } catch (RuntimeException e) {
+ Throwable c = e.getCause();
+ if (c.getClass() == UnexpectedError.class)
+ System.err.println("exception caught as expected: " + c);
+ else
+ throw e;
+ }
+ }
+
+ public static class UnexpectedError extends Error { }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/GetTask_FileObjectsTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2012, 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 6493690
+ * @summary javadoc should have a javax.tools.Tool service provider
+ * @build APITest
+ * @run main GetTask_FileObjectsTest
+ */
+
+import java.io.File;
+import java.util.Arrays;
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+/**
+ * Tests for DocumentationTool.getTask fileObjects parameter.
+ */
+public class GetTask_FileObjectsTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new GetTask_FileObjectsTest().run();
+ }
+
+ /**
+ * Verify that expected output files are written via the file manager,
+ * for a source file read from the file system with StandardJavaFileManager.
+ */
+ @Test
+ public void testStandardFileObject() throws Exception {
+ File testSrc = new File(System.getProperty("test.src"));
+ File srcFile = new File(testSrc, "pkg/C.java");
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(srcFile);
+ DocumentationTask t = tool.getTask(null, fm, null, null, null, files);
+ if (t.call()) {
+ System.err.println("task succeeded");
+ checkFiles(outDir, standardExpectFiles);
+ } else {
+ throw new Exception("task failed");
+ }
+ }
+
+ /**
+ * Verify that expected output files are written via the file manager,
+ * for an in-memory file object.
+ */
+ @Test
+ public void testMemoryFileObject() throws Exception {
+ JavaFileObject srcFile = createSimpleJavaFileObject();
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ DocumentationTask t = tool.getTask(null, fm, null, null, null, files);
+ if (t.call()) {
+ System.err.println("task succeeded");
+ checkFiles(outDir, standardExpectFiles);
+ } else {
+ throw new Exception("task failed");
+ }
+ }
+
+ /**
+ * Verify bad file object is handled correctly.
+ */
+ @Test
+ public void testBadFileObject() throws Exception {
+ File testSrc = new File(System.getProperty("test.src"));
+ File srcFile = new File(testSrc, "pkg/C.class"); // unacceptable file kind
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(srcFile);
+ try {
+ DocumentationTask t = tool.getTask(null, fm, null, null, null, files);
+ error("getTask succeeded, no exception thrown");
+ } catch (IllegalArgumentException e) {
+ System.err.println("exception caught as expected: " + e);
+ }
+ }
+
+ /**
+ * Verify null is handled correctly.
+ */
+ @Test
+ public void testNull() throws Exception {
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<? extends JavaFileObject> files = Arrays.asList((JavaFileObject) null);
+ try {
+ DocumentationTask t = tool.getTask(null, fm, null, null, null, files);
+ error("getTask succeeded, no exception thrown");
+ } catch (NullPointerException e) {
+ System.err.println("exception caught as expected: " + e);
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/GetTask_OptionsTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2012, 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 6493690
+ * @summary javadoc should have a javax.tools.Tool service provider
+ * @build APITest
+ * @run main GetTask_OptionsTest
+ */
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.TreeSet;
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+/**
+ * Tests for DocumentationTool.getTask options parameter.
+ */
+public class GetTask_OptionsTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new GetTask_OptionsTest().run();
+ }
+
+ /**
+ * Verify that expected output files are written for given options.
+ */
+ @Test
+ public void testNoIndex() throws Exception {
+ JavaFileObject srcFile = createSimpleJavaFileObject();
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ Iterable<String> options = Arrays.asList("-noindex");
+ DocumentationTask t = tool.getTask(null, fm, null, null, options, files);
+ if (t.call()) {
+ System.err.println("task succeeded");
+ Set<String> expectFiles = new TreeSet<String>(standardExpectFiles);
+ expectFiles.remove("index-all.html");
+ checkFiles(outDir, expectFiles);
+ } else {
+ error("task failed");
+ }
+ }
+
+ /**
+ * Verify null is handled correctly.
+ */
+ @Test
+ public void testNull() throws Exception {
+ JavaFileObject srcFile = createSimpleJavaFileObject();
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<String> options = Arrays.asList((String) null);
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ try {
+ DocumentationTask t = tool.getTask(null, fm, null, null, options, files);
+ error("getTask succeeded, no exception thrown");
+ } catch (NullPointerException e) {
+ System.err.println("exception caught as expected: " + e);
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/GetTask_WriterTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, 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 6493690
+ * @summary javadoc should have a javax.tools.Tool service provider
+ * @build APITest
+ * @run main GetTask_WriterTest
+ */
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+/**
+ * Tests for DocumentationTool.getTask writer parameter.
+ */
+public class GetTask_WriterTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new GetTask_WriterTest().run();
+ }
+
+ /**
+ * Verify that a writer can be provided.
+ */
+ @Test
+ public void testWriter() throws Exception {
+ JavaFileObject srcFile = createSimpleJavaFileObject();
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ DocumentationTask t = tool.getTask(pw, fm, null, null, null, files);
+ if (t.call()) {
+ System.err.println("task succeeded");
+ checkFiles(outDir, standardExpectFiles);
+ String out = sw.toString();
+ System.err.println(">>" + out + "<<");
+ for (String f: standardExpectFiles) {
+ String f1 = f.replace('/', File.separatorChar);
+ if (f1.endsWith(".html") && !out.contains(f1))
+ throw new Exception("expected string not found: " + f1);
+ }
+ } else {
+ throw new Exception("task failed");
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/IsSupportedOptionTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, 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 6493690
+ * @summary javadoc should have a javax.tools.Tool service provider
+ * @build APITest
+ * @run main IsSupportedOptionTest
+ */
+
+import javax.tools.DocumentationTool;
+import javax.tools.ToolProvider;
+
+/**
+ * Tests for DocumentationTool.usSupportedOption method.
+ */
+public class IsSupportedOptionTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new IsSupportedOptionTest().run();
+ }
+
+ /**
+ * Verify that isSupportedOption method can be invoked.
+ */
+ @Test
+ public void test() throws Exception {
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ check(tool, "-sourcepath", 1);
+ check(tool, "-verbose", 0);
+ check(tool, "-ZZZ", -1);
+
+ try {
+ check(tool, null, -1);
+ error("null was accepted without exception");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ private void check(DocumentationTool tool, String option, int numArgs) {
+ System.err.println("check " + option);
+ int n = tool.isSupportedOption(option);
+ if (n != numArgs)
+ error("unexpected result for option: " + option + ": " + n);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/JavadocTaskImplTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2012, 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 6493690
+ * @summary javadoc should have a javax.tools.Tool service provider
+ * @build APITest
+ * @run main JavadocTaskImplTest
+ */
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.concurrent.Callable;
+
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javadoc.Messager;
+import com.sun.tools.javadoc.api.JavadocTaskImpl;
+
+/**
+ * Misc tests for JavacTaskImpl.
+ */
+public class JavadocTaskImplTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new JavadocTaskImplTest().run();
+ }
+
+ @Test
+ public void testRawCall() throws Exception {
+ JavaFileObject srcFile = createSimpleJavaFileObject();
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+
+ @SuppressWarnings("rawtypes")
+ Callable t = tool.getTask(null, fm, null, null, null, files);
+
+ if (t.call() == Boolean.TRUE) {
+ System.err.println("task succeeded");
+ } else {
+ throw new Exception("task failed");
+ }
+ }
+
+ @Test
+ public void testDirectAccess1() throws Exception {
+ JavaFileObject srcFile = createSimpleJavaFileObject();
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ Context c = new Context();
+ Messager.preRegister(c, "javadoc");
+ StandardJavaFileManager fm = new JavacFileManager(c, true, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ DocumentationTask t = new JavadocTaskImpl(c, null, null, files);
+ if (t.call()) {
+ System.err.println("task succeeded");
+ } else {
+ throw new Exception("task failed");
+ }
+ }
+
+ @Test
+ public void testDirectAccess2() throws Exception {
+ JavaFileObject srcFile = null; // error, provokes NPE
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ Context c = new Context();
+ Messager.preRegister(c, "javadoc");
+ StandardJavaFileManager fm = new JavacFileManager(c, true, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ try {
+ DocumentationTask t = new JavadocTaskImpl(c, null, null, files);;
+ error("getTask succeeded, no exception thrown");
+ } catch (NullPointerException e) {
+ System.err.println("exception caught as expected: " + e);
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/RunTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2012, 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 6493690
+ * @summary javadoc should have a javax.tools.Tool service provider
+ * @build APITest
+ * @run main RunTest
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import javax.tools.DocumentationTool;
+import javax.tools.ToolProvider;
+
+/**
+ * Tests for DocumentationTool.run method.
+ */
+public class RunTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new RunTest().run();
+ }
+
+ /**
+ * Verify that run method can be invoked.
+ */
+ @Test
+ public void testRun() throws Exception {
+ File testSrc = new File(System.getProperty("test.src"));
+ File srcFile = new File(testSrc, "pkg/C.java");
+ File outDir = getOutDir();
+ String[] args = { "-d", outDir.getPath(), srcFile.getPath() };
+
+ ByteArrayOutputStream stdout = new ByteArrayOutputStream();
+ ByteArrayOutputStream stderr = new ByteArrayOutputStream();
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ int rc = tool.run(null, stdout, stderr, args);
+ System.err.println("stdout >>" + stdout.toString() + "<<");
+ System.err.println("stderr >>" + stderr.toString() + "<<");
+
+ if (rc == 0) {
+ System.err.println("call succeeded");
+ checkFiles(outDir, standardExpectFiles);
+ String out = stdout.toString();
+ for (String f: standardExpectFiles) {
+ String f1 = f.replace('/', File.separatorChar);
+ if (f1.endsWith(".html") && !out.contains(f1))
+ error("expected string not found: " + f1);
+ }
+ } else {
+ error("call failed");
+ }
+ }
+
+ /**
+ * Verify that run method can be invoked.
+ */
+ @Test
+ public void testRun2() throws Exception {
+ File outDir = getOutDir();
+ String badfile = "badfile.java";
+ String[] args = { "-d", outDir.getPath(), badfile };
+
+ ByteArrayOutputStream stdout = new ByteArrayOutputStream();
+ ByteArrayOutputStream stderr = new ByteArrayOutputStream();
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ int rc = tool.run(null, stdout, stderr, args);
+ System.err.println("stdout >>" + stdout.toString() + "<<");
+ System.err.println("stderr >>" + stderr.toString() + "<<");
+
+ if (rc == 0) {
+ error("call succeeded unexpectedly");
+ } else {
+ String err = stderr.toString();
+ if (err.contains(badfile))
+ System.err.println("call failed as expected");
+ else
+ error("expected diagnostic not found");
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/TagletPathTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2012, 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 6493690
+ * @summary javadoc should have a javax.tools.Tool service provider
+ * @build APITest
+ * @run main TagletPathTest
+ */
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.List;
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+/**
+ * Tests for locating a doclet via the file manager's DOCLET_PATH.
+ */
+public class TagletPathTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new TagletPathTest().run();
+ }
+
+ /**
+ * Verify that a taglet can be specified, and located via
+ * the file manager's TAGLET_PATH.
+ */
+ @Test
+ public void testTagletPath() throws Exception {
+ File testSrc = new File(System.getProperty("test.src"));
+ File tagletSrcFile = new File(testSrc, "taglets/UnderlineTaglet.java");
+ File tagletDir = getOutDir("classes");
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager cfm = compiler.getStandardFileManager(null, null, null);
+ cfm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(tagletDir));
+ Iterable<? extends JavaFileObject> cfiles = cfm.getJavaFileObjects(tagletSrcFile);
+ if (!compiler.getTask(null, cfm, null, null, null, cfiles).call())
+ throw new Exception("cannot compile taglet");
+
+ JavaFileObject srcFile = createSimpleJavaFileObject("pkg/C", testSrcText);
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir("api");
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ fm.setLocation(DocumentationTool.Location.TAGLET_PATH, Arrays.asList(tagletDir));
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ Iterable<String> options = Arrays.asList("-taglet", "UnderlineTaglet");
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ DocumentationTask t = tool.getTask(pw, fm, null, null, options, files);
+ boolean ok = t.call();
+ String out = sw.toString();
+ System.err.println(">>" + out + "<<");
+ if (ok) {
+ File f = new File(outDir, "pkg/C.html");
+ List<String> doc = Files.readAllLines(f.toPath(), Charset.defaultCharset());
+ for (String line: doc) {
+ if (line.contains("<u>" + TEST_STRING + "</u>")) {
+ System.err.println("taglet executed as expected");
+ return;
+ }
+ }
+ error("expected text not found in output " + f);
+ } else {
+ error("task failed");
+ }
+ }
+
+ static final String TEST_STRING = "xyzzy";
+ static final String testSrcText =
+ "package pkg;\n" +
+ "/** {@underline " + TEST_STRING + "} */\n" +
+ "public class C { }";
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/Task_reuseTest.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012, 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 6493690
+ * @summary javadoc should have a javax.tools.Tool service provider
+ * @build APITest
+ * @run main Task_reuseTest
+ */
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Locale;
+import javax.tools.DocumentationTool;
+import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+/**
+ * Tests for reusing a documentation task.
+ */
+public class Task_reuseTest extends APITest {
+ public static void main(String... args) throws Exception {
+ new Task_reuseTest().run();
+ }
+
+ /**
+ * Verify that call can only be called once.
+ */
+ @Test
+ public void testReuse() throws Exception {
+ DocumentationTask t = getAndRunTask();
+ try {
+ t.call();
+ error("task was reused without exception");
+ } catch (IllegalStateException e) {
+ System.err.println("caught exception " + e);
+ }
+ }
+
+ /**
+ * Verify that cannot update task after call
+ */
+ @Test
+ public void testUpdateSetLocale() throws Exception {
+ DocumentationTask t = getAndRunTask();
+ try {
+ t.setLocale(Locale.getDefault());
+ error("task was reused without exception");
+ } catch (IllegalStateException e) {
+ System.err.println("caught exception " + e);
+ }
+ }
+
+ private DocumentationTask getAndRunTask() throws Exception {
+ JavaFileObject srcFile = createSimpleJavaFileObject();
+ DocumentationTool tool = ToolProvider.getSystemDocumentationTool();
+ StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+ File outDir = getOutDir();
+ fm.setLocation(DocumentationTool.Location.DOCUMENTATION_OUTPUT, Arrays.asList(outDir));
+ Iterable<? extends JavaFileObject> files = Arrays.asList(srcFile);
+ DocumentationTask t = tool.getTask(null, fm, null, null, null, files);
+ if (t.call()) {
+ System.err.println("task succeeded");
+ return t;
+ } else {
+ throw new Exception("task failed");
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/pkg/C.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+package pkg;
+
+public class C { }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/api/basic/taglets/UnderlineTaglet.java Fri Nov 30 17:09:05 2012 -0800
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * -Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * -Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Oracle nor the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
+ * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
+ * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
+ * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
+ * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
+ * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
+ * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
+ * THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that Software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ */
+
+import com.sun.tools.doclets.Taglet;
+import com.sun.javadoc.*;
+import java.util.Map;
+
+/**
+ * A sample Inline Taglet representing {@underline ...}. This tag can
+ * be used in any kind of {@link com.sun.javadoc.Doc}.
+ * The text is underlined. For example,
+ * "@underline UNDERLINE ME" would be shown as: <u>UNDERLINE ME</u>.
+ *
+ * @author Jamie Ho
+ * @since 1.4
+ */
+
+public class UnderlineTaglet implements Taglet {
+
+ private static final String NAME = "underline";
+
+ /**
+ * Return the name of this custom tag.
+ */
+ public String getName() {
+ return NAME;
+ }
+
+ /**
+ * @return true since this tag can be used in a field
+ * doc comment
+ */
+ public boolean inField() {
+ return true;
+ }
+
+ /**
+ * @return true since this tag can be used in a constructor
+ * doc comment
+ */
+ public boolean inConstructor() {
+ return true;
+ }
+
+ /**
+ * @return true since this tag can be used in a method
+ * doc comment
+ */
+ public boolean inMethod() {
+ return true;
+ }
+
+ /**
+ * @return true since this tag can be used in an overview
+ * doc comment
+ */
+ public boolean inOverview() {
+ return true;
+ }
+
+ /**
+ * @return true since this tag can be used in a package
+ * doc comment
+ */
+ public boolean inPackage() {
+ return true;
+ }
+
+ /**
+ * @return true since this
+ */
+ public boolean inType() {
+ return true;
+ }
+
+ /**
+ * Will return true since this is an inline tag.
+ * @return true since this is an inline tag.
+ */
+
+ public boolean isInlineTag() {
+ return true;
+ }
+
+ /**
+ * Register this Taglet.
+ * @param tagletMap the map to register this tag to.
+ */
+ public static void register(Map tagletMap) {
+ UnderlineTaglet tag = new UnderlineTaglet();
+ Taglet t = (Taglet) tagletMap.get(tag.getName());
+ if (t != null) {
+ tagletMap.remove(tag.getName());
+ }
+ tagletMap.put(tag.getName(), tag);
+ }
+
+ /**
+ * Given the <code>Tag</code> representation of this custom
+ * tag, return its string representation.
+ * @param tag he <code>Tag</code> representation of this custom tag.
+ */
+ public String toString(Tag tag) {
+ return "<u>" + tag.text() + "</u>";
+ }
+
+ /**
+ * This method should not be called since arrays of inline tags do not
+ * exist. Method {@link #tostring(Tag)} should be used to convert this
+ * inline tag to a string.
+ * @param tags the array of <code>Tag</code>s representing of this custom tag.
+ */
+ public String toString(Tag[] tags) {
+ return null;
+ }
+}
+