diff --git a/.hgtags b/.hgtags index 1e4981545c3..a470c9afa31 100644 --- a/.hgtags +++ b/.hgtags @@ -218,3 +218,4 @@ b72ae39e1329fefae50d4690db4fde43f3841a95 jdk8-b93 0d804e3b955dce406af6a79ac1cc35c696aff7fb jdk8-b94 49fe9c8049132647ad38837a877dd473e6c9b0e5 jdk8-b95 ea73f01b9053e7165e7ba80f242bafecbc6af712 jdk8-b96 +0a85476a0b9cb876d5666d45097dac68bef3fce1 jdk8-b97 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 03af8b5ef30..64129189d67 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -218,3 +218,4 @@ cb51fb4789ac0b8be4056482077ddfb8f3bd3805 jdk8-b91 50d2bde060f2a9bbbe4da0c8986e20aca61f2e2e jdk8-b94 785d07fe38901ecc1b7e0145e53e1c3da9361fee jdk8-b95 c156084add486f941c12d886a0b1b2854795d557 jdk8-b96 +a1c1e8bf71f354f3aec0214cf13d6668811e021d jdk8-b97 diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index b9c2b38a47e..1f084da68c9 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.67 for OpenJDK jdk8. +# Generated by GNU Autoconf 2.68 for OpenJDK jdk8. # # Report bugs to . # @@ -91,6 +91,7 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. +as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -216,11 +217,18 @@ IFS=$as_save_IFS # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : @@ -1461,7 +1469,7 @@ Try \`$0 --help' for more information" $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac @@ -1897,7 +1905,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF OpenJDK configure jdk8 -generated by GNU Autoconf 2.67 +generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation @@ -1943,7 +1951,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile @@ -1981,7 +1989,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile @@ -2019,7 +2027,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_objc_try_compile @@ -2056,7 +2064,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp @@ -2093,7 +2101,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp @@ -2106,10 +2114,10 @@ fi ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval "test \"\${$3+set}\"" = set; then : + if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -2176,7 +2184,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -2185,7 +2193,7 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_mongrel @@ -2226,7 +2234,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_run @@ -2240,7 +2248,7 @@ ac_fn_cxx_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2258,7 +2266,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_compile @@ -2435,7 +2443,7 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ rm -f conftest.val fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_compute_int @@ -2481,7 +2489,7 @@ fi # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link @@ -2494,7 +2502,7 @@ ac_fn_cxx_check_func () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2549,7 +2557,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_func @@ -2562,7 +2570,7 @@ ac_fn_c_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2580,7 +2588,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile cat >config.log <<_ACEOF @@ -2588,7 +2596,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2846,7 +2854,7 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;} || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi done @@ -3786,7 +3794,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1372770384 +DATE_WHEN_GENERATED=1373384053 ############################################################################### # @@ -3824,7 +3832,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_BASENAME+set}" = set; then : +if ${ac_cv_path_BASENAME+:} false; then : $as_echo_n "(cached) " >&6 else case $BASENAME in @@ -3883,7 +3891,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_BASH+set}" = set; then : +if ${ac_cv_path_BASH+:} false; then : $as_echo_n "(cached) " >&6 else case $BASH in @@ -3942,7 +3950,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CAT+set}" = set; then : +if ${ac_cv_path_CAT+:} false; then : $as_echo_n "(cached) " >&6 else case $CAT in @@ -4001,7 +4009,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CHMOD+set}" = set; then : +if ${ac_cv_path_CHMOD+:} false; then : $as_echo_n "(cached) " >&6 else case $CHMOD in @@ -4060,7 +4068,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CMP+set}" = set; then : +if ${ac_cv_path_CMP+:} false; then : $as_echo_n "(cached) " >&6 else case $CMP in @@ -4119,7 +4127,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_COMM+set}" = set; then : +if ${ac_cv_path_COMM+:} false; then : $as_echo_n "(cached) " >&6 else case $COMM in @@ -4178,7 +4186,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CP+set}" = set; then : +if ${ac_cv_path_CP+:} false; then : $as_echo_n "(cached) " >&6 else case $CP in @@ -4237,7 +4245,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CPIO+set}" = set; then : +if ${ac_cv_path_CPIO+:} false; then : $as_echo_n "(cached) " >&6 else case $CPIO in @@ -4296,7 +4304,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CUT+set}" = set; then : +if ${ac_cv_path_CUT+:} false; then : $as_echo_n "(cached) " >&6 else case $CUT in @@ -4355,7 +4363,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_DATE+set}" = set; then : +if ${ac_cv_path_DATE+:} false; then : $as_echo_n "(cached) " >&6 else case $DATE in @@ -4414,7 +4422,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_DIFF+set}" = set; then : +if ${ac_cv_path_DIFF+:} false; then : $as_echo_n "(cached) " >&6 else case $DIFF in @@ -4473,7 +4481,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_DIRNAME+set}" = set; then : +if ${ac_cv_path_DIRNAME+:} false; then : $as_echo_n "(cached) " >&6 else case $DIRNAME in @@ -4532,7 +4540,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_ECHO+set}" = set; then : +if ${ac_cv_path_ECHO+:} false; then : $as_echo_n "(cached) " >&6 else case $ECHO in @@ -4591,7 +4599,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_EXPR+set}" = set; then : +if ${ac_cv_path_EXPR+:} false; then : $as_echo_n "(cached) " >&6 else case $EXPR in @@ -4650,7 +4658,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_FILE+set}" = set; then : +if ${ac_cv_path_FILE+:} false; then : $as_echo_n "(cached) " >&6 else case $FILE in @@ -4709,7 +4717,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_FIND+set}" = set; then : +if ${ac_cv_path_FIND+:} false; then : $as_echo_n "(cached) " >&6 else case $FIND in @@ -4768,7 +4776,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_HEAD+set}" = set; then : +if ${ac_cv_path_HEAD+:} false; then : $as_echo_n "(cached) " >&6 else case $HEAD in @@ -4827,7 +4835,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_LN+set}" = set; then : +if ${ac_cv_path_LN+:} false; then : $as_echo_n "(cached) " >&6 else case $LN in @@ -4886,7 +4894,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_LS+set}" = set; then : +if ${ac_cv_path_LS+:} false; then : $as_echo_n "(cached) " >&6 else case $LS in @@ -4945,7 +4953,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_MKDIR+set}" = set; then : +if ${ac_cv_path_MKDIR+:} false; then : $as_echo_n "(cached) " >&6 else case $MKDIR in @@ -5004,7 +5012,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_MKTEMP+set}" = set; then : +if ${ac_cv_path_MKTEMP+:} false; then : $as_echo_n "(cached) " >&6 else case $MKTEMP in @@ -5063,7 +5071,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_MV+set}" = set; then : +if ${ac_cv_path_MV+:} false; then : $as_echo_n "(cached) " >&6 else case $MV in @@ -5122,7 +5130,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_PRINTF+set}" = set; then : +if ${ac_cv_path_PRINTF+:} false; then : $as_echo_n "(cached) " >&6 else case $PRINTF in @@ -5181,7 +5189,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_RM+set}" = set; then : +if ${ac_cv_path_RM+:} false; then : $as_echo_n "(cached) " >&6 else case $RM in @@ -5240,7 +5248,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_SH+set}" = set; then : +if ${ac_cv_path_SH+:} false; then : $as_echo_n "(cached) " >&6 else case $SH in @@ -5299,7 +5307,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_SORT+set}" = set; then : +if ${ac_cv_path_SORT+:} false; then : $as_echo_n "(cached) " >&6 else case $SORT in @@ -5358,7 +5366,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TAIL+set}" = set; then : +if ${ac_cv_path_TAIL+:} false; then : $as_echo_n "(cached) " >&6 else case $TAIL in @@ -5417,7 +5425,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TAR+set}" = set; then : +if ${ac_cv_path_TAR+:} false; then : $as_echo_n "(cached) " >&6 else case $TAR in @@ -5476,7 +5484,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TEE+set}" = set; then : +if ${ac_cv_path_TEE+:} false; then : $as_echo_n "(cached) " >&6 else case $TEE in @@ -5535,7 +5543,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TOUCH+set}" = set; then : +if ${ac_cv_path_TOUCH+:} false; then : $as_echo_n "(cached) " >&6 else case $TOUCH in @@ -5594,7 +5602,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TR+set}" = set; then : +if ${ac_cv_path_TR+:} false; then : $as_echo_n "(cached) " >&6 else case $TR in @@ -5653,7 +5661,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_UNAME+set}" = set; then : +if ${ac_cv_path_UNAME+:} false; then : $as_echo_n "(cached) " >&6 else case $UNAME in @@ -5712,7 +5720,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_UNIQ+set}" = set; then : +if ${ac_cv_path_UNIQ+:} false; then : $as_echo_n "(cached) " >&6 else case $UNIQ in @@ -5771,7 +5779,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_WC+set}" = set; then : +if ${ac_cv_path_WC+:} false; then : $as_echo_n "(cached) " >&6 else case $WC in @@ -5830,7 +5838,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_WHICH+set}" = set; then : +if ${ac_cv_path_WHICH+:} false; then : $as_echo_n "(cached) " >&6 else case $WHICH in @@ -5889,7 +5897,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_XARGS+set}" = set; then : +if ${ac_cv_path_XARGS+:} false; then : $as_echo_n "(cached) " >&6 else case $XARGS in @@ -5949,7 +5957,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AWK+set}" = set; then : +if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then @@ -5999,7 +6007,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if test "${ac_cv_path_GREP+set}" = set; then : +if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then @@ -6074,7 +6082,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then : +if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 @@ -6153,7 +6161,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } -if test "${ac_cv_path_FGREP+set}" = set; then : +if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 @@ -6232,7 +6240,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } -if test "${ac_cv_path_SED+set}" = set; then : +if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ @@ -6318,7 +6326,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_NAWK+set}" = set; then : +if ${ac_cv_path_NAWK+:} false; then : $as_echo_n "(cached) " >&6 else case $NAWK in @@ -6382,7 +6390,7 @@ THEPWDCMD=pwd set dummy cygpath; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CYGPATH+set}" = set; then : +if ${ac_cv_path_CYGPATH+:} false; then : $as_echo_n "(cached) " >&6 else case $CYGPATH in @@ -6422,7 +6430,7 @@ fi set dummy readlink; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_READLINK+set}" = set; then : +if ${ac_cv_path_READLINK+:} false; then : $as_echo_n "(cached) " >&6 else case $READLINK in @@ -6462,7 +6470,7 @@ fi set dummy df; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_DF+set}" = set; then : +if ${ac_cv_path_DF+:} false; then : $as_echo_n "(cached) " >&6 else case $DF in @@ -6502,7 +6510,7 @@ fi set dummy SetFile; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_SETFILE+set}" = set; then : +if ${ac_cv_path_SETFILE+:} false; then : $as_echo_n "(cached) " >&6 else case $SETFILE in @@ -6548,7 +6556,7 @@ $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } -if test "${ac_cv_build+set}" = set; then : +if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias @@ -6564,7 +6572,7 @@ fi $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' @@ -6582,7 +6590,7 @@ case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } -if test "${ac_cv_host+set}" = set; then : +if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then @@ -6597,7 +6605,7 @@ fi $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' @@ -6615,7 +6623,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } -if test "${ac_cv_target+set}" = set; then : +if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then @@ -6630,7 +6638,7 @@ fi $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; -*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5 ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' @@ -8156,7 +8164,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_PKGHANDLER+set}" = set; then : +if ${ac_cv_prog_PKGHANDLER+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PKGHANDLER"; then @@ -8521,7 +8529,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CHECK_GMAKE+set}" = set; then : +if ${ac_cv_path_CHECK_GMAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $CHECK_GMAKE in @@ -8875,7 +8883,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CHECK_MAKE+set}" = set; then : +if ${ac_cv_path_CHECK_MAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $CHECK_MAKE in @@ -9234,7 +9242,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CHECK_TOOLSDIR_GMAKE+set}" = set; then : +if ${ac_cv_path_CHECK_TOOLSDIR_GMAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_GMAKE in @@ -9587,7 +9595,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CHECK_TOOLSDIR_MAKE+set}" = set; then : +if ${ac_cv_path_CHECK_TOOLSDIR_MAKE+:} false; then : $as_echo_n "(cached) " >&6 else case $CHECK_TOOLSDIR_MAKE in @@ -9983,7 +9991,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_UNZIP+set}" = set; then : +if ${ac_cv_path_UNZIP+:} false; then : $as_echo_n "(cached) " >&6 else case $UNZIP in @@ -10042,7 +10050,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_ZIP+set}" = set; then : +if ${ac_cv_path_ZIP+:} false; then : $as_echo_n "(cached) " >&6 else case $ZIP in @@ -10101,7 +10109,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} set dummy ldd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_LDD+set}" = set; then : +if ${ac_cv_path_LDD+:} false; then : $as_echo_n "(cached) " >&6 else case $LDD in @@ -10147,7 +10155,7 @@ fi set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_OTOOL+set}" = set; then : +if ${ac_cv_path_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else case $OTOOL in @@ -10192,7 +10200,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_READELF+set}" = set; then : +if ${ac_cv_path_READELF+:} false; then : $as_echo_n "(cached) " >&6 else case $READELF in @@ -10235,7 +10243,7 @@ done set dummy hg; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_HG+set}" = set; then : +if ${ac_cv_path_HG+:} false; then : $as_echo_n "(cached) " >&6 else case $HG in @@ -10275,7 +10283,7 @@ fi set dummy stat; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_STAT+set}" = set; then : +if ${ac_cv_path_STAT+:} false; then : $as_echo_n "(cached) " >&6 else case $STAT in @@ -10315,7 +10323,7 @@ fi set dummy time; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TIME+set}" = set; then : +if ${ac_cv_path_TIME+:} false; then : $as_echo_n "(cached) " >&6 else case $TIME in @@ -10368,7 +10376,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_COMM+set}" = set; then : +if ${ac_cv_path_COMM+:} false; then : $as_echo_n "(cached) " >&6 else case $COMM in @@ -10430,7 +10438,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_XATTR+set}" = set; then : +if ${ac_cv_path_XATTR+:} false; then : $as_echo_n "(cached) " >&6 else case $XATTR in @@ -10486,7 +10494,7 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;} set dummy codesign; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CODESIGN+set}" = set; then : +if ${ac_cv_path_CODESIGN+:} false; then : $as_echo_n "(cached) " >&6 else case $CODESIGN in @@ -10550,7 +10558,7 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : +if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in @@ -10593,7 +10601,7 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in @@ -10766,7 +10774,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_BDEPS_UNZIP+set}" = set; then : +if ${ac_cv_prog_BDEPS_UNZIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_UNZIP"; then @@ -10812,7 +10820,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_BDEPS_FTP+set}" = set; then : +if ${ac_cv_prog_BDEPS_FTP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$BDEPS_FTP"; then @@ -12108,7 +12116,7 @@ $as_echo "$BOOT_JDK_VERSION" >&6; } set dummy javac; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_JAVAC_CHECK+set}" = set; then : +if ${ac_cv_path_JAVAC_CHECK+:} false; then : $as_echo_n "(cached) " >&6 else case $JAVAC_CHECK in @@ -12148,7 +12156,7 @@ fi set dummy java; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_JAVA_CHECK+set}" = set; then : +if ${ac_cv_path_JAVA_CHECK+:} false; then : $as_echo_n "(cached) " >&6 else case $JAVA_CHECK in @@ -16477,7 +16485,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_JTREGEXE+set}" = set; then : +if ${ac_cv_path_JTREGEXE+:} false; then : $as_echo_n "(cached) " >&6 else case $JTREGEXE in @@ -16545,7 +16553,7 @@ if test "x$OPENJDK_TARGET_OS" = "xwindows"; then set dummy link; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CYGWIN_LINK+set}" = set; then : +if ${ac_cv_path_CYGWIN_LINK+:} false; then : $as_echo_n "(cached) " >&6 else case $CYGWIN_LINK in @@ -17319,6 +17327,8 @@ $as_echo "ok" >&6; } # Remove any trailing \ from INCLUDE and LIB to avoid trouble in spec.gmk. VS_INCLUDE=`$ECHO "$INCLUDE" | $SED 's/\\\\$//'` VS_LIB=`$ECHO "$LIB" | $SED 's/\\\\$//'` + # Remove any paths containing # (typically F#) as that messes up make + PATH=`$ECHO "$PATH" | $SED 's/[^:#]*#[^:]*://g'` VS_PATH="$PATH" @@ -17986,7 +17996,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_BUILD_CC+set}" = set; then : +if ${ac_cv_path_BUILD_CC+:} false; then : $as_echo_n "(cached) " >&6 else case $BUILD_CC in @@ -18297,7 +18307,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_BUILD_CXX+set}" = set; then : +if ${ac_cv_path_BUILD_CXX+:} false; then : $as_echo_n "(cached) " >&6 else case $BUILD_CXX in @@ -18606,7 +18616,7 @@ $as_echo "$as_me: Rewriting BUILD_CXX to \"$new_complete\"" >&6;} set dummy ld; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_BUILD_LD+set}" = set; then : +if ${ac_cv_path_BUILD_LD+:} false; then : $as_echo_n "(cached) " >&6 else case $BUILD_LD in @@ -19113,7 +19123,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TOOLS_DIR_CC+set}" = set; then : +if ${ac_cv_path_TOOLS_DIR_CC+:} false; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CC in @@ -19165,7 +19175,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_POTENTIAL_CC+set}" = set; then : +if ${ac_cv_path_POTENTIAL_CC+:} false; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CC in @@ -19578,7 +19588,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_PROPER_COMPILER_CC+set}" = set; then : +if ${ac_cv_prog_PROPER_COMPILER_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CC"; then @@ -19622,7 +19632,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+set}" = set; then : +if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CC"; then @@ -20072,7 +20082,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -20116,7 +20126,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : +if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -20169,7 +20179,7 @@ fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -20284,7 +20294,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -20327,7 +20337,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -20386,7 +20396,7 @@ $as_echo "$ac_try_echo"; } >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi fi fi @@ -20397,7 +20407,7 @@ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } -if test "${ac_cv_objext+set}" = set; then : +if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20438,7 +20448,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi @@ -20448,7 +20458,7 @@ OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then : +if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20485,7 +20495,7 @@ ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then : +if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag @@ -20563,7 +20573,7 @@ else fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then : +if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no @@ -20686,7 +20696,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_TOOLS_DIR_CXX+set}" = set; then : +if ${ac_cv_path_TOOLS_DIR_CXX+:} false; then : $as_echo_n "(cached) " >&6 else case $TOOLS_DIR_CXX in @@ -20738,7 +20748,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_POTENTIAL_CXX+set}" = set; then : +if ${ac_cv_path_POTENTIAL_CXX+:} false; then : $as_echo_n "(cached) " >&6 else case $POTENTIAL_CXX in @@ -21151,7 +21161,7 @@ $as_echo "yes, trying to find proper $COMPILER_NAME compiler" >&6; } set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_PROPER_COMPILER_CXX+set}" = set; then : +if ${ac_cv_prog_PROPER_COMPILER_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PROPER_COMPILER_CXX"; then @@ -21195,7 +21205,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+set}" = set; then : +if ${ac_cv_prog_ac_ct_PROPER_COMPILER_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_PROPER_COMPILER_CXX"; then @@ -21649,7 +21659,7 @@ if test -z "$CXX"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CXX+set}" = set; then : +if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then @@ -21693,7 +21703,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : +if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then @@ -21771,7 +21781,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : +if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -21808,7 +21818,7 @@ ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } -if test "${ac_cv_prog_cxx_g+set}" = set; then : +if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag @@ -21906,7 +21916,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OBJC+set}" = set; then : +if ${ac_cv_prog_OBJC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJC"; then @@ -21950,7 +21960,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OBJC+set}" = set; then : +if ${ac_cv_prog_ac_ct_OBJC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJC"; then @@ -22026,7 +22036,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Objective C compiler" >&5 $as_echo_n "checking whether we are using the GNU Objective C compiler... " >&6; } -if test "${ac_cv_objc_compiler_gnu+set}" = set; then : +if ${ac_cv_objc_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -22063,7 +22073,7 @@ ac_test_OBJCFLAGS=${OBJCFLAGS+set} ac_save_OBJCFLAGS=$OBJCFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $OBJC accepts -g" >&5 $as_echo_n "checking whether $OBJC accepts -g... " >&6; } -if test "${ac_cv_prog_objc_g+set}" = set; then : +if ${ac_cv_prog_objc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_objc_werror_flag=$ac_objc_werror_flag @@ -22439,7 +22449,7 @@ if test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AR+set}" = set; then : +if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then @@ -22479,7 +22489,7 @@ if test -z "$ac_cv_prog_AR"; then set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : +if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then @@ -22821,7 +22831,7 @@ if test "x$OPENJDK_TARGET_OS" = xwindows; then : set dummy link; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_WINLD+set}" = set; then : +if ${ac_cv_prog_WINLD+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$WINLD"; then @@ -23160,7 +23170,7 @@ $as_echo "yes" >&6; } set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_MT+set}" = set; then : +if ${ac_cv_prog_MT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MT"; then @@ -23481,7 +23491,7 @@ $as_echo "$as_me: Rewriting MT to \"$new_complete\"" >&6;} set dummy rc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_RC+set}" = set; then : +if ${ac_cv_prog_RC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RC"; then @@ -23873,7 +23883,7 @@ fi set dummy lib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_WINAR+set}" = set; then : +if ${ac_cv_prog_WINAR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$WINAR"; then @@ -24179,7 +24189,7 @@ $as_echo "$as_me: Rewriting WINAR to \"$new_complete\"" >&6;} set dummy dumpbin; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_DUMPBIN+set}" = set; then : +if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then @@ -24498,7 +24508,7 @@ if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then : + if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded @@ -24614,7 +24624,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=cpp @@ -24898,7 +24908,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then - if test "${ac_cv_prog_CXXCPP+set}" = set; then : + if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded @@ -25014,7 +25024,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=cpp @@ -25316,7 +25326,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then set dummy as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_AS+set}" = set; then : +if ${ac_cv_path_AS+:} false; then : $as_echo_n "(cached) " >&6 else case $AS in @@ -25628,7 +25638,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then set dummy nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_NM+set}" = set; then : +if ${ac_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else case $NM in @@ -25934,7 +25944,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy gnm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_GNM+set}" = set; then : +if ${ac_cv_path_GNM+:} false; then : $as_echo_n "(cached) " >&6 else case $GNM in @@ -26240,7 +26250,7 @@ $as_echo "$as_me: Rewriting GNM to \"$new_complete\"" >&6;} set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_STRIP+set}" = set; then : +if ${ac_cv_path_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else case $STRIP in @@ -26546,7 +26556,7 @@ $as_echo "$as_me: Rewriting STRIP to \"$new_complete\"" >&6;} set dummy mcs; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_MCS+set}" = set; then : +if ${ac_cv_path_MCS+:} false; then : $as_echo_n "(cached) " >&6 else case $MCS in @@ -26854,7 +26864,7 @@ elif test "x$OPENJDK_TARGET_OS" != xwindows; then set dummy ${ac_tool_prefix}nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_NM+set}" = set; then : +if ${ac_cv_prog_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then @@ -26894,7 +26904,7 @@ if test -z "$ac_cv_prog_NM"; then set dummy nm; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_NM+set}" = set; then : +if ${ac_cv_prog_ac_ct_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NM"; then @@ -27214,7 +27224,7 @@ $as_echo "$as_me: Rewriting NM to \"$new_complete\"" >&6;} set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_STRIP+set}" = set; then : +if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then @@ -27254,7 +27264,7 @@ if test -z "$ac_cv_prog_STRIP"; then set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then @@ -27579,7 +27589,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OBJCOPY+set}" = set; then : +if ${ac_cv_prog_OBJCOPY+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJCOPY"; then @@ -27623,7 +27633,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then : +if ${ac_cv_prog_ac_ct_OBJCOPY+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJCOPY"; then @@ -27950,7 +27960,7 @@ if test -n "$ac_tool_prefix"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_OBJDUMP+set}" = set; then : +if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then @@ -27994,7 +28004,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then @@ -28318,7 +28328,7 @@ if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_LIPO+set}" = set; then : +if ${ac_cv_path_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else case $LIPO in @@ -28635,7 +28645,7 @@ PATH="$OLD_PATH" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then : +if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -28812,7 +28822,7 @@ fi for ac_header in stdio.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default" -if test "x$ac_cv_header_stdio_h" = x""yes; then : +if test "x$ac_cv_header_stdio_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDIO_H 1 _ACEOF @@ -28841,7 +28851,7 @@ done # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int *" >&5 $as_echo_n "checking size of int *... " >&6; } -if test "${ac_cv_sizeof_int_p+set}" = set; then : +if ${ac_cv_sizeof_int_p+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (int *))" "ac_cv_sizeof_int_p" "$ac_includes_default"; then : @@ -28851,7 +28861,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int *) -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int_p=0 fi @@ -28898,7 +28908,7 @@ $as_echo "$OPENJDK_TARGET_CPU_BITS bits" >&6; } # { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if test "${ac_cv_c_bigendian+set}" = set; then : +if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown @@ -30074,8 +30084,8 @@ if test "x$with_x" = xno; then have_x=disabled else case $x_includes,$x_libraries in #( - *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5 ;; #( - *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then : + *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( + *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. @@ -30352,7 +30362,7 @@ if ac_fn_cxx_try_link "$LINENO"; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } -if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then : +if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30386,14 +30396,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_dnet_ntoa" = x""yes; then : +if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } -if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then : +if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30427,7 +30437,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = x""yes; then : +if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi @@ -30446,14 +30456,14 @@ rm -f core conftest.err conftest.$ac_objext \ # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. ac_fn_cxx_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" -if test "x$ac_cv_func_gethostbyname" = x""yes; then : +if test "x$ac_cv_func_gethostbyname" = xyes; then : fi if test $ac_cv_func_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } -if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then : +if ${ac_cv_lib_nsl_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30487,14 +30497,14 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } -if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then : +if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 $as_echo_n "checking for gethostbyname in -lbsd... " >&6; } -if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then : +if ${ac_cv_lib_bsd_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30528,7 +30538,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 $as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } -if test "x$ac_cv_lib_bsd_gethostbyname" = x""yes; then : +if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi @@ -30543,14 +30553,14 @@ fi # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. ac_fn_cxx_check_func "$LINENO" "connect" "ac_cv_func_connect" -if test "x$ac_cv_func_connect" = x""yes; then : +if test "x$ac_cv_func_connect" = xyes; then : fi if test $ac_cv_func_connect = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } -if test "${ac_cv_lib_socket_connect+set}" = set; then : +if ${ac_cv_lib_socket_connect+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30584,7 +30594,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 $as_echo "$ac_cv_lib_socket_connect" >&6; } -if test "x$ac_cv_lib_socket_connect" = x""yes; then : +if test "x$ac_cv_lib_socket_connect" = xyes; then : X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi @@ -30592,14 +30602,14 @@ fi # Guillermo Gomez says -lposix is necessary on A/UX. ac_fn_cxx_check_func "$LINENO" "remove" "ac_cv_func_remove" -if test "x$ac_cv_func_remove" = x""yes; then : +if test "x$ac_cv_func_remove" = xyes; then : fi if test $ac_cv_func_remove = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 $as_echo_n "checking for remove in -lposix... " >&6; } -if test "${ac_cv_lib_posix_remove+set}" = set; then : +if ${ac_cv_lib_posix_remove+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30633,7 +30643,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 $as_echo "$ac_cv_lib_posix_remove" >&6; } -if test "x$ac_cv_lib_posix_remove" = x""yes; then : +if test "x$ac_cv_lib_posix_remove" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi @@ -30641,14 +30651,14 @@ fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. ac_fn_cxx_check_func "$LINENO" "shmat" "ac_cv_func_shmat" -if test "x$ac_cv_func_shmat" = x""yes; then : +if test "x$ac_cv_func_shmat" = xyes; then : fi if test $ac_cv_func_shmat = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 $as_echo_n "checking for shmat in -lipc... " >&6; } -if test "${ac_cv_lib_ipc_shmat+set}" = set; then : +if ${ac_cv_lib_ipc_shmat+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30682,7 +30692,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 $as_echo "$ac_cv_lib_ipc_shmat" >&6; } -if test "x$ac_cv_lib_ipc_shmat" = x""yes; then : +if test "x$ac_cv_lib_ipc_shmat" = xyes; then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi @@ -30700,7 +30710,7 @@ fi # John Interrante, Karl Berry { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 $as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } -if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then : +if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -30734,7 +30744,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 $as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } -if test "x$ac_cv_lib_ICE_IceConnectionNumber" = x""yes; then : +if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi @@ -31752,7 +31762,7 @@ $as_echo "$FREETYPE2_FOUND" >&6; } LDFLAGS="$FREETYPE2_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FT_Init_FreeType in -lfreetype" >&5 $as_echo_n "checking for FT_Init_FreeType in -lfreetype... " >&6; } -if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then : +if ${ac_cv_lib_freetype_FT_Init_FreeType+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -31786,7 +31796,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5 $as_echo "$ac_cv_lib_freetype_FT_Init_FreeType" >&6; } -if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = x""yes; then : +if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = xyes; then : FREETYPE2_FOUND=true else as_fn_error $? "Could not find freetype2! $HELP_MSG " "$LINENO" 5 @@ -32074,7 +32084,7 @@ fi for ac_header in alsa/asoundlib.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "alsa/asoundlib.h" "ac_cv_header_alsa_asoundlib_h" "$ac_includes_default" -if test "x$ac_cv_header_alsa_asoundlib_h" = x""yes; then : +if test "x$ac_cv_header_alsa_asoundlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ALSA_ASOUNDLIB_H 1 _ACEOF @@ -32133,7 +32143,7 @@ fi USE_EXTERNAL_LIBJPEG=true { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ljpeg" >&5 $as_echo_n "checking for main in -ljpeg... " >&6; } -if test "${ac_cv_lib_jpeg_main+set}" = set; then : +if ${ac_cv_lib_jpeg_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -32161,7 +32171,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_main" >&5 $as_echo "$ac_cv_lib_jpeg_main" >&6; } -if test "x$ac_cv_lib_jpeg_main" = x""yes; then : +if test "x$ac_cv_lib_jpeg_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBJPEG 1 _ACEOF @@ -32210,7 +32220,7 @@ if test "x${with_giflib}" = "xbundled"; then USE_EXTERNAL_LIBGIF=false elif test "x${with_giflib}" = "xsystem"; then ac_fn_cxx_check_header_mongrel "$LINENO" "gif_lib.h" "ac_cv_header_gif_lib_h" "$ac_includes_default" -if test "x$ac_cv_header_gif_lib_h" = x""yes; then : +if test "x$ac_cv_header_gif_lib_h" = xyes; then : else as_fn_error $? "--with-giflib=system specified, but gif_lib.h not found!" "$LINENO" 5 @@ -32219,7 +32229,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DGifGetCode in -lgif" >&5 $as_echo_n "checking for DGifGetCode in -lgif... " >&6; } -if test "${ac_cv_lib_gif_DGifGetCode+set}" = set; then : +if ${ac_cv_lib_gif_DGifGetCode+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -32253,7 +32263,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gif_DGifGetCode" >&5 $as_echo "$ac_cv_lib_gif_DGifGetCode" >&6; } -if test "x$ac_cv_lib_gif_DGifGetCode" = x""yes; then : +if test "x$ac_cv_lib_gif_DGifGetCode" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBGIF 1 _ACEOF @@ -32285,7 +32295,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compress in -lz" >&5 $as_echo_n "checking for compress in -lz... " >&6; } -if test "${ac_cv_lib_z_compress+set}" = set; then : +if ${ac_cv_lib_z_compress+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -32319,7 +32329,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_compress" >&5 $as_echo "$ac_cv_lib_z_compress" >&6; } -if test "x$ac_cv_lib_z_compress" = x""yes; then : +if test "x$ac_cv_lib_z_compress" = xyes; then : ZLIB_FOUND=yes else ZLIB_FOUND=no @@ -32412,7 +32422,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 $as_echo_n "checking for cos in -lm... " >&6; } -if test "${ac_cv_lib_m_cos+set}" = set; then : +if ${ac_cv_lib_m_cos+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -32446,7 +32456,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 $as_echo "$ac_cv_lib_m_cos" >&6; } -if test "x$ac_cv_lib_m_cos" = x""yes; then : +if test "x$ac_cv_lib_m_cos" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF @@ -32470,7 +32480,7 @@ save_LIBS="$LIBS" LIBS="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then : +if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -32504,7 +32514,7 @@ LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF @@ -32734,7 +32744,7 @@ and LIBFFI_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } else LIBFFI_CFLAGS=$pkg_cv_LIBFFI_CFLAGS LIBFFI_LIBS=$pkg_cv_LIBFFI_LIBS @@ -32750,7 +32760,7 @@ if test "x$JVM_VARIANT_ZEROSHARK" = xtrue; then set dummy llvm-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_LLVM_CONFIG+set}" = set; then : +if ${ac_cv_prog_LLVM_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LLVM_CONFIG"; then @@ -33366,7 +33376,7 @@ fi set dummy ccache; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_CCACHE+set}" = set; then : +if ${ac_cv_path_CCACHE+:} false; then : $as_echo_n "(cached) " >&6 else case $CCACHE in @@ -33628,10 +33638,21 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && + if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} @@ -33663,7 +33684,7 @@ LTLIBOBJS=$ac_ltlibobjs -: ${CONFIG_STATUS=./config.status} +: "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" @@ -33764,6 +33785,7 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. +as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -34071,7 +34093,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by OpenJDK $as_me jdk8, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -34134,7 +34156,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ OpenJDK config.status jdk8 -configured by $0, generated by GNU Autoconf 2.67, +configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. @@ -34263,7 +34285,7 @@ do "$OUTPUT_ROOT/spec.sh") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/spec.sh:$AUTOCONF_DIR/spec.sh.in" ;; "$OUTPUT_ROOT/Makefile") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/Makefile:$AUTOCONF_DIR/Makefile.in" ;; - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done @@ -34285,9 +34307,10 @@ fi # after its creation but before its name has been assigned to `$tmp'. $debug || { - tmp= + tmp= ac_tmp= trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } @@ -34295,12 +34318,13 @@ $debug || { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" + test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -34322,7 +34346,7 @@ else ac_cs_awk_cr=$ac_cr fi -echo 'BEGIN {' >"$tmp/subs1.awk" && +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF @@ -34350,7 +34374,7 @@ done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h @@ -34398,7 +34422,7 @@ t delim rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK -cat >>"\$tmp/subs1.awk" <<_ACAWK && +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" @@ -34430,7 +34454,7 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat -fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF @@ -34464,7 +34488,7 @@ fi # test -n "$CONFIG_FILES" # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then -cat >"$tmp/defines.awk" <<\_ACAWK || +cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF @@ -34476,8 +34500,8 @@ _ACEOF # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do - ac_t=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_t"; then + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 @@ -34578,7 +34602,7 @@ do esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -34597,7 +34621,7 @@ do for ac_f do case $ac_f in - -) ac_f="$tmp/stdin";; + -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. @@ -34606,7 +34630,7 @@ do [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" @@ -34632,8 +34656,8 @@ $as_echo "$as_me: creating $ac_file" >&6;} esac case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -34758,21 +34782,22 @@ s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} - rm -f "$tmp/stdin" + rm -f "$ac_tmp/stdin" case $ac_file in - -) cat "$tmp/out" && rm -f "$tmp/out";; - *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; @@ -34783,20 +34808,20 @@ which seems to be undefined. Please make sure it is defined" >&2;} if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" - } >"$tmp/config.h" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" - mv "$tmp/config.h" "$ac_file" \ + mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; diff --git a/common/autoconf/toolchain_windows.m4 b/common/autoconf/toolchain_windows.m4 index 966c0133995..e5d4fff38f9 100644 --- a/common/autoconf/toolchain_windows.m4 +++ b/common/autoconf/toolchain_windows.m4 @@ -208,6 +208,8 @@ AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV], # Remove any trailing \ from INCLUDE and LIB to avoid trouble in spec.gmk. VS_INCLUDE=`$ECHO "$INCLUDE" | $SED 's/\\\\$//'` VS_LIB=`$ECHO "$LIB" | $SED 's/\\\\$//'` + # Remove any paths containing # (typically F#) as that messes up make + PATH=`$ECHO "$PATH" | $SED 's/[[^:#]]*#[^:]*://g'` VS_PATH="$PATH" AC_SUBST(VS_INCLUDE) AC_SUBST(VS_LIB) diff --git a/corba/.hgtags b/corba/.hgtags index 77bfead7060..28f0b92d88b 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -218,3 +218,4 @@ c8286839d0df04aba819ec4bef12b86babccf30e jdk8-b90 22f5d7f261d9d61a953d2d9a53f2e9ce0ca361d1 jdk8-b94 2cf36f43df36137980d9828cec27003ec10daeee jdk8-b95 3357c2776431d51a8de326a85e0f41420e40774f jdk8-b96 +469995a8e97424f450c880606d689bf345277b19 jdk8-b97 diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 0363e7ebd3e..89d305f1d94 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -355,3 +355,5 @@ b786c04b7be15194febe88dc1f0c9443e737a84b hs25-b35 2cc5a9d1ba66dfdff578918b393c727bd9450210 hs25-b38 e6a4b8c71fa6f225bd989a34de2d0d0a656a8be8 jdk8-b96 2b9380b0bf0b649f40704735773e8956c2d88ba0 hs25-b39 +d197d377ab2e016d024e8c86cb06a57bd7eae590 jdk8-b97 +c9dd82da51ed34a28f7c6b3245163ee962e94572 hs25-b40 diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java index 5071235fa3e..9e8d016dcc2 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java @@ -31,13 +31,19 @@ import java.io.*; import java.util.*; public class CLHSDB { + + public CLHSDB(JVMDebugger d) { + jvmDebugger = d; + } + public static void main(String[] args) { new CLHSDB(args).run(); } - private void run() { - // At this point, if pidText != null we are supposed to attach to it. - // Else, if execPath != null, it is the path of a jdk/bin/java + public void run() { + // If jvmDebugger is already set, we have been given a JVMDebugger. + // Otherwise, if pidText != null we are supposed to attach to it. + // Finally, if execPath != null, it is the path of a jdk/bin/java // and coreFilename is the pathname of a core file we are // supposed to attach to. @@ -49,7 +55,9 @@ public class CLHSDB { } }); - if (pidText != null) { + if (jvmDebugger != null) { + attachDebugger(jvmDebugger); + } else if (pidText != null) { attachDebugger(pidText); } else if (execPath != null) { attachDebugger(execPath, coreFilename); @@ -96,6 +104,7 @@ public class CLHSDB { // Internals only below this point // private HotSpotAgent agent; + private JVMDebugger jvmDebugger; private boolean attached; // These had to be made data members because they are referenced in inner classes. private String pidText; @@ -120,7 +129,7 @@ public class CLHSDB { case (1): if (args[0].equals("help") || args[0].equals("-help")) { doUsage(); - System.exit(0); + return; } // If all numbers, it is a PID to attach to // Else, it is a pathname to a .../bin/java for a core file. @@ -142,10 +151,15 @@ public class CLHSDB { default: System.out.println("HSDB Error: Too many options specified"); doUsage(); - System.exit(1); + return; } } + private void attachDebugger(JVMDebugger d) { + agent.attach(d); + attached = true; + } + /** NOTE we are in a different thread here than either the main thread or the Swing/AWT event handler thread, so we must be very careful when creating or removing widgets */ diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java index 2233844267c..1840caf9313 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java @@ -101,6 +101,9 @@ import sun.jvm.hotspot.utilities.soql.JSJavaFactoryImpl; import sun.jvm.hotspot.utilities.soql.JSJavaScriptEngine; public class CommandProcessor { + + volatile boolean quit; + public abstract static class DebuggerInterface { public abstract HotSpotAgent getAgent(); public abstract boolean isAttached(); @@ -1135,7 +1138,7 @@ public class CommandProcessor { usage(); } else { debugger.detach(); - System.exit(0); + quit = true; } } }, @@ -1714,7 +1717,7 @@ public class CommandProcessor { } protected void quit() { debugger.detach(); - System.exit(0); + quit = true; } protected BufferedReader getInputReader() { return in; @@ -1781,7 +1784,7 @@ public class CommandProcessor { public void run(boolean prompt) { // Process interactive commands. - while (true) { + while (!quit) { if (prompt) printPrompt(); String ln = null; try { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HSDB.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HSDB.java index 5143408c687..d50cbaa5140 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HSDB.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HSDB.java @@ -59,8 +59,11 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { // Internals only below this point // private HotSpotAgent agent; + private JVMDebugger jvmDebugger; private JDesktopPane desktop; private boolean attached; + private boolean argError; + private JFrame frame; /** List */ private java.util.List attachMenuItems; /** List */ @@ -85,6 +88,11 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { System.out.println(" path-to-corefile: Debug this corefile. The default is 'core'"); System.out.println(" If no arguments are specified, you can select what to do from the GUI.\n"); HotSpotAgent.showUsage(); + argError = true; + } + + public HSDB(JVMDebugger d) { + jvmDebugger = d; } private HSDB(String[] args) { @@ -95,7 +103,6 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { case (1): if (args[0].equals("help") || args[0].equals("-help")) { doUsage(); - System.exit(0); } // If all numbers, it is a PID to attach to // Else, it is a pathname to a .../bin/java for a core file. @@ -117,24 +124,29 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { default: System.out.println("HSDB Error: Too many options specified"); doUsage(); - System.exit(1); } } - private void run() { - // At this point, if pidText != null we are supposed to attach to it. - // Else, if execPath != null, it is the path of a jdk/bin/java - // and coreFilename is the pathname of a core file we are - // supposed to attach to. + // close this tool without calling System.exit + protected void closeUI() { + workerThread.shutdown(); + frame.dispose(); + } + + public void run() { + // Don't start the UI if there were bad arguments. + if (argError) { + return; + } agent = new HotSpotAgent(); workerThread = new WorkerThread(); attachMenuItems = new java.util.ArrayList(); detachMenuItems = new java.util.ArrayList(); - JFrame frame = new JFrame("HSDB - HotSpot Debugger"); + frame = new JFrame("HSDB - HotSpot Debugger"); frame.setSize(800, 600); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); JMenuBar menuBar = new JMenuBar(); @@ -197,7 +209,7 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { item = createMenuItem("Exit", new ActionListener() { public void actionPerformed(ActionEvent e) { - System.exit(0); + closeUI(); } }); item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK)); @@ -406,7 +418,15 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { } }); - if (pidText != null) { + // If jvmDebugger is already set, we have been given a JVMDebugger. + // Otherwise, if pidText != null we are supposed to attach to it. + // Finally, if execPath != null, it is the path of a jdk/bin/java + // and coreFilename is the pathname of a core file we are + // supposed to attach to. + + if (jvmDebugger != null) { + attach(jvmDebugger); + } else if (pidText != null) { attach(pidText); } else if (execPath != null) { attach(execPath, coreFilename); @@ -1113,6 +1133,12 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { }); } + // Attach to existing JVMDebugger, which should be already attached to a core/process. + private void attach(JVMDebugger d) { + attached = true; + showThreadsDialog(); + } + /** NOTE we are in a different thread here than either the main thread or the Swing/AWT event handler thread, so we must be very careful when creating or removing widgets */ diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java index bdf9bd369e6..c963350591d 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java @@ -25,6 +25,8 @@ package sun.jvm.hotspot; import java.rmi.RemoteException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import sun.jvm.hotspot.debugger.Debugger; import sun.jvm.hotspot.debugger.DebuggerException; @@ -63,7 +65,6 @@ public class HotSpotAgent { private String os; private String cpu; - private String fileSep; // The system can work in several ways: // - Attaching to local process @@ -155,6 +156,14 @@ public class HotSpotAgent { go(); } + /** This uses a JVMDebugger that is already attached to the core or process */ + public synchronized void attach(JVMDebugger d) + throws DebuggerException { + debugger = d; + isServer = false; + go(); + } + /** This attaches to a "debug server" on a remote machine; this remote server has already attached to a process or opened a core file and is waiting for RMI calls on the Debugger object to @@ -303,28 +312,37 @@ public class HotSpotAgent { // server, but not client attaching to server) // - try { - os = PlatformInfo.getOS(); - cpu = PlatformInfo.getCPU(); - } - catch (UnsupportedPlatformException e) { - throw new DebuggerException(e); - } - fileSep = System.getProperty("file.separator"); + // Handle existing or alternate JVMDebugger: + // these will set os, cpu independently of our PlatformInfo implementation. + String alternateDebugger = System.getProperty("sa.altDebugger"); + if (debugger != null) { + setupDebuggerExisting(); + + } else if (alternateDebugger != null) { + setupDebuggerAlternate(alternateDebugger); - if (os.equals("solaris")) { - setupDebuggerSolaris(); - } else if (os.equals("win32")) { - setupDebuggerWin32(); - } else if (os.equals("linux")) { - setupDebuggerLinux(); - } else if (os.equals("bsd")) { - setupDebuggerBsd(); - } else if (os.equals("darwin")) { - setupDebuggerDarwin(); } else { - // Add support for more operating systems here - throw new DebuggerException("Operating system " + os + " not yet supported"); + // Otherwise, os, cpu are those of our current platform: + try { + os = PlatformInfo.getOS(); + cpu = PlatformInfo.getCPU(); + } catch (UnsupportedPlatformException e) { + throw new DebuggerException(e); + } + if (os.equals("solaris")) { + setupDebuggerSolaris(); + } else if (os.equals("win32")) { + setupDebuggerWin32(); + } else if (os.equals("linux")) { + setupDebuggerLinux(); + } else if (os.equals("bsd")) { + setupDebuggerBsd(); + } else if (os.equals("darwin")) { + setupDebuggerDarwin(); + } else { + // Add support for more operating systems here + throw new DebuggerException("Operating system " + os + " not yet supported"); + } } if (isServer) { @@ -423,6 +441,41 @@ public class HotSpotAgent { // OS-specific debugger setup/connect routines // + // Use the existing JVMDebugger, as passed to our constructor. + // Retrieve os and cpu from that debugger, not the current platform. + private void setupDebuggerExisting() { + + os = debugger.getOS(); + cpu = debugger.getCPU(); + setupJVMLibNames(os); + machDesc = debugger.getMachineDescription(); + } + + // Given a classname, load an alternate implementation of JVMDebugger. + private void setupDebuggerAlternate(String alternateName) { + + try { + Class c = Class.forName(alternateName); + Constructor cons = c.getConstructor(); + debugger = (JVMDebugger) cons.newInstance(); + attachDebugger(); + setupDebuggerExisting(); + + } catch (ClassNotFoundException cnfe) { + throw new DebuggerException("Cannot find alternate SA Debugger: '" + alternateName + "'"); + } catch (NoSuchMethodException nsme) { + throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' has missing constructor."); + } catch (InstantiationException ie) { + throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' fails to initialise: ", ie); + } catch (IllegalAccessException iae) { + throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' fails to initialise: ", iae); + } catch (InvocationTargetException iae) { + throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' fails to initialise: ", iae); + } + + System.err.println("Loaded alternate HotSpot SA Debugger: " + alternateName); + } + // // Solaris // @@ -466,6 +519,11 @@ public class HotSpotAgent { debugger = new RemoteDebuggerClient(remote); machDesc = ((RemoteDebuggerClient) debugger).getMachineDescription(); os = debugger.getOS(); + setupJVMLibNames(os); + cpu = debugger.getCPU(); + } + + private void setupJVMLibNames(String os) { if (os.equals("solaris")) { setupJVMLibNamesSolaris(); } else if (os.equals("win32")) { @@ -479,8 +537,6 @@ public class HotSpotAgent { } else { throw new RuntimeException("Unknown OS type"); } - - cpu = debugger.getCPU(); } private void setupJVMLibNamesSolaris() { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java index 9e85e133b3a..cff29ce8edc 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java @@ -26,11 +26,11 @@ package sun.jvm.hotspot.debugger.linux; import sun.jvm.hotspot.debugger.*; -class LinuxAddress implements Address { +public class LinuxAddress implements Address { protected LinuxDebugger debugger; protected long addr; - LinuxAddress(LinuxDebugger debugger, long addr) { + public LinuxAddress(LinuxDebugger debugger, long addr) { this.debugger = debugger; this.addr = addr; } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java index 310acb88ac7..99291aada29 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java @@ -26,8 +26,8 @@ package sun.jvm.hotspot.debugger.linux; import sun.jvm.hotspot.debugger.*; -class LinuxOopHandle extends LinuxAddress implements OopHandle { - LinuxOopHandle(LinuxDebugger debugger, long addr) { +public class LinuxOopHandle extends LinuxAddress implements OopHandle { + public LinuxOopHandle(LinuxDebugger debugger, long addr) { super(debugger, addr); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java index 0a9d9436878..f84da894ac2 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java @@ -246,7 +246,7 @@ public class VM { } } - private static final boolean disableDerivedPrinterTableCheck; + private static final boolean disableDerivedPointerTableCheck; private static final Properties saProps; static { @@ -256,12 +256,12 @@ public class VM { url = VM.class.getClassLoader().getResource("sa.properties"); saProps.load(new BufferedInputStream(url.openStream())); } catch (Exception e) { - throw new RuntimeException("Unable to load properties " + + System.err.println("Unable to load properties " + (url == null ? "null" : url.toString()) + ": " + e.getMessage()); } - disableDerivedPrinterTableCheck = System.getProperty("sun.jvm.hotspot.runtime.VM.disableDerivedPointerTableCheck") != null; + disableDerivedPointerTableCheck = System.getProperty("sun.jvm.hotspot.runtime.VM.disableDerivedPointerTableCheck") != null; } private VM(TypeDataBase db, JVMDebugger debugger, boolean isBigEndian) { @@ -371,7 +371,8 @@ public class VM { /** This is used by the debugging system */ public static void initialize(TypeDataBase db, JVMDebugger debugger) { if (soleInstance != null) { - throw new RuntimeException("Attempt to initialize VM twice"); + // Using multiple SA Tool classes in the same process creates a call here. + return; } soleInstance = new VM(db, debugger, debugger.getMachineDescription().isBigEndian()); @@ -683,7 +684,7 @@ public class VM { /** Returns true if C2 derived pointer table should be used, false otherwise */ public boolean useDerivedPointerTable() { - return !disableDerivedPrinterTableCheck; + return !disableDerivedPointerTableCheck; } /** Returns the code cache; should not be used if is core build */ diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java index 77f0f800445..eeda376b1d6 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java @@ -41,6 +41,14 @@ import sun.jvm.hotspot.utilities.*; public class ClassLoaderStats extends Tool { boolean verbose = true; + public ClassLoaderStats() { + super(); + } + + public ClassLoaderStats(JVMDebugger d) { + super(d); + } + public static void main(String[] args) { ClassLoaderStats cls = new ClassLoaderStats(); cls.start(args); diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java index 79e6784a63e..ed707b9ee8a 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java @@ -24,6 +24,7 @@ package sun.jvm.hotspot.tools; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.tools.*; import sun.jvm.hotspot.oops.*; @@ -42,6 +43,15 @@ import java.util.Comparator; * summary of these objects in the form of a histogram. */ public class FinalizerInfo extends Tool { + + public FinalizerInfo() { + super(); + } + + public FinalizerInfo(JVMDebugger d) { + super(d); + } + public static void main(String[] args) { FinalizerInfo finfo = new FinalizerInfo(); finfo.start(args); diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java index effeabb582a..c8db6d6b044 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java @@ -25,10 +25,19 @@ package sun.jvm.hotspot.tools; import java.io.PrintStream; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.runtime.*; public class FlagDumper extends Tool { + public FlagDumper() { + super(); + } + + public FlagDumper(JVMDebugger d) { + super(d); + } + public void run() { VM.Flag[] flags = VM.getVM().getCommandLineFlags(); PrintStream out = System.out; diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java index 5a7c06618b9..c5af0ed005d 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java @@ -25,6 +25,7 @@ package sun.jvm.hotspot.tools; import sun.jvm.hotspot.utilities.HeapHprofBinWriter; +import sun.jvm.hotspot.debugger.JVMDebugger; import java.io.IOException; /* @@ -42,6 +43,11 @@ public class HeapDumper extends Tool { this.dumpFile = dumpFile; } + public HeapDumper(String dumpFile, JVMDebugger d) { + super(d); + this.dumpFile = dumpFile; + } + protected void printFlagsUsage() { System.out.println(" \tto dump heap to " + DEFAULT_DUMP_FILE); diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java index 87621655269..a0123dd4c99 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java @@ -29,12 +29,21 @@ import sun.jvm.hotspot.gc_interface.*; import sun.jvm.hotspot.gc_implementation.g1.*; import sun.jvm.hotspot.gc_implementation.parallelScavenge.*; import sun.jvm.hotspot.gc_implementation.shared.*; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.memory.*; import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.runtime.*; public class HeapSummary extends Tool { + public HeapSummary() { + super(); + } + + public HeapSummary(JVMDebugger d) { + super(d); + } + public static void main(String[] args) { HeapSummary hs = new HeapSummary(); hs.start(args); diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java index a9f6c0e9c90..f2452420744 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java @@ -25,12 +25,21 @@ package sun.jvm.hotspot.tools; import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.debugger.JVMDebugger; public class JInfo extends Tool { + public JInfo() { + super(); + } + public JInfo(int m) { mode = m; } + public JInfo(JVMDebugger d) { + super(d); + } + protected boolean needsJavaPrefix() { return false; } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java index d9ea364edaa..f6f3c0741c0 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java @@ -25,6 +25,7 @@ package sun.jvm.hotspot.tools; import java.io.*; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.utilities.*; public class JMap extends Tool { @@ -36,6 +37,10 @@ public class JMap extends Tool { this(MODE_PMAP); } + public JMap(JVMDebugger d) { + super(d); + } + protected boolean needsJavaPrefix() { return false; } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java index 95f46445f8a..9301f1059fd 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java @@ -25,9 +25,19 @@ package sun.jvm.hotspot.tools; import java.io.*; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.runtime.*; public class JSnap extends Tool { + + public JSnap() { + super(); + } + + public JSnap(JVMDebugger d) { + super(d); + } + public void run() { final PrintStream out = System.out; if (PerfMemory.initialized()) { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java index 9e0688cf393..7cbe8f4d945 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java @@ -24,6 +24,8 @@ package sun.jvm.hotspot.tools; +import sun.jvm.hotspot.debugger.JVMDebugger; + public class JStack extends Tool { public JStack(boolean mixedMode, boolean concurrentLocks) { this.mixedMode = mixedMode; @@ -34,6 +36,10 @@ public class JStack extends Tool { this(true, true); } + public JStack(JVMDebugger d) { + super(d); + } + protected boolean needsJavaPrefix() { return false; } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java index f03469e13f1..168202eec2c 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java @@ -33,6 +33,14 @@ import java.io.PrintStream; an object histogram from a remote or crashed VM. */ public class ObjectHistogram extends Tool { + public ObjectHistogram() { + super(); + } + + public ObjectHistogram(JVMDebugger d) { + super(d); + } + public void run() { run(System.out, System.err); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java index 70bd55513b9..2a234130991 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java @@ -31,6 +31,15 @@ import sun.jvm.hotspot.debugger.cdbg.*; import sun.jvm.hotspot.runtime.*; public class PMap extends Tool { + + public PMap() { + super(); + } + + public PMap(JVMDebugger d) { + super(d); + } + public void run() { run(System.out); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java index 0b3720ff594..7f10612b317 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java @@ -45,6 +45,10 @@ public class PStack extends Tool { this(true, true); } + public PStack(JVMDebugger d) { + super(d); + } + public void run() { run(System.out); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java index 83270bfdeff..eb0cc88d116 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java @@ -45,6 +45,16 @@ public class StackTrace extends Tool { run(System.out); } + public StackTrace(JVMDebugger d) { + super(d); + } + + public StackTrace(JVMDebugger d, boolean v, boolean concurrentLocks) { + super(d); + this.verbose = v; + this.concurrentLocks = concurrentLocks; + } + public void run(java.io.PrintStream tty) { // Ready to go with the database... try { diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java index bb4f703c64b..d601fef4401 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java @@ -27,10 +27,19 @@ package sun.jvm.hotspot.tools; import java.io.PrintStream; import java.util.*; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.runtime.*; public class SysPropsDumper extends Tool { + public SysPropsDumper() { + super(); + } + + public SysPropsDumper(JVMDebugger d) { + super(d); + } + public void run() { Properties sysProps = VM.getVM().getSystemProperties(); PrintStream out = System.out; diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java index 4279c425bd8..3021801c9dd 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java @@ -35,6 +35,7 @@ import sun.jvm.hotspot.debugger.*; public abstract class Tool implements Runnable { private HotSpotAgent agent; + private JVMDebugger jvmDebugger; private int debugeeType; // debugeeType is one of constants below @@ -42,6 +43,13 @@ public abstract class Tool implements Runnable { protected static final int DEBUGEE_CORE = 1; protected static final int DEBUGEE_REMOTE = 2; + public Tool() { + } + + public Tool(JVMDebugger d) { + jvmDebugger = d; + } + public String getName() { return getClass().getName(); } @@ -90,7 +98,6 @@ public abstract class Tool implements Runnable { protected void usage() { printUsage(); - System.exit(1); } /* @@ -106,13 +113,13 @@ public abstract class Tool implements Runnable { protected void stop() { if (agent != null) { agent.detach(); - System.exit(0); } } protected void start(String[] args) { if ((args.length < 1) || (args.length > 2)) { usage(); + return; } // Attempt to handle -h or -help or some invalid flag @@ -185,13 +192,31 @@ public abstract class Tool implements Runnable { } if (e.getMessage() != null) { err.print(e.getMessage()); + e.printStackTrace(); } err.println(); - System.exit(1); + return; } err.println("Debugger attached successfully."); + startInternal(); + } + // When using an existing JVMDebugger. + public void start() { + + if (jvmDebugger == null) { + throw new RuntimeException("Tool.start() called with no JVMDebugger set."); + } + agent = new HotSpotAgent(); + agent.attach(jvmDebugger); + startInternal(); + } + + // Remains of the start mechanism, common to both start methods. + private void startInternal() { + + PrintStream err = System.err; VM vm = VM.getVM(); if (vm.isCore()) { err.println("Core build detected."); diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java index 34ccc102acb..96817b26226 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java @@ -25,6 +25,7 @@ package sun.jvm.hotspot.tools.jcore; import java.io.*; +import java.lang.reflect.Constructor; import java.util.jar.JarOutputStream; import java.util.jar.JarEntry; import java.util.jar.Manifest; @@ -38,6 +39,16 @@ public class ClassDump extends Tool { private ClassFilter classFilter; private String outputDirectory; private JarOutputStream jarStream; + private String pkgList; + + public ClassDump() { + super(); + } + + public ClassDump(JVMDebugger d, String pkgList) { + super(d); + this.pkgList = pkgList; + } public void setClassFilter(ClassFilter cf) { classFilter = cf; @@ -63,6 +74,25 @@ public class ClassDump extends Tool { public void run() { // Ready to go with the database... try { + // The name of the filter always comes from a System property. + // If we have a pkgList, pass it, otherwise let the filter read + // its own System property for the list of classes. + String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter", + "sun.jvm.hotspot.tools.jcore.PackageNameFilter"); + try { + Class filterClass = Class.forName(filterClassName); + if (pkgList == null) { + classFilter = (ClassFilter) filterClass.newInstance(); + } else { + Constructor con = filterClass.getConstructor(String.class); + classFilter = (ClassFilter) con.newInstance(pkgList); + } + } catch(Exception exp) { + System.err.println("Warning: Can not create class filter!"); + } + + String outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir", "."); + setOutputDirectory(outputDirectory); // walk through the system dictionary SystemDictionary dict = VM.getVM().getSystemDictionary(); @@ -139,26 +169,8 @@ public class ClassDump extends Tool { } public static void main(String[] args) { - // load class filters - ClassFilter classFilter = null; - String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter"); - if (filterClassName != null) { - try { - Class filterClass = Class.forName(filterClassName); - classFilter = (ClassFilter) filterClass.newInstance(); - } catch(Exception exp) { - System.err.println("Warning: Can not create class filter!"); - } - } - - String outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir"); - if (outputDirectory == null) - outputDirectory = "."; - ClassDump cd = new ClassDump(); - cd.setClassFilter(classFilter); - cd.setOutputDirectory(outputDirectory); cd.start(args); cd.stop(); } diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java index e46de0194d7..09874af178e 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java @@ -24,12 +24,22 @@ package sun.jvm.hotspot.tools.soql; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.tools.*; import sun.jvm.hotspot.utilities.*; import sun.jvm.hotspot.utilities.soql.*; /** This is command line JavaScript debugger console */ public class JSDB extends Tool { + + public JSDB() { + super(); + } + + public JSDB(JVMDebugger d) { + super(d); + } + public static void main(String[] args) { JSDB jsdb = new JSDB(); jsdb.start(args); diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java index 3a4c2470b1b..b3054b90bd0 100644 --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java @@ -44,6 +44,14 @@ public class SOQL extends Tool { soql.stop(); } + public SOQL() { + super(); + } + + public SOQL(JVMDebugger d) { + super(d); + } + protected SOQLEngine soqlEngine; protected BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); protected PrintStream out = System.out; diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index 17088cd02f9..b597ff990be 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=39 +HS_BUILD_NUMBER=40 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp index 1cbc5c41316..64745015923 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2946,6 +2946,9 @@ void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst_opr) { } } +void LIR_Assembler::emit_updatecrc32(LIR_OpUpdateCRC32* op) { + fatal("CRC32 intrinsic is not implemented on this platform"); +} void LIR_Assembler::emit_lock(LIR_OpLock* op) { Register obj = op->obj_opr()->as_register(); diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp index 82cc696e8b7..dc3bc8691ac 100644 --- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -784,6 +784,10 @@ void LIRGenerator::do_ArrayCopy(Intrinsic* x) { set_no_result(x); } +void LIRGenerator::do_update_CRC32(Intrinsic* x) { + fatal("CRC32 intrinsic is not implemented on this platform"); +} + // _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f // _i2b, _i2c, _i2s void LIRGenerator::do_Convert(Convert* x) { diff --git a/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp index a43a9cee538..c6cf521272d 100644 --- a/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/c1_globals_sparc.hpp @@ -49,8 +49,9 @@ define_pd_global(intx, FreqInlineSize, 325 ); define_pd_global(bool, ResizeTLAB, true ); define_pd_global(intx, ReservedCodeCacheSize, 32*M ); define_pd_global(intx, CodeCacheExpansionSize, 32*K ); -define_pd_global(uintx,CodeCacheMinBlockLength, 1); -define_pd_global(uintx,MetaspaceSize, 12*M ); +define_pd_global(uintx, CodeCacheMinBlockLength, 1); +define_pd_global(uintx, CodeCacheMinimumUseSpace, 400*K); +define_pd_global(uintx, MetaspaceSize, 12*M ); define_pd_global(bool, NeverActAsServerClassMachine, true ); define_pd_global(intx, NewSizeThreadIncrease, 16*K ); define_pd_global(uint64_t,MaxRAM, 1ULL*G); diff --git a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp index c642e915fe1..e32094deb06 100644 --- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp @@ -86,7 +86,8 @@ define_pd_global(intx, CodeCacheExpansionSize, 32*K); // Ergonomics related flags define_pd_global(uint64_t,MaxRAM, 4ULL*G); #endif -define_pd_global(uintx,CodeCacheMinBlockLength, 4); +define_pd_global(uintx, CodeCacheMinBlockLength, 4); +define_pd_global(uintx, CodeCacheMinimumUseSpace, 400*K); // Heap related flags define_pd_global(uintx,MetaspaceSize, ScaleForWordSize(16*M)); diff --git a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp index 55f344f55a1..ac9746679b3 100644 --- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp @@ -257,11 +257,6 @@ bool frame::safe_for_sender(JavaThread *thread) { return false; } - // Could be a zombie method - if (sender_blob->is_zombie() || sender_blob->is_unloaded()) { - return false; - } - // It should be safe to construct the sender though it might not be valid frame sender(_SENDER_SP, younger_sp, adjusted_stack); diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp index 02a438f2f40..761b5c3259f 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1673,6 +1673,11 @@ void Assembler::movdqa(XMMRegister dst, XMMRegister src) { emit_simd_arith_nonds(0x6F, dst, src, VEX_SIMD_66); } +void Assembler::movdqa(XMMRegister dst, Address src) { + NOT_LP64(assert(VM_Version::supports_sse2(), "")); + emit_simd_arith_nonds(0x6F, dst, src, VEX_SIMD_66); +} + void Assembler::movdqu(XMMRegister dst, Address src) { NOT_LP64(assert(VM_Version::supports_sse2(), "")); emit_simd_arith_nonds(0x6F, dst, src, VEX_SIMD_F3); @@ -2286,6 +2291,38 @@ void Assembler::pcmpestri(XMMRegister dst, XMMRegister src, int imm8) { emit_int8(imm8); } +void Assembler::pextrd(Register dst, XMMRegister src, int imm8) { + assert(VM_Version::supports_sse4_1(), ""); + int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, false); + emit_int8(0x16); + emit_int8((unsigned char)(0xC0 | encode)); + emit_int8(imm8); +} + +void Assembler::pextrq(Register dst, XMMRegister src, int imm8) { + assert(VM_Version::supports_sse4_1(), ""); + int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, true); + emit_int8(0x16); + emit_int8((unsigned char)(0xC0 | encode)); + emit_int8(imm8); +} + +void Assembler::pinsrd(XMMRegister dst, Register src, int imm8) { + assert(VM_Version::supports_sse4_1(), ""); + int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, false); + emit_int8(0x22); + emit_int8((unsigned char)(0xC0 | encode)); + emit_int8(imm8); +} + +void Assembler::pinsrq(XMMRegister dst, Register src, int imm8) { + assert(VM_Version::supports_sse4_1(), ""); + int encode = simd_prefix_and_encode(dst, dst, as_XMMRegister(src->encoding()), VEX_SIMD_66, VEX_OPCODE_0F_3A, true); + emit_int8(0x22); + emit_int8((unsigned char)(0xC0 | encode)); + emit_int8(imm8); +} + void Assembler::pmovzxbw(XMMRegister dst, Address src) { assert(VM_Version::supports_sse4_1(), ""); InstructionMark im(this); @@ -3691,6 +3728,16 @@ void Assembler::vpbroadcastd(XMMRegister dst, XMMRegister src) { emit_int8((unsigned char)(0xC0 | encode)); } +// Carry-Less Multiplication Quadword +void Assembler::vpclmulqdq(XMMRegister dst, XMMRegister nds, XMMRegister src, int mask) { + assert(VM_Version::supports_avx() && VM_Version::supports_clmul(), ""); + bool vector256 = false; + int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_3A); + emit_int8(0x44); + emit_int8((unsigned char)(0xC0 | encode)); + emit_int8((unsigned char)mask); +} + void Assembler::vzeroupper() { assert(VM_Version::supports_avx(), ""); (void)vex_prefix_and_encode(xmm0, xmm0, xmm0, VEX_SIMD_NONE); diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.hpp b/hotspot/src/cpu/x86/vm/assembler_x86.hpp index 97a5bfc0368..31481b5808f 100644 --- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp @@ -1266,6 +1266,7 @@ private: // Move Aligned Double Quadword void movdqa(XMMRegister dst, XMMRegister src); + void movdqa(XMMRegister dst, Address src); // Move Unaligned Double Quadword void movdqu(Address dst, XMMRegister src); @@ -1404,6 +1405,14 @@ private: void pcmpestri(XMMRegister xmm1, XMMRegister xmm2, int imm8); void pcmpestri(XMMRegister xmm1, Address src, int imm8); + // SSE 4.1 extract + void pextrd(Register dst, XMMRegister src, int imm8); + void pextrq(Register dst, XMMRegister src, int imm8); + + // SSE 4.1 insert + void pinsrd(XMMRegister dst, Register src, int imm8); + void pinsrq(XMMRegister dst, Register src, int imm8); + // SSE4.1 packed move void pmovzxbw(XMMRegister dst, XMMRegister src); void pmovzxbw(XMMRegister dst, Address src); @@ -1764,6 +1773,9 @@ private: // duplicate 4-bytes integer data from src into 8 locations in dest void vpbroadcastd(XMMRegister dst, XMMRegister src); + // Carry-Less Multiplication Quadword + void vpclmulqdq(XMMRegister dst, XMMRegister nds, XMMRegister src, int mask); + // AVX instruction which is used to clear upper 128 bits of YMM registers and // to avoid transaction penalty between AVX and SSE states. There is no // penalty if legacy SSE instructions are encoded using VEX prefix because diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index a99d7939373..b5bceeb60c6 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3512,6 +3512,22 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) { __ bind(*stub->continuation()); } +void LIR_Assembler::emit_updatecrc32(LIR_OpUpdateCRC32* op) { + assert(op->crc()->is_single_cpu(), "crc must be register"); + assert(op->val()->is_single_cpu(), "byte value must be register"); + assert(op->result_opr()->is_single_cpu(), "result must be register"); + Register crc = op->crc()->as_register(); + Register val = op->val()->as_register(); + Register res = op->result_opr()->as_register(); + + assert_different_registers(val, crc, res); + + __ lea(res, ExternalAddress(StubRoutines::crc_table_addr())); + __ notl(crc); // ~crc + __ update_byte_crc32(crc, val, res); + __ notl(crc); // ~crc + __ mov(res, crc); +} void LIR_Assembler::emit_lock(LIR_OpLock* op) { Register obj = op->obj_opr()->as_register(); // may not be an oop diff --git a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp index 6810ae54216..e6638581bcf 100644 --- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -932,6 +932,81 @@ void LIRGenerator::do_ArrayCopy(Intrinsic* x) { __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint } +void LIRGenerator::do_update_CRC32(Intrinsic* x) { + assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support"); + // Make all state_for calls early since they can emit code + LIR_Opr result = rlock_result(x); + int flags = 0; + switch (x->id()) { + case vmIntrinsics::_updateCRC32: { + LIRItem crc(x->argument_at(0), this); + LIRItem val(x->argument_at(1), this); + crc.load_item(); + val.load_item(); + __ update_crc32(crc.result(), val.result(), result); + break; + } + case vmIntrinsics::_updateBytesCRC32: + case vmIntrinsics::_updateByteBufferCRC32: { + bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32); + + LIRItem crc(x->argument_at(0), this); + LIRItem buf(x->argument_at(1), this); + LIRItem off(x->argument_at(2), this); + LIRItem len(x->argument_at(3), this); + buf.load_item(); + off.load_nonconstant(); + + LIR_Opr index = off.result(); + int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0; + if(off.result()->is_constant()) { + index = LIR_OprFact::illegalOpr; + offset += off.result()->as_jint(); + } + LIR_Opr base_op = buf.result(); + +#ifndef _LP64 + if (!is_updateBytes) { // long b raw address + base_op = new_register(T_INT); + __ convert(Bytecodes::_l2i, buf.result(), base_op); + } +#else + if (index->is_valid()) { + LIR_Opr tmp = new_register(T_LONG); + __ convert(Bytecodes::_i2l, index, tmp); + index = tmp; + } +#endif + + LIR_Address* a = new LIR_Address(base_op, + index, + LIR_Address::times_1, + offset, + T_BYTE); + BasicTypeList signature(3); + signature.append(T_INT); + signature.append(T_ADDRESS); + signature.append(T_INT); + CallingConvention* cc = frame_map()->c_calling_convention(&signature); + const LIR_Opr result_reg = result_register_for(x->type()); + + LIR_Opr addr = new_pointer_register(); + __ leal(LIR_OprFact::address(a), addr); + + crc.load_item_force(cc->at(0)); + __ move(addr, cc->at(1)); + len.load_item_force(cc->at(2)); + + __ call_runtime_leaf(StubRoutines::updateBytesCRC32(), getThreadTemp(), result_reg, cc->args()); + __ move(result_reg, result); + + break; + } + default: { + ShouldNotReachHere(); + } + } +} // _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f // _i2b, _i2c, _i2s diff --git a/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp b/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp index 98e02b16cd0..13f3df82c29 100644 --- a/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c1_globals_x86.hpp @@ -50,8 +50,9 @@ define_pd_global(intx, InitialCodeCacheSize, 160*K); define_pd_global(intx, ReservedCodeCacheSize, 32*M ); define_pd_global(bool, ProfileInterpreter, false); define_pd_global(intx, CodeCacheExpansionSize, 32*K ); -define_pd_global(uintx,CodeCacheMinBlockLength, 1); -define_pd_global(uintx,MetaspaceSize, 12*M ); +define_pd_global(uintx, CodeCacheMinBlockLength, 1); +define_pd_global(uintx, CodeCacheMinimumUseSpace, 400*K); +define_pd_global(uintx, MetaspaceSize, 12*M ); define_pd_global(bool, NeverActAsServerClassMachine, true ); define_pd_global(uint64_t,MaxRAM, 1ULL*G); define_pd_global(bool, CICompileOSR, true ); diff --git a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp index f63b8c46d58..ce92123e818 100644 --- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp @@ -85,7 +85,8 @@ define_pd_global(bool, OptoScheduling, false); define_pd_global(bool, OptoBundling, false); define_pd_global(intx, ReservedCodeCacheSize, 48*M); -define_pd_global(uintx,CodeCacheMinBlockLength, 4); +define_pd_global(uintx, CodeCacheMinBlockLength, 4); +define_pd_global(uintx, CodeCacheMinimumUseSpace, 400*K); // Heap related flags define_pd_global(uintx,MetaspaceSize, ScaleForWordSize(16*M)); diff --git a/hotspot/src/cpu/x86/vm/globals_x86.hpp b/hotspot/src/cpu/x86/vm/globals_x86.hpp index 07ab0cfcdce..c47f7d1c193 100644 --- a/hotspot/src/cpu/x86/vm/globals_x86.hpp +++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp @@ -96,6 +96,9 @@ define_pd_global(uintx, CMSYoungGenPerWorker, 64*M); // default max size of CMS product(intx, UseAVX, 99, \ "Highest supported AVX instructions set on x86/x64") \ \ + product(bool, UseCLMUL, false, \ + "Control whether CLMUL instructions can be used on x86/x64") \ + \ diagnostic(bool, UseIncDec, true, \ "Use INC, DEC instructions on x86") \ \ diff --git a/hotspot/src/cpu/x86/vm/interpreterGenerator_x86.hpp b/hotspot/src/cpu/x86/vm/interpreterGenerator_x86.hpp index 13786e4149a..08f47708cdc 100644 --- a/hotspot/src/cpu/x86/vm/interpreterGenerator_x86.hpp +++ b/hotspot/src/cpu/x86/vm/interpreterGenerator_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,8 @@ address generate_empty_entry(void); address generate_accessor_entry(void); address generate_Reference_get_entry(); + address generate_CRC32_update_entry(); + address generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind); void lock_method(void); void generate_stack_overflow_check(void); diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp index 98c93f99a0f..8aad6965156 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2794,6 +2794,15 @@ void MacroAssembler::movdqu(XMMRegister dst, AddressLiteral src) { } } +void MacroAssembler::movdqa(XMMRegister dst, AddressLiteral src) { + if (reachable(src)) { + Assembler::movdqa(dst, as_Address(src)); + } else { + lea(rscratch1, src); + Assembler::movdqa(dst, Address(rscratch1, 0)); + } +} + void MacroAssembler::movsd(XMMRegister dst, AddressLiteral src) { if (reachable(src)) { Assembler::movsd(dst, as_Address(src)); @@ -6388,6 +6397,193 @@ void MacroAssembler::encode_iso_array(Register src, Register dst, Register len, bind(L_done); } +/** + * Emits code to update CRC-32 with a byte value according to constants in table + * + * @param [in,out]crc Register containing the crc. + * @param [in]val Register containing the byte to fold into the CRC. + * @param [in]table Register containing the table of crc constants. + * + * uint32_t crc; + * val = crc_table[(val ^ crc) & 0xFF]; + * crc = val ^ (crc >> 8); + * + */ +void MacroAssembler::update_byte_crc32(Register crc, Register val, Register table) { + xorl(val, crc); + andl(val, 0xFF); + shrl(crc, 8); // unsigned shift + xorl(crc, Address(table, val, Address::times_4, 0)); +} + +/** + * Fold 128-bit data chunk + */ +void MacroAssembler::fold_128bit_crc32(XMMRegister xcrc, XMMRegister xK, XMMRegister xtmp, Register buf, int offset) { + vpclmulhdq(xtmp, xK, xcrc); // [123:64] + vpclmulldq(xcrc, xK, xcrc); // [63:0] + vpxor(xcrc, xcrc, Address(buf, offset), false /* vector256 */); + pxor(xcrc, xtmp); +} + +void MacroAssembler::fold_128bit_crc32(XMMRegister xcrc, XMMRegister xK, XMMRegister xtmp, XMMRegister xbuf) { + vpclmulhdq(xtmp, xK, xcrc); + vpclmulldq(xcrc, xK, xcrc); + pxor(xcrc, xbuf); + pxor(xcrc, xtmp); +} + +/** + * 8-bit folds to compute 32-bit CRC + * + * uint64_t xcrc; + * timesXtoThe32[xcrc & 0xFF] ^ (xcrc >> 8); + */ +void MacroAssembler::fold_8bit_crc32(XMMRegister xcrc, Register table, XMMRegister xtmp, Register tmp) { + movdl(tmp, xcrc); + andl(tmp, 0xFF); + movdl(xtmp, Address(table, tmp, Address::times_4, 0)); + psrldq(xcrc, 1); // unsigned shift one byte + pxor(xcrc, xtmp); +} + +/** + * uint32_t crc; + * timesXtoThe32[crc & 0xFF] ^ (crc >> 8); + */ +void MacroAssembler::fold_8bit_crc32(Register crc, Register table, Register tmp) { + movl(tmp, crc); + andl(tmp, 0xFF); + shrl(crc, 8); + xorl(crc, Address(table, tmp, Address::times_4, 0)); +} + +/** + * @param crc register containing existing CRC (32-bit) + * @param buf register pointing to input byte buffer (byte*) + * @param len register containing number of bytes + * @param table register that will contain address of CRC table + * @param tmp scratch register + */ +void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, Register table, Register tmp) { + assert_different_registers(crc, buf, len, table, tmp, rax); + + Label L_tail, L_tail_restore, L_tail_loop, L_exit, L_align_loop, L_aligned; + Label L_fold_tail, L_fold_128b, L_fold_512b, L_fold_512b_loop, L_fold_tail_loop; + + lea(table, ExternalAddress(StubRoutines::crc_table_addr())); + notl(crc); // ~crc + cmpl(len, 16); + jcc(Assembler::less, L_tail); + + // Align buffer to 16 bytes + movl(tmp, buf); + andl(tmp, 0xF); + jccb(Assembler::zero, L_aligned); + subl(tmp, 16); + addl(len, tmp); + + align(4); + BIND(L_align_loop); + movsbl(rax, Address(buf, 0)); // load byte with sign extension + update_byte_crc32(crc, rax, table); + increment(buf); + incrementl(tmp); + jccb(Assembler::less, L_align_loop); + + BIND(L_aligned); + movl(tmp, len); // save + shrl(len, 4); + jcc(Assembler::zero, L_tail_restore); + + // Fold crc into first bytes of vector + movdqa(xmm1, Address(buf, 0)); + movdl(rax, xmm1); + xorl(crc, rax); + pinsrd(xmm1, crc, 0); + addptr(buf, 16); + subl(len, 4); // len > 0 + jcc(Assembler::less, L_fold_tail); + + movdqa(xmm2, Address(buf, 0)); + movdqa(xmm3, Address(buf, 16)); + movdqa(xmm4, Address(buf, 32)); + addptr(buf, 48); + subl(len, 3); + jcc(Assembler::lessEqual, L_fold_512b); + + // Fold total 512 bits of polynomial on each iteration, + // 128 bits per each of 4 parallel streams. + movdqu(xmm0, ExternalAddress(StubRoutines::x86::crc_by128_masks_addr() + 32)); + + align(32); + BIND(L_fold_512b_loop); + fold_128bit_crc32(xmm1, xmm0, xmm5, buf, 0); + fold_128bit_crc32(xmm2, xmm0, xmm5, buf, 16); + fold_128bit_crc32(xmm3, xmm0, xmm5, buf, 32); + fold_128bit_crc32(xmm4, xmm0, xmm5, buf, 48); + addptr(buf, 64); + subl(len, 4); + jcc(Assembler::greater, L_fold_512b_loop); + + // Fold 512 bits to 128 bits. + BIND(L_fold_512b); + movdqu(xmm0, ExternalAddress(StubRoutines::x86::crc_by128_masks_addr() + 16)); + fold_128bit_crc32(xmm1, xmm0, xmm5, xmm2); + fold_128bit_crc32(xmm1, xmm0, xmm5, xmm3); + fold_128bit_crc32(xmm1, xmm0, xmm5, xmm4); + + // Fold the rest of 128 bits data chunks + BIND(L_fold_tail); + addl(len, 3); + jccb(Assembler::lessEqual, L_fold_128b); + movdqu(xmm0, ExternalAddress(StubRoutines::x86::crc_by128_masks_addr() + 16)); + + BIND(L_fold_tail_loop); + fold_128bit_crc32(xmm1, xmm0, xmm5, buf, 0); + addptr(buf, 16); + decrementl(len); + jccb(Assembler::greater, L_fold_tail_loop); + + // Fold 128 bits in xmm1 down into 32 bits in crc register. + BIND(L_fold_128b); + movdqu(xmm0, ExternalAddress(StubRoutines::x86::crc_by128_masks_addr())); + vpclmulqdq(xmm2, xmm0, xmm1, 0x1); + vpand(xmm3, xmm0, xmm2, false /* vector256 */); + vpclmulqdq(xmm0, xmm0, xmm3, 0x1); + psrldq(xmm1, 8); + psrldq(xmm2, 4); + pxor(xmm0, xmm1); + pxor(xmm0, xmm2); + + // 8 8-bit folds to compute 32-bit CRC. + for (int j = 0; j < 4; j++) { + fold_8bit_crc32(xmm0, table, xmm1, rax); + } + movdl(crc, xmm0); // mov 32 bits to general register + for (int j = 0; j < 4; j++) { + fold_8bit_crc32(crc, table, rax); + } + + BIND(L_tail_restore); + movl(len, tmp); // restore + BIND(L_tail); + andl(len, 0xf); + jccb(Assembler::zero, L_exit); + + // Fold the rest of bytes + align(4); + BIND(L_tail_loop); + movsbl(rax, Address(buf, 0)); // load byte with sign extension + update_byte_crc32(crc, rax, table); + increment(buf); + decrementl(len); + jccb(Assembler::greater, L_tail_loop); + + BIND(L_exit); + notl(crc); // ~c +} + #undef BIND #undef BLOCK_COMMENT diff --git a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp index e9f409dc500..3acef073c0e 100644 --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -899,6 +899,11 @@ public: void movdqu(XMMRegister dst, XMMRegister src) { Assembler::movdqu(dst, src); } void movdqu(XMMRegister dst, AddressLiteral src); + // Move Aligned Double Quadword + void movdqa(XMMRegister dst, Address src) { Assembler::movdqa(dst, src); } + void movdqa(XMMRegister dst, XMMRegister src) { Assembler::movdqa(dst, src); } + void movdqa(XMMRegister dst, AddressLiteral src); + void movsd(XMMRegister dst, XMMRegister src) { Assembler::movsd(dst, src); } void movsd(Address dst, XMMRegister src) { Assembler::movsd(dst, src); } void movsd(XMMRegister dst, Address src) { Assembler::movsd(dst, src); } @@ -1027,6 +1032,16 @@ public: Assembler::vinsertf128h(dst, nds, src); } + // Carry-Less Multiplication Quadword + void vpclmulldq(XMMRegister dst, XMMRegister nds, XMMRegister src) { + // 0x00 - multiply lower 64 bits [0:63] + Assembler::vpclmulqdq(dst, nds, src, 0x00); + } + void vpclmulhdq(XMMRegister dst, XMMRegister nds, XMMRegister src) { + // 0x11 - multiply upper 64 bits [64:127] + Assembler::vpclmulqdq(dst, nds, src, 0x11); + } + // Data void cmov32( Condition cc, Register dst, Address src); @@ -1143,6 +1158,16 @@ public: XMMRegister tmp1, XMMRegister tmp2, XMMRegister tmp3, XMMRegister tmp4, Register tmp5, Register result); + // CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic. + void update_byte_crc32(Register crc, Register val, Register table); + void kernel_crc32(Register crc, Register buf, Register len, Register table, Register tmp); + // Fold 128-bit data chunk + void fold_128bit_crc32(XMMRegister xcrc, XMMRegister xK, XMMRegister xtmp, Register buf, int offset); + void fold_128bit_crc32(XMMRegister xcrc, XMMRegister xK, XMMRegister xtmp, XMMRegister xbuf); + // Fold 8-bit data + void fold_8bit_crc32(Register crc, Register table, Register tmp); + void fold_8bit_crc32(XMMRegister crc, Register table, XMMRegister xtmp, Register tmp); + #undef VIRTUAL }; diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp index f24c5fdb38d..82e4183ef47 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2713,6 +2713,59 @@ class StubGenerator: public StubCodeGenerator { return start; } + /** + * Arguments: + * + * Inputs: + * rsp(4) - int crc + * rsp(8) - byte* buf + * rsp(12) - int length + * + * Ouput: + * rax - int crc result + */ + address generate_updateBytesCRC32() { + assert(UseCRC32Intrinsics, "need AVX and CLMUL instructions"); + + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32"); + + address start = __ pc(); + + const Register crc = rdx; // crc + const Register buf = rsi; // source java byte array address + const Register len = rcx; // length + const Register table = rdi; // crc_table address (reuse register) + const Register tmp = rbx; + assert_different_registers(crc, buf, len, table, tmp, rax); + + BLOCK_COMMENT("Entry:"); + __ enter(); // required for proper stackwalking of RuntimeStub frame + __ push(rsi); + __ push(rdi); + __ push(rbx); + + Address crc_arg(rbp, 8 + 0); + Address buf_arg(rbp, 8 + 4); + Address len_arg(rbp, 8 + 8); + + // Load up: + __ movl(crc, crc_arg); + __ movptr(buf, buf_arg); + __ movl(len, len_arg); + + __ kernel_crc32(crc, buf, len, table, tmp); + + __ movl(rax, crc); + __ pop(rbx); + __ pop(rdi); + __ pop(rsi); + __ leave(); // required for proper stackwalking of RuntimeStub frame + __ ret(0); + + return start; + } + public: // Information about frame layout at time of blocking runtime call. @@ -2887,6 +2940,12 @@ class StubGenerator: public StubCodeGenerator { // Build this early so it's available for the interpreter StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError)); + + if (UseCRC32Intrinsics) { + // set table address before stub generation which use it + StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table; + StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32(); + } } diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp index 7b8408d7131..2d94642f828 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3584,7 +3584,45 @@ class StubGenerator: public StubCodeGenerator { return start; } + /** + * Arguments: + * + * Inputs: + * c_rarg0 - int crc + * c_rarg1 - byte* buf + * c_rarg2 - int length + * + * Ouput: + * rax - int crc result + */ + address generate_updateBytesCRC32() { + assert(UseCRC32Intrinsics, "need AVX and CLMUL instructions"); + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32"); + + address start = __ pc(); + // Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) + // Unix: rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...) + // rscratch1: r10 + const Register crc = c_rarg0; // crc + const Register buf = c_rarg1; // source java byte array address + const Register len = c_rarg2; // length + const Register table = c_rarg3; // crc_table address (reuse register) + const Register tmp = r11; + assert_different_registers(crc, buf, len, table, tmp, rax); + + BLOCK_COMMENT("Entry:"); + __ enter(); // required for proper stackwalking of RuntimeStub frame + + __ kernel_crc32(crc, buf, len, table, tmp); + + __ movl(rax, crc); + __ leave(); // required for proper stackwalking of RuntimeStub frame + __ ret(0); + + return start; + } #undef __ #define __ masm-> @@ -3736,6 +3774,11 @@ class StubGenerator: public StubCodeGenerator { CAST_FROM_FN_PTR(address, SharedRuntime:: throw_StackOverflowError)); + if (UseCRC32Intrinsics) { + // set table address before stub generation which use it + StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table; + StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32(); + } } void generate_all() { diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86.cpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86.cpp new file mode 100644 index 00000000000..200f2aff80d --- /dev/null +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 "runtime/deoptimization.hpp" +#include "runtime/frame.inline.hpp" +#include "runtime/stubRoutines.hpp" +#include "runtime/thread.inline.hpp" + +// Implementation of the platform-specific part of StubRoutines - for +// a description of how to extend it, see the stubRoutines.hpp file. + +address StubRoutines::x86::_verify_mxcsr_entry = NULL; +address StubRoutines::x86::_key_shuffle_mask_addr = NULL; + +uint64_t StubRoutines::x86::_crc_by128_masks[] = +{ + /* The fields in this structure are arranged so that they can be + * picked up two at a time with 128-bit loads. + * + * Because of flipped bit order for this CRC polynomials + * the constant for X**N is left-shifted by 1. This is because + * a 64 x 64 polynomial multiply produces a 127-bit result + * but the highest term is always aligned to bit 0 in the container. + * Pre-shifting by one fixes this, at the cost of potentially making + * the 32-bit constant no longer fit in a 32-bit container (thus the + * use of uint64_t, though this is also the size used by the carry- + * less multiply instruction. + * + * In addition, the flipped bit order and highest-term-at-least-bit + * multiply changes the constants used. The 96-bit result will be + * aligned to the high-term end of the target 128-bit container, + * not the low-term end; that is, instead of a 512-bit or 576-bit fold, + * instead it is a 480 (=512-32) or 544 (=512+64-32) bit fold. + * + * This cause additional problems in the 128-to-64-bit reduction; see the + * code for details. By storing a mask in the otherwise unused half of + * a 128-bit constant, bits can be cleared before multiplication without + * storing and reloading. Note that staying on a 128-bit datapath means + * that some data is uselessly stored and some unused data is intersected + * with an irrelevant constant. + */ + + ((uint64_t) 0xffffffffUL), /* low of K_M_64 */ + ((uint64_t) 0xb1e6b092U << 1), /* high of K_M_64 */ + ((uint64_t) 0xba8ccbe8U << 1), /* low of K_160_96 */ + ((uint64_t) 0x6655004fU << 1), /* high of K_160_96 */ + ((uint64_t) 0xaa2215eaU << 1), /* low of K_544_480 */ + ((uint64_t) 0xe3720acbU << 1) /* high of K_544_480 */ +}; + +/** + * crc_table[] from jdk/src/share/native/java/util/zip/zlib-1.2.5/crc32.h + */ +juint StubRoutines::x86::_crc_table[] = +{ + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +}; diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86.hpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86.hpp new file mode 100644 index 00000000000..d8e52ab3b11 --- /dev/null +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86.hpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 CPU_X86_VM_STUBROUTINES_X86_HPP +#define CPU_X86_VM_STUBROUTINES_X86_HPP + +// This file holds the platform specific parts of the StubRoutines +// definition. See stubRoutines.hpp for a description on how to +// extend it. + + private: + static address _verify_mxcsr_entry; + // shuffle mask for fixing up 128-bit words consisting of big-endian 32-bit integers + static address _key_shuffle_mask_addr; + // masks and table for CRC32 + static uint64_t _crc_by128_masks[]; + static juint _crc_table[]; + + public: + static address verify_mxcsr_entry() { return _verify_mxcsr_entry; } + static address key_shuffle_mask_addr() { return _key_shuffle_mask_addr; } + static address crc_by128_masks_addr() { return (address)_crc_by128_masks; } + +#endif // CPU_X86_VM_STUBROUTINES_X86_32_HPP diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp index 65e773ed53c..53464dcccdf 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,4 @@ // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. -address StubRoutines::x86::_verify_mxcsr_entry = NULL; address StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = NULL; -address StubRoutines::x86::_key_shuffle_mask_addr = NULL; diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp index d53124fc6c8..bca5d493ce4 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,15 +39,12 @@ class x86 { friend class VMStructs; private: - static address _verify_mxcsr_entry; static address _verify_fpu_cntrl_wrd_entry; - // shuffle mask for fixing up 128-bit words consisting of big-endian 32-bit integers - static address _key_shuffle_mask_addr; public: - static address verify_mxcsr_entry() { return _verify_mxcsr_entry; } static address verify_fpu_cntrl_wrd_entry() { return _verify_fpu_cntrl_wrd_entry; } - static address key_shuffle_mask_addr() { return _key_shuffle_mask_addr; } + +# include "stubRoutines_x86.hpp" }; diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp index 9f0a94200a5..5c11734cc97 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,8 +34,6 @@ address StubRoutines::x86::_get_previous_fp_entry = NULL; address StubRoutines::x86::_get_previous_sp_entry = NULL; -address StubRoutines::x86::_verify_mxcsr_entry = NULL; - address StubRoutines::x86::_f2i_fixup = NULL; address StubRoutines::x86::_f2l_fixup = NULL; address StubRoutines::x86::_d2i_fixup = NULL; @@ -45,4 +43,3 @@ address StubRoutines::x86::_float_sign_flip = NULL; address StubRoutines::x86::_double_sign_mask = NULL; address StubRoutines::x86::_double_sign_flip = NULL; address StubRoutines::x86::_mxcsr_std = NULL; -address StubRoutines::x86::_key_shuffle_mask_addr = NULL; diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp index c3efeecb759..d63e9fdf57f 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,6 @@ class x86 { private: static address _get_previous_fp_entry; static address _get_previous_sp_entry; - static address _verify_mxcsr_entry; static address _f2i_fixup; static address _f2l_fixup; @@ -54,8 +53,6 @@ class x86 { static address _double_sign_mask; static address _double_sign_flip; static address _mxcsr_std; - // shuffle mask for fixing up 128-bit words consisting of big-endian 32-bit integers - static address _key_shuffle_mask_addr; public: @@ -69,11 +66,6 @@ class x86 { return _get_previous_sp_entry; } - static address verify_mxcsr_entry() - { - return _verify_mxcsr_entry; - } - static address f2i_fixup() { return _f2i_fixup; @@ -119,7 +111,7 @@ class x86 { return _mxcsr_std; } - static address key_shuffle_mask_addr() { return _key_shuffle_mask_addr; } +# include "stubRoutines_x86.hpp" }; diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp index 3908a8c09da..2efa59f8b33 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp @@ -868,6 +868,120 @@ address InterpreterGenerator::generate_Reference_get_entry(void) { return generate_accessor_entry(); } +/** + * Method entry for static native methods: + * int java.util.zip.CRC32.update(int crc, int b) + */ +address InterpreterGenerator::generate_CRC32_update_entry() { + if (UseCRC32Intrinsics) { + address entry = __ pc(); + + // rbx,: Method* + // rsi: senderSP must preserved for slow path, set SP to it on fast path + // rdx: scratch + // rdi: scratch + + Label slow_path; + // If we need a safepoint check, generate full interpreter entry. + ExternalAddress state(SafepointSynchronize::address_of_state()); + __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), + SafepointSynchronize::_not_synchronized); + __ jcc(Assembler::notEqual, slow_path); + + // We don't generate local frame and don't align stack because + // we call stub code and there is no safepoint on this path. + + // Load parameters + const Register crc = rax; // crc + const Register val = rdx; // source java byte value + const Register tbl = rdi; // scratch + + // Arguments are reversed on java expression stack + __ movl(val, Address(rsp, wordSize)); // byte value + __ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC + + __ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr())); + __ notl(crc); // ~crc + __ update_byte_crc32(crc, val, tbl); + __ notl(crc); // ~crc + // result in rax + + // _areturn + __ pop(rdi); // get return address + __ mov(rsp, rsi); // set sp to sender sp + __ jmp(rdi); + + // generate a vanilla native entry as the slow path + __ bind(slow_path); + + (void) generate_native_entry(false); + + return entry; + } + return generate_native_entry(false); +} + +/** + * Method entry for static native methods: + * int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len) + * int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len) + */ +address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { + if (UseCRC32Intrinsics) { + address entry = __ pc(); + + // rbx,: Method* + // rsi: senderSP must preserved for slow path, set SP to it on fast path + // rdx: scratch + // rdi: scratch + + Label slow_path; + // If we need a safepoint check, generate full interpreter entry. + ExternalAddress state(SafepointSynchronize::address_of_state()); + __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), + SafepointSynchronize::_not_synchronized); + __ jcc(Assembler::notEqual, slow_path); + + // We don't generate local frame and don't align stack because + // we call stub code and there is no safepoint on this path. + + // Load parameters + const Register crc = rax; // crc + const Register buf = rdx; // source java byte array address + const Register len = rdi; // length + + // Arguments are reversed on java expression stack + __ movl(len, Address(rsp, wordSize)); // Length + // Calculate address of start element + if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) { + __ movptr(buf, Address(rsp, 3*wordSize)); // long buf + __ addptr(buf, Address(rsp, 2*wordSize)); // + offset + __ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC + } else { + __ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array + __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size + __ addptr(buf, Address(rsp, 2*wordSize)); // + offset + __ movl(crc, Address(rsp, 4*wordSize)); // Initial CRC + } + + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len); + // result in rax + + // _areturn + __ pop(rdi); // get return address + __ mov(rsp, rsi); // set sp to sender sp + __ jmp(rdi); + + // generate a vanilla native entry as the slow path + __ bind(slow_path); + + (void) generate_native_entry(false); + + return entry; + } + return generate_native_entry(false); +} + // // Interpreter stub for calling a native method. (asm interpreter) // This sets up a somewhat different looking stack for calling the native method @@ -1501,15 +1615,16 @@ address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter: // determine code generation flags bool synchronized = false; address entry_point = NULL; + InterpreterGenerator* ig_this = (InterpreterGenerator*)this; switch (kind) { - case Interpreter::zerolocals : break; - case Interpreter::zerolocals_synchronized: synchronized = true; break; - case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break; - case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break; - case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break; - case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break; - case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break; + case Interpreter::zerolocals : break; + case Interpreter::zerolocals_synchronized: synchronized = true; break; + case Interpreter::native : entry_point = ig_this->generate_native_entry(false); break; + case Interpreter::native_synchronized : entry_point = ig_this->generate_native_entry(true); break; + case Interpreter::empty : entry_point = ig_this->generate_empty_entry(); break; + case Interpreter::accessor : entry_point = ig_this->generate_accessor_entry(); break; + case Interpreter::abstract : entry_point = ig_this->generate_abstract_entry(); break; case Interpreter::java_lang_math_sin : // fall thru case Interpreter::java_lang_math_cos : // fall thru @@ -1519,9 +1634,15 @@ address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter: case Interpreter::java_lang_math_log10 : // fall thru case Interpreter::java_lang_math_sqrt : // fall thru case Interpreter::java_lang_math_pow : // fall thru - case Interpreter::java_lang_math_exp : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind); break; + case Interpreter::java_lang_math_exp : entry_point = ig_this->generate_math_entry(kind); break; case Interpreter::java_lang_ref_reference_get - : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break; + : entry_point = ig_this->generate_Reference_get_entry(); break; + case Interpreter::java_util_zip_CRC32_update + : entry_point = ig_this->generate_CRC32_update_entry(); break; + case Interpreter::java_util_zip_CRC32_updateBytes + : // fall thru + case Interpreter::java_util_zip_CRC32_updateByteBuffer + : entry_point = ig_this->generate_CRC32_updateBytes_entry(kind); break; default: fatal(err_msg("unexpected method kind: %d", kind)); break; @@ -1529,7 +1650,7 @@ address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter: if (entry_point) return entry_point; - return ((InterpreterGenerator*)this)->generate_normal_entry(synchronized); + return ig_this->generate_normal_entry(synchronized); } diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp index 50bb8a968f6..f0a2258a70e 100644 --- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp @@ -840,6 +840,117 @@ address InterpreterGenerator::generate_Reference_get_entry(void) { return generate_accessor_entry(); } +/** + * Method entry for static native methods: + * int java.util.zip.CRC32.update(int crc, int b) + */ +address InterpreterGenerator::generate_CRC32_update_entry() { + if (UseCRC32Intrinsics) { + address entry = __ pc(); + + // rbx,: Method* + // rsi: senderSP must preserved for slow path, set SP to it on fast path + // rdx: scratch + // rdi: scratch + + Label slow_path; + // If we need a safepoint check, generate full interpreter entry. + ExternalAddress state(SafepointSynchronize::address_of_state()); + __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), + SafepointSynchronize::_not_synchronized); + __ jcc(Assembler::notEqual, slow_path); + + // We don't generate local frame and don't align stack because + // we call stub code and there is no safepoint on this path. + + // Load parameters + const Register crc = rax; // crc + const Register val = rdx; // source java byte value + const Register tbl = rdi; // scratch + + // Arguments are reversed on java expression stack + __ movl(val, Address(rsp, wordSize)); // byte value + __ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC + + __ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr())); + __ notl(crc); // ~crc + __ update_byte_crc32(crc, val, tbl); + __ notl(crc); // ~crc + // result in rax + + // _areturn + __ pop(rdi); // get return address + __ mov(rsp, rsi); // set sp to sender sp + __ jmp(rdi); + + // generate a vanilla native entry as the slow path + __ bind(slow_path); + + (void) generate_native_entry(false); + + return entry; + } + return generate_native_entry(false); +} + +/** + * Method entry for static native methods: + * int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len) + * int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len) + */ +address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { + if (UseCRC32Intrinsics) { + address entry = __ pc(); + + // rbx,: Method* + // r13: senderSP must preserved for slow path, set SP to it on fast path + + Label slow_path; + // If we need a safepoint check, generate full interpreter entry. + ExternalAddress state(SafepointSynchronize::address_of_state()); + __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), + SafepointSynchronize::_not_synchronized); + __ jcc(Assembler::notEqual, slow_path); + + // We don't generate local frame and don't align stack because + // we call stub code and there is no safepoint on this path. + + // Load parameters + const Register crc = c_rarg0; // crc + const Register buf = c_rarg1; // source java byte array address + const Register len = c_rarg2; // length + + // Arguments are reversed on java expression stack + __ movl(len, Address(rsp, wordSize)); // Length + // Calculate address of start element + if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) { + __ movptr(buf, Address(rsp, 3*wordSize)); // long buf + __ addptr(buf, Address(rsp, 2*wordSize)); // + offset + __ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC + } else { + __ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array + __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size + __ addptr(buf, Address(rsp, 2*wordSize)); // + offset + __ movl(crc, Address(rsp, 4*wordSize)); // Initial CRC + } + + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len); + // result in rax + + // _areturn + __ pop(rdi); // get return address + __ mov(rsp, r13); // set sp to sender sp + __ jmp(rdi); + + // generate a vanilla native entry as the slow path + __ bind(slow_path); + + (void) generate_native_entry(false); + + return entry; + } + return generate_native_entry(false); +} // Interpreter stub for calling a native method. (asm interpreter) // This sets up a somewhat different looking stack for calling the @@ -1510,15 +1621,16 @@ address AbstractInterpreterGenerator::generate_method_entry( // determine code generation flags bool synchronized = false; address entry_point = NULL; + InterpreterGenerator* ig_this = (InterpreterGenerator*)this; switch (kind) { - case Interpreter::zerolocals : break; - case Interpreter::zerolocals_synchronized: synchronized = true; break; - case Interpreter::native : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break; - case Interpreter::native_synchronized : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true); break; - case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break; - case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break; - case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break; + case Interpreter::zerolocals : break; + case Interpreter::zerolocals_synchronized: synchronized = true; break; + case Interpreter::native : entry_point = ig_this->generate_native_entry(false); break; + case Interpreter::native_synchronized : entry_point = ig_this->generate_native_entry(true); break; + case Interpreter::empty : entry_point = ig_this->generate_empty_entry(); break; + case Interpreter::accessor : entry_point = ig_this->generate_accessor_entry(); break; + case Interpreter::abstract : entry_point = ig_this->generate_abstract_entry(); break; case Interpreter::java_lang_math_sin : // fall thru case Interpreter::java_lang_math_cos : // fall thru @@ -1528,9 +1640,15 @@ address AbstractInterpreterGenerator::generate_method_entry( case Interpreter::java_lang_math_log10 : // fall thru case Interpreter::java_lang_math_sqrt : // fall thru case Interpreter::java_lang_math_pow : // fall thru - case Interpreter::java_lang_math_exp : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind); break; + case Interpreter::java_lang_math_exp : entry_point = ig_this->generate_math_entry(kind); break; case Interpreter::java_lang_ref_reference_get - : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break; + : entry_point = ig_this->generate_Reference_get_entry(); break; + case Interpreter::java_util_zip_CRC32_update + : entry_point = ig_this->generate_CRC32_update_entry(); break; + case Interpreter::java_util_zip_CRC32_updateBytes + : // fall thru + case Interpreter::java_util_zip_CRC32_updateByteBuffer + : entry_point = ig_this->generate_CRC32_updateBytes_entry(kind); break; default: fatal(err_msg("unexpected method kind: %d", kind)); break; @@ -1540,8 +1658,7 @@ address AbstractInterpreterGenerator::generate_method_entry( return entry_point; } - return ((InterpreterGenerator*) this)-> - generate_normal_entry(synchronized); + return ig_this->generate_normal_entry(synchronized); } // These should never be compiled since the interpreter will prefer diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp index 90066c1041a..de38b4a3a53 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -446,6 +446,7 @@ void VM_Version::get_processor_features() { (supports_avx() ? ", avx" : ""), (supports_avx2() ? ", avx2" : ""), (supports_aes() ? ", aes" : ""), + (supports_clmul() ? ", clmul" : ""), (supports_erms() ? ", erms" : ""), (supports_mmx_ext() ? ", mmxext" : ""), (supports_3dnow_prefetch() ? ", 3dnowpref" : ""), @@ -489,6 +490,27 @@ void VM_Version::get_processor_features() { FLAG_SET_DEFAULT(UseAES, false); } + // Use CLMUL instructions if available. + if (supports_clmul()) { + if (FLAG_IS_DEFAULT(UseCLMUL)) { + UseCLMUL = true; + } + } else if (UseCLMUL) { + if (!FLAG_IS_DEFAULT(UseCLMUL)) + warning("CLMUL instructions not available on this CPU (AVX may also be required)"); + FLAG_SET_DEFAULT(UseCLMUL, false); + } + + if (UseCLMUL && (UseAVX > 0) && (UseSSE > 2)) { + if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) { + UseCRC32Intrinsics = true; + } + } else if (UseCRC32Intrinsics) { + if (!FLAG_IS_DEFAULT(UseCRC32Intrinsics)) + warning("CRC32 Intrinsics requires AVX and CLMUL instructions (not available on this CPU)"); + FLAG_SET_DEFAULT(UseCRC32Intrinsics, false); + } + // The AES intrinsic stubs require AES instruction support (of course) // but also require sse3 mode for instructions it use. if (UseAES && (UseSSE > 2)) { diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp index ec8caba23f0..86e9b662d52 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,8 @@ public: uint32_t value; struct { uint32_t sse3 : 1, - : 2, + clmul : 1, + : 1, monitor : 1, : 1, vmx : 1, @@ -249,7 +250,8 @@ protected: CPU_AVX = (1 << 17), CPU_AVX2 = (1 << 18), CPU_AES = (1 << 19), - CPU_ERMS = (1 << 20) // enhanced 'rep movsb/stosb' instructions + CPU_ERMS = (1 << 20), // enhanced 'rep movsb/stosb' instructions + CPU_CLMUL = (1 << 21) // carryless multiply for CRC } cpuFeatureFlags; enum { @@ -429,6 +431,8 @@ protected: result |= CPU_AES; if (_cpuid_info.sef_cpuid7_ebx.bits.erms != 0) result |= CPU_ERMS; + if (_cpuid_info.std_cpuid1_ecx.bits.clmul != 0) + result |= CPU_CLMUL; // AMD features. if (is_amd()) { @@ -555,6 +559,7 @@ public: static bool supports_tsc() { return (_cpuFeatures & CPU_TSC) != 0; } static bool supports_aes() { return (_cpuFeatures & CPU_AES) != 0; } static bool supports_erms() { return (_cpuFeatures & CPU_ERMS) != 0; } + static bool supports_clmul() { return (_cpuFeatures & CPU_CLMUL) != 0; } // Intel features static bool is_intel_family_core() { return is_intel() && diff --git a/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp b/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp index 1d17143761a..c04b225b830 100644 --- a/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp +++ b/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp @@ -58,7 +58,9 @@ define_pd_global(intx, ReservedCodeCacheSize, 32*M ); define_pd_global(bool, ProfileInterpreter, false); define_pd_global(intx, CodeCacheExpansionSize, 32*K ); define_pd_global(uintx, CodeCacheMinBlockLength, 1 ); -define_pd_global(uintx, MetaspaceSize, 12*M ); +define_pd_global(uintx, CodeCacheMinimumUseSpace, 200*K); + +define_pd_global(uintx, MetaspaceSize, 12*M ); define_pd_global(bool, NeverActAsServerClassMachine, true ); define_pd_global(uint64_t, MaxRAM, 1ULL*G); define_pd_global(bool, CICompileOSR, true ); diff --git a/hotspot/src/os/solaris/dtrace/jhelper.d b/hotspot/src/os/solaris/dtrace/jhelper.d index 976a832107f..752f5ae535e 100644 --- a/hotspot/src/os/solaris/dtrace/jhelper.d +++ b/hotspot/src/os/solaris/dtrace/jhelper.d @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -332,12 +332,15 @@ dtrace:helper:ustack: this->nameSymbol = copyin_ptr(this->constantPool + this->nameIndex * sizeof (pointer) + SIZE_ConstantPool); + /* The symbol is a CPSlot and has lower bit set to indicate metadata */ + this->nameSymbol &= (~1); /* remove metadata lsb */ this->nameSymbolLength = copyin_uint16(this->nameSymbol + OFFSET_Symbol_length); this->signatureSymbol = copyin_ptr(this->constantPool + this->signatureIndex * sizeof (pointer) + SIZE_ConstantPool); + this->signatureSymbol &= (~1); /* remove metadata lsb */ this->signatureSymbolLength = copyin_uint16(this->signatureSymbol + OFFSET_Symbol_length); diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp index 8d7619eedd6..b84c8911e4c 100644 --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3461,6 +3461,14 @@ bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) { preserves_state = true; break; + case vmIntrinsics::_updateCRC32: + case vmIntrinsics::_updateBytesCRC32: + case vmIntrinsics::_updateByteBufferCRC32: + if (!UseCRC32Intrinsics) return false; + cantrap = false; + preserves_state = true; + break; + case vmIntrinsics::_loadFence : case vmIntrinsics::_storeFence: case vmIntrinsics::_fullFence : diff --git a/hotspot/src/share/vm/c1/c1_LIR.cpp b/hotspot/src/share/vm/c1/c1_LIR.cpp index e2611534ea1..cb0ceab90c0 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.cpp +++ b/hotspot/src/share/vm/c1/c1_LIR.cpp @@ -430,6 +430,11 @@ LIR_OpArrayCopy::LIR_OpArrayCopy(LIR_Opr src, LIR_Opr src_pos, LIR_Opr dst, LIR_ _stub = new ArrayCopyStub(this); } +LIR_OpUpdateCRC32::LIR_OpUpdateCRC32(LIR_Opr crc, LIR_Opr val, LIR_Opr res) + : LIR_Op(lir_updatecrc32, res, NULL) + , _crc(crc) + , _val(val) { +} //-------------------verify-------------------------- @@ -876,6 +881,20 @@ void LIR_OpVisitState::visit(LIR_Op* op) { } +// LIR_OpUpdateCRC32 + case lir_updatecrc32: { + assert(op->as_OpUpdateCRC32() != NULL, "must be"); + LIR_OpUpdateCRC32* opUp = (LIR_OpUpdateCRC32*)op; + + assert(opUp->_crc->is_valid(), "used"); do_input(opUp->_crc); do_temp(opUp->_crc); + assert(opUp->_val->is_valid(), "used"); do_input(opUp->_val); do_temp(opUp->_val); + assert(opUp->_result->is_valid(), "used"); do_output(opUp->_result); + assert(opUp->_info == NULL, "no info for LIR_OpUpdateCRC32"); + + break; + } + + // LIR_OpLock case lir_lock: case lir_unlock: { @@ -1056,6 +1075,10 @@ void LIR_OpArrayCopy::emit_code(LIR_Assembler* masm) { masm->emit_code_stub(stub()); } +void LIR_OpUpdateCRC32::emit_code(LIR_Assembler* masm) { + masm->emit_updatecrc32(this); +} + void LIR_Op0::emit_code(LIR_Assembler* masm) { masm->emit_op0(this); } @@ -1763,6 +1786,8 @@ const char * LIR_Op::name() const { case lir_dynamic_call: s = "dynamic"; break; // LIR_OpArrayCopy case lir_arraycopy: s = "arraycopy"; break; + // LIR_OpUpdateCRC32 + case lir_updatecrc32: s = "updatecrc32"; break; // LIR_OpLock case lir_lock: s = "lock"; break; case lir_unlock: s = "unlock"; break; @@ -1815,6 +1840,13 @@ void LIR_OpArrayCopy::print_instr(outputStream* out) const { tmp()->print(out); out->print(" "); } +// LIR_OpUpdateCRC32 +void LIR_OpUpdateCRC32::print_instr(outputStream* out) const { + crc()->print(out); out->print(" "); + val()->print(out); out->print(" "); + result_opr()->print(out); out->print(" "); +} + // LIR_OpCompareAndSwap void LIR_OpCompareAndSwap::print_instr(outputStream* out) const { addr()->print(out); out->print(" "); diff --git a/hotspot/src/share/vm/c1/c1_LIR.hpp b/hotspot/src/share/vm/c1/c1_LIR.hpp index 61dd59e3fe9..fab85e5750f 100644 --- a/hotspot/src/share/vm/c1/c1_LIR.hpp +++ b/hotspot/src/share/vm/c1/c1_LIR.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -877,6 +877,7 @@ class LIR_OpCall; class LIR_OpJavaCall; class LIR_OpRTCall; class LIR_OpArrayCopy; +class LIR_OpUpdateCRC32; class LIR_OpLock; class LIR_OpTypeCheck; class LIR_OpCompareAndSwap; @@ -982,6 +983,9 @@ enum LIR_Code { , begin_opArrayCopy , lir_arraycopy , end_opArrayCopy + , begin_opUpdateCRC32 + , lir_updatecrc32 + , end_opUpdateCRC32 , begin_opLock , lir_lock , lir_unlock @@ -1137,6 +1141,7 @@ class LIR_Op: public CompilationResourceObj { virtual LIR_Op2* as_Op2() { return NULL; } virtual LIR_Op3* as_Op3() { return NULL; } virtual LIR_OpArrayCopy* as_OpArrayCopy() { return NULL; } + virtual LIR_OpUpdateCRC32* as_OpUpdateCRC32() { return NULL; } virtual LIR_OpTypeCheck* as_OpTypeCheck() { return NULL; } virtual LIR_OpCompareAndSwap* as_OpCompareAndSwap() { return NULL; } virtual LIR_OpProfileCall* as_OpProfileCall() { return NULL; } @@ -1293,6 +1298,25 @@ public: void print_instr(outputStream* out) const PRODUCT_RETURN; }; +// LIR_OpUpdateCRC32 +class LIR_OpUpdateCRC32: public LIR_Op { + friend class LIR_OpVisitState; + +private: + LIR_Opr _crc; + LIR_Opr _val; + +public: + + LIR_OpUpdateCRC32(LIR_Opr crc, LIR_Opr val, LIR_Opr res); + + LIR_Opr crc() const { return _crc; } + LIR_Opr val() const { return _val; } + + virtual void emit_code(LIR_Assembler* masm); + virtual LIR_OpUpdateCRC32* as_OpUpdateCRC32() { return this; } + void print_instr(outputStream* out) const PRODUCT_RETURN; +}; // -------------------------------------------------- // LIR_Op0 @@ -2212,6 +2236,8 @@ class LIR_List: public CompilationResourceObj { void arraycopy(LIR_Opr src, LIR_Opr src_pos, LIR_Opr dst, LIR_Opr dst_pos, LIR_Opr length, LIR_Opr tmp, ciArrayKlass* expected_type, int flags, CodeEmitInfo* info) { append(new LIR_OpArrayCopy(src, src_pos, dst, dst_pos, length, tmp, expected_type, flags, info)); } + void update_crc32(LIR_Opr crc, LIR_Opr val, LIR_Opr res) { append(new LIR_OpUpdateCRC32(crc, val, res)); } + void fpop_raw() { append(new LIR_Op0(lir_fpop_raw)); } void instanceof(LIR_Opr result, LIR_Opr object, ciKlass* klass, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, bool fast_check, CodeEmitInfo* info_for_patch, ciMethod* profiled_method, int profiled_bci); diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp index 87dd8dbae15..4ced297c07b 100644 --- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -195,6 +195,7 @@ class LIR_Assembler: public CompilationResourceObj { void emit_opBranch(LIR_OpBranch* op); void emit_opLabel(LIR_OpLabel* op); void emit_arraycopy(LIR_OpArrayCopy* op); + void emit_updatecrc32(LIR_OpUpdateCRC32* op); void emit_opConvert(LIR_OpConvert* op); void emit_alloc_obj(LIR_OpAllocObj* op); void emit_alloc_array(LIR_OpAllocArray* op); diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp index fcd6910ed95..3af2d23b7d6 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp @@ -2994,6 +2994,12 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) { do_Reference_get(x); break; + case vmIntrinsics::_updateCRC32: + case vmIntrinsics::_updateBytesCRC32: + case vmIntrinsics::_updateByteBufferCRC32: + do_update_CRC32(x); + break; + default: ShouldNotReachHere(); break; } } diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp index d3c76865dbd..0a029207308 100644 --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -247,6 +247,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure { void do_NIOCheckIndex(Intrinsic* x); void do_FPIntrinsics(Intrinsic* x); void do_Reference_get(Intrinsic* x); + void do_update_CRC32(Intrinsic* x); void do_UnsafePrefetch(UnsafePrefetch* x, bool is_store); diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index 53d1f5326a8..908571f6cc4 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -299,6 +299,7 @@ const char* Runtime1::name_for_address(address entry) { #ifdef TRACE_HAVE_INTRINSICS FUNCTION_CASE(entry, TRACE_TIME_METHOD); #endif + FUNCTION_CASE(entry, StubRoutines::updateBytesCRC32()); #undef FUNCTION_CASE diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index 49def1e8d26..7ec43bd7e86 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -771,6 +771,17 @@ do_name( decrypt_name, "decrypt") \ do_signature(byteArray_int_int_byteArray_int_signature, "([BII[BI)V") \ \ + /* support for java.util.zip */ \ + do_class(java_util_zip_CRC32, "java/util/zip/CRC32") \ + do_intrinsic(_updateCRC32, java_util_zip_CRC32, update_name, int2_int_signature, F_SN) \ + do_name( update_name, "update") \ + do_intrinsic(_updateBytesCRC32, java_util_zip_CRC32, updateBytes_name, updateBytes_signature, F_SN) \ + do_name( updateBytes_name, "updateBytes") \ + do_signature(updateBytes_signature, "(I[BII)I") \ + do_intrinsic(_updateByteBufferCRC32, java_util_zip_CRC32, updateByteBuffer_name, updateByteBuffer_signature, F_SN) \ + do_name( updateByteBuffer_name, "updateByteBuffer") \ + do_signature(updateByteBuffer_signature, "(IJII)I") \ + \ /* support for sun.misc.Unsafe */ \ do_class(sun_misc_Unsafe, "sun/misc/Unsafe") \ \ diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp index 00ea5b54850..f75e518facc 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp @@ -152,12 +152,9 @@ uint G1CardCounts::add_card_count(jbyte* card_ptr) { if (card_num < _committed_max_card_num) { count = (uint) _card_counts[card_num]; if (count < G1ConcRSHotCardLimit) { - _card_counts[card_num] += 1; + _card_counts[card_num] = + (jubyte)(MIN2((uintx)(_card_counts[card_num] + 1), G1ConcRSHotCardLimit)); } - assert(_card_counts[card_num] <= G1ConcRSHotCardLimit, - err_msg("Refinement count overflow? " - "new count: "UINT32_FORMAT, - (uint) _card_counts[card_num])); } } return count; diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp index 9cee1eb1ba2..218be0c0e40 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp @@ -47,7 +47,7 @@ void G1SATBCardTableModRefBS::enqueue(oop pre_val) { JavaThread* jt = (JavaThread*)thr; jt->satb_mark_queue().enqueue(pre_val); } else { - MutexLocker x(Shared_SATB_Q_lock); + MutexLockerEx x(Shared_SATB_Q_lock, Mutex::_no_safepoint_check_flag); JavaThread::satb_mark_queue_set().shared_satb_queue()->enqueue(pre_val); } } diff --git a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp index 264d4fffbf6..77471ad3d5f 100644 --- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp +++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * 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,9 @@ class AbstractInterpreter: AllStatic { java_lang_math_pow, // implementation of java.lang.Math.pow (x,y) java_lang_math_exp, // implementation of java.lang.Math.exp (x) java_lang_ref_reference_get, // implementation of java.lang.ref.Reference.get() + java_util_zip_CRC32_update, // implementation of java.util.zip.CRC32.update() + java_util_zip_CRC32_updateBytes, // implementation of java.util.zip.CRC32.updateBytes() + java_util_zip_CRC32_updateByteBuffer, // implementation of java.util.zip.CRC32.updateByteBuffer() number_of_method_entries, invalid = -1 }; diff --git a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp index b51ba870568..538b836f08a 100644 --- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp +++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp @@ -1581,7 +1581,7 @@ run: #define ARRAY_LOADTO32(T, T2, format, stackRes, extra) \ { \ ARRAY_INTRO(-2); \ - extra; \ + (void)extra; \ SET_ ## stackRes(*(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)), \ -2); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ @@ -1592,8 +1592,8 @@ run: { \ ARRAY_INTRO(-2); \ SET_ ## stackRes(*(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)), -1); \ - extra; \ - UPDATE_PC_AND_CONTINUE(1); \ + (void)extra; \ + UPDATE_PC_AND_CONTINUE(1); \ } CASE(_iaload): @@ -1617,7 +1617,7 @@ run: #define ARRAY_STOREFROM32(T, T2, format, stackSrc, extra) \ { \ ARRAY_INTRO(-3); \ - extra; \ + (void)extra; \ *(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)) = stackSrc( -1); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); \ } @@ -1626,7 +1626,7 @@ run: #define ARRAY_STOREFROM64(T, T2, stackSrc, extra) \ { \ ARRAY_INTRO(-4); \ - extra; \ + (void)extra; \ *(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)) = stackSrc( -1); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -4); \ } diff --git a/hotspot/src/share/vm/interpreter/interpreter.cpp b/hotspot/src/share/vm/interpreter/interpreter.cpp index 06554172bf1..dfd8b5b145a 100644 --- a/hotspot/src/share/vm/interpreter/interpreter.cpp +++ b/hotspot/src/share/vm/interpreter/interpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -195,6 +195,17 @@ AbstractInterpreter::MethodKind AbstractInterpreter::method_kind(methodHandle m) return kind; } +#ifndef CC_INTERP + if (UseCRC32Intrinsics && m->is_native()) { + // Use optimized stub code for CRC32 native methods. + switch (m->intrinsic_id()) { + case vmIntrinsics::_updateCRC32 : return java_util_zip_CRC32_update; + case vmIntrinsics::_updateBytesCRC32 : return java_util_zip_CRC32_updateBytes; + case vmIntrinsics::_updateByteBufferCRC32 : return java_util_zip_CRC32_updateByteBuffer; + } + } +#endif + // Native method? // Note: This test must come _before_ the test for intrinsic // methods. See also comments below. @@ -297,6 +308,9 @@ void AbstractInterpreter::print_method_kind(MethodKind kind) { case java_lang_math_sqrt : tty->print("java_lang_math_sqrt" ); break; case java_lang_math_log : tty->print("java_lang_math_log" ); break; case java_lang_math_log10 : tty->print("java_lang_math_log10" ); break; + case java_util_zip_CRC32_update : tty->print("java_util_zip_CRC32_update"); break; + case java_util_zip_CRC32_updateBytes : tty->print("java_util_zip_CRC32_updateBytes"); break; + case java_util_zip_CRC32_updateByteBuffer : tty->print("java_util_zip_CRC32_updateByteBuffer"); break; default: if (kind >= method_handle_invoke_FIRST && kind <= method_handle_invoke_LAST) { diff --git a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp index 53e50b1c7fe..9f7ed4c7e97 100644 --- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp +++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -373,6 +373,12 @@ void TemplateInterpreterGenerator::generate_all() { method_entry(java_lang_math_pow ) method_entry(java_lang_ref_reference_get) + if (UseCRC32Intrinsics) { + method_entry(java_util_zip_CRC32_update) + method_entry(java_util_zip_CRC32_updateBytes) + method_entry(java_util_zip_CRC32_updateByteBuffer) + } + initialize_method_handle_entries(); // all native method kinds (must be one contiguous block) diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp index dbc0c87edce..5dfaf6f9701 100644 --- a/hotspot/src/share/vm/memory/filemap.cpp +++ b/hotspot/src/share/vm/memory/filemap.cpp @@ -549,3 +549,13 @@ bool FileMapInfo::is_in_shared_space(const void* p) { return false; } + +void FileMapInfo::print_shared_spaces() { + gclog_or_tty->print_cr("Shared Spaces:"); + for (int i = 0; i < MetaspaceShared::n_regions; i++) { + struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; + gclog_or_tty->print(" %s " INTPTR_FORMAT "-" INTPTR_FORMAT, + shared_region_name[i], + si->_base, si->_base + si->_used); + } +} diff --git a/hotspot/src/share/vm/memory/filemap.hpp b/hotspot/src/share/vm/memory/filemap.hpp index a11914b9c01..ee4ccec5bfe 100644 --- a/hotspot/src/share/vm/memory/filemap.hpp +++ b/hotspot/src/share/vm/memory/filemap.hpp @@ -149,6 +149,7 @@ public: // Return true if given address is in the mapped shared space. bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false); + void print_shared_spaces() NOT_CDS_RETURN; }; #endif // SHARE_VM_MEMORY_FILEMAP_HPP diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp index 638f848513a..1522eddb76b 100644 --- a/hotspot/src/share/vm/memory/metaspace.cpp +++ b/hotspot/src/share/vm/memory/metaspace.cpp @@ -70,7 +70,7 @@ enum ChunkSizes { // in words. SpecializedChunk = 128, ClassSmallChunk = 256, SmallChunk = 512, - ClassMediumChunk = 1 * K, + ClassMediumChunk = 4 * K, MediumChunk = 8 * K, HumongousChunkGranularity = 8 }; @@ -580,7 +580,6 @@ class SpaceManager : public CHeapObj { // Number of small chunks to allocate to a manager // If class space manager, small chunks are unlimited static uint const _small_chunk_limit; - bool has_small_chunk_limit() { return !vs_list()->is_class(); } // Sum of all space in allocated chunks size_t _allocated_blocks_words; @@ -1298,13 +1297,18 @@ size_t MetaspaceGC::delta_capacity_until_GC(size_t word_size) { bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) { - size_t committed_capacity_bytes = MetaspaceAux::allocated_capacity_bytes(); // If the user wants a limit, impose one. - size_t max_metaspace_size_bytes = MaxMetaspaceSize; - size_t metaspace_size_bytes = MetaspaceSize; - if (!FLAG_IS_DEFAULT(MaxMetaspaceSize) && - MetaspaceAux::reserved_in_bytes() >= MaxMetaspaceSize) { - return false; + // The reason for someone using this flag is to limit reserved space. So + // for non-class virtual space, compare against virtual spaces that are reserved. + // For class virtual space, we only compare against the committed space, not + // reserved space, because this is a larger space prereserved for compressed + // class pointers. + if (!FLAG_IS_DEFAULT(MaxMetaspaceSize)) { + size_t real_allocated = Metaspace::space_list()->virtual_space_total() + + MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType); + if (real_allocated >= MaxMetaspaceSize) { + return false; + } } // Class virtual space should always be expanded. Call GC for the other @@ -1318,11 +1322,12 @@ bool MetaspaceGC::should_expand(VirtualSpaceList* vsl, size_t word_size) { } - // If the capacity is below the minimum capacity, allow the // expansion. Also set the high-water-mark (capacity_until_GC) // to that minimum capacity so that a GC will not be induced // until that minimum capacity is exceeded. + size_t committed_capacity_bytes = MetaspaceAux::allocated_capacity_bytes(); + size_t metaspace_size_bytes = MetaspaceSize; if (committed_capacity_bytes < metaspace_size_bytes || capacity_until_GC() == 0) { set_capacity_until_GC(metaspace_size_bytes); @@ -1854,13 +1859,11 @@ size_t SpaceManager::sum_waste_in_chunks_in_use(ChunkIndex index) const { Metachunk* chunk = chunks_in_use(index); // Count the free space in all the chunk but not the // current chunk from which allocations are still being done. - if (chunk != NULL) { - Metachunk* prev = chunk; - while (chunk != NULL && chunk != current_chunk()) { + while (chunk != NULL) { + if (chunk != current_chunk()) { result += chunk->free_word_size(); - prev = chunk; - chunk = chunk->next(); } + chunk = chunk->next(); } return result; } @@ -1949,8 +1952,7 @@ size_t SpaceManager::calc_chunk_size(size_t word_size) { // chunks will be allocated. size_t chunk_word_size; if (chunks_in_use(MediumIndex) == NULL && - (!has_small_chunk_limit() || - sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit)) { + sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) { chunk_word_size = (size_t) small_chunk_size(); if (word_size + Metachunk::overhead() > small_chunk_size()) { chunk_word_size = medium_chunk_size(); @@ -2659,10 +2661,10 @@ void MetaspaceAux::print_on(outputStream* out, Metaspace::MetadataType mdtype) { // Print total fragmentation for class and data metaspaces separately void MetaspaceAux::print_waste(outputStream* out) { - size_t specialized_waste = 0, small_waste = 0, medium_waste = 0, large_waste = 0; - size_t specialized_count = 0, small_count = 0, medium_count = 0, large_count = 0; - size_t cls_specialized_waste = 0, cls_small_waste = 0, cls_medium_waste = 0, cls_large_waste = 0; - size_t cls_specialized_count = 0, cls_small_count = 0, cls_medium_count = 0, cls_large_count = 0; + size_t specialized_waste = 0, small_waste = 0, medium_waste = 0; + size_t specialized_count = 0, small_count = 0, medium_count = 0, humongous_count = 0; + size_t cls_specialized_waste = 0, cls_small_waste = 0, cls_medium_waste = 0; + size_t cls_specialized_count = 0, cls_small_count = 0, cls_medium_count = 0, cls_humongous_count = 0; ClassLoaderDataGraphMetaspaceIterator iter; while (iter.repeat()) { @@ -2674,8 +2676,7 @@ void MetaspaceAux::print_waste(outputStream* out) { small_count += msp->vsm()->sum_count_in_chunks_in_use(SmallIndex); medium_waste += msp->vsm()->sum_waste_in_chunks_in_use(MediumIndex); medium_count += msp->vsm()->sum_count_in_chunks_in_use(MediumIndex); - large_waste += msp->vsm()->sum_waste_in_chunks_in_use(HumongousIndex); - large_count += msp->vsm()->sum_count_in_chunks_in_use(HumongousIndex); + humongous_count += msp->vsm()->sum_count_in_chunks_in_use(HumongousIndex); cls_specialized_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(SpecializedIndex); cls_specialized_count += msp->class_vsm()->sum_count_in_chunks_in_use(SpecializedIndex); @@ -2683,20 +2684,23 @@ void MetaspaceAux::print_waste(outputStream* out) { cls_small_count += msp->class_vsm()->sum_count_in_chunks_in_use(SmallIndex); cls_medium_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(MediumIndex); cls_medium_count += msp->class_vsm()->sum_count_in_chunks_in_use(MediumIndex); - cls_large_waste += msp->class_vsm()->sum_waste_in_chunks_in_use(HumongousIndex); - cls_large_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex); + cls_humongous_count += msp->class_vsm()->sum_count_in_chunks_in_use(HumongousIndex); } } out->print_cr("Total fragmentation waste (words) doesn't count free space"); out->print_cr(" data: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", " SIZE_FORMAT " small(s) " SIZE_FORMAT ", " - SIZE_FORMAT " medium(s) " SIZE_FORMAT, + SIZE_FORMAT " medium(s) " SIZE_FORMAT ", " + "large count " SIZE_FORMAT, specialized_count, specialized_waste, small_count, - small_waste, medium_count, medium_waste); + small_waste, medium_count, medium_waste, humongous_count); out->print_cr(" class: " SIZE_FORMAT " specialized(s) " SIZE_FORMAT ", " - SIZE_FORMAT " small(s) " SIZE_FORMAT, + SIZE_FORMAT " small(s) " SIZE_FORMAT ", " + SIZE_FORMAT " medium(s) " SIZE_FORMAT ", " + "large count " SIZE_FORMAT, cls_specialized_count, cls_specialized_waste, - cls_small_count, cls_small_waste); + cls_small_count, cls_small_waste, + cls_medium_count, cls_medium_waste, cls_humongous_count); } // Dump global metaspace things from the end of ClassLoaderDataGraph @@ -3037,18 +3041,24 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size, if (Verbose && TraceMetadataChunkAllocation) { gclog_or_tty->print_cr("Metaspace allocation failed for size " SIZE_FORMAT, word_size); - if (loader_data->metaspace_or_null() != NULL) loader_data->metaspace_or_null()->dump(gclog_or_tty); + if (loader_data->metaspace_or_null() != NULL) loader_data->dump(gclog_or_tty); MetaspaceAux::dump(gclog_or_tty); } // -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError support - report_java_out_of_memory("Metadata space"); + const char* space_string = (mdtype == ClassType) ? "Class Metadata space" : + "Metadata space"; + report_java_out_of_memory(space_string); if (JvmtiExport::should_post_resource_exhausted()) { JvmtiExport::post_resource_exhausted( JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR, - "Metadata space"); + space_string); + } + if (mdtype == ClassType) { + THROW_OOP_0(Universe::out_of_memory_error_class_metaspace()); + } else { + THROW_OOP_0(Universe::out_of_memory_error_metaspace()); } - THROW_OOP_0(Universe::out_of_memory_error_perm_gen()); } } return Metablock::initialize(result, word_size); diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp index d2c91827485..c7d61f7b732 100644 --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp @@ -826,35 +826,15 @@ public: bool reading() const { return true; } }; - -// Save bounds of shared spaces mapped in. -static char* _ro_base = NULL; -static char* _rw_base = NULL; -static char* _md_base = NULL; -static char* _mc_base = NULL; - // Return true if given address is in the mapped shared space. bool MetaspaceShared::is_in_shared_space(const void* p) { - if (_ro_base == NULL || _rw_base == NULL) { - return false; - } else { - return ((p >= _ro_base && p < (_ro_base + SharedReadOnlySize)) || - (p >= _rw_base && p < (_rw_base + SharedReadWriteSize))); - } + return UseSharedSpaces && FileMapInfo::current_info()->is_in_shared_space(p); } void MetaspaceShared::print_shared_spaces() { - gclog_or_tty->print_cr("Shared Spaces:"); - gclog_or_tty->print(" read-only " INTPTR_FORMAT "-" INTPTR_FORMAT, - _ro_base, _ro_base + SharedReadOnlySize); - gclog_or_tty->print(" read-write " INTPTR_FORMAT "-" INTPTR_FORMAT, - _rw_base, _rw_base + SharedReadWriteSize); - gclog_or_tty->cr(); - gclog_or_tty->print(" misc-data " INTPTR_FORMAT "-" INTPTR_FORMAT, - _md_base, _md_base + SharedMiscDataSize); - gclog_or_tty->print(" misc-code " INTPTR_FORMAT "-" INTPTR_FORMAT, - _mc_base, _mc_base + SharedMiscCodeSize); - gclog_or_tty->cr(); + if (UseSharedSpaces) { + FileMapInfo::current_info()->print_shared_spaces(); + } } @@ -874,6 +854,11 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) { assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces"); + char* _ro_base = NULL; + char* _rw_base = NULL; + char* _md_base = NULL; + char* _mc_base = NULL; + // Map each shared region if ((_ro_base = mapinfo->map_region(ro)) != NULL && (_rw_base = mapinfo->map_region(rw)) != NULL && diff --git a/hotspot/src/share/vm/memory/referenceProcessorStats.hpp b/hotspot/src/share/vm/memory/referenceProcessorStats.hpp index 73208331bac..7497c09b92f 100644 --- a/hotspot/src/share/vm/memory/referenceProcessorStats.hpp +++ b/hotspot/src/share/vm/memory/referenceProcessorStats.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp index b443310b3c3..3514886d0d9 100644 --- a/hotspot/src/share/vm/memory/universe.cpp +++ b/hotspot/src/share/vm/memory/universe.cpp @@ -111,7 +111,8 @@ LatestMethodOopCache* Universe::_loader_addClass_cache = NULL; LatestMethodOopCache* Universe::_pd_implies_cache = NULL; ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL; oop Universe::_out_of_memory_error_java_heap = NULL; -oop Universe::_out_of_memory_error_perm_gen = NULL; +oop Universe::_out_of_memory_error_metaspace = NULL; +oop Universe::_out_of_memory_error_class_metaspace = NULL; oop Universe::_out_of_memory_error_array_size = NULL; oop Universe::_out_of_memory_error_gc_overhead_limit = NULL; objArrayOop Universe::_preallocated_out_of_memory_error_array = NULL; @@ -180,7 +181,8 @@ void Universe::oops_do(OopClosure* f, bool do_all) { f->do_oop((oop*)&_the_null_string); f->do_oop((oop*)&_the_min_jint_string); f->do_oop((oop*)&_out_of_memory_error_java_heap); - f->do_oop((oop*)&_out_of_memory_error_perm_gen); + f->do_oop((oop*)&_out_of_memory_error_metaspace); + f->do_oop((oop*)&_out_of_memory_error_class_metaspace); f->do_oop((oop*)&_out_of_memory_error_array_size); f->do_oop((oop*)&_out_of_memory_error_gc_overhead_limit); f->do_oop((oop*)&_preallocated_out_of_memory_error_array); @@ -563,7 +565,8 @@ bool Universe::should_fill_in_stack_trace(Handle throwable) { // a potential loop which could happen if an out of memory occurs when attempting // to allocate the backtrace. return ((throwable() != Universe::_out_of_memory_error_java_heap) && - (throwable() != Universe::_out_of_memory_error_perm_gen) && + (throwable() != Universe::_out_of_memory_error_metaspace) && + (throwable() != Universe::_out_of_memory_error_class_metaspace) && (throwable() != Universe::_out_of_memory_error_array_size) && (throwable() != Universe::_out_of_memory_error_gc_overhead_limit)); } @@ -1014,7 +1017,8 @@ bool universe_post_init() { k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_OutOfMemoryError(), true, CHECK_false); k_h = instanceKlassHandle(THREAD, k); Universe::_out_of_memory_error_java_heap = k_h->allocate_instance(CHECK_false); - Universe::_out_of_memory_error_perm_gen = k_h->allocate_instance(CHECK_false); + Universe::_out_of_memory_error_metaspace = k_h->allocate_instance(CHECK_false); + Universe::_out_of_memory_error_class_metaspace = k_h->allocate_instance(CHECK_false); Universe::_out_of_memory_error_array_size = k_h->allocate_instance(CHECK_false); Universe::_out_of_memory_error_gc_overhead_limit = k_h->allocate_instance(CHECK_false); @@ -1047,7 +1051,9 @@ bool universe_post_init() { java_lang_Throwable::set_message(Universe::_out_of_memory_error_java_heap, msg()); msg = java_lang_String::create_from_str("Metadata space", CHECK_false); - java_lang_Throwable::set_message(Universe::_out_of_memory_error_perm_gen, msg()); + java_lang_Throwable::set_message(Universe::_out_of_memory_error_metaspace, msg()); + msg = java_lang_String::create_from_str("Class Metadata space", CHECK_false); + java_lang_Throwable::set_message(Universe::_out_of_memory_error_class_metaspace, msg()); msg = java_lang_String::create_from_str("Requested array size exceeds VM limit", CHECK_false); java_lang_Throwable::set_message(Universe::_out_of_memory_error_array_size, msg()); diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp index 85397960f8c..24a95e84594 100644 --- a/hotspot/src/share/vm/memory/universe.hpp +++ b/hotspot/src/share/vm/memory/universe.hpp @@ -178,10 +178,12 @@ class Universe: AllStatic { static LatestMethodOopCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector static LatestMethodOopCache* _pd_implies_cache; // method for checking protection domain attributes static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks - static oop _out_of_memory_error_java_heap; // preallocated error object (no backtrace) - static oop _out_of_memory_error_perm_gen; // preallocated error object (no backtrace) - static oop _out_of_memory_error_array_size;// preallocated error object (no backtrace) - static oop _out_of_memory_error_gc_overhead_limit; // preallocated error object (no backtrace) + // preallocated error objects (no backtrace) + static oop _out_of_memory_error_java_heap; + static oop _out_of_memory_error_metaspace; + static oop _out_of_memory_error_class_metaspace; + static oop _out_of_memory_error_array_size; + static oop _out_of_memory_error_gc_overhead_limit; static Array* _the_empty_int_array; // Canonicalized int array static Array* _the_empty_short_array; // Canonicalized short array @@ -352,7 +354,8 @@ class Universe: AllStatic { // may or may not have a backtrace. If error has a backtrace then the stack trace is already // filled in. static oop out_of_memory_error_java_heap() { return gen_out_of_memory_error(_out_of_memory_error_java_heap); } - static oop out_of_memory_error_perm_gen() { return gen_out_of_memory_error(_out_of_memory_error_perm_gen); } + static oop out_of_memory_error_metaspace() { return gen_out_of_memory_error(_out_of_memory_error_metaspace); } + static oop out_of_memory_error_class_metaspace() { return gen_out_of_memory_error(_out_of_memory_error_class_metaspace); } static oop out_of_memory_error_array_size() { return gen_out_of_memory_error(_out_of_memory_error_array_size); } static oop out_of_memory_error_gc_overhead_limit() { return gen_out_of_memory_error(_out_of_memory_error_gc_overhead_limit); } diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index fd561a0c20c..c95226f110c 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -933,6 +933,7 @@ void ConnectionGraph::process_call_arguments(CallNode *call) { (call->as_CallLeaf()->_name != NULL && (strcmp(call->as_CallLeaf()->_name, "g1_wb_pre") == 0 || strcmp(call->as_CallLeaf()->_name, "g1_wb_post") == 0 || + strcmp(call->as_CallLeaf()->_name, "updateBytesCRC32") == 0 || strcmp(call->as_CallLeaf()->_name, "aescrypt_encryptBlock") == 0 || strcmp(call->as_CallLeaf()->_name, "aescrypt_decryptBlock") == 0 || strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_encryptAESCrypt") == 0 || diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index 590770b7c72..a363b11a5b8 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -3332,9 +3332,14 @@ AllocateNode* AllocateNode::Ideal_allocation(Node* ptr, PhaseTransform* phase) { if (ptr == NULL) { // reduce dumb test in callers return NULL; } - ptr = ptr->uncast(); // strip a raw-to-oop cast - if (ptr == NULL) return NULL; - + if (ptr->is_CheckCastPP()) { // strip only one raw-to-oop cast + ptr = ptr->in(1); + if (ptr == NULL) return NULL; + } + // Return NULL for allocations with several casts: + // j.l.reflect.Array.newInstance(jobject, jint) + // Object.clone() + // to keep more precise type from last cast. if (ptr->is_Proj()) { Node* allo = ptr->in(0); if (allo != NULL && allo->is_Allocate()) { diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 728d892534b..df84634832a 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -291,6 +291,9 @@ class LibraryCallKit : public GraphKit { Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting); Node* get_key_start_from_aescrypt_object(Node* aescrypt_object); bool inline_encodeISOArray(); + bool inline_updateCRC32(); + bool inline_updateBytesCRC32(); + bool inline_updateByteBufferCRC32(); }; @@ -488,6 +491,12 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { is_predicted = true; break; + case vmIntrinsics::_updateCRC32: + case vmIntrinsics::_updateBytesCRC32: + case vmIntrinsics::_updateByteBufferCRC32: + if (!UseCRC32Intrinsics) return NULL; + break; + default: assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility"); assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?"); @@ -807,6 +816,13 @@ bool LibraryCallKit::try_to_inline() { case vmIntrinsics::_encodeISOArray: return inline_encodeISOArray(); + case vmIntrinsics::_updateCRC32: + return inline_updateCRC32(); + case vmIntrinsics::_updateBytesCRC32: + return inline_updateBytesCRC32(); + case vmIntrinsics::_updateByteBufferCRC32: + return inline_updateByteBufferCRC32(); + default: // If you get here, it may be that someone has added a new intrinsic // to the list in vmSymbols.hpp without implementing it here. @@ -884,7 +900,7 @@ Node* LibraryCallKit::generate_guard(Node* test, RegionNode* region, float true_ IfNode* iff = create_and_map_if(control(), test, true_prob, COUNT_UNKNOWN); - Node* if_slow = _gvn.transform( new (C) IfTrueNode(iff) ); + Node* if_slow = _gvn.transform(new (C) IfTrueNode(iff)); if (if_slow == top()) { // The slow branch is never taken. No need to build this guard. return NULL; @@ -893,7 +909,7 @@ Node* LibraryCallKit::generate_guard(Node* test, RegionNode* region, float true_ if (region != NULL) region->add_req(if_slow); - Node* if_fast = _gvn.transform( new (C) IfFalseNode(iff) ); + Node* if_fast = _gvn.transform(new (C) IfFalseNode(iff)); set_control(if_fast); return if_slow; @@ -912,8 +928,8 @@ inline Node* LibraryCallKit::generate_negative_guard(Node* index, RegionNode* re return NULL; // already stopped if (_gvn.type(index)->higher_equal(TypeInt::POS)) // [0,maxint] return NULL; // index is already adequately typed - Node* cmp_lt = _gvn.transform( new (C) CmpINode(index, intcon(0)) ); - Node* bol_lt = _gvn.transform( new (C) BoolNode(cmp_lt, BoolTest::lt) ); + Node* cmp_lt = _gvn.transform(new (C) CmpINode(index, intcon(0))); + Node* bol_lt = _gvn.transform(new (C) BoolNode(cmp_lt, BoolTest::lt)); Node* is_neg = generate_guard(bol_lt, region, PROB_MIN); if (is_neg != NULL && pos_index != NULL) { // Emulate effect of Parse::adjust_map_after_if. @@ -930,9 +946,9 @@ inline Node* LibraryCallKit::generate_nonpositive_guard(Node* index, bool never_ return NULL; // already stopped if (_gvn.type(index)->higher_equal(TypeInt::POS1)) // [1,maxint] return NULL; // index is already adequately typed - Node* cmp_le = _gvn.transform( new (C) CmpINode(index, intcon(0)) ); + Node* cmp_le = _gvn.transform(new (C) CmpINode(index, intcon(0))); BoolTest::mask le_or_eq = (never_negative ? BoolTest::eq : BoolTest::le); - Node* bol_le = _gvn.transform( new (C) BoolNode(cmp_le, le_or_eq) ); + Node* bol_le = _gvn.transform(new (C) BoolNode(cmp_le, le_or_eq)); Node* is_notp = generate_guard(bol_le, NULL, PROB_MIN); if (is_notp != NULL && pos_index != NULL) { // Emulate effect of Parse::adjust_map_after_if. @@ -968,9 +984,9 @@ inline Node* LibraryCallKit::generate_limit_guard(Node* offset, return NULL; // common case of whole-array copy Node* last = subseq_length; if (!zero_offset) // last += offset - last = _gvn.transform( new (C) AddINode(last, offset)); - Node* cmp_lt = _gvn.transform( new (C) CmpUNode(array_length, last) ); - Node* bol_lt = _gvn.transform( new (C) BoolNode(cmp_lt, BoolTest::lt) ); + last = _gvn.transform(new (C) AddINode(last, offset)); + Node* cmp_lt = _gvn.transform(new (C) CmpUNode(array_length, last)); + Node* bol_lt = _gvn.transform(new (C) BoolNode(cmp_lt, BoolTest::lt)); Node* is_over = generate_guard(bol_lt, region, PROB_MIN); return is_over; } @@ -1151,8 +1167,8 @@ bool LibraryCallKit::inline_string_equals() { Node* argument_cnt = load_String_length(no_ctrl, argument); // Check for receiver count != argument count - Node* cmp = _gvn.transform( new(C) CmpINode(receiver_cnt, argument_cnt) ); - Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::ne) ); + Node* cmp = _gvn.transform(new(C) CmpINode(receiver_cnt, argument_cnt)); + Node* bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::ne)); Node* if_ne = generate_slow_guard(bol, NULL); if (if_ne != NULL) { phi->init_req(4, intcon(0)); @@ -1258,7 +1274,7 @@ Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_ar Node* sourceOffset = load_String_offset(no_ctrl, string_object); Node* sourceCount = load_String_length(no_ctrl, string_object); - Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true)) ); + Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true))); jint target_length = target_array->length(); const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin)); const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot); @@ -1365,8 +1381,8 @@ bool LibraryCallKit::inline_string_indexOf() { Node* substr_cnt = load_String_length(no_ctrl, arg); // Check for substr count > string count - Node* cmp = _gvn.transform( new(C) CmpINode(substr_cnt, source_cnt) ); - Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::gt) ); + Node* cmp = _gvn.transform(new(C) CmpINode(substr_cnt, source_cnt)); + Node* bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::gt)); Node* if_gt = generate_slow_guard(bol, NULL); if (if_gt != NULL) { result_phi->init_req(2, intcon(-1)); @@ -1375,8 +1391,8 @@ bool LibraryCallKit::inline_string_indexOf() { if (!stopped()) { // Check for substr count == 0 - cmp = _gvn.transform( new(C) CmpINode(substr_cnt, intcon(0)) ); - bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) ); + cmp = _gvn.transform(new(C) CmpINode(substr_cnt, intcon(0))); + bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::eq)); Node* if_zero = generate_slow_guard(bol, NULL); if (if_zero != NULL) { result_phi->init_req(3, intcon(0)); @@ -1552,7 +1568,7 @@ bool LibraryCallKit::inline_trig(vmIntrinsics::ID id) { // Check PI/4 : abs(arg) Node *cmp = _gvn.transform(new (C) CmpDNode(pi4,abs)); // Check: If PI/4 < abs(arg) then go slow - Node *bol = _gvn.transform( new (C) BoolNode( cmp, BoolTest::lt ) ); + Node *bol = _gvn.transform(new (C) BoolNode( cmp, BoolTest::lt )); // Branch either way IfNode *iff = create_and_xform_if(control(),bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); set_control(opt_iff(r,iff)); @@ -1617,8 +1633,8 @@ void LibraryCallKit::finish_pow_exp(Node* result, Node* x, Node* y, const TypeFu // to the runtime to properly handle corner cases IfNode* iff = create_and_xform_if(control(), bolisnum, PROB_STATIC_FREQUENT, COUNT_UNKNOWN); - Node* if_slow = _gvn.transform( new (C) IfFalseNode(iff) ); - Node* if_fast = _gvn.transform( new (C) IfTrueNode(iff) ); + Node* if_slow = _gvn.transform(new (C) IfFalseNode(iff)); + Node* if_fast = _gvn.transform(new (C) IfTrueNode(iff)); if (!if_slow->is_top()) { RegionNode* result_region = new (C) RegionNode(3); @@ -1704,42 +1720,42 @@ bool LibraryCallKit::inline_pow() { // Check x:0 Node *cmp = _gvn.transform(new (C) CmpDNode(x, zeronode)); // Check: If (x<=0) then go complex path - Node *bol1 = _gvn.transform( new (C) BoolNode( cmp, BoolTest::le ) ); + Node *bol1 = _gvn.transform(new (C) BoolNode( cmp, BoolTest::le )); // Branch either way IfNode *if1 = create_and_xform_if(control(),bol1, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); // Fast path taken; set region slot 3 - Node *fast_taken = _gvn.transform( new (C) IfFalseNode(if1) ); + Node *fast_taken = _gvn.transform(new (C) IfFalseNode(if1)); r->init_req(3,fast_taken); // Capture fast-control // Fast path not-taken, i.e. slow path - Node *complex_path = _gvn.transform( new (C) IfTrueNode(if1) ); + Node *complex_path = _gvn.transform(new (C) IfTrueNode(if1)); // Set fast path result - Node *fast_result = _gvn.transform( new (C) PowDNode(C, control(), x, y) ); + Node *fast_result = _gvn.transform(new (C) PowDNode(C, control(), x, y)); phi->init_req(3, fast_result); // Complex path // Build the second if node (if y is long) // Node for (long)y - Node *longy = _gvn.transform( new (C) ConvD2LNode(y)); + Node *longy = _gvn.transform(new (C) ConvD2LNode(y)); // Node for (double)((long) y) - Node *doublelongy= _gvn.transform( new (C) ConvL2DNode(longy)); + Node *doublelongy= _gvn.transform(new (C) ConvL2DNode(longy)); // Check (double)((long) y) : y Node *cmplongy= _gvn.transform(new (C) CmpDNode(doublelongy, y)); // Check if (y isn't long) then go to slow path - Node *bol2 = _gvn.transform( new (C) BoolNode( cmplongy, BoolTest::ne ) ); + Node *bol2 = _gvn.transform(new (C) BoolNode( cmplongy, BoolTest::ne )); // Branch either way IfNode *if2 = create_and_xform_if(complex_path,bol2, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN); - Node* ylong_path = _gvn.transform( new (C) IfFalseNode(if2)); + Node* ylong_path = _gvn.transform(new (C) IfFalseNode(if2)); - Node *slow_path = _gvn.transform( new (C) IfTrueNode(if2) ); + Node *slow_path = _gvn.transform(new (C) IfTrueNode(if2)); // Calculate DPow(abs(x), y)*(1 & (long)y) // Node for constant 1 Node *conone = longcon(1); // 1& (long)y - Node *signnode= _gvn.transform( new (C) AndLNode(conone, longy) ); + Node *signnode= _gvn.transform(new (C) AndLNode(conone, longy)); // A huge number is always even. Detect a huge number by checking // if y + 1 == y and set integer to be tested for parity to 0. @@ -1747,9 +1763,9 @@ bool LibraryCallKit::inline_pow() { // (long)9.223372036854776E18 = max_jlong // (double)(long)9.223372036854776E18 = 9.223372036854776E18 // max_jlong is odd but 9.223372036854776E18 is even - Node* yplus1 = _gvn.transform( new (C) AddDNode(y, makecon(TypeD::make(1)))); + Node* yplus1 = _gvn.transform(new (C) AddDNode(y, makecon(TypeD::make(1)))); Node *cmpyplus1= _gvn.transform(new (C) CmpDNode(yplus1, y)); - Node *bolyplus1 = _gvn.transform( new (C) BoolNode( cmpyplus1, BoolTest::eq ) ); + Node *bolyplus1 = _gvn.transform(new (C) BoolNode( cmpyplus1, BoolTest::eq )); Node* correctedsign = NULL; if (ConditionalMoveLimit != 0) { correctedsign = _gvn.transform( CMoveNode::make(C, NULL, bolyplus1, signnode, longcon(0), TypeLong::LONG)); @@ -1757,8 +1773,8 @@ bool LibraryCallKit::inline_pow() { IfNode *ifyplus1 = create_and_xform_if(ylong_path,bolyplus1, PROB_FAIR, COUNT_UNKNOWN); RegionNode *r = new (C) RegionNode(3); Node *phi = new (C) PhiNode(r, TypeLong::LONG); - r->init_req(1, _gvn.transform( new (C) IfFalseNode(ifyplus1))); - r->init_req(2, _gvn.transform( new (C) IfTrueNode(ifyplus1))); + r->init_req(1, _gvn.transform(new (C) IfFalseNode(ifyplus1))); + r->init_req(2, _gvn.transform(new (C) IfTrueNode(ifyplus1))); phi->init_req(1, signnode); phi->init_req(2, longcon(0)); correctedsign = _gvn.transform(phi); @@ -1771,11 +1787,11 @@ bool LibraryCallKit::inline_pow() { // Check (1&(long)y)==0? Node *cmpeq1 = _gvn.transform(new (C) CmpLNode(correctedsign, conzero)); // Check if (1&(long)y)!=0?, if so the result is negative - Node *bol3 = _gvn.transform( new (C) BoolNode( cmpeq1, BoolTest::ne ) ); + Node *bol3 = _gvn.transform(new (C) BoolNode( cmpeq1, BoolTest::ne )); // abs(x) - Node *absx=_gvn.transform( new (C) AbsDNode(x)); + Node *absx=_gvn.transform(new (C) AbsDNode(x)); // abs(x)^y - Node *absxpowy = _gvn.transform( new (C) PowDNode(C, control(), absx, y) ); + Node *absxpowy = _gvn.transform(new (C) PowDNode(C, control(), absx, y)); // -abs(x)^y Node *negabsxpowy = _gvn.transform(new (C) NegDNode (absxpowy)); // (1&(long)y)==1?-DPow(abs(x), y):DPow(abs(x), y) @@ -1786,8 +1802,8 @@ bool LibraryCallKit::inline_pow() { IfNode *ifyeven = create_and_xform_if(ylong_path,bol3, PROB_FAIR, COUNT_UNKNOWN); RegionNode *r = new (C) RegionNode(3); Node *phi = new (C) PhiNode(r, Type::DOUBLE); - r->init_req(1, _gvn.transform( new (C) IfFalseNode(ifyeven))); - r->init_req(2, _gvn.transform( new (C) IfTrueNode(ifyeven))); + r->init_req(1, _gvn.transform(new (C) IfFalseNode(ifyeven))); + r->init_req(2, _gvn.transform(new (C) IfTrueNode(ifyeven))); phi->init_req(1, absxpowy); phi->init_req(2, negabsxpowy); signresult = _gvn.transform(phi); @@ -1920,7 +1936,7 @@ LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) { int cmp_op = Op_CmpI; Node* xkey = xvalue; Node* ykey = yvalue; - Node* ideal_cmpxy = _gvn.transform( new(C) CmpINode(xkey, ykey) ); + Node* ideal_cmpxy = _gvn.transform(new(C) CmpINode(xkey, ykey)); if (ideal_cmpxy->is_Cmp()) { // E.g., if we have CmpI(length - offset, count), // it might idealize to CmpI(length, count + offset) @@ -2013,7 +2029,7 @@ LibraryCallKit::generate_min_max(vmIntrinsics::ID id, Node* x0, Node* y0) { default: if (cmpxy == NULL) cmpxy = ideal_cmpxy; - best_bol = _gvn.transform( new(C) BoolNode(cmpxy, BoolTest::lt) ); + best_bol = _gvn.transform(new(C) BoolNode(cmpxy, BoolTest::lt)); // and fall through: case BoolTest::lt: // x < y case BoolTest::le: // x <= y @@ -2073,7 +2089,7 @@ LibraryCallKit::classify_unsafe_addr(Node* &base, Node* &offset) { return Type::AnyPtr; } else if (base_type == TypePtr::NULL_PTR) { // Since this is a NULL+long form, we have to switch to a rawptr. - base = _gvn.transform( new (C) CastX2PNode(offset) ); + base = _gvn.transform(new (C) CastX2PNode(offset)); offset = MakeConX(0); return Type::RawPtr; } else if (base_type->base() == Type::RawPtr) { @@ -2467,7 +2483,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_native_ptr, bool is_store, Bas case T_ADDRESS: // Repackage the long as a pointer. val = ConvL2X(val); - val = _gvn.transform( new (C) CastX2PNode(val) ); + val = _gvn.transform(new (C) CastX2PNode(val)); break; } @@ -2775,7 +2791,7 @@ bool LibraryCallKit::inline_unsafe_load_store(BasicType type, LoadStoreKind kind // SCMemProjNodes represent the memory state of a LoadStore. Their // main role is to prevent LoadStore nodes from being optimized away // when their results aren't used. - Node* proj = _gvn.transform( new (C) SCMemProjNode(load_store)); + Node* proj = _gvn.transform(new (C) SCMemProjNode(load_store)); set_memory(proj, alias_idx); // Add the trailing membar surrounding the access @@ -3010,8 +3026,8 @@ bool LibraryCallKit::inline_native_isInterrupted() { Node* rec_thr = argument(0); Node* tls_ptr = NULL; Node* cur_thr = generate_current_thread(tls_ptr); - Node* cmp_thr = _gvn.transform( new (C) CmpPNode(cur_thr, rec_thr) ); - Node* bol_thr = _gvn.transform( new (C) BoolNode(cmp_thr, BoolTest::ne) ); + Node* cmp_thr = _gvn.transform(new (C) CmpPNode(cur_thr, rec_thr)); + Node* bol_thr = _gvn.transform(new (C) BoolNode(cmp_thr, BoolTest::ne)); generate_slow_guard(bol_thr, slow_region); @@ -3022,36 +3038,36 @@ bool LibraryCallKit::inline_native_isInterrupted() { // Set the control input on the field _interrupted read to prevent it floating up. Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT); - Node* cmp_bit = _gvn.transform( new (C) CmpINode(int_bit, intcon(0)) ); - Node* bol_bit = _gvn.transform( new (C) BoolNode(cmp_bit, BoolTest::ne) ); + Node* cmp_bit = _gvn.transform(new (C) CmpINode(int_bit, intcon(0))); + Node* bol_bit = _gvn.transform(new (C) BoolNode(cmp_bit, BoolTest::ne)); IfNode* iff_bit = create_and_map_if(control(), bol_bit, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN); // First fast path: if (!TLS._interrupted) return false; - Node* false_bit = _gvn.transform( new (C) IfFalseNode(iff_bit) ); + Node* false_bit = _gvn.transform(new (C) IfFalseNode(iff_bit)); result_rgn->init_req(no_int_result_path, false_bit); result_val->init_req(no_int_result_path, intcon(0)); // drop through to next case - set_control( _gvn.transform(new (C) IfTrueNode(iff_bit)) ); + set_control( _gvn.transform(new (C) IfTrueNode(iff_bit))); // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path. Node* clr_arg = argument(1); - Node* cmp_arg = _gvn.transform( new (C) CmpINode(clr_arg, intcon(0)) ); - Node* bol_arg = _gvn.transform( new (C) BoolNode(cmp_arg, BoolTest::ne) ); + Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0))); + Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne)); IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN); // Second fast path: ... else if (!clear_int) return true; - Node* false_arg = _gvn.transform( new (C) IfFalseNode(iff_arg) ); + Node* false_arg = _gvn.transform(new (C) IfFalseNode(iff_arg)); result_rgn->init_req(no_clear_result_path, false_arg); result_val->init_req(no_clear_result_path, intcon(1)); // drop through to next case - set_control( _gvn.transform(new (C) IfTrueNode(iff_arg)) ); + set_control( _gvn.transform(new (C) IfTrueNode(iff_arg))); // (d) Otherwise, go to the slow path. slow_region->add_req(control()); - set_control( _gvn.transform(slow_region) ); + set_control( _gvn.transform(slow_region)); if (stopped()) { // There is no slow path. @@ -3107,7 +3123,7 @@ Node* LibraryCallKit::load_klass_from_mirror_common(Node* mirror, if (region == NULL) never_see_null = true; Node* p = basic_plus_adr(mirror, offset); const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL; - Node* kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type) ); + Node* kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, kls_type)); Node* null_ctl = top(); kls = null_check_oop(kls, &null_ctl, never_see_null); if (region != NULL) { @@ -3129,9 +3145,9 @@ Node* LibraryCallKit::generate_access_flags_guard(Node* kls, int modifier_mask, Node* mods = make_load(NULL, modp, TypeInt::INT, T_INT); Node* mask = intcon(modifier_mask); Node* bits = intcon(modifier_bits); - Node* mbit = _gvn.transform( new (C) AndINode(mods, mask) ); - Node* cmp = _gvn.transform( new (C) CmpINode(mbit, bits) ); - Node* bol = _gvn.transform( new (C) BoolNode(cmp, BoolTest::ne) ); + Node* mbit = _gvn.transform(new (C) AndINode(mods, mask)); + Node* cmp = _gvn.transform(new (C) CmpINode(mbit, bits)); + Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::ne)); return generate_fair_guard(bol, region); } Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) { @@ -3282,7 +3298,7 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { phi->add_req(makecon(TypeInstPtr::make(env()->Object_klass()->java_mirror()))); // If we fall through, it's a plain class. Get its _super. p = basic_plus_adr(kls, in_bytes(Klass::super_offset())); - kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL) ); + kls = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL)); null_ctl = top(); kls = null_check_oop(kls, &null_ctl); if (null_ctl != top()) { @@ -3395,8 +3411,8 @@ bool LibraryCallKit::inline_native_subtype_check() { set_control(region->in(_prim_0_path)); // go back to first null check if (!stopped()) { // Since superc is primitive, make a guard for the superc==subc case. - Node* cmp_eq = _gvn.transform( new (C) CmpPNode(args[0], args[1]) ); - Node* bol_eq = _gvn.transform( new (C) BoolNode(cmp_eq, BoolTest::eq) ); + Node* cmp_eq = _gvn.transform(new (C) CmpPNode(args[0], args[1])); + Node* bol_eq = _gvn.transform(new (C) BoolNode(cmp_eq, BoolTest::eq)); generate_guard(bol_eq, region, PROB_FAIR); if (region->req() == PATH_LIMIT+1) { // A guard was added. If the added guard is taken, superc==subc. @@ -3461,11 +3477,11 @@ Node* LibraryCallKit::generate_array_guard_common(Node* kls, RegionNode* region, ? ((jint)Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift) : Klass::_lh_neutral_value); - Node* cmp = _gvn.transform( new(C) CmpINode(layout_val, intcon(nval)) ); + Node* cmp = _gvn.transform(new(C) CmpINode(layout_val, intcon(nval))); BoolTest::mask btest = BoolTest::lt; // correct for testing is_[obj]array // invert the test if we are looking for a non-array if (not_array) btest = BoolTest(btest).negate(); - Node* bol = _gvn.transform( new(C) BoolNode(cmp, btest) ); + Node* bol = _gvn.transform(new(C) BoolNode(cmp, btest)); return generate_fair_guard(bol, region); } @@ -3525,7 +3541,7 @@ bool LibraryCallKit::inline_native_newArray() { // Return the combined state. set_i_o( _gvn.transform(result_io) ); - set_all_memory( _gvn.transform(result_mem) ); + set_all_memory( _gvn.transform(result_mem)); C->set_has_split_ifs(true); // Has chance for split-if optimization set_result(result_reg, result_val); @@ -3678,8 +3694,8 @@ Node* LibraryCallKit::generate_virtual_guard(Node* obj_klass, const TypePtr* native_call_addr = TypeMetadataPtr::make(method); Node* native_call = makecon(native_call_addr); - Node* chk_native = _gvn.transform( new(C) CmpPNode(target_call, native_call) ); - Node* test_native = _gvn.transform( new(C) BoolNode(chk_native, BoolTest::ne) ); + Node* chk_native = _gvn.transform(new(C) CmpPNode(target_call, native_call)); + Node* test_native = _gvn.transform(new(C) BoolNode(chk_native, BoolTest::ne)); return generate_slow_guard(test_native, slow_region); } @@ -3800,10 +3816,10 @@ bool LibraryCallKit::inline_native_hashcode(bool is_virtual, bool is_static) { // Test the header to see if it is unlocked. Node *lock_mask = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place); - Node *lmasked_header = _gvn.transform( new (C) AndXNode(header, lock_mask) ); + Node *lmasked_header = _gvn.transform(new (C) AndXNode(header, lock_mask)); Node *unlocked_val = _gvn.MakeConX(markOopDesc::unlocked_value); - Node *chk_unlocked = _gvn.transform( new (C) CmpXNode( lmasked_header, unlocked_val)); - Node *test_unlocked = _gvn.transform( new (C) BoolNode( chk_unlocked, BoolTest::ne) ); + Node *chk_unlocked = _gvn.transform(new (C) CmpXNode( lmasked_header, unlocked_val)); + Node *test_unlocked = _gvn.transform(new (C) BoolNode( chk_unlocked, BoolTest::ne)); generate_slow_guard(test_unlocked, slow_region); @@ -3813,17 +3829,17 @@ bool LibraryCallKit::inline_native_hashcode(bool is_virtual, bool is_static) { // vm: see markOop.hpp. Node *hash_mask = _gvn.intcon(markOopDesc::hash_mask); Node *hash_shift = _gvn.intcon(markOopDesc::hash_shift); - Node *hshifted_header= _gvn.transform( new (C) URShiftXNode(header, hash_shift) ); + Node *hshifted_header= _gvn.transform(new (C) URShiftXNode(header, hash_shift)); // This hack lets the hash bits live anywhere in the mark object now, as long // as the shift drops the relevant bits into the low 32 bits. Note that // Java spec says that HashCode is an int so there's no point in capturing // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build). hshifted_header = ConvX2I(hshifted_header); - Node *hash_val = _gvn.transform( new (C) AndINode(hshifted_header, hash_mask) ); + Node *hash_val = _gvn.transform(new (C) AndINode(hshifted_header, hash_mask)); Node *no_hash_val = _gvn.intcon(markOopDesc::no_hash); - Node *chk_assigned = _gvn.transform( new (C) CmpINode( hash_val, no_hash_val)); - Node *test_assigned = _gvn.transform( new (C) BoolNode( chk_assigned, BoolTest::eq) ); + Node *chk_assigned = _gvn.transform(new (C) CmpINode( hash_val, no_hash_val)); + Node *test_assigned = _gvn.transform(new (C) BoolNode( chk_assigned, BoolTest::eq)); generate_slow_guard(test_assigned, slow_region); @@ -3854,7 +3870,7 @@ bool LibraryCallKit::inline_native_hashcode(bool is_virtual, bool is_static) { // Return the combined state. set_i_o( _gvn.transform(result_io) ); - set_all_memory( _gvn.transform(result_mem) ); + set_all_memory( _gvn.transform(result_mem)); set_result(result_reg, result_val); return true; @@ -3982,7 +3998,7 @@ bool LibraryCallKit::inline_fp_conversions(vmIntrinsics::ID id) { Node *opt_isnan = _gvn.transform(ifisnan); assert( opt_isnan->is_If(), "Expect an IfNode"); IfNode *opt_ifisnan = (IfNode*)opt_isnan; - Node *iftrue = _gvn.transform( new (C) IfTrueNode(opt_ifisnan) ); + Node *iftrue = _gvn.transform(new (C) IfTrueNode(opt_ifisnan)); set_control(iftrue); @@ -4023,7 +4039,7 @@ bool LibraryCallKit::inline_fp_conversions(vmIntrinsics::ID id) { Node *opt_isnan = _gvn.transform(ifisnan); assert( opt_isnan->is_If(), "Expect an IfNode"); IfNode *opt_ifisnan = (IfNode*)opt_isnan; - Node *iftrue = _gvn.transform( new (C) IfTrueNode(opt_ifisnan) ); + Node *iftrue = _gvn.transform(new (C) IfTrueNode(opt_ifisnan)); set_control(iftrue); @@ -4152,8 +4168,8 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b // Compute the length also, if needed: Node* countx = size; - countx = _gvn.transform( new (C) SubXNode(countx, MakeConX(base_off)) ); - countx = _gvn.transform( new (C) URShiftXNode(countx, intcon(LogBytesPerLong) )); + countx = _gvn.transform(new (C) SubXNode(countx, MakeConX(base_off))); + countx = _gvn.transform(new (C) URShiftXNode(countx, intcon(LogBytesPerLong) )); const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; bool disjoint_bases = true; @@ -4357,9 +4373,9 @@ bool LibraryCallKit::inline_native_clone(bool is_virtual) { } // Return the combined state. - set_control( _gvn.transform(result_reg) ); - set_i_o( _gvn.transform(result_i_o) ); - set_all_memory( _gvn.transform(result_mem) ); + set_control( _gvn.transform(result_reg)); + set_i_o( _gvn.transform(result_i_o)); + set_all_memory( _gvn.transform(result_mem)); } // original reexecute is set back here set_result(_gvn.transform(result_val)); @@ -4684,8 +4700,8 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type, // are dest_head = dest[0..off] and dest_tail = dest[off+len..dest.length]. Node* dest_size = alloc->in(AllocateNode::AllocSize); Node* dest_length = alloc->in(AllocateNode::ALength); - Node* dest_tail = _gvn.transform( new(C) AddINode(dest_offset, - copy_length) ); + Node* dest_tail = _gvn.transform(new(C) AddINode(dest_offset, + copy_length)); // If there is a head section that needs zeroing, do it now. if (find_int_con(dest_offset, -1) != 0) { @@ -4701,8 +4717,8 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type, // the copy to a more hardware-friendly word size of 64 bits. Node* tail_ctl = NULL; if (!stopped() && !dest_tail->eqv_uncast(dest_length)) { - Node* cmp_lt = _gvn.transform( new(C) CmpINode(dest_tail, dest_length) ); - Node* bol_lt = _gvn.transform( new(C) BoolNode(cmp_lt, BoolTest::lt) ); + Node* cmp_lt = _gvn.transform(new(C) CmpINode(dest_tail, dest_length)); + Node* bol_lt = _gvn.transform(new(C) BoolNode(cmp_lt, BoolTest::lt)); tail_ctl = generate_slow_guard(bol_lt, NULL); assert(tail_ctl != NULL || !stopped(), "must be an outcome"); } @@ -4745,7 +4761,7 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type, dest_size); done_ctl->init_req(2, control()); done_mem->init_req(2, memory(adr_type)); - set_control( _gvn.transform(done_ctl) ); + set_control( _gvn.transform(done_ctl)); set_memory( _gvn.transform(done_mem), adr_type ); } } @@ -4832,18 +4848,18 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type, // Clean up after the checked call. // The returned value is either 0 or -1^K, // where K = number of partially transferred array elements. - Node* cmp = _gvn.transform( new(C) CmpINode(checked_value, intcon(0)) ); - Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) ); + Node* cmp = _gvn.transform(new(C) CmpINode(checked_value, intcon(0))); + Node* bol = _gvn.transform(new(C) BoolNode(cmp, BoolTest::eq)); IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN); // If it is 0, we are done, so transfer to the end. - Node* checks_done = _gvn.transform( new(C) IfTrueNode(iff) ); + Node* checks_done = _gvn.transform(new(C) IfTrueNode(iff)); result_region->init_req(checked_path, checks_done); result_i_o ->init_req(checked_path, checked_i_o); result_memory->init_req(checked_path, checked_mem); // If it is not zero, merge into the slow call. - set_control( _gvn.transform( new(C) IfFalseNode(iff) )); + set_control( _gvn.transform(new(C) IfFalseNode(iff) )); RegionNode* slow_reg2 = new(C) RegionNode(3); PhiNode* slow_i_o2 = new(C) PhiNode(slow_reg2, Type::ABIO); PhiNode* slow_mem2 = new(C) PhiNode(slow_reg2, Type::MEMORY, adr_type); @@ -4866,16 +4882,16 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type, } else { // We must continue the copy exactly where it failed, or else // another thread might see the wrong number of writes to dest. - Node* checked_offset = _gvn.transform( new(C) XorINode(checked_value, intcon(-1)) ); + Node* checked_offset = _gvn.transform(new(C) XorINode(checked_value, intcon(-1))); Node* slow_offset = new(C) PhiNode(slow_reg2, TypeInt::INT); slow_offset->init_req(1, intcon(0)); slow_offset->init_req(2, checked_offset); slow_offset = _gvn.transform(slow_offset); // Adjust the arguments by the conditionally incoming offset. - Node* src_off_plus = _gvn.transform( new(C) AddINode(src_offset, slow_offset) ); - Node* dest_off_plus = _gvn.transform( new(C) AddINode(dest_offset, slow_offset) ); - Node* length_minus = _gvn.transform( new(C) SubINode(copy_length, slow_offset) ); + Node* src_off_plus = _gvn.transform(new(C) AddINode(src_offset, slow_offset)); + Node* dest_off_plus = _gvn.transform(new(C) AddINode(dest_offset, slow_offset)); + Node* length_minus = _gvn.transform(new(C) SubINode(copy_length, slow_offset)); // Tweak the node variables to adjust the code produced below: src_offset = src_off_plus; @@ -4914,7 +4930,7 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type, } // Finished; return the combined state. - set_control( _gvn.transform(result_region) ); + set_control( _gvn.transform(result_region)); set_i_o( _gvn.transform(result_i_o) ); set_memory( _gvn.transform(result_memory), adr_type ); @@ -5096,10 +5112,10 @@ LibraryCallKit::generate_clear_array(const TypePtr* adr_type, int end_round = (-1 << scale) & (BytesPerLong - 1); Node* end = ConvI2X(slice_len); if (scale != 0) - end = _gvn.transform( new(C) LShiftXNode(end, intcon(scale) )); + end = _gvn.transform(new(C) LShiftXNode(end, intcon(scale) )); end_base += end_round; - end = _gvn.transform( new(C) AddXNode(end, MakeConX(end_base)) ); - end = _gvn.transform( new(C) AndXNode(end, MakeConX(~end_round)) ); + end = _gvn.transform(new(C) AddXNode(end, MakeConX(end_base))); + end = _gvn.transform(new(C) AndXNode(end, MakeConX(~end_round))); mem = ClearArrayNode::clear_memory(control(), mem, dest, start_con, end, &_gvn); } else if (start_con < 0 && dest_size != top()) { @@ -5108,8 +5124,8 @@ LibraryCallKit::generate_clear_array(const TypePtr* adr_type, Node* start = slice_idx; start = ConvI2X(start); if (scale != 0) - start = _gvn.transform( new(C) LShiftXNode( start, intcon(scale) )); - start = _gvn.transform( new(C) AddXNode(start, MakeConX(abase)) ); + start = _gvn.transform(new(C) LShiftXNode( start, intcon(scale) )); + start = _gvn.transform(new(C) AddXNode(start, MakeConX(abase))); if ((bump_bit | clear_low) != 0) { int to_clear = (bump_bit | clear_low); // Align up mod 8, then store a jint zero unconditionally @@ -5120,14 +5136,14 @@ LibraryCallKit::generate_clear_array(const TypePtr* adr_type, assert((abase & to_clear) == 0, "array base must be long-aligned"); } else { // Bump 'start' up to (or past) the next jint boundary: - start = _gvn.transform( new(C) AddXNode(start, MakeConX(bump_bit)) ); + start = _gvn.transform(new(C) AddXNode(start, MakeConX(bump_bit))); assert((abase & clear_low) == 0, "array base must be int-aligned"); } // Round bumped 'start' down to jlong boundary in body of array. - start = _gvn.transform( new(C) AndXNode(start, MakeConX(~to_clear)) ); + start = _gvn.transform(new(C) AndXNode(start, MakeConX(~to_clear))); if (bump_bit != 0) { // Store a zero to the immediately preceding jint: - Node* x1 = _gvn.transform( new(C) AddXNode(start, MakeConX(-bump_bit)) ); + Node* x1 = _gvn.transform(new(C) AddXNode(start, MakeConX(-bump_bit))); Node* p1 = basic_plus_adr(dest, x1); mem = StoreNode::make(_gvn, control(), mem, p1, adr_type, intcon(0), T_INT); mem = _gvn.transform(mem); @@ -5194,8 +5210,8 @@ LibraryCallKit::generate_block_arraycopy(const TypePtr* adr_type, Node* sptr = basic_plus_adr(src, src_off); Node* dptr = basic_plus_adr(dest, dest_off); Node* countx = dest_size; - countx = _gvn.transform( new (C) SubXNode(countx, MakeConX(dest_off)) ); - countx = _gvn.transform( new (C) URShiftXNode(countx, intcon(LogBytesPerLong)) ); + countx = _gvn.transform(new (C) SubXNode(countx, MakeConX(dest_off))); + countx = _gvn.transform(new (C) URShiftXNode(countx, intcon(LogBytesPerLong))); bool disjoint_bases = true; // since alloc != NULL generate_unchecked_arraycopy(adr_type, T_LONG, disjoint_bases, @@ -5360,6 +5376,117 @@ bool LibraryCallKit::inline_encodeISOArray() { return true; } +/** + * Calculate CRC32 for byte. + * int java.util.zip.CRC32.update(int crc, int b) + */ +bool LibraryCallKit::inline_updateCRC32() { + assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support"); + assert(callee()->signature()->size() == 2, "update has 2 parameters"); + // no receiver since it is static method + Node* crc = argument(0); // type: int + Node* b = argument(1); // type: int + + /* + * int c = ~ crc; + * b = timesXtoThe32[(b ^ c) & 0xFF]; + * b = b ^ (c >>> 8); + * crc = ~b; + */ + + Node* M1 = intcon(-1); + crc = _gvn.transform(new (C) XorINode(crc, M1)); + Node* result = _gvn.transform(new (C) XorINode(crc, b)); + result = _gvn.transform(new (C) AndINode(result, intcon(0xFF))); + + Node* base = makecon(TypeRawPtr::make(StubRoutines::crc_table_addr())); + Node* offset = _gvn.transform(new (C) LShiftINode(result, intcon(0x2))); + Node* adr = basic_plus_adr(top(), base, ConvI2X(offset)); + result = make_load(control(), adr, TypeInt::INT, T_INT); + + crc = _gvn.transform(new (C) URShiftINode(crc, intcon(8))); + result = _gvn.transform(new (C) XorINode(crc, result)); + result = _gvn.transform(new (C) XorINode(result, M1)); + set_result(result); + return true; +} + +/** + * Calculate CRC32 for byte[] array. + * int java.util.zip.CRC32.updateBytes(int crc, byte[] buf, int off, int len) + */ +bool LibraryCallKit::inline_updateBytesCRC32() { + assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support"); + assert(callee()->signature()->size() == 4, "updateBytes has 4 parameters"); + // no receiver since it is static method + Node* crc = argument(0); // type: int + Node* src = argument(1); // type: oop + Node* offset = argument(2); // type: int + Node* length = argument(3); // type: int + + const Type* src_type = src->Value(&_gvn); + const TypeAryPtr* top_src = src_type->isa_aryptr(); + if (top_src == NULL || top_src->klass() == NULL) { + // failed array check + return false; + } + + // Figure out the size and type of the elements we will be copying. + BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type(); + if (src_elem != T_BYTE) { + return false; + } + + // 'src_start' points to src array + scaled offset + Node* src_start = array_element_address(src, offset, src_elem); + + // We assume that range check is done by caller. + // TODO: generate range check (offset+length < src.length) in debug VM. + + // Call the stub. + address stubAddr = StubRoutines::updateBytesCRC32(); + const char *stubName = "updateBytesCRC32"; + + Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(), + stubAddr, stubName, TypePtr::BOTTOM, + crc, src_start, length); + Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); + set_result(result); + return true; +} + +/** + * Calculate CRC32 for ByteBuffer. + * int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len) + */ +bool LibraryCallKit::inline_updateByteBufferCRC32() { + assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support"); + assert(callee()->signature()->size() == 5, "updateByteBuffer has 4 parameters and one is long"); + // no receiver since it is static method + Node* crc = argument(0); // type: int + Node* src = argument(1); // type: long + Node* offset = argument(3); // type: int + Node* length = argument(4); // type: int + + src = ConvL2X(src); // adjust Java long to machine word + Node* base = _gvn.transform(new (C) CastX2PNode(src)); + offset = ConvI2X(offset); + + // 'src_start' points to src array + scaled offset + Node* src_start = basic_plus_adr(top(), base, offset); + + // Call the stub. + address stubAddr = StubRoutines::updateBytesCRC32(); + const char *stubName = "updateBytesCRC32"; + + Node* call = make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::updateBytesCRC32_Type(), + stubAddr, stubName, TypePtr::BOTTOM, + crc, src_start, length); + Node* result = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms)); + set_result(result); + return true; +} + //----------------------------inline_reference_get---------------------------- // public T java.lang.ref.Reference.get(); bool LibraryCallKit::inline_reference_get() { diff --git a/hotspot/src/share/vm/opto/runtime.cpp b/hotspot/src/share/vm/opto/runtime.cpp index d0aefad66b7..9a278c5ac1c 100644 --- a/hotspot/src/share/vm/opto/runtime.cpp +++ b/hotspot/src/share/vm/opto/runtime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -829,6 +829,28 @@ const TypeFunc* OptoRuntime::aescrypt_block_Type() { return TypeFunc::make(domain, range); } +/** + * int updateBytesCRC32(int crc, byte* b, int len) + */ +const TypeFunc* OptoRuntime::updateBytesCRC32_Type() { + // create input type (domain) + int num_args = 3; + int argcnt = num_args; + const Type** fields = TypeTuple::fields(argcnt); + int argp = TypeFunc::Parms; + fields[argp++] = TypeInt::INT; // crc + fields[argp++] = TypePtr::NOTNULL; // src + fields[argp++] = TypeInt::INT; // len + assert(argp == TypeFunc::Parms+argcnt, "correct decoding"); + const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields); + + // result type needed + fields = TypeTuple::fields(1); + fields[TypeFunc::Parms+0] = TypeInt::INT; // crc result + const TypeTuple* range = TypeTuple::make(TypeFunc::Parms+1, fields); + return TypeFunc::make(domain, range); +} + // for cipherBlockChaining calls of aescrypt encrypt/decrypt, four pointers and a length, returning void const TypeFunc* OptoRuntime::cipherBlockChaining_aescrypt_Type() { // create input type (domain) diff --git a/hotspot/src/share/vm/opto/runtime.hpp b/hotspot/src/share/vm/opto/runtime.hpp index 295b7123757..b3f7ff4cb1a 100644 --- a/hotspot/src/share/vm/opto/runtime.hpp +++ b/hotspot/src/share/vm/opto/runtime.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -284,6 +284,8 @@ private: static const TypeFunc* aescrypt_block_Type(); static const TypeFunc* cipherBlockChaining_aescrypt_Type(); + static const TypeFunc* updateBytesCRC32_Type(); + // leaf on stack replacement interpreter accessor types static const TypeFunc* osr_end_Type(); diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp index 85f3e2e0e41..f37ea34c46d 100644 --- a/hotspot/src/share/vm/prims/jni.cpp +++ b/hotspot/src/share/vm/prims/jni.cpp @@ -879,7 +879,7 @@ JNI_ENTRY(jint, jni_PushLocalFrame(JNIEnv *env, jint capacity)) env, capacity); #endif /* USDT2 */ //%note jni_11 - if (capacity < 0 && capacity > MAX_REASONABLE_LOCAL_CAPACITY) { + if (capacity < 0 || capacity > MAX_REASONABLE_LOCAL_CAPACITY) { #ifndef USDT2 DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, JNI_ERR); #else /* USDT2 */ diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp index bb9da0034e4..ac1c796eb31 100644 --- a/hotspot/src/share/vm/prims/methodHandles.cpp +++ b/hotspot/src/share/vm/prims/methodHandles.cpp @@ -1137,7 +1137,12 @@ JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, if (VerifyMethodHandles && caller_jh != NULL && java_lang_invoke_MemberName::clazz(mname()) != NULL) { Klass* reference_klass = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(mname())); - if (reference_klass != NULL) { + if (reference_klass != NULL && reference_klass->oop_is_objArray()) { + reference_klass = ObjArrayKlass::cast(reference_klass)->bottom_klass(); + } + + // Reflection::verify_class_access can only handle instance classes. + if (reference_klass != NULL && reference_klass->oop_is_instance()) { // Emulate LinkResolver::check_klass_accessability. Klass* caller = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh)); if (!Reflection::verify_class_access(caller, diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 625feda03f9..c52959d6976 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -849,7 +849,7 @@ bool Arguments::process_argument(const char* arg, arg_len = equal_sign - argname; } - Flag* found_flag = Flag::find_flag((char*)argname, arg_len, true); + Flag* found_flag = Flag::find_flag((const char*)argname, arg_len, true); if (found_flag != NULL) { char locked_message_buf[BUFLEN]; found_flag->get_locked_message(locked_message_buf, BUFLEN); @@ -870,6 +870,14 @@ bool Arguments::process_argument(const char* arg, } else { jio_fprintf(defaultStream::error_stream(), "Unrecognized VM option '%s'\n", argname); + Flag* fuzzy_matched = Flag::fuzzy_match((const char*)argname, arg_len, true); + if (fuzzy_matched != NULL) { + jio_fprintf(defaultStream::error_stream(), + "Did you mean '%s%s%s'?\n", + (fuzzy_matched->is_bool()) ? "(+/-)" : "", + fuzzy_matched->name, + (fuzzy_matched->is_bool()) ? "" : "="); + } } // allow for commandline "commenting out" options like -XX:#+Verbose @@ -1571,7 +1579,9 @@ void Arguments::set_heap_base_min_address() { // By default HeapBaseMinAddress is 2G on all platforms except Solaris x86. // G1 currently needs a lot of C-heap, so on Solaris we have to give G1 // some extra space for the C-heap compared to other collectors. - FLAG_SET_ERGO(uintx, HeapBaseMinAddress, 1*G); + // Use FLAG_SET_DEFAULT here rather than FLAG_SET_ERGO to make sure that + // code that checks for default values work correctly. + FLAG_SET_DEFAULT(HeapBaseMinAddress, 1*G); } } @@ -2211,11 +2221,24 @@ bool Arguments::check_vm_args_consistency() { status = false; } - if (ReservedCodeCacheSize < InitialCodeCacheSize) { + // Check lower bounds of the code cache + // Template Interpreter code is approximately 3X larger in debug builds. + uint min_code_cache_size = (CodeCacheMinimumUseSpace DEBUG_ONLY(* 3)) + CodeCacheMinimumFreeSpace; + if (InitialCodeCacheSize < (uintx)os::vm_page_size()) { jio_fprintf(defaultStream::error_stream(), - "Invalid ReservedCodeCacheSize: %dK. Should be greater than InitialCodeCacheSize=%dK\n", + "Invalid InitialCodeCacheSize=%dK. Must be at least %dK.\n", InitialCodeCacheSize/K, + os::vm_page_size()/K); + status = false; + } else if (ReservedCodeCacheSize < InitialCodeCacheSize) { + jio_fprintf(defaultStream::error_stream(), + "Invalid ReservedCodeCacheSize: %dK. Must be at least InitialCodeCacheSize=%dK.\n", ReservedCodeCacheSize/K, InitialCodeCacheSize/K); status = false; + } else if (ReservedCodeCacheSize < min_code_cache_size) { + jio_fprintf(defaultStream::error_stream(), + "Invalid ReservedCodeCacheSize=%dK. Must be at least %uK.\n", ReservedCodeCacheSize/K, + min_code_cache_size/K); + status = false; } return status; @@ -2616,10 +2639,20 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, // -Xoss } else if (match_option(option, "-Xoss", &tail)) { // HotSpot does not have separate native and Java stacks, ignore silently for compatibility - // -Xmaxjitcodesize + } else if (match_option(option, "-XX:CodeCacheExpansionSize=", &tail)) { + julong long_CodeCacheExpansionSize = 0; + ArgsRange errcode = parse_memory_size(tail, &long_CodeCacheExpansionSize, os::vm_page_size()); + if (errcode != arg_in_range) { + jio_fprintf(defaultStream::error_stream(), + "Invalid argument: %s. Must be at least %luK.\n", option->optionString, + os::vm_page_size()/K); + return JNI_EINVAL; + } + FLAG_SET_CMDLINE(uintx, CodeCacheExpansionSize, (uintx)long_CodeCacheExpansionSize); } else if (match_option(option, "-Xmaxjitcodesize", &tail) || match_option(option, "-XX:ReservedCodeCacheSize=", &tail)) { julong long_ReservedCodeCacheSize = 0; + ArgsRange errcode = parse_memory_size(tail, &long_ReservedCodeCacheSize, 1); if (errcode != arg_in_range) { jio_fprintf(defaultStream::error_stream(), diff --git a/hotspot/src/share/vm/runtime/globals.cpp b/hotspot/src/share/vm/runtime/globals.cpp index b45e15c9560..a6c47bfe1de 100644 --- a/hotspot/src/share/vm/runtime/globals.cpp +++ b/hotspot/src/share/vm/runtime/globals.cpp @@ -276,14 +276,14 @@ static Flag flagTable[] = { Flag* Flag::flags = flagTable; size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag)); -inline bool str_equal(const char* s, char* q, size_t len) { +inline bool str_equal(const char* s, const char* q, size_t len) { // s is null terminated, q is not! if (strlen(s) != (unsigned int) len) return false; return strncmp(s, q, len) == 0; } // Search the flag table for a named flag -Flag* Flag::find_flag(char* name, size_t length, bool allow_locked) { +Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked) { for (Flag* current = &flagTable[0]; current->name != NULL; current++) { if (str_equal(current->name, name, length)) { // Found a matching entry. Report locked flags only if allowed. @@ -301,6 +301,52 @@ Flag* Flag::find_flag(char* name, size_t length, bool allow_locked) { return NULL; } +// Compute string similarity based on Dice's coefficient +static float str_similar(const char* str1, const char* str2, size_t len2) { + int len1 = (int) strlen(str1); + int total = len1 + (int) len2; + + int hit = 0; + + for (int i = 0; i < len1 -1; ++i) { + for (int j = 0; j < (int) len2 -1; ++j) { + if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) { + ++hit; + break; + } + } + } + + return 2.0f * (float) hit / (float) total; +} + +Flag* Flag::fuzzy_match(const char* name, size_t length, bool allow_locked) { + float VMOptionsFuzzyMatchSimilarity = 0.7f; + Flag* match = NULL; + float score; + float max_score = -1; + + for (Flag* current = &flagTable[0]; current->name != NULL; current++) { + score = str_similar(current->name, name, length); + if (score > max_score) { + max_score = score; + match = current; + } + } + + if (!(match->is_unlocked() || match->is_unlocker())) { + if (!allow_locked) { + return NULL; + } + } + + if (max_score < VMOptionsFuzzyMatchSimilarity) { + return NULL; + } + + return match; +} + // Returns the address of the index'th element static Flag* address_of_flag(CommandLineFlagWithType flag) { assert((size_t)flag < Flag::numFlags, "bad command line flag index"); diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index b1adcf7fce1..d07785d0b61 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -220,7 +220,8 @@ struct Flag { // number of flags static size_t numFlags; - static Flag* find_flag(char* name, size_t length, bool allow_locked = false); + static Flag* find_flag(const char* name, size_t length, bool allow_locked = false); + static Flag* fuzzy_match(const char* name, size_t length, bool allow_locked = false); bool is_bool() const { return strcmp(type, "bool") == 0; } bool get_bool() const { return *((bool*) addr); } @@ -644,6 +645,9 @@ class CommandLineFlags { product(bool, UseAESIntrinsics, false, \ "use intrinsics for AES versions of crypto") \ \ + product(bool, UseCRC32Intrinsics, false, \ + "use intrinsics for java.util.zip.CRC32") \ + \ develop(bool, TraceCallFixup, false, \ "traces all call fixups") \ \ @@ -3160,6 +3164,9 @@ class CommandLineFlags { product_pd(uintx, InitialCodeCacheSize, \ "Initial code cache size (in bytes)") \ \ + develop_pd(uintx, CodeCacheMinimumUseSpace, \ + "Minimum code cache size (in bytes) required to start VM.") \ + \ product_pd(uintx, ReservedCodeCacheSize, \ "Reserved code cache size (in bytes) - maximum code cache size") \ \ diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp index 15869cc5c0e..f06a7f922aa 100644 --- a/hotspot/src/share/vm/runtime/reflection.cpp +++ b/hotspot/src/share/vm/runtime/reflection.cpp @@ -458,7 +458,7 @@ bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, boo // doesn't have a classloader. if ((current_class == NULL) || (current_class == new_class) || - (InstanceKlass::cast(new_class)->is_public()) || + (new_class->is_public()) || is_same_class_package(current_class, new_class)) { return true; } diff --git a/hotspot/src/share/vm/runtime/stubRoutines.cpp b/hotspot/src/share/vm/runtime/stubRoutines.cpp index c559865b821..a1179acd543 100644 --- a/hotspot/src/share/vm/runtime/stubRoutines.cpp +++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -125,6 +125,9 @@ address StubRoutines::_aescrypt_decryptBlock = NULL; address StubRoutines::_cipherBlockChaining_encryptAESCrypt = NULL; address StubRoutines::_cipherBlockChaining_decryptAESCrypt = NULL; +address StubRoutines::_updateBytesCRC32 = NULL; +address StubRoutines::_crc_table_adr = NULL; + double (* StubRoutines::_intrinsic_log )(double) = NULL; double (* StubRoutines::_intrinsic_log10 )(double) = NULL; double (* StubRoutines::_intrinsic_exp )(double) = NULL; diff --git a/hotspot/src/share/vm/runtime/stubRoutines.hpp b/hotspot/src/share/vm/runtime/stubRoutines.hpp index 7ad66371300..b8d61ea0cbf 100644 --- a/hotspot/src/share/vm/runtime/stubRoutines.hpp +++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp @@ -204,6 +204,9 @@ class StubRoutines: AllStatic { static address _cipherBlockChaining_encryptAESCrypt; static address _cipherBlockChaining_decryptAESCrypt; + static address _updateBytesCRC32; + static address _crc_table_adr; + // These are versions of the java.lang.Math methods which perform // the same operations as the intrinsic version. They are used for // constant folding in the compiler to ensure equivalence. If the @@ -342,6 +345,9 @@ class StubRoutines: AllStatic { static address cipherBlockChaining_encryptAESCrypt() { return _cipherBlockChaining_encryptAESCrypt; } static address cipherBlockChaining_decryptAESCrypt() { return _cipherBlockChaining_decryptAESCrypt; } + static address updateBytesCRC32() { return _updateBytesCRC32; } + static address crc_table_addr() { return _crc_table_adr; } + static address select_fill_function(BasicType t, bool aligned, const char* &name); static address zero_aligned_words() { return _zero_aligned_words; } diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp index caf785a2cfb..94b24eec8ea 100644 --- a/hotspot/src/share/vm/runtime/vmStructs.cpp +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp @@ -437,10 +437,6 @@ typedef BinaryTreeDictionary MetablockTreeDictionary; static_field(Universe, _main_thread_group, oop) \ static_field(Universe, _system_thread_group, oop) \ static_field(Universe, _the_empty_class_klass_array, objArrayOop) \ - static_field(Universe, _out_of_memory_error_java_heap, oop) \ - static_field(Universe, _out_of_memory_error_perm_gen, oop) \ - static_field(Universe, _out_of_memory_error_array_size, oop) \ - static_field(Universe, _out_of_memory_error_gc_overhead_limit, oop) \ static_field(Universe, _null_ptr_exception_instance, oop) \ static_field(Universe, _arithmetic_exception_instance, oop) \ static_field(Universe, _vm_exception, oop) \ diff --git a/hotspot/src/share/vm/services/memReporter.cpp b/hotspot/src/share/vm/services/memReporter.cpp index 573d9e03c14..9d0f45ada36 100644 --- a/hotspot/src/share/vm/services/memReporter.cpp +++ b/hotspot/src/share/vm/services/memReporter.cpp @@ -188,8 +188,8 @@ void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline& (MallocCallsitePointer*)prev_malloc_itr.current(); while (cur_malloc_callsite != NULL || prev_malloc_callsite != NULL) { - if (prev_malloc_callsite == NULL || - cur_malloc_callsite->addr() < prev_malloc_callsite->addr()) { + if (prev_malloc_callsite == NULL) { + assert(cur_malloc_callsite != NULL, "sanity check"); // this is a new callsite _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(), amount_in_current_scale(cur_malloc_callsite->amount()), @@ -197,22 +197,42 @@ void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline& diff_in_current_scale(cur_malloc_callsite->amount(), 0), diff(cur_malloc_callsite->count(), 0)); cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next(); - } else if (cur_malloc_callsite == NULL || - cur_malloc_callsite->addr() > prev_malloc_callsite->addr()) { + } else if (cur_malloc_callsite == NULL) { + assert(prev_malloc_callsite != NULL, "Sanity check"); // this callsite is already gone _outputer.diff_malloc_callsite(prev_malloc_callsite->addr(), - amount_in_current_scale(0), 0, + 0, 0, diff_in_current_scale(0, prev_malloc_callsite->amount()), diff(0, prev_malloc_callsite->count())); prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next(); - } else { // the same callsite - _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(), - amount_in_current_scale(cur_malloc_callsite->amount()), - cur_malloc_callsite->count(), - diff_in_current_scale(cur_malloc_callsite->amount(), prev_malloc_callsite->amount()), - diff(cur_malloc_callsite->count(), prev_malloc_callsite->count())); - cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next(); - prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next(); + } else { + assert(cur_malloc_callsite != NULL, "Sanity check"); + assert(prev_malloc_callsite != NULL, "Sanity check"); + if (cur_malloc_callsite->addr() < prev_malloc_callsite->addr()) { + // this is a new callsite + _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(), + amount_in_current_scale(cur_malloc_callsite->amount()), + cur_malloc_callsite->count(), + diff_in_current_scale(cur_malloc_callsite->amount(), 0), + diff(cur_malloc_callsite->count(), 0)); + cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next(); + } else if (cur_malloc_callsite->addr() > prev_malloc_callsite->addr()) { + // this callsite is already gone + _outputer.diff_malloc_callsite(prev_malloc_callsite->addr(), + 0, 0, + diff_in_current_scale(0, prev_malloc_callsite->amount()), + diff(0, prev_malloc_callsite->count())); + prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next(); + } else { + // the same callsite + _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(), + amount_in_current_scale(cur_malloc_callsite->amount()), + cur_malloc_callsite->count(), + diff_in_current_scale(cur_malloc_callsite->amount(), prev_malloc_callsite->amount()), + diff(cur_malloc_callsite->count(), prev_malloc_callsite->count())); + cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next(); + prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next(); + } } } diff --git a/hotspot/src/share/vm/trace/trace.xml b/hotspot/src/share/vm/trace/trace.xml index c530bbc3c16..6b1d9a8850f 100644 --- a/hotspot/src/share/vm/trace/trace.xml +++ b/hotspot/src/share/vm/trace/trace.xml @@ -158,7 +158,7 @@ Declares a structure type that can be used in other events. - + @@ -203,7 +203,7 @@ Declares a structure type that can be used in other events. - + @@ -211,7 +211,7 @@ Declares a structure type that can be used in other events. - + @@ -240,14 +240,14 @@ Declares a structure type that can be used in other events. - + - + - + diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp index f7b940b52e7..64f753bc75c 100644 --- a/hotspot/src/share/vm/utilities/vmError.cpp +++ b/hotspot/src/share/vm/utilities/vmError.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -799,6 +799,14 @@ void VMError::report(outputStream* st) { VMError* volatile VMError::first_error = NULL; volatile jlong VMError::first_error_tid = -1; +// An error could happen before tty is initialized or after it has been +// destroyed. Here we use a very simple unbuffered fdStream for printing. +// Only out.print_raw() and out.print_raw_cr() should be used, as other +// printing methods need to allocate large buffer on stack. To format a +// string, use jio_snprintf() with a static buffer or use staticBufferStream. +fdStream VMError::out(defaultStream::output_fd()); +fdStream VMError::log; // error log used by VMError::report_and_die() + /** Expand a pattern into a buffer starting at pos and open a file using constructed path */ static int expand_and_open(const char* pattern, char* buf, size_t buflen, size_t pos) { int fd = -1; @@ -853,13 +861,6 @@ void VMError::report_and_die() { // Don't allocate large buffer on stack static char buffer[O_BUFLEN]; - // An error could happen before tty is initialized or after it has been - // destroyed. Here we use a very simple unbuffered fdStream for printing. - // Only out.print_raw() and out.print_raw_cr() should be used, as other - // printing methods need to allocate large buffer on stack. To format a - // string, use jio_snprintf() with a static buffer or use staticBufferStream. - static fdStream out(defaultStream::output_fd()); - // How many errors occurred in error handler when reporting first_error. static int recursive_error_count; @@ -868,7 +869,6 @@ void VMError::report_and_die() { static bool out_done = false; // done printing to standard out static bool log_done = false; // done saving error log static bool transmit_report_done = false; // done error reporting - static fdStream log; // error log // disble NMT to avoid further exception MemTracker::shutdown(MemTracker::NMT_error_reporting); diff --git a/hotspot/src/share/vm/utilities/vmError.hpp b/hotspot/src/share/vm/utilities/vmError.hpp index f298c1edbf5..1b1608bdc90 100644 --- a/hotspot/src/share/vm/utilities/vmError.hpp +++ b/hotspot/src/share/vm/utilities/vmError.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,6 +96,9 @@ class VMError : public StackObj { return (id != OOM_MALLOC_ERROR) && (id != OOM_MMAP_ERROR); } + static fdStream out; + static fdStream log; // error log used by VMError::report_and_die() + public: // Constructor for crashes diff --git a/hotspot/test/compiler/7088419/CRCTest.java b/hotspot/test/compiler/7088419/CRCTest.java new file mode 100644 index 00000000000..fa1f520cca8 --- /dev/null +++ b/hotspot/test/compiler/7088419/CRCTest.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 7088419 + @run main CRCTest + @summary Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32 and java.util.zip.Adler32 + */ + +import java.nio.ByteBuffer; +import java.util.zip.CRC32; +import java.util.zip.Checksum; + +public class CRCTest { + + public static void main(String[] args) throws Exception { + + byte[] b = initializedBytes(4096 * 4096); + + { + CRC32 crc1 = new CRC32(); + CRC32 crc2 = new CRC32(); + CRC32 crc3 = new CRC32(); + CRC32 crc4 = new CRC32(); + + crc1.update(b, 0, b.length); + updateSerial(crc2, b, 0, b.length); + updateDirect(crc3, b, 0, b.length); + updateSerialSlow(crc4, b, 0, b.length); + + check(crc1, crc2); + check(crc3, crc4); + check(crc1, crc3); + + crc1.update(17); + crc2.update(17); + crc3.update(17); + crc4.update(17); + + crc1.update(b, 1, b.length-2); + updateSerial(crc2, b, 1, b.length-2); + updateDirect(crc3, b, 1, b.length-2); + updateSerialSlow(crc4, b, 1, b.length-2); + + check(crc1, crc2); + check(crc3, crc4); + check(crc1, crc3); + + report("finished huge crc", crc1, crc2, crc3, crc4); + + for (int i = 0; i < 256; i++) { + for (int j = 0; j < 256; j += 1) { + crc1.update(b, i, j); + updateSerial(crc2, b, i, j); + updateDirect(crc3, b, i, j); + updateSerialSlow(crc4, b, i, j); + + check(crc1, crc2); + check(crc3, crc4); + check(crc1, crc3); + + } + } + + report("finished small survey crc", crc1, crc2, crc3, crc4); + } + + } + + private static void report(String s, Checksum crc1, Checksum crc2, + Checksum crc3, Checksum crc4) { + System.out.println(s + ", crc1 = " + crc1.getValue() + + ", crc2 = " + crc2.getValue()+ + ", crc3 = " + crc3.getValue()+ + ", crc4 = " + crc4.getValue()); + } + + private static void check(Checksum crc1, Checksum crc2) throws Exception { + if (crc1.getValue() != crc2.getValue()) { + String s = "value 1 = " + crc1.getValue() + ", value 2 = " + crc2.getValue(); + System.err.println(s); + throw new Exception(s); + } + } + + private static byte[] initializedBytes(int M) { + byte[] bytes = new byte[M]; + for (int i = 0; i < bytes.length; i++) { + bytes[i] = (byte) i; + } + return bytes; + } + + private static void updateSerial(Checksum crc, byte[] b, int start, int length) { + for (int i = 0; i < length; i++) + crc.update(b[i+start]); + } + + private static void updateSerialSlow(Checksum crc, byte[] b, int start, int length) { + for (int i = 0; i < length; i++) + crc.update(b[i+start]); + crc.getValue(); + } + + private static void updateDirect(CRC32 crc3, byte[] b, int start, int length) { + ByteBuffer buf = ByteBuffer.allocateDirect(length); + buf.put(b, start, length); + buf.flip(); + crc3.update(buf); + } +} diff --git a/hotspot/test/gc/arguments/TestUnrecognizedVMOptionsHandling.java b/hotspot/test/gc/arguments/TestUnrecognizedVMOptionsHandling.java new file mode 100644 index 00000000000..a61b5f30940 --- /dev/null +++ b/hotspot/test/gc/arguments/TestUnrecognizedVMOptionsHandling.java @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please 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 TestUnrecognizedVMOptionsHandling + * @key gc + * @bug 8017611 + * @summary Tests handling unrecognized VM options + * @library /testlibrary + * @run main/othervm TestUnrecognizedVMOptionsHandling + */ + +import com.oracle.java.testlibrary.*; + +public class TestUnrecognizedVMOptionsHandling { + + public static void main(String args[]) throws Exception { + // The first two JAVA processes are expected to fail, but with a correct VM option suggestion + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+PrintGc", + "-version" + ); + OutputAnalyzer outputWithError = new OutputAnalyzer(pb.start()); + outputWithError.shouldContain("Did you mean '(+/-)PrintGC'?"); + if (outputWithError.getExitValue() == 0) { + throw new RuntimeException("Not expected to get exit value 0"); + } + + pb = ProcessTools.createJavaProcessBuilder( + "-XX:MaxiumHeapSize=500m", + "-version" + ); + outputWithError = new OutputAnalyzer(pb.start()); + outputWithError.shouldContain("Did you mean 'MaxHeapSize='?"); + if (outputWithError.getExitValue() == 0) { + throw new RuntimeException("Not expected to get exit value 0"); + } + + // The last JAVA process should run successfully for the purpose of sanity check + pb = ProcessTools.createJavaProcessBuilder( + "-XX:+PrintGC", + "-version" + ); + OutputAnalyzer outputWithNoError = new OutputAnalyzer(pb.start()); + outputWithNoError.shouldNotContain("Did you mean '(+/-)PrintGC'?"); + outputWithNoError.shouldHaveExitValue(0); + } +} + diff --git a/hotspot/test/runtime/7196045/Test7196045.java b/hotspot/test/runtime/7196045/Test7196045.java index 59704f72590..4c6fcc8c072 100644 --- a/hotspot/test/runtime/7196045/Test7196045.java +++ b/hotspot/test/runtime/7196045/Test7196045.java @@ -26,7 +26,7 @@ * @test * @bug 7196045 * @summary Possible JVM deadlock in ThreadTimesClosure when using HotspotInternal non-public API. - * @run main/othervm Test7196045 + * @run main/othervm -XX:+UsePerfData Test7196045 */ import java.lang.management.ManagementFactory; diff --git a/hotspot/test/runtime/8001071/Test8001071.java b/hotspot/test/runtime/8001071/Test8001071.java new file mode 100644 index 00000000000..df03e197de8 --- /dev/null +++ b/hotspot/test/runtime/8001071/Test8001071.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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 sun.misc.Unsafe; +import java.lang.reflect.Field; + +@SuppressWarnings("sunapi") +public class Test8001071 { + public static Unsafe unsafe; + + static { + try { + Field f = Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + unsafe = (Unsafe) f.get(null); + } catch ( Exception e ) { + e.printStackTrace(); + } + } + + public static void main(String args[]) { + unsafe.getObject(new Test8001071(), Short.MAX_VALUE); + } + +} diff --git a/hotspot/test/runtime/8001071/Test8001071.sh b/hotspot/test/runtime/8001071/Test8001071.sh new file mode 100644 index 00000000000..79ba2fe503d --- /dev/null +++ b/hotspot/test/runtime/8001071/Test8001071.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. + +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). + +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +# Please 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 8001071 +## @summary Add simple range check into VM implemenation of Unsafe access methods +## @compile Test8001071.java +## @run shell Test8001071.sh +## @author filipp.zhinkin@oracle.com + +VERSION=`${TESTJAVA}/bin/java ${TESTVMOPTS} -version 2>&1` + +if [ -n "`echo $VERSION | grep debug`" -o -n "`echo $VERSION | grep jvmg`" ]; then + echo "Build type check passed" + echo "Continue testing" +else + echo "Fastdebug build is required for this test" + exit 0 +fi + +${TESTJAVA}/bin/java -cp ${TESTCLASSES} ${TESTVMOPTS} Test8001071 2>&1 + +HS_ERR_FILE=hs_err_pid*.log + +if [ ! -f $HS_ERR_FILE ] +then + echo "hs_err_pid log file was not found" + echo "Test failed" + exit 1 +fi + +grep "assert(byte_offset < p_size) failed: Unsafe access: offset.*> object's size.*" $HS_ERR_FILE + +if [ "0" = "$?" ]; +then + echo "Range check assertion failed as expected" + echo "Test passed" + exit 0 +else + echo "Range check assertion was not failed" + echo "Test failed" + exit 1 +fi diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 81a40076854..ed78f7ecae7 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -218,3 +218,4 @@ d583a491d63c49eeda4869525048075da1cb596e jdk8-b93 c84658e1740df64931005a9bc4c8ecef38eb47c3 jdk8-b94 b8c5f4b6f0fffb44618fc609a584953c4ed67c0b jdk8-b95 6121efd299235b057f3de94b0a4158c388c2907c jdk8-b96 +6c830db28d21108f32af990ecf4d80a75887980d jdk8-b97 diff --git a/jaxws/.hgtags b/jaxws/.hgtags index f358e9135cf..fff5bca7aab 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -218,3 +218,4 @@ a0f604766ca14818e2a7b1558cc399499caabf75 jdk8-b92 254c53fd97ab24942043adcfa5c1a0a38a3b274e jdk8-b94 1468c94135f978dd29d03bce2f7d7e952154d144 jdk8-b95 690d34b326bc78a6f5f225522695b41c7f7f70e8 jdk8-b96 +dcde7f049111353ad23175f54985a4f6bfea720c jdk8-b97 diff --git a/jdk/.hgtags b/jdk/.hgtags index e86f63c268a..45fbf746c13 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -219,3 +219,4 @@ a2a2a91075ad85becbe10a39d7fd04ef9bea8df5 jdk8-b92 42aa9f1828852bb8b77e98ec695211493ae0759d jdk8-b95 4a5d3cf2b3af1660db0237e8da324c140e534fa4 jdk8-b96 978a95239044f26dcc8a6d59246be07ad6ca6be2 jdk8-b97 +c4908732fef5235f1b98cafe0ce507771ef7892c jdk8-b98 diff --git a/jdk/src/macosx/native/sun/awt/AWTEvent.m b/jdk/src/macosx/native/sun/awt/AWTEvent.m index fd3caa6051f..b2d54f7e705 100644 --- a/jdk/src/macosx/native/sun/awt/AWTEvent.m +++ b/jdk/src/macosx/native/sun/awt/AWTEvent.m @@ -382,7 +382,7 @@ static unichar NsGetDeadKeyChar(unsigned short keyCode) { TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); CFDataRef uchr = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); - if (uchr == nil) { return; } + if (uchr == nil) { return 0; } const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr); // Carbon modifiers should be used instead of NSEvent modifiers UInt32 modifierKeyState = (GetCurrentEventKeyModifiers() >> 8) & 0xFF; diff --git a/jdk/src/share/classes/java/io/DataInput.java b/jdk/src/share/classes/java/io/DataInput.java index 4dad59d55f3..58a3a2bfd3f 100644 --- a/jdk/src/share/classes/java/io/DataInput.java +++ b/jdk/src/share/classes/java/io/DataInput.java @@ -48,132 +48,87 @@ package java.io; * may be thrown if the input stream has been * closed. * - *

Modified UTF-8

+ *

Modified UTF-8

*

* Implementations of the DataInput and DataOutput interfaces represent * Unicode strings in a format that is a slight modification of UTF-8. * (For information regarding the standard UTF-8 format, see section * 3.9 Unicode Encoding Forms of The Unicode Standard, Version * 4.0). - * Note that in the following tables, the most significant bit appears in the + * Note that in the following table, the most significant bit appears in the * far left-hand column. - *

- * All characters in the range {@code '\u005Cu0001'} to - * {@code '\u005Cu007F'} are represented by a single byte: * *

- * * + * + * + * * - * + * * * * - * + * + * + * * - *
+ * All characters in the range {@code '\u005Cu0001'} to + * {@code '\u005Cu007F'} are represented by a single byte:
Bit ValuesBit Values
Byte 1 - * - * - * - *
0
- *
bits 6-0
- *
- *
0
+ *
bits 6-0
+ *
+ * The null character {@code '\u005Cu0000'} and characters + * in the range {@code '\u005Cu0080'} to {@code '\u005Cu07FF'} are + * represented by a pair of bytes:
- *
- * - *

- * The null character {@code '\u005Cu0000'} and characters in the - * range {@code '\u005Cu0080'} to {@code '\u005Cu07FF'} are - * represented by a pair of bytes: - * - *

- * * * - * + * * * * - * + * * * - * + * + * + * * - *
Bit ValuesBit Values
Byte 1 - * - * - * - *
1
- *
1
- *
0
- *
bits 10-6
- *
- *
1
+ *
1
+ *
0
+ *
bits 10-6
*
Byte 2 - * - * - * - *
1
- *
0
- *
bits 5-0
- *
- *
1
+ *
0
+ *
bits 5-0
+ *
+ * {@code char} values in the range {@code '\u005Cu0800'} + * to {@code '\u005CuFFFF'} are represented by three bytes:
- *
- * - *
- * {@code char} values in the range {@code '\u005Cu0800'} to - * {@code '\u005CuFFFF'} are represented by three bytes: - * - *
- * * * - * + * * * * - * + * * * - * + * * * - * + * *
Bit ValuesBit Values
Byte 1 - * - * - * - *
1
- *
1
- *
1
- *
0
- *
bits 15-12
- *
- *
1
+ *
1
+ *
1
+ *
0
+ *
bits 15-12
*
Byte 2 - * - * - * - *
1
- *
0
- *
bits 11-6
- *
- *
1
+ *
0
+ *
bits 11-6
*
Byte 3 - * - * - * - *
1
- *
0
- *
bits 5-0
- *
- *
1
+ *
0
+ *
bits 5-0
*
- *
- * + * *

* The differences between this format and the * standard UTF-8 format are the following: diff --git a/jdk/src/share/classes/java/io/File.java b/jdk/src/share/classes/java/io/File.java index 6bab9bb21fe..f11530d2f67 100644 --- a/jdk/src/share/classes/java/io/File.java +++ b/jdk/src/share/classes/java/io/File.java @@ -129,7 +129,7 @@ import sun.security.action.GetPropertyAction; * created, the abstract pathname represented by a File object * will never change. * - *

Interoperability with {@code java.nio.file} package

+ *

Interoperability with {@code java.nio.file} package

* *

The {@code java.nio.file} * package defines interfaces and classes for the Java virtual machine to access diff --git a/jdk/src/share/classes/java/io/ObjectStreamField.java b/jdk/src/share/classes/java/io/ObjectStreamField.java index ceae3fd188e..981e4ba8ca2 100644 --- a/jdk/src/share/classes/java/io/ObjectStreamField.java +++ b/jdk/src/share/classes/java/io/ObjectStreamField.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -240,6 +240,8 @@ public class ObjectStreamField * Returns boolean value indicating whether or not the serializable field * represented by this ObjectStreamField instance is unshared. * + * @return {@code true} if this field is unshared + * * @since 1.4 */ public boolean isUnshared() { diff --git a/jdk/src/share/classes/java/io/RandomAccessFile.java b/jdk/src/share/classes/java/io/RandomAccessFile.java index 5e32ad5dba1..440cd225c80 100644 --- a/jdk/src/share/classes/java/io/RandomAccessFile.java +++ b/jdk/src/share/classes/java/io/RandomAccessFile.java @@ -128,7 +128,7 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { * meanings are: * * - * + * * * *

Value

Meaning

ValueMeaning
"r" Open for reading only. Invoking any of the write * methods of the resulting object will cause an {@link diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index 2e47377996f..9df0805167b 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -157,10 +157,10 @@ public final class Class implements java.io.Serializable, * * The string is formatted as a list of type modifiers, if any, * followed by the kind of type (empty string for primitive types - * and {@code class}, {@code enum}, {@code interface}, or {@code - * @interface}, as appropriate), followed by the type's name, - * followed by an angle-bracketed comma-separated list of the - * type's type parameters, if any. + * and {@code class}, {@code enum}, {@code interface}, or + * @{@code interface}, as appropriate), followed + * by the type's name, followed by an angle-bracketed + * comma-separated list of the type's type parameters, if any. * * A space is used to separate modifiers from one another and to * separate any modifiers from the kind of type. The modifiers diff --git a/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java b/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java index 892a9dd5316..79b3b69fcf3 100644 --- a/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java +++ b/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java @@ -24,24 +24,23 @@ */ package java.lang.invoke; -import java.io.Serializable; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; import sun.invoke.util.Wrapper; -import static sun.invoke.util.Wrapper.*; + +import static sun.invoke.util.Wrapper.forPrimitiveType; +import static sun.invoke.util.Wrapper.forWrapperType; +import static sun.invoke.util.Wrapper.isWrapperType; /** - * Abstract implementation of a lambda metafactory which provides parameter unrolling and input validation. + * Abstract implementation of a lambda metafactory which provides parameter + * unrolling and input validation. * * @see LambdaMetafactory */ /* package */ abstract class AbstractValidatingLambdaMetafactory { /* - * For context, the comments for the following fields are marked in quotes with their values, given this program: + * For context, the comments for the following fields are marked in quotes + * with their values, given this program: * interface II { Object foo(T x); } * interface JJ extends II { } * class CC { String impl(int i) { return "impl:"+i; }} @@ -54,9 +53,7 @@ import static sun.invoke.util.Wrapper.*; final Class targetClass; // The class calling the meta-factory via invokedynamic "class X" final MethodType invokedType; // The type of the invoked method "(CC)II" final Class samBase; // The type of the returned instance "interface JJ" - final MethodHandle samMethod; // Raw method handle for the functional interface method - final MethodHandleInfo samInfo; // Info about the SAM method handle "MethodHandleInfo[9 II.foo(Object)Object]" - final Class samClass; // Interface containing the SAM method "interface II" + final String samMethodName; // Name of the SAM method "foo" final MethodType samMethodType; // Type of the SAM method "(Object)Object" final MethodHandle implMethod; // Raw method handle for the implementation method final MethodHandleInfo implInfo; // Info about the implementation method handle "MethodHandleInfo[5 CC.impl(int)String]" @@ -67,44 +64,64 @@ import static sun.invoke.util.Wrapper.*; final MethodType instantiatedMethodType; // Instantiated erased functional interface method type "(Integer)Object" final boolean isSerializable; // Should the returned instance be serializable final Class[] markerInterfaces; // Additional marker interfaces to be implemented + final MethodType[] additionalBridges; // Signatures of additional methods to bridge /** * Meta-factory constructor. * - * @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges - * of the caller. - * @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes the - * expected static type of the returned lambda object, and the static types of the captured - * arguments for the lambda. In the event that the implementation method is an instance method, - * the first argument in the invocation signature will correspond to the receiver. - * @param samMethod The primary method in the functional interface to which the lambda or method reference is - * being converted, represented as a method handle. - * @param implMethod The implementation method which should be called (with suitable adaptation of argument - * types, return types, and adjustment for captured arguments) when methods of the resulting - * functional interface instance are invoked. - * @param instantiatedMethodType The signature of the primary functional interface method after type variables - * are substituted with their instantiation from the capture site + * @param caller Stacked automatically by VM; represents a lookup context + * with the accessibility privileges of the caller. + * @param invokedType Stacked automatically by VM; the signature of the + * invoked method, which includes the expected static + * type of the returned lambda object, and the static + * types of the captured arguments for the lambda. In + * the event that the implementation method is an + * instance method, the first argument in the invocation + * signature will correspond to the receiver. + * @param samMethodName Name of the method in the functional interface to + * which the lambda or method reference is being + * converted, represented as a String. + * @param samMethodType Type of the method in the functional interface to + * which the lambda or method reference is being + * converted, represented as a MethodType. + * @param implMethod The implementation method which should be called + * (with suitable adaptation of argument types, return + * types, and adjustment for captured arguments) when + * methods of the resulting functional interface instance + * are invoked. + * @param instantiatedMethodType The signature of the primary functional + * interface method after type variables are + * substituted with their instantiation from + * the capture site + * @param isSerializable Should the lambda be made serializable? If set, + * either the target type or one of the additional SAM + * types must extend {@code Serializable}. + * @param markerInterfaces Additional interfaces which the lambda object + * should implement. + * @param additionalBridges Method types for additional signatures to be + * bridged to the implementation method * @throws ReflectiveOperationException - * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated + * @throws LambdaConversionException If any of the meta-factory protocol + * invariants are violated */ AbstractValidatingLambdaMetafactory(MethodHandles.Lookup caller, MethodType invokedType, - MethodHandle samMethod, + String samMethodName, + MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType, - int flags, - Class[] markerInterfaces) + boolean isSerializable, + Class[] markerInterfaces, + MethodType[] additionalBridges) throws ReflectiveOperationException, LambdaConversionException { this.targetClass = caller.lookupClass(); this.invokedType = invokedType; this.samBase = invokedType.returnType(); - this.samMethod = samMethod; - this.samInfo = new MethodHandleInfo(samMethod); - this.samClass = samInfo.getDeclaringClass(); - this.samMethodType = samInfo.getMethodType(); + this.samMethodName = samMethodName; + this.samMethodType = samMethodType; this.implMethod = implMethod; this.implInfo = new MethodHandleInfo(implMethod); @@ -118,32 +135,24 @@ import static sun.invoke.util.Wrapper.*; implKind == MethodHandleInfo.REF_invokeInterface; this.implDefiningClass = implInfo.getDeclaringClass(); this.implMethodType = implInfo.getMethodType(); - this.instantiatedMethodType = instantiatedMethodType; + this.isSerializable = isSerializable; + this.markerInterfaces = markerInterfaces; + this.additionalBridges = additionalBridges; - if (!samClass.isInterface()) { + if (!samBase.isInterface()) { throw new LambdaConversionException(String.format( "Functional interface %s is not an interface", - samClass.getName())); + samBase.getName())); } - boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(samBase); for (Class c : markerInterfaces) { if (!c.isInterface()) { throw new LambdaConversionException(String.format( "Marker interface %s is not an interface", c.getName())); } - foundSerializableSupertype |= Serializable.class.isAssignableFrom(c); } - this.isSerializable = ((flags & LambdaMetafactory.FLAG_SERIALIZABLE) != 0) - || foundSerializableSupertype; - - if (isSerializable && !foundSerializableSupertype) { - markerInterfaces = Arrays.copyOf(markerInterfaces, markerInterfaces.length + 1); - markerInterfaces[markerInterfaces.length-1] = Serializable.class; - } - this.markerInterfaces = markerInterfaces; } /** @@ -153,20 +162,14 @@ import static sun.invoke.util.Wrapper.*; * functional interface * @throws ReflectiveOperationException */ - abstract CallSite buildCallSite() throws ReflectiveOperationException, LambdaConversionException; + abstract CallSite buildCallSite() + throws ReflectiveOperationException, LambdaConversionException; /** * Check the meta-factory arguments for errors * @throws LambdaConversionException if there are improper conversions */ void validateMetafactoryArgs() throws LambdaConversionException { - // Check target type is a subtype of class where SAM method is defined - if (!samClass.isAssignableFrom(samBase)) { - throw new LambdaConversionException( - String.format("Invalid target type %s for lambda conversion; not a subtype of functional interface %s", - samBase.getName(), samClass.getName())); - } - switch (implKind) { case MethodHandleInfo.REF_invokeInterface: case MethodHandleInfo.REF_invokeVirtual: @@ -265,9 +268,9 @@ import static sun.invoke.util.Wrapper.*; } /** - * Check type adaptability - * @param fromType - * @param toType + * Check type adaptability for parameter types. + * @param fromType Type to convert from + * @param toType Type to convert to * @param strict If true, do strict checks, else allow that fromType may be parameterized * @return True if 'fromType' can be passed to an argument of 'toType' */ @@ -299,15 +302,14 @@ import static sun.invoke.util.Wrapper.*; } } else { // both are reference types: fromType should be a superclass of toType. - return strict? toType.isAssignableFrom(fromType) : true; + return !strict || toType.isAssignableFrom(fromType); } } } /** - * Check type adaptability for return types -- special handling of void type) and parameterized fromType - * @param fromType - * @param toType + * Check type adaptability for return types -- + * special handling of void type) and parameterized fromType * @return True if 'fromType' can be converted to 'toType' */ private boolean isAdaptableToAsReturn(Class fromType, Class toType) { @@ -338,89 +340,4 @@ import static sun.invoke.util.Wrapper.*; } ***********************/ - /** - * Find the functional interface method and corresponding abstract methods - * which should be bridged. The functional interface method and those to be - * bridged will have the same name and number of parameters. Check for - * matching default methods (non-abstract), the VM will create bridges for - * default methods; We don't have enough readily available type information - * to distinguish between where the functional interface method should be - * bridged and where the default method should be bridged; This situation is - * flagged. - */ - class MethodAnalyzer { - private final Method[] methods = samBase.getMethods(); - - private Method samMethod = null; - private final List methodsToBridge = new ArrayList<>(methods.length); - private boolean conflictFoundBetweenDefaultAndBridge = false; - - MethodAnalyzer() { - String samMethodName = samInfo.getName(); - Class[] samParamTypes = samMethodType.parameterArray(); - int samParamLength = samParamTypes.length; - Class samReturnType = samMethodType.returnType(); - Class objectClass = Object.class; - List defaultMethods = new ArrayList<>(methods.length); - - for (Method m : methods) { - if (m.getName().equals(samMethodName) && m.getDeclaringClass() != objectClass) { - Class[] mParamTypes = m.getParameterTypes(); - if (mParamTypes.length == samParamLength) { - // Method matches name and parameter length -- and is not Object - if (Modifier.isAbstract(m.getModifiers())) { - // Method is abstract - if (m.getReturnType().equals(samReturnType) - && Arrays.equals(mParamTypes, samParamTypes)) { - // Exact match, this is the SAM method signature - samMethod = m; - } else if (!hasMatchingBridgeSignature(m)) { - // Record bridges, exclude methods with duplicate signatures - methodsToBridge.add(m); - } - } else { - // Record default methods for conflict testing - defaultMethods.add(m); - } - } - } - } - for (Method dm : defaultMethods) { - if (hasMatchingBridgeSignature(dm)) { - conflictFoundBetweenDefaultAndBridge = true; - break; - } - } - } - - Method getSamMethod() { - return samMethod; - } - - List getMethodsToBridge() { - return methodsToBridge; - } - - boolean conflictFoundBetweenDefaultAndBridge() { - return conflictFoundBetweenDefaultAndBridge; - } - - /** - * Search the list of previously found bridge methods to determine if there is a method with the same signature - * (return and parameter types) as the specified method. - * - * @param m The method to match - * @return True if the method was found, False otherwise - */ - private boolean hasMatchingBridgeSignature(Method m) { - Class[] ptypes = m.getParameterTypes(); - Class rtype = m.getReturnType(); - for (Method md : methodsToBridge) { - if (md.getReturnType().equals(rtype) && Arrays.equals(ptypes, md.getParameterTypes())) { - return true; - } - } - return false; - } - } } diff --git a/jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java b/jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java index 0b6f4016b1d..f74678e1bae 100644 --- a/jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java +++ b/jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java @@ -25,22 +25,26 @@ package java.lang.invoke; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.security.ProtectionDomain; -import java.util.concurrent.atomic.AtomicInteger; import jdk.internal.org.objectweb.asm.*; -import static jdk.internal.org.objectweb.asm.Opcodes.*; import sun.misc.Unsafe; + +import java.lang.reflect.Constructor; import java.security.AccessController; import java.security.PrivilegedAction; +import java.security.ProtectionDomain; +import java.util.concurrent.atomic.AtomicInteger; + +import static jdk.internal.org.objectweb.asm.Opcodes.*; /** - * Lambda metafactory implementation which dynamically creates an inner-class-like class per lambda callsite. + * Lambda metafactory implementation which dynamically creates an + * inner-class-like class per lambda callsite. * * @see LambdaMetafactory */ /* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory { + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + private static final int CLASSFILE_VERSION = 51; private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE); private static final String NAME_MAGIC_ACCESSOR_IMPL = "java/lang/invoke/MagicLambdaImpl"; @@ -54,7 +58,7 @@ import java.security.PrivilegedAction; private static final String DESCR_CTOR_SERIALIZED_LAMBDA = MethodType.methodType(void.class, Class.class, - int.class, String.class, String.class, String.class, + String.class, String.class, String.class, int.class, String.class, String.class, String.class, String.class, Object[].class).toMethodDescriptorString(); @@ -77,36 +81,56 @@ import java.security.PrivilegedAction; private final Type[] instantiatedArgumentTypes; // ASM types for the functional interface arguments /** - * General meta-factory constructor, standard cases and allowing for uncommon options such as serialization. + * General meta-factory constructor, supporting both standard cases and + * allowing for uncommon options such as serialization or bridging. * - * @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges - * of the caller. - * @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes the - * expected static type of the returned lambda object, and the static types of the captured - * arguments for the lambda. In the event that the implementation method is an instance method, - * the first argument in the invocation signature will correspond to the receiver. - * @param samMethod The primary method in the functional interface to which the lambda or method reference is - * being converted, represented as a method handle. - * @param implMethod The implementation method which should be called (with suitable adaptation of argument - * types, return types, and adjustment for captured arguments) when methods of the resulting - * functional interface instance are invoked. - * @param instantiatedMethodType The signature of the primary functional interface method after type variables - * are substituted with their instantiation from the capture site - * @param flags A bitmask containing flags that may influence the translation of this lambda expression. Defined - * fields include FLAG_SERIALIZABLE. - * @param markerInterfaces Additional interfaces which the lambda object should implement. + * @param caller Stacked automatically by VM; represents a lookup context + * with the accessibility privileges of the caller. + * @param invokedType Stacked automatically by VM; the signature of the + * invoked method, which includes the expected static + * type of the returned lambda object, and the static + * types of the captured arguments for the lambda. In + * the event that the implementation method is an + * instance method, the first argument in the invocation + * signature will correspond to the receiver. + * @param samMethodName Name of the method in the functional interface to + * which the lambda or method reference is being + * converted, represented as a String. + * @param samMethodType Type of the method in the functional interface to + * which the lambda or method reference is being + * converted, represented as a MethodType. + * @param implMethod The implementation method which should be called (with + * suitable adaptation of argument types, return types, + * and adjustment for captured arguments) when methods of + * the resulting functional interface instance are invoked. + * @param instantiatedMethodType The signature of the primary functional + * interface method after type variables are + * substituted with their instantiation from + * the capture site + * @param isSerializable Should the lambda be made serializable? If set, + * either the target type or one of the additional SAM + * types must extend {@code Serializable}. + * @param markerInterfaces Additional interfaces which the lambda object + * should implement. + * @param additionalBridges Method types for additional signatures to be + * bridged to the implementation method * @throws ReflectiveOperationException - * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated + * @throws LambdaConversionException If any of the meta-factory protocol + * invariants are violated */ public InnerClassLambdaMetafactory(MethodHandles.Lookup caller, MethodType invokedType, - MethodHandle samMethod, + String samMethodName, + MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType, - int flags, - Class[] markerInterfaces) + boolean isSerializable, + Class[] markerInterfaces, + MethodType[] additionalBridges) throws ReflectiveOperationException, LambdaConversionException { - super(caller, invokedType, samMethod, implMethod, instantiatedMethodType, flags, markerInterfaces); + super(caller, invokedType, samMethodName, samMethodType, + implMethod, instantiatedMethodType, + isSerializable, markerInterfaces, additionalBridges); implMethodClassName = implDefiningClass.getName().replace('.', '/'); implMethodName = implInfo.getName(); implMethodDesc = implMethodType.toMethodDescriptorString(); @@ -124,7 +148,8 @@ import java.security.PrivilegedAction; for (int i = 0; i < argTypes.length; i++) { argNames[i] = "arg$" + (i + 1); } - instantiatedArgumentTypes = Type.getArgumentTypes(instantiatedMethodType.toMethodDescriptorString()); + instantiatedArgumentTypes = Type.getArgumentTypes( + instantiatedMethodType.toMethodDescriptorString()); } /** @@ -136,7 +161,8 @@ import java.security.PrivilegedAction; * @return a CallSite, which, when invoked, will return an instance of the * functional interface * @throws ReflectiveOperationException - * @throws LambdaConversionException If properly formed functional interface is not found + * @throws LambdaConversionException If properly formed functional interface + * is not found */ @Override CallSite buildCallSite() throws ReflectiveOperationException, LambdaConversionException { @@ -167,8 +193,8 @@ import java.security.PrivilegedAction; } else { return new ConstantCallSite( MethodHandles.Lookup.IMPL_LOOKUP - .findConstructor(innerClass, constructorType) - .asType(constructorType.changeReturnType(samBase))); + .findConstructor(innerClass, constructorType) + .asType(constructorType.changeReturnType(samBase))); } } @@ -176,13 +202,20 @@ import java.security.PrivilegedAction; * Generate a class file which implements the functional * interface, define and return the class. * + * @implNote The class that is generated does not include signature + * information for exceptions that may be present on the SAM method. + * This is to reduce classfile size, and is harmless as checked exceptions + * are erased anyway, no one will ever compile against this classfile, + * and we make no guarantees about the reflective properties of lambda + * objects. + * * @return a Class which implements the functional interface - * @throws LambdaConversionException If properly formed functional interface is not found + * @throws LambdaConversionException If properly formed functional interface + * is not found */ private Class spinInnerClass() throws LambdaConversionException { - String samName = samBase.getName().replace('.', '/'); String[] interfaces = new String[markerInterfaces.length + 1]; - interfaces[0] = samName; + interfaces[0] = samBase.getName().replace('.', '/'); for (int i=0; i) Unsafe.getUnsafe().defineClass(lambdaClassName, classBytes, 0, classBytes.length, - loader, pd); + return UNSAFE.defineClass(lambdaClassName, + classBytes, 0, classBytes.length, + loader, pd); } /** @@ -258,19 +293,23 @@ import java.security.PrivilegedAction; */ private void generateConstructor() { // Generate constructor - MethodVisitor ctor = cw.visitMethod(ACC_PRIVATE, NAME_CTOR, constructorDesc, null, null); + MethodVisitor ctor = cw.visitMethod(ACC_PRIVATE, NAME_CTOR, + constructorDesc, null, null); ctor.visitCode(); ctor.visitVarInsn(ALOAD, 0); - ctor.visitMethodInsn(INVOKESPECIAL, NAME_MAGIC_ACCESSOR_IMPL, NAME_CTOR, METHOD_DESCRIPTOR_VOID); + ctor.visitMethodInsn(INVOKESPECIAL, NAME_MAGIC_ACCESSOR_IMPL, NAME_CTOR, + METHOD_DESCRIPTOR_VOID); int lvIndex = 0; for (int i = 0; i < argTypes.length; i++) { ctor.visitVarInsn(ALOAD, 0); ctor.visitVarInsn(argTypes[i].getOpcode(ILOAD), lvIndex + 1); lvIndex += argTypes[i].getSize(); - ctor.visitFieldInsn(PUTFIELD, lambdaClassName, argNames[i], argTypes[i].getDescriptor()); + ctor.visitFieldInsn(PUTFIELD, lambdaClassName, argNames[i], + argTypes[i].getDescriptor()); } ctor.visitInsn(RETURN); - ctor.visitMaxs(-1, -1); // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored + // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored + ctor.visitMaxs(-1, -1); ctor.visitEnd(); } @@ -279,18 +318,18 @@ import java.security.PrivilegedAction; */ private void generateWriteReplace() { TypeConvertingMethodAdapter mv - = new TypeConvertingMethodAdapter(cw.visitMethod(ACC_PRIVATE + ACC_FINAL, - NAME_METHOD_WRITE_REPLACE, DESCR_METHOD_WRITE_REPLACE, - null, null)); + = new TypeConvertingMethodAdapter( + cw.visitMethod(ACC_PRIVATE + ACC_FINAL, + NAME_METHOD_WRITE_REPLACE, DESCR_METHOD_WRITE_REPLACE, + null, null)); mv.visitCode(); mv.visitTypeInsn(NEW, NAME_SERIALIZED_LAMBDA); - mv.visitInsn(DUP);; + mv.visitInsn(DUP); mv.visitLdcInsn(Type.getType(targetClass)); - mv.visitLdcInsn(samInfo.getReferenceKind()); mv.visitLdcInsn(invokedType.returnType().getName().replace('.', '/')); - mv.visitLdcInsn(samInfo.getName()); - mv.visitLdcInsn(samInfo.getMethodType().toMethodDescriptorString()); + mv.visitLdcInsn(samMethodName); + mv.visitLdcInsn(samMethodType.toMethodDescriptorString()); mv.visitLdcInsn(implInfo.getReferenceKind()); mv.visitLdcInsn(implInfo.getDeclaringClass().getName().replace('.', '/')); mv.visitLdcInsn(implInfo.getName()); @@ -303,35 +342,19 @@ import java.security.PrivilegedAction; mv.visitInsn(DUP); mv.iconst(i); mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], argTypes[i].getDescriptor()); + mv.visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], + argTypes[i].getDescriptor()); mv.boxIfTypePrimitive(argTypes[i]); mv.visitInsn(AASTORE); } mv.visitMethodInsn(INVOKESPECIAL, NAME_SERIALIZED_LAMBDA, NAME_CTOR, DESCR_CTOR_SERIALIZED_LAMBDA); mv.visitInsn(ARETURN); - mv.visitMaxs(-1, -1); // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored + // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored + mv.visitMaxs(-1, -1); mv.visitEnd(); } - /** - * Generate a method which calls the lambda implementation method, - * converting arguments, as needed. - * @param m The method whose signature should be generated - * @param isBridge True if this methods should be flagged as a bridge - */ - private void generateForwardingMethod(Method m, boolean isBridge) { - Class[] exceptionTypes = m.getExceptionTypes(); - String[] exceptionNames = new String[exceptionTypes.length]; - for (int i = 0; i < exceptionTypes.length; i++) { - exceptionNames[i] = exceptionTypes[i].getName().replace('.', '/'); - } - String methodDescriptor = Type.getMethodDescriptor(m); - int access = isBridge? ACC_PUBLIC | ACC_BRIDGE : ACC_PUBLIC; - MethodVisitor mv = cw.visitMethod(access, m.getName(), methodDescriptor, null, exceptionNames); - new ForwardingMethodGenerator(mv).generate(m); - } - /** * This class generates a method body which calls the lambda implementation * method, converting arguments, as needed. @@ -342,36 +365,39 @@ import java.security.PrivilegedAction; super(mv); } - void generate(Method m) throws InternalError { + void generate(String methodDescriptor) { visitCode(); if (implKind == MethodHandleInfo.REF_newInvokeSpecial) { visitTypeInsn(NEW, implMethodClassName); - visitInsn(DUP);; + visitInsn(DUP); } for (int i = 0; i < argTypes.length; i++) { visitVarInsn(ALOAD, 0); - visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], argTypes[i].getDescriptor()); + visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], + argTypes[i].getDescriptor()); } - convertArgumentTypes(Type.getArgumentTypes(m)); + convertArgumentTypes(Type.getArgumentTypes(methodDescriptor)); // Invoke the method we want to forward to visitMethodInsn(invocationOpcode(), implMethodClassName, implMethodName, implMethodDesc); // Convert the return value (if any) and return it - // Note: if adapting from non-void to void, the 'return' instruction will pop the unneeded result - Type samReturnType = Type.getReturnType(m); + // Note: if adapting from non-void to void, the 'return' + // instruction will pop the unneeded result + Type samReturnType = Type.getReturnType(methodDescriptor); convertType(implMethodReturnType, samReturnType, samReturnType); visitInsn(samReturnType.getOpcode(Opcodes.IRETURN)); - - visitMaxs(-1, -1); // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored + // Maxs computed by ClassWriter.COMPUTE_MAXS,these arguments ignored + visitMaxs(-1, -1); visitEnd(); } private void convertArgumentTypes(Type[] samArgumentTypes) { int lvIndex = 0; - boolean samIncludesReceiver = implIsInstanceMethod && argTypes.length == 0; + boolean samIncludesReceiver = implIsInstanceMethod && + argTypes.length == 0; int samReceiverLength = samIncludesReceiver ? 1 : 0; if (samIncludesReceiver) { // push receiver @@ -395,7 +421,9 @@ import java.security.PrivilegedAction; } private void convertType(Type argType, Type targetType, Type functionalType) { - convertType(argType.getDescriptor(), targetType.getDescriptor(), functionalType.getDescriptor()); + convertType(argType.getDescriptor(), + targetType.getDescriptor(), + functionalType.getDescriptor()); } private int invocationOpcode() throws InternalError { diff --git a/jdk/src/share/classes/java/lang/invoke/LambdaConversionException.java b/jdk/src/share/classes/java/lang/invoke/LambdaConversionException.java index 5cc3c626e36..e1123da59d8 100644 --- a/jdk/src/share/classes/java/lang/invoke/LambdaConversionException.java +++ b/jdk/src/share/classes/java/lang/invoke/LambdaConversionException.java @@ -29,6 +29,8 @@ package java.lang.invoke; * LambdaConversionException */ public class LambdaConversionException extends Exception { + private static final long serialVersionUID = 292L + 8L; + /** * Constructs a {@code LambdaConversionException}. */ diff --git a/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java b/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java index e03dda002d1..87c7923d9ba 100644 --- a/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java +++ b/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java @@ -25,6 +25,9 @@ package java.lang.invoke; +import java.io.Serializable; +import java.util.Arrays; + /** *

Bootstrap methods for converting lambda expressions and method references to functional interface objects.

* @@ -44,16 +47,11 @@ package java.lang.invoke; * *

When parameterized types are used, the instantiated type of the functional interface method may be different * from that in the functional interface. For example, consider - * interface I<T> { int m(T x); } if this functional interface type is used in a lambda - * I<Byte> v = ..., we need both the actual functional interface method which has the signature - * (Object)int and the erased instantiated type of the functional interface method (or simply + * {@code interface I { int m(T x); }} if this functional interface type is used in a lambda + * {@code I; v = ...}, we need both the actual functional interface method which has the signature + * {@code (Object)int} and the erased instantiated type of the functional interface method (or simply * instantiated method type), which has signature - * (Byte)int. - * - *

While functional interfaces only have a single abstract method from the language perspective (concrete - * methods in Object are and default methods may be present), at the bytecode level they may actually have multiple - * methods because of the need for bridge methods. Invoking any of these methods on the lambda object will result - * in invoking the implementation method. + * {@code (Byte)int}. * *

The argument list of the implementation method and the argument list of the functional interface method(s) * may differ in several ways. The implementation methods may have additional arguments to accommodate arguments @@ -137,108 +135,147 @@ package java.lang.invoke; *

* - * The default bootstrap ({@link #metaFactory}) represents the common cases and uses an optimized protocol. - * Alternate bootstraps (e.g., {@link #altMetaFactory}) exist to support uncommon cases such as serialization + * The default bootstrap ({@link #metafactory}) represents the common cases and uses an optimized protocol. + * Alternate bootstraps (e.g., {@link #altMetafactory}) exist to support uncommon cases such as serialization * or additional marker superinterfaces. * */ public class LambdaMetafactory { - /** Flag for alternate metafactories indicating the lambda object is must to be serializable */ + /** Flag for alternate metafactories indicating the lambda object is + * must to be serializable */ public static final int FLAG_SERIALIZABLE = 1 << 0; /** - * Flag for alternate metafactories indicating the lambda object implements other marker interfaces + * Flag for alternate metafactories indicating the lambda object implements + * other marker interfaces * besides Serializable */ public static final int FLAG_MARKERS = 1 << 1; + /** + * Flag for alternate metafactories indicating the lambda object requires + * additional bridge methods + */ + public static final int FLAG_BRIDGES = 1 << 2; + private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; + private static final MethodType[] EMPTY_MT_ARRAY = new MethodType[0]; /** - * Standard meta-factory for conversion of lambda expressions or method references to functional interfaces. + * Standard meta-factory for conversion of lambda expressions or method + * references to functional interfaces. * - * @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges - * of the caller. - * @param invokedName Stacked automatically by VM; the name of the invoked method as it appears at the call site. - * Currently unused. - * @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes the - * expected static type of the returned lambda object, and the static types of the captured - * arguments for the lambda. In the event that the implementation method is an instance method, - * the first argument in the invocation signature will correspond to the receiver. - * @param samMethod The primary method in the functional interface to which the lambda or method reference is - * being converted, represented as a method handle. - * @param implMethod The implementation method which should be called (with suitable adaptation of argument - * types, return types, and adjustment for captured arguments) when methods of the resulting - * functional interface instance are invoked. - * @param instantiatedMethodType The signature of the primary functional interface method after type variables - * are substituted with their instantiation from the capture site - * @return a CallSite, which, when invoked, will return an instance of the functional interface - * @throws ReflectiveOperationException if the caller is not able to reconstruct one of the method handles - * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated + * @param caller Stacked automatically by VM; represents a lookup context + * with the accessibility privileges of the caller. + * @param invokedName Stacked automatically by VM; the name of the invoked + * method as it appears at the call site. + * Used as the name of the functional interface method + * to which the lambda or method reference is being + * converted. + * @param invokedType Stacked automatically by VM; the signature of the + * invoked method, which includes the expected static + * type of the returned lambda object, and the static + * types of the captured arguments for the lambda. + * In the event that the implementation method is an + * instance method, the first argument in the invocation + * signature will correspond to the receiver. + * @param samMethodType MethodType of the method in the functional interface + * to which the lambda or method reference is being + * converted, represented as a MethodType. + * @param implMethod The implementation method which should be called + * (with suitable adaptation of argument types, return + * types, and adjustment for captured arguments) when + * methods of the resulting functional interface instance + * are invoked. + * @param instantiatedMethodType The signature of the primary functional + * interface method after type variables + * are substituted with their instantiation + * from the capture site + * @return a CallSite, which, when invoked, will return an instance of the + * functional interface + * @throws ReflectiveOperationException if the caller is not able to + * reconstruct one of the method handles + * @throws LambdaConversionException If any of the meta-factory protocol + * invariants are violated */ - public static CallSite metaFactory(MethodHandles.Lookup caller, + public static CallSite metafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, - MethodHandle samMethod, + MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType) throws ReflectiveOperationException, LambdaConversionException { AbstractValidatingLambdaMetafactory mf; - mf = new InnerClassLambdaMetafactory(caller, invokedType, samMethod, implMethod, instantiatedMethodType, - 0, EMPTY_CLASS_ARRAY); + mf = new InnerClassLambdaMetafactory(caller, invokedType, + invokedName, samMethodType, + implMethod, instantiatedMethodType, + false, EMPTY_CLASS_ARRAY, EMPTY_MT_ARRAY); mf.validateMetafactoryArgs(); return mf.buildCallSite(); } /** - * Alternate meta-factory for conversion of lambda expressions or method references to functional interfaces, - * which supports serialization and other uncommon options. + * Alternate meta-factory for conversion of lambda expressions or method + * references to functional interfaces, which supports serialization and + * other uncommon options. * * The declared argument list for this method is: * - * CallSite altMetaFactory(MethodHandles.Lookup caller, + * CallSite altMetafactory(MethodHandles.Lookup caller, * String invokedName, * MethodType invokedType, * Object... args) * * but it behaves as if the argument list is: * - * CallSite altMetaFactory(MethodHandles.Lookup caller, + * CallSite altMetafactory(MethodHandles.Lookup caller, * String invokedName, * MethodType invokedType, - * MethodHandle samMethod + * MethodType samMethodType * MethodHandle implMethod, * MethodType instantiatedMethodType, * int flags, * int markerInterfaceCount, // IF flags has MARKERS set * Class... markerInterfaces // IF flags has MARKERS set + * int bridgeCount, // IF flags has BRIDGES set + * MethodType... bridges // IF flags has BRIDGES set * ) * * - * @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges - * of the caller. - * @param invokedName Stacked automatically by VM; the name of the invoked method as it appears at the call site. - * Currently unused. - * @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes thefu - * expected static type of the returned lambda object, and the static types of the captured - * arguments for the lambda. In the event that the implementation method is an instance method, - * the first argument in the invocation signature will correspond to the receiver. - * @param args argument to pass, flags, marker interface count, and marker interfaces as described above - * @return a CallSite, which, when invoked, will return an instance of the functional interface - * @throws ReflectiveOperationException if the caller is not able to reconstruct one of the method handles - * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated + * @param caller Stacked automatically by VM; represents a lookup context + * with the accessibility privileges of the caller. + * @param invokedName Stacked automatically by VM; the name of the invoked + * method as it appears at the call site. + * Used as the name of the functional interface method + * to which the lambda or method reference is being + * converted. + * @param invokedType Stacked automatically by VM; the signature of the + * invoked method, which includes the expected static + * type of the returned lambda object, and the static + * types of the captured arguments for the lambda. + * In the event that the implementation method is an + * instance method, the first argument in the invocation + * signature will correspond to the receiver. + * @param args flags and optional arguments, as described above + * @return a CallSite, which, when invoked, will return an instance of the + * functional interface + * @throws ReflectiveOperationException if the caller is not able to + * reconstruct one of the method handles + * @throws LambdaConversionException If any of the meta-factory protocol + * invariants are violated */ - public static CallSite altMetaFactory(MethodHandles.Lookup caller, + public static CallSite altMetafactory(MethodHandles.Lookup caller, String invokedName, MethodType invokedType, Object... args) throws ReflectiveOperationException, LambdaConversionException { - MethodHandle samMethod = (MethodHandle)args[0]; + MethodType samMethodType = (MethodType)args[0]; MethodHandle implMethod = (MethodHandle)args[1]; MethodType instantiatedMethodType = (MethodType)args[2]; int flags = (Integer) args[3]; Class[] markerInterfaces; + MethodType[] bridges; int argIndex = 4; if ((flags & FLAG_MARKERS) != 0) { int markerCount = (Integer) args[argIndex++]; @@ -248,9 +285,33 @@ public class LambdaMetafactory { } else markerInterfaces = EMPTY_CLASS_ARRAY; - AbstractValidatingLambdaMetafactory mf; - mf = new InnerClassLambdaMetafactory(caller, invokedType, samMethod, implMethod, instantiatedMethodType, - flags, markerInterfaces); + if ((flags & FLAG_BRIDGES) != 0) { + int bridgeCount = (Integer) args[argIndex++]; + bridges = new MethodType[bridgeCount]; + System.arraycopy(args, argIndex, bridges, 0, bridgeCount); + argIndex += bridgeCount; + } + else + bridges = EMPTY_MT_ARRAY; + + boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(invokedType.returnType()); + for (Class c : markerInterfaces) + foundSerializableSupertype |= Serializable.class.isAssignableFrom(c); + boolean isSerializable = ((flags & LambdaMetafactory.FLAG_SERIALIZABLE) != 0) + || foundSerializableSupertype; + + if (isSerializable && !foundSerializableSupertype) { + markerInterfaces = Arrays.copyOf(markerInterfaces, markerInterfaces.length + 1); + markerInterfaces[markerInterfaces.length-1] = Serializable.class; + } + + AbstractValidatingLambdaMetafactory mf + = new InnerClassLambdaMetafactory(caller, invokedType, + invokedName, samMethodType, + implMethod, + instantiatedMethodType, + isSerializable, + markerInterfaces, bridges); mf.validateMetafactoryArgs(); return mf.buildCallSite(); } diff --git a/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java b/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java index 558fa5ab6ee..a775fc43e34 100644 --- a/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java +++ b/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java @@ -44,7 +44,6 @@ public final class SerializedLambda implements Serializable { private final String functionalInterfaceClass; private final String functionalInterfaceMethodName; private final String functionalInterfaceMethodSignature; - private final int functionalInterfaceMethodKind; private final String implClass; private final String implMethodName; private final String implMethodSignature; @@ -53,28 +52,32 @@ public final class SerializedLambda implements Serializable { private final Object[] capturedArgs; /** - * Create a {@code SerializedLambda} from the low-level information present at the lambda factory site. + * Create a {@code SerializedLambda} from the low-level information present + * at the lambda factory site. * * @param capturingClass The class in which the lambda expression appears - * @param functionalInterfaceMethodKind Method handle kind (see {@link MethodHandleInfo}) for the - * functional interface method handle present at the lambda factory site - * @param functionalInterfaceClass Name, in slash-delimited form, for the functional interface class present at the - * lambda factory site - * @param functionalInterfaceMethodName Name of the primary method for the functional interface present at the + * @param functionalInterfaceClass Name, in slash-delimited form, of static + * type of the returned lambda object + * @param functionalInterfaceMethodName Name of the functional interface + * method for the present at the * lambda factory site - * @param functionalInterfaceMethodSignature Signature of the primary method for the functional interface present - * at the lambda factory site + * @param functionalInterfaceMethodSignature Signature of the functional + * interface method present at + * the lambda factory site * @param implMethodKind Method handle kind for the implementation method - * @param implClass Name, in slash-delimited form, for the class holding the implementation method + * @param implClass Name, in slash-delimited form, for the class holding + * the implementation method * @param implMethodName Name of the implementation method * @param implMethodSignature Signature of the implementation method - * @param instantiatedMethodType The signature of the primary functional interface method after type variables - * are substituted with their instantiation from the capture site - * @param capturedArgs The dynamic arguments to the lambda factory site, which represent variables captured by + * @param instantiatedMethodType The signature of the primary functional + * interface method after type variables + * are substituted with their instantiation + * from the capture site + * @param capturedArgs The dynamic arguments to the lambda factory site, + * which represent variables captured by * the lambda */ public SerializedLambda(Class capturingClass, - int functionalInterfaceMethodKind, String functionalInterfaceClass, String functionalInterfaceMethodName, String functionalInterfaceMethodSignature, @@ -85,7 +88,6 @@ public final class SerializedLambda implements Serializable { String instantiatedMethodType, Object[] capturedArgs) { this.capturingClass = capturingClass; - this.functionalInterfaceMethodKind = functionalInterfaceMethodKind; this.functionalInterfaceClass = functionalInterfaceClass; this.functionalInterfaceMethodName = functionalInterfaceMethodName; this.functionalInterfaceMethodSignature = functionalInterfaceMethodSignature; @@ -106,10 +108,10 @@ public final class SerializedLambda implements Serializable { } /** - * Get the name of the functional interface class to which this + * Get the name of the invoked type to which this * lambda has been converted - * @return the name of the functional interface this lambda has - * been converted to + * @return the name of the functional interface class to which + * this lambda has been converted */ public String getFunctionalInterfaceClass() { return functionalInterfaceClass; @@ -134,17 +136,6 @@ public final class SerializedLambda implements Serializable { return functionalInterfaceMethodSignature; } - /** - * Get the method handle kind (see {@link MethodHandleInfo}) of - * the primary method for the functional interface to which this - * lambda has been converted - * @return the method handle kind of the primary method of - * functional interface - */ - public int getFunctionalInterfaceMethodKind() { - return functionalInterfaceMethodKind; - } - /** * Get the name of the class containing the implementation * method. @@ -234,11 +225,17 @@ public final class SerializedLambda implements Serializable { @Override public String toString() { - return String.format("SerializedLambda[capturingClass=%s, functionalInterfaceMethod=%s %s.%s:%s, " + - "implementation=%s %s.%s:%s, instantiatedMethodType=%s, numCaptured=%d]", - capturingClass, MethodHandleInfo.getReferenceKindString(functionalInterfaceMethodKind), - functionalInterfaceClass, functionalInterfaceMethodName, functionalInterfaceMethodSignature, - MethodHandleInfo.getReferenceKindString(implMethodKind), implClass, implMethodName, - implMethodSignature, instantiatedMethodType, capturedArgs.length); + String implKind=MethodHandleInfo.getReferenceKindString(implMethodKind); + return String.format("SerializedLambda[%s=%s, %s=%s.%s:%s, " + + "%s=%s %s.%s:%s, %s=%s, %s=%d]", + "capturingClass", capturingClass, + "functionalInterfaceMethod", functionalInterfaceClass, + functionalInterfaceMethodName, + functionalInterfaceMethodSignature, + "implementation", + implKind, + implClass, implMethodName, implMethodSignature, + "instantiatedMethodType", instantiatedMethodType, + "numCaptured", capturedArgs.length); } } diff --git a/jdk/src/share/classes/java/lang/reflect/Parameter.java b/jdk/src/share/classes/java/lang/reflect/Parameter.java index f49c1daa436..0568d9ee2e0 100644 --- a/jdk/src/share/classes/java/lang/reflect/Parameter.java +++ b/jdk/src/share/classes/java/lang/reflect/Parameter.java @@ -162,7 +162,7 @@ public final class Parameter implements AnnotatedElement { /** * Returns the name of the parameter. If the parameter's name is - * {@linkplain isNamePresent() present}, then this method returns + * {@linkplain #isNamePresent() present}, then this method returns * the name provided by the class file. Otherwise, this method * synthesizes a name of the form argN, where N is the index of * the parameter in the descriptor of the method which declares diff --git a/jdk/src/share/classes/java/nio/channels/package-info.java b/jdk/src/share/classes/java/nio/channels/package-info.java index 85590dde06d..cb55f8f8da7 100644 --- a/jdk/src/share/classes/java/nio/channels/package-info.java +++ b/jdk/src/share/classes/java/nio/channels/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ * * *

- * + * * * * @@ -110,7 +110,7 @@ * write them to a given writable byte channel. * *

Channels

Description

ChannelsDescription
{@link java.nio.channels.Channel}A nexus for I/O operations
  {@link java.nio.channels.ReadableByteChannel}
- * + * * * * @@ -138,7 +138,7 @@ * * *

File channels

Description

File channelsDescription
{@link java.nio.channels.FileChannel}Reads, writes, maps, and manipulates files
{@link java.nio.channels.FileLock}
- * + * * * * @@ -225,7 +225,7 @@ * * *

Multiplexed, non-blocking I/O

Description

Multiplexed, non-blocking I/O

Description

{@link java.nio.channels.SelectableChannel}A channel that can be multiplexed
  {@link java.nio.channels.DatagramChannel}
- * + * * * * diff --git a/jdk/src/share/classes/java/nio/charset/Charset.java b/jdk/src/share/classes/java/nio/charset/Charset.java index 278bacb17c5..e1a828dcb15 100644 --- a/jdk/src/share/classes/java/nio/charset/Charset.java +++ b/jdk/src/share/classes/java/nio/charset/Charset.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,7 @@ import sun.security.action.GetPropertyAction; * concurrent threads. * * - * + * *

Charset names

* *

Charsets are named by strings composed of the following characters: @@ -111,21 +111,17 @@ import sun.security.action.GetPropertyAction; * The aliases of a charset are returned by the {@link #aliases() aliases} * method. * - * - * - *

Some charsets have an historical name that is defined for - * compatibility with previous versions of the Java platform. A charset's + *

Some charsets have an historical name that is defined for + * compatibility with previous versions of the Java platform. A charset's * historical name is either its canonical name or one of its aliases. The * historical name is returned by the getEncoding() methods of the * {@link java.io.InputStreamReader#getEncoding InputStreamReader} and {@link * java.io.OutputStreamWriter#getEncoding OutputStreamWriter} classes. * - * - * - *

If a charset listed in the If a charset listed in the IANA Charset * Registry is supported by an implementation of the Java platform then - * its canonical name must be the name listed in the registry. Many charsets + * its canonical name must be the name listed in the registry. Many charsets * are given more than one name in the registry, in which case the registry * identifies one of the names as MIME-preferred. If a charset has more * than one registry name then its canonical name must be the MIME-preferred @@ -142,15 +138,15 @@ import sun.security.action.GetPropertyAction; * *

Standard charsets

* - * * - *

Every implementation of the Java platform is required to support the - * following standard charsets. Consult the release documentation for your + * + *

Every implementation of the Java platform is required to support the + * following standard charsets. Consult the release documentation for your * implementation to see if any other charsets are supported. The behavior * of such optional charsets may differ between implementations. * *

Asynchronous I/O

Description

Asynchronous I/ODescription
{@link java.nio.channels.AsynchronousFileChannel}An asynchronous channel for reading, writing, and manipulating a file
{@link java.nio.channels.AsynchronousSocketChannel}
- * + * * * diff --git a/jdk/src/share/classes/java/nio/charset/MalformedInputException.java b/jdk/src/share/classes/java/nio/charset/MalformedInputException.java index ba1d1018a53..aadbadccc2a 100644 --- a/jdk/src/share/classes/java/nio/charset/MalformedInputException.java +++ b/jdk/src/share/classes/java/nio/charset/MalformedInputException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,14 +42,27 @@ public class MalformedInputException private int inputLength; + /** + * Constructs an {@code MalformedInputException} with the given + * length. + * @param inputLength the length of the input + */ public MalformedInputException(int inputLength) { this.inputLength = inputLength; } + /** + * Returns the length of the input. + * @return the length of the input + */ public int getInputLength() { return inputLength; } + /** + * Returns the message. + * @return the message + */ public String getMessage() { return "Input length = " + inputLength; } diff --git a/jdk/src/share/classes/java/nio/charset/UnmappableCharacterException.java b/jdk/src/share/classes/java/nio/charset/UnmappableCharacterException.java index 5fa12476d68..c33f0404b64 100644 --- a/jdk/src/share/classes/java/nio/charset/UnmappableCharacterException.java +++ b/jdk/src/share/classes/java/nio/charset/UnmappableCharacterException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,14 +42,27 @@ public class UnmappableCharacterException private int inputLength; + /** + * Constructs an {@code UnmappableCharacterException} with the + * given length. + * @param inputLength the length of the input + */ public UnmappableCharacterException(int inputLength) { this.inputLength = inputLength; } + /** + * Returns the length of the input. + * @return the length of the input + */ public int getInputLength() { return inputLength; } + /** + * Returns the message. + * @return the message + */ public String getMessage() { return "Input length = " + inputLength; } diff --git a/jdk/src/share/classes/java/nio/file/attribute/package-info.java b/jdk/src/share/classes/java/nio/file/attribute/package-info.java index 222b7251f00..b0e87b64c76 100644 --- a/jdk/src/share/classes/java/nio/file/attribute/package-info.java +++ b/jdk/src/share/classes/java/nio/file/attribute/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ * Interfaces and classes providing access to file and file system attributes. * *

Charset

Description

CharsetDescription
US-ASCIISeven-bit ASCII, a.k.a. ISO646-US, * a.k.a. the Basic Latin block of the Unicode character set
- * + * * * * @@ -38,7 +38,7 @@ * * * - * + * * * * @@ -86,14 +86,14 @@ * *
    * - *

  • The {@link java.nio.file.attribute.UserPrincipal} and + *
  • The {@link java.nio.file.attribute.UserPrincipal} and * {@link java.nio.file.attribute.GroupPrincipal} interfaces represent an * identity or group identity.
  • * - *

  • The {@link java.nio.file.attribute.UserPrincipalLookupService} + *
  • The {@link java.nio.file.attribute.UserPrincipalLookupService} * interface defines methods to lookup user or group principals.
  • * - *

  • The {@link java.nio.file.attribute.FileAttribute} interface + *
  • The {@link java.nio.file.attribute.FileAttribute} interface * represents the value of an attribute for cases where the attribute value is * required to be set atomically when creating an object in the file system.
  • * diff --git a/jdk/src/share/classes/java/nio/file/package-info.java b/jdk/src/share/classes/java/nio/file/package-info.java index c0cf571b555..ca3e946d567 100644 --- a/jdk/src/share/classes/java/nio/file/package-info.java +++ b/jdk/src/share/classes/java/nio/file/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,8 @@ * package is used by service provider implementors wishing to extend the * platform default provider, or to construct other provider implementations.

    * - *

    Symbolic Links

    - * Many operating systems and file systems support for symbolic links. + *

    Symbolic Links

    + *

    Many operating systems and file systems support for symbolic links. * A symbolic link is a special file that serves as a reference to another file. * For the most part, symbolic links are transparent to applications and * operations on symbolic links are automatically redirected to the target @@ -45,8 +45,8 @@ * that are semantically close but support for these other types of links is * not included in this package.

    * - *

    Interoperability

    - * The {@link java.io.File} class defines the {@link java.io.File#toPath + *

    Interoperability

    + *

    The {@link java.io.File} class defines the {@link java.io.File#toPath * toPath} method to construct a {@link java.nio.file.Path} by converting * the abstract path represented by the {@code java.io.File} object. The resulting * {@code Path} can be used to operate on the same file as the {@code File} @@ -55,7 +55,7 @@ * and {@code java.io.File} objects.

    * *

    Visibility

    - * The view of the files and file system provided by classes in this package are + *

    The view of the files and file system provided by classes in this package are * guaranteed to be consistent with other views provided by other instances in the * same Java virtual machine. The view may or may not, however, be consistent with * the view of the file system as seen by other concurrently running programs due @@ -65,8 +65,8 @@ * or on some other machine. The exact nature of any such inconsistencies are * system-dependent and are therefore unspecified.

    * - *

    Synchronized I/O File Integrity

    - * The {@link java.nio.file.StandardOpenOption#SYNC SYNC} and {@link + *

    Synchronized I/O File Integrity

    + *

    The {@link java.nio.file.StandardOpenOption#SYNC SYNC} and {@link * java.nio.file.StandardOpenOption#DSYNC DSYNC} options are used when opening a file * to require that updates to the file are written synchronously to the underlying * storage device. In the case of the default provider, and the file resides on @@ -83,7 +83,7 @@ * specific.

    * *

    General Exceptions

    - * Unless otherwise noted, passing a {@code null} argument to a constructor + *

    Unless otherwise noted, passing a {@code null} argument to a constructor * or method of any class or interface in this package will cause a {@link * java.lang.NullPointerException NullPointerException} to be thrown. Additionally, * invoking a method with a collection containing a {@code null} element will diff --git a/jdk/src/share/classes/java/time/DayOfWeek.java b/jdk/src/share/classes/java/time/DayOfWeek.java index d2a6f5aa541..b48482241df 100644 --- a/jdk/src/share/classes/java/time/DayOfWeek.java +++ b/jdk/src/share/classes/java/time/DayOfWeek.java @@ -61,7 +61,6 @@ */ package java.time; -import java.time.temporal.UnsupportedTemporalTypeException; import static java.time.temporal.ChronoField.DAY_OF_WEEK; import static java.time.temporal.ChronoUnit.DAYS; @@ -73,6 +72,7 @@ import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; +import java.time.temporal.UnsupportedTemporalTypeException; import java.time.temporal.ValueRange; import java.time.temporal.WeekFields; import java.util.Locale; @@ -339,7 +339,7 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster { if (field == DAY_OF_WEEK) { return getValue(); } else if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } diff --git a/jdk/src/share/classes/java/time/Duration.java b/jdk/src/share/classes/java/time/Duration.java index 52b225e6e69..ab7da66f83a 100644 --- a/jdk/src/share/classes/java/time/Duration.java +++ b/jdk/src/share/classes/java/time/Duration.java @@ -459,9 +459,9 @@ public final class Duration */ public static Duration between(Temporal startInclusive, Temporal endExclusive) { try { - return ofNanos(startInclusive.periodUntil(endExclusive, NANOS)); + return ofNanos(startInclusive.until(endExclusive, NANOS)); } catch (DateTimeException | ArithmeticException ex) { - long secs = startInclusive.periodUntil(endExclusive, SECONDS); + long secs = startInclusive.until(endExclusive, SECONDS); long nanos; try { nanos = endExclusive.getLong(NANO_OF_SECOND) - startInclusive.getLong(NANO_OF_SECOND); @@ -523,7 +523,7 @@ public final class Duration } else if (unit == NANOS) { return nanos; } else { - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } } diff --git a/jdk/src/share/classes/java/time/Instant.java b/jdk/src/share/classes/java/time/Instant.java index 6dc24646945..aeecdbed524 100644 --- a/jdk/src/share/classes/java/time/Instant.java +++ b/jdk/src/share/classes/java/time/Instant.java @@ -69,6 +69,7 @@ import static java.time.temporal.ChronoField.INSTANT_SECONDS; import static java.time.temporal.ChronoField.MICRO_OF_SECOND; import static java.time.temporal.ChronoField.MILLI_OF_SECOND; import static java.time.temporal.ChronoField.NANO_OF_SECOND; +import static java.time.temporal.ChronoUnit.DAYS; import static java.time.temporal.ChronoUnit.NANOS; import java.io.DataInput; @@ -418,8 +419,9 @@ public final class Instant * Checks if the specified field is supported. *

    * This checks if this instant can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. *

    * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -447,6 +449,44 @@ public final class Instant return field != null && field.isSupportedBy(this); } + /** + * Checks if the specified unit is supported. + *

    + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + *

    + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + *

      + *
    • {@code NANOS} + *
    • {@code MICROS} + *
    • {@code MILLIS} + *
    • {@code SECONDS} + *
    • {@code MINUTES} + *
    • {@code HOURS} + *
    • {@code HALF_DAYS} + *
    • {@code DAYS} + *
    + * All other {@code ChronoUnit} instances will return false. + *

    + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override + public boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit.isTimeBased() || unit == DAYS; + } + return unit != null && unit.isSupportedBy(this); + } + + //----------------------------------------------------------------------- /** * Gets the range of valid values for the specified field. *

    @@ -511,7 +551,7 @@ public final class Instant case MILLI_OF_SECOND: return nanos / 1000_000; case INSTANT_SECONDS: INSTANT_SECONDS.checkValidIntValue(seconds); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return range(field).checkValidIntValue(field.getFrom(this), field); } @@ -548,7 +588,7 @@ public final class Instant case MILLI_OF_SECOND: return nanos / 1000_000; case INSTANT_SECONDS: return seconds; } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } @@ -665,7 +705,7 @@ public final class Instant case NANO_OF_SECOND: return (newValue != nanos ? create(seconds, (int) newValue) : this); case INSTANT_SECONDS: return (newValue != seconds ? create(newValue, nanos) : this); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.adjustInto(this, newValue); } @@ -807,7 +847,7 @@ public final class Instant case HALF_DAYS: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_DAY / 2)); case DAYS: return plusSeconds(Math.multiplyExact(amountToAdd, SECONDS_PER_DAY)); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.addTo(this, amountToAdd); } @@ -1053,14 +1093,14 @@ public final class Instant * complete units between the two instants. * The {@code Temporal} passed to this method must be an {@code Instant}. * For example, the amount in days between two dates can be calculated - * using {@code startInstant.periodUntil(endInstant, SECONDS)}. + * using {@code startInstant.until(endInstant, SECONDS)}. *

    * There are two equivalent ways of using this method. * The first is to invoke this method. * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: *

          *   // these two lines are equivalent
    -     *   amount = start.periodUntil(end, SECONDS);
    +     *   amount = start.until(end, SECONDS);
          *   amount = SECONDS.between(start, end);
          * 
    * The choice should be made based on which makes the code more readable. @@ -1085,7 +1125,7 @@ public final class Instant * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endInstant, TemporalUnit unit) { + public long until(Temporal endInstant, TemporalUnit unit) { if (endInstant instanceof Instant == false) { Objects.requireNonNull(endInstant, "endInstant"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -1103,7 +1143,7 @@ public final class Instant case HALF_DAYS: return secondsUntil(end) / (12 * SECONDS_PER_HOUR); case DAYS: return secondsUntil(end) / (SECONDS_PER_DAY); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endInstant); } diff --git a/jdk/src/share/classes/java/time/LocalDate.java b/jdk/src/share/classes/java/time/LocalDate.java index ede6d8326b9..d96f5b1fd1e 100644 --- a/jdk/src/share/classes/java/time/LocalDate.java +++ b/jdk/src/share/classes/java/time/LocalDate.java @@ -127,7 +127,7 @@ import java.util.Objects; * @since 1.8 */ public final class LocalDate - implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable { + implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable { /** * The minimum supported {@code LocalDate}, '-999999999-01-01'. @@ -466,8 +466,9 @@ public final class LocalDate * Checks if the specified field is supported. *

    * This checks if this date can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. *

    * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -501,6 +502,41 @@ public final class LocalDate return ChronoLocalDate.super.isSupported(field); } + /** + * Checks if the specified unit is supported. + *

    + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + *

    + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + *

      + *
    • {@code DAYS} + *
    • {@code WEEKS} + *
    • {@code MONTHS} + *
    • {@code YEARS} + *
    • {@code DECADES} + *
    • {@code CENTURIES} + *
    • {@code MILLENNIA} + *
    • {@code ERAS} + *
    + * All other {@code ChronoUnit} instances will return false. + *

    + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override // override for Javadoc + public boolean isSupported(TemporalUnit unit) { + return ChronoLocalDate.super.isSupported(unit); + } + + //----------------------------------------------------------------------- /** * Gets the range of valid values for the specified field. *

    @@ -538,7 +574,7 @@ public final class LocalDate } return field.range(); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); } @@ -631,7 +667,7 @@ public final class LocalDate case YEAR: return year; case ERA: return (year >= 1 ? 1 : 0); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } private long getProlepticMonth() { @@ -988,7 +1024,7 @@ public final class LocalDate case YEAR: return withYear((int) newValue); case ERA: return (getLong(ERA) == newValue ? this : withYear(1 - year)); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.adjustInto(this, newValue); } @@ -1187,7 +1223,7 @@ public final class LocalDate case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000)); case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd)); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.addTo(this, amountToAdd); } @@ -1497,7 +1533,7 @@ public final class LocalDate * The result will be negative if the end is before the start. * The {@code Temporal} passed to this method must be a {@code LocalDate}. * For example, the amount in days between two dates can be calculated - * using {@code startDate.periodUntil(endDate, DAYS)}. + * using {@code startDate.until(endDate, DAYS)}. *

    * The calculation returns a whole number, representing the number of * complete units between the two dates. @@ -1509,7 +1545,7 @@ public final class LocalDate * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: *

          *   // these two lines are equivalent
    -     *   amount = start.periodUntil(end, MONTHS);
    +     *   amount = start.until(end, MONTHS);
          *   amount = MONTHS.between(start, end);
          * 
    * The choice should be made based on which makes the code more readable. @@ -1534,7 +1570,7 @@ public final class LocalDate * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endDate, TemporalUnit unit) { + public long until(Temporal endDate, TemporalUnit unit) { Objects.requireNonNull(unit, "unit"); if (endDate instanceof LocalDate == false) { Objects.requireNonNull(endDate, "endDate"); @@ -1552,7 +1588,7 @@ public final class LocalDate case MILLENNIA: return monthsUntil(end) / 12000; case ERAS: return end.getLong(ERA) - getLong(ERA); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endDate); } @@ -1591,7 +1627,7 @@ public final class LocalDate * The second is to use {@link Period#between(LocalDate, LocalDate)}: *
          *   // these two lines are equivalent
    -     *   period = start.periodUntil(end);
    +     *   period = start.until(end);
          *   period = Period.between(start, end);
          * 
    * The choice should be made based on which makes the code more readable. @@ -1600,7 +1636,7 @@ public final class LocalDate * @return the period between this date and the end date, not null */ @Override - public Period periodUntil(ChronoLocalDate endDate) { + public Period until(ChronoLocalDate endDate) { LocalDate end = LocalDate.from(endDate); long totalMonths = end.getProlepticMonth() - this.getProlepticMonth(); // safe int days = end.day - this.day; @@ -1803,7 +1839,7 @@ public final class LocalDate * @return the comparator value, negative if less, positive if greater */ @Override // override for Javadoc and performance - public int compareTo(ChronoLocalDate other) { + public int compareTo(ChronoLocalDate other) { if (other instanceof LocalDate) { return compareTo0((LocalDate) other); } @@ -1843,7 +1879,7 @@ public final class LocalDate * @return true if this date is after the specified date */ @Override // override for Javadoc and performance - public boolean isAfter(ChronoLocalDate other) { + public boolean isAfter(ChronoLocalDate other) { if (other instanceof LocalDate) { return compareTo0((LocalDate) other) > 0; } @@ -1872,7 +1908,7 @@ public final class LocalDate * @return true if this date is before the specified date */ @Override // override for Javadoc and performance - public boolean isBefore(ChronoLocalDate other) { + public boolean isBefore(ChronoLocalDate other) { if (other instanceof LocalDate) { return compareTo0((LocalDate) other) < 0; } @@ -1901,7 +1937,7 @@ public final class LocalDate * @return true if this date is equal to the specified date */ @Override // override for Javadoc and performance - public boolean isEqual(ChronoLocalDate other) { + public boolean isEqual(ChronoLocalDate other) { if (other instanceof LocalDate) { return compareTo0((LocalDate) other) == 0; } diff --git a/jdk/src/share/classes/java/time/LocalDateTime.java b/jdk/src/share/classes/java/time/LocalDateTime.java index 6e6c87bc2ff..d68d6f52537 100644 --- a/jdk/src/share/classes/java/time/LocalDateTime.java +++ b/jdk/src/share/classes/java/time/LocalDateTime.java @@ -515,8 +515,9 @@ public final class LocalDateTime * Checks if the specified field is supported. *

    * This checks if this date-time can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. *

    * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -569,6 +570,48 @@ public final class LocalDateTime return field != null && field.isSupportedBy(this); } + /** + * Checks if the specified unit is supported. + *

    + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + *

    + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + *

      + *
    • {@code NANOS} + *
    • {@code MICROS} + *
    • {@code MILLIS} + *
    • {@code SECONDS} + *
    • {@code MINUTES} + *
    • {@code HOURS} + *
    • {@code HALF_DAYS} + *
    • {@code DAYS} + *
    • {@code WEEKS} + *
    • {@code MONTHS} + *
    • {@code YEARS} + *
    • {@code DECADES} + *
    • {@code CENTURIES} + *
    • {@code MILLENNIA} + *
    • {@code ERAS} + *
    + * All other {@code ChronoUnit} instances will return false. + *

    + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override // override for Javadoc + public boolean isSupported(TemporalUnit unit) { + return ChronoLocalDateTime.super.isSupported(unit); + } + + //----------------------------------------------------------------------- /** * Gets the range of valid values for the specified field. *

    @@ -1570,7 +1613,7 @@ public final class LocalDateTime * The result will be negative if the end is before the start. * The {@code Temporal} passed to this method must be a {@code LocalDateTime}. * For example, the amount in days between two date-times can be calculated - * using {@code startDateTime.periodUntil(endDateTime, DAYS)}. + * using {@code startDateTime.until(endDateTime, DAYS)}. *

    * The calculation returns a whole number, representing the number of * complete units between the two date-times. @@ -1582,7 +1625,7 @@ public final class LocalDateTime * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: *

          *   // these two lines are equivalent
    -     *   amount = start.periodUntil(end, MONTHS);
    +     *   amount = start.until(end, MONTHS);
          *   amount = MONTHS.between(start, end);
          * 
    * The choice should be made based on which makes the code more readable. @@ -1609,18 +1652,17 @@ public final class LocalDateTime * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof LocalDateTime == false) { Objects.requireNonNull(endDateTime, "endDateTime"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); } LocalDateTime end = (LocalDateTime) endDateTime; if (unit instanceof ChronoUnit) { - ChronoUnit f = (ChronoUnit) unit; - if (f.isTimeUnit()) { + if (unit.isTimeBased()) { long amount = date.daysUntil(end.date); if (amount == 0) { - return time.periodUntil(end.time, unit); + return time.until(end.time, unit); } long timePart = end.time.toNanoOfDay() - time.toNanoOfDay(); if (amount > 0) { @@ -1630,7 +1672,7 @@ public final class LocalDateTime amount++; // safe timePart -= NANOS_PER_DAY; // safe } - switch (f) { + switch ((ChronoUnit) unit) { case NANOS: amount = Math.multiplyExact(amount, NANOS_PER_DAY); break; @@ -1667,7 +1709,7 @@ public final class LocalDateTime } else if (endDate.isBefore(date) && end.time.isAfter(time)) { endDate = endDate.plusDays(1); } - return date.periodUntil(endDate, unit); + return date.until(endDate, unit); } return unit.between(this, endDateTime); } diff --git a/jdk/src/share/classes/java/time/LocalTime.java b/jdk/src/share/classes/java/time/LocalTime.java index 41b1a927560..2bace6e7bc9 100644 --- a/jdk/src/share/classes/java/time/LocalTime.java +++ b/jdk/src/share/classes/java/time/LocalTime.java @@ -470,8 +470,9 @@ public final class LocalTime * Checks if the specified field is supported. *

    * This checks if this time can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. *

    * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -510,6 +511,43 @@ public final class LocalTime return field != null && field.isSupportedBy(this); } + /** + * Checks if the specified unit is supported. + *

    + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + *

    + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + *

      + *
    • {@code NANOS} + *
    • {@code MICROS} + *
    • {@code MILLIS} + *
    • {@code SECONDS} + *
    • {@code MINUTES} + *
    • {@code HOURS} + *
    • {@code HALF_DAYS} + *
    + * All other {@code ChronoUnit} instances will return false. + *

    + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override // override for Javadoc + public boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit.isTimeBased(); + } + return unit != null && unit.isSupportedBy(this); + } + + //----------------------------------------------------------------------- /** * Gets the range of valid values for the specified field. *

    @@ -628,7 +666,7 @@ public final class LocalTime case CLOCK_HOUR_OF_DAY: return (hour == 0 ? 24 : hour); case AMPM_OF_DAY: return hour / 12; } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } //----------------------------------------------------------------------- @@ -803,7 +841,7 @@ public final class LocalTime case CLOCK_HOUR_OF_DAY: return withHour((int) (newValue == 24 ? 0 : newValue)); case AMPM_OF_DAY: return plusHours((newValue - (hour / 12)) * 12); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.adjustInto(this, newValue); } @@ -995,8 +1033,7 @@ public final class LocalTime @Override public LocalTime plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { - ChronoUnit f = (ChronoUnit) unit; - switch (f) { + switch ((ChronoUnit) unit) { case NANOS: return plusNanos(amountToAdd); case MICROS: return plusNanos((amountToAdd % MICROS_PER_DAY) * 1000); case MILLIS: return plusNanos((amountToAdd % MILLIS_PER_DAY) * 1000_000); @@ -1005,7 +1042,7 @@ public final class LocalTime case HOURS: return plusHours(amountToAdd); case HALF_DAYS: return plusHours((amountToAdd % 2) * 12); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.addTo(this, amountToAdd); } @@ -1295,7 +1332,7 @@ public final class LocalTime * The result will be negative if the end is before the start. * The {@code Temporal} passed to this method must be a {@code LocalTime}. * For example, the amount in hours between two times can be calculated - * using {@code startTime.periodUntil(endTime, HOURS)}. + * using {@code startTime.until(endTime, HOURS)}. *

    * The calculation returns a whole number, representing the number of * complete units between the two times. @@ -1307,7 +1344,7 @@ public final class LocalTime * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: *

          *   // these two lines are equivalent
    -     *   amount = start.periodUntil(end, MINUTES);
    +     *   amount = start.until(end, MINUTES);
          *   amount = MINUTES.between(start, end);
          * 
    * The choice should be made based on which makes the code more readable. @@ -1332,7 +1369,7 @@ public final class LocalTime * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endTime, TemporalUnit unit) { + public long until(Temporal endTime, TemporalUnit unit) { if (endTime instanceof LocalTime == false) { Objects.requireNonNull(endTime, "endTime"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -1349,7 +1386,7 @@ public final class LocalTime case HOURS: return nanosUntil / NANOS_PER_HOUR; case HALF_DAYS: return nanosUntil / (12 * NANOS_PER_HOUR); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endTime); } diff --git a/jdk/src/share/classes/java/time/Month.java b/jdk/src/share/classes/java/time/Month.java index 272e8f96b36..85d12d8f136 100644 --- a/jdk/src/share/classes/java/time/Month.java +++ b/jdk/src/share/classes/java/time/Month.java @@ -61,7 +61,6 @@ */ package java.time; -import java.time.temporal.UnsupportedTemporalTypeException; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoUnit.MONTHS; @@ -75,6 +74,7 @@ import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; +import java.time.temporal.UnsupportedTemporalTypeException; import java.time.temporal.ValueRange; import java.util.Locale; @@ -370,7 +370,7 @@ public enum Month implements TemporalAccessor, TemporalAdjuster { if (field == MONTH_OF_YEAR) { return getValue(); } else if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } diff --git a/jdk/src/share/classes/java/time/MonthDay.java b/jdk/src/share/classes/java/time/MonthDay.java index 4204ef74a7d..06aa0437af8 100644 --- a/jdk/src/share/classes/java/time/MonthDay.java +++ b/jdk/src/share/classes/java/time/MonthDay.java @@ -438,7 +438,7 @@ public final class MonthDay case DAY_OF_MONTH: return day; case MONTH_OF_YEAR: return month; } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } diff --git a/jdk/src/share/classes/java/time/OffsetDateTime.java b/jdk/src/share/classes/java/time/OffsetDateTime.java index b053085a9f5..5641154cf3e 100644 --- a/jdk/src/share/classes/java/time/OffsetDateTime.java +++ b/jdk/src/share/classes/java/time/OffsetDateTime.java @@ -65,6 +65,7 @@ import static java.time.temporal.ChronoField.EPOCH_DAY; import static java.time.temporal.ChronoField.INSTANT_SECONDS; import static java.time.temporal.ChronoField.NANO_OF_DAY; import static java.time.temporal.ChronoField.OFFSET_SECONDS; +import static java.time.temporal.ChronoUnit.FOREVER; import static java.time.temporal.ChronoUnit.NANOS; import java.io.IOException; @@ -137,25 +138,40 @@ public final class OffsetDateTime public static final OffsetDateTime MAX = LocalDateTime.MAX.atOffset(ZoneOffset.MIN); /** - * Comparator for two {@code OffsetDateTime} instances based solely on the instant. + * Gets a comparator that compares two {@code OffsetDateTime} instances + * based solely on the instant. *

    * This method differs from the comparison in {@link #compareTo} in that it * only compares the underlying instant. * + * @return a comparator that compares in time-line order + * * @see #isAfter * @see #isBefore * @see #isEqual */ - public static final Comparator INSTANT_COMPARATOR = new Comparator() { - @Override - public int compare(OffsetDateTime datetime1, OffsetDateTime datetime2) { - int cmp = Long.compare(datetime1.toEpochSecond(), datetime2.toEpochSecond()); - if (cmp == 0) { - cmp = Long.compare(datetime1.toLocalTime().toNanoOfDay(), datetime2.toLocalTime().toNanoOfDay()); - } - return cmp; + public static Comparator timeLineOrder() { + return OffsetDateTime::compareInstant; + } + + /** + * Compares this {@code OffsetDateTime} to another date-time. + * The comparison is based on the instant. + * + * @param datetime1 the first date-time to compare, not null + * @param datetime2 the other date-time to compare to, not null + * @return the comparator value, negative if less, positive if greater + */ + private static int compareInstant(OffsetDateTime datetime1, OffsetDateTime datetime2) { + if (datetime1.getOffset().equals(datetime2.getOffset())) { + return datetime1.toLocalDateTime().compareTo(datetime2.toLocalDateTime()); } - }; + int cmp = Long.compare(datetime1.toEpochSecond(), datetime2.toEpochSecond()); + if (cmp == 0) { + cmp = datetime1.toLocalTime().getNano() - datetime2.toLocalTime().getNano(); + } + return cmp; + } /** * Serialization version. @@ -406,8 +422,9 @@ public final class OffsetDateTime * Checks if the specified field is supported. *

    * This checks if this date-time can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. *

    * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -458,6 +475,51 @@ public final class OffsetDateTime return field instanceof ChronoField || (field != null && field.isSupportedBy(this)); } + /** + * Checks if the specified unit is supported. + *

    + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + *

    + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + *

      + *
    • {@code NANOS} + *
    • {@code MICROS} + *
    • {@code MILLIS} + *
    • {@code SECONDS} + *
    • {@code MINUTES} + *
    • {@code HOURS} + *
    • {@code HALF_DAYS} + *
    • {@code DAYS} + *
    • {@code WEEKS} + *
    • {@code MONTHS} + *
    • {@code YEARS} + *
    • {@code DECADES} + *
    • {@code CENTURIES} + *
    • {@code MILLENNIA} + *
    • {@code ERAS} + *
    + * All other {@code ChronoUnit} instances will return false. + *

    + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override // override for Javadoc + public boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit != FOREVER; + } + return unit != null && unit.isSupportedBy(this); + } + + //----------------------------------------------------------------------- /** * Gets the range of valid values for the specified field. *

    @@ -1528,7 +1590,7 @@ public final class OffsetDateTime * The start and end points are {@code this} and the specified date-time. * The result will be negative if the end is before the start. * For example, the period in days between two date-times can be calculated - * using {@code startDateTime.periodUntil(endDateTime, DAYS)}. + * using {@code startDateTime.until(endDateTime, DAYS)}. *

    * The {@code Temporal} passed to this method must be an {@code OffsetDateTime}. * If the offset differs between the two date-times, the specified @@ -1544,7 +1606,7 @@ public final class OffsetDateTime * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: *

          *   // these two lines are equivalent
    -     *   amount = start.periodUntil(end, MONTHS);
    +     *   amount = start.until(end, MONTHS);
          *   amount = MONTHS.between(start, end);
          * 
    * The choice should be made based on which makes the code more readable. @@ -1571,7 +1633,7 @@ public final class OffsetDateTime * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof OffsetDateTime == false) { Objects.requireNonNull(endDateTime, "endDateTime"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -1579,7 +1641,7 @@ public final class OffsetDateTime if (unit instanceof ChronoUnit) { OffsetDateTime end = (OffsetDateTime) endDateTime; end = end.withOffsetSameInstant(offset); - return dateTime.periodUntil(end.dateTime, unit); + return dateTime.until(end.dateTime, unit); } return unit.between(this, endDateTime); } @@ -1724,15 +1786,9 @@ public final class OffsetDateTime */ @Override public int compareTo(OffsetDateTime other) { - if (getOffset().equals(other.getOffset())) { - return toLocalDateTime().compareTo(other.toLocalDateTime()); - } - int cmp = Long.compare(toEpochSecond(), other.toEpochSecond()); + int cmp = compareInstant(this, other); if (cmp == 0) { - cmp = toLocalTime().getNano() - other.toLocalTime().getNano(); - if (cmp == 0) { - cmp = toLocalDateTime().compareTo(other.toLocalDateTime()); - } + cmp = toLocalDateTime().compareTo(other.toLocalDateTime()); } return cmp; } diff --git a/jdk/src/share/classes/java/time/OffsetTime.java b/jdk/src/share/classes/java/time/OffsetTime.java index ff990696942..2872cff4b26 100644 --- a/jdk/src/share/classes/java/time/OffsetTime.java +++ b/jdk/src/share/classes/java/time/OffsetTime.java @@ -348,8 +348,9 @@ public final class OffsetTime * Checks if the specified field is supported. *

    * This checks if this time can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. *

    * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -389,6 +390,43 @@ public final class OffsetTime return field != null && field.isSupportedBy(this); } + /** + * Checks if the specified unit is supported. + *

    + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + *

    + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + *

      + *
    • {@code NANOS} + *
    • {@code MICROS} + *
    • {@code MILLIS} + *
    • {@code SECONDS} + *
    • {@code MINUTES} + *
    • {@code HOURS} + *
    • {@code HALF_DAYS} + *
    + * All other {@code ChronoUnit} instances will return false. + *

    + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override // override for Javadoc + public boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit.isTimeBased(); + } + return unit != null && unit.isSupportedBy(this); + } + + //----------------------------------------------------------------------- /** * Gets the range of valid values for the specified field. *

    @@ -1084,7 +1122,7 @@ public final class OffsetTime * The start and end points are {@code this} and the specified time. * The result will be negative if the end is before the start. * For example, the period in hours between two times can be calculated - * using {@code startTime.periodUntil(endTime, HOURS)}. + * using {@code startTime.until(endTime, HOURS)}. *

    * The {@code Temporal} passed to this method must be an {@code OffsetTime}. * If the offset differs between the two times, then the specified @@ -1100,7 +1138,7 @@ public final class OffsetTime * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: *

          *   // these two lines are equivalent
    -     *   amount = start.periodUntil(end, MINUTES);
    +     *   amount = start.until(end, MINUTES);
          *   amount = MINUTES.between(start, end);
          * 
    * The choice should be made based on which makes the code more readable. @@ -1125,7 +1163,7 @@ public final class OffsetTime * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endTime, TemporalUnit unit) { + public long until(Temporal endTime, TemporalUnit unit) { if (endTime instanceof OffsetTime == false) { Objects.requireNonNull(endTime, "endTime"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -1142,7 +1180,7 @@ public final class OffsetTime case HOURS: return nanosUntil / NANOS_PER_HOUR; case HALF_DAYS: return nanosUntil / (12 * NANOS_PER_HOUR); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endTime); } diff --git a/jdk/src/share/classes/java/time/Period.java b/jdk/src/share/classes/java/time/Period.java index b2748f089ce..45980d08740 100644 --- a/jdk/src/share/classes/java/time/Period.java +++ b/jdk/src/share/classes/java/time/Period.java @@ -139,7 +139,7 @@ public final class Period * The pattern for parsing. */ private final static Pattern PATTERN = - Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)Y)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)D)?", Pattern.CASE_INSENSITIVE); + Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)Y)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)W)?(?:([-+]?[0-9]+)D)?", Pattern.CASE_INSENSITIVE); /** * The set of supported units. */ @@ -186,6 +186,20 @@ public final class Period return create(0, months, 0); } + /** + * Obtains a {@code Period} representing a number of weeks. + *

    + * The resulting period will be day-based, with the amount of days + * equal to the number of weeks multiplied by 7. + * The years and months units will be zero. + * + * @param weeks the number of weeks, positive or negative + * @return the period, with the input weeks converted to days, not null + */ + public static Period ofWeeks(int weeks) { + return create(0, 0, Math.multiplyExact(weeks, 7)); + } + /** * Obtains a {@code Period} representing a number of days. *

    @@ -257,22 +271,36 @@ public final class Period * Obtains a {@code Period} from a text string such as {@code PnYnMnD}. *

    * This will parse the string produced by {@code toString()} which is - * based on the ISO-8601 period format {@code PnYnMnD}. + * based on the ISO-8601 period formats {@code PnYnMnD} and {@code PnW}. *

    * The string starts with an optional sign, denoted by the ASCII negative * or positive symbol. If negative, the whole period is negated. * The ASCII letter "P" is next in upper or lower case. - * There are then three sections, each consisting of a number and a suffix. - * At least one of the three sections must be present. - * The sections have suffixes in ASCII of "Y", "M" and "D" for - * years, months and days, accepted in upper or lower case. + * There are then four sections, each consisting of a number and a suffix. + * At least one of the four sections must be present. + * The sections have suffixes in ASCII of "Y", "M", "W" and "D" for + * years, months, weeks and days, accepted in upper or lower case. * The suffixes must occur in order. * The number part of each section must consist of ASCII digits. * The number may be prefixed by the ASCII negative or positive symbol. * The number must parse to an {@code int}. *

    * The leading plus/minus sign, and negative values for other units are - * not part of the ISO-8601 standard. + * not part of the ISO-8601 standard. In addition, ISO-8601 does not + * permit mixing between the {@code PnYnMnD} and {@code PnW} formats. + * Any week-based input is multiplied by 7 and treated as a number of days. + *

    + * For example, the following are valid inputs: + *

    +     *   "P2Y"             -- Period.ofYears(2)
    +     *   "P3M"             -- Period.ofMonths(3)
    +     *   "P4W"             -- Period.ofWeeks(4)
    +     *   "P5D"             -- Period.ofDays(5)
    +     *   "P1Y2M3D"         -- Period.of(1, 2, 3)
    +     *   "P1Y2M3W4D"       -- Period.of(1, 2, 25)
    +     *   "P-1Y2M"          -- Period.of(-1, 2, 0)
    +     *   "-P1Y2M"          -- Period.of(-1, -2, 0)
    +     * 
    * * @param text the text to parse, not null * @return the parsed period, not null @@ -285,14 +313,18 @@ public final class Period int negate = ("-".equals(matcher.group(1)) ? -1 : 1); String yearMatch = matcher.group(2); String monthMatch = matcher.group(3); - String dayMatch = matcher.group(4); - if (yearMatch != null || monthMatch != null || dayMatch != null) { + String weekMatch = matcher.group(4); + String dayMatch = matcher.group(5); + if (yearMatch != null || monthMatch != null || dayMatch != null || weekMatch != null) { try { - return create(parseNumber(text, yearMatch, negate), - parseNumber(text, monthMatch, negate), - parseNumber(text, dayMatch, negate)); + int years = parseNumber(text, yearMatch, negate); + int months = parseNumber(text, monthMatch, negate); + int weeks = parseNumber(text, weekMatch, negate); + int days = parseNumber(text, dayMatch, negate); + days = Math.addExact(days, Math.multiplyExact(weeks, 7)); + return create(years, months, days); } catch (NumberFormatException ex) { - throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Period", text, 0).initCause(ex); + throw new DateTimeParseException("Text cannot be parsed to a Period", text, 0, ex); } } } @@ -307,7 +339,7 @@ public final class Period try { return Math.multiplyExact(val, negate); } catch (ArithmeticException ex) { - throw (DateTimeParseException) new DateTimeParseException("Text cannot be parsed to a Period", text, 0).initCause(ex); + throw new DateTimeParseException("Text cannot be parsed to a Period", text, 0, ex); } } @@ -329,10 +361,10 @@ public final class Period * @param startDate the start date, inclusive, not null * @param endDate the end date, exclusive, not null * @return the period between this date and the end date, not null - * @see ChronoLocalDate#periodUntil(ChronoLocalDate) + * @see ChronoLocalDate#until(ChronoLocalDate) */ public static Period between(LocalDate startDate, LocalDate endDate) { - return startDate.periodUntil(endDate); + return startDate.until(endDate); } //----------------------------------------------------------------------- @@ -386,7 +418,7 @@ public final class Period } else if (unit == ChronoUnit.DAYS) { return getDays(); } else { - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } } diff --git a/jdk/src/share/classes/java/time/Year.java b/jdk/src/share/classes/java/time/Year.java index c2d9974d79a..fb180d859cb 100644 --- a/jdk/src/share/classes/java/time/Year.java +++ b/jdk/src/share/classes/java/time/Year.java @@ -64,6 +64,10 @@ package java.time; import static java.time.temporal.ChronoField.ERA; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoUnit.CENTURIES; +import static java.time.temporal.ChronoUnit.DECADES; +import static java.time.temporal.ChronoUnit.ERAS; +import static java.time.temporal.ChronoUnit.MILLENNIA; import static java.time.temporal.ChronoUnit.YEARS; import java.io.DataInput; @@ -329,8 +333,9 @@ public final class Year * Checks if the specified field is supported. *

    * This checks if this year can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. *

    * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -357,6 +362,41 @@ public final class Year return field != null && field.isSupportedBy(this); } + /** + * Checks if the specified unit is supported. + *

    + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + *

    + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + *

      + *
    • {@code YEARS} + *
    • {@code DECADES} + *
    • {@code CENTURIES} + *
    • {@code MILLENNIA} + *
    • {@code ERAS} + *
    + * All other {@code ChronoUnit} instances will return false. + *

    + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override + public boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit == YEARS || unit == DECADES || unit == CENTURIES || unit == MILLENNIA || unit == ERAS; + } + return unit != null && unit.isSupportedBy(this); + } + + //----------------------------------------------------------------------- /** * Gets the range of valid values for the specified field. *

    @@ -450,7 +490,7 @@ public final class Year case YEAR: return year; case ERA: return (year < 1 ? 0 : 1); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } @@ -575,7 +615,7 @@ public final class Year case YEAR: return Year.of((int) newValue); case ERA: return (getLong(ERA) == newValue ? this : Year.of(1 - year)); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.adjustInto(this, newValue); } @@ -664,7 +704,7 @@ public final class Year case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000)); case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd)); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.addTo(this, amountToAdd); } @@ -821,7 +861,7 @@ public final class Year * The result will be negative if the end is before the start. * The {@code Temporal} passed to this method must be a {@code Year}. * For example, the period in decades between two year can be calculated - * using {@code startYear.periodUntil(endYear, DECADES)}. + * using {@code startYear.until(endYear, DECADES)}. *

    * The calculation returns a whole number, representing the number of * complete units between the two years. @@ -833,7 +873,7 @@ public final class Year * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: *

          *   // these two lines are equivalent
    -     *   amount = start.periodUntil(end, YEARS);
    +     *   amount = start.until(end, YEARS);
          *   amount = YEARS.between(start, end);
          * 
    * The choice should be made based on which makes the code more readable. @@ -858,7 +898,7 @@ public final class Year * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endYear, TemporalUnit unit) { + public long until(Temporal endYear, TemporalUnit unit) { if (endYear instanceof Year == false) { Objects.requireNonNull(endYear, "endYear"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -873,7 +913,7 @@ public final class Year case MILLENNIA: return yearsUntil / 1000; case ERAS: return end.getLong(ERA) - getLong(ERA); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endYear); } diff --git a/jdk/src/share/classes/java/time/YearMonth.java b/jdk/src/share/classes/java/time/YearMonth.java index 855774eed1a..1d974095336 100644 --- a/jdk/src/share/classes/java/time/YearMonth.java +++ b/jdk/src/share/classes/java/time/YearMonth.java @@ -66,7 +66,12 @@ import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoUnit.CENTURIES; +import static java.time.temporal.ChronoUnit.DECADES; +import static java.time.temporal.ChronoUnit.ERAS; +import static java.time.temporal.ChronoUnit.MILLENNIA; import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.YEARS; import java.io.DataInput; import java.io.DataOutput; @@ -313,8 +318,9 @@ public final class YearMonth * Checks if the specified field is supported. *

    * This checks if this year-month can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. *

    * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -344,6 +350,42 @@ public final class YearMonth return field != null && field.isSupportedBy(this); } + /** + * Checks if the specified unit is supported. + *

    + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + *

    + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + *

      + *
    • {@code MONTHS} + *
    • {@code YEARS} + *
    • {@code DECADES} + *
    • {@code CENTURIES} + *
    • {@code MILLENNIA} + *
    • {@code ERAS} + *
    + * All other {@code ChronoUnit} instances will return false. + *

    + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override + public boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit == MONTHS || unit == YEARS || unit == DECADES || unit == CENTURIES || unit == MILLENNIA || unit == ERAS; + } + return unit != null && unit.isSupportedBy(this); + } + + //----------------------------------------------------------------------- /** * Gets the range of valid values for the specified field. *

    @@ -440,7 +482,7 @@ public final class YearMonth case YEAR: return year; case ERA: return (year < 1 ? 0 : 1); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } @@ -639,7 +681,7 @@ public final class YearMonth case YEAR: return withYear((int) newValue); case ERA: return (getLong(ERA) == newValue ? this : withYear(1 - year)); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.adjustInto(this, newValue); } @@ -761,7 +803,7 @@ public final class YearMonth case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000)); case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd)); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.addTo(this, amountToAdd); } @@ -952,7 +994,7 @@ public final class YearMonth * The result will be negative if the end is before the start. * The {@code Temporal} passed to this method must be a {@code YearMonth}. * For example, the period in years between two year-months can be calculated - * using {@code startYearMonth.periodUntil(endYearMonth, YEARS)}. + * using {@code startYearMonth.until(endYearMonth, YEARS)}. *

    * The calculation returns a whole number, representing the number of * complete units between the two year-months. @@ -964,7 +1006,7 @@ public final class YearMonth * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: *

          *   // these two lines are equivalent
    -     *   amount = start.periodUntil(end, MONTHS);
    +     *   amount = start.until(end, MONTHS);
          *   amount = MONTHS.between(start, end);
          * 
    * The choice should be made based on which makes the code more readable. @@ -989,7 +1031,7 @@ public final class YearMonth * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endYearMonth, TemporalUnit unit) { + public long until(Temporal endYearMonth, TemporalUnit unit) { if (endYearMonth instanceof YearMonth == false) { Objects.requireNonNull(endYearMonth, "endYearMonth"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -1005,7 +1047,7 @@ public final class YearMonth case MILLENNIA: return monthsUntil / 12000; case ERAS: return end.getLong(ERA) - getLong(ERA); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endYearMonth); } diff --git a/jdk/src/share/classes/java/time/ZoneId.java b/jdk/src/share/classes/java/time/ZoneId.java index 026f73ef512..dcde85ae884 100644 --- a/jdk/src/share/classes/java/time/ZoneId.java +++ b/jdk/src/share/classes/java/time/ZoneId.java @@ -400,6 +400,36 @@ public abstract class ZoneId implements Serializable { return of(zoneId, true); } + /** + * Obtains an instance of {@code ZoneId} wrapping an offset. + *

    + * If the prefix is "GMT", "UTC", or "UT" a {@code ZoneId} + * with the prefix and the non-zero offset is returned. + * If the prefix is empty {@code ""} the {@code ZoneOffset} is returned. + * + * @param prefix the time-zone ID, not null + * @param offset the offset, not null + * @return the zone ID, not null + * @throws IllegalArgumentException if the prefix is not one of + * "GMT", "UTC", or "UT", or "" + */ + public static ZoneId ofOffset(String prefix, ZoneOffset offset) { + Objects.requireNonNull(prefix, "prefix"); + Objects.requireNonNull(offset, "offset"); + if (prefix.length() == 0) { + return offset; + } + + if (!prefix.equals("GMT") && !prefix.equals("UTC") && !prefix.equals("UT")) { + throw new IllegalArgumentException("prefix should be GMT, UTC or UT, is: " + prefix); + } + + if (offset.getTotalSeconds() != 0) { + prefix = prefix.concat(offset.getId()); + } + return new ZoneRegion(prefix, offset.getRules()); + } + /** * Parses the ID, taking a flag to indicate whether {@code ZoneRulesException} * should be thrown or not, used in deserialization. @@ -433,7 +463,7 @@ public abstract class ZoneId implements Serializable { private static ZoneId ofWithPrefix(String zoneId, int prefixLength, boolean checkAvailable) { String prefix = zoneId.substring(0, prefixLength); if (zoneId.length() == prefixLength) { - return ZoneRegion.ofPrefixedOffset(prefix, ZoneOffset.UTC); + return ofOffset(prefix, ZoneOffset.UTC); } if (zoneId.charAt(prefixLength) != '+' && zoneId.charAt(prefixLength) != '-') { return ZoneRegion.ofId(zoneId, checkAvailable); // drop through to ZoneRulesProvider @@ -441,9 +471,9 @@ public abstract class ZoneId implements Serializable { try { ZoneOffset offset = ZoneOffset.of(zoneId.substring(prefixLength)); if (offset == ZoneOffset.UTC) { - return ZoneRegion.ofPrefixedOffset(prefix, offset); + return ofOffset(prefix, offset); } - return ZoneRegion.ofPrefixedOffset(prefix + offset.toString(), offset); + return ofOffset(prefix, offset); } catch (DateTimeException ex) { throw new DateTimeException("Invalid ID for offset-based ZoneId: " + zoneId, ex); } diff --git a/jdk/src/share/classes/java/time/ZoneOffset.java b/jdk/src/share/classes/java/time/ZoneOffset.java index 4bbc4e4fa84..c5e4d056ee8 100644 --- a/jdk/src/share/classes/java/time/ZoneOffset.java +++ b/jdk/src/share/classes/java/time/ZoneOffset.java @@ -61,7 +61,6 @@ */ package java.time; -import java.time.temporal.UnsupportedTemporalTypeException; import static java.time.LocalTime.MINUTES_PER_HOUR; import static java.time.LocalTime.SECONDS_PER_HOUR; import static java.time.LocalTime.SECONDS_PER_MINUTE; @@ -79,6 +78,7 @@ import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; +import java.time.temporal.UnsupportedTemporalTypeException; import java.time.temporal.ValueRange; import java.time.zone.ZoneRules; import java.util.Objects; @@ -581,7 +581,7 @@ public final class ZoneOffset if (field == OFFSET_SECONDS) { return totalSeconds; } else if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return range(field).checkValidIntValue(getLong(field), field); } @@ -613,7 +613,7 @@ public final class ZoneOffset if (field == OFFSET_SECONDS) { return totalSeconds; } else if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } diff --git a/jdk/src/share/classes/java/time/ZoneRegion.java b/jdk/src/share/classes/java/time/ZoneRegion.java index af6a5405a69..66d30709d98 100644 --- a/jdk/src/share/classes/java/time/ZoneRegion.java +++ b/jdk/src/share/classes/java/time/ZoneRegion.java @@ -66,7 +66,6 @@ import java.time.zone.ZoneRules; import java.time.zone.ZoneRulesException; import java.time.zone.ZoneRulesProvider; import java.util.Objects; -import java.util.regex.Pattern; /** * A geographical region where the same time-zone rules apply. @@ -153,19 +152,6 @@ final class ZoneRegion extends ZoneId implements Serializable { } } - /** - * Obtains an instance of {@code ZoneId} wrapping an offset. - *

    - * For example, zone IDs like 'UTC', 'GMT', 'UT' and 'UTC+01:30' will be setup here. - * - * @param zoneId the time-zone ID, not null - * @param offset the offset, not null - * @return the zone ID, not null - */ - static ZoneRegion ofPrefixedOffset(String zoneId, ZoneOffset offset) { - return new ZoneRegion(zoneId, offset.getRules()); - } - //------------------------------------------------------------------------- /** * Constructor. diff --git a/jdk/src/share/classes/java/time/ZonedDateTime.java b/jdk/src/share/classes/java/time/ZonedDateTime.java index e7ed5551d33..151470ecf93 100644 --- a/jdk/src/share/classes/java/time/ZonedDateTime.java +++ b/jdk/src/share/classes/java/time/ZonedDateTime.java @@ -642,8 +642,9 @@ public final class ZonedDateTime * Checks if the specified field is supported. *

    * This checks if this date-time can be queried for the specified field. - * If false, then calling the {@link #range(TemporalField) range} and - * {@link #get(TemporalField) get} methods will throw an exception. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. *

    * If the field is a {@link ChronoField} then the query is implemented here. * The supported fields are: @@ -694,6 +695,48 @@ public final class ZonedDateTime return field instanceof ChronoField || (field != null && field.isSupportedBy(this)); } + /** + * Checks if the specified unit is supported. + *

    + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + *

    + * If the unit is a {@link ChronoUnit} then the query is implemented here. + * The supported units are: + *

      + *
    • {@code NANOS} + *
    • {@code MICROS} + *
    • {@code MILLIS} + *
    • {@code SECONDS} + *
    • {@code MINUTES} + *
    • {@code HOURS} + *
    • {@code HALF_DAYS} + *
    • {@code DAYS} + *
    • {@code WEEKS} + *
    • {@code MONTHS} + *
    • {@code YEARS} + *
    • {@code DECADES} + *
    • {@code CENTURIES} + *
    • {@code MILLENNIA} + *
    • {@code ERAS} + *
    + * All other {@code ChronoUnit} instances will return false. + *

    + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override // override for Javadoc + public boolean isSupported(TemporalUnit unit) { + return ChronoZonedDateTime.super.isSupported(unit); + } + + //----------------------------------------------------------------------- /** * Gets the range of valid values for the specified field. *

    @@ -1540,8 +1583,7 @@ public final class ZonedDateTime @Override public ZonedDateTime plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { - ChronoUnit u = (ChronoUnit) unit; - if (u.isDateUnit()) { + if (unit.isDateBased()) { return resolveLocal(dateTime.plus(amountToAdd, unit)); } else { return resolveInstant(dateTime.plus(amountToAdd, unit)); @@ -1990,7 +2032,7 @@ public final class ZonedDateTime * The start and end points are {@code this} and the specified date-time. * The result will be negative if the end is before the start. * For example, the period in days between two date-times can be calculated - * using {@code startDateTime.periodUntil(endDateTime, DAYS)}. + * using {@code startDateTime.until(endDateTime, DAYS)}. *

    * The {@code Temporal} passed to this method must be a {@code ZonedDateTime}. * If the time-zone differs between the two zoned date-times, the specified @@ -2006,7 +2048,7 @@ public final class ZonedDateTime * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: *

          *   // these two lines are equivalent
    -     *   amount = start.periodUntil(end, MONTHS);
    +     *   amount = start.until(end, MONTHS);
          *   amount = MONTHS.between(start, end);
          * 
    * The choice should be made based on which makes the code more readable. @@ -2047,7 +2089,7 @@ public final class ZonedDateTime * @throws ArithmeticException if numeric overflow occurs */ @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof ZonedDateTime == false) { Objects.requireNonNull(endDateTime, "endDateTime"); throw new DateTimeException("Unable to calculate amount as objects are of two different types"); @@ -2055,11 +2097,10 @@ public final class ZonedDateTime if (unit instanceof ChronoUnit) { ZonedDateTime end = (ZonedDateTime) endDateTime; end = end.withZoneSameInstant(zone); - ChronoUnit u = (ChronoUnit) unit; - if (u.isDateUnit()) { - return dateTime.periodUntil(end.dateTime, unit); + if (unit.isDateBased()) { + return dateTime.until(end.dateTime, unit); } else { - return toOffsetDateTime().periodUntil(end.toOffsetDateTime(), unit); + return toOffsetDateTime().until(end.toOffsetDateTime(), unit); } } return unit.between(this, endDateTime); diff --git a/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java index 14e2bf58f2a..99ba58f05b9 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java @@ -67,6 +67,8 @@ import java.time.DateTimeException; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalAmount; +import java.time.temporal.TemporalField; import java.time.temporal.TemporalUnit; import java.time.temporal.UnsupportedTemporalTypeException; import java.time.temporal.ValueRange; @@ -96,12 +98,12 @@ import java.util.Objects; * // Enumerate the list of available calendars and print today for each * Set<Chronology> chronos = Chronology.getAvailableChronologies(); * for (Chronology chrono : chronos) { - * ChronoLocalDate<?> date = chrono.dateNow(); + * ChronoLocalDate date = chrono.dateNow(); * System.out.printf(" %20s: %s%n", chrono.getID(), date.toString()); * } * * // Print the Hijrah date and calendar - * ChronoLocalDate<?> date = Chronology.of("Hijrah").dateNow(); + * ChronoLocalDate date = Chronology.of("Hijrah").dateNow(); * int day = date.get(ChronoField.DAY_OF_MONTH); * int dow = date.get(ChronoField.DAY_OF_WEEK); * int month = date.get(ChronoField.MONTH_OF_YEAR); @@ -110,10 +112,10 @@ import java.util.Objects; * dow, day, month, year); * // Print today's date and the last day of the year - * ChronoLocalDate<?> now1 = Chronology.of("Hijrah").dateNow(); - * ChronoLocalDate<?> first = now1.with(ChronoField.DAY_OF_MONTH, 1) + * ChronoLocalDate now1 = Chronology.of("Hijrah").dateNow(); + * ChronoLocalDate first = now1.with(ChronoField.DAY_OF_MONTH, 1) * .with(ChronoField.MONTH_OF_YEAR, 1); - * ChronoLocalDate<?> last = first.plus(1, ChronoUnit.YEARS) + * ChronoLocalDate last = first.plus(1, ChronoUnit.YEARS) * .minus(1, ChronoUnit.DAYS); * System.out.printf(" Today is %s: start: %s; end: %s%n", last.getChronology().getID(), * first, last); @@ -138,22 +140,61 @@ import java.util.Objects; * @param the ChronoLocalDate of this date-time * @since 1.8 */ -abstract class ChronoDateImpl> - implements ChronoLocalDate, Temporal, TemporalAdjuster, Serializable { +abstract class ChronoDateImpl + implements ChronoLocalDate, Temporal, TemporalAdjuster, Serializable { /** * Serialization version. */ private static final long serialVersionUID = 6282433883239719096L; + /** + * Casts the {@code Temporal} to {@code ChronoLocalDate} ensuring it bas the specified chronology. + * + * @param chrono the chronology to check for, not null + * @param temporal a date-time to cast, not null + * @return the date-time checked and cast to {@code ChronoLocalDate}, not null + * @throws ClassCastException if the date-time cannot be cast to ChronoLocalDate + * or the chronology is not equal this Chronology + */ + static D ensureValid(Chronology chrono, Temporal temporal) { + @SuppressWarnings("unchecked") + D other = (D) temporal; + if (chrono.equals(other.getChronology()) == false) { + throw new ClassCastException("Chronology mismatch, expected: " + chrono.getId() + ", actual: " + other.getChronology().getId()); + } + return other; + } + + //----------------------------------------------------------------------- /** * Creates an instance. */ ChronoDateImpl() { } + @Override + @SuppressWarnings("unchecked") + public D with(TemporalAdjuster adjuster) { + return (D) ChronoLocalDate.super.with(adjuster); + } + + @Override + @SuppressWarnings("unchecked") + public D with(TemporalField field, long value) { + return (D) ChronoLocalDate.super.with(field, value); + } + //----------------------------------------------------------------------- @Override + @SuppressWarnings("unchecked") + public D plus(TemporalAmount amount) { + return (D) ChronoLocalDate.super.plus(amount); + } + + //----------------------------------------------------------------------- + @Override + @SuppressWarnings("unchecked") public D plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { ChronoUnit f = (ChronoUnit) unit; @@ -167,9 +208,21 @@ abstract class ChronoDateImpl> case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000)); case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd)); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return ChronoLocalDate.super.plus(amountToAdd, unit); + return (D) ChronoLocalDate.super.plus(amountToAdd, unit); + } + + @Override + @SuppressWarnings("unchecked") + public D minus(TemporalAmount amount) { + return (D) ChronoLocalDate.super.minus(amount); + } + + @Override + @SuppressWarnings("unchecked") + public D minus(long amountToSubtract, TemporalUnit unit) { + return (D) ChronoLocalDate.super.minus(amountToSubtract, unit); } //----------------------------------------------------------------------- @@ -254,6 +307,7 @@ abstract class ChronoDateImpl> * @return a date based on this one with the years subtracted, not null * @throws DateTimeException if the result exceeds the supported date range */ + @SuppressWarnings("unchecked") D minusYears(long yearsToSubtract) { return (yearsToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl)plusYears(Long.MAX_VALUE)).plusYears(1) : plusYears(-yearsToSubtract)); } @@ -274,6 +328,7 @@ abstract class ChronoDateImpl> * @return a date based on this one with the months subtracted, not null * @throws DateTimeException if the result exceeds the supported date range */ + @SuppressWarnings("unchecked") D minusMonths(long monthsToSubtract) { return (monthsToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl)plusMonths(Long.MAX_VALUE)).plusMonths(1) : plusMonths(-monthsToSubtract)); } @@ -293,6 +348,7 @@ abstract class ChronoDateImpl> * @return a date based on this one with the weeks subtracted, not null * @throws DateTimeException if the result exceeds the supported date range */ + @SuppressWarnings("unchecked") D minusWeeks(long weeksToSubtract) { return (weeksToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl)plusWeeks(Long.MAX_VALUE)).plusWeeks(1) : plusWeeks(-weeksToSubtract)); } @@ -310,6 +366,7 @@ abstract class ChronoDateImpl> * @return a date based on this one with the days subtracted, not null * @throws DateTimeException if the result exceeds the supported date range */ + @SuppressWarnings("unchecked") D minusDays(long daysToSubtract) { return (daysToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl)plusDays(Long.MAX_VALUE)).plusDays(1) : plusDays(-daysToSubtract)); } @@ -321,13 +378,13 @@ abstract class ChronoDateImpl> * @throws ArithmeticException {@inheritDoc} */ @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { Objects.requireNonNull(endDateTime, "endDateTime"); Objects.requireNonNull(unit, "unit"); if (endDateTime instanceof ChronoLocalDate == false) { throw new DateTimeException("Unable to calculate amount as objects are of two different types"); } - ChronoLocalDate end = (ChronoLocalDate) endDateTime; + ChronoLocalDate end = (ChronoLocalDate) endDateTime; if (getChronology().equals(end.getChronology()) == false) { throw new DateTimeException("Unable to calculate amount as objects have different chronologies"); } @@ -342,16 +399,16 @@ abstract class ChronoDateImpl> case MILLENNIA: return monthsUntil(end) / 12000; case ERAS: return end.getLong(ERA) - getLong(ERA); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.between(this, endDateTime); } - private long daysUntil(ChronoLocalDate end) { + private long daysUntil(ChronoLocalDate end) { return end.toEpochDay() - toEpochDay(); // no overflow } - private long monthsUntil(ChronoLocalDate end) { + private long monthsUntil(ChronoLocalDate end) { ValueRange range = getChronology().range(MONTH_OF_YEAR); if (range.getMaximum() != 12) { throw new IllegalStateException("ChronoDateImpl only supports Chronologies with 12 months per year"); @@ -367,7 +424,7 @@ abstract class ChronoDateImpl> return true; } if (obj instanceof ChronoLocalDate) { - return compareTo((ChronoLocalDate) obj) == 0; + return compareTo((ChronoLocalDate) obj) == 0; } return false; } diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java index 31c08260d6e..923e8960b0f 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDate.java @@ -242,11 +242,10 @@ import java.util.Objects; * Additional calendar systems may be added to the system. * See {@link Chronology} for more details. * - * @param the concrete type for the date * @since 1.8 */ -public interface ChronoLocalDate> - extends Temporal, TemporalAdjuster, Comparable> { +public interface ChronoLocalDate + extends Temporal, TemporalAdjuster, Comparable { /** * Gets a comparator that compares {@code ChronoLocalDate} in @@ -263,7 +262,7 @@ public interface ChronoLocalDate> * @see #isBefore * @see #isEqual */ - static Comparator> timeLineOrder() { + static Comparator timeLineOrder() { return Chronology.DATE_ORDER; } @@ -289,9 +288,9 @@ public interface ChronoLocalDate> * @throws DateTimeException if unable to convert to a {@code ChronoLocalDate} * @see Chronology#date(TemporalAccessor) */ - static ChronoLocalDate from(TemporalAccessor temporal) { + static ChronoLocalDate from(TemporalAccessor temporal) { if (temporal instanceof ChronoLocalDate) { - return (ChronoLocalDate) temporal; + return (ChronoLocalDate) temporal; } Chronology chrono = temporal.query(TemporalQuery.chronology()); if (chrono == null) { @@ -367,6 +366,25 @@ public interface ChronoLocalDate> return (isLeapYear() ? 366 : 365); } + /** + * Checks if the specified field is supported. + *

    + * This checks if the specified field can be queried on this date. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. + *

    + * The set of supported fields is defined by the chronology and normally includes + * all {@code ChronoField} date fields. + *

    + * If the field is not a {@code ChronoField}, then the result of this method + * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} + * passing {@code this} as the argument. + * Whether the field is supported is determined by the field. + * + * @param field the field to check, null returns false + * @return true if the field can be queried, false if not + */ @Override default boolean isSupported(TemporalField field) { if (field instanceof ChronoField) { @@ -375,6 +393,32 @@ public interface ChronoLocalDate> return field != null && field.isSupportedBy(this); } + /** + * Checks if the specified unit is supported. + *

    + * This checks if the specified unit can be added to or subtracted from this date. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + *

    + * The set of supported units is defined by the chronology and normally includes + * all {@code ChronoUnit} date units except {@code FOREVER}. + *

    + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override + default boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit.isDateBased(); + } + return unit != null && unit.isSupportedBy(this); + } + //----------------------------------------------------------------------- // override for covariant return type /** @@ -383,8 +427,8 @@ public interface ChronoLocalDate> * @throws ArithmeticException {@inheritDoc} */ @Override - default D with(TemporalAdjuster adjuster) { - return (D) getChronology().ensureChronoLocalDate(Temporal.super.with(adjuster)); + default ChronoLocalDate with(TemporalAdjuster adjuster) { + return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.with(adjuster)); } /** @@ -394,11 +438,11 @@ public interface ChronoLocalDate> * @throws ArithmeticException {@inheritDoc} */ @Override - default D with(TemporalField field, long newValue) { + default ChronoLocalDate with(TemporalField field, long newValue) { if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } - return (D) getChronology().ensureChronoLocalDate(field.adjustInto(this, newValue)); + return ChronoDateImpl.ensureValid(getChronology(), field.adjustInto(this, newValue)); } /** @@ -407,8 +451,8 @@ public interface ChronoLocalDate> * @throws ArithmeticException {@inheritDoc} */ @Override - default D plus(TemporalAmount amount) { - return (D) getChronology().ensureChronoLocalDate(Temporal.super.plus(amount)); + default ChronoLocalDate plus(TemporalAmount amount) { + return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.plus(amount)); } /** @@ -417,11 +461,11 @@ public interface ChronoLocalDate> * @throws ArithmeticException {@inheritDoc} */ @Override - default D plus(long amountToAdd, TemporalUnit unit) { + default ChronoLocalDate plus(long amountToAdd, TemporalUnit unit) { if (unit instanceof ChronoUnit) { - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } - return (D) getChronology().ensureChronoLocalDate(unit.addTo(this, amountToAdd)); + return ChronoDateImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd)); } /** @@ -430,8 +474,8 @@ public interface ChronoLocalDate> * @throws ArithmeticException {@inheritDoc} */ @Override - default D minus(TemporalAmount amount) { - return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amount)); + default ChronoLocalDate minus(TemporalAmount amount) { + return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amount)); } /** @@ -441,8 +485,8 @@ public interface ChronoLocalDate> * @throws ArithmeticException {@inheritDoc} */ @Override - default D minus(long amountToSubtract, TemporalUnit unit) { - return (D) getChronology().ensureChronoLocalDate(Temporal.super.minus(amountToSubtract, unit)); + default ChronoLocalDate minus(long amountToSubtract, TemporalUnit unit) { + return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit)); } //----------------------------------------------------------------------- @@ -522,14 +566,14 @@ public interface ChronoLocalDate> * The calculation returns a whole number, representing the number of * complete units between the two dates. * For example, the amount in days between two dates can be calculated - * using {@code startDate.periodUntil(endDate, DAYS)}. + * using {@code startDate.until(endDate, DAYS)}. *

    * There are two equivalent ways of using this method. * The first is to invoke this method. * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: *

          *   // these two lines are equivalent
    -     *   amount = start.periodUntil(end, MONTHS);
    +     *   amount = start.until(end, MONTHS);
          *   amount = MONTHS.between(start, end);
          * 
    * The choice should be made based on which makes the code more readable. @@ -555,7 +599,7 @@ public interface ChronoLocalDate> * @throws ArithmeticException if numeric overflow occurs */ @Override // override for Javadoc - long periodUntil(Temporal endDate, TemporalUnit unit); + long until(Temporal endDate, TemporalUnit unit); /** * Calculates the period between this date and another date as a {@code Period}. @@ -575,7 +619,7 @@ public interface ChronoLocalDate> * @throws DateTimeException if the period cannot be calculated * @throws ArithmeticException if numeric overflow occurs */ - Period periodUntil(ChronoLocalDate endDate); + Period until(ChronoLocalDate endDate); /** * Formats this date using the specified formatter. @@ -606,8 +650,9 @@ public interface ChronoLocalDate> * @param localTime the local time to use, not null * @return the local date-time formed from this date and the specified time, not null */ - default ChronoLocalDateTime atTime(LocalTime localTime) { - return (ChronoLocalDateTime)ChronoLocalDateTimeImpl.of(this, localTime); + @SuppressWarnings("unchecked") + default ChronoLocalDateTime atTime(LocalTime localTime) { + return ChronoLocalDateTimeImpl.of(this, localTime); } //----------------------------------------------------------------------- @@ -656,7 +701,7 @@ public interface ChronoLocalDate> * @return the comparator value, negative if less, positive if greater */ @Override - default int compareTo(ChronoLocalDate other) { + default int compareTo(ChronoLocalDate other) { int cmp = Long.compare(toEpochDay(), other.toEpochDay()); if (cmp == 0) { cmp = getChronology().compareTo(other.getChronology()); @@ -678,7 +723,7 @@ public interface ChronoLocalDate> * @param other the other date to compare to, not null * @return true if this is after the specified date */ - default boolean isAfter(ChronoLocalDate other) { + default boolean isAfter(ChronoLocalDate other) { return this.toEpochDay() > other.toEpochDay(); } @@ -696,7 +741,7 @@ public interface ChronoLocalDate> * @param other the other date to compare to, not null * @return true if this is before the specified date */ - default boolean isBefore(ChronoLocalDate other) { + default boolean isBefore(ChronoLocalDate other) { return this.toEpochDay() < other.toEpochDay(); } @@ -714,7 +759,7 @@ public interface ChronoLocalDate> * @param other the other date to compare to, not null * @return true if the underlying date is equal to the specified date */ - default boolean isEqual(ChronoLocalDate other) { + default boolean isEqual(ChronoLocalDate other) { return this.toEpochDay() == other.toEpochDay(); } diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java index f0a893a4c95..be93f0e036a 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTime.java @@ -63,6 +63,7 @@ package java.time.chrono; import static java.time.temporal.ChronoField.EPOCH_DAY; import static java.time.temporal.ChronoField.NANO_OF_DAY; +import static java.time.temporal.ChronoUnit.FOREVER; import static java.time.temporal.ChronoUnit.NANOS; import java.time.DateTimeException; @@ -73,6 +74,7 @@ import java.time.ZoneId; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoField; +import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAdjuster; @@ -114,7 +116,7 @@ import java.util.Objects; * @param the concrete type for the date of this date-time * @since 1.8 */ -public interface ChronoLocalDateTime> +public interface ChronoLocalDateTime extends Temporal, TemporalAdjuster, Comparable> { /** @@ -191,9 +193,54 @@ public interface ChronoLocalDateTime> */ LocalTime toLocalTime(); - @Override // Override to provide javadoc + /** + * Checks if the specified field is supported. + *

    + * This checks if the specified field can be queried on this date-time. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. + *

    + * The set of supported fields is defined by the chronology and normally includes + * all {@code ChronoField} date and time fields. + *

    + * If the field is not a {@code ChronoField}, then the result of this method + * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} + * passing {@code this} as the argument. + * Whether the field is supported is determined by the field. + * + * @param field the field to check, null returns false + * @return true if the field can be queried, false if not + */ + @Override boolean isSupported(TemporalField field); + /** + * Checks if the specified unit is supported. + *

    + * This checks if the specified unit can be added to or subtracted from this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + *

    + * The set of supported units is defined by the chronology and normally includes + * all {@code ChronoUnit} units except {@code FOREVER}. + *

    + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override + default boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit != FOREVER; + } + return unit != null && unit.isSupportedBy(this); + } + //----------------------------------------------------------------------- // override for covariant return type /** @@ -203,7 +250,7 @@ public interface ChronoLocalDateTime> */ @Override default ChronoLocalDateTime with(TemporalAdjuster adjuster) { - return (ChronoLocalDateTime)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.with(adjuster))); + return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.with(adjuster)); } /** @@ -221,7 +268,7 @@ public interface ChronoLocalDateTime> */ @Override default ChronoLocalDateTime plus(TemporalAmount amount) { - return (ChronoLocalDateTime)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.plus(amount))); + return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.plus(amount)); } /** @@ -239,7 +286,7 @@ public interface ChronoLocalDateTime> */ @Override default ChronoLocalDateTime minus(TemporalAmount amount) { - return (ChronoLocalDateTime)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.minus(amount))); + return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amount)); } /** @@ -249,7 +296,7 @@ public interface ChronoLocalDateTime> */ @Override default ChronoLocalDateTime minus(long amountToSubtract, TemporalUnit unit) { - return (ChronoLocalDateTime)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.minus(amountToSubtract, unit))); + return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amountToSubtract, unit)); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java index 1f7195bc6f7..14f7bd927c2 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java @@ -98,7 +98,7 @@ import java.util.Objects; * @param the concrete type for the date of this date-time * @since 1.8 */ -final class ChronoLocalDateTimeImpl> +final class ChronoLocalDateTimeImpl implements ChronoLocalDateTime, Temporal, TemporalAdjuster, Serializable { /** @@ -171,9 +171,27 @@ final class ChronoLocalDateTimeImpl> * @param time the local time, not null * @return the local date-time, not null */ - @SuppressWarnings("rawtypes") - static ChronoLocalDateTimeImpl of(ChronoLocalDate date, LocalTime time) { - return new ChronoLocalDateTimeImpl(date, time); + static ChronoLocalDateTimeImpl of(R date, LocalTime time) { + return new ChronoLocalDateTimeImpl<>(date, time); + } + + /** + * Casts the {@code Temporal} to {@code ChronoLocalDateTime} ensuring it bas the specified chronology. + * + * @param chrono the chronology to check for, not null + * @param temporal a date-time to cast, not null + * @return the date-time checked and cast to {@code ChronoLocalDateTime}, not null + * @throws ClassCastException if the date-time cannot be cast to ChronoLocalDateTimeImpl + * or the chronology is not equal this Chronology + */ + static ChronoLocalDateTimeImpl ensureValid(Chronology chrono, Temporal temporal) { + @SuppressWarnings("unchecked") + ChronoLocalDateTimeImpl other = (ChronoLocalDateTimeImpl) temporal; + if (chrono.equals(other.toLocalDate().getChronology()) == false) { + throw new ClassCastException("Chronology mismatch, required: " + chrono.getId() + + ", actual: " + other.toLocalDate().getChronology().getId()); + } + return other; } /** @@ -202,7 +220,7 @@ final class ChronoLocalDateTimeImpl> return this; } // Validate that the new Temporal is a ChronoLocalDate (and not something else) - D cd = (D) date.getChronology().ensureChronoLocalDate(newDate); + D cd = ChronoDateImpl.ensureValid(date.getChronology(), newDate); return new ChronoLocalDateTimeImpl<>(cd, newTime); } @@ -260,13 +278,13 @@ final class ChronoLocalDateTimeImpl> public ChronoLocalDateTimeImpl with(TemporalAdjuster adjuster) { if (adjuster instanceof ChronoLocalDate) { // The Chronology is checked in with(date,time) - return with((ChronoLocalDate) adjuster, time); + return with((ChronoLocalDate) adjuster, time); } else if (adjuster instanceof LocalTime) { return with(date, (LocalTime) adjuster); } else if (adjuster instanceof ChronoLocalDateTimeImpl) { - return (ChronoLocalDateTimeImpl)(date.getChronology().ensureChronoLocalDateTime((ChronoLocalDateTimeImpl) adjuster)); + return ChronoLocalDateTimeImpl.ensureValid(date.getChronology(), (ChronoLocalDateTimeImpl) adjuster); } - return (ChronoLocalDateTimeImpl)(date.getChronology().ensureChronoLocalDateTime((ChronoLocalDateTimeImpl) adjuster.adjustInto(this))); + return ChronoLocalDateTimeImpl.ensureValid(date.getChronology(), (ChronoLocalDateTimeImpl) adjuster.adjustInto(this)); } @Override @@ -279,7 +297,7 @@ final class ChronoLocalDateTimeImpl> return with(date.with(field, newValue), time); } } - return (ChronoLocalDateTimeImpl)(date.getChronology().ensureChronoLocalDateTime(field.adjustInto(this, newValue))); + return ChronoLocalDateTimeImpl.ensureValid(date.getChronology(), field.adjustInto(this, newValue)); } //----------------------------------------------------------------------- @@ -298,7 +316,7 @@ final class ChronoLocalDateTimeImpl> } return with(date.plus(amountToAdd, unit), time); } - return (ChronoLocalDateTimeImpl)(date.getChronology().ensureChronoLocalDateTime(unit.addTo(this, amountToAdd))); + return ChronoLocalDateTimeImpl.ensureValid(date.getChronology(), unit.addTo(this, amountToAdd)); } private ChronoLocalDateTimeImpl plusDays(long days) { @@ -322,7 +340,7 @@ final class ChronoLocalDateTimeImpl> } //----------------------------------------------------------------------- - private ChronoLocalDateTimeImpl plusWithOverflow(ChronoLocalDate newDate, long hours, long minutes, long seconds, long nanos) { + private ChronoLocalDateTimeImpl plusWithOverflow(D newDate, long hours, long minutes, long seconds, long nanos) { // 9223372036854775808 long, 2147483648 int if ((hours | minutes | seconds | nanos) == 0) { return with(newDate, time); @@ -351,7 +369,7 @@ final class ChronoLocalDateTimeImpl> //----------------------------------------------------------------------- @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof ChronoLocalDateTime == false) { throw new DateTimeException("Unable to calculate amount as objects are of two different types"); } @@ -361,10 +379,9 @@ final class ChronoLocalDateTimeImpl> throw new DateTimeException("Unable to calculate amount as objects have different chronologies"); } if (unit instanceof ChronoUnit) { - ChronoUnit f = (ChronoUnit) unit; - if (f.isTimeUnit()) { + if (unit.isTimeBased()) { long amount = end.getLong(EPOCH_DAY) - date.getLong(EPOCH_DAY); - switch (f) { + switch ((ChronoUnit) unit) { case NANOS: amount = Math.multiplyExact(amount, NANOS_PER_DAY); break; case MICROS: amount = Math.multiplyExact(amount, MICROS_PER_DAY); break; case MILLIS: amount = Math.multiplyExact(amount, MILLIS_PER_DAY); break; @@ -373,13 +390,13 @@ final class ChronoLocalDateTimeImpl> case HOURS: amount = Math.multiplyExact(amount, HOURS_PER_DAY); break; case HALF_DAYS: amount = Math.multiplyExact(amount, 2); break; } - return Math.addExact(amount, time.periodUntil(end.toLocalTime(), unit)); + return Math.addExact(amount, time.until(end.toLocalTime(), unit)); } - D endDate = end.toLocalDate(); + ChronoLocalDate endDate = end.toLocalDate(); if (end.toLocalTime().isBefore(time)) { endDate = endDate.minus(1, ChronoUnit.DAYS); } - return date.periodUntil(endDate, unit); + return date.until(endDate, unit); } return unit.between(this, endDateTime); } @@ -404,7 +421,7 @@ final class ChronoLocalDateTimeImpl> } static ChronoLocalDateTime readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - ChronoLocalDate date = (ChronoLocalDate) in.readObject(); + ChronoLocalDate date = (ChronoLocalDate) in.readObject(); LocalTime time = (LocalTime) in.readObject(); return date.atTime(time); } diff --git a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java index d838a36ec29..dd911fcd789 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java @@ -63,6 +63,7 @@ package java.time.chrono; import static java.time.temporal.ChronoField.INSTANT_SECONDS; import static java.time.temporal.ChronoField.OFFSET_SECONDS; +import static java.time.temporal.ChronoUnit.FOREVER; import static java.time.temporal.ChronoUnit.NANOS; import java.time.DateTimeException; @@ -73,6 +74,7 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoField; +import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAdjuster; @@ -115,7 +117,7 @@ import java.util.Objects; * @param the concrete type for the date of this date-time * @since 1.8 */ -public interface ChronoZonedDateTime> +public interface ChronoZonedDateTime extends Temporal, Comparable> { /** @@ -338,9 +340,54 @@ public interface ChronoZonedDateTime> */ ChronoZonedDateTime withZoneSameInstant(ZoneId zone); - @Override // Override to provide javadoc + /** + * Checks if the specified field is supported. + *

    + * This checks if the specified field can be queried on this date-time. + * If false, then calling the {@link #range(TemporalField) range}, + * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} + * methods will throw an exception. + *

    + * The set of supported fields is defined by the chronology and normally includes + * all {@code ChronoField} fields. + *

    + * If the field is not a {@code ChronoField}, then the result of this method + * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} + * passing {@code this} as the argument. + * Whether the field is supported is determined by the field. + * + * @param field the field to check, null returns false + * @return true if the field can be queried, false if not + */ + @Override boolean isSupported(TemporalField field); + /** + * Checks if the specified unit is supported. + *

    + * This checks if the specified unit can be added to or subtracted from this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + *

    + * The set of supported units is defined by the chronology and normally includes + * all {@code ChronoUnit} units except {@code FOREVER}. + *

    + * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + * Whether the unit is supported is determined by the unit. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + @Override + default boolean isSupported(TemporalUnit unit) { + if (unit instanceof ChronoUnit) { + return unit != FOREVER; + } + return unit != null && unit.isSupportedBy(this); + } + //----------------------------------------------------------------------- // override for covariant return type /** @@ -350,7 +397,7 @@ public interface ChronoZonedDateTime> */ @Override default ChronoZonedDateTime with(TemporalAdjuster adjuster) { - return (ChronoZonedDateTime)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.with(adjuster))); + return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.with(adjuster)); } /** @@ -368,7 +415,7 @@ public interface ChronoZonedDateTime> */ @Override default ChronoZonedDateTime plus(TemporalAmount amount) { - return (ChronoZonedDateTime)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.plus(amount))); + return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.plus(amount)); } /** @@ -386,7 +433,7 @@ public interface ChronoZonedDateTime> */ @Override default ChronoZonedDateTime minus(TemporalAmount amount) { - return (ChronoZonedDateTime)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.minus(amount))); + return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amount)); } /** @@ -396,7 +443,7 @@ public interface ChronoZonedDateTime> */ @Override default ChronoZonedDateTime minus(long amountToSubtract, TemporalUnit unit) { - return (ChronoZonedDateTime)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.minus(amountToSubtract, unit))); + return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amountToSubtract, unit)); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java index 835ec932184..a39ed298d37 100644 --- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java +++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java @@ -101,7 +101,7 @@ import java.util.Objects; * @param the concrete type for the date of this date-time * @since 1.8 */ -final class ChronoZonedDateTimeImpl> +final class ChronoZonedDateTimeImpl implements ChronoZonedDateTime, Serializable { /** @@ -131,7 +131,7 @@ final class ChronoZonedDateTimeImpl> * @param preferredOffset the zone offset, null if no preference * @return the zoned date-time, not null */ - static > ChronoZonedDateTime ofBest( + static ChronoZonedDateTime ofBest( ChronoLocalDateTimeImpl localDateTime, ZoneId zone, ZoneOffset preferredOffset) { Objects.requireNonNull(localDateTime, "localDateTime"); Objects.requireNonNull(zone, "zone"); @@ -167,14 +167,13 @@ final class ChronoZonedDateTimeImpl> * @param zone the zone identifier, not null * @return the zoned date-time, not null */ - @SuppressWarnings("rawtypes") static ChronoZonedDateTimeImpl ofInstant(Chronology chrono, Instant instant, ZoneId zone) { ZoneRules rules = zone.getRules(); ZoneOffset offset = rules.getOffset(instant); Objects.requireNonNull(offset, "offset"); // protect against bad ZoneRules LocalDateTime ldt = LocalDateTime.ofEpochSecond(instant.getEpochSecond(), instant.getNano(), offset); - ChronoLocalDateTimeImpl cldt = (ChronoLocalDateTimeImpl) chrono.localDateTime(ldt); - return new ChronoZonedDateTimeImpl(cldt, offset, zone); + ChronoLocalDateTimeImpl cldt = (ChronoLocalDateTimeImpl)chrono.localDateTime(ldt); + return new ChronoZonedDateTimeImpl<>(cldt, offset, zone); } /** @@ -184,10 +183,30 @@ final class ChronoZonedDateTimeImpl> * @param zone the time-zone to use, validated not null * @return the zoned date-time, validated not null */ + @SuppressWarnings("unchecked") private ChronoZonedDateTimeImpl create(Instant instant, ZoneId zone) { return (ChronoZonedDateTimeImpl)ofInstant(toLocalDate().getChronology(), instant, zone); } + /** + * Casts the {@code Temporal} to {@code ChronoZonedDateTimeImpl} ensuring it bas the specified chronology. + * + * @param chrono the chronology to check for, not null + * @param temporal a date-time to cast, not null + * @return the date-time checked and cast to {@code ChronoZonedDateTimeImpl}, not null + * @throws ClassCastException if the date-time cannot be cast to ChronoZonedDateTimeImpl + * or the chronology is not equal this Chronology + */ + static ChronoZonedDateTimeImpl ensureValid(Chronology chrono, Temporal temporal) { + @SuppressWarnings("unchecked") + ChronoZonedDateTimeImpl other = (ChronoZonedDateTimeImpl) temporal; + if (chrono.equals(other.toLocalDate().getChronology()) == false) { + throw new ClassCastException("Chronology mismatch, required: " + chrono.getId() + + ", actual: " + other.toLocalDate().getChronology().getId()); + } + return other; + } + //----------------------------------------------------------------------- /** * Constructor. @@ -271,7 +290,7 @@ final class ChronoZonedDateTimeImpl> } return ofBest(dateTime.with(field, newValue), zone, offset); } - return (ChronoZonedDateTime)(toLocalDate().getChronology().ensureChronoZonedDateTime(field.adjustInto(this, newValue))); + return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), field.adjustInto(this, newValue)); } //----------------------------------------------------------------------- @@ -280,12 +299,12 @@ final class ChronoZonedDateTimeImpl> if (unit instanceof ChronoUnit) { return with(dateTime.plus(amountToAdd, unit)); } - return (ChronoZonedDateTime)(toLocalDate().getChronology().ensureChronoZonedDateTime(unit.addTo(this, amountToAdd))); /// TODO: Generics replacement Risk! + return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), unit.addTo(this, amountToAdd)); /// TODO: Generics replacement Risk! } //----------------------------------------------------------------------- @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof ChronoZonedDateTime == false) { throw new DateTimeException("Unable to calculate amount as objects are of two different types"); } @@ -296,7 +315,7 @@ final class ChronoZonedDateTimeImpl> } if (unit instanceof ChronoUnit) { end = end.withZoneSameInstant(offset); - return dateTime.periodUntil(end.toLocalDateTime(), unit); + return dateTime.until(end.toLocalDateTime(), unit); } return unit.between(this, endDateTime); } diff --git a/jdk/src/share/classes/java/time/chrono/Chronology.java b/jdk/src/share/classes/java/time/chrono/Chronology.java index e5daae76464..561e2f794fa 100644 --- a/jdk/src/share/classes/java/time/chrono/Chronology.java +++ b/jdk/src/share/classes/java/time/chrono/Chronology.java @@ -74,6 +74,9 @@ import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.WEEKS; import static java.time.temporal.TemporalAdjuster.nextOrSame; import java.io.DataInput; @@ -88,14 +91,16 @@ import java.time.DayOfWeek; import java.time.Instant; import java.time.LocalDate; import java.time.LocalTime; +import java.time.Month; +import java.time.Year; import java.time.ZoneId; import java.time.format.DateTimeFormatterBuilder; import java.time.format.ResolverStyle; import java.time.format.TextStyle; import java.time.temporal.ChronoField; -import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; import java.time.temporal.UnsupportedTemporalTypeException; @@ -188,8 +193,8 @@ public abstract class Chronology implements Comparable { /** * ChronoLocalDate order constant. */ - static final Comparator> DATE_ORDER = - (Comparator> & Serializable) (date1, date2) -> { + static final Comparator DATE_ORDER = + (Comparator & Serializable) (date1, date2) -> { return Long.compare(date1.toEpochDay(), date2.toEpochDay()); }; /** @@ -480,60 +485,6 @@ public abstract class Chronology implements Comparable { protected Chronology() { } - //----------------------------------------------------------------------- - /** - * Casts the {@code Temporal} to {@code ChronoLocalDate} with the same chronology. - * - * @param temporal a date-time to cast, not null - * @return the date-time checked and cast to {@code ChronoLocalDate}, not null - * @throws ClassCastException if the date-time cannot be cast to ChronoLocalDate - * or the chronology is not equal this Chronology - */ - ChronoLocalDate ensureChronoLocalDate(Temporal temporal) { - @SuppressWarnings("unchecked") - ChronoLocalDate other = (ChronoLocalDate) temporal; - if (this.equals(other.getChronology()) == false) { - throw new ClassCastException("Chronology mismatch, expected: " + getId() + ", actual: " + other.getChronology().getId()); - } - return other; - } - - /** - * Casts the {@code Temporal} to {@code ChronoLocalDateTime} with the same chronology. - * - * @param temporal a date-time to cast, not null - * @return the date-time checked and cast to {@code ChronoLocalDateTime}, not null - * @throws ClassCastException if the date-time cannot be cast to ChronoLocalDateTimeImpl - * or the chronology is not equal this Chronology - */ - ChronoLocalDateTimeImpl ensureChronoLocalDateTime(Temporal temporal) { - @SuppressWarnings("unchecked") - ChronoLocalDateTimeImpl other = (ChronoLocalDateTimeImpl) temporal; - if (this.equals(other.toLocalDate().getChronology()) == false) { - throw new ClassCastException("Chronology mismatch, required: " + getId() - + ", supplied: " + other.toLocalDate().getChronology().getId()); - } - return other; - } - - /** - * Casts the {@code Temporal} to {@code ChronoZonedDateTimeImpl} with the same chronology. - * - * @param temporal a date-time to cast, not null - * @return the date-time checked and cast to {@code ChronoZonedDateTimeImpl}, not null - * @throws ClassCastException if the date-time cannot be cast to ChronoZonedDateTimeImpl - * or the chronology is not equal this Chronology - */ - ChronoZonedDateTimeImpl ensureChronoZonedDateTime(Temporal temporal) { - @SuppressWarnings("unchecked") - ChronoZonedDateTimeImpl other = (ChronoZonedDateTimeImpl) temporal; - if (this.equals(other.toLocalDate().getChronology()) == false) { - throw new ClassCastException("Chronology mismatch, required: " + getId() - + ", supplied: " + other.toLocalDate().getChronology().getId()); - } - return other; - } - //----------------------------------------------------------------------- /** * Gets the ID of the chronology. @@ -574,7 +525,7 @@ public abstract class Chronology implements Comparable { * @throws DateTimeException if unable to create the date * @throws ClassCastException if the {@code era} is not of the correct type for the chronology */ - public ChronoLocalDate date(Era era, int yearOfEra, int month, int dayOfMonth) { + public ChronoLocalDate date(Era era, int yearOfEra, int month, int dayOfMonth) { return date(prolepticYear(era, yearOfEra), month, dayOfMonth); } @@ -588,7 +539,7 @@ public abstract class Chronology implements Comparable { * @return the local date in this chronology, not null * @throws DateTimeException if unable to create the date */ - public abstract ChronoLocalDate date(int prolepticYear, int month, int dayOfMonth); + public abstract ChronoLocalDate date(int prolepticYear, int month, int dayOfMonth); /** * Obtains a local date in this chronology from the era, year-of-era and @@ -601,7 +552,7 @@ public abstract class Chronology implements Comparable { * @throws DateTimeException if unable to create the date * @throws ClassCastException if the {@code era} is not of the correct type for the chronology */ - public ChronoLocalDate dateYearDay(Era era, int yearOfEra, int dayOfYear) { + public ChronoLocalDate dateYearDay(Era era, int yearOfEra, int dayOfYear) { return dateYearDay(prolepticYear(era, yearOfEra), dayOfYear); } @@ -614,7 +565,7 @@ public abstract class Chronology implements Comparable { * @return the local date in this chronology, not null * @throws DateTimeException if unable to create the date */ - public abstract ChronoLocalDate dateYearDay(int prolepticYear, int dayOfYear); + public abstract ChronoLocalDate dateYearDay(int prolepticYear, int dayOfYear); /** * Obtains a local date in this chronology from the epoch-day. @@ -626,7 +577,7 @@ public abstract class Chronology implements Comparable { * @return the local date in this chronology, not null * @throws DateTimeException if unable to create the date */ - public abstract ChronoLocalDate dateEpochDay(long epochDay); + public abstract ChronoLocalDate dateEpochDay(long epochDay); //----------------------------------------------------------------------- /** @@ -643,7 +594,7 @@ public abstract class Chronology implements Comparable { * @return the current local date using the system clock and default time-zone, not null * @throws DateTimeException if unable to create the date */ - public ChronoLocalDate dateNow() { + public ChronoLocalDate dateNow() { return dateNow(Clock.systemDefaultZone()); } @@ -660,7 +611,7 @@ public abstract class Chronology implements Comparable { * @return the current local date using the system clock, not null * @throws DateTimeException if unable to create the date */ - public ChronoLocalDate dateNow(ZoneId zone) { + public ChronoLocalDate dateNow(ZoneId zone) { return dateNow(Clock.system(zone)); } @@ -675,7 +626,7 @@ public abstract class Chronology implements Comparable { * @return the current local date, not null * @throws DateTimeException if unable to create the date */ - public ChronoLocalDate dateNow(Clock clock) { + public ChronoLocalDate dateNow(Clock clock) { Objects.requireNonNull(clock, "clock"); return date(LocalDate.now(clock)); } @@ -699,7 +650,7 @@ public abstract class Chronology implements Comparable { * @throws DateTimeException if unable to create the date * @see ChronoLocalDate#from(TemporalAccessor) */ - public abstract ChronoLocalDate date(TemporalAccessor temporal); + public abstract ChronoLocalDate date(TemporalAccessor temporal); /** * Obtains a local date-time in this chronology from another temporal object. @@ -722,7 +673,7 @@ public abstract class Chronology implements Comparable { * @throws DateTimeException if unable to create the date-time * @see ChronoLocalDateTime#from(TemporalAccessor) */ - public ChronoLocalDateTime localDateTime(TemporalAccessor temporal) { + public ChronoLocalDateTime localDateTime(TemporalAccessor temporal) { try { return date(temporal).atTime(LocalTime.from(temporal)); } catch (DateTimeException ex) { @@ -754,7 +705,7 @@ public abstract class Chronology implements Comparable { * @throws DateTimeException if unable to create the date-time * @see ChronoZonedDateTime#from(TemporalAccessor) */ - public ChronoZonedDateTime zonedDateTime(TemporalAccessor temporal) { + public ChronoZonedDateTime zonedDateTime(TemporalAccessor temporal) { try { ZoneId zone = ZoneId.from(temporal); try { @@ -762,8 +713,7 @@ public abstract class Chronology implements Comparable { return zonedDateTime(instant, zone); } catch (DateTimeException ex1) { - @SuppressWarnings("rawtypes") - ChronoLocalDateTimeImpl cldt = ensureChronoLocalDateTime(localDateTime(temporal)); + ChronoLocalDateTimeImpl cldt = ChronoLocalDateTimeImpl.ensureValid(this, localDateTime(temporal)); return ChronoZonedDateTimeImpl.ofBest(cldt, zone, null); } } catch (DateTimeException ex) { @@ -781,7 +731,7 @@ public abstract class Chronology implements Comparable { * @return the zoned date-time, not null * @throws DateTimeException if the result exceeds the supported range */ - public ChronoZonedDateTime zonedDateTime(Instant instant, ZoneId zone) { + public ChronoZonedDateTime zonedDateTime(Instant instant, ZoneId zone) { return ChronoZonedDateTimeImpl.ofInstant(this, instant, zone); } @@ -929,11 +879,82 @@ public abstract class Chronology implements Comparable { * As such, {@code ChronoField} date fields are resolved here in the * context of a specific chronology. *

    + * {@code ChronoField} instances are resolved by this method, which may + * be overridden in subclasses. + *

      + *
    • {@code EPOCH_DAY} - If present, this is converted to a date and + * all other date fields are then cross-checked against the date. + *
    • {@code PROLEPTIC_MONTH} - If present, then it is split into the + * {@code YEAR} and {@code MONTH_OF_YEAR}. If the mode is strict or smart + * then the field is validated. + *
    • {@code YEAR_OF_ERA} and {@code ERA} - If both are present, then they + * are combined to form a {@code YEAR}. In lenient mode, the {@code YEAR_OF_ERA} + * range is not validated, in smart and strict mode it is. The {@code ERA} is + * validated for range in all three modes. If only the {@code YEAR_OF_ERA} is + * present, and the mode is smart or lenient, then the last available era + * is assumed. In strict mode, no era is assumed and the {@code YEAR_OF_ERA} is + * left untouched. If only the {@code ERA} is present, then it is left untouched. + *
    • {@code YEAR}, {@code MONTH_OF_YEAR} and {@code DAY_OF_MONTH} - + * If all three are present, then they are combined to form a date. + * In all three modes, the {@code YEAR} is validated. + * If the mode is smart or strict, then the month and day are validated. + * If the mode is lenient, then the date is combined in a manner equivalent to + * creating a date on the first day of the first month in the requested year, + * then adding the difference in months, then the difference in days. + * If the mode is smart, and the day-of-month is greater than the maximum for + * the year-month, then the day-of-month is adjusted to the last day-of-month. + * If the mode is strict, then the three fields must form a valid date. + *
    • {@code YEAR} and {@code DAY_OF_YEAR} - + * If both are present, then they are combined to form a date. + * In all three modes, the {@code YEAR} is validated. + * If the mode is lenient, then the date is combined in a manner equivalent to + * creating a date on the first day of the requested year, then adding + * the difference in days. + * If the mode is smart or strict, then the two fields must form a valid date. + *
    • {@code YEAR}, {@code MONTH_OF_YEAR}, {@code ALIGNED_WEEK_OF_MONTH} and + * {@code ALIGNED_DAY_OF_WEEK_IN_MONTH} - + * If all four are present, then they are combined to form a date. + * In all three modes, the {@code YEAR} is validated. + * If the mode is lenient, then the date is combined in a manner equivalent to + * creating a date on the first day of the first month in the requested year, then adding + * the difference in months, then the difference in weeks, then in days. + * If the mode is smart or strict, then the all four fields are validated to + * their outer ranges. The date is then combined in a manner equivalent to + * creating a date on the first day of the requested year and month, then adding + * the amount in weeks and days to reach their values. If the mode is strict, + * the date is additionally validated to check that the day and week adjustment + * did not change the month. + *
    • {@code YEAR}, {@code MONTH_OF_YEAR}, {@code ALIGNED_WEEK_OF_MONTH} and + * {@code DAY_OF_WEEK} - If all four are present, then they are combined to + * form a date. The approach is the same as described above for + * years, months and weeks in {@code ALIGNED_DAY_OF_WEEK_IN_MONTH}. + * The day-of-week is adjusted as the next or same matching day-of-week once + * the years, months and weeks have been handled. + *
    • {@code YEAR}, {@code ALIGNED_WEEK_OF_YEAR} and {@code ALIGNED_DAY_OF_WEEK_IN_YEAR} - + * If all three are present, then they are combined to form a date. + * In all three modes, the {@code YEAR} is validated. + * If the mode is lenient, then the date is combined in a manner equivalent to + * creating a date on the first day of the requested year, then adding + * the difference in weeks, then in days. + * If the mode is smart or strict, then the all three fields are validated to + * their outer ranges. The date is then combined in a manner equivalent to + * creating a date on the first day of the requested year, then adding + * the amount in weeks and days to reach their values. If the mode is strict, + * the date is additionally validated to check that the day and week adjustment + * did not change the year. + *
    • {@code YEAR}, {@code ALIGNED_WEEK_OF_YEAR} and {@code DAY_OF_WEEK} - + * If all three are present, then they are combined to form a date. + * The approach is the same as described above for years and weeks in + * {@code ALIGNED_DAY_OF_WEEK_IN_YEAR}. The day-of-week is adjusted as the + * next or same matching day-of-week once the years and weeks have been handled. + *
    + *

    * The default implementation is suitable for most calendar systems. * If {@link ChronoField#YEAR_OF_ERA} is found without an {@link ChronoField#ERA} * then the last era in {@link #eras()} is used. * The implementation assumes a 7 day week, that the first day-of-month - * has the value 1, and that first day-of-year has the value 1. + * has the value 1, that first day-of-year has the value 1, and that the + * first of the month and year always exists. * * @param fieldValues the map of fields to values, which can be updated, not null * @param resolverStyle the requested type of resolve, not null @@ -941,99 +962,214 @@ public abstract class Chronology implements Comparable { * @throws DateTimeException if the date cannot be resolved, typically * because of a conflict in the input data */ - public ChronoLocalDate resolveDate(Map fieldValues, ResolverStyle resolverStyle) { + public ChronoLocalDate resolveDate(Map fieldValues, ResolverStyle resolverStyle) { // check epoch-day before inventing era if (fieldValues.containsKey(EPOCH_DAY)) { return dateEpochDay(fieldValues.remove(EPOCH_DAY)); } // fix proleptic month before inventing era - Long pMonth = fieldValues.remove(PROLEPTIC_MONTH); - if (pMonth != null) { - // first day-of-month is likely to be safest for setting proleptic-month - // cannot add to year zero, as not all chronologies have a year zero - ChronoLocalDate chronoDate = dateNow() - .with(DAY_OF_MONTH, 1).with(PROLEPTIC_MONTH, pMonth); - addFieldValue(fieldValues, MONTH_OF_YEAR, chronoDate.get(MONTH_OF_YEAR)); - addFieldValue(fieldValues, YEAR, chronoDate.get(YEAR)); - } + resolveProlepticMonth(fieldValues, resolverStyle); // invent era if necessary to resolve year-of-era - Long yoeLong = fieldValues.remove(YEAR_OF_ERA); - if (yoeLong != null) { - Long eraLong = fieldValues.remove(ERA); - int yoe = range(YEAR_OF_ERA).checkValidIntValue(yoeLong, YEAR_OF_ERA); - if (eraLong != null) { - Era eraObj = eraOf(Math.toIntExact(eraLong)); - addFieldValue(fieldValues, YEAR, prolepticYear(eraObj, yoe)); - } else if (fieldValues.containsKey(YEAR)) { - int year = range(YEAR).checkValidIntValue(fieldValues.get(YEAR), YEAR); - ChronoLocalDate chronoDate = dateYearDay(year, 1); - addFieldValue(fieldValues, YEAR, prolepticYear(chronoDate.getEra(), yoe)); - } else { - List eras = eras(); - if (eras.isEmpty()) { - addFieldValue(fieldValues, YEAR, yoe); - } else { - Era eraObj = eras.get(eras.size() - 1); - addFieldValue(fieldValues, YEAR, prolepticYear(eraObj, yoe)); - } - } + ChronoLocalDate resolved = resolveYearOfEra(fieldValues, resolverStyle); + if (resolved != null) { + return resolved; } // build date if (fieldValues.containsKey(YEAR)) { if (fieldValues.containsKey(MONTH_OF_YEAR)) { if (fieldValues.containsKey(DAY_OF_MONTH)) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); - int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH); - return date(y, moy, dom); + return resolveYMD(fieldValues, resolverStyle); } if (fieldValues.containsKey(ALIGNED_WEEK_OF_MONTH)) { if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_MONTH)) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); - int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); - int ad = range(ALIGNED_DAY_OF_WEEK_IN_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), ALIGNED_DAY_OF_WEEK_IN_MONTH); - ChronoLocalDate chronoDate = date(y, moy, 1); - return chronoDate.plus((aw - 1) * 7 + (ad - 1), ChronoUnit.DAYS); + return resolveYMAA(fieldValues, resolverStyle); } if (fieldValues.containsKey(DAY_OF_WEEK)) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); - int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); - int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); - ChronoLocalDate chronoDate = date(y, moy, 1); - return chronoDate.plus((aw - 1) * 7, ChronoUnit.DAYS).with(nextOrSame(DayOfWeek.of(dow))); + return resolveYMAD(fieldValues, resolverStyle); } } } if (fieldValues.containsKey(DAY_OF_YEAR)) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - int doy = range(DAY_OF_YEAR).checkValidIntValue(fieldValues.remove(DAY_OF_YEAR), DAY_OF_YEAR); - return dateYearDay(y, doy); + return resolveYD(fieldValues, resolverStyle); } if (fieldValues.containsKey(ALIGNED_WEEK_OF_YEAR)) { if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_YEAR)) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); - int ad = range(ALIGNED_DAY_OF_WEEK_IN_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), ALIGNED_DAY_OF_WEEK_IN_YEAR); - ChronoLocalDate chronoDate = dateYearDay(y, 1); - return chronoDate.plus((aw - 1) * 7 + (ad - 1), ChronoUnit.DAYS); + return resolveYAA(fieldValues, resolverStyle); } if (fieldValues.containsKey(DAY_OF_WEEK)) { - int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); - int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); - int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); - ChronoLocalDate chronoDate = dateYearDay(y, 1); - return chronoDate.plus((aw - 1) * 7, ChronoUnit.DAYS).with(nextOrSame(DayOfWeek.of(dow))); + return resolveYAD(fieldValues, resolverStyle); } } } return null; } + void resolveProlepticMonth(Map fieldValues, ResolverStyle resolverStyle) { + Long pMonth = fieldValues.remove(PROLEPTIC_MONTH); + if (pMonth != null) { + if (resolverStyle != ResolverStyle.LENIENT) { + PROLEPTIC_MONTH.checkValidValue(pMonth); + } + // first day-of-month is likely to be safest for setting proleptic-month + // cannot add to year zero, as not all chronologies have a year zero + ChronoLocalDate chronoDate = dateNow() + .with(DAY_OF_MONTH, 1).with(PROLEPTIC_MONTH, pMonth); + addFieldValue(fieldValues, MONTH_OF_YEAR, chronoDate.get(MONTH_OF_YEAR)); + addFieldValue(fieldValues, YEAR, chronoDate.get(YEAR)); + } + } + + ChronoLocalDate resolveYearOfEra(Map fieldValues, ResolverStyle resolverStyle) { + Long yoeLong = fieldValues.remove(YEAR_OF_ERA); + if (yoeLong != null) { + Long eraLong = fieldValues.remove(ERA); + int yoe; + if (resolverStyle != ResolverStyle.LENIENT) { + yoe = range(YEAR_OF_ERA).checkValidIntValue(yoeLong, YEAR_OF_ERA); + } else { + yoe = Math.toIntExact(yoeLong); + } + if (eraLong != null) { + Era eraObj = eraOf(range(ERA).checkValidIntValue(eraLong, ERA)); + addFieldValue(fieldValues, YEAR, prolepticYear(eraObj, yoe)); + } else { + if (fieldValues.containsKey(YEAR)) { + int year = range(YEAR).checkValidIntValue(fieldValues.get(YEAR), YEAR); + ChronoLocalDate chronoDate = dateYearDay(year, 1); + addFieldValue(fieldValues, YEAR, prolepticYear(chronoDate.getEra(), yoe)); + } else if (resolverStyle == ResolverStyle.STRICT) { + // do not invent era if strict + // reinstate the field removed earlier, no cross-check issues + fieldValues.put(YEAR_OF_ERA, yoeLong); + } else { + List eras = eras(); + if (eras.isEmpty()) { + addFieldValue(fieldValues, YEAR, yoe); + } else { + Era eraObj = eras.get(eras.size() - 1); + addFieldValue(fieldValues, YEAR, prolepticYear(eraObj, yoe)); + } + } + } + } else if (fieldValues.containsKey(ERA)) { + range(ERA).checkValidValue(fieldValues.get(ERA), ERA); // always validated + } + return null; + } + + ChronoLocalDate resolveYMD(Map fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); + long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1); + return date(y, 1, 1).plus(months, MONTHS).plus(days, DAYS); + } + int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); + ValueRange domRange = range(DAY_OF_MONTH); + int dom = domRange.checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH); + if (resolverStyle == ResolverStyle.SMART) { // previous valid + try { + return date(y, moy, dom); + } catch (DateTimeException ex) { + return date(y, moy, 1).with(TemporalAdjuster.lastDayOfMonth()); + } + } + return date(y, moy, dom); + } + + ChronoLocalDate resolveYD(Map fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long days = Math.subtractExact(fieldValues.remove(DAY_OF_YEAR), 1); + return dateYearDay(y, 1).plus(days, DAYS); + } + int doy = range(DAY_OF_YEAR).checkValidIntValue(fieldValues.remove(DAY_OF_YEAR), DAY_OF_YEAR); + return dateYearDay(y, doy); // smart is same as strict + } + + ChronoLocalDate resolveYMAA(Map fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); + long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1); + long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), 1); + return date(y, 1, 1).plus(months, MONTHS).plus(weeks, WEEKS).plus(days, DAYS); + } + int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); + int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); + int ad = range(ALIGNED_DAY_OF_WEEK_IN_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), ALIGNED_DAY_OF_WEEK_IN_MONTH); + ChronoLocalDate date = date(y, moy, 1).plus((aw - 1) * 7 + (ad - 1), DAYS); + if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); + } + return date; + } + + ChronoLocalDate resolveYMAD(Map fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); + long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1); + long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1); + return resolveAligned(date(y, 1, 1), months, weeks, dow); + } + int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); + int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); + int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); + ChronoLocalDate date = date(y, moy, 1).plus((aw - 1) * 7, DAYS).with(nextOrSame(DayOfWeek.of(dow))); + if (resolverStyle == ResolverStyle.STRICT && date.get(MONTH_OF_YEAR) != moy) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); + } + return date; + } + + ChronoLocalDate resolveYAA(Map fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1); + long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), 1); + return dateYearDay(y, 1).plus(weeks, WEEKS).plus(days, DAYS); + } + int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); + int ad = range(ALIGNED_DAY_OF_WEEK_IN_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), ALIGNED_DAY_OF_WEEK_IN_YEAR); + ChronoLocalDate date = dateYearDay(y, 1).plus((aw - 1) * 7 + (ad - 1), DAYS); + if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); + } + return date; + } + + ChronoLocalDate resolveYAD(Map fieldValues, ResolverStyle resolverStyle) { + int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); + if (resolverStyle == ResolverStyle.LENIENT) { + long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1); + long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1); + return resolveAligned(dateYearDay(y, 1), 0, weeks, dow); + } + int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); + int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); + ChronoLocalDate date = dateYearDay(y, 1).plus((aw - 1) * 7, DAYS).with(nextOrSame(DayOfWeek.of(dow))); + if (resolverStyle == ResolverStyle.STRICT && date.get(YEAR) != y) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); + } + return date; + } + + ChronoLocalDate resolveAligned(ChronoLocalDate base, long months, long weeks, long dow) { + ChronoLocalDate date = base.plus(months, MONTHS).plus(weeks, WEEKS); + if (dow > 7) { + date = date.plus((dow - 1) / 7, WEEKS); + dow = ((dow - 1) % 7) + 1; + } else if (dow < 1) { + date = date.plus(Math.subtractExact(dow, 7) / 7, WEEKS); + dow = ((dow + 6) % 7) + 1; + } + return date.with(nextOrSame(DayOfWeek.of((int) dow))); + } + /** * Adds a field-value pair to the map, checking for conflicts. *

    diff --git a/jdk/src/share/classes/java/time/chrono/Era.java b/jdk/src/share/classes/java/time/chrono/Era.java index 330346dcc36..0fd31c9887d 100644 --- a/jdk/src/share/classes/java/time/chrono/Era.java +++ b/jdk/src/share/classes/java/time/chrono/Era.java @@ -238,7 +238,7 @@ public interface Era extends TemporalAccessor, TemporalAdjuster { if (field == ERA) { return getValue(); } else if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } diff --git a/jdk/src/share/classes/java/time/chrono/HijrahChronology.java b/jdk/src/share/classes/java/time/chrono/HijrahChronology.java index 63dfc1c213b..c5061b05a32 100644 --- a/jdk/src/share/classes/java/time/chrono/HijrahChronology.java +++ b/jdk/src/share/classes/java/time/chrono/HijrahChronology.java @@ -71,8 +71,10 @@ import java.time.DateTimeException; import java.time.Instant; import java.time.LocalDate; import java.time.ZoneId; +import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalField; import java.time.temporal.ValueRange; import java.util.Arrays; import java.util.HashMap; @@ -115,7 +117,7 @@ import sun.util.logging.PlatformLogger; *

* * - * + * * * * @@ -126,10 +128,10 @@ import sun.util.logging.PlatformLogger; *

* Selecting the chronology from the locale uses {@link Chronology#ofLocale} * to find the Chronology based on Locale supported BCP 47 extension mechanism - * to request a specific calendar ("ca") and variant ("cv"). For example, + * to request a specific calendar ("ca"). For example, *

*
- *      Locale locale = Locale.forLanguageTag("en-US-u-ca-islamic-cv-umalqura");
+ *      Locale locale = Locale.forLanguageTag("en-US-u-ca-islamic-umalqura");
  *      Chronology chrono = Chronology.ofLocale(locale);
  * 
* @@ -472,11 +474,16 @@ public final class HijrahChronology extends Chronology implements Serializable { * @param prolepticYear the proleptic-year * @param dayOfYear the day-of-year * @return the Hijrah local date, not null - * @throws DateTimeException if unable to create the date + * @throws DateTimeException if the value of the year is out of range, + * or if the day-of-year is invalid for the year */ @Override public HijrahDate dateYearDay(int prolepticYear, int dayOfYear) { - return HijrahDate.of(this, prolepticYear, 1, 1).plusDays(dayOfYear - 1); // TODO better + HijrahDate date = HijrahDate.of(this, prolepticYear, 1, 1); + if (dayOfYear > date.lengthOfYear()) { + throw new DateTimeException("Invalid dayOfYear: " + dayOfYear); + } + return date.plusDays(dayOfYear - 1); } /** @@ -515,16 +522,19 @@ public final class HijrahChronology extends Chronology implements Serializable { } @Override + @SuppressWarnings("unchecked") public ChronoLocalDateTime localDateTime(TemporalAccessor temporal) { return (ChronoLocalDateTime) super.localDateTime(temporal); } @Override + @SuppressWarnings("unchecked") public ChronoZonedDateTime zonedDateTime(TemporalAccessor temporal) { return (ChronoZonedDateTime) super.zonedDateTime(temporal); } @Override + @SuppressWarnings("unchecked") public ChronoZonedDateTime zonedDateTime(Instant instant, ZoneId zone) { return (ChronoZonedDateTime) super.zonedDateTime(instant, zone); } @@ -550,7 +560,7 @@ public final class HijrahChronology extends Chronology implements Serializable { } @Override - public Era eraOf(int eraValue) { + public HijrahEra eraOf(int eraValue) { switch (eraValue) { case 1: return HijrahEra.AH; @@ -580,6 +590,8 @@ public final class HijrahChronology extends Chronology implements Serializable { case YEAR: case YEAR_OF_ERA: return ValueRange.of(getMinimumYear(), getMaximumYear()); + case ERA: + return ValueRange.of(1, 1); default: return field.range(); } @@ -587,6 +599,13 @@ public final class HijrahChronology extends Chronology implements Serializable { return field.range(); } + //----------------------------------------------------------------------- + @Override // override for return type + public HijrahDate resolveDate(Map fieldValues, ResolverStyle resolverStyle) { + return (HijrahDate) super.resolveDate(fieldValues, resolverStyle); + } + + //----------------------------------------------------------------------- /** * Check the validity of a year. * diff --git a/jdk/src/share/classes/java/time/chrono/HijrahDate.java b/jdk/src/share/classes/java/time/chrono/HijrahDate.java index 3c01e94b980..ef40b6dc948 100644 --- a/jdk/src/share/classes/java/time/chrono/HijrahDate.java +++ b/jdk/src/share/classes/java/time/chrono/HijrahDate.java @@ -109,7 +109,7 @@ import java.time.temporal.ValueRange; */ public final class HijrahDate extends ChronoDateImpl - implements ChronoLocalDate, Serializable { + implements ChronoLocalDate, Serializable { /** * Serialization version. @@ -204,7 +204,7 @@ public final class HijrahDate * @throws DateTimeException if the current date cannot be obtained */ public static HijrahDate now(Clock clock) { - return HijrahChronology.INSTANCE.date(LocalDate.now(clock)); + return HijrahDate.ofEpochDay(HijrahChronology.INSTANCE, LocalDate.now(clock).toEpochDay()); } /** @@ -349,7 +349,7 @@ public final class HijrahDate } return getChronology().range(f); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); } @@ -372,7 +372,7 @@ public final class HijrahDate case YEAR: return prolepticYear; case ERA: return getEraValue(); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } @@ -393,7 +393,7 @@ public final class HijrahDate case ALIGNED_DAY_OF_WEEK_IN_MONTH: return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_MONTH)); case ALIGNED_DAY_OF_WEEK_IN_YEAR: return plusDays(newValue - getLong(ALIGNED_DAY_OF_WEEK_IN_YEAR)); case DAY_OF_MONTH: return resolvePreviousValid(prolepticYear, monthOfYear, nvalue); - case DAY_OF_YEAR: return resolvePreviousValid(prolepticYear, ((nvalue - 1) / 30) + 1, ((nvalue - 1) % 30) + 1); + case DAY_OF_YEAR: return plusDays(Math.min(nvalue, lengthOfYear()) - getDayOfYear()); case EPOCH_DAY: return new HijrahDate(chrono, newValue); case ALIGNED_WEEK_OF_MONTH: return plusDays((newValue - getLong(ALIGNED_WEEK_OF_MONTH)) * 7); case ALIGNED_WEEK_OF_YEAR: return plusDays((newValue - getLong(ALIGNED_WEEK_OF_YEAR)) * 7); @@ -403,9 +403,9 @@ public final class HijrahDate case YEAR: return resolvePreviousValid(nvalue, monthOfYear, dayOfMonth); case ERA: return resolvePreviousValid(1 - prolepticYear, monthOfYear, dayOfMonth); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } - return ChronoLocalDate.super.with(field, newValue); + return super.with(field, newValue); } private HijrahDate resolvePreviousValid(int prolepticYear, int month, int day) { @@ -479,7 +479,7 @@ public final class HijrahDate * @return the day-of-year */ private int getDayOfYear() { - return chrono.getDayOfYear(prolepticYear, monthOfYear); + return chrono.getDayOfYear(prolepticYear, monthOfYear) + dayOfMonth; } /** @@ -575,12 +575,13 @@ public final class HijrahDate } @Override // for javadoc and covariant return type + @SuppressWarnings("unchecked") public final ChronoLocalDateTime atTime(LocalTime localTime) { - return super.atTime(localTime); + return (ChronoLocalDateTime)super.atTime(localTime); } @Override - public Period periodUntil(ChronoLocalDate endDate) { + public Period until(ChronoLocalDate endDate) { // TODO: untested HijrahDate end = getChronology().date(endDate); long totalMonths = (end.prolepticYear - this.prolepticYear) * 12 + (end.monthOfYear - this.monthOfYear); // safe @@ -622,7 +623,7 @@ public final class HijrahDate return this; } - static ChronoLocalDate readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + static HijrahDate readExternal(ObjectInput in) throws IOException, ClassNotFoundException { HijrahChronology chrono = (HijrahChronology) in.readObject(); int year = in.readInt(); int month = in.readByte(); diff --git a/jdk/src/share/classes/java/time/chrono/IsoChronology.java b/jdk/src/share/classes/java/time/chrono/IsoChronology.java index 66b0dc10d23..a2f6badeaa5 100644 --- a/jdk/src/share/classes/java/time/chrono/IsoChronology.java +++ b/jdk/src/share/classes/java/time/chrono/IsoChronology.java @@ -61,25 +61,16 @@ */ package java.time.chrono; -import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH; -import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; -import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; -import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; import static java.time.temporal.ChronoField.DAY_OF_MONTH; -import static java.time.temporal.ChronoField.DAY_OF_WEEK; -import static java.time.temporal.ChronoField.DAY_OF_YEAR; -import static java.time.temporal.ChronoField.EPOCH_DAY; import static java.time.temporal.ChronoField.ERA; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; -import static java.time.temporal.TemporalAdjuster.nextOrSame; import java.io.Serializable; import java.time.Clock; import java.time.DateTimeException; -import java.time.DayOfWeek; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; @@ -398,7 +389,7 @@ public final class IsoChronology extends Chronology implements Serializable { } @Override - public Era eraOf(int eraValue) { + public IsoEra eraOf(int eraValue) { return IsoEra.of(eraValue); } @@ -421,7 +412,7 @@ public final class IsoChronology extends Chronology implements Serializable { * as follows. *
    *
  • {@code EPOCH_DAY} - If present, this is converted to a {@code LocalDate} - * all other date fields are then cross-checked against the date + * and all other date fields are then cross-checked against the date. *
  • {@code PROLEPTIC_MONTH} - If present, then it is split into the * {@code YEAR} and {@code MONTH_OF_YEAR}. If the mode is strict or smart * then the field is validated. @@ -430,7 +421,7 @@ public final class IsoChronology extends Chronology implements Serializable { * range is not validated, in smart and strict mode it is. The {@code ERA} is * validated for range in all three modes. If only the {@code YEAR_OF_ERA} is * present, and the mode is smart or lenient, then the current era (CE/AD) - * is assumed. In strict mode, no ers is assumed and the {@code YEAR_OF_ERA} is + * is assumed. In strict mode, no era is assumed and the {@code YEAR_OF_ERA} is * left untouched. If only the {@code ERA} is present, then it is left untouched. *
  • {@code YEAR}, {@code MONTH_OF_YEAR} and {@code DAY_OF_MONTH} - * If all three are present, then they are combined to form a {@code LocalDate}. @@ -495,48 +486,11 @@ public final class IsoChronology extends Chronology implements Serializable { */ @Override // override for performance public LocalDate resolveDate(Map fieldValues, ResolverStyle resolverStyle) { - // check epoch-day before inventing era - if (fieldValues.containsKey(EPOCH_DAY)) { - return LocalDate.ofEpochDay(fieldValues.remove(EPOCH_DAY)); - } - - // fix proleptic month before inventing era - resolveProlepticMonth(fieldValues, resolverStyle); - - // invent era if necessary to resolve year-of-era - resolveYearOfEra(fieldValues, resolverStyle); - - // build date - if (fieldValues.containsKey(YEAR)) { - if (fieldValues.containsKey(MONTH_OF_YEAR)) { - if (fieldValues.containsKey(DAY_OF_MONTH)) { - return resolveYMD(fieldValues, resolverStyle); - } - if (fieldValues.containsKey(ALIGNED_WEEK_OF_MONTH)) { - if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_MONTH)) { - return resolveYMAA(fieldValues, resolverStyle); - } - if (fieldValues.containsKey(DAY_OF_WEEK)) { - return resolveYMAD(fieldValues, resolverStyle); - } - } - } - if (fieldValues.containsKey(DAY_OF_YEAR)) { - return resolveYD(fieldValues, resolverStyle); - } - if (fieldValues.containsKey(ALIGNED_WEEK_OF_YEAR)) { - if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_YEAR)) { - return resolveYAA(fieldValues, resolverStyle); - } - if (fieldValues.containsKey(DAY_OF_WEEK)) { - return resolveYAD(fieldValues, resolverStyle); - } - } - } - return null; + return (LocalDate) super.resolveDate(fieldValues, resolverStyle); } - private void resolveProlepticMonth(Map fieldValues, ResolverStyle resolverStyle) { + @Override // override for better proleptic algorithm + void resolveProlepticMonth(Map fieldValues, ResolverStyle resolverStyle) { Long pMonth = fieldValues.remove(PROLEPTIC_MONTH); if (pMonth != null) { if (resolverStyle != ResolverStyle.LENIENT) { @@ -547,7 +501,8 @@ public final class IsoChronology extends Chronology implements Serializable { } } - private void resolveYearOfEra(Map fieldValues, ResolverStyle resolverStyle) { + @Override // override for enhanced behaviour + LocalDate resolveYearOfEra(Map fieldValues, ResolverStyle resolverStyle) { Long yoeLong = fieldValues.remove(YEAR_OF_ERA); if (yoeLong != null) { if (resolverStyle != ResolverStyle.LENIENT) { @@ -575,10 +530,14 @@ public final class IsoChronology extends Chronology implements Serializable { } else { throw new DateTimeException("Invalid value for era: " + era); } + } else if (fieldValues.containsKey(ERA)) { + ERA.checkValidValue(fieldValues.get(ERA)); // always validated } + return null; } - private LocalDate resolveYMD(Map fieldValues, ResolverStyle resolverStyle) { + @Override // override for performance + LocalDate resolveYMD(Map fieldValues, ResolverStyle resolverStyle) { int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); if (resolverStyle == ResolverStyle.LENIENT) { long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); @@ -598,96 +557,6 @@ public final class IsoChronology extends Chronology implements Serializable { return LocalDate.of(y, moy, dom); } - private LocalDate resolveYD(Map fieldValues, ResolverStyle resolverStyle) { - int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); - if (resolverStyle == ResolverStyle.LENIENT) { - long days = Math.subtractExact(fieldValues.remove(DAY_OF_YEAR), 1); - return LocalDate.of(y, 1, 1).plusDays(days); - } - int doy = DAY_OF_YEAR.checkValidIntValue(fieldValues.remove(DAY_OF_YEAR)); - return LocalDate.ofYearDay(y, doy); // smart is same as strict - } - - private LocalDate resolveYMAA(Map fieldValues, ResolverStyle resolverStyle) { - int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); - if (resolverStyle == ResolverStyle.LENIENT) { - long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); - long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1); - long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), 1); - return LocalDate.of(y, 1, 1).plusMonths(months).plusWeeks(weeks).plusDays(days); - } - int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR)); - int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH)); - int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH)); - LocalDate date = LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7 + (ad - 1)); - if (resolverStyle == ResolverStyle.STRICT && date.getMonthValue() != moy) { - throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); - } - return date; - } - - private LocalDate resolveYMAD(Map fieldValues, ResolverStyle resolverStyle) { - int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); - if (resolverStyle == ResolverStyle.LENIENT) { - long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); - long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), 1); - long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1); - return resolveAligned(y, months, weeks, dow); - } - int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR)); - int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH)); - int dow = DAY_OF_WEEK.checkValidIntValue(fieldValues.remove(DAY_OF_WEEK)); - LocalDate date = LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow))); - if (resolverStyle == ResolverStyle.STRICT && date.getMonthValue() != moy) { - throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); - } - return date; - } - - private LocalDate resolveYAA(Map fieldValues, ResolverStyle resolverStyle) { - int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); - if (resolverStyle == ResolverStyle.LENIENT) { - long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1); - long days = Math.subtractExact(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), 1); - return LocalDate.of(y, 1, 1).plusWeeks(weeks).plusDays(days); - } - int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR)); - int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR)); - LocalDate date = LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1)); - if (resolverStyle == ResolverStyle.STRICT && date.getYear() != y) { - throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); - } - return date; - } - - private LocalDate resolveYAD(Map fieldValues, ResolverStyle resolverStyle) { - int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); - if (resolverStyle == ResolverStyle.LENIENT) { - long weeks = Math.subtractExact(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), 1); - long dow = Math.subtractExact(fieldValues.remove(DAY_OF_WEEK), 1); - return resolveAligned(y, 0, weeks, dow); - } - int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR)); - int dow = DAY_OF_WEEK.checkValidIntValue(fieldValues.remove(DAY_OF_WEEK)); - LocalDate date = LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow))); - if (resolverStyle == ResolverStyle.STRICT && date.getYear() != y) { - throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); - } - return date; - } - - private LocalDate resolveAligned(int y, long months, long weeks, long dow) { - LocalDate date = LocalDate.of(y, 1, 1).plusMonths(months).plusWeeks(weeks); - if (dow > 7) { - date = date.plusWeeks((dow - 1) / 7); - dow = ((dow - 1) % 7) + 1; - } else if (dow < 1) { - date = date.plusWeeks(Math.subtractExact(dow, 7) / 7); - dow = ((dow + 6) % 7) + 1; - } - return date.with(nextOrSame(DayOfWeek.of((int) dow))); - } - //----------------------------------------------------------------------- @Override public ValueRange range(ChronoField field) { diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java b/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java index 1aead71b8ad..68a12755ea3 100644 --- a/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java +++ b/jdk/src/share/classes/java/time/chrono/JapaneseChronology.java @@ -56,6 +56,15 @@ */ package java.time.chrono; +import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; +import static java.time.temporal.ChronoField.ERA; +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoField.YEAR; +import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.MONTHS; + import java.io.Serializable; import java.time.Clock; import java.time.DateTimeException; @@ -63,13 +72,18 @@ import java.time.Instant; import java.time.LocalDate; import java.time.Year; import java.time.ZoneId; +import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalField; +import java.time.temporal.UnsupportedTemporalTypeException; import java.time.temporal.ValueRange; import java.util.Arrays; import java.util.Calendar; import java.util.List; import java.util.Locale; +import java.util.Map; import sun.util.calendar.CalendarSystem; import sun.util.calendar.LocalGregorianCalendar; @@ -82,8 +96,22 @@ import sun.util.calendar.LocalGregorianCalendar; * The Japanese Imperial calendar system is the same as the ISO calendar system * apart from the era-based year numbering. *

    - * Only Meiji (1865-04-07 - 1868-09-07) and later eras are supported. - * Older eras are handled as an unknown era where the year-of-era is the ISO year. + * Japan introduced the Gregorian calendar starting with Meiji 6. + * Only Meiji and later eras are supported; + * dates before Meiji 6, January 1 are not supported. + *

    + * The supported {@code ChronoField} instances are: + *

      + *
    • {@code DAY_OF_WEEK} + *
    • {@code DAY_OF_MONTH} + *
    • {@code DAY_OF_YEAR} + *
    • {@code EPOCH_DAY} + *
    • {@code MONTH_OF_YEAR} + *
    • {@code PROLEPTIC_MONTH} + *
    • {@code YEAR_OF_ERA} + *
    • {@code YEAR} + *
    • {@code ERA} + *
    * * @implSpec * This class is immutable and thread-safe. @@ -91,7 +119,6 @@ import sun.util.calendar.LocalGregorianCalendar; * @since 1.8 */ public final class JapaneseChronology extends Chronology implements Serializable { - // TODO: definition for unknown era may break requirement that year-of-era >= 1 static final LocalGregorianCalendar JCAL = (LocalGregorianCalendar) CalendarSystem.forName("japanese"); @@ -152,6 +179,16 @@ public final class JapaneseChronology extends Chronology implements Serializable /** * Obtains a local date in Japanese calendar system from the * era, year-of-era, month-of-year and day-of-month fields. + *

    + * The Japanese month and day-of-month are the same as those in the + * ISO calendar system. They are not reset when the era changes. + * For example: + *

    +     *  6th Jan Showa 64 = ISO 1989-01-06
    +     *  7th Jan Showa 64 = ISO 1989-01-07
    +     *  8th Jan Heisei 1 = ISO 1989-01-08
    +     *  9th Jan Heisei 1 = ISO 1989-01-09
    +     * 
    * * @param era the Japanese era, not null * @param yearOfEra the year-of-era @@ -172,6 +209,9 @@ public final class JapaneseChronology extends Chronology implements Serializable /** * Obtains a local date in Japanese calendar system from the * proleptic-year, month-of-year and day-of-month fields. + *

    + * The Japanese proleptic year, month and day-of-month are the same as those + * in the ISO calendar system. They are not reset when the era changes. * * @param prolepticYear the proleptic-year * @param month the month-of-year @@ -187,6 +227,17 @@ public final class JapaneseChronology extends Chronology implements Serializable /** * Obtains a local date in Japanese calendar system from the * era, year-of-era and day-of-year fields. + *

    + * The day-of-year in this factory is expressed relative to the start of the year-of-era. + * This definition changes the normal meaning of day-of-year only in those years + * where the year-of-era is reset to one due to a change in the era. + * For example: + *

    +     *  6th Jan Showa 64 = day-of-year 6
    +     *  7th Jan Showa 64 = day-of-year 7
    +     *  8th Jan Heisei 1 = day-of-year 1
    +     *  9th Jan Heisei 1 = day-of-year 2
    +     * 
    * * @param era the Japanese era, not null * @param yearOfEra the year-of-era @@ -203,6 +254,10 @@ public final class JapaneseChronology extends Chronology implements Serializable /** * Obtains a local date in Japanese calendar system from the * proleptic-year and day-of-year fields. + *

    + * The day-of-year in this factory is expressed relative to the start of the proleptic year. + * The Japanese proleptic year and day-of-year are the same as those in the ISO calendar system. + * They are not reset when the era changes. * * @param prolepticYear the proleptic-year * @param dayOfYear the day-of-year @@ -211,8 +266,7 @@ public final class JapaneseChronology extends Chronology implements Serializable */ @Override public JapaneseDate dateYearDay(int prolepticYear, int dayOfYear) { - LocalDate date = LocalDate.ofYearDay(prolepticYear, dayOfYear); - return date(prolepticYear, date.getMonthValue(), date.getDayOfMonth()); + return new JapaneseDate(LocalDate.ofYearDay(prolepticYear, dayOfYear)); } /** @@ -290,15 +344,6 @@ public final class JapaneseChronology extends Chronology implements Serializable throw new ClassCastException("Era must be JapaneseEra"); } - if (era == JapaneseEra.SEIREKI) { - JapaneseEra nextEra = JapaneseEra.values()[1]; - int nextEraYear = nextEra.getPrivateEra().getSinceDate().getYear(); - if (yearOfEra >= nextEraYear || yearOfEra < Year.MIN_VALUE) { - throw new DateTimeException("Invalid yearOfEra value"); - } - return yearOfEra; - } - JapaneseEra jera = (JapaneseEra) era; int gregorianYear = jera.getPrivateEra().getSinceDate().getYear() + yearOfEra - 1; if (yearOfEra == 1) { @@ -320,14 +365,13 @@ public final class JapaneseChronology extends Chronology implements Serializable * See the description of each Era for the numeric values of: * {@link JapaneseEra#HEISEI}, {@link JapaneseEra#SHOWA},{@link JapaneseEra#TAISHO}, * {@link JapaneseEra#MEIJI}), only Meiji and later eras are supported. - * Prior to Meiji {@link JapaneseEra#SEIREKI} is used. * * @param eraValue the era value * @return the Japanese {@code Era} for the given numeric era value * @throws DateTimeException if {@code eraValue} is invalid */ @Override - public Era eraOf(int eraValue) { + public JapaneseEra eraOf(int eraValue) { return JapaneseEra.of(eraValue); } @@ -346,49 +390,117 @@ public final class JapaneseChronology extends Chronology implements Serializable @Override public ValueRange range(ChronoField field) { switch (field) { - case YEAR: - case DAY_OF_MONTH: - case DAY_OF_WEEK: - case MICRO_OF_DAY: - case MICRO_OF_SECOND: - case HOUR_OF_DAY: - case HOUR_OF_AMPM: - case MINUTE_OF_DAY: - case MINUTE_OF_HOUR: - case SECOND_OF_DAY: - case SECOND_OF_MINUTE: - case MILLI_OF_DAY: - case MILLI_OF_SECOND: - case NANO_OF_DAY: - case NANO_OF_SECOND: - case CLOCK_HOUR_OF_DAY: - case CLOCK_HOUR_OF_AMPM: - case EPOCH_DAY: - case PROLEPTIC_MONTH: - case MONTH_OF_YEAR: - return field.range(); - case ERA: - return ValueRange.of(JapaneseEra.SEIREKI.getValue(), - getCurrentEra().getValue()); - } - Calendar jcal = Calendar.getInstance(LOCALE); - int fieldIndex; - switch (field) { + case ALIGNED_DAY_OF_WEEK_IN_MONTH: + case ALIGNED_DAY_OF_WEEK_IN_YEAR: + case ALIGNED_WEEK_OF_MONTH: + case ALIGNED_WEEK_OF_YEAR: + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); case YEAR_OF_ERA: { + Calendar jcal = Calendar.getInstance(LOCALE); int startYear = getCurrentEra().getPrivateEra().getSinceDate().getYear(); - return ValueRange.of(Year.MIN_VALUE, jcal.getGreatestMinimum(Calendar.YEAR), + return ValueRange.of(1, jcal.getGreatestMinimum(Calendar.YEAR), jcal.getLeastMaximum(Calendar.YEAR) + 1, // +1 due to the different definitions Year.MAX_VALUE - startYear); } - case DAY_OF_YEAR: - fieldIndex = Calendar.DAY_OF_YEAR; - break; + case DAY_OF_YEAR: { + Calendar jcal = Calendar.getInstance(LOCALE); + int fieldIndex = Calendar.DAY_OF_YEAR; + return ValueRange.of(jcal.getMinimum(fieldIndex), jcal.getGreatestMinimum(fieldIndex), + jcal.getLeastMaximum(fieldIndex), jcal.getMaximum(fieldIndex)); + } + case YEAR: + return ValueRange.of(JapaneseDate.MEIJI_6_ISODATE.getYear(), Year.MAX_VALUE); + case ERA: + return ValueRange.of(JapaneseEra.MEIJI.getValue(), getCurrentEra().getValue()); default: - // TODO: review the remaining fields - throw new UnsupportedOperationException("Unimplementable field: " + field); + return field.range(); } - return ValueRange.of(jcal.getMinimum(fieldIndex), jcal.getGreatestMinimum(fieldIndex), - jcal.getLeastMaximum(fieldIndex), jcal.getMaximum(fieldIndex)); + } + + //----------------------------------------------------------------------- + @Override // override for return type + public JapaneseDate resolveDate(Map fieldValues, ResolverStyle resolverStyle) { + return (JapaneseDate) super.resolveDate(fieldValues, resolverStyle); + } + + @Override // override for special Japanese behavior + ChronoLocalDate resolveYearOfEra(Map fieldValues, ResolverStyle resolverStyle) { + // validate era and year-of-era + Long eraLong = fieldValues.get(ERA); + JapaneseEra era = null; + if (eraLong != null) { + era = eraOf(range(ERA).checkValidIntValue(eraLong, ERA)); // always validated + } + Long yoeLong = fieldValues.get(YEAR_OF_ERA); + int yoe = 0; + if (yoeLong != null) { + yoe = range(YEAR_OF_ERA).checkValidIntValue(yoeLong, YEAR_OF_ERA); // always validated + } + // if only year-of-era and no year then invent era unless strict + if (era == null && yoeLong != null && fieldValues.containsKey(YEAR) == false && resolverStyle != ResolverStyle.STRICT) { + era = JapaneseEra.values()[JapaneseEra.values().length - 1]; + } + // if both present, then try to create date + if (yoeLong != null && era != null) { + if (fieldValues.containsKey(MONTH_OF_YEAR)) { + if (fieldValues.containsKey(DAY_OF_MONTH)) { + return resolveYMD(era, yoe, fieldValues, resolverStyle); + } + } + if (fieldValues.containsKey(DAY_OF_YEAR)) { + return resolveYD(era, yoe, fieldValues, resolverStyle); + } + } + return null; + } + + private int prolepticYearLenient(JapaneseEra era, int yearOfEra) { + return era.getPrivateEra().getSinceDate().getYear() + yearOfEra - 1; + } + + private ChronoLocalDate resolveYMD(JapaneseEra era, int yoe, Map fieldValues, ResolverStyle resolverStyle) { + fieldValues.remove(ERA); + fieldValues.remove(YEAR_OF_ERA); + if (resolverStyle == ResolverStyle.LENIENT) { + int y = prolepticYearLenient(era, yoe); + long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1); + long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1); + return date(y, 1, 1).plus(months, MONTHS).plus(days, DAYS); + } + int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); + int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH); + if (resolverStyle == ResolverStyle.SMART) { // previous valid + if (yoe < 1) { + throw new DateTimeException("Invalid YearOfEra: " + yoe); + } + int y = prolepticYearLenient(era, yoe); + JapaneseDate result; + try { + result = date(y, moy, dom); + } catch (DateTimeException ex) { + result = date(y, moy, 1).with(TemporalAdjuster.lastDayOfMonth()); + } + // handle the era being changed + // only allow if the new date is in the same Jan-Dec as the era change + // determine by ensuring either original yoe or result yoe is 1 + if (result.getEra() != era && result.get(YEAR_OF_ERA) > 1 && yoe > 1) { + throw new DateTimeException("Invalid YearOfEra for Era: " + era + " " + yoe); + } + return result; + } + return date(era, yoe, moy, dom); + } + + private ChronoLocalDate resolveYD(JapaneseEra era, int yoe, Map fieldValues, ResolverStyle resolverStyle) { + fieldValues.remove(ERA); + fieldValues.remove(YEAR_OF_ERA); + if (resolverStyle == ResolverStyle.LENIENT) { + int y = prolepticYearLenient(era, yoe); + long days = Math.subtractExact(fieldValues.remove(DAY_OF_YEAR), 1); + return dateYearDay(y, 1).plus(days, DAYS); + } + int doy = range(DAY_OF_YEAR).checkValidIntValue(fieldValues.remove(DAY_OF_YEAR), DAY_OF_YEAR); + return dateYearDay(era, yoe, doy); // smart is same as strict } } diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java index 646315b3d80..e49a8f33c75 100644 --- a/jdk/src/share/classes/java/time/chrono/JapaneseDate.java +++ b/jdk/src/share/classes/java/time/chrono/JapaneseDate.java @@ -56,9 +56,15 @@ */ package java.time.chrono; +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.YEAR; +import static java.time.temporal.ChronoField.YEAR_OF_ERA; import java.io.DataInput; import java.io.DataOutput; @@ -96,6 +102,10 @@ import sun.util.calendar.LocalGregorianCalendar; * apart from the era-based year numbering. The proleptic-year is defined to be * equal to the ISO proleptic-year. *

    + * Japan introduced the Gregorian calendar starting with Meiji 6. + * Only Meiji and later eras are supported; + * dates before Meiji 6, January 1 are not supported. + *

    * For example, the Japanese year "Heisei 24" corresponds to ISO year "2012".
    * Calling {@code japaneseDate.get(YEAR_OF_ERA)} will return 24.
    * Calling {@code japaneseDate.get(YEAR)} will return 2012.
    @@ -109,7 +119,7 @@ import sun.util.calendar.LocalGregorianCalendar; */ public final class JapaneseDate extends ChronoDateImpl - implements ChronoLocalDate, Serializable { + implements ChronoLocalDate, Serializable { /** * Serialization version. @@ -129,6 +139,11 @@ public final class JapaneseDate */ private transient int yearOfEra; + /** + * The first day supported by the JapaneseChronology is Meiji 6, January 1st. + */ + final static LocalDate MEIJI_6_ISODATE = LocalDate.of(1873, 1, 1); + //----------------------------------------------------------------------- /** * Obtains the current {@code JapaneseDate} from the system clock in the default time-zone. @@ -173,7 +188,7 @@ public final class JapaneseDate * @throws DateTimeException if the current date cannot be obtained */ public static JapaneseDate now(Clock clock) { - return JapaneseChronology.INSTANCE.date(LocalDate.now(clock)); + return new JapaneseDate(LocalDate.now(clock)); } /** @@ -182,6 +197,16 @@ public final class JapaneseDate *

    * This returns a {@code JapaneseDate} with the specified fields. * The day must be valid for the year and month, otherwise an exception will be thrown. + *

    + * The Japanese month and day-of-month are the same as those in the + * ISO calendar system. They are not reset when the era changes. + * For example: + *

    +     *  6th Jan Showa 64 = ISO 1989-01-06
    +     *  7th Jan Showa 64 = ISO 1989-01-07
    +     *  8th Jan Heisei 1 = ISO 1989-01-08
    +     *  9th Jan Heisei 1 = ISO 1989-01-09
    +     * 
    * * @param era the Japanese era, not null * @param yearOfEra the Japanese year-of-era @@ -192,11 +217,15 @@ public final class JapaneseDate * or if the day-of-month is invalid for the month-year, * or if the date is not a Japanese era */ - public static JapaneseDate of(Era era, int yearOfEra, int month, int dayOfMonth) { - if (era instanceof JapaneseEra == false) { - throw new ClassCastException("Era must be JapaneseEra"); + public static JapaneseDate of(JapaneseEra era, int yearOfEra, int month, int dayOfMonth) { + Objects.requireNonNull(era, "era"); + LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null); + jdate.setEra(era.getPrivateEra()).setDate(yearOfEra, month, dayOfMonth); + if (!JapaneseChronology.JCAL.validate(jdate)) { + throw new DateTimeException("year, month, and day not valid for Era"); } - return JapaneseDate.of((JapaneseEra) era, yearOfEra, month, dayOfMonth); + LocalDate date = LocalDate.of(jdate.getNormalizedYear(), month, dayOfMonth); + return new JapaneseDate(era, yearOfEra, date); } /** @@ -205,6 +234,9 @@ public final class JapaneseDate *

    * This returns a {@code JapaneseDate} with the specified fields. * The day must be valid for the year and month, otherwise an exception will be thrown. + *

    + * The Japanese proleptic year, month and day-of-month are the same as those + * in the ISO calendar system. They are not reset when the era changes. * * @param prolepticYear the Japanese proleptic-year * @param month the Japanese month-of-year, from 1 to 12 @@ -219,23 +251,31 @@ public final class JapaneseDate /** * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar - * system from the proleptic-year and day-of-year fields. + * system from the era, year-of-era and day-of-year fields. *

    * This returns a {@code JapaneseDate} with the specified fields. * The day must be valid for the year, otherwise an exception will be thrown. + *

    + * The day-of-year in this factory is expressed relative to the start of the year-of-era. + * This definition changes the normal meaning of day-of-year only in those years + * where the year-of-era is reset to one due to a change in the era. + * For example: + *

    +     *  6th Jan Showa 64 = day-of-year 6
    +     *  7th Jan Showa 64 = day-of-year 7
    +     *  8th Jan Heisei 1 = day-of-year 1
    +     *  9th Jan Heisei 1 = day-of-year 2
    +     * 
    * - * @param prolepticYear the chronology proleptic-year + * @param era the Japanese era, not null + * @param yearOfEra the Japanese year-of-era * @param dayOfYear the chronology day-of-year, from 1 to 366 * @return the date in Japanese calendar system, not null * @throws DateTimeException if the value of any field is out of range, * or if the day-of-year is invalid for the year */ - public static JapaneseDate ofYearDay(int prolepticYear, int dayOfYear) { - LocalDate date = LocalDate.ofYearDay(prolepticYear, dayOfYear); - return of(prolepticYear, date.getMonthValue(), date.getDayOfMonth()); - } - static JapaneseDate ofYearDay(JapaneseEra era, int yearOfEra, int dayOfYear) { + Objects.requireNonNull(era, "era"); CalendarDate firstDay = era.getPrivateEra().getSinceDate(); LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null); jdate.setEra(era.getPrivateEra()); @@ -253,32 +293,6 @@ public final class JapaneseDate return new JapaneseDate(era, yearOfEra, localdate); } - /** - * Obtains a {@code JapaneseDate} representing a date in the Japanese calendar - * system from the era, year-of-era, month-of-year and day-of-month fields. - *

    - * This returns a {@code JapaneseDate} with the specified fields. - * The day must be valid for the year and month, otherwise an exception will be thrown. - * - * @param era the Japanese era, not null - * @param yearOfEra the Japanese year-of-era - * @param month the Japanese month-of-year, from 1 to 12 - * @param dayOfMonth the Japanese day-of-month, from 1 to 31 - * @return the date in Japanese calendar system, not null - * @throws DateTimeException if the value of any field is out of range, - * or if the day-of-month is invalid for the month-year - */ - static JapaneseDate of(JapaneseEra era, int yearOfEra, int month, int dayOfMonth) { - Objects.requireNonNull(era, "era"); - LocalGregorianCalendar.Date jdate = JapaneseChronology.JCAL.newCalendarDate(null); - jdate.setEra(era.getPrivateEra()).setDate(yearOfEra, month, dayOfMonth); - if (!JapaneseChronology.JCAL.validate(jdate)) { - throw new DateTimeException("year, month, and day not valid for Era"); - } - LocalDate date = LocalDate.of(jdate.getNormalizedYear(), month, dayOfMonth); - return new JapaneseDate(era, yearOfEra, date); - } - /** * Obtains a {@code JapaneseDate} from a temporal object. *

    @@ -307,6 +321,9 @@ public final class JapaneseDate * @param isoDate the standard local date, validated not null */ JapaneseDate(LocalDate isoDate) { + if (isoDate.isBefore(MEIJI_6_ISODATE)) { + throw new DateTimeException("JapaneseDate before Meiji 6 is not supported"); + } LocalGregorianCalendar.Date jdate = toPrivateJapaneseDate(isoDate); this.era = JapaneseEra.toJapaneseEra(jdate.getEra()); this.yearOfEra = jdate.getYear(); @@ -322,6 +339,9 @@ public final class JapaneseDate * @param isoDate the standard local date, validated not null */ JapaneseDate(JapaneseEra era, int year, LocalDate isoDate) { + if (isoDate.isBefore(MEIJI_6_ISODATE)) { + throw new DateTimeException("JapaneseDate before Meiji 6 is not supported"); + } this.era = era; this.yearOfEra = year; this.isoDate = isoDate; @@ -366,55 +386,99 @@ public final class JapaneseDate return isoDate.lengthOfMonth(); } + @Override + public int lengthOfYear() { + Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE); + jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET); + jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth()); + return jcal.getActualMaximum(Calendar.DAY_OF_YEAR); + } + //----------------------------------------------------------------------- + /** + * Checks if the specified field is supported. + *

    + * This checks if this date can be queried for the specified field. + * If false, then calling the {@link #range(TemporalField) range} and + * {@link #get(TemporalField) get} methods will throw an exception. + *

    + * If the field is a {@link ChronoField} then the query is implemented here. + * The supported fields are: + *

      + *
    • {@code DAY_OF_WEEK} + *
    • {@code DAY_OF_MONTH} + *
    • {@code DAY_OF_YEAR} + *
    • {@code EPOCH_DAY} + *
    • {@code MONTH_OF_YEAR} + *
    • {@code PROLEPTIC_MONTH} + *
    • {@code YEAR_OF_ERA} + *
    • {@code YEAR} + *
    • {@code ERA} + *
    + * All other {@code ChronoField} instances will return false. + *

    + * If the field is not a {@code ChronoField}, then the result of this method + * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} + * passing {@code this} as the argument. + * Whether the field is supported is determined by the field. + * + * @param field the field to check, null returns false + * @return true if the field is supported on this date, false if not + */ + @Override + public boolean isSupported(TemporalField field) { + if (field == ALIGNED_DAY_OF_WEEK_IN_MONTH || field == ALIGNED_DAY_OF_WEEK_IN_YEAR || + field == ALIGNED_WEEK_OF_MONTH || field == ALIGNED_WEEK_OF_YEAR) { + return false; + } + return ChronoLocalDate.super.isSupported(field); + } + @Override public ValueRange range(TemporalField field) { if (field instanceof ChronoField) { if (isSupported(field)) { ChronoField f = (ChronoField) field; switch (f) { - case DAY_OF_MONTH: - case ALIGNED_WEEK_OF_MONTH: - return isoDate.range(field); - case DAY_OF_YEAR: - return actualRange(Calendar.DAY_OF_YEAR); - case YEAR_OF_ERA: - return actualRange(Calendar.YEAR); + case DAY_OF_MONTH: return ValueRange.of(1, lengthOfMonth()); + case DAY_OF_YEAR: return ValueRange.of(1, lengthOfYear()); + case YEAR_OF_ERA: { + Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE); + jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET); + jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth()); + return ValueRange.of(1, jcal.getActualMaximum(Calendar.YEAR)); + } } return getChronology().range(f); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); } - private ValueRange actualRange(int calendarField) { - Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE); - jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET); // TODO: cannot calculate this way for SEIREKI - jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth()); - return ValueRange.of(jcal.getActualMinimum(calendarField), - jcal.getActualMaximum(calendarField)); - } - @Override public long getLong(TemporalField field) { if (field instanceof ChronoField) { // same as ISO: - // DAY_OF_WEEK, ALIGNED_DAY_OF_WEEK_IN_MONTH, DAY_OF_MONTH, EPOCH_DAY, - // ALIGNED_WEEK_OF_MONTH, MONTH_OF_YEAR, PROLEPTIC_MONTH, YEAR + // DAY_OF_WEEK, DAY_OF_MONTH, EPOCH_DAY, MONTH_OF_YEAR, PROLEPTIC_MONTH, YEAR // // calendar specific fields - // ALIGNED_DAY_OF_WEEK_IN_YEAR, DAY_OF_YEAR, ALIGNED_WEEK_OF_YEAR, YEAR_OF_ERA, ERA + // DAY_OF_YEAR, YEAR_OF_ERA, ERA switch ((ChronoField) field) { + case ALIGNED_DAY_OF_WEEK_IN_MONTH: + case ALIGNED_DAY_OF_WEEK_IN_YEAR: + case ALIGNED_WEEK_OF_MONTH: + case ALIGNED_WEEK_OF_YEAR: + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); case YEAR_OF_ERA: return yearOfEra; case ERA: return era.getValue(); - case DAY_OF_YEAR: { - LocalGregorianCalendar.Date jdate = toPrivateJapaneseDate(isoDate); - return JapaneseChronology.JCAL.getDayOfYear(jdate); - } - // TODO: ALIGNED_DAY_OF_WEEK_IN_YEAR and ALIGNED_WEEK_OF_YEAR ??? + case DAY_OF_YEAR: + Calendar jcal = Calendar.getInstance(JapaneseChronology.LOCALE); + jcal.set(Calendar.ERA, era.getValue() + JapaneseEra.ERA_OFFSET); + jcal.set(yearOfEra, isoDate.getMonthValue() - 1, isoDate.getDayOfMonth()); + return jcal.get(Calendar.DAY_OF_YEAR); } return isoDate.getLong(field); } @@ -444,7 +508,7 @@ public final class JapaneseDate public JapaneseDate with(TemporalField field, long newValue) { if (field instanceof ChronoField) { ChronoField f = (ChronoField) field; - if (getLong(f) == newValue) { + if (getLong(f) == newValue) { // getLong() validates for supported fields return this; } switch (f) { @@ -464,10 +528,9 @@ public final class JapaneseDate } } // YEAR, PROLEPTIC_MONTH and others are same as ISO - // TODO: review other fields, such as WEEK_OF_YEAR return with(isoDate.with(field, newValue)); } - return ChronoLocalDate.super.with(field, newValue); + return super.with(field, newValue); } /** @@ -592,13 +655,14 @@ public final class JapaneseDate } @Override // for javadoc and covariant return type + @SuppressWarnings("unchecked") public final ChronoLocalDateTime atTime(LocalTime localTime) { - return super.atTime(localTime); + return (ChronoLocalDateTime)super.atTime(localTime); } @Override - public Period periodUntil(ChronoLocalDate endDate) { - return isoDate.periodUntil(endDate); + public Period until(ChronoLocalDate endDate) { + return isoDate.until(endDate); } @Override // override for performance @@ -624,14 +688,6 @@ public final class JapaneseDate return getChronology().getId().hashCode() ^ isoDate.hashCode(); } - @Override - public String toString() { - if (era == JapaneseEra.SEIREKI) { - return getChronology().getId() + " " + isoDate.toString(); - } - return super.toString(); - } - //----------------------------------------------------------------------- private Object writeReplace() { return new Ser(Ser.JAPANESE_DATE_TYPE, this); diff --git a/jdk/src/share/classes/java/time/chrono/JapaneseEra.java b/jdk/src/share/classes/java/time/chrono/JapaneseEra.java index 17635793b08..ba9fb434bf9 100644 --- a/jdk/src/share/classes/java/time/chrono/JapaneseEra.java +++ b/jdk/src/share/classes/java/time/chrono/JapaneseEra.java @@ -61,6 +61,7 @@ */ package java.time.chrono; +import static java.time.chrono.JapaneseDate.MEIJI_6_ISODATE; import static java.time.temporal.ChronoField.ERA; import java.io.DataInput; @@ -84,12 +85,9 @@ import sun.util.calendar.CalendarDate; * An era in the Japanese Imperial calendar system. *

    * This class defines the valid eras for the Japanese chronology. - * Only Meiji (1868-09-08 - 1912-07-29) and later eras are supported. - * Japan introduced the Gregorian calendar since Meiji 6. The dates - * between Meiji 1 - 5 are not historically correct. - * The older eras are recognized as Seireki (Western calendar) era, - * and the year of era of Seireki is proleptic Gregorian year. - * (The Julian to Gregorian transition is not supported.) + * Japan introduced the Gregorian calendar starting with Meiji 6. + * Only Meiji and later eras are supported; + * dates before Meiji 6, January 1 are not supported. * * @implSpec * This class is immutable and thread-safe. @@ -100,16 +98,11 @@ public final class JapaneseEra implements Era, Serializable { // The offset value to 0-based index from the era value. - // i.e., getValue() + ERA_OFFSET == 0-based index; except that -999 is mapped to zero + // i.e., getValue() + ERA_OFFSET == 0-based index static final int ERA_OFFSET = 2; static final sun.util.calendar.Era[] ERA_CONFIG; - /** - * The singleton instance for the before Meiji era ( - 1868-09-07) - * which has the value -999. - */ - public static final JapaneseEra SEIREKI = new JapaneseEra(-999, LocalDate.MIN); /** * The singleton instance for the 'Meiji' era (1868-09-08 - 1912-07-29) * which has the value -1. @@ -144,17 +137,13 @@ public final class JapaneseEra private static final JapaneseEra[] KNOWN_ERAS; static { - sun.util.calendar.Era[] sunEras = JapaneseChronology.JCAL.getEras(); - ERA_CONFIG = new sun.util.calendar.Era[sunEras.length + 1]; - for (int i = 1; i < ERA_CONFIG.length; i++) { - ERA_CONFIG[i] = sunEras[i - 1]; - } + ERA_CONFIG = JapaneseChronology.JCAL.getEras(); + KNOWN_ERAS = new JapaneseEra[ERA_CONFIG.length]; - KNOWN_ERAS[0] = SEIREKI; - KNOWN_ERAS[1] = MEIJI; - KNOWN_ERAS[2] = TAISHO; - KNOWN_ERAS[3] = SHOWA; - KNOWN_ERAS[4] = HEISEI; + KNOWN_ERAS[0] = MEIJI; + KNOWN_ERAS[1] = TAISHO; + KNOWN_ERAS[2] = SHOWA; + KNOWN_ERAS[3] = HEISEI; for (int i = N_ERA_CONSTANTS; i < ERA_CONFIG.length; i++) { CalendarDate date = ERA_CONFIG[i].getSinceDate(); LocalDate isoDate = LocalDate.of(date.getYear(), date.getMonth(), date.getDayOfMonth()); @@ -203,10 +192,8 @@ public final class JapaneseEra //----------------------------------------------------------------------- /** * Returns the Sun private Era instance corresponding to this {@code JapaneseEra}. - * SEIREKI doesn't have its corresponding one. * - * @return the Sun private Era instance for this {@code JapaneseEra}, - * or null for SEIREKI. + * @return the Sun private Era instance for this {@code JapaneseEra}. */ sun.util.calendar.Era getPrivateEra() { return ERA_CONFIG[ordinal(eraValue)]; @@ -218,16 +205,14 @@ public final class JapaneseEra *

    * The {@link #SHOWA} era that contains 1970-01-01 (ISO calendar system) has the value 1 * Later era is numbered 2 ({@link #HEISEI}). Earlier eras are numbered 0 ({@link #TAISHO}), - * -1 ({@link #MEIJI}), only Meiji and later eras are supported. The prior to Meiji, - * {@link #SEIREKI} is used. + * -1 ({@link #MEIJI}), only Meiji and later eras are supported. * * @param japaneseEra the era to represent * @return the {@code JapaneseEra} singleton, not null * @throws DateTimeException if the value is invalid */ public static JapaneseEra of(int japaneseEra) { - if (japaneseEra != SEIREKI.eraValue && - (japaneseEra < MEIJI.eraValue || japaneseEra > HEISEI.eraValue)) { + if (japaneseEra < MEIJI.eraValue || japaneseEra > HEISEI.eraValue) { throw new DateTimeException("Invalid era: " + japaneseEra); } return KNOWN_ERAS[ordinal(japaneseEra)]; @@ -276,22 +261,25 @@ public final class JapaneseEra * @return the Era singleton, never null */ static JapaneseEra from(LocalDate date) { + if (date.isBefore(MEIJI_6_ISODATE)) { + throw new DateTimeException("JapaneseDate before Meiji 6 are not supported"); + } for (int i = KNOWN_ERAS.length - 1; i > 0; i--) { JapaneseEra era = KNOWN_ERAS[i]; if (date.compareTo(era.since) >= 0) { return era; } } - return SEIREKI; + return null; } static JapaneseEra toJapaneseEra(sun.util.calendar.Era privateEra) { - for (int i = ERA_CONFIG.length - 1; i > 0; i--) { + for (int i = ERA_CONFIG.length - 1; i >= 0; i--) { if (ERA_CONFIG[i].equals(privateEra)) { return KNOWN_ERAS[i]; } } - return SEIREKI; + return null; } static sun.util.calendar.Era privateEraFrom(LocalDate isoDate) { @@ -306,13 +294,13 @@ public final class JapaneseEra /** * Returns the index into the arrays from the Era value. - * the eraValue is a valid Era number, -999, -1..2. + * the eraValue is a valid Era number, -1..2. * * @param eraValue the era value to convert to the index * @return the index of the current Era */ private static int ordinal(int eraValue) { - return (eraValue == SEIREKI.eraValue) ? 0 : eraValue + ERA_OFFSET; + return eraValue + ERA_OFFSET - 1; } //----------------------------------------------------------------------- @@ -321,7 +309,7 @@ public final class JapaneseEra *

    * The {@link #SHOWA} era that contains 1970-01-01 (ISO calendar system) has the value 1. * Later eras are numbered from 2 ({@link #HEISEI}). - * Earlier eras are numbered 0 ({@link #TAISHO}), -1 ({@link #MEIJI}), and -999 ({@link #SEIREKI}). + * Earlier eras are numbered 0 ({@link #TAISHO}), -1 ({@link #MEIJI})). * * @return the era value */ @@ -374,11 +362,7 @@ public final class JapaneseEra } String getName() { - int index = ordinal(getValue()); - if (index == 0) { - return "Seireki"; - } - return ERA_CONFIG[index].getName(); + return ERA_CONFIG[ordinal(getValue())].getName(); } @Override diff --git a/jdk/src/share/classes/java/time/chrono/MinguoChronology.java b/jdk/src/share/classes/java/time/chrono/MinguoChronology.java index 1c9c2e34c16..088588004c3 100644 --- a/jdk/src/share/classes/java/time/chrono/MinguoChronology.java +++ b/jdk/src/share/classes/java/time/chrono/MinguoChronology.java @@ -65,12 +65,15 @@ import java.time.DateTimeException; import java.time.Instant; import java.time.LocalDate; import java.time.ZoneId; +import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalField; import java.time.temporal.ValueRange; import java.util.Arrays; import java.util.List; import java.util.Locale; +import java.util.Map; /** * The Minguo calendar system. @@ -253,16 +256,19 @@ public final class MinguoChronology extends Chronology implements Serializable { } @Override + @SuppressWarnings("unchecked") public ChronoLocalDateTime localDateTime(TemporalAccessor temporal) { return (ChronoLocalDateTime)super.localDateTime(temporal); } @Override + @SuppressWarnings("unchecked") public ChronoZonedDateTime zonedDateTime(TemporalAccessor temporal) { return (ChronoZonedDateTime)super.zonedDateTime(temporal); } @Override + @SuppressWarnings("unchecked") public ChronoZonedDateTime zonedDateTime(Instant instant, ZoneId zone) { return (ChronoZonedDateTime)super.zonedDateTime(instant, zone); } @@ -292,7 +298,7 @@ public final class MinguoChronology extends Chronology implements Serializable { } @Override - public Era eraOf(int eraValue) { + public MinguoEra eraOf(int eraValue) { return MinguoEra.of(eraValue); } @@ -321,4 +327,10 @@ public final class MinguoChronology extends Chronology implements Serializable { return field.range(); } + //----------------------------------------------------------------------- + @Override // override for return type + public MinguoDate resolveDate(Map fieldValues, ResolverStyle resolverStyle) { + return (MinguoDate) super.resolveDate(fieldValues, resolverStyle); + } + } diff --git a/jdk/src/share/classes/java/time/chrono/MinguoDate.java b/jdk/src/share/classes/java/time/chrono/MinguoDate.java index b6a5582ef98..e15b0e90a15 100644 --- a/jdk/src/share/classes/java/time/chrono/MinguoDate.java +++ b/jdk/src/share/classes/java/time/chrono/MinguoDate.java @@ -96,7 +96,7 @@ import java.util.Objects; */ public final class MinguoDate extends ChronoDateImpl - implements ChronoLocalDate, Serializable { + implements ChronoLocalDate, Serializable { /** * Serialization version. @@ -152,7 +152,7 @@ public final class MinguoDate * @throws DateTimeException if the current date cannot be obtained */ public static MinguoDate now(Clock clock) { - return MinguoChronology.INSTANCE.date(LocalDate.now(clock)); + return new MinguoDate(LocalDate.now(clock)); } /** @@ -264,7 +264,7 @@ public final class MinguoDate } return getChronology().range(f); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); } @@ -325,7 +325,7 @@ public final class MinguoDate } return with(isoDate.with(field, newValue)); } - return ChronoLocalDate.super.with(field, newValue); + return super.with(field, newValue); } /** @@ -369,6 +369,11 @@ public final class MinguoDate return with(isoDate.plusMonths(months)); } + @Override + MinguoDate plusWeeks(long weeksToAdd) { + return super.plusWeeks(weeksToAdd); + } + @Override MinguoDate plusDays(long days) { return with(isoDate.plusDays(days)); @@ -384,11 +389,6 @@ public final class MinguoDate return super.minus(amountToAdd, unit); } - @Override - MinguoDate plusWeeks(long weeksToAdd) { - return super.plusWeeks(weeksToAdd); - } - @Override MinguoDate minusYears(long yearsToSubtract) { return super.minusYears(yearsToSubtract); @@ -414,13 +414,14 @@ public final class MinguoDate } @Override // for javadoc and covariant return type + @SuppressWarnings("unchecked") public final ChronoLocalDateTime atTime(LocalTime localTime) { - return super.atTime(localTime); + return (ChronoLocalDateTime)super.atTime(localTime); } @Override - public Period periodUntil(ChronoLocalDate endDate) { - return isoDate.periodUntil(endDate); + public Period until(ChronoLocalDate endDate) { + return isoDate.until(endDate); } @Override // override for performance @@ -458,7 +459,7 @@ public final class MinguoDate out.writeByte(get(DAY_OF_MONTH)); } - static ChronoLocalDate readExternal(DataInput in) throws IOException { + static MinguoDate readExternal(DataInput in) throws IOException { int year = in.readInt(); int month = in.readByte(); int dayOfMonth = in.readByte(); diff --git a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java index 27c98a6f079..04f59ceb93c 100644 --- a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java +++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistChronology.java @@ -65,13 +65,16 @@ import java.time.DateTimeException; import java.time.Instant; import java.time.LocalDate; import java.time.ZoneId; +import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalField; import java.time.temporal.ValueRange; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; /** * The Thai Buddhist calendar system. @@ -289,16 +292,19 @@ public final class ThaiBuddhistChronology extends Chronology implements Serializ } @Override + @SuppressWarnings("unchecked") public ChronoLocalDateTime localDateTime(TemporalAccessor temporal) { return (ChronoLocalDateTime)super.localDateTime(temporal); } @Override + @SuppressWarnings("unchecked") public ChronoZonedDateTime zonedDateTime(TemporalAccessor temporal) { return (ChronoZonedDateTime)super.zonedDateTime(temporal); } @Override + @SuppressWarnings("unchecked") public ChronoZonedDateTime zonedDateTime(Instant instant, ZoneId zone) { return (ChronoZonedDateTime)super.zonedDateTime(instant, zone); } @@ -328,7 +334,7 @@ public final class ThaiBuddhistChronology extends Chronology implements Serializ } @Override - public Era eraOf(int eraValue) { + public ThaiBuddhistEra eraOf(int eraValue) { return ThaiBuddhistEra.of(eraValue); } @@ -357,4 +363,10 @@ public final class ThaiBuddhistChronology extends Chronology implements Serializ return field.range(); } + //----------------------------------------------------------------------- + @Override // override for return type + public ThaiBuddhistDate resolveDate(Map fieldValues, ResolverStyle resolverStyle) { + return (ThaiBuddhistDate) super.resolveDate(fieldValues, resolverStyle); + } + } diff --git a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java index 973c7b8ab0f..67799ad5af8 100644 --- a/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java +++ b/jdk/src/share/classes/java/time/chrono/ThaiBuddhistDate.java @@ -96,7 +96,7 @@ import java.util.Objects; */ public final class ThaiBuddhistDate extends ChronoDateImpl - implements ChronoLocalDate, Serializable { + implements ChronoLocalDate, Serializable { /** * Serialization version. @@ -152,7 +152,7 @@ public final class ThaiBuddhistDate * @throws DateTimeException if the current date cannot be obtained */ public static ThaiBuddhistDate now(Clock clock) { - return ThaiBuddhistChronology.INSTANCE.date(LocalDate.now(clock)); + return new ThaiBuddhistDate(LocalDate.now(clock)); } /** @@ -264,7 +264,7 @@ public final class ThaiBuddhistDate } return getChronology().range(f); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); } @@ -325,7 +325,7 @@ public final class ThaiBuddhistDate } return with(isoDate.with(field, newValue)); } - return ChronoLocalDate.super.with(field, newValue); + return super.with(field, newValue); } /** @@ -414,13 +414,14 @@ public final class ThaiBuddhistDate } @Override // for javadoc and covariant return type + @SuppressWarnings("unchecked") public final ChronoLocalDateTime atTime(LocalTime localTime) { - return super.atTime(localTime); + return (ChronoLocalDateTime) super.atTime(localTime); } @Override - public Period periodUntil(ChronoLocalDate endDate) { - return isoDate.periodUntil(endDate); + public Period until(ChronoLocalDate endDate) { + return isoDate.until(endDate); } @Override // override for performance diff --git a/jdk/src/share/classes/java/time/chrono/package-info.java b/jdk/src/share/classes/java/time/chrono/package-info.java index 4f2a3f6e78c..9273a770f82 100644 --- a/jdk/src/share/classes/java/time/chrono/package-info.java +++ b/jdk/src/share/classes/java/time/chrono/package-info.java @@ -103,7 +103,7 @@ * // Enumerate the list of available calendars and print todays date for each. * Set<Chronology> chronos = Chronology.getAvailableChronologies(); * for (Chronology chrono : chronos) { - * ChronoLocalDate<?> date = chrono.dateNow(); + * ChronoLocalDate date = chrono.dateNow(); * System.out.printf(" %20s: %s%n", chrono.getId(), date.toString()); * } * @@ -113,7 +113,7 @@ *

    *
      *   // Print the Thai Buddhist date
    - *       ChronoLocalDate<?> now1 = Chronology.of("ThaiBuddhist").dateNow();
    + *       ChronoLocalDate now1 = Chronology.of("ThaiBuddhist").dateNow();
      *       int day = now1.get(ChronoField.DAY_OF_MONTH);
      *       int dow = now1.get(ChronoField.DAY_OF_WEEK);
      *       int month = now1.get(ChronoField.MONTH_OF_YEAR);
    @@ -121,10 +121,10 @@
      *       System.out.printf("  Today is %s %s %d-%s-%d%n", now1.getChronology().getId(),
      *                 dow, day, month, year);
      *   // Print today's date and the last day of the year for the Thai Buddhist Calendar.
    - *       ChronoLocalDate<?> first = now1
    + *       ChronoLocalDate first = now1
      *                 .with(ChronoField.DAY_OF_MONTH, 1)
      *                 .with(ChronoField.MONTH_OF_YEAR, 1);
    - *       ChronoLocalDate<?> last = first
    + *       ChronoLocalDate last = first
      *                 .plus(1, ChronoUnit.YEARS)
      *                 .minus(1, ChronoUnit.DAYS);
      *       System.out.printf("  %s: 1st of year: %s; end of year: %s%n", last.getChronology().getId(),
    diff --git a/jdk/src/share/classes/java/time/format/DateTimeFormatter.java b/jdk/src/share/classes/java/time/format/DateTimeFormatter.java
    index 2552f96e5ad..0c0a5979b14 100644
    --- a/jdk/src/share/classes/java/time/format/DateTimeFormatter.java
    +++ b/jdk/src/share/classes/java/time/format/DateTimeFormatter.java
    @@ -265,7 +265,7 @@ import java.util.Set;
      * 

    * For example: *

    - *  DateTimeFormatter formatter = DateTimeFormatter.pattern("yyyy MM dd");
    + *  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
      *  String text = date.toString(formatter);
      *  LocalDate date = LocalDate.parse(text, formatter);
      * 
    @@ -460,7 +460,7 @@ import java.util.Set; *
  • The {@code ChronoField} time fields are resolved. * This is documented on {@link ChronoField} and is the same for all chronologies. *
  • Any fields that are not {@code ChronoField} are processed. - * This is achieved using {@link TemporalField#resolve(TemporalAccessor, long, ResolverStyle)}. + * This is achieved using {@link TemporalField#resolve(Map, Chronology, ZoneId, ResolverStyle)}. * Documentation about field resolution is located in the implementation * of {@code TemporalField}. *
  • The {@code ChronoField} date and time fields are re-resolved. diff --git a/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java b/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java index cec07840439..f4983b48861 100644 --- a/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java +++ b/jdk/src/share/classes/java/time/format/DateTimeFormatterBuilder.java @@ -77,7 +77,6 @@ import java.math.BigInteger; import java.math.RoundingMode; import java.text.ParsePosition; import java.time.DateTimeException; -import java.time.Duration; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; @@ -962,12 +961,9 @@ public final class DateTimeFormatterBuilder { *
          *   "Europe/London"           -- ZoneId.of("Europe/London")
          *   "Z"                       -- ZoneOffset.UTC
    -     *   "UT"                      -- ZoneOffset.UTC
    -     *   "UTC"                     -- ZoneOffset.UTC
    -     *   "GMT"                     -- ZoneOffset.UTC
    -     *   "UT0"                     -- ZoneOffset.UTC
    -     *   "UTC0"                    -- ZoneOffset.UTC
    -     *   "GMT0"                    -- ZoneOffset.UTC
    +     *   "UT"                      -- ZoneId.of("UT")
    +     *   "UTC"                     -- ZoneId.of("UTC")
    +     *   "GMT"                     -- ZoneId.of("GMT")
          *   "+01:30"                  -- ZoneOffset.of("+01:30")
          *   "UT+01:30"                -- ZoneOffset.of("+01:30")
          *   "UTC+01:30"               -- ZoneOffset.of("+01:30")
    @@ -1016,12 +1012,9 @@ public final class DateTimeFormatterBuilder {
          * 
          *   "Europe/London"           -- ZoneId.of("Europe/London")
          *   "Z"                       -- ZoneOffset.UTC
    -     *   "UT"                      -- ZoneOffset.UTC
    -     *   "UTC"                     -- ZoneOffset.UTC
    -     *   "GMT"                     -- ZoneOffset.UTC
    -     *   "UT0"                     -- ZoneOffset.UTC
    -     *   "UTC0"                    -- ZoneOffset.UTC
    -     *   "GMT0"                    -- ZoneOffset.UTC
    +     *   "UT"                      -- ZoneId.of("UT")
    +     *   "UTC"                     -- ZoneId.of("UTC")
    +     *   "GMT"                     -- ZoneId.of("GMT")
          *   "+01:30"                  -- ZoneOffset.of("+01:30")
          *   "UT+01:30"                -- ZoneOffset.of("+01:30")
          *   "UTC+01:30"               -- ZoneOffset.of("+01:30")
    @@ -1077,16 +1070,13 @@ public final class DateTimeFormatterBuilder {
          * 
          *   "Europe/London"           -- ZoneId.of("Europe/London")
          *   "Z"                       -- ZoneOffset.UTC
    -     *   "UT"                      -- ZoneOffset.UTC
    -     *   "UTC"                     -- ZoneOffset.UTC
    -     *   "GMT"                     -- ZoneOffset.UTC
    -     *   "UT0"                     -- ZoneOffset.UTC
    -     *   "UTC0"                    -- ZoneOffset.UTC
    -     *   "GMT0"                    -- ZoneOffset.UTC
    +     *   "UT"                      -- ZoneId.of("UT")
    +     *   "UTC"                     -- ZoneId.of("UTC")
    +     *   "GMT"                     -- ZoneId.of("GMT")
          *   "+01:30"                  -- ZoneOffset.of("+01:30")
    -     *   "UT+01:30"                -- ZoneOffset.of("+01:30")
    -     *   "UTC+01:30"               -- ZoneOffset.of("+01:30")
    -     *   "GMT+01:30"               -- ZoneOffset.of("+01:30")
    +     *   "UT+01:30"                -- ZoneOffset.of("UT+01:30")
    +     *   "UTC+01:30"               -- ZoneOffset.of("UTC+01:30")
    +     *   "GMT+01:30"               -- ZoneOffset.of("GMT+01:30")
          * 
    *

    * Note that this method is is identical to {@code appendZoneId()} except @@ -2530,7 +2520,7 @@ public final class DateTimeFormatterBuilder { DecimalStyle decimalStyle = context.getDecimalStyle(); String str = (value == Long.MIN_VALUE ? "9223372036854775808" : Long.toString(Math.abs(value))); if (str.length() > maxWidth) { - throw new DateTimeException("Field " + field.getName() + + throw new DateTimeException("Field " + field + " cannot be printed as the value " + value + " exceeds the maximum print width of " + maxWidth); } @@ -2555,7 +2545,7 @@ public final class DateTimeFormatterBuilder { buf.append(decimalStyle.getNegativeSign()); break; case NOT_NEGATIVE: - throw new DateTimeException("Field " + field.getName() + + throw new DateTimeException("Field " + field + " cannot be printed as the value " + value + " cannot be negative according to the SignStyle"); } @@ -2699,12 +2689,12 @@ public final class DateTimeFormatterBuilder { @Override public String toString() { if (minWidth == 1 && maxWidth == 19 && signStyle == SignStyle.NORMAL) { - return "Value(" + field.getName() + ")"; + return "Value(" + field + ")"; } if (minWidth == maxWidth && signStyle == SignStyle.NOT_NEGATIVE) { - return "Value(" + field.getName() + "," + minWidth + ")"; + return "Value(" + field + "," + minWidth + ")"; } - return "Value(" + field.getName() + "," + minWidth + "," + maxWidth + "," + signStyle + ")"; + return "Value(" + field + "," + minWidth + "," + maxWidth + "," + signStyle + ")"; } } @@ -2817,7 +2807,7 @@ public final class DateTimeFormatterBuilder { @Override public String toString() { - return "ReducedValue(" + field.getName() + "," + minWidth + "," + maxWidth + "," + baseValue + ")"; + return "ReducedValue(" + field + "," + minWidth + "," + maxWidth + "," + baseValue + ")"; } } @@ -2842,7 +2832,7 @@ public final class DateTimeFormatterBuilder { FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) { Objects.requireNonNull(field, "field"); if (field.range().isFixed() == false) { - throw new IllegalArgumentException("Field must have a fixed set of values: " + field.getName()); + throw new IllegalArgumentException("Field must have a fixed set of values: " + field); } if (minWidth < 0 || minWidth > 9) { throw new IllegalArgumentException("Minimum width must be from 0 to 9 inclusive but was " + minWidth); @@ -2984,7 +2974,7 @@ public final class DateTimeFormatterBuilder { @Override public String toString() { String decimal = (decimalPoint ? ",DecimalPoint" : ""); - return "Fraction(" + field.getName() + "," + minWidth + "," + maxWidth + decimal + ")"; + return "Fraction(" + field + "," + minWidth + "," + maxWidth + decimal + ")"; } } @@ -3079,9 +3069,9 @@ public final class DateTimeFormatterBuilder { @Override public String toString() { if (textStyle == TextStyle.FULL) { - return "Text(" + field.getName() + ")"; + return "Text(" + field + ")"; } - return "Text(" + field.getName() + "," + textStyle + ")"; + return "Text(" + field + "," + textStyle + ")"; } } @@ -3756,17 +3746,17 @@ public final class DateTimeFormatterBuilder { // handle fixed time-zone IDs char nextChar = text.charAt(position); if (nextChar == '+' || nextChar == '-') { - return parseOffsetBased(context, text, position, OffsetIdPrinterParser.INSTANCE_ID_Z); + return parseOffsetBased(context, text, position, position, OffsetIdPrinterParser.INSTANCE_ID_Z); } else if (length >= position + 2) { char nextNextChar = text.charAt(position + 1); if (context.charEquals(nextChar, 'U') && context.charEquals(nextNextChar, 'T')) { if (length >= position + 3 && context.charEquals(text.charAt(position + 2), 'C')) { - return parseOffsetBased(context, text, position + 3, OffsetIdPrinterParser.INSTANCE_ID_ZERO); + return parseOffsetBased(context, text, position, position + 3, OffsetIdPrinterParser.INSTANCE_ID_ZERO); } - return parseOffsetBased(context, text, position + 2, OffsetIdPrinterParser.INSTANCE_ID_ZERO); + return parseOffsetBased(context, text, position, position + 2, OffsetIdPrinterParser.INSTANCE_ID_ZERO); } else if (context.charEquals(nextChar, 'G') && length >= position + 3 && context.charEquals(nextNextChar, 'M') && context.charEquals(text.charAt(position + 2), 'T')) { - return parseOffsetBased(context, text, position + 3, OffsetIdPrinterParser.INSTANCE_ID_ZERO); + return parseOffsetBased(context, text, position, position + 3, OffsetIdPrinterParser.INSTANCE_ID_ZERO); } } @@ -3785,20 +3775,49 @@ public final class DateTimeFormatterBuilder { return ppos.getIndex(); } - private int parseOffsetBased(DateTimeParseContext context, CharSequence text, int position, OffsetIdPrinterParser parser) { - DateTimeParseContext newContext = context.copy(); - int endPos = parser.parse(newContext, text, position); - if (endPos < 0) { - if (parser == OffsetIdPrinterParser.INSTANCE_ID_Z) { - return ~position; - } - context.setParsed(ZoneOffset.UTC); + /** + * Parse an offset following a prefix and set the ZoneId if it is valid. + * To matching the parsing of ZoneId.of the values are not normalized + * to ZoneOffsets. + * + * @param context the parse context + * @param text the input text + * @param prefixPos start of the prefix + * @param position start of text after the prefix + * @param parser parser for the value after the prefix + * @return the position after the parse + */ + private int parseOffsetBased(DateTimeParseContext context, CharSequence text, int prefixPos, int position, OffsetIdPrinterParser parser) { + String prefix = text.toString().substring(prefixPos, position).toUpperCase(); + if (position >= text.length()) { + context.setParsed(ZoneId.of(prefix)); return position; } - int offset = (int) newContext.getParsed(OFFSET_SECONDS).longValue(); - ZoneId zone = ZoneOffset.ofTotalSeconds(offset); - context.setParsed(zone); - return endPos; + + // '0' or 'Z' after prefix is not part of a valid ZoneId; use bare prefix + if (text.charAt(position) == '0' || + context.charEquals(text.charAt(position), 'Z')) { + context.setParsed(ZoneId.of(prefix)); + return position; + } + + DateTimeParseContext newContext = context.copy(); + int endPos = parser.parse(newContext, text, position); + try { + if (endPos < 0) { + if (parser == OffsetIdPrinterParser.INSTANCE_ID_Z) { + return ~prefixPos; + } + context.setParsed(ZoneId.of(prefix)); + return position; + } + int offset = (int) newContext.getParsed(OFFSET_SECONDS).longValue(); + ZoneOffset zoneOffset = ZoneOffset.ofTotalSeconds(offset); + context.setParsed(ZoneId.ofOffset(prefix, zoneOffset)); + return endPos; + } catch (DateTimeException dte) { + return ~prefixPos; + } } @Override diff --git a/jdk/src/share/classes/java/time/format/DateTimePrintContext.java b/jdk/src/share/classes/java/time/format/DateTimePrintContext.java index 3e3f90fb5eb..e744bb7d946 100644 --- a/jdk/src/share/classes/java/time/format/DateTimePrintContext.java +++ b/jdk/src/share/classes/java/time/format/DateTimePrintContext.java @@ -157,7 +157,7 @@ final class DateTimePrintContext { } } final ZoneId effectiveZone = (overrideZone != null ? overrideZone : temporalZone); - final ChronoLocalDate effectiveDate; + final ChronoLocalDate effectiveDate; if (overrideChrono != null) { if (temporal.isSupported(EPOCH_DAY)) { effectiveDate = effectiveChrono.date(temporal); diff --git a/jdk/src/share/classes/java/time/format/Parsed.java b/jdk/src/share/classes/java/time/format/Parsed.java index b0a7fe810d9..42223d6c1d9 100644 --- a/jdk/src/share/classes/java/time/format/Parsed.java +++ b/jdk/src/share/classes/java/time/format/Parsed.java @@ -143,7 +143,7 @@ final class Parsed implements TemporalAccessor { /** * The resolved date. */ - private ChronoLocalDate date; + private ChronoLocalDate date; /** * The resolved time. */ @@ -197,7 +197,7 @@ final class Parsed implements TemporalAccessor { return time.getLong(field); } if (field instanceof ChronoField) { - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } @@ -255,42 +255,34 @@ final class Parsed implements TemporalAccessor { // if any other fields, handle them // any lenient date resolution should return epoch-day if (fieldValues.size() > 0) { - boolean changed = false; + int changedCount = 0; outer: - while (true) { + while (changedCount < 50) { for (Map.Entry entry : fieldValues.entrySet()) { TemporalField targetField = entry.getKey(); - Map changes = targetField.resolve(this, entry.getValue(), resolverStyle); - if (changes != null) { - changed = true; - resolveFieldsMakeChanges(targetField, changes); - fieldValues.remove(targetField); // helps avoid infinite loops + ChronoLocalDate resolvedDate = targetField.resolve(fieldValues, chrono, zone, resolverStyle); + if (resolvedDate != null) { + updateCheckConflict(resolvedDate); + changedCount++; + continue outer; // have to restart to avoid concurrent modification + } else if (fieldValues.containsKey(targetField) == false) { + changedCount++; continue outer; // have to restart to avoid concurrent modification } } break; } + if (changedCount == 50) { // catch infinite loops + throw new DateTimeException("One of the parsed fields has an incorrectly implemented resolve method"); + } // if something changed then have to redo ChronoField resolve - if (changed) { + if (changedCount > 0) { resolveDateFields(); resolveTimeFields(); } } } - private void resolveFieldsMakeChanges(TemporalField targetField, Map changes) { - for (Map.Entry change : changes.entrySet()) { - TemporalField changeField = change.getKey(); - Long changeValue = change.getValue(); - Objects.requireNonNull(changeField, "changeField"); - if (changeValue != null) { - updateCheckConflict(targetField, changeField, changeValue); - } else { - fieldValues.remove(changeField); - } - } - } - private void updateCheckConflict(TemporalField targetField, TemporalField changeField, Long changeValue) { Long old = fieldValues.put(changeField, changeValue); if (old != null && old.longValue() != changeValue.longValue()) { @@ -305,7 +297,7 @@ final class Parsed implements TemporalAccessor { updateCheckConflict(chrono.resolveDate(fieldValues, resolverStyle)); } - private void updateCheckConflict(ChronoLocalDate cld) { + private void updateCheckConflict(ChronoLocalDate cld) { if (date != null) { if (cld != null && date.equals(cld) == false) { throw new DateTimeException("Conflict found: Fields resolved to two different dates: " + date + " " + cld); diff --git a/jdk/src/share/classes/java/time/temporal/ChronoField.java b/jdk/src/share/classes/java/time/temporal/ChronoField.java index ac4522bb60b..fe3254e60ab 100644 --- a/jdk/src/share/classes/java/time/temporal/ChronoField.java +++ b/jdk/src/share/classes/java/time/temporal/ChronoField.java @@ -403,6 +403,12 @@ public enum ChronoField implements TemporalField { * Non-ISO calendar systems should implement this field using the most recognized * day-of-year values for users of the calendar system. * Normally, this is a count of days from 1 to the length of the year. + *

    + * Note that a non-ISO calendar system may have year numbering system that changes + * at a different point to the natural reset in the month numbering. An example + * of this is the Japanese calendar system where a change of era, which resets + * the year number to 1, can happen on any date. The era and year reset also cause + * the day-of-year to be reset to 1, but not the month-of-year or day-of-month. */ DAY_OF_YEAR("DayOfYear", DAYS, YEARS, ValueRange.of(1, 365, 366)), /** @@ -559,12 +565,11 @@ public enum ChronoField implements TemporalField { *

    * This represents the concept of the sequential count of seconds where * 1970-01-01T00:00Z (ISO) is zero. - * This field may be used with {@link #NANO_OF_DAY} to represent the fraction of the day. + * This field may be used with {@link #NANO_OF_SECOND} to represent the fraction of the second. *

    * An {@link Instant} represents an instantaneous point on the time-line. - * On their own they have no elements which allow a local date-time to be obtained. - * Only when paired with an offset or time-zone can the local date or time be found. - * This field allows the seconds part of the instant to be queried. + * On their own, an instant has insufficient information to allow a local date-time to be obtained. + * Only when paired with an offset or time-zone can the local date or time be calculated. *

    * This field is strictly defined to have the same meaning in all calendar systems. * This is necessary to ensure interoperation between calendars. @@ -608,24 +613,18 @@ public enum ChronoField implements TemporalField { this.displayNameKey = displayNameKey; } - //----------------------------------------------------------------------- - @Override - public String getName() { - return name; - } - @Override public String getDisplayName(Locale locale) { Objects.requireNonNull(locale, "locale"); if (displayNameKey == null) { - return getName(); + return name; } LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased() .getLocaleResources(locale); ResourceBundle rb = lr.getJavaTimeFormatData(); String key = "field." + displayNameKey; - return rb.containsKey(key) ? rb.getString(key) : getName(); + return rb.containsKey(key) ? rb.getString(key) : name; } @Override @@ -748,7 +747,7 @@ public enum ChronoField implements TemporalField { //----------------------------------------------------------------------- @Override public String toString() { - return getName(); + return name; } } diff --git a/jdk/src/share/classes/java/time/temporal/ChronoUnit.java b/jdk/src/share/classes/java/time/temporal/ChronoUnit.java index 661960c28fb..19a37e46f4c 100644 --- a/jdk/src/share/classes/java/time/temporal/ChronoUnit.java +++ b/jdk/src/share/classes/java/time/temporal/ChronoUnit.java @@ -57,9 +57,6 @@ package java.time.temporal; import java.time.Duration; -import java.time.chrono.ChronoLocalDate; -import java.time.chrono.ChronoLocalDateTime; -import java.time.chrono.ChronoZonedDateTime; /** * A standard set of date periods units. @@ -200,12 +197,6 @@ public enum ChronoUnit implements TemporalUnit { this.duration = estimatedDuration; } - //----------------------------------------------------------------------- - @Override - public String getName() { - return name; - } - //----------------------------------------------------------------------- /** * Gets the estimated duration of this unit in the ISO calendar system. @@ -233,41 +224,40 @@ public enum ChronoUnit implements TemporalUnit { */ @Override public boolean isDurationEstimated() { - return isDateUnit(); + return this.compareTo(DAYS) >= 0; } //----------------------------------------------------------------------- /** * Checks if this unit is a date unit. + *

    + * All units from days to eras inclusive are date-based. + * Time-based units and {@code FOREVER} return false. * * @return true if a date unit, false if a time unit */ - public boolean isDateUnit() { - return this.compareTo(DAYS) >= 0; + @Override + public boolean isDateBased() { + return this.compareTo(DAYS) >= 0 && this != FOREVER; } /** * Checks if this unit is a time unit. + *

    + * All units from nanos to half-days inclusive are time-based. + * Date-based units and {@code FOREVER} return false. * * @return true if a time unit, false if a date unit */ - public boolean isTimeUnit() { + @Override + public boolean isTimeBased() { return this.compareTo(DAYS) < 0; } //----------------------------------------------------------------------- @Override public boolean isSupportedBy(Temporal temporal) { - if (this == FOREVER) { - return false; - } - if (temporal instanceof ChronoLocalDate) { - return isDateUnit(); - } - if (temporal instanceof ChronoLocalDateTime || temporal instanceof ChronoZonedDateTime) { - return true; - } - return TemporalUnit.super.isSupportedBy(temporal); + return temporal.isSupported(this); } @SuppressWarnings("unchecked") @@ -279,13 +269,13 @@ public enum ChronoUnit implements TemporalUnit { //----------------------------------------------------------------------- @Override public long between(Temporal temporal1, Temporal temporal2) { - return temporal1.periodUntil(temporal2, this); + return temporal1.until(temporal2, this); } //----------------------------------------------------------------------- @Override public String toString() { - return getName(); + return name; } } diff --git a/jdk/src/share/classes/java/time/temporal/IsoFields.java b/jdk/src/share/classes/java/time/temporal/IsoFields.java index e335c434d23..eae057afb2a 100644 --- a/jdk/src/share/classes/java/time/temporal/IsoFields.java +++ b/jdk/src/share/classes/java/time/temporal/IsoFields.java @@ -71,6 +71,8 @@ import static java.time.temporal.ChronoUnit.YEARS; import java.time.Duration; import java.time.LocalDate; +import java.time.ZoneId; +import java.time.chrono.ChronoLocalDate; import java.time.chrono.Chronology; import java.time.chrono.IsoChronology; import java.time.format.ResolverStyle; @@ -288,10 +290,6 @@ public final class IsoFields { */ private static enum Field implements TemporalField { DAY_OF_QUARTER { - @Override - public String getName() { - return "DayOfQuarter"; - } @Override public TemporalUnit getBaseUnit() { return DAYS; @@ -344,17 +342,21 @@ public final class IsoFields { return (R) temporal.with(DAY_OF_YEAR, temporal.getLong(DAY_OF_YEAR) + (newValue - curValue)); } @Override - public Map resolve(TemporalAccessor temporal, long doq, ResolverStyle resolverStyle) { - if ((temporal.isSupported(YEAR) && temporal.isSupported(QUARTER_OF_YEAR)) == false) { + public ChronoLocalDate resolve( + Map fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { + Long yearLong = fieldValues.get(YEAR); + Long qoyLong = fieldValues.get(QUARTER_OF_YEAR); + if (yearLong == null || qoyLong == null) { return null; } - int y = temporal.get(YEAR); // validated + int y = YEAR.checkValidIntValue(yearLong); // always validate + long doq = fieldValues.get(DAY_OF_QUARTER); LocalDate date; if (resolverStyle == ResolverStyle.LENIENT) { - long qoy = temporal.getLong(QUARTER_OF_YEAR); // unvalidated - date = LocalDate.of(y, 1, 1).plusMonths(Math.multiplyExact(Math.subtractExact(qoy, 1), 3)); + date = LocalDate.of(y, 1, 1).plusMonths(Math.multiplyExact(Math.subtractExact(qoyLong, 1), 3)); + doq = Math.subtractExact(doq, 1); } else { - int qoy = temporal.get(QUARTER_OF_YEAR); // validated + int qoy = QUARTER_OF_YEAR.range().checkValidIntValue(qoyLong, QUARTER_OF_YEAR); // validated date = LocalDate.of(y, ((qoy - 1) * 3) + 1, 1); if (doq < 1 || doq > 90) { if (resolverStyle == ResolverStyle.STRICT) { @@ -363,20 +365,19 @@ public final class IsoFields { range().checkValidValue(doq, this); // allow 1-92 rolling into next quarter } } + doq--; } - long epochDay = Math.addExact(date.toEpochDay(), Math.subtractExact(doq, 1)); - Map result = new HashMap<>(4, 1.0f); - result.put(EPOCH_DAY, epochDay); - result.put(YEAR, null); - result.put(QUARTER_OF_YEAR, null); - return result; + fieldValues.remove(this); + fieldValues.remove(YEAR); + fieldValues.remove(QUARTER_OF_YEAR); + return date.plusDays(doq); + } + @Override + public String toString() { + return "DayOfQuarter"; } }, QUARTER_OF_YEAR { - @Override - public String getName() { - return "QuarterOfYear"; - } @Override public TemporalUnit getBaseUnit() { return QUARTER_YEARS; @@ -409,20 +410,19 @@ public final class IsoFields { range().checkValidValue(newValue, this); // strictly check from 1 to 4 return (R) temporal.with(MONTH_OF_YEAR, temporal.getLong(MONTH_OF_YEAR) + (newValue - curValue) * 3); } + @Override + public String toString() { + return "QuarterOfYear"; + } }, WEEK_OF_WEEK_BASED_YEAR { - @Override - public String getName() { - return "WeekOfWeekBasedYear"; - } - @Override public String getDisplayName(Locale locale) { Objects.requireNonNull(locale, "locale"); LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased() .getLocaleResources(locale); ResourceBundle rb = lr.getJavaTimeFormatData(); - return rb.containsKey("field.week") ? rb.getString("field.week") : getName(); + return rb.containsKey("field.week") ? rb.getString("field.week") : toString(); } @Override @@ -463,14 +463,18 @@ public final class IsoFields { return (R) temporal.plus(Math.subtractExact(newValue, getFrom(temporal)), WEEKS); } @Override - public Map resolve(TemporalAccessor temporal, long wowby, ResolverStyle resolverStyle) { - if ((temporal.isSupported(WEEK_BASED_YEAR) && temporal.isSupported(DAY_OF_WEEK)) == false) { + public ChronoLocalDate resolve( + Map fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { + Long wbyLong = fieldValues.get(WEEK_BASED_YEAR); + Long dowLong = fieldValues.get(DAY_OF_WEEK); + if (wbyLong == null || dowLong == null) { return null; } - int wby = temporal.get(WEEK_BASED_YEAR); // validated + int wby = WEEK_BASED_YEAR.range().checkValidIntValue(wbyLong, WEEK_BASED_YEAR); // always validate + long wowby = fieldValues.get(WEEK_OF_WEEK_BASED_YEAR); LocalDate date = LocalDate.of(wby, 1, 4); if (resolverStyle == ResolverStyle.LENIENT) { - long dow = temporal.getLong(DAY_OF_WEEK); // unvalidated + long dow = dowLong; // unvalidated if (dow > 7) { date = date.plusWeeks((dow - 1) / 7); dow = ((dow - 1) % 7) + 1; @@ -480,7 +484,7 @@ public final class IsoFields { } date = date.plusWeeks(Math.subtractExact(wowby, 1)).with(DAY_OF_WEEK, dow); } else { - int dow = temporal.get(DAY_OF_WEEK); // validated + int dow = DAY_OF_WEEK.checkValidIntValue(dowLong); // validated if (wowby < 1 || wowby > 52) { if (resolverStyle == ResolverStyle.STRICT) { getWeekRange(date).checkValidValue(wowby, this); // only allow exact range @@ -490,18 +494,17 @@ public final class IsoFields { } date = date.plusWeeks(wowby - 1).with(DAY_OF_WEEK, dow); } - Map result = new HashMap<>(2, 1.0f); - result.put(EPOCH_DAY, date.toEpochDay()); - result.put(WEEK_BASED_YEAR, null); - result.put(DAY_OF_WEEK, null); - return result; + fieldValues.remove(this); + fieldValues.remove(WEEK_BASED_YEAR); + fieldValues.remove(DAY_OF_WEEK); + return date; + } + @Override + public String toString() { + return "WeekOfWeekBasedYear"; } }, WEEK_BASED_YEAR { - @Override - public String getName() { - return "WeekBasedYear"; - } @Override public TemporalUnit getBaseUnit() { return WEEK_BASED_YEARS; @@ -537,6 +540,10 @@ public final class IsoFields { date = date.withDayOfYear(180).withYear(newVal).with(WEEK_OF_WEEK_BASED_YEAR, week); return (R) date.with(date); } + @Override + public String toString() { + return "WeekBasedYear"; + } }; @Override @@ -545,13 +552,13 @@ public final class IsoFields { } @Override - public ValueRange rangeRefinedBy(TemporalAccessor temporal) { - return range(); + public boolean isTimeBased() { + return false; } @Override - public String toString() { - return getName(); + public ValueRange rangeRefinedBy(TemporalAccessor temporal) { + return range(); } //------------------------------------------------------------------------- @@ -635,11 +642,6 @@ public final class IsoFields { this.duration = estimatedDuration; } - @Override - public String getName() { - return name; - } - @Override public Duration getDuration() { return duration; @@ -650,6 +652,16 @@ public final class IsoFields { return true; } + @Override + public boolean isDateBased() { + return true; + } + + @Override + public boolean isTimeBased() { + return false; + } + @Override public boolean isSupportedBy(Temporal temporal) { return temporal.isSupported(EPOCH_DAY); @@ -658,7 +670,7 @@ public final class IsoFields { @SuppressWarnings("unchecked") @Override public R addTo(R temporal, long amount) { - switch(this) { + switch (this) { case WEEK_BASED_YEARS: return (R) temporal.with(WEEK_BASED_YEAR, Math.addExact(temporal.get(WEEK_BASED_YEAR), amount)); @@ -678,7 +690,7 @@ public final class IsoFields { return Math.subtractExact(temporal2.getLong(WEEK_BASED_YEAR), temporal1.getLong(WEEK_BASED_YEAR)); case QUARTER_YEARS: - return temporal1.periodUntil(temporal2, MONTHS) / 3; + return temporal1.until(temporal2, MONTHS) / 3; default: throw new IllegalStateException("Unreachable"); } @@ -686,8 +698,7 @@ public final class IsoFields { @Override public String toString() { - return getName(); - + return name; } } } diff --git a/jdk/src/share/classes/java/time/temporal/JulianFields.java b/jdk/src/share/classes/java/time/temporal/JulianFields.java index 95400addcaa..326f20d222f 100644 --- a/jdk/src/share/classes/java/time/temporal/JulianFields.java +++ b/jdk/src/share/classes/java/time/temporal/JulianFields.java @@ -66,6 +66,9 @@ import static java.time.temporal.ChronoUnit.DAYS; import static java.time.temporal.ChronoUnit.FOREVER; import java.time.DateTimeException; +import java.time.ZoneId; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.Chronology; import java.time.format.ResolverStyle; import java.util.Collections; import java.util.Map; @@ -232,11 +235,6 @@ public final class JulianFields { } //----------------------------------------------------------------------- - @Override - public String getName() { - return name; - } - @Override public TemporalUnit getBaseUnit() { return baseUnit; @@ -252,6 +250,11 @@ public final class JulianFields { return true; } + @Override + public boolean isTimeBased() { + return false; + } + @Override public ValueRange range() { return range; @@ -287,15 +290,14 @@ public final class JulianFields { //----------------------------------------------------------------------- @Override - public Map resolve(TemporalAccessor temporal, long value, ResolverStyle resolverStyle) { - long epochDay; + public ChronoLocalDate resolve( + Map fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { + long value = fieldValues.remove(this); if (resolverStyle == ResolverStyle.LENIENT) { - epochDay = Math.subtractExact(value, offset); - } else { - range().checkValidValue(value, this); - epochDay = value - offset; + return chronology.dateEpochDay(Math.subtractExact(value, offset)); } - return Collections.singletonMap(EPOCH_DAY, epochDay); + range().checkValidValue(value, this); + return chronology.dateEpochDay(value - offset); } //----------------------------------------------------------------------- diff --git a/jdk/src/share/classes/java/time/temporal/Temporal.java b/jdk/src/share/classes/java/time/temporal/Temporal.java index 1928186b285..af8424c1560 100644 --- a/jdk/src/share/classes/java/time/temporal/Temporal.java +++ b/jdk/src/share/classes/java/time/temporal/Temporal.java @@ -62,7 +62,6 @@ package java.time.temporal; import java.time.DateTimeException; -import java.time.ZoneId; /** * Framework-level interface defining read-write access to a temporal object, @@ -81,7 +80,8 @@ import java.time.ZoneId; * See {@link ChronoField} for the standard set of fields. *

    * Two pieces of date/time information cannot be represented by numbers, - * the {@linkplain java.time.chrono.Chronology chronology} and the {@linkplain ZoneId time-zone}. + * the {@linkplain java.time.chrono.Chronology chronology} and the + * {@linkplain java.time.ZoneId time-zone}. * These can be accessed via {@link #query(TemporalQuery) queries} using * the static methods defined on {@link TemporalQuery}. *

    @@ -128,6 +128,29 @@ import java.time.ZoneId; */ public interface Temporal extends TemporalAccessor { + /** + * Checks if the specified unit is supported. + *

    + * This checks if the specified unit can be added to, or subtracted from, this date-time. + * If false, then calling the {@link #plus(long, TemporalUnit)} and + * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. + * + * @implSpec + * Implementations must check and handle all units defined in {@link ChronoUnit}. + * If the unit is supported, then true must be returned, otherwise false must be returned. + *

    + * If the field is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} + * passing {@code this} as the argument. + *

    + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. + * + * @param unit the unit to check, null returns false + * @return true if the unit can be added/subtracted, false if not + */ + boolean isSupported(TemporalUnit unit); + /** * Returns an adjusted object of the same type as this object with the adjustment made. *

    @@ -352,7 +375,7 @@ public interface Temporal extends TemporalAccessor { * The start and end points are {@code this} and the specified temporal. * The result will be negative if the end is before the start. * For example, the period in hours between two temporal objects can be - * calculated using {@code startTime.periodUntil(endTime, HOURS)}. + * calculated using {@code startTime.until(endTime, HOURS)}. *

    * The calculation returns a whole number, representing the number of * complete units between the two temporals. @@ -364,7 +387,7 @@ public interface Temporal extends TemporalAccessor { * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: *

          *   // these two lines are equivalent
    -     *   temporal = start.periodUntil(end, unit);
    +     *   temporal = start.until(end, unit);
          *   temporal = unit.between(start, end);
          * 
    * The choice should be made based on which makes the code more readable. @@ -372,7 +395,7 @@ public interface Temporal extends TemporalAccessor { * For example, this method allows the number of days between two dates to * be calculated: *
    -     *  long daysBetween = start.periodUntil(end, DAYS);
    +     *  long daysBetween = start.until(end, DAYS);
          *  // or alternatively
          *  long daysBetween = DAYS.between(start, end);
          * 
    @@ -399,7 +422,8 @@ public interface Temporal extends TemporalAccessor { * return unit.between(this, endTemporal); *
    *

    - * Neither this object, nor the specified temporal, may be altered. + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. * * @param endTemporal the end temporal, of the same type as this object, not null * @param unit the unit to measure the amount in, not null @@ -410,6 +434,6 @@ public interface Temporal extends TemporalAccessor { * @throws UnsupportedTemporalTypeException if the unit is not supported * @throws ArithmeticException if numeric overflow occurs */ - long periodUntil(Temporal endTemporal, TemporalUnit unit); + long until(Temporal endTemporal, TemporalUnit unit); } diff --git a/jdk/src/share/classes/java/time/temporal/TemporalAccessor.java b/jdk/src/share/classes/java/time/temporal/TemporalAccessor.java index a212be85981..343447e36b9 100644 --- a/jdk/src/share/classes/java/time/temporal/TemporalAccessor.java +++ b/jdk/src/share/classes/java/time/temporal/TemporalAccessor.java @@ -62,7 +62,6 @@ package java.time.temporal; import java.time.DateTimeException; -import java.time.ZoneId; import java.util.Objects; /** @@ -80,7 +79,8 @@ import java.util.Objects; * See {@link ChronoField} for the standard set of fields. *

    * Two pieces of date/time information cannot be represented by numbers, - * the {@linkplain java.time.chrono.Chronology chronology} and the {@linkplain ZoneId time-zone}. + * the {@linkplain java.time.chrono.Chronology chronology} and the + * {@linkplain java.time.ZoneId time-zone}. * These can be accessed via {@linkplain #query(TemporalQuery) queries} using * the static methods defined on {@link TemporalQuery}. *

    @@ -111,13 +111,14 @@ public interface TemporalAccessor { * * @implSpec * Implementations must check and handle all fields defined in {@link ChronoField}. - * If the field is supported, then true is returned, otherwise false + * If the field is supported, then true must be returned, otherwise false must be returned. *

    * If the field is not a {@code ChronoField}, then the result of this method * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} * passing {@code this} as the argument. *

    - * Implementations must not alter either this object. + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. * * @param field the field to check, null returns false * @return true if this date-time can be queried for the field, false if not @@ -146,7 +147,8 @@ public interface TemporalAccessor { * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessorl)} * passing {@code this} as the argument. *

    - * Implementations must not alter either this object. + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. *

    * The default implementation must behave equivalent to this code: *

    @@ -154,7 +156,7 @@ public interface TemporalAccessor {
          *    if (isSupported(field)) {
          *      return field.range();
          *    }
    -     *    throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName());
    +     *    throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
          *  }
          *  return field.rangeRefinedBy(this);
          * 
    @@ -169,7 +171,7 @@ public interface TemporalAccessor { if (isSupported(field)) { return field.range(); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } Objects.requireNonNull(field, "field"); return field.rangeRefinedBy(this); @@ -193,7 +195,8 @@ public interface TemporalAccessor { * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)} * passing {@code this} as the argument. *

    - * Implementations must not alter this object. + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. *

    * The default implementation must behave equivalent to this code: *

    @@ -240,7 +243,8 @@ public interface TemporalAccessor {
          * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
          * passing {@code this} as the argument.
          * 

    - * Implementations must not alter either this object. + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. * * @param field the field to get, not null * @return the value for the field @@ -291,6 +295,9 @@ public interface TemporalAccessor { * } * return TemporalAccessor.super.query(query); *

    + *

    + * Implementations must ensure that no observable state is altered when this + * read-only method is invoked. * * @param the type of the result * @param query the query to invoke, not null diff --git a/jdk/src/share/classes/java/time/temporal/TemporalField.java b/jdk/src/share/classes/java/time/temporal/TemporalField.java index cce2dfbd4de..e4d6b407783 100644 --- a/jdk/src/share/classes/java/time/temporal/TemporalField.java +++ b/jdk/src/share/classes/java/time/temporal/TemporalField.java @@ -62,6 +62,9 @@ package java.time.temporal; import java.time.DateTimeException; +import java.time.ZoneId; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.Chronology; import java.time.format.ResolverStyle; import java.util.Locale; import java.util.Map; @@ -92,30 +95,20 @@ import java.util.Objects; */ public interface TemporalField { - /** - * Gets a descriptive name for the field. - *

    - * The should be of the format 'BaseOfRange', such as 'MonthOfYear', - * unless the field has a range of {@code FOREVER}, when only - * the base unit is mentioned, such as 'Year' or 'Era'. - * - * @return the name, not null - */ - String getName(); - /** * Gets the display name for the field in the requested locale. *

    - * If there is no display name for the locale the value of {@code getName} - * is returned. + * If there is no display name for the locale then a suitable default must be returned. + *

    + * The default implementation must check the locale is not null + * and return {@code toString()}. * * @param locale the locale to use, not null - * @return the display name for the locale or the value of {@code getName}, - * not null + * @return the display name for the locale or a suitable default, not null */ default String getDisplayName(Locale locale) { - Objects.requireNonNull(locale, "local"); - return getName(); + Objects.requireNonNull(locale, "locale"); + return toString(); } /** @@ -164,28 +157,24 @@ public interface TemporalField { *

    * A field is date-based if it can be derived from * {@link ChronoField#EPOCH_DAY EPOCH_DAY}. - *

    - * The default implementation must return false. + * Note that it is valid for both {@code isDateBased()} and {@code isTimeBased()} + * to return false, such as when representing a field like minute-of-week. * * @return true if this field is a component of a date */ - default boolean isDateBased() { - return false; - } + boolean isDateBased(); /** * Checks if this field represents a component of a time. *

    * A field is time-based if it can be derived from * {@link ChronoField#NANO_OF_DAY NANO_OF_DAY}. - *

    - * The default implementation must return false. + * Note that it is valid for both {@code isDateBased()} and {@code isTimeBased()} + * to return false, such as when representing a field like minute-of-week. * * @return true if this field is a component of a time */ - default boolean isTimeBased() { - return false; - } + boolean isTimeBased(); //----------------------------------------------------------------------- /** @@ -319,45 +308,79 @@ public interface TemporalField { R adjustInto(R temporal, long newValue); /** - * Resolves this field to provide a simpler alternative. + * Resolves this field to provide a simpler alternative or a date. *

    * This method is invoked during the resolve phase of parsing. * It is designed to allow application defined fields to be simplified into - * more standard fields, such as those on {@code ChronoField}. + * more standard fields, such as those on {@code ChronoField}, or into a date. *

    - * The method will only be invoked if the specified temporal supports this field. - * The value of this field is provided. + * Applications should not normally invoke this method directly. + * + * @implSpec + * If an implementation represents a field that can be simplified, or + * combined with others, then this method must be implemented. *

    - * The temporal must be queried using the methods of {@code TemporalAccessor}, - * not using {@code getFrom}, {@code isSupportedBy} or {@code rangeRefinedBy}. - * Before querying any field, implementations must ensure it is supported, as - * exceptions of this type would negatively affect the calculation of a parsed result. + * The specified map contains the current state of the parse. + * The map is mutable and must be mutated to resolve the field and + * any related fields. This method will only be invoked during parsing + * if the map contains this field, and implementations should therefore + * assume this field is present. *

    - * If this field can resolve, it must return a map, if not it must return null. - * The returned map contains the changes to be made to the temporal, expressed - * as field-value pairs. If the value for a field is null, the field is to be - * removed from the temporal. A null key must not be added to the result map. + * Resolving a field will consist of looking at the value of this field, + * and potentially other fields, and either updating the map with a + * simpler value, such as a {@code ChronoField}, or returning a + * complete {@code ChronoLocalDate}. If a resolve is successful, + * the code must remove all the fields that were resolved from the map, + * including this field. *

    - * If the result is non-null, this field will be removed from the temporal. - * This field should not be added to the result map. + * For example, the {@code IsoFields} class contains the quarter-of-year + * and day-of-quarter fields. The implementation of this method in that class + * resolves the two fields plus the {@link ChronoField#YEAR YEAR} into a + * complete {@code LocalDate}. The resolve method will remove all three + * fields from the map before returning the {@code LocalDate}. *

    - * The {@link ResolverStyle} should be used by implementations to determine - * how to perform the resolve. + * If resolution should be possible, but the data is invalid, the resolver + * style should be used to determine an appropriate level of leniency, which + * may require throwing a {@code DateTimeException} or {@code ArithmeticException}. + * If no resolution is possible, the resolve method must return null. + *

    + * When resolving time fields, the map will be altered and null returned. + * When resolving date fields, the date is normally returned from the method, + * with the map altered to remove the resolved fields. However, it would also + * be acceptable for the date fields to be resolved into other {@code ChronoField} + * instances that can produce a date, such as {@code EPOCH_DAY}. + *

    + * The zone is not normally required for resolution, but is provided for completeness. *

    * The default implementation must return null. * - * @param temporal the temporal to resolve, not null - * @param value the value of this field + * @param fieldValues the map of fields to values, which can be updated, not null + * @param chronology the effective chronology, not null + * @param zone the effective zone, not null * @param resolverStyle the requested type of resolve, not null - * @return a map of fields to update in the temporal, with a mapping to null - * indicating a deletion. The whole map must be null if no resolving occurred + * @return the resolved date; null if resolving only changed the map, + * or no resolve occurred + * @throws ArithmeticException if numeric overflow occurs * @throws DateTimeException if resolving results in an error. This must not be thrown * by querying a field on the temporal without first checking if it is supported - * @throws ArithmeticException if numeric overflow occurs */ - default Map resolve( - TemporalAccessor temporal, long value, ResolverStyle resolverStyle) { + default ChronoLocalDate resolve( + Map fieldValues, Chronology chronology, + ZoneId zone, ResolverStyle resolverStyle) { return null; } + /** + * Gets a descriptive name for the field. + *

    + * The should be of the format 'BaseOfRange', such as 'MonthOfYear', + * unless the field has a range of {@code FOREVER}, when only + * the base unit is mentioned, such as 'Year' or 'Era'. + * + * @return the name of the field, not null + */ + @Override + String toString(); + + } diff --git a/jdk/src/share/classes/java/time/temporal/TemporalUnit.java b/jdk/src/share/classes/java/time/temporal/TemporalUnit.java index 01ab406f85a..05577d713f8 100644 --- a/jdk/src/share/classes/java/time/temporal/TemporalUnit.java +++ b/jdk/src/share/classes/java/time/temporal/TemporalUnit.java @@ -63,7 +63,11 @@ package java.time.temporal; import java.time.DateTimeException; import java.time.Duration; +import java.time.LocalTime; import java.time.Period; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoZonedDateTime; /** * A unit of date-time, such as Days or Hours. @@ -92,15 +96,6 @@ import java.time.Period; */ public interface TemporalUnit { - /** - * Gets a descriptive name for the unit. - *

    - * This should be in the plural and upper-first camel case, such as 'Days' or 'Minutes'. - * - * @return the name, not null - */ - String getName(); - /** * Gets the duration of this unit, which may be an estimate. *

    @@ -130,6 +125,33 @@ public interface TemporalUnit { */ boolean isDurationEstimated(); + //----------------------------------------------------------------------- + /** + * Checks if this unit represents a component of a date. + *

    + * A date is time-based if it can be used to imply meaning from a date. + * It must have a {@linkplain #getDuration() duration} that is an integral + * multiple of the length of a standard day. + * Note that it is valid for both {@code isDateBased()} and {@code isTimeBased()} + * to return false, such as when representing a unit like 36 hours. + * + * @return true if this unit is a component of a date + */ + boolean isDateBased(); + + /** + * Checks if this unit represents a component of a time. + *

    + * A unit is time-based if it can be used to imply meaning from a time. + * It must have a {@linkplain #getDuration() duration} that divides into + * the length of a standard day without remainder. + * Note that it is valid for both {@code isDateBased()} and {@code isTimeBased()} + * to return false, such as when representing a unit like 36 hours. + * + * @return true if this unit is a component of a time + */ + boolean isTimeBased(); + //----------------------------------------------------------------------- /** * Checks if this unit is supported by the specified temporal object. @@ -144,6 +166,15 @@ public interface TemporalUnit { * @return true if the unit is supported */ default boolean isSupportedBy(Temporal temporal) { + if (temporal instanceof LocalTime) { + return isTimeBased(); + } + if (temporal instanceof ChronoLocalDate) { + return isDateBased(); + } + if (temporal instanceof ChronoLocalDateTime || temporal instanceof ChronoZonedDateTime) { + return true; + } try { temporal.plus(1, this); return true; @@ -212,11 +243,11 @@ public interface TemporalUnit { *

    * There are two equivalent ways of using this method. * The first is to invoke this method directly. - * The second is to use {@link Temporal#periodUntil(Temporal, TemporalUnit)}: + * The second is to use {@link Temporal#until(Temporal, TemporalUnit)}: *

          *   // these two lines are equivalent
          *   between = thisUnit.between(start, end);
    -     *   between = start.periodUntil(end, thisUnit);
    +     *   between = start.until(end, thisUnit);
          * 
    * The choice should be made based on which makes the code more readable. *

    @@ -225,7 +256,7 @@ public interface TemporalUnit { *

          *  long daysBetween = DAYS.between(start, end);
          *  // or alternatively
    -     *  long daysBetween = start.periodUntil(end, DAYS);
    +     *  long daysBetween = start.until(end, DAYS);
          * 
    *

    * Implementations should perform any queries or calculations using the units @@ -245,7 +276,9 @@ public interface TemporalUnit { //----------------------------------------------------------------------- /** - * Outputs this unit as a {@code String} using the name. + * Gets a descriptive name for the unit. + *

    + * This should be in the plural and upper-first camel case, such as 'Days' or 'Minutes'. * * @return the name of this unit, not null */ diff --git a/jdk/src/share/classes/java/time/temporal/ValueRange.java b/jdk/src/share/classes/java/time/temporal/ValueRange.java index 4ac8e74402a..e003f114adc 100644 --- a/jdk/src/share/classes/java/time/temporal/ValueRange.java +++ b/jdk/src/share/classes/java/time/temporal/ValueRange.java @@ -331,7 +331,7 @@ public final class ValueRange implements Serializable { private String genInvalidFieldMessage(TemporalField field, long value) { if (field != null) { - return "Invalid value for " + field.getName() + " (valid values " + this + "): " + value; + return "Invalid value for " + field + " (valid values " + this + "): " + value; } else { return "Invalid value (valid values " + this + "): " + value; } diff --git a/jdk/src/share/classes/java/time/temporal/WeekFields.java b/jdk/src/share/classes/java/time/temporal/WeekFields.java index 07ffa91d2a3..b3eb1383450 100644 --- a/jdk/src/share/classes/java/time/temporal/WeekFields.java +++ b/jdk/src/share/classes/java/time/temporal/WeekFields.java @@ -75,7 +75,9 @@ import static java.time.temporal.ChronoUnit.YEARS; import java.io.InvalidObjectException; import java.io.Serializable; +import java.time.DateTimeException; import java.time.DayOfWeek; +import java.time.ZoneId; import java.time.chrono.ChronoLocalDate; import java.time.chrono.Chronology; import java.time.format.ResolverStyle; @@ -395,6 +397,11 @@ public final class WeekFields implements Serializable { *

    * For example, if the first day-of-week is Sunday, then that will have the * value 1, with other days ranging from Monday as 2 to Saturday as 7. + *

    + * In the resolving phase of parsing, a localized day-of-week will be converted + * to a standardized {@code ChronoField} day-of-week. + * The day-of-week must be in the valid range 1 to 7. + * Other fields in this class build dates using the standardized day-of-week. * * @return a field providing access to the day-of-week with localized numbering, not null */ @@ -421,6 +428,26 @@ public final class WeekFields implements Serializable { * - if the 5th day of the month is a Monday, week two starts on the 5th and the 1st to 4th is in week one
    *

    * This field can be used with any calendar system. + *

    + * In the resolving phase of parsing, a date can be created from a year, + * week-of-month, month-of-year and day-of-week. + *

    + * In {@linkplain ResolverStyle#STRICT strict mode}, all four fields are + * validated against their range of valid values. The week-of-month field + * is validated to ensure that the resulting month is the month requested. + *

    + * In {@linkplain ResolverStyle#SMART smart mode}, all four fields are + * validated against their range of valid values. The week-of-month field + * is validated from 0 to 6, meaning that the resulting date can be in a + * different month to that specified. + *

    + * In {@linkplain ResolverStyle#LENIENT lenient mode}, the year and day-of-week + * are validated against the range of valid values. The resulting date is calculated + * equivalent to the following four stage approach. + * First, create a date on the first day of the first week of January in the requested year. + * Then take the month-of-year, subtract one, and add the amount in months to the date. + * Then take the week-of-month, subtract one, and add the amount in weeks to the date. + * Finally, adjust to the correct day-of-week within the localized week. * * @return a field providing access to the week-of-month, not null */ @@ -447,6 +474,25 @@ public final class WeekFields implements Serializable { * - if the 5th day of the year is a Monday, week two starts on the 5th and the 1st to 4th is in week one
    *

    * This field can be used with any calendar system. + *

    + * In the resolving phase of parsing, a date can be created from a year, + * week-of-year and day-of-week. + *

    + * In {@linkplain ResolverStyle#STRICT strict mode}, all three fields are + * validated against their range of valid values. The week-of-year field + * is validated to ensure that the resulting year is the year requested. + *

    + * In {@linkplain ResolverStyle#SMART smart mode}, all three fields are + * validated against their range of valid values. The week-of-year field + * is validated from 0 to 54, meaning that the resulting date can be in a + * different year to that specified. + *

    + * In {@linkplain ResolverStyle#LENIENT lenient mode}, the year and day-of-week + * are validated against the range of valid values. The resulting date is calculated + * equivalent to the following three stage approach. + * First, create a date on the first day of the first week in the requested year. + * Then take the week-of-year, subtract one, and add the amount in weeks to the date. + * Finally, adjust to the correct day-of-week within the localized week. * * @return a field providing access to the week-of-year, not null */ @@ -477,6 +523,26 @@ public final class WeekFields implements Serializable { * the 1st to 4th is in week one
    *

    * This field can be used with any calendar system. + *

    + * In the resolving phase of parsing, a date can be created from a week-based-year, + * week-of-year and day-of-week. + *

    + * In {@linkplain ResolverStyle#STRICT strict mode}, all three fields are + * validated against their range of valid values. The week-of-year field + * is validated to ensure that the resulting week-based-year is the + * week-based-year requested. + *

    + * In {@linkplain ResolverStyle#SMART smart mode}, all three fields are + * validated against their range of valid values. The week-of-week-based-year field + * is validated from 1 to 53, meaning that the resulting date can be in the + * following week-based-year to that specified. + *

    + * In {@linkplain ResolverStyle#LENIENT lenient mode}, the year and day-of-week + * are validated against the range of valid values. The resulting date is calculated + * equivalent to the following three stage approach. + * First, create a date on the first day of the first week in the requested week-based-year. + * Then take the week-of-week-based-year, subtract one, and add the amount in weeks to the date. + * Finally, adjust to the correct day-of-week within the localized week. * * @return a field providing access to the week-of-week-based-year, not null */ @@ -499,6 +565,26 @@ public final class WeekFields implements Serializable { * is in the last week of the previous year. *

    * This field can be used with any calendar system. + *

    + * In the resolving phase of parsing, a date can be created from a week-based-year, + * week-of-year and day-of-week. + *

    + * In {@linkplain ResolverStyle#STRICT strict mode}, all three fields are + * validated against their range of valid values. The week-of-year field + * is validated to ensure that the resulting week-based-year is the + * week-based-year requested. + *

    + * In {@linkplain ResolverStyle#SMART smart mode}, all three fields are + * validated against their range of valid values. The week-of-week-based-year field + * is validated from 1 to 53, meaning that the resulting date can be in the + * following week-based-year to that specified. + *

    + * In {@linkplain ResolverStyle#LENIENT lenient mode}, the year and day-of-week + * are validated against the range of valid values. The resulting date is calculated + * equivalent to the following three stage approach. + * First, create a date on the first day of the first week in the requested week-based-year. + * Then take the week-of-week-based-year, subtract one, and add the amount in weeks to the date. + * Finally, adjust to the correct day-of-week within the localized week. * * @return a field providing access to the week-based-year, not null */ @@ -615,9 +701,9 @@ public final class WeekFields implements Serializable { * @param dow the day of the week * @return a ChronoLocalDate for the requested year, week of year, and day of week */ - private ChronoLocalDate ofWeekBasedYear(Chronology chrono, + private ChronoLocalDate ofWeekBasedYear(Chronology chrono, int yowby, int wowby, int dow) { - ChronoLocalDate date = chrono.date(yowby, 1, 1); + ChronoLocalDate date = chrono.date(yowby, 1, 1); int ldow = localizedDayOfWeek(date); int offset = startOfWeekOffset(1, ldow); @@ -671,6 +757,11 @@ public final class WeekFields implements Serializable { return Math.floorMod(isoDow - sow, 7) + 1; } + private int localizedDayOfWeek(int isoDow) { + int sow = weekDef.getFirstDayOfWeek().getValue(); + return Math.floorMod(isoDow - sow, 7) + 1; + } + private long localizedWeekOfMonth(TemporalAccessor temporal) { int dow = localizedDayOfWeek(temporal); int dom = temporal.get(DAY_OF_MONTH); @@ -800,75 +891,121 @@ public final class WeekFields implements Serializable { } @Override - public Map resolve(TemporalAccessor temporal, long value, ResolverStyle resolverStyle) { - int newValue = range.checkValidIntValue(value, this); - int sow = weekDef.getFirstDayOfWeek().getValue(); + public ChronoLocalDate resolve( + Map fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { + final long value = fieldValues.get(this); + final int newValue = Math.toIntExact(value); // broad limit makes overflow checking lighter + // first convert localized day-of-week to ISO day-of-week + // doing this first handles case where both ISO and localized were parsed and might mismatch + // day-of-week is always strict as two different day-of-week values makes lenient complex if (rangeUnit == WEEKS) { // day-of-week - int isoDow = Math.floorMod((sow - 1) + (newValue - 1), 7) + 1; - return Collections.singletonMap(DAY_OF_WEEK, (long) isoDow); - } - if (temporal.isSupported(DAY_OF_WEEK) == false) { + final int checkedValue = range.checkValidIntValue(value, this); // no leniency as too complex + final int startDow = weekDef.getFirstDayOfWeek().getValue(); + long isoDow = Math.floorMod((startDow - 1) + (checkedValue - 1), 7) + 1; + fieldValues.remove(this); + fieldValues.put(DAY_OF_WEEK, isoDow); return null; } - Chronology chrono = Chronology.from(temporal); // defaults to ISO - int dow = localizedDayOfWeek(temporal); - if (temporal.isSupported(YEAR)) { - int year = temporal.get(YEAR); - if (rangeUnit == MONTHS) { // week-of-month - if (temporal.isSupported(MONTH_OF_YEAR) == false) { - return null; - } - int month = temporal.get(ChronoField.MONTH_OF_YEAR); - @SuppressWarnings("rawtypes") - ChronoLocalDate date = chrono.date(year, month, 1); - int dateDow = localizedDayOfWeek(date); - long weeks = newValue - localizedWeekOfMonth(date); - int days = dow - dateDow; - date = date.plus(weeks * 7 + days, DAYS); - Map result = new HashMap<>(4, 1.0f); - result.put(EPOCH_DAY, date.toEpochDay()); - result.put(YEAR, null); - result.put(MONTH_OF_YEAR, null); - result.put(DAY_OF_WEEK, null); - return result; - } else if (rangeUnit == YEARS) { // week-of-year - @SuppressWarnings("rawtypes") - ChronoLocalDate date = chrono.date(year, 1, 1); - int dateDow = localizedDayOfWeek(date); - long weeks = newValue - localizedWeekOfYear(date); - int days = dow - dateDow; - date = date.plus(weeks * 7 + days, DAYS); - Map result = new HashMap<>(4, 1.0f); - result.put(EPOCH_DAY, date.toEpochDay()); - result.put(YEAR, null); - result.put(DAY_OF_WEEK, null); - return result; - } - } else if (rangeUnit == WEEK_BASED_YEARS || rangeUnit == FOREVER) { - if (temporal.isSupported(weekDef.weekBasedYear) && - temporal.isSupported(weekDef.weekOfWeekBasedYear)) { - // week-of-week-based-year and year-of-week-based-year - int yowby = temporal.get(weekDef.weekBasedYear); - int wowby = temporal.get(weekDef.weekOfWeekBasedYear); - ChronoLocalDate date = ofWeekBasedYear(Chronology.from(temporal), yowby, wowby, dow); - Map result = new HashMap<>(4, 1.0f); - result.put(EPOCH_DAY, date.toEpochDay()); - result.put(DAY_OF_WEEK, null); - result.put(weekDef.weekOfWeekBasedYear, null); - result.put(weekDef.weekBasedYear, null); - return result; + // can only build date if ISO day-of-week is present + if (fieldValues.containsKey(DAY_OF_WEEK) == false) { + return null; + } + int isoDow = DAY_OF_WEEK.checkValidIntValue(fieldValues.get(DAY_OF_WEEK)); + int dow = localizedDayOfWeek(isoDow); + + // build date + if (fieldValues.containsKey(YEAR)) { + int year = YEAR.checkValidIntValue(fieldValues.get(YEAR)); // validate + if (rangeUnit == MONTHS && fieldValues.containsKey(MONTH_OF_YEAR)) { // week-of-month + long month = fieldValues.get(MONTH_OF_YEAR); // not validated yet + return resolveWoM(fieldValues, chronology, year, month, newValue, dow, resolverStyle); } + if (rangeUnit == YEARS) { // week-of-year + return resolveWoY(fieldValues, chronology, year, newValue, dow, resolverStyle); + } + } else if ((rangeUnit == WEEK_BASED_YEARS || rangeUnit == FOREVER) && + fieldValues.containsKey(weekDef.weekBasedYear) && + fieldValues.containsKey(weekDef.weekOfWeekBasedYear)) { // week-of-week-based-year and year-of-week-based-year + return resolveWBY(fieldValues, chronology, dow, resolverStyle); } return null; } - //----------------------------------------------------------------------- - @Override - public String getName() { - return name; + private ChronoLocalDate resolveWoM( + Map fieldValues, Chronology chrono, int year, long month, long wom, int localDow, ResolverStyle resolverStyle) { + ChronoLocalDate date; + if (resolverStyle == ResolverStyle.LENIENT) { + date = chrono.date(year, 1, 1).plus(Math.subtractExact(month, 1), MONTHS); + long weeks = Math.subtractExact(wom, localizedWeekOfMonth(date)); + int days = localDow - localizedDayOfWeek(date); // safe from overflow + date = date.plus(Math.addExact(Math.multiplyExact(weeks, 7), days), DAYS); + } else { + int monthValid = MONTH_OF_YEAR.checkValidIntValue(month); // validate + date = chrono.date(year, monthValid, 1); + int womInt = range.checkValidIntValue(wom, this); // validate + int weeks = (int) (womInt - localizedWeekOfMonth(date)); // safe from overflow + int days = localDow - localizedDayOfWeek(date); // safe from overflow + date = date.plus(weeks * 7 + days, DAYS); + if (resolverStyle == ResolverStyle.STRICT && date.getLong(MONTH_OF_YEAR) != month) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different month"); + } + } + fieldValues.remove(this); + fieldValues.remove(YEAR); + fieldValues.remove(MONTH_OF_YEAR); + fieldValues.remove(DAY_OF_WEEK); + return date; } + private ChronoLocalDate resolveWoY( + Map fieldValues, Chronology chrono, int year, long woy, int localDow, ResolverStyle resolverStyle) { + ChronoLocalDate date = chrono.date(year, 1, 1); + if (resolverStyle == ResolverStyle.LENIENT) { + long weeks = Math.subtractExact(woy, localizedWeekOfYear(date)); + int days = localDow - localizedDayOfWeek(date); // safe from overflow + date = date.plus(Math.addExact(Math.multiplyExact(weeks, 7), days), DAYS); + } else { + int womInt = range.checkValidIntValue(woy, this); // validate + int weeks = (int) (womInt - localizedWeekOfYear(date)); // safe from overflow + int days = localDow - localizedDayOfWeek(date); // safe from overflow + date = date.plus(weeks * 7 + days, DAYS); + if (resolverStyle == ResolverStyle.STRICT && date.getLong(YEAR) != year) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different year"); + } + } + fieldValues.remove(this); + fieldValues.remove(YEAR); + fieldValues.remove(DAY_OF_WEEK); + return date; + } + + private ChronoLocalDate resolveWBY( + Map fieldValues, Chronology chrono, int localDow, ResolverStyle resolverStyle) { + int yowby = weekDef.weekBasedYear.range().checkValidIntValue( + fieldValues.get(weekDef.weekBasedYear), weekDef.weekBasedYear); + ChronoLocalDate date; + if (resolverStyle == ResolverStyle.LENIENT) { + date = ofWeekBasedYear(chrono, yowby, 1, localDow); + long wowby = fieldValues.get(weekDef.weekOfWeekBasedYear); + long weeks = Math.subtractExact(wowby, 1); + date = date.plus(weeks, WEEKS); + } else { + int wowby = weekDef.weekOfWeekBasedYear.range().checkValidIntValue( + fieldValues.get(weekDef.weekOfWeekBasedYear), weekDef.weekOfWeekBasedYear); // validate + date = ofWeekBasedYear(chrono, yowby, wowby, localDow); + if (resolverStyle == ResolverStyle.STRICT && localizedWeekBasedYear(date) != yowby) { + throw new DateTimeException("Strict mode rejected resolved date as it is in a different week-based-year"); + } + } + fieldValues.remove(this); + fieldValues.remove(weekDef.weekBasedYear); + fieldValues.remove(weekDef.weekOfWeekBasedYear); + fieldValues.remove(DAY_OF_WEEK); + return date; + } + + //----------------------------------------------------------------------- @Override public String getDisplayName(Locale locale) { Objects.requireNonNull(locale, "locale"); @@ -876,9 +1013,9 @@ public final class WeekFields implements Serializable { LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased() .getLocaleResources(locale); ResourceBundle rb = lr.getJavaTimeFormatData(); - return rb.containsKey("field.week") ? rb.getString("field.week") : getName(); + return rb.containsKey("field.week") ? rb.getString("field.week") : name; } - return getName(); + return name; } @Override @@ -896,6 +1033,11 @@ public final class WeekFields implements Serializable { return true; } + @Override + public boolean isTimeBased() { + return false; + } + @Override public ValueRange range() { return range; @@ -988,7 +1130,7 @@ public final class WeekFields implements Serializable { //----------------------------------------------------------------------- @Override public String toString() { - return getName() + "[" + weekDef.toString() + "]"; + return name + "[" + weekDef.toString() + "]"; } } } diff --git a/jdk/src/share/classes/java/util/PriorityQueue.java b/jdk/src/share/classes/java/util/PriorityQueue.java index c28647b58bb..c5a961cdbe9 100644 --- a/jdk/src/share/classes/java/util/PriorityQueue.java +++ b/jdk/src/share/classes/java/util/PriorityQueue.java @@ -135,6 +135,19 @@ public class PriorityQueue extends AbstractQueue this(initialCapacity, null); } + /** + * Creates a {@code PriorityQueue} with the default initial capacity + * that orders its elements according to the specified comparator. + * + * @param comparator the comparator that will be used to order this + * priority queue. If {@code null}, the {@linkplain Comparable + * natural ordering} of the elements will be used. + * @since 1.8 + */ + public PriorityQueue(Comparator comparator) { + this(DEFAULT_INITIAL_CAPACITY, comparator); + } + /** * Creates a {@code PriorityQueue} with the specified initial capacity * that orders its elements according to the specified comparator. diff --git a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java index 08e2bd38239..edd788afe25 100644 --- a/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/jdk/src/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -265,7 +265,8 @@ import java.util.stream.Stream; * @param the type of keys maintained by this map * @param the type of mapped values */ -public class ConcurrentHashMap extends AbstractMap implements ConcurrentMap, Serializable { +public class ConcurrentHashMap extends AbstractMap + implements ConcurrentMap, Serializable { private static final long serialVersionUID = 7249069246763182397L; /* @@ -439,16 +440,18 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * related operations (which is the main reason we cannot use * existing collections such as TreeMaps). TreeBins contain * Comparable elements, but may contain others, as well as - * elements that are Comparable but not necessarily Comparable - * for the same T, so we cannot invoke compareTo among them. To - * handle this, the tree is ordered primarily by hash value, then - * by Comparable.compareTo order if applicable. On lookup at a - * node, if elements are not comparable or compare as 0 then both - * left and right children may need to be searched in the case of - * tied hash values. (This corresponds to the full list search - * that would be necessary if all elements were non-Comparable and - * had tied hashes.) The red-black balancing code is updated from - * pre-jdk-collections + * elements that are Comparable but not necessarily Comparable for + * the same T, so we cannot invoke compareTo among them. To handle + * this, the tree is ordered primarily by hash value, then by + * Comparable.compareTo order if applicable. On lookup at a node, + * if elements are not comparable or compare as 0 then both left + * and right children may need to be searched in the case of tied + * hash values. (This corresponds to the full list search that + * would be necessary if all elements were non-Comparable and had + * tied hashes.) On insertion, to keep a total ordering (or as + * close as is required here) across rebalancings, we compare + * classes and identityHashCodes as tie-breakers. The red-black + * balancing code is updated from pre-jdk-collections * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) * based in turn on Cormen, Leiserson, and Rivest "Introduction to * Algorithms" (CLR). @@ -478,6 +481,10 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * unused "Segment" class that is instantiated in minimal form * only when serializing. * + * Also, solely for compatibility with previous versions of this + * class, it extends AbstractMap, even though all of its methods + * are overridden, so it is just useless baggage. + * * This file is organized to make things a little easier to follow * while reading than they might otherwise: First the main static * declarations and utilities, then fields, then main public @@ -1352,6 +1359,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * Saves the state of the {@code ConcurrentHashMap} instance to a * stream (i.e., serializes it). * @param s the stream + * @throws java.io.IOException if an I/O error occurs * @serialData * the key (Object) and value (Object) * for each key-value mapping, followed by a null pair. @@ -1394,6 +1402,9 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre /** * Reconstitutes the instance from a stream (that is, deserializes it). * @param s the stream + * @throws ClassNotFoundException if the class of a serialized object + * could not be found + * @throws java.io.IOException if an I/O error occurs */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { @@ -2080,6 +2091,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * Creates a new {@link Set} backed by a ConcurrentHashMap * from the given type to {@code Boolean.TRUE}. * + * @param the element type of the returned set * @return the new set * @since 1.8 */ @@ -2094,9 +2106,10 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * * @param initialCapacity The implementation performs internal * sizing to accommodate this many elements. + * @param the element type of the returned set + * @return the new set * @throws IllegalArgumentException if the initial capacity of * elements is negative - * @return the new set * @since 1.8 */ public static KeySetView newKeySet(int initialCapacity) { @@ -2643,19 +2656,18 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre p = pr; else if ((pk = p.key) == k || (pk != null && k.equals(pk))) return p; - else if (pl == null && pr == null) - break; + else if (pl == null) + p = pr; + else if (pr == null) + p = pl; else if ((kc != null || (kc = comparableClassFor(k)) != null) && (dir = compareComparables(kc, k, pk)) != 0) p = (dir < 0) ? pl : pr; - else if (pl == null) - p = pr; - else if (pr == null || - (q = pr.findTreeNode(h, k, kc)) == null) - p = pl; - else + else if ((q = pr.findTreeNode(h, k, kc)) != null) return q; + else + p = pl; } while (p != null); } return null; @@ -2681,6 +2693,23 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre static final int WAITER = 2; // set when waiting for write lock static final int READER = 4; // increment value for setting read lock + /** + * Tie-breaking utility for ordering insertions when equal + * hashCodes and non-comparable. We don't require a total + * order, just a consistent insertion rule to maintain + * equivalence across rebalancings. Tie-breaking further than + * necessary simplifies testing a bit. + */ + static int tieBreakOrder(Object a, Object b) { + int d; + if (a == null || b == null || + (d = a.getClass().getName(). + compareTo(b.getClass().getName())) == 0) + d = (System.identityHashCode(a) <= System.identityHashCode(b) ? + -1 : 1); + return d; + } + /** * Creates bin with initial set of nodes headed by b. */ @@ -2697,21 +2726,21 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre r = x; } else { - Object key = x.key; - int hash = x.hash; + K k = x.key; + int h = x.hash; Class kc = null; for (TreeNode p = r;;) { int dir, ph; - if ((ph = p.hash) > hash) + K pk = p.key; + if ((ph = p.hash) > h) dir = -1; - else if (ph < hash) + else if (ph < h) dir = 1; - else if ((kc != null || - (kc = comparableClassFor(key)) != null)) - dir = compareComparables(kc, key, p.key); - else - dir = 0; - TreeNode xp = p; + else if ((kc == null && + (kc = comparableClassFor(k)) == null) || + (dir = compareComparables(kc, k, pk)) == 0) + dir = tieBreakOrder(k, pk); + TreeNode xp = p; if ((p = (dir <= 0) ? p.left : p.right) == null) { x.parent = xp; if (dir <= 0) @@ -2725,6 +2754,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre } } this.root = r; + assert checkInvariants(root); } /** @@ -2805,8 +2835,9 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre */ final TreeNode putTreeVal(int h, K k, V v) { Class kc = null; + boolean searched = false; for (TreeNode p = root;;) { - int dir, ph; K pk; TreeNode q, pr; + int dir, ph; K pk; if (p == null) { first = root = new TreeNode(h, k, v, null, null); break; @@ -2820,21 +2851,25 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre else if ((kc == null && (kc = comparableClassFor(k)) == null) || (dir = compareComparables(kc, k, pk)) == 0) { - if (p.left == null) - dir = 1; - else if ((pr = p.right) == null || - (q = pr.findTreeNode(h, k, kc)) == null) - dir = -1; - else - return q; + if (!searched) { + TreeNode q, ch; + searched = true; + if (((ch = p.left) != null && + (q = ch.findTreeNode(h, k, kc)) != null) || + ((ch = p.right) != null && + (q = ch.findTreeNode(h, k, kc)) != null)) + return q; + } + dir = tieBreakOrder(k, pk); } + TreeNode xp = p; - if ((p = (dir < 0) ? p.left : p.right) == null) { + if ((p = (dir <= 0) ? p.left : p.right) == null) { TreeNode x, f = first; first = x = new TreeNode(h, k, v, f, xp); if (f != null) f.prev = x; - if (dir < 0) + if (dir <= 0) xp.left = x; else xp.right = x; @@ -3546,6 +3581,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * for an element, or null if there is no transformation (in * which case the action is not applied) * @param action the action + * @param the return type of the transformer * @since 1.8 */ public void forEach(long parallelismThreshold, @@ -3569,6 +3605,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * needed for this operation to be executed in parallel * @param searchFunction a function returning a non-null * result on success, else null + * @param the return type of the search function * @return a non-null result from applying the given search * function on each (key, value), or null if none * @since 1.8 @@ -3592,6 +3629,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * for an element, or null if there is no transformation (in * which case it is not combined) * @param reducer a commutative associative combining function + * @param the return type of the transformer * @return the result of accumulating the given transformation * of all (key, value) pairs * @since 1.8 @@ -3710,6 +3748,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * for an element, or null if there is no transformation (in * which case the action is not applied) * @param action the action + * @param the return type of the transformer * @since 1.8 */ public void forEachKey(long parallelismThreshold, @@ -3733,6 +3772,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * needed for this operation to be executed in parallel * @param searchFunction a function returning a non-null * result on success, else null + * @param the return type of the search function * @return a non-null result from applying the given search * function on each key, or null if none * @since 1.8 @@ -3775,6 +3815,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * for an element, or null if there is no transformation (in * which case it is not combined) * @param reducer a commutative associative combining function + * @param the return type of the transformer * @return the result of accumulating the given transformation * of all keys * @since 1.8 @@ -3894,6 +3935,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * for an element, or null if there is no transformation (in * which case the action is not applied) * @param action the action + * @param the return type of the transformer * @since 1.8 */ public void forEachValue(long parallelismThreshold, @@ -3917,6 +3959,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * needed for this operation to be executed in parallel * @param searchFunction a function returning a non-null * result on success, else null + * @param the return type of the search function * @return a non-null result from applying the given search * function on each value, or null if none * @since 1.8 @@ -3958,6 +4001,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * for an element, or null if there is no transformation (in * which case it is not combined) * @param reducer a commutative associative combining function + * @param the return type of the transformer * @return the result of accumulating the given transformation * of all values * @since 1.8 @@ -4075,6 +4119,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * for an element, or null if there is no transformation (in * which case the action is not applied) * @param action the action + * @param the return type of the transformer * @since 1.8 */ public void forEachEntry(long parallelismThreshold, @@ -4098,6 +4143,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * needed for this operation to be executed in parallel * @param searchFunction a function returning a non-null * result on success, else null + * @param the return type of the search function * @return a non-null result from applying the given search * function on each entry, or null if none * @since 1.8 @@ -4139,6 +4185,7 @@ public class ConcurrentHashMap extends AbstractMap implements Concurre * for an element, or null if there is no transformation (in * which case it is not combined) * @param reducer a commutative associative combining function + * @param the return type of the transformer * @return the result of accumulating the given transformation * of all entries * @since 1.8 diff --git a/jdk/src/share/classes/java/util/function/BiConsumer.java b/jdk/src/share/classes/java/util/function/BiConsumer.java index afc0ba34d1e..61690e6471a 100644 --- a/jdk/src/share/classes/java/util/function/BiConsumer.java +++ b/jdk/src/share/classes/java/util/function/BiConsumer.java @@ -27,13 +27,16 @@ package java.util.function; import java.util.Objects; /** - * An operation which accepts two input arguments and returns no result. This is - * the two-arity specialization of {@link Consumer}. Unlike most other - * functional interfaces, {@code BiConsumer} is expected to operate via - * side-effects. + * Represents an operation that accepts two input arguments and returns no + * result. This is the two-arity specialization of {@link Consumer}. + * Unlike most other functional interfaces, {@code BiConsumer} is expected + * to operate via side-effects. * - * @param the type of the first argument to the {@code accept} operation - * @param the type of the second argument to the {@code accept} operation + *

    This is a functional interface + * whose functional method is {@link #accept(Object, Object)}. + * + * @param the type of the first argument to the operation + * @param the type of the second argument to the operation * * @see Consumer * @since 1.8 @@ -42,35 +45,31 @@ import java.util.Objects; public interface BiConsumer { /** - * Performs operations upon the provided objects which may modify those - * objects and/or external state. + * Performs this operation on the given arguments. * - * @param t an input object - * @param u an input object + * @param t the first input argument + * @param u the second input argument */ void accept(T t, U u); /** - * Returns a {@code BiConsumer} which performs, in sequence, the operation - * represented by this object followed by the operation represented by - * the other {@code BiConsumer}. + * Returns a composed {@code BiConsumer} that performs, in sequence, this + * operation followed by the {@code after} operation. If performing either + * operation throws an exception, it is relayed to the caller of the + * composed operation. If performing this operation throws an exception, + * the {@code after} operation will not be performed. * - *

    Any exceptions thrown by either {@code accept} method are relayed - * to the caller; if performing this operation throws an exception, the - * other operation will not be performed. - * - * @param other a BiConsumer which will be chained after this BiConsumer - * @return a BiConsumer which performs in sequence the {@code accept} method - * of this BiConsumer and the {@code accept} method of the specified - * BiConsumer operation - * @throws NullPointerException if other is null + * @param after the operation to perform after this operation + * @return a composed {@code BiConsumer} that performs in sequence this + * operation followed by the {@code after} operation + * @throws NullPointerException if {@code after} is null */ - default BiConsumer chain(BiConsumer other) { - Objects.requireNonNull(other); + default BiConsumer andThen(BiConsumer after) { + Objects.requireNonNull(after); return (l, r) -> { accept(l, r); - other.accept(l, r); + after.accept(l, r); }; } } diff --git a/jdk/src/share/classes/java/util/function/BiFunction.java b/jdk/src/share/classes/java/util/function/BiFunction.java index fb66ec0e8bb..ef75901fb34 100644 --- a/jdk/src/share/classes/java/util/function/BiFunction.java +++ b/jdk/src/share/classes/java/util/function/BiFunction.java @@ -27,14 +27,15 @@ package java.util.function; import java.util.Objects; /** - * Apply a function to the input arguments, yielding an appropriate result. This - * is the two-arity specialization of {@link Function}. A function may - * variously provide a mapping between types, object instances or keys and - * values or any other form of transformation upon the input. + * Represents a function that accepts two arguments and produces a result. + * This is the two-arity specialization of {@link Function}. * - * @param the type of the first argument to the {@code apply} operation - * @param the type of the second argument to the {@code apply} operation - * @param the type of results returned by the {@code apply} operation + *

    This is a functional interface + * whose functional method is {@link #apply(Object, Object)}. + * + * @param the type of the first argument to the function + * @param the type of the second argument to the function + * @param the type of the result of the function * * @see Function * @since 1.8 @@ -43,25 +44,25 @@ import java.util.Objects; public interface BiFunction { /** - * Compute the result of applying the function to the input arguments + * Applies this function to the given arguments. * - * @param t an input object - * @param u an input object + * @param t the first function argument + * @param u the second function argument * @return the function result */ R apply(T t, U u); /** - * Returns a new function which applies this function followed by the - * provided function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed function that first applies this function to + * its input, and then applies the {@code after} function to the result. + * If evaluation of either function throws an exception, it is relayed to + * the caller of the composed function. * - * @param Type of output objects to the combined function. May be the - * same type as {@code }, {@code } or {@code } - * @param after An additional function to be applied after this function is - * applied - * @return A function which performs this function followed by the provided - * function + * @param the type of output of the {@code after} function, and of the + * composed function + * @param after the function to apply after this function is applied + * @return a composed function that first applies this function and then + * applies the {@code after} function * @throws NullPointerException if after is null */ default BiFunction andThen(Function after) { diff --git a/jdk/src/share/classes/java/util/function/BiPredicate.java b/jdk/src/share/classes/java/util/function/BiPredicate.java index 29e92b875f7..a0f19b812d0 100644 --- a/jdk/src/share/classes/java/util/function/BiPredicate.java +++ b/jdk/src/share/classes/java/util/function/BiPredicate.java @@ -27,11 +27,14 @@ package java.util.function; import java.util.Objects; /** - * Determines if the input objects match some criteria. This is the two-arity - * specialization of {@link Predicate}. + * Represents a predicate (boolean-valued function) of two arguments. This is + * the two-arity specialization of {@link Predicate}. * - * @param the type of the first argument to {@code test} - * @param the type of the second argument to {@code test} + *

    This is a functional interface + * whose functional method is {@link #test(Object, Object)}. + * + * @param the type of the first argument to the predicate + * @param the type of the second argument the predicate * * @see Predicate * @since 1.8 @@ -40,34 +43,41 @@ import java.util.Objects; public interface BiPredicate { /** - * Return {@code true} if the inputs match some criteria. + * Evaluates this predicate on the given arguments. * - * @param t an input object - * @param u an input object - * @return {@code true} if the inputs match some criteria + * @param t the first input argument + * @param u the second input argument + * @return {@code true} if the input arguments match the predicate, + * otherwise {@code false} */ boolean test(T t, U u); /** - * Returns a predicate which evaluates to {@code true} only if this - * predicate and the provided predicate both evaluate to {@code true}. If - * this predicate returns {@code false} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * AND of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code false}, then the {@code other} + * predicate is not evaluated. * - * @param p a predicate which will be logically-ANDed with this predicate - * @return a new predicate which returns {@code true} only if both - * predicates return {@code true} - * @throws NullPointerException if p is null + *

    Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. + * + * @param other a predicate that will be logically-ANDed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * AND of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default BiPredicate and(BiPredicate p) { - Objects.requireNonNull(p); - return (T t, U u) -> test(t, u) && p.test(t, u); + default BiPredicate and(BiPredicate other) { + Objects.requireNonNull(other); + return (T t, U u) -> test(t, u) && other.test(t, u); } /** - * Returns a predicate which negates the result of this predicate. + * Returns a predicate that represents the logical negation of this + * predicate. * - * @return a new predicate who's result is always the opposite of this + * @return a predicate that represents the logical negation of this * predicate */ default BiPredicate negate() { @@ -75,18 +85,23 @@ public interface BiPredicate { } /** - * Returns a predicate which evaluates to {@code true} if either this - * predicate or the provided predicate evaluates to {@code true}. If this - * predicate returns {@code true} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * OR of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code true}, then the {@code other} + * predicate is not evaluated. * - * @param p a predicate which will be logically-ORed with this predicate - * @return a new predicate which returns {@code true} if either predicate - * returns {@code true} - * @throws NullPointerException if p is null + *

    Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. + * + * @param other a predicate that will be logically-ORed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * OR of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default BiPredicate or(BiPredicate p) { - Objects.requireNonNull(p); - return (T t, U u) -> test(t, u) || p.test(t, u); + default BiPredicate or(BiPredicate other) { + Objects.requireNonNull(other); + return (T t, U u) -> test(t, u) || other.test(t, u); } } diff --git a/jdk/src/share/classes/java/util/function/BinaryOperator.java b/jdk/src/share/classes/java/util/function/BinaryOperator.java index 195eba1c3c1..a0150589c80 100644 --- a/jdk/src/share/classes/java/util/function/BinaryOperator.java +++ b/jdk/src/share/classes/java/util/function/BinaryOperator.java @@ -28,42 +28,48 @@ import java.util.Objects; import java.util.Comparator; /** - * An operation upon two operands yielding a result. This is a specialization of - * {@code BiFunction} where the operands and the result are all of the same type. + * Represents an operation upon two operands of the same type, producing a result + * of the same type as the operands. This is a specialization of + * {@link BiFunction} for the case where the operands and the result are all of + * the same type. * - * @param the type of operands to {@code apply} and of the result + *

    This is a functional interface + * whose functional method is {@link #apply(Object, Object)}. + * + * @param the type of the operands and result of the operator * * @see BiFunction + * @see UnaryOperator * @since 1.8 */ @FunctionalInterface public interface BinaryOperator extends BiFunction { /** * Returns a {@link BinaryOperator} which returns the lesser of two elements - * according to the specified {@code Comparator} + * according to the specified {@code Comparator}. * - * @param the type of values to be compared and returned - * @param comparator a {@code Comparator} for comparing the two values + * @param the type of the input arguments of the comparator + * @param comparator a {@code Comparator} for comparing the two values * @return a {@code BinaryOperator} which returns the lesser of its operands, * according to the supplied {@code Comparator} * @throws NullPointerException if the argument is null */ - public static BinaryOperator minBy(Comparator comparator) { + public static BinaryOperator minBy(Comparator comparator) { Objects.requireNonNull(comparator); return (a, b) -> comparator.compare(a, b) <= 0 ? a : b; } /** * Returns a {@link BinaryOperator} which returns the greater of two elements - * according to the specified {@code Comparator} + * according to the specified {@code Comparator}. * - * @param the type of values to be compared and returned - * @param comparator a {@code Comparator} for comparing the two values + * @param the type of the input arguments of the comparator + * @param comparator a {@code Comparator} for comparing the two values * @return a {@code BinaryOperator} which returns the greater of its operands, * according to the supplied {@code Comparator} * @throws NullPointerException if the argument is null */ - public static BinaryOperator maxBy(Comparator comparator) { + public static BinaryOperator maxBy(Comparator comparator) { Objects.requireNonNull(comparator); return (a, b) -> comparator.compare(a, b) >= 0 ? a : b; } diff --git a/jdk/src/share/classes/java/util/function/BooleanSupplier.java b/jdk/src/share/classes/java/util/function/BooleanSupplier.java index 875ac748628..2faff307e63 100644 --- a/jdk/src/share/classes/java/util/function/BooleanSupplier.java +++ b/jdk/src/share/classes/java/util/function/BooleanSupplier.java @@ -26,8 +26,14 @@ package java.util.function; /** - * A supplier of {@code boolean} values. This is the {@code boolean}-providing - * primitive specialization of {@link Supplier}. + * Represents a supplier of {@code boolean}-valued results. This is the + * {@code boolean}-producing primitive specialization of {@link Supplier}. + * + *

    There is no requirement that a new or distinct result be returned each + * time the supplier is invoked. + * + *

    This is a functional interface + * whose functional method is {@link #getAsBoolean()}. * * @see Supplier * @since 1.8 @@ -36,9 +42,9 @@ package java.util.function; public interface BooleanSupplier { /** - * Returns a {@code boolean} value. + * Gets a result. * - * @return a {@code boolean} value + * @return a result */ boolean getAsBoolean(); } diff --git a/jdk/src/share/classes/java/util/function/Consumer.java b/jdk/src/share/classes/java/util/function/Consumer.java index 69add851dcc..a2481fe4f41 100644 --- a/jdk/src/share/classes/java/util/function/Consumer.java +++ b/jdk/src/share/classes/java/util/function/Consumer.java @@ -27,11 +27,14 @@ package java.util.function; import java.util.Objects; /** - * An operation which accepts a single input argument and returns no result. - * Unlike most other functional interfaces, {@code Consumer} is expected to - * operate via side-effects. + * Represents an operation that accepts a single input argument and returns no + * result. Unlike most other functional interfaces, {@code Consumer} is expected + * to operate via side-effects. * - * @param The type of input objects to {@code accept} + *

    This is a functional interface + * whose functional method is {@link #accept(Object)}. + * + * @param the type of the input to the operation * * @since 1.8 */ @@ -39,29 +42,26 @@ import java.util.Objects; public interface Consumer { /** - * Accept an input value. + * Performs this operation on the given argument. * - * @param t the input object + * @param t the input argument */ void accept(T t); /** - * Returns a {@code Consumer} which performs, in sequence, the operation - * represented by this object followed by the operation represented by - * the other {@code Consumer}. + * Returns a composed {@code Consumer} that performs, in sequence, this + * operation followed by the {@code after} operation. If performing either + * operation throws an exception, it is relayed to the caller of the + * composed operation. If performing this operation throws an exception, + * the {@code after} operation will not be performed. * - *

    Any exceptions thrown by either {@code accept} method are relayed - * to the caller; if performing this operation throws an exception, the - * other operation will not be performed. - * - * @param other a Consumer which will be chained after this Consumer - * @return a Consumer which performs in sequence the {@code accept} method - * of this Consumer and the {@code accept} method of the specified Consumer - * operation - * @throws NullPointerException if other is null + * @param after the operation to perform after this operation + * @return a composed {@code Consumer} that performs in sequence this + * operation followed by the {@code after} operation + * @throws NullPointerException if {@code after} is null */ - default Consumer chain(Consumer other) { - Objects.requireNonNull(other); - return (T t) -> { accept(t); other.accept(t); }; + default Consumer andThen(Consumer after) { + Objects.requireNonNull(after); + return (T t) -> { accept(t); after.accept(t); }; } } diff --git a/jdk/src/share/classes/java/util/function/DoubleBinaryOperator.java b/jdk/src/share/classes/java/util/function/DoubleBinaryOperator.java index 7d1e68aaced..839433da573 100644 --- a/jdk/src/share/classes/java/util/function/DoubleBinaryOperator.java +++ b/jdk/src/share/classes/java/util/function/DoubleBinaryOperator.java @@ -25,23 +25,25 @@ package java.util.function; /** - * An operation on two {@code double} operands yielding a {@code double} result. - * This is the primitive type specialization of {@link BinaryOperator} for - * {@code double}. + * Represents an operation upon two {@code double}-valued operands and producing a + * {@code double}-valued result. This is the primitive type specialization of + * {@link BinaryOperator} for {@code double}. + * + *

    This is a functional interface + * whose functional method is {@link #applyAsDouble(double, double)}. * * @see BinaryOperator + * @see DoubleUnaryOperator * @since 1.8 */ @FunctionalInterface public interface DoubleBinaryOperator { /** - * Returns the {@code double} result of the operation upon the - * {@code double} operands. The parameters are named {@code left} and - * {@code right} for operations where the order of parameters matters. + * Applies this operator to the given operands. * - * @param left the left operand value - * @param right the right operand value - * @return the result of the operation + * @param left the first operand + * @param right the second operand + * @return the operator result */ double applyAsDouble(double left, double right); } diff --git a/jdk/src/share/classes/java/util/function/DoubleConsumer.java b/jdk/src/share/classes/java/util/function/DoubleConsumer.java index 665b80a3d20..046360c6da8 100644 --- a/jdk/src/share/classes/java/util/function/DoubleConsumer.java +++ b/jdk/src/share/classes/java/util/function/DoubleConsumer.java @@ -27,11 +27,14 @@ package java.util.function; import java.util.Objects; /** - * An operation which accepts a single double argument and returns no result. - * This is the primitive type specialization of {@link Consumer} for - * {@code double}. Unlike most other functional interfaces, + * Represents an operation that accepts a single {@code double}-valued argument and + * returns no result. This is the primitive type specialization of + * {@link Consumer} for {@code double}. Unlike most other functional interfaces, * {@code DoubleConsumer} is expected to operate via side-effects. * + *

    This is a functional interface + * whose functional method is {@link #accept(double)}. + * * @see Consumer * @since 1.8 */ @@ -39,30 +42,26 @@ import java.util.Objects; public interface DoubleConsumer { /** - * Accept an input value. + * Performs this operation on the given argument. * - * @param value the input value + * @param value the input argument */ void accept(double value); /** - * Returns a {@code DoubleConsumer} which performs, in sequence, the operation - * represented by this object followed by the operation represented by - * another {@code DoubleConsumer}. + * Returns a composed {@code DoubleConsumer} that performs, in sequence, this + * operation followed by the {@code after} operation. If performing either + * operation throws an exception, it is relayed to the caller of the + * composed operation. If performing this operation throws an exception, + * the {@code after} operation will not be performed. * - *

    Any exceptions thrown by either {@code accept} method are relayed - * to the caller; if performing this operation throws an exception, the - * other operation will not be performed. - * - * @param other a DoubleConsumer which will be chained after this - * DoubleConsumer - * @return an DoubleConsumer which performs in sequence the {@code accept} method - * of this DoubleConsumer and the {@code accept} method of the specified IntConsumer - * operation - * @throws NullPointerException if other is null + * @param after the operation to perform after this operation + * @return a composed {@code DoubleConsumer} that performs in sequence this + * operation followed by the {@code after} operation + * @throws NullPointerException if {@code after} is null */ - default DoubleConsumer chain(DoubleConsumer other) { - Objects.requireNonNull(other); - return (double t) -> { accept(t); other.accept(t); }; + default DoubleConsumer andThen(DoubleConsumer after) { + Objects.requireNonNull(after); + return (double t) -> { accept(t); after.accept(t); }; } } diff --git a/jdk/src/share/classes/java/util/function/DoubleFunction.java b/jdk/src/share/classes/java/util/function/DoubleFunction.java index d8141d0a8a2..a8bb57ddd88 100644 --- a/jdk/src/share/classes/java/util/function/DoubleFunction.java +++ b/jdk/src/share/classes/java/util/function/DoubleFunction.java @@ -25,11 +25,14 @@ package java.util.function; /** - * Apply a function to the double-valued input argument, yielding an appropriate - * result. This is the {@code double}-consuming primitive specialization for + * Represents a function that accepts a double-valued argument and produces a + * result. This is the {@code double}-consuming primitive specialization for * {@link Function}. * - * @param the type of output objects from the function + *

    This is a functional interface + * whose functional method is {@link #apply(double)}. + * + * @param the type of the result of the function * * @see Function * @since 1.8 @@ -38,9 +41,9 @@ package java.util.function; public interface DoubleFunction { /** - * Compute the result of applying the function to the input argument + * Applies this function to the given argument. * - * @param value the input value + * @param value the function argument * @return the function result */ R apply(double value); diff --git a/jdk/src/share/classes/java/util/function/DoublePredicate.java b/jdk/src/share/classes/java/util/function/DoublePredicate.java index 8156b65cb93..1df17624cab 100644 --- a/jdk/src/share/classes/java/util/function/DoublePredicate.java +++ b/jdk/src/share/classes/java/util/function/DoublePredicate.java @@ -27,9 +27,12 @@ package java.util.function; import java.util.Objects; /** - * Determines if the {@code double} input value matches some criteria. This is - * the {@code double}-consuming primitive type specialization of - * {@link Predicate}. + * Represents a predicate (boolean-valued function) of one {@code double}-valued + * argument. This is the {@code double}-consuming primitive type specialization + * of {@link Predicate}. + * + *

    This is a functional interface + * whose functional method is {@link #test(double)}. * * @see Predicate * @since 1.8 @@ -38,38 +41,40 @@ import java.util.Objects; public interface DoublePredicate { /** - * Returns {@code true} if the input value matches some criteria. + * Evaluates this predicate on the given argument. * - * @param value the value to be tested - * @return {@code true} if the input value matches some criteria, otherwise - * {@code false} + * @param value the input argument + * @return {@code true} if the input argument matches the predicate, + * otherwise {@code false} */ boolean test(double value); /** - * Returns a predicate which evaluates to {@code true} only if this - * predicate and the provided predicate both evaluate to {@code true}. If - * this predicate returns {@code false} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * AND of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code false}, then the {@code other} + * predicate is not evaluated. * - *

    Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + *

    Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ANDed with this predicate - * @return a new predicate which returns {@code true} only if both - * predicates return {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ANDed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * AND of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default DoublePredicate and(DoublePredicate p) { - Objects.requireNonNull(p); - return (value) -> test(value) && p.test(value); + default DoublePredicate and(DoublePredicate other) { + Objects.requireNonNull(other); + return (value) -> test(value) && other.test(value); } /** - * Returns a predicate which negates the result of this predicate. + * Returns a predicate that represents the logical negation of this + * predicate. * - * @return a new predicate who's result is always the opposite of this + * @return a predicate that represents the logical negation of this * predicate */ default DoublePredicate negate() { @@ -77,22 +82,23 @@ public interface DoublePredicate { } /** - * Returns a predicate which evaluates to {@code true} if either this - * predicate or the provided predicate evaluates to {@code true}. If this - * predicate returns {@code true} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * OR of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code true}, then the {@code other} + * predicate is not evaluated. * - *

    Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + *

    Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ANDed with this predicate - * @return a new predicate which returns {@code true} if either predicate - * returns {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ORed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * OR of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default DoublePredicate or(DoublePredicate p) { - Objects.requireNonNull(p); - return (value) -> test(value) || p.test(value); + default DoublePredicate or(DoublePredicate other) { + Objects.requireNonNull(other); + return (value) -> test(value) || other.test(value); } } diff --git a/jdk/src/share/classes/java/util/function/DoubleSupplier.java b/jdk/src/share/classes/java/util/function/DoubleSupplier.java index c661fdff927..5169011b3a5 100644 --- a/jdk/src/share/classes/java/util/function/DoubleSupplier.java +++ b/jdk/src/share/classes/java/util/function/DoubleSupplier.java @@ -25,8 +25,14 @@ package java.util.function; /** - * A supplier of {@code double} values. This is the {@code double}-providing - * primitive specialization of {@link Supplier}. + * Represents a supplier of {@code double}-valued results. This is the + * {@code double}-producing primitive specialization of {@link Supplier}. + * + *

    There is no requirement that a distinct result be returned each + * time the supplier is invoked. + * + *

    This is a functional interface + * whose functional method is {@link #getAsDouble()}. * * @see Supplier * @since 1.8 @@ -35,9 +41,9 @@ package java.util.function; public interface DoubleSupplier { /** - * Returns a {@code double} value. + * Gets a result. * - * @return a {@code double} value + * @return a result */ double getAsDouble(); } diff --git a/jdk/src/share/classes/java/util/function/DoubleToIntFunction.java b/jdk/src/share/classes/java/util/function/DoubleToIntFunction.java index 8eaf0b8374a..a23f033e4df 100644 --- a/jdk/src/share/classes/java/util/function/DoubleToIntFunction.java +++ b/jdk/src/share/classes/java/util/function/DoubleToIntFunction.java @@ -25,22 +25,24 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code double}-to-{@code int} specialization for {@link Function}. + * Represents a function that accepts a double-valued argument and produces an + * int-valued result. This is the {@code double}-to-{@code int} primitive + * specialization for {@link Function}. + * + *

    This is a functional interface + * whose functional method is {@link #applyAsInt(double)}. * * @see Function - * @see IntToDoubleFunction - * @see LongToIntFunction * @since 1.8 */ @FunctionalInterface public interface DoubleToIntFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param value the input value - * @return the function result value + * @param value the function argument + * @return the function result */ int applyAsInt(double value); } diff --git a/jdk/src/share/classes/java/util/function/DoubleToLongFunction.java b/jdk/src/share/classes/java/util/function/DoubleToLongFunction.java index 7568157353d..436369c6f48 100644 --- a/jdk/src/share/classes/java/util/function/DoubleToLongFunction.java +++ b/jdk/src/share/classes/java/util/function/DoubleToLongFunction.java @@ -25,22 +25,24 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code double}-to-{@code long} specialization for {@link Function}. + * Represents a function that accepts a double-valued argument and produces a + * long-valued result. This is the {@code double}-to-{@code long} primitive + * specialization for {@link Function}. + * + *

    This is a functional interface + * whose functional method is {@link #applyAsLong(double)}. * * @see Function - * @see LongToDoubleFunction - * @see IntToLongFunction * @since 1.8 */ @FunctionalInterface public interface DoubleToLongFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param value the input value - * @return the function result value + * @param value the function argument + * @return the function result */ long applyAsLong(double value); } diff --git a/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java b/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java index 39dfa6ab6a7..2f134c9994f 100644 --- a/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java +++ b/jdk/src/share/classes/java/util/function/DoubleUnaryOperator.java @@ -27,9 +27,12 @@ package java.util.function; import java.util.Objects; /** - * An operation on a {@code double} operand yielding a {@code double} - * result. This is the primitive type specialization of {@link UnaryOperator} - * for {@code double}. + * Represents an operation on a single {@code double}-valued operand that produces + * a {@code double}-valued result. This is the primitive type specialization of + * {@link UnaryOperator} for {@code double}. + * + *

    This is a functional interface + * whose functional method is {@link #applyAsDouble(double)}. * * @see UnaryOperator * @since 1.8 @@ -38,24 +41,25 @@ import java.util.Objects; public interface DoubleUnaryOperator { /** - * Returns the {@code double} result of the operation upon the - * {@code double} operand. + * Applies this operator to the given operand. * - * @param operand the operand value - * @return the operation result value + * @param operand the operand + * @return the operator result */ double applyAsDouble(double operand); /** - * Compose a new function which applies the provided function followed by - * this function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed operator that first applies the {@code before} + * operator to its input, and then applies this operator to the result. + * If evaluation of either operator throws an exception, it is relayed to + * the caller of the composed operator. * - * @param before An additional function to be applied before this function - * is applied - * @return A function which performs the provided function followed by this - * function + * @param before the operator to apply before this operator is applied + * @return a composed operator that first applies the {@code before} + * operator and then applies this operator * @throws NullPointerException if before is null + * + * @see #andThen(DoubleUnaryOperator) */ default DoubleUnaryOperator compose(DoubleUnaryOperator before) { Objects.requireNonNull(before); @@ -63,15 +67,17 @@ public interface DoubleUnaryOperator { } /** - * Compose a new function which applies this function followed by the - * provided function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed operator that first applies this operator to + * its input, and then applies the {@code after} operator to the result. + * If evaluation of either operator throws an exception, it is relayed to + * the caller of the composed operator. * - * @param after An additional function to be applied after this function is - * applied - * @return A function which performs this function followed by the provided - * function followed + * @param after the operator to apply after this operator is applied + * @return a composed operator that first applies this operator and then + * applies the {@code after} operator * @throws NullPointerException if after is null + * + * @see #compose(DoubleUnaryOperator) */ default DoubleUnaryOperator andThen(DoubleUnaryOperator after) { Objects.requireNonNull(after); @@ -79,9 +85,9 @@ public interface DoubleUnaryOperator { } /** - * Returns a unary operator that provides its input value as the result. + * Returns a unary operator that always returns its input argument. * - * @return a unary operator that provides its input value as the result + * @return a unary operator that always returns its input argument */ static DoubleUnaryOperator identity() { return t -> t; diff --git a/jdk/src/share/classes/java/util/function/Function.java b/jdk/src/share/classes/java/util/function/Function.java index 084ba4cc9c7..7bcbfd06bb6 100644 --- a/jdk/src/share/classes/java/util/function/Function.java +++ b/jdk/src/share/classes/java/util/function/Function.java @@ -27,12 +27,13 @@ package java.util.function; import java.util.Objects; /** - * Apply a function to the input argument, yielding an appropriate result. A - * function may variously provide a mapping between types, object instances or - * keys and values or any other form of transformation upon the input. + * Represents a function that accepts one argument and produces a result. * - * @param the type of the input to the {@code apply} operation - * @param the type of the result of the {@code apply} operation + *

    This is a functional interface + * whose functional method is {@link #apply(Object)}. + * + * @param the type of the input to the function + * @param the type of the result of the function * * @since 1.8 */ @@ -40,25 +41,27 @@ import java.util.Objects; public interface Function { /** - * Compute the result of applying the function to the input argument + * Applies this function to the given argument. * - * @param t the input object + * @param t the function argument * @return the function result */ R apply(T t); /** - * Returns a new function which applies the provided function followed by - * this function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed function that first applies the {@code before} + * function to its input, and then applies this function to the result. + * If evaluation of either function throws an exception, it is relayed to + * the caller of the composed function. * - * @param type of input objects to the combined function. May be the - * same type as {@code } or {@code } - * @param before an additional function to be applied before this function - * is applied - * @return a function which performs the provided function followed by this - * function + * @param the type of input to the {@code before} function, and to the + * composed function + * @param before the function to apply before this function is applied + * @return a composed function that first applies the {@code before} + * function and then applies this function * @throws NullPointerException if before is null + * + * @see #andThen(Function) */ default Function compose(Function before) { Objects.requireNonNull(before); @@ -66,17 +69,19 @@ public interface Function { } /** - * Returns a new function which applies this function followed by the - * provided function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed function that first applies this function to + * its input, and then applies the {@code after} function to the result. + * If evaluation of either function throws an exception, it is relayed to + * the caller of the composed function. * - * @param type of output objects to the combined function. May be the - * same type as {@code } or {@code } - * @param after an additional function to be applied after this function is - * applied - * @return a function which performs this function followed by the provided - * function + * @param the type of output of the {@code after} function, and of the + * composed function + * @param after the function to apply after this function is applied + * @return a composed function that first applies this function and then + * applies the {@code after} function * @throws NullPointerException if after is null + * + * @see #compose(Function) */ default Function andThen(Function after) { Objects.requireNonNull(after); @@ -84,10 +89,10 @@ public interface Function { } /** - * Returns a {@code Function} whose {@code apply} method returns its input. + * Returns a function that always returns its input argument. * * @param the type of the input and output objects to the function - * @return a {@code Function} whose {@code apply} method returns its input + * @return a function that always returns its input argument */ static Function identity() { return t -> t; diff --git a/jdk/src/share/classes/java/util/function/IntBinaryOperator.java b/jdk/src/share/classes/java/util/function/IntBinaryOperator.java index a0788a1d734..21bb9469ede 100644 --- a/jdk/src/share/classes/java/util/function/IntBinaryOperator.java +++ b/jdk/src/share/classes/java/util/function/IntBinaryOperator.java @@ -25,24 +25,26 @@ package java.util.function; /** - * An operation on two {@code int} operands yielding an {@code int} result. - * This is the primitive type specialization of {@link BinaryOperator} for - * {@code int}. + * Represents an operation upon two {@code int}-valued operands and producing an + * {@code int}-valued result. This is the primitive type specialization of + * {@link BinaryOperator} for {@code int}. + * + *

    This is a functional interface + * whose functional method is {@link #applyAsInt(int, int)}. * * @see BinaryOperator + * @see IntUnaryOperator * @since 1.8 */ @FunctionalInterface public interface IntBinaryOperator { /** - * Returns the {@code int} result of the operation upon the {@code int} - * operands. The parameters are named {@code left} and {@code right} for - * operations where the order of parameters matters. + * Applies this operator to the given operands. * - * @param left the left operand value - * @param right the right operand value - * @return the result of the operation + * @param left the first operand + * @param right the second operand + * @return the operator result */ int applyAsInt(int left, int right); } diff --git a/jdk/src/share/classes/java/util/function/IntConsumer.java b/jdk/src/share/classes/java/util/function/IntConsumer.java index 3c2a770332f..d8daf73ca2c 100644 --- a/jdk/src/share/classes/java/util/function/IntConsumer.java +++ b/jdk/src/share/classes/java/util/function/IntConsumer.java @@ -27,10 +27,13 @@ package java.util.function; import java.util.Objects; /** - * An operation which accepts a single integer argument and returns no result. - * This is the primitive type specialization of {@link Consumer} for {@code int}. - * Unlike most other functional interfaces, {@code IntConsumer} is expected to - * operate via side-effects. + * Represents an operation that accepts a single {@code int}-valued argument and + * returns no result. This is the primitive type specialization of + * {@link Consumer} for {@code int}. Unlike most other functional interfaces, + * {@code IntConsumer} is expected to operate via side-effects. + * + *

    This is a functional interface + * whose functional method is {@link #accept(int)}. * * @see Consumer * @since 1.8 @@ -39,30 +42,26 @@ import java.util.Objects; public interface IntConsumer { /** - * Accept an input value. + * Performs this operation on the given argument. * - * @param value the input value + * @param value the input argument */ void accept(int value); /** - * Returns an {@code IntConsumer} which performs, in sequence, the operation - * represented by this object followed by the operation represented by - * another {@code IntConsumer}. + * Returns a composed {@code IntConsumer} that performs, in sequence, this + * operation followed by the {@code after} operation. If performing either + * operation throws an exception, it is relayed to the caller of the + * composed operation. If performing this operation throws an exception, + * the {@code after} operation will not be performed. * - *

    Any exceptions thrown by either {@code accept} method are relayed - * to the caller; if performing this operation throws an exception, the - * other operation will not be performed. - * - * @param other an IntConsumer which will be chained after this - * IntConsumer - * @return an IntConsumer which performs in sequence the {@code accept} method - * of this IntConsumer and the {@code accept} method of the specified IntConsumer - * operation - * @throws NullPointerException if other is null + * @param after the operation to perform after this operation + * @return a composed {@code IntConsumer} that performs in sequence this + * operation followed by the {@code after} operation + * @throws NullPointerException if {@code after} is null */ - default IntConsumer chain(IntConsumer other) { - Objects.requireNonNull(other); - return (int t) -> { accept(t); other.accept(t); }; + default IntConsumer andThen(IntConsumer after) { + Objects.requireNonNull(after); + return (int t) -> { accept(t); after.accept(t); }; } } diff --git a/jdk/src/share/classes/java/util/function/IntFunction.java b/jdk/src/share/classes/java/util/function/IntFunction.java index ec2ffcae249..de10df499e1 100644 --- a/jdk/src/share/classes/java/util/function/IntFunction.java +++ b/jdk/src/share/classes/java/util/function/IntFunction.java @@ -25,11 +25,14 @@ package java.util.function; /** - * Apply a function to the integer-valued input argument, yielding an - * appropriate result. This is the {@code int}-consuming primitive - * specialization for {@link Function}. + * Represents a function that accepts an int-valued argument and produces a + * result. This is the {@code int}-consuming primitive specialization for + * {@link Function}. * - * @param the type of output objects from the function + *

    This is a functional interface + * whose functional method is {@link #apply(int)}. + * + * @param the type of the result of the function * * @see Function * @since 1.8 @@ -38,9 +41,9 @@ package java.util.function; public interface IntFunction { /** - * Compute the result of applying the function to the input argument + * Applies this function to the given argument. * - * @param value the input value + * @param value the function argument * @return the function result */ R apply(int value); diff --git a/jdk/src/share/classes/java/util/function/IntPredicate.java b/jdk/src/share/classes/java/util/function/IntPredicate.java index 0e7ec0737d5..5a9bd46dd70 100644 --- a/jdk/src/share/classes/java/util/function/IntPredicate.java +++ b/jdk/src/share/classes/java/util/function/IntPredicate.java @@ -27,8 +27,12 @@ package java.util.function; import java.util.Objects; /** - * Determines if the {@code int} input value matches some criteria. This is the - * {@code int}-consuming primitive type specialization of {@link Predicate}. + * Represents a predicate (boolean-valued function) of one {@code int}-valued + * argument. This is the {@code int}-consuming primitive type specialization of + * {@link Predicate}. + * + *

    This is a functional interface + * whose functional method is {@link #test(int)}. * * @see Predicate * @since 1.8 @@ -37,38 +41,40 @@ import java.util.Objects; public interface IntPredicate { /** - * Returns {@code true} if the input value matches some criteria. + * Evaluates this predicate on the given argument. * - * @param value the value to be tested - * @return {@code true} if the input value matches some criteria, otherwise - * {@code false} + * @param value the input argument + * @return {@code true} if the input argument matches the predicate, + * otherwise {@code false} */ boolean test(int value); /** - * Returns a predicate which evaluates to {@code true} only if this - * predicate and the provided predicate both evaluate to {@code true}. If - * this predicate returns {@code false} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * AND of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code false}, then the {@code other} + * predicate is not evaluated. * - *

    Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + *

    Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ANDed with this predicate - * @return a new predicate which returns {@code true} only if both - * predicates return {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ANDed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * AND of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default IntPredicate and(IntPredicate p) { - Objects.requireNonNull(p); - return (value) -> test(value) && p.test(value); + default IntPredicate and(IntPredicate other) { + Objects.requireNonNull(other); + return (value) -> test(value) && other.test(value); } /** - * Returns a predicate which negates the result of this predicate. + * Returns a predicate that represents the logical negation of this + * predicate. * - * @return a new predicate who's result is always the opposite of this + * @return a predicate that represents the logical negation of this * predicate */ default IntPredicate negate() { @@ -76,22 +82,23 @@ public interface IntPredicate { } /** - * Returns a predicate which evaluates to {@code true} if either this - * predicate or the provided predicate evaluates to {@code true}. If this - * predicate returns {@code true} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * OR of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code true}, then the {@code other} + * predicate is not evaluated. * - *

    Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + *

    Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ORed with this predicate - * @return a new predicate which returns {@code true} if either predicate - * returns {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ORed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * OR of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default IntPredicate or(IntPredicate p) { - Objects.requireNonNull(p); - return (value) -> test(value) || p.test(value); + default IntPredicate or(IntPredicate other) { + Objects.requireNonNull(other); + return (value) -> test(value) || other.test(value); } } diff --git a/jdk/src/share/classes/java/util/function/IntSupplier.java b/jdk/src/share/classes/java/util/function/IntSupplier.java index 3165d3f4061..89489c59bac 100644 --- a/jdk/src/share/classes/java/util/function/IntSupplier.java +++ b/jdk/src/share/classes/java/util/function/IntSupplier.java @@ -25,8 +25,14 @@ package java.util.function; /** - * A supplier of {@code int} values. This is the {@code int}-providing - * primitive specialization of {@link Supplier}. + * Represents a supplier of {@code int}-valued results. This is the + * {@code int}-producing primitive specialization of {@link Supplier}. + * + *

    There is no requirement that a distinct result be returned each + * time the supplier is invoked. + * + *

    This is a functional interface + * whose functional method is {@link #getAsInt()}. * * @see Supplier * @since 1.8 @@ -35,9 +41,9 @@ package java.util.function; public interface IntSupplier { /** - * Returns an {@code int} value. + * Gets a result. * - * @return an {@code int} value + * @return a result */ int getAsInt(); } diff --git a/jdk/src/share/classes/java/util/function/IntToDoubleFunction.java b/jdk/src/share/classes/java/util/function/IntToDoubleFunction.java index 773164d4c96..5012154c2a0 100644 --- a/jdk/src/share/classes/java/util/function/IntToDoubleFunction.java +++ b/jdk/src/share/classes/java/util/function/IntToDoubleFunction.java @@ -25,22 +25,24 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code int}-to-{@code double} specialization for {@link Function}. + * Represents a function that accepts an int-valued argument and produces a + * double-valued result. This is the {@code int}-to-{@code double} primitive + * specialization for {@link Function}. + * + *

    This is a functional interface + * whose functional method is {@link #applyAsDouble(int)}. * * @see Function - * @see DoubleToIntFunction - * @see LongToDoubleFunction * @since 1.8 */ @FunctionalInterface public interface IntToDoubleFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param value the input value - * @return the function result value + * @param value the function argument + * @return the function result */ double applyAsDouble(int value); } diff --git a/jdk/src/share/classes/java/util/function/IntToLongFunction.java b/jdk/src/share/classes/java/util/function/IntToLongFunction.java index c50b20fc8c8..6c52faa7009 100644 --- a/jdk/src/share/classes/java/util/function/IntToLongFunction.java +++ b/jdk/src/share/classes/java/util/function/IntToLongFunction.java @@ -25,22 +25,24 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code int}-to-{@code long} specialization for {@link Function}. + * Represents a function that accepts an int-valued argument and produces a + * long-valued result. This is the {@code int}-to-{@code long} primitive + * specialization for {@link Function}. + * + *

    This is a functional interface + * whose functional method is {@link #applyAsLong(int)}. * * @see Function - * @see LongToIntFunction - * @see DoubleToLongFunction * @since 1.8 */ @FunctionalInterface public interface IntToLongFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param value the input value - * @return the function result value + * @param value the function argument + * @return the function result */ long applyAsLong(int value); } diff --git a/jdk/src/share/classes/java/util/function/IntUnaryOperator.java b/jdk/src/share/classes/java/util/function/IntUnaryOperator.java index 2e14c151b1f..300fc14666a 100644 --- a/jdk/src/share/classes/java/util/function/IntUnaryOperator.java +++ b/jdk/src/share/classes/java/util/function/IntUnaryOperator.java @@ -27,9 +27,12 @@ package java.util.function; import java.util.Objects; /** - * An operation on a single {@code int} operand yielding an {@code int} result. - * This is the primitive type specialization of {@link UnaryOperator} for - * {@code int}. + * Represents an operation on a single {@code int}-valued operand that produces + * an {@code int}-valued result. This is the primitive type specialization of + * {@link UnaryOperator} for {@code int}. + * + *

    This is a functional interface + * whose functional method is {@link #applyAsInt(int)}. * * @see UnaryOperator * @since 1.8 @@ -38,24 +41,25 @@ import java.util.Objects; public interface IntUnaryOperator { /** - * Returns the {@code int} value result of the operation upon the - * {@code int} operand. + * Applies this operator to the given operand. * - * @param operand the operand value - * @return the operation result value + * @param operand the operand + * @return the operator result */ int applyAsInt(int operand); /** - * Compose a new function which applies the provided function followed by - * this function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed operator that first applies the {@code before} + * operator to its input, and then applies this operator to the result. + * If evaluation of either operator throws an exception, it is relayed to + * the caller of the composed operator. * - * @param before an additional function to be applied before this function - * is applied - * @return a function which performs the provided function followed by this - * function + * @param before the operator to apply before this operator is applied + * @return a composed operator that first applies the {@code before} + * operator and then applies this operator * @throws NullPointerException if before is null + * + * @see #andThen(IntUnaryOperator) */ default IntUnaryOperator compose(IntUnaryOperator before) { Objects.requireNonNull(before); @@ -63,15 +67,17 @@ public interface IntUnaryOperator { } /** - * Compose a new function which applies this function followed by the - * provided function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed operator that first applies this operator to + * its input, and then applies the {@code after} operator to the result. + * If evaluation of either operator throws an exception, it is relayed to + * the caller of the composed operator. * - * @param after an additional function to be applied after this function is - * applied - * @return a function which performs this function followed by the provided - * function followed + * @param after the operator to apply after this operator is applied + * @return a composed operator that first applies this operator and then + * applies the {@code after} operator * @throws NullPointerException if after is null + * + * @see #compose(IntUnaryOperator) */ default IntUnaryOperator andThen(IntUnaryOperator after) { Objects.requireNonNull(after); @@ -79,9 +85,9 @@ public interface IntUnaryOperator { } /** - * Returns a unary operator that provides its input value as the result. + * Returns a unary operator that always returns its input argument. * - * @return a unary operator that provides its input value as the result + * @return a unary operator that always returns its input argument */ static IntUnaryOperator identity() { return t -> t; diff --git a/jdk/src/share/classes/java/util/function/LongBinaryOperator.java b/jdk/src/share/classes/java/util/function/LongBinaryOperator.java index f35258bea60..287481e4e34 100644 --- a/jdk/src/share/classes/java/util/function/LongBinaryOperator.java +++ b/jdk/src/share/classes/java/util/function/LongBinaryOperator.java @@ -25,24 +25,26 @@ package java.util.function; /** - * An operation on two {@code long} operands yielding a {@code long} result. - * This is the primitive type specialization of {@link BinaryOperator} for - * {@code long}. + * Represents an operation upon two {@code long}-valued operands and producing a + * {@code long}-valued result. This is the primitive type specialization of + * {@link BinaryOperator} for {@code long}. + * + *

    This is a functional interface + * whose functional method is {@link #applyAsLong(long, long)}. * * @see BinaryOperator + * @see LongUnaryOperator * @since 1.8 */ @FunctionalInterface public interface LongBinaryOperator { /** - * Returns the {@code long} result of the operation upon the {@code long} - * operands. The parameters are named {@code left} and {@code right} for - * operations where the order of parameters matters. + * Applies this operator to the given operands. * - * @param left the left operand value - * @param right the right operand value - * @return the result of the operation + * @param left the first operand + * @param right the second operand + * @return the operator result */ long applyAsLong(long left, long right); } diff --git a/jdk/src/share/classes/java/util/function/LongConsumer.java b/jdk/src/share/classes/java/util/function/LongConsumer.java index 754af39d918..b59d0303f91 100644 --- a/jdk/src/share/classes/java/util/function/LongConsumer.java +++ b/jdk/src/share/classes/java/util/function/LongConsumer.java @@ -27,10 +27,13 @@ package java.util.function; import java.util.Objects; /** - * An operation which accepts a single long argument and returns no result. - * This is the {@code long}-consuming primitive type specialization of - * {@link Consumer}. Unlike most other functional interfaces, {@code LongConsumer} - * is expected to operate via side-effects. + * Represents an operation that accepts a single {@code long}-valued argument and + * returns no result. This is the primitive type specialization of + * {@link Consumer} for {@code long}. Unlike most other functional interfaces, + * {@code LongConsumer} is expected to operate via side-effects. + * + *

    This is a functional interface + * whose functional method is {@link #accept(long)}. * * @see Consumer * @since 1.8 @@ -39,30 +42,26 @@ import java.util.Objects; public interface LongConsumer { /** - * Accept an input value. + * Performs this operation on the given argument. * - * @param value the input value + * @param value the input argument */ void accept(long value); /** - * Returns a {@code LongConsumer} which performs, in sequence, the operation - * represented by this object followed by the operation represented by - * another {@code LongConsumer}. + * Returns a composed {@code LongConsumer} that performs, in sequence, this + * operation followed by the {@code after} operation. If performing either + * operation throws an exception, it is relayed to the caller of the + * composed operation. If performing this operation throws an exception, + * the {@code after} operation will not be performed. * - *

    Any exceptions thrown by either {@code accept} method are relayed - * to the caller; if performing this operation throws an exception, the - * other operation will not be performed. - * - * @param other a LongConsumer which will be chained after this - * LongConsumer - * @return a LongConsumer which performs in sequence the {@code accept} method - * of this LongConsumer and the {@code accept} method of the specified LongConsumer - * operation - * @throws NullPointerException if other is null + * @param after the operation to perform after this operation + * @return a composed {@code LongConsumer} that performs in sequence this + * operation followed by the {@code after} operation + * @throws NullPointerException if {@code after} is null */ - default LongConsumer chain(LongConsumer other) { - Objects.requireNonNull(other); - return (long t) -> { accept(t); other.accept(t); }; + default LongConsumer andThen(LongConsumer after) { + Objects.requireNonNull(after); + return (long t) -> { accept(t); after.accept(t); }; } } diff --git a/jdk/src/share/classes/java/util/function/LongFunction.java b/jdk/src/share/classes/java/util/function/LongFunction.java index d87f22ab7e9..2030c04e422 100644 --- a/jdk/src/share/classes/java/util/function/LongFunction.java +++ b/jdk/src/share/classes/java/util/function/LongFunction.java @@ -25,11 +25,14 @@ package java.util.function; /** - * Apply a function to the long-valued input argument, yielding an appropriate - * result. This is the {@code long}-consuming primitive specialization for + * Represents a function that accepts a long-valued argument and produces a + * result. This is the {@code long}-consuming primitive specialization for * {@link Function}. * - * @param the type of output objects from the function + *

    This is a functional interface + * whose functional method is {@link #apply(long)}. + * + * @param the type of the result of the function * * @see Function * @since 1.8 @@ -38,9 +41,9 @@ package java.util.function; public interface LongFunction { /** - * Compute the result of applying the function to the input argument + * Applies this function to the given argument. * - * @param value the input value + * @param value the function argument * @return the function result */ R apply(long value); diff --git a/jdk/src/share/classes/java/util/function/LongPredicate.java b/jdk/src/share/classes/java/util/function/LongPredicate.java index 1a28708ea45..5afdd41ef1d 100644 --- a/jdk/src/share/classes/java/util/function/LongPredicate.java +++ b/jdk/src/share/classes/java/util/function/LongPredicate.java @@ -27,8 +27,12 @@ package java.util.function; import java.util.Objects; /** - * Determines if the {@code long} input value matches some criteria. This is the - * {@code long}-consuming primitive type specialization of {@link Predicate}. + * Represents a predicate (boolean-valued function) of one {@code long}-valued + * argument. This is the {@code long}-consuming primitive type specialization of + * {@link Predicate}. + * + *

    This is a functional interface + * whose functional method is {@link #test(long)}. * * @see Predicate * @since 1.8 @@ -37,37 +41,40 @@ import java.util.Objects; public interface LongPredicate { /** - * Returns {@code true} if the input value matches some criteria. + * Evaluates this predicate on the given argument. * - * @param value the value to be tested - * @return {@code true} if the input value matches some criteria, otherwise - * {@code false} + * @param value the input argument + * @return {@code true} if the input argument matches the predicate, + * otherwise {@code false} */ boolean test(long value); /** - * Returns a predicate which evaluates to {@code true} only if this - * predicate and the provided predicate both evaluate to {@code true}. If - * this predicate returns {@code false} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * AND of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code false}, then the {@code other} + * predicate is not evaluated. * - *

    Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + *

    Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ANDed with this predicate - * @return a new predicate which returns {@code true} only if both - * predicates return {@code true} + * @param other a predicate that will be logically-ANDed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * AND of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default LongPredicate and(LongPredicate p) { - Objects.requireNonNull(p); - return (value) -> test(value) && p.test(value); + default LongPredicate and(LongPredicate other) { + Objects.requireNonNull(other); + return (value) -> test(value) && other.test(value); } /** - * Returns a predicate which negates the result of this predicate. + * Returns a predicate that represents the logical negation of this + * predicate. * - * @return a new predicate who's result is always the opposite of this + * @return a predicate that represents the logical negation of this * predicate */ default LongPredicate negate() { @@ -75,22 +82,23 @@ public interface LongPredicate { } /** - * Returns a predicate which evaluates to {@code true} if either this - * predicate or the provided predicate evaluates to {@code true}. If this - * predicate returns {@code true} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * OR of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code true}, then the {@code other} + * predicate is not evaluated. * - *

    Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + *

    Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ORed with this predicate - * @return a new predicate which returns {@code true} if either predicate - * returns {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ORed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * OR of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default LongPredicate or(LongPredicate p) { - Objects.requireNonNull(p); - return (value) -> test(value) || p.test(value); + default LongPredicate or(LongPredicate other) { + Objects.requireNonNull(other); + return (value) -> test(value) || other.test(value); } } diff --git a/jdk/src/share/classes/java/util/function/LongSupplier.java b/jdk/src/share/classes/java/util/function/LongSupplier.java index d88c399a790..513d9062e94 100644 --- a/jdk/src/share/classes/java/util/function/LongSupplier.java +++ b/jdk/src/share/classes/java/util/function/LongSupplier.java @@ -25,8 +25,14 @@ package java.util.function; /** - * A supplier of {@code long} values. This is the {@code long}-providing - * primitive specialization of {@link Supplier}. + * Represents a supplier of {@code long}-valued results. This is the + * {@code long}-producing primitive specialization of {@link Supplier}. + * + *

    There is no requirement that a distinct result be returned each + * time the supplier is invoked. + * + *

    This is a functional interface + * whose functional method is {@link #getAsLong()}. * * @see Supplier * @since 1.8 @@ -35,9 +41,9 @@ package java.util.function; public interface LongSupplier { /** - * Returns a {@code long} value. + * Gets a result. * - * @return a {@code long} value + * @return a result */ long getAsLong(); } diff --git a/jdk/src/share/classes/java/util/function/LongToDoubleFunction.java b/jdk/src/share/classes/java/util/function/LongToDoubleFunction.java index 718021cc9a8..9d0831f35ec 100644 --- a/jdk/src/share/classes/java/util/function/LongToDoubleFunction.java +++ b/jdk/src/share/classes/java/util/function/LongToDoubleFunction.java @@ -25,22 +25,24 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code long}-to-{@code double} specialization for {@link Function}. + * Represents a function that accepts a long-valued argument and produces a + * double-valued result. This is the {@code long}-to-{@code double} primitive + * specialization for {@link Function}. + * + *

    This is a functional interface + * whose functional method is {@link #applyAsDouble(long)}. * * @see Function - * @see DoubleToLongFunction - * @see IntToDoubleFunction * @since 1.8 */ @FunctionalInterface public interface LongToDoubleFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param value the input value - * @return the function result value + * @param value the function argument + * @return the function result */ double applyAsDouble(long value); } diff --git a/jdk/src/share/classes/java/util/function/LongToIntFunction.java b/jdk/src/share/classes/java/util/function/LongToIntFunction.java index e5dc6ba3d0d..d1d6c347054 100644 --- a/jdk/src/share/classes/java/util/function/LongToIntFunction.java +++ b/jdk/src/share/classes/java/util/function/LongToIntFunction.java @@ -25,22 +25,24 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code long}-to-{@code int} specialization for {@link Function}. + * Represents a function that accepts a long-valued argument and produces an + * int-valued result. This is the {@code long}-to-{@code int} primitive + * specialization for {@link Function}. + * + *

    This is a functional interface + * whose functional method is {@link #applyAsInt(long)}. * * @see Function - * @see IntToLongFunction - * @see DoubleToIntFunction * @since 1.8 */ @FunctionalInterface public interface LongToIntFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param value the input value - * @return the function result value + * @param value the function argument + * @return the function result */ int applyAsInt(long value); } diff --git a/jdk/src/share/classes/java/util/function/LongUnaryOperator.java b/jdk/src/share/classes/java/util/function/LongUnaryOperator.java index a32918fc56b..e2bbdddbfc9 100644 --- a/jdk/src/share/classes/java/util/function/LongUnaryOperator.java +++ b/jdk/src/share/classes/java/util/function/LongUnaryOperator.java @@ -27,9 +27,12 @@ package java.util.function; import java.util.Objects; /** - * An operation on a single {@code long} operand yielding a {@code long} result. - * This is the primitive type specialization of {@link UnaryOperator} for - * {@code long}. + * Represents an operation on a single {@code long}-valued operand that produces + * a {@code long}-valued result. This is the primitive type specialization of + * {@link UnaryOperator} for {@code long}. + * + *

    This is a functional interface + * whose functional method is {@link #applyAsLong(long)}. * * @see UnaryOperator * @since 1.8 @@ -38,24 +41,25 @@ import java.util.Objects; public interface LongUnaryOperator { /** - * Returns the {@code long} result of the operation upon the {@code long} - * operand. + * Applies this operator to the given operand. * - * @param operand the operand value - * @return the operation result value + * @param operand the operand + * @return the operator result */ long applyAsLong(long operand); /** - * Compose a new function which applies the provided function followed by - * this function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed operator that first applies the {@code before} + * operator to its input, and then applies this operator to the result. + * If evaluation of either operator throws an exception, it is relayed to + * the caller of the composed operator. * - * @param before An additional function to be applied before this function - * is applied - * @return A function which performs the provided function followed by this - * function + * @param before the operator to apply before this operator is applied + * @return a composed operator that first applies the {@code before} + * operator and then applies this operator * @throws NullPointerException if before is null + * + * @see #andThen(LongUnaryOperator) */ default LongUnaryOperator compose(LongUnaryOperator before) { Objects.requireNonNull(before); @@ -63,15 +67,17 @@ public interface LongUnaryOperator { } /** - * Compose a new function which applies this function followed by the - * provided function. If either function throws an exception, it is relayed - * to the caller. + * Returns a composed operator that first applies this operator to + * its input, and then applies the {@code after} operator to the result. + * If evaluation of either operator throws an exception, it is relayed to + * the caller of the composed operator. * - * @param after An additional function to be applied after this function is - * applied - * @return A function which performs this function followed by the provided - * function followed + * @param after the operator to apply after this operator is applied + * @return a composed operator that first applies this operator and then + * applies the {@code after} operator * @throws NullPointerException if after is null + * + * @see #compose(LongUnaryOperator) */ default LongUnaryOperator andThen(LongUnaryOperator after) { Objects.requireNonNull(after); @@ -79,9 +85,9 @@ public interface LongUnaryOperator { } /** - * Returns a unary operator that provides its input value as the result. + * Returns a unary operator that always returns its input argument. * - * @return a unary operator that provides its input value as the result + * @return a unary operator that always returns its input argument */ static LongUnaryOperator identity() { return t -> t; diff --git a/jdk/src/share/classes/java/util/function/ObjDoubleConsumer.java b/jdk/src/share/classes/java/util/function/ObjDoubleConsumer.java index dd8c0c9cf99..d551fc7bf00 100644 --- a/jdk/src/share/classes/java/util/function/ObjDoubleConsumer.java +++ b/jdk/src/share/classes/java/util/function/ObjDoubleConsumer.java @@ -25,12 +25,16 @@ package java.util.function; /** - * An operation which accepts an object reference and a double, and returns no - * result. This is the {@code (reference, double)} specialization of - * {@link BiConsumer}. Unlike most other functional interfaces, - * {@code ObjDoubleConsumer} is expected to operate via side-effects. + * Represents an operation that accepts an object-valued and a + * {@code double}-valued argument, and returns no result. This is the + * {@code (reference, double)} specialization of {@link BiConsumer}. + * Unlike most other functional interfaces, {@code ObjDoubleConsumer} is + * expected to operate via side-effects. * - * @param Type of reference argument to {@code accept()}. + *

    This is a functional interface + * whose functional method is {@link #accept(Object, double)}. + * + * @param the type of the object argument to the operation * * @see BiConsumer * @since 1.8 @@ -39,10 +43,10 @@ package java.util.function; public interface ObjDoubleConsumer { /** - * Accept a set of input values. + * Performs this operation on the given arguments. * - * @param t an input object - * @param value an input value + * @param t the first input argument + * @param value the second input argument */ void accept(T t, double value); } diff --git a/jdk/src/share/classes/java/util/function/ObjIntConsumer.java b/jdk/src/share/classes/java/util/function/ObjIntConsumer.java index 3ab4d5eef05..2eb32d63ec4 100644 --- a/jdk/src/share/classes/java/util/function/ObjIntConsumer.java +++ b/jdk/src/share/classes/java/util/function/ObjIntConsumer.java @@ -25,12 +25,16 @@ package java.util.function; /** - * An operation which accepts an object reference and an int, and returns no - * result. This is the {@code (reference, int)} specialization of - * {@link BiConsumer}. Unlike most other functional interfaces, - * {@code ObjIntConsumer} is expected to operate via side-effects. + * Represents an operation that accepts an object-valued and a + * {@code int}-valued argument, and returns no result. This is the + * {@code (reference, int)} specialization of {@link BiConsumer}. + * Unlike most other functional interfaces, {@code ObjIntConsumer} is + * expected to operate via side-effects. * - * @param Type of reference argument to {@code accept()} + *

    This is a functional interface + * whose functional method is {@link #accept(Object, int)}. + * + * @param the type of the object argument to the operation * * @see BiConsumer * @since 1.8 @@ -39,10 +43,10 @@ package java.util.function; public interface ObjIntConsumer { /** - * Accept a set of input values. + * Performs this operation on the given arguments. * - * @param t an input object - * @param value an input value + * @param t the first input argument + * @param value the second input argument */ void accept(T t, int value); } diff --git a/jdk/src/share/classes/java/util/function/ObjLongConsumer.java b/jdk/src/share/classes/java/util/function/ObjLongConsumer.java index f90a4f84c77..f40eea2c0f8 100644 --- a/jdk/src/share/classes/java/util/function/ObjLongConsumer.java +++ b/jdk/src/share/classes/java/util/function/ObjLongConsumer.java @@ -25,12 +25,16 @@ package java.util.function; /** - * An operation which accepts an object reference and a long, and returns no - * result. This is the {@code (reference, long)} specialization of - * {@link BiConsumer}. Unlike most other functional interfaces, - * {@code ObjLongConsumer} is expected to operate via side-effects. + * Represents an operation that accepts an object-valued and a + * {@code long}-valued argument, and returns no result. This is the + * {@code (reference, long)} specialization of {@link BiConsumer}. + * Unlike most other functional interfaces, {@code ObjLongConsumer} is + * expected to operate via side-effects. * - * @param Type of reference argument to {@code accept()} + *

    This is a functional interface + * whose functional method is {@link #accept(Object, long)}. + * + * @param the type of the object argument to the operation * * @see BiConsumer * @since 1.8 @@ -39,10 +43,10 @@ package java.util.function; public interface ObjLongConsumer { /** - * Accept a set of input values. + * Performs this operation on the given arguments. * - * @param t an input object - * @param value an input value + * @param t the first input argument + * @param value the second input argument */ void accept(T t, long value); } diff --git a/jdk/src/share/classes/java/util/function/Predicate.java b/jdk/src/share/classes/java/util/function/Predicate.java index ac207a3d593..e2f448b1674 100644 --- a/jdk/src/share/classes/java/util/function/Predicate.java +++ b/jdk/src/share/classes/java/util/function/Predicate.java @@ -27,9 +27,12 @@ package java.util.function; import java.util.Objects; /** - * Determines if the input object matches some criteria. + * Represents a predicate (boolean-valued function) of one argument. * - * @param the type of argument to {@code test} + *

    This is a functional interface + * whose functional method is {@link #test(Object)}. + * + * @param the type of the input to the predicate * * @since 1.8 */ @@ -37,76 +40,80 @@ import java.util.Objects; public interface Predicate { /** - * Returns {@code true} if the input object matches some criteria. + * Evaluates this predicate on the given argument. * - * @param t the input object - * @return {@code true} if the input object matches some criteria, otherwise - * {@code false} + * @param t the input argument + * @return {@code true} if the input argument matches the predicate, + * otherwise {@code false} */ boolean test(T t); /** - * Returns a predicate which evaluates to {@code true} only if this - * predicate and the provided predicate both evaluate to {@code true}. If - * this predicate returns {@code false} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * AND of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code false}, then the {@code other} + * predicate is not evaluated. * - *

    Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + *

    Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ANDed with this predicate - * @return a new predicate which returns {@code true} only if both - * predicates return {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ANDed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * AND of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default Predicate and(Predicate p) { - Objects.requireNonNull(p); - return (t) -> test(t) && p.test(t); + default Predicate and(Predicate other) { + Objects.requireNonNull(other); + return (t) -> test(t) && other.test(t); } /** - * Returns a predicate which negates the result of this predicate. - * - * @return a new predicate who's result is always the opposite of this + * Returns a predicate that represents the logical negation of this * predicate. + * + * @return a predicate that represents the logical negation of this + * predicate */ default Predicate negate() { return (t) -> !test(t); } /** - * Returns a predicate which evaluates to {@code true} if either this - * predicate or the provided predicate evaluates to {@code true}. If this - * predicate returns {@code true} then the remaining predicate is not - * evaluated. + * Returns a composed predicate that represents a short-circuiting logical + * OR of this predicate and another. When evaluating the composed + * predicate, if this predicate is {@code true}, then the {@code other} + * predicate is not evaluated. * - *

    Any exceptions thrown by either {@code test} method are relayed - * to the caller; if performing first operation throws an exception, the - * second operation will not be performed. + *

    Any exceptions thrown during evaluation of either predicate are relayed + * to the caller; if evaluation of this predicate throws an exception, the + * {@code other} predicate will not be evaluated. * - * @param p a predicate which will be logically-ORed with this predicate - * @return a new predicate which returns {@code true} if either predicate - * returns {@code true} - * @throws NullPointerException if p is null + * @param other a predicate that will be logically-ORed with this + * predicate + * @return a composed predicate that represents the short-circuiting logical + * OR of this predicate and the {@code other} predicate + * @throws NullPointerException if other is null */ - default Predicate or(Predicate p) { - Objects.requireNonNull(p); - return (t) -> test(t) || p.test(t); + default Predicate or(Predicate other) { + Objects.requireNonNull(other); + return (t) -> test(t) || other.test(t); } /** - * Returns a predicate who's result matches - * {@code Objects.equals(target, t)}. + * Returns a predicate that tests if two arguments are equal according + * to {@link Objects#equals(Object, Object)}. * - * @param the type of values evaluated by the predicate - * @param target the target value to be compared for equality - * @return a predicate who's result matches - * {@code Objects.equals(target, t)} + * @param the type of arguments to the predicate + * @param targetRef the object reference with which to compare for equality, + * which may be {@code null} + * @return a predicate that tests if two arguments are equal according + * to {@link Objects#equals(Object, Object)} */ - static Predicate isEqual(Object target) { - return (null == target) + static Predicate isEqual(Object targetRef) { + return (null == targetRef) ? Objects::isNull - : object -> target.equals(object); + : object -> targetRef.equals(object); } } diff --git a/jdk/src/share/classes/java/util/function/Supplier.java b/jdk/src/share/classes/java/util/function/Supplier.java index 728994b17cf..b87777e882a 100644 --- a/jdk/src/share/classes/java/util/function/Supplier.java +++ b/jdk/src/share/classes/java/util/function/Supplier.java @@ -25,10 +25,15 @@ package java.util.function; /** - * A supplier of objects. The result objects are either created during the - * invocation of {@link #get} or by some prior action. + * Represents a supplier of results. * - * @param The type of objects returned by {@code get} + *

    There is no requirement that a new or distinct result be returned each + * time the supplier is invoked. + * + *

    This is a functional interface + * whose functional method is {@link #get()}. + * + * @param the type of results supplied by this supplier * * @since 1.8 */ @@ -36,9 +41,9 @@ package java.util.function; public interface Supplier { /** - * Returns an object. + * Gets a result. * - * @return an object + * @return a result */ T get(); } diff --git a/jdk/src/share/classes/java/util/function/ToDoubleBiFunction.java b/jdk/src/share/classes/java/util/function/ToDoubleBiFunction.java index bd82422b9ab..d0efceef54e 100644 --- a/jdk/src/share/classes/java/util/function/ToDoubleBiFunction.java +++ b/jdk/src/share/classes/java/util/function/ToDoubleBiFunction.java @@ -25,13 +25,15 @@ package java.util.function; /** - * Apply a function to the input arguments, yielding an appropriate result. - * This is the {@code double}-bearing specialization for {@link BiFunction}. + * Represents a function that accepts two arguments and produces a double-valued + * result. This is the {@code double}-producing primitive specialization for + * {@link BiFunction}. * - * @param the type of the first argument to the {@code applyAsDouble} - * operation. - * @param the type of the second argument to the {@code applyAsDouble} - * operation. + *

    This is a functional interface + * whose functional method is {@link #applyAsDouble(Object, Object)}. + * + * @param the type of the first argument to the function + * @param the type of the second argument to the function * * @see BiFunction * @since 1.8 @@ -40,11 +42,11 @@ package java.util.function; public interface ToDoubleBiFunction { /** - * Compute the result of applying the function to the input arguments + * Applies this function to the given arguments. * - * @param t an input object - * @param u an input object - * @return the function result value + * @param t the first function argument + * @param u the second function argument + * @return the function result */ double applyAsDouble(T t, U u); } diff --git a/jdk/src/share/classes/java/util/function/ToDoubleFunction.java b/jdk/src/share/classes/java/util/function/ToDoubleFunction.java index c63d984a7ed..29bf9881387 100644 --- a/jdk/src/share/classes/java/util/function/ToDoubleFunction.java +++ b/jdk/src/share/classes/java/util/function/ToDoubleFunction.java @@ -25,10 +25,13 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code double}-bearing specialization for {@link Function}. + * Represents a function that produces a double-valued result. This is the + * {@code double}-producing primitive specialization for {@link Function}. * - * @param the type of input objects to the function + *

    This is a functional interface + * whose functional method is {@link #applyAsDouble(Object)}. + * + * @param the type of the input to the function * * @see Function * @since 1.8 @@ -37,10 +40,10 @@ package java.util.function; public interface ToDoubleFunction { /** - * Compute the result of applying the function to the input argument + * Applies this function to the given argument. * - * @param t the input object - * @return the function result value + * @param value the function argument + * @return the function result */ - double applyAsDouble(T t); + double applyAsDouble(T value); } diff --git a/jdk/src/share/classes/java/util/function/ToIntBiFunction.java b/jdk/src/share/classes/java/util/function/ToIntBiFunction.java index 3fc6d560030..e3109282569 100644 --- a/jdk/src/share/classes/java/util/function/ToIntBiFunction.java +++ b/jdk/src/share/classes/java/util/function/ToIntBiFunction.java @@ -25,13 +25,15 @@ package java.util.function; /** - * Apply a function to the input arguments, yielding an appropriate result. - * This is the {@code int}-bearing specialization for {@link BiFunction}. + * Represents a function that accepts two arguments and produces an int-valued + * result. This is the {@code int}-producing primitive specialization for + * {@link BiFunction}. * - * @param the type of the first argument to the {@code applyAsInt} - * operation - * @param the type of the second argument to the {@code applyAsInt} - * operation + *

    This is a functional interface + * whose functional method is {@link #applyAsInt(Object, Object)}. + * + * @param the type of the first argument to the function + * @param the type of the second argument to the function * * @see BiFunction * @since 1.8 @@ -40,11 +42,11 @@ package java.util.function; public interface ToIntBiFunction { /** - * Compute the result of applying the function to the input arguments + * Applies this function to the given arguments. * - * @param t an input object - * @param u an input object - * @return the function result value + * @param t the first function argument + * @param u the second function argument + * @return the function result */ int applyAsInt(T t, U u); } diff --git a/jdk/src/share/classes/java/util/function/ToIntFunction.java b/jdk/src/share/classes/java/util/function/ToIntFunction.java index c3fd2f7004f..5768242d1b4 100644 --- a/jdk/src/share/classes/java/util/function/ToIntFunction.java +++ b/jdk/src/share/classes/java/util/function/ToIntFunction.java @@ -25,10 +25,13 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code int}-bearing specialization for {@link Function}. + * Represents a function that produces an int-valued result. This is the + * {@code int}-producing primitive specialization for {@link Function}. * - * @param the type of input objects to the function + *

    This is a functional interface + * whose functional method is {@link #applyAsInt(Object)}. + * + * @param the type of the input to the function * * @see Function * @since 1.8 @@ -37,10 +40,10 @@ package java.util.function; public interface ToIntFunction { /** - * Compute the result of applying the function to the input arguments + * Applies this function to the given argument. * - * @param t the input object - * @return the function result value + * @param value the function argument + * @return the function result */ - int applyAsInt(T t); + int applyAsInt(T value); } diff --git a/jdk/src/share/classes/java/util/function/ToLongBiFunction.java b/jdk/src/share/classes/java/util/function/ToLongBiFunction.java index abf6f7851d1..8b5ed7e533d 100644 --- a/jdk/src/share/classes/java/util/function/ToLongBiFunction.java +++ b/jdk/src/share/classes/java/util/function/ToLongBiFunction.java @@ -25,13 +25,15 @@ package java.util.function; /** - * Apply a function to the input arguments, yielding an appropriate result. - * This is the {@code long}-bearing specialization for {@link BiFunction}. + * Represents a function that accepts two arguments and produces a long-valued + * result. This is the {@code long}-producing primitive specialization for + * {@link BiFunction}. * - * @param the type of the first argument to the {@code applyAsLong} - * operation. - * @param the type of the second argument to the {@code applyAsLong} - * operation. + *

    This is a functional interface + * whose functional method is {@link #applyAsLong(Object, Object)}. + * + * @param the type of the first argument to the function + * @param the type of the second argument to the function * * @see BiFunction * @since 1.8 @@ -40,11 +42,11 @@ package java.util.function; public interface ToLongBiFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given arguments. * - * @param t an input object - * @param u an input object - * @return the function result value + * @param t the first function argument + * @param u the second function argument + * @return the function result */ long applyAsLong(T t, U u); } diff --git a/jdk/src/share/classes/java/util/function/ToLongFunction.java b/jdk/src/share/classes/java/util/function/ToLongFunction.java index 4489c6fa655..eefb6178bd5 100644 --- a/jdk/src/share/classes/java/util/function/ToLongFunction.java +++ b/jdk/src/share/classes/java/util/function/ToLongFunction.java @@ -25,10 +25,13 @@ package java.util.function; /** - * Apply a function to the input argument, yielding an appropriate result. - * This is the {@code long}-bearing specialization for {@link Function}. + * Represents a function that produces a long-valued result. This is the + * {@code long}-producing primitive specialization for {@link Function}. * - * @param the type of input objects to the function + *

    This is a functional interface + * whose functional method is {@link #applyAsLong(Object)}. + * + * @param the type of the input to the function * * @see Function * @since 1.8 @@ -37,10 +40,10 @@ package java.util.function; public interface ToLongFunction { /** - * Compute the result of applying the function to the input arguments. + * Applies this function to the given argument. * - * @param t the input object - * @return the function result value + * @param value the function argument + * @return the function result */ - long applyAsLong(T t); + long applyAsLong(T value); } diff --git a/jdk/src/share/classes/java/util/function/UnaryOperator.java b/jdk/src/share/classes/java/util/function/UnaryOperator.java index e7794ca19e5..c4aa749a68a 100644 --- a/jdk/src/share/classes/java/util/function/UnaryOperator.java +++ b/jdk/src/share/classes/java/util/function/UnaryOperator.java @@ -25,11 +25,14 @@ package java.util.function; /** - * An operation upon a single operand yielding a result. The operand and the - * result are of the same type. This is a specialization of {@code Function} for + * Represents an operation on a single operand that produces a result of the + * same type as its operand. This is a specialization of {@code Function} for * the case where the operand and result are of the same type. * - * @param the type of operand to {@code apply} and of the result + *

    This is a functional interface + * whose functional method is {@link #apply(Object)}. + * + * @param the type of the operand and result of the operator * * @see Function * @since 1.8 @@ -38,10 +41,10 @@ package java.util.function; public interface UnaryOperator extends Function { /** - * Returns a unary operator that provides its input value as the result. + * Returns a unary operator that always returns its input argument. * - * @param the type of the input and output objects to the function - * @return a unary operator that provides its input value as the result + * @param the type of the input and output of the operator + * @return a unary operator that always returns its input argument */ static UnaryOperator identity() { return t -> t; diff --git a/jdk/src/share/classes/java/util/function/package-info.java b/jdk/src/share/classes/java/util/function/package-info.java index 36eda330d19..158d1f0212d 100644 --- a/jdk/src/share/classes/java/util/function/package-info.java +++ b/jdk/src/share/classes/java/util/function/package-info.java @@ -25,56 +25,82 @@ /** * Functional interfaces provide target types for lambda expressions - * and method references. Each functional interface has a single abstract method + * and method references. Each functional interface has a single abstract + * method, called the functional method for that functional interface, * to which the lambda expression's parameter and return types are matched or - * adapted. Functional interfaces can provide a target type in multiple contexts, - * such as assignment context, method invocation, or cast context: + * adapted. Functional interfaces can provide a target type in multiple + * contexts, such as assignment context, method invocation, or cast context: * - *

    - *     Predicate<String> p = String::isEmpty;
    + * 
    {@code
    + *     // Assignment context
    + *     Predicate p = String::isEmpty;
      *
    + *     // Method invocation context
      *     stream.filter(e -> e.getSize() > 10)...
      *
    + *     // Cast context
      *     stream.map((ToIntFunction) e -> e.getSize())...
    - * 
    + * }
    * - *

    The interfaces in this package are functional interfaces used by the JDK, - * and are available to be used by user code as well. While they do not identify - * a complete set of function shapes to which lambda expressions might be adapted, - * they provide enough to cover common requirements. + *

    The interfaces in this package are general purpose functional interfaces + * used by the JDK, and are available to be used by user code as well. While + * they do not identify a complete set of function shapes to which lambda + * expressions might be adapted, they provide enough to cover common + * requirements. Other functional interfaces provided for specific purposes, + * such as {@link java.io.FileFilter}, are defined in the packages where they + * are used. * - *

    The interfaces in this package are annotated with @{link FunctionalInterface}. - * This annotation is not a requirement for the compiler to recognize an interface - * as a functional interface, but merely an aid to capture design intent and enlist the - * help of the compiler in identifying accidental violations of design intent. + *

    The interfaces in this package are annotated with + * {@link java.lang.FunctionalInterface}. This annotation is not a requirement + * for the compiler to recognize an interface as a functional interface, but + * merely an aid to capture design intent and enlist the help of the compiler in + * identifying accidental violations of design intent. * - *

    The functional interfaces in this package follow an extensible naming convention, - * as follows: + *

    Functional interfaces often represent abstract concepts like functions, + * actions, or predicates. In documenting functional interfaces, or referring + * to variables typed as functional interfaces, it is common to refer directly + * to those abstract concepts, for example using "this function" instead of + * "the function represented by this object". + * + *

    The functional interfaces in this package follow an extensible naming + * convention, as follows: * *

      - *
    • There are several basic function shapes, including {@link java.util.function.Function} ({@code T -> R}), - * {@link java.util.function.Consumer} ({@code T -> void}), - * {@link java.util.function.Predicate} ({@code T -> boolean}), - * and {@link java.util.function.Supplier} ({@code () -> T}). + *
    • There are several basic function shapes, including + * {@link java.util.function.Function} (unary function from {@code T} to {@code R}), + * {@link java.util.function.Consumer} (unary function from {@code T} to {@code void}), + * {@link java.util.function.Predicate} (unary function from {@code T} to {@code boolean}), + * and {@link java.util.function.Supplier} (nilary function to {@code R}). *
    • - *
    • Function shapes have a natural arity based on how they are most commonly used. - * The basic shapes can be modified by an arity prefix to indicate a different arity, - * such as {@link java.util.function.BiFunction} ({@code (T, U) -> R}). + * + *
    • Function shapes have a natural arity based on how they are most + * commonly used. The basic shapes can be modified by an arity prefix to + * indicate a different arity, such as + * {@link java.util.function.BiFunction} (binary function from {@code T} and + * {@code U} to {@code R}). *
    • - *
    • There are additional derived function shapes which extend the basic function - * shapes, including {@link java.util.function.UnaryOperator} (extends {@code Function}) and - * {@link java.util.function.BinaryOperator} (extends {@code BiFunction}). + * + *
    • There are additional derived function shapes which extend the basic + * function shapes, including {@link java.util.function.UnaryOperator} + * (extends {@code Function}) and {@link java.util.function.BinaryOperator} + * (extends {@code BiFunction}). *
    • - *
    • Type parameters of functional interfaces can be specialized to primitives with - * additional type prefixes. To specialize the return type for a type that has both - * generic return type and generic arguments, we prefix {@code ToXxx}, as in - * {@link java.util.function.ToIntFunction}. Otherwise, type arguments are specialized left-to-right, - * as in {@link java.util.function.DoubleConsumer} or {@link java.util.function.ObjIntConsumer}. - * (The type prefix {@code Obj} is used to indicate that we don't want to specialize this parameter, - * but want to move on to the next parameter.) These schemes can be combined as in {@code IntToDoubleFunction}. + * + *
    • Type parameters of functional interfaces can be specialized to + * primitives with additional type prefixes. To specialize the return type + * for a type that has both generic return type and generic arguments, we + * prefix {@code ToXxx}, as in {@link java.util.function.ToIntFunction}. + * Otherwise, type arguments are specialized left-to-right, as in + * {@link java.util.function.DoubleConsumer} + * or {@link java.util.function.ObjIntConsumer}. + * (The type prefix {@code Obj} is used to indicate that we don't want to + * specialize this parameter, but want to move on to the next parameter, + * as in {@link java.util.function.ObjIntConsumer}.) + * These schemes can be combined, as in {@code IntToDoubleFunction}. *
    • - *
    • If there are specialization prefixes for all arguments, the arity prefix may be left - * out (as in {@link java.util.function.ObjIntConsumer}). + * + *
    • If there are specialization prefixes for all arguments, the arity + * prefix may be left out (as in {@link java.util.function.ObjIntConsumer}). *
    • *
    * diff --git a/jdk/src/share/classes/javax/security/auth/AuthPermission.java b/jdk/src/share/classes/javax/security/auth/AuthPermission.java index a5a40d87f5d..b1973e1286f 100644 --- a/jdk/src/share/classes/javax/security/auth/AuthPermission.java +++ b/jdk/src/share/classes/javax/security/auth/AuthPermission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,10 +41,10 @@ package javax.security.auth; * *
      *      doAs -                  allow the caller to invoke the
    - *                              Subject.doAs methods.
    + *                              {@code Subject.doAs} methods.
      *
      *      doAsPrivileged -        allow the caller to invoke the
    - *                              Subject.doAsPrivileged methods.
    + *                              {@code Subject.doAsPrivileged} methods.
      *
      *      getSubject -            allow for the retrieval of the
      *                              Subject(s) associated with the
    @@ -52,39 +52,39 @@ package javax.security.auth;
      *
      *      getSubjectFromDomainCombiner -  allow for the retrieval of the
      *                              Subject associated with the
    - *                              a SubjectDomainCombiner.
    + *                              a {@code SubjectDomainCombiner}.
      *
      *      setReadOnly -           allow the caller to set a Subject
      *                              to be read-only.
      *
    - *      modifyPrincipals -      allow the caller to modify the Set
    + *      modifyPrincipals -      allow the caller to modify the {@code Set}
      *                              of Principals associated with a
    - *                              Subject
    + *                              {@code Subject}
      *
      *      modifyPublicCredentials - allow the caller to modify the
    - *                              Set of public credentials
    - *                              associated with a Subject
    + *                              {@code Set} of public credentials
    + *                              associated with a {@code Subject}
      *
      *      modifyPrivateCredentials - allow the caller to modify the
    - *                              Set of private credentials
    - *                              associated with a Subject
    + *                              {@code Set} of private credentials
    + *                              associated with a {@code Subject}
      *
    - *      refreshCredential -     allow code to invoke the refresh
    + *      refreshCredential -     allow code to invoke the {@code refresh}
      *                              method on a credential which implements
    - *                              the Refreshable interface.
    + *                              the {@code Refreshable} interface.
      *
    - *      destroyCredential -     allow code to invoke the destroy
    - *                              method on a credential object
    - *                              which implements the Destroyable
    + *      destroyCredential -     allow code to invoke the {@code destroy}
    + *                              method on a credential {@code object}
    + *                              which implements the {@code Destroyable}
      *                              interface.
      *
      *      createLoginContext.{name} -  allow code to instantiate a
    - *                              LoginContext with the
    + *                              {@code LoginContext} with the
      *                              specified name.  name
      *                              is used as the index into the installed login
    - *                              Configuration
    + *                              {@code Configuration}
      *                              (that returned by
    - *                              Configuration.getConfiguration()).
    + *                              {@code Configuration.getConfiguration()}).
      *                              name can be wildcarded (set to '*')
      *                              to allow for any name.
      *
    @@ -93,7 +93,7 @@ package javax.security.auth;
      *
      *      createLoginConfiguration.{type} - allow code to obtain a Configuration
      *                              object via
    - *                              Configuration.getInstance.
    + *                              {@code Configuration.getInstance}.
      *
      *      setLoginConfiguration - allow for the setting of the system-wide
      *                              login Configuration.
    @@ -103,15 +103,15 @@ package javax.security.auth;
      * 
    * *

    The following target name has been deprecated in favor of - * createLoginContext.{name}. + * {@code createLoginContext.{name}}. * *

      *      createLoginContext -    allow code to instantiate a
    - *                              LoginContext.
    + *                              {@code LoginContext}.
      * 
    * - *

    javax.security.auth.Policy has been - * deprecated in favor of java.security.Policy. + *

    {@code javax.security.auth.Policy} has been + * deprecated in favor of {@code java.security.Policy}. * Therefore, the following target names have also been deprecated: * *

    @@ -139,8 +139,8 @@ java.security.BasicPermission {
          *
          * @param name the name of the AuthPermission
          *
    -     * @throws NullPointerException if name is null.
    -     * @throws IllegalArgumentException if name is empty.
    +     * @throws NullPointerException if {@code name} is {@code null}.
    +     * @throws IllegalArgumentException if {@code name} is empty.
          */
         public AuthPermission(String name) {
             // for backwards compatibility --
    @@ -160,8 +160,8 @@ java.security.BasicPermission {
          *
          * @param actions should be null.
          *
    -     * @throws NullPointerException if name is null.
    -     * @throws IllegalArgumentException if name is empty.
    +     * @throws NullPointerException if {@code name} is {@code null}.
    +     * @throws IllegalArgumentException if {@code name} is empty.
          */
         public AuthPermission(String name, String actions) {
             // for backwards compatibility --
    diff --git a/jdk/src/share/classes/javax/security/auth/DestroyFailedException.java b/jdk/src/share/classes/javax/security/auth/DestroyFailedException.java
    index 16888fd068e..41e99a33192 100644
    --- a/jdk/src/share/classes/javax/security/auth/DestroyFailedException.java
    +++ b/jdk/src/share/classes/javax/security/auth/DestroyFailedException.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
      * 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,10 +26,10 @@
     package javax.security.auth;
     
     /**
    - * Signals that a destroy operation failed.
    + * Signals that a {@code destroy} operation failed.
      *
      * 

    This exception is thrown by credentials implementing - * the Destroyable interface when the destroy + * the {@code Destroyable} interface when the {@code destroy} * method fails. * */ diff --git a/jdk/src/share/classes/javax/security/auth/Destroyable.java b/jdk/src/share/classes/javax/security/auth/Destroyable.java index 5afb6aa810b..15b92006cdf 100644 --- a/jdk/src/share/classes/javax/security/auth/Destroyable.java +++ b/jdk/src/share/classes/javax/security/auth/Destroyable.java @@ -34,12 +34,12 @@ package javax.security.auth; public interface Destroyable { /** - * Destroy this Object. + * Destroy this {@code Object}. * - *

    Sensitive information associated with this Object + *

    Sensitive information associated with this {@code Object} * is destroyed or cleared. Subsequent calls to certain methods - * on this Object will result in an - * IllegalStateException being thrown. + * on this {@code Object} will result in an + * {@code IllegalStateException} being thrown. * *

    * The default implementation throws {@code DestroyFailedException}. @@ -47,19 +47,19 @@ public interface Destroyable { * @exception DestroyFailedException if the destroy operation fails.

    * * @exception SecurityException if the caller does not have permission - * to destroy this Object. + * to destroy this {@code Object}. */ public default void destroy() throws DestroyFailedException { throw new DestroyFailedException(); } /** - * Determine if this Object has been destroyed. + * Determine if this {@code Object} has been destroyed. * *

    * The default implementation returns false. * - * @return true if this Object has been destroyed, + * @return true if this {@code Object} has been destroyed, * false otherwise. */ public default boolean isDestroyed() { diff --git a/jdk/src/share/classes/javax/security/auth/Policy.java b/jdk/src/share/classes/javax/security/auth/Policy.java index 5fd27ee071e..a32339ca78c 100644 --- a/jdk/src/share/classes/javax/security/auth/Policy.java +++ b/jdk/src/share/classes/javax/security/auth/Policy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * 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,11 +32,11 @@ import sun.security.util.Debug; *

    This is an abstract class for representing the system policy for * Subject-based authorization. A subclass implementation * of this class provides a means to specify a Subject-based - * access control Policy. + * access control {@code Policy}. * - *

    A Policy object can be queried for the set of + *

    A {@code Policy} object can be queried for the set of * Permissions granted to code running as a - * Principal in the following manner: + * {@code Principal} in the following manner: * *

      *      policy = Policy.getPolicy();
    @@ -44,20 +44,20 @@ import sun.security.util.Debug;
      *                                                      codeSource);
      * 
    * - * The Policy object consults the local policy and returns - * and appropriate Permissions object with the + * The {@code Policy} object consults the local policy and returns + * and appropriate {@code Permissions} object with the * Permissions granted to the Principals associated with the * provided subject, and granted to the code specified * by the provided codeSource. * - *

    A Policy contains the following information. + *

    A {@code Policy} contains the following information. * Note that this example only represents the syntax for the default - * Policy implementation. Subclass implementations of this class + * {@code Policy} implementation. Subclass implementations of this class * may implement alternative syntaxes and may retrieve the - * Policy from any source such as files, databases, + * {@code Policy} from any source such as files, databases, * or servers. * - *

    Each entry in the Policy is represented as + *

    Each entry in the {@code Policy} is represented as * a grant entry. Each grant entry * specifies a codebase, code signers, and Principals triplet, * as well as the Permissions granted to that triplet. @@ -84,23 +84,23 @@ import sun.security.util.Debug; *

    * * This grant entry specifies that code from "foo.com", - * signed by "foo', and running as a SolarisPrincipal with the - * name, duke, has one Permission. This Permission + * signed by "foo', and running as a {@code SolarisPrincipal} with the + * name, duke, has one {@code Permission}. This {@code Permission} * permits the executing code to read and write files in the directory, * "/home/duke". * - *

    To "run" as a particular Principal, - * code invokes the Subject.doAs(subject, ...) method. + *

    To "run" as a particular {@code Principal}, + * code invokes the {@code Subject.doAs(subject, ...)} method. * After invoking that method, the code runs as all the Principals - * associated with the specified Subject. - * Note that this Policy (and the Permissions - * granted in this Policy) only become effective - * after the call to Subject.doAs has occurred. + * associated with the specified {@code Subject}. + * Note that this {@code Policy} (and the Permissions + * granted in this {@code Policy}) only become effective + * after the call to {@code Subject.doAs} has occurred. * *

    Multiple Principals may be listed within one grant entry. * All the Principals in the grant entry must be associated with - * the Subject provided to Subject.doAs - * for that Subject to be granted the specified Permissions. + * the {@code Subject} provided to {@code Subject.doAs} + * for that {@code Subject} to be granted the specified Permissions. * *

      *      grant Principal com.sun.security.auth.SolarisPrincipal "duke",
    @@ -115,7 +115,7 @@ import sun.security.util.Debug;
      * as well as permission to make socket connections to "duke.com".
      *
      * 

    Note that non Principal-based grant entries are not permitted - * in this Policy. Therefore, grant entries such as: + * in this {@code Policy}. Therefore, grant entries such as: * *

      *      grant CodeBase "foo.com", Signedby "foo" {
    @@ -124,7 +124,7 @@ import sun.security.util.Debug;
      * 
    * * are rejected. Such permission must be listed in the - * java.security.Policy. + * {@code java.security.Policy}. * *

    The default {@code Policy} implementation can be changed by * setting the value of the {@code auth.policy.provider} security property to @@ -179,14 +179,14 @@ public abstract class Policy { /** * Returns the installed Policy object. * This method first calls - * SecurityManager.checkPermission with the - * AuthPermission("getPolicy") permission + * {@code SecurityManager.checkPermission} with the + * {@code AuthPermission("getPolicy")} permission * to ensure the caller has permission to get the Policy object. * *

    * * @return the installed Policy. The return value cannot be - * null. + * {@code null}. * * @exception java.lang.SecurityException if the current thread does not * have permission to get the Policy object. @@ -252,8 +252,8 @@ public abstract class Policy { /** * Sets the system-wide Policy object. This method first calls - * SecurityManager.checkPermission with the - * AuthPermission("setPolicy") + * {@code SecurityManager.checkPermission} with the + * {@code AuthPermission("setPolicy")} * permission to ensure the caller has permission to set the Policy. * *

    @@ -313,25 +313,25 @@ public abstract class Policy { /** * Retrieve the Permissions granted to the Principals associated with - * the specified CodeSource. + * the specified {@code CodeSource}. * *

    * - * @param subject the Subject + * @param subject the {@code Subject} * whose associated Principals, * in conjunction with the provided - * CodeSource, determines the Permissions + * {@code CodeSource}, determines the Permissions * returned by this method. This parameter - * may be null.

    + * may be {@code null}.

    * - * @param cs the code specified by its CodeSource + * @param cs the code specified by its {@code CodeSource} * that determines, in conjunction with the provided - * Subject, the Permissions + * {@code Subject}, the Permissions * returned by this method. This parameter may be - * null. + * {@code null}. * * @return the Collection of Permissions granted to all the - * Subject and code specified in + * {@code Subject} and code specified in * the provided subject and cs * parameters. */ @@ -345,7 +345,7 @@ public abstract class Policy { *

    This method causes this object to refresh/reload its current * Policy. This is implementation-dependent. * For example, if the Policy object is stored in - * a file, calling refresh will cause the file to be re-read. + * a file, calling {@code refresh} will cause the file to be re-read. * *

    * diff --git a/jdk/src/share/classes/javax/security/auth/PrivateCredentialPermission.java b/jdk/src/share/classes/javax/security/auth/PrivateCredentialPermission.java index 3f5e708f5ca..810cff2228a 100644 --- a/jdk/src/share/classes/javax/security/auth/PrivateCredentialPermission.java +++ b/jdk/src/share/classes/javax/security/auth/PrivateCredentialPermission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,10 +34,10 @@ import sun.security.util.ResourcesMgr; /** * This class is used to protect access to private Credentials - * belonging to a particular Subject. The Subject + * belonging to a particular {@code Subject}. The {@code Subject} * is represented by a Set of Principals. * - *

    The target name of this Permission specifies + *

    The target name of this {@code Permission} specifies * a Credential class name, and a Set of Principals. * The only valid value for this Permission's actions is, "read". * The target name must abide by the following syntax: @@ -65,12 +65,12 @@ import sun.security.util.ResourcesMgr; * * If CredentialClass is "*", then access is granted to * all private Credentials belonging to the specified - * Subject. + * {@code Subject}. * If "PrincipalName" is "*", then access is granted to the - * specified Credential owned by any Subject that has the - * specified Principal (the actual PrincipalName doesn't matter). + * specified Credential owned by any {@code Subject} that has the + * specified {@code Principal} (the actual PrincipalName doesn't matter). * For example, the following grants access to the - * a.b.Credential owned by any Subject that has + * a.b.Credential owned by any {@code Subject} that has * an a.b.Principal. * *

    @@ -83,7 +83,7 @@ import sun.security.util.ResourcesMgr;
      *
      * If both the PrincipalClass and "PrincipalName" are "*",
      * then access is granted to the specified Credential owned by
    - * any Subject.
    + * any {@code Subject}.
      *
      * 

    In addition, the PrincipalClass/PrincipalName pairing may be repeated: * @@ -96,7 +96,7 @@ import sun.security.util.ResourcesMgr; *

    * * The above grants access to the private Credential, "a.b.Credential", - * belonging to a Subject with at least two associated Principals: + * belonging to a {@code Subject} with at least two associated Principals: * "a.b.Principal" with the name, "duke", and "c.d.Principal", with the name, * "dukette". * @@ -115,7 +115,7 @@ public final class PrivateCredentialPermission extends Permission { /** * @serial The Principals associated with this permission. * The set contains elements of type, - * PrivateCredentialPermission.CredOwner. + * {@code PrivateCredentialPermission.CredOwner}. */ private Set principals; // ignored - kept around for compatibility private transient CredOwner[] credOwners; @@ -126,8 +126,8 @@ public final class PrivateCredentialPermission extends Permission { private boolean testing = false; /** - * Create a new PrivateCredentialPermission - * with the specified credentialClass and Principals. + * Create a new {@code PrivateCredentialPermission} + * with the specified {@code credentialClass} and Principals. */ PrivateCredentialPermission(String credentialClass, Set principals) { @@ -153,19 +153,19 @@ public final class PrivateCredentialPermission extends Permission { } /** - * Creates a new PrivateCredentialPermission - * with the specified name. The name - * specifies both a Credential class and a Principal Set. + * Creates a new {@code PrivateCredentialPermission} + * with the specified {@code name}. The {@code name} + * specifies both a Credential class and a {@code Principal} Set. * *

    * * @param name the name specifying the Credential class and - * Principal Set.

    + * {@code Principal} Set.

    * * @param actions the actions specifying that the Credential can be read. * - * @throws IllegalArgumentException if name does not conform - * to the correct syntax or if actions is not "read". + * @throws IllegalArgumentException if {@code name} does not conform + * to the correct syntax or if {@code actions} is not "read". */ public PrivateCredentialPermission(String name, String actions) { super(name); @@ -178,34 +178,34 @@ public final class PrivateCredentialPermission extends Permission { /** * Returns the Class name of the Credential associated with this - * PrivateCredentialPermission. + * {@code PrivateCredentialPermission}. * *

    * * @return the Class name of the Credential associated with this - * PrivateCredentialPermission. + * {@code PrivateCredentialPermission}. */ public String getCredentialClass() { return credentialClass; } /** - * Returns the Principal classes and names - * associated with this PrivateCredentialPermission. + * Returns the {@code Principal} classes and names + * associated with this {@code PrivateCredentialPermission}. * The information is returned as a two-dimensional array (array[x][y]). - * The 'x' value corresponds to the number of Principal + * The 'x' value corresponds to the number of {@code Principal} * class and name pairs. When (y==0), it corresponds to - * the Principal class value, and when (y==1), - * it corresponds to the Principal name value. + * the {@code Principal} class value, and when (y==1), + * it corresponds to the {@code Principal} name value. * For example, array[0][0] corresponds to the class name of - * the first Principal in the array. array[0][1] - * corresponds to the Principal name of the - * first Principal in the array. + * the first {@code Principal} in the array. array[0][1] + * corresponds to the {@code Principal} name of the + * first {@code Principal} in the array. * *

    * - * @return the Principal class and names associated - * with this PrivateCredentialPermission. + * @return the {@code Principal} class and names associated + * with this {@code PrivateCredentialPermission}. */ public String[][] getPrincipals() { @@ -222,8 +222,8 @@ public final class PrivateCredentialPermission extends Permission { } /** - * Checks if this PrivateCredentialPermission implies - * the specified Permission. + * Checks if this {@code PrivateCredentialPermission} implies + * the specified {@code Permission}. * *

    * @@ -241,10 +241,10 @@ public final class PrivateCredentialPermission extends Permission { * *

    * - * @param p the Permission to check against. + * @param p the {@code Permission} to check against. * - * @return true if this PrivateCredentialPermission implies - * the specified Permission, false if not. + * @return true if this {@code PrivateCredentialPermission} implies + * the specified {@code Permission}, false if not. */ public boolean implies(Permission p) { @@ -260,9 +260,9 @@ public final class PrivateCredentialPermission extends Permission { } /** - * Checks two PrivateCredentialPermission objects for + * Checks two {@code PrivateCredentialPermission} objects for * equality. Checks that obj is a - * PrivateCredentialPermission, + * {@code PrivateCredentialPermission}, * and has the same credential class as this object, * as well as the same Principals as this object. * The order of the Principals in the respective Permission's @@ -272,7 +272,7 @@ public final class PrivateCredentialPermission extends Permission { * * @param obj the object we are testing for equality with this object. * - * @return true if obj is a PrivateCredentialPermission, + * @return true if obj is a {@code PrivateCredentialPermission}, * has the same credential class as this object, * and has the same Principals as this object. */ @@ -311,9 +311,9 @@ public final class PrivateCredentialPermission extends Permission { /** * Return a homogeneous collection of PrivateCredentialPermissions - * in a PermissionCollection. - * No such PermissionCollection is defined, - * so this method always returns null. + * in a {@code PermissionCollection}. + * No such {@code PermissionCollection} is defined, + * so this method always returns {@code null}. * *

    * diff --git a/jdk/src/share/classes/javax/security/auth/RefreshFailedException.java b/jdk/src/share/classes/javax/security/auth/RefreshFailedException.java index 3c51f1a9cf0..86c3245a807 100644 --- a/jdk/src/share/classes/javax/security/auth/RefreshFailedException.java +++ b/jdk/src/share/classes/javax/security/auth/RefreshFailedException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * 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,10 +26,10 @@ package javax.security.auth; /** - * Signals that a refresh operation failed. + * Signals that a {@code refresh} operation failed. * *

    This exception is thrown by credentials implementing - * the Refreshable interface when the refresh + * the {@code Refreshable} interface when the {@code refresh} * method fails. * */ diff --git a/jdk/src/share/classes/javax/security/auth/Refreshable.java b/jdk/src/share/classes/javax/security/auth/Refreshable.java index 23ea81cff80..9ed85ace547 100644 --- a/jdk/src/share/classes/javax/security/auth/Refreshable.java +++ b/jdk/src/share/classes/javax/security/auth/Refreshable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,24 +37,24 @@ package javax.security.auth; public interface Refreshable { /** - * Determine if this Object is current. + * Determine if this {@code Object} is current. * *

    * - * @return true if this Object is currently current, + * @return true if this {@code Object} is currently current, * false otherwise. */ boolean isCurrent(); /** * Update or extend the validity period for this - * Object. + * {@code Object}. * *

    * * @exception SecurityException if the caller does not have permission * to update or extend the validity period for this - * Object.

    + * {@code Object}.

    * * @exception RefreshFailedException if the refresh attempt failed. */ diff --git a/jdk/src/share/classes/javax/security/auth/Subject.java b/jdk/src/share/classes/javax/security/auth/Subject.java index c72734edab3..d5e4240a40a 100644 --- a/jdk/src/share/classes/javax/security/auth/Subject.java +++ b/jdk/src/share/classes/javax/security/auth/Subject.java @@ -42,39 +42,39 @@ import java.security.ProtectionDomain; import sun.security.util.ResourcesMgr; /** - *

    A Subject represents a grouping of related information + *

    A {@code Subject} represents a grouping of related information * for a single entity, such as a person. * Such information includes the Subject's identities as well as * its security-related attributes * (passwords and cryptographic keys, for example). * *

    Subjects may potentially have multiple identities. - * Each identity is represented as a Principal - * within the Subject. Principals simply bind names to a - * Subject. For example, a Subject that happens + * Each identity is represented as a {@code Principal} + * within the {@code Subject}. Principals simply bind names to a + * {@code Subject}. For example, a {@code Subject} that happens * to be a person, Alice, might have two Principals: * one which binds "Alice Bar", the name on her driver license, - * to the Subject, and another which binds, + * to the {@code Subject}, and another which binds, * "999-99-9999", the number on her student identification card, - * to the Subject. Both Principals refer to the same - * Subject even though each has a different name. + * to the {@code Subject}. Both Principals refer to the same + * {@code Subject} even though each has a different name. * - *

    A Subject may also own security-related attributes, + *

    A {@code Subject} may also own security-related attributes, * which are referred to as credentials. * Sensitive credentials that require special protection, such as * private cryptographic keys, are stored within a private credential - * Set. Credentials intended to be shared, such as + * {@code Set}. Credentials intended to be shared, such as * public key certificates or Kerberos server tickets are stored - * within a public credential Set. Different permissions + * within a public credential {@code Set}. Different permissions * are required to access and modify the different credential Sets. * - *

    To retrieve all the Principals associated with a Subject, - * invoke the getPrincipals method. To retrieve - * all the public or private credentials belonging to a Subject, - * invoke the getPublicCredentials method or - * getPrivateCredentials method, respectively. - * To modify the returned Set of Principals and credentials, - * use the methods defined in the Set class. + *

    To retrieve all the Principals associated with a {@code Subject}, + * invoke the {@code getPrincipals} method. To retrieve + * all the public or private credentials belonging to a {@code Subject}, + * invoke the {@code getPublicCredentials} method or + * {@code getPrivateCredentials} method, respectively. + * To modify the returned {@code Set} of Principals and credentials, + * use the methods defined in the {@code Set} class. * For example: *

      *      Subject subject;
    @@ -86,13 +86,13 @@ import sun.security.util.ResourcesMgr;
      *      subject.getPublicCredentials().add(credential);
      * 
    * - *

    This Subject class implements Serializable. - * While the Principals associated with the Subject are serialized, - * the credentials associated with the Subject are not. - * Note that the java.security.Principal class - * does not implement Serializable. Therefore all concrete - * Principal implementations associated with Subjects - * must implement Serializable. + *

    This {@code Subject} class implements {@code Serializable}. + * While the Principals associated with the {@code Subject} are serialized, + * the credentials associated with the {@code Subject} are not. + * Note that the {@code java.security.Principal} class + * does not implement {@code Serializable}. Therefore all concrete + * {@code Principal} implementations associated with Subjects + * must implement {@code Serializable}. * * @see java.security.Principal * @see java.security.DomainCombiner @@ -102,14 +102,14 @@ public final class Subject implements java.io.Serializable { private static final long serialVersionUID = -8308522755600156056L; /** - * A Set that provides a view of all of this + * A {@code Set} that provides a view of all of this * Subject's Principals * *

    * * @serial Each element in this set is a - * java.security.Principal. - * The set is a Subject.SecureSet. + * {@code java.security.Principal}. + * The set is a {@code Subject.SecureSet}. */ Set principals; @@ -135,21 +135,21 @@ public final class Subject implements java.io.Serializable { = new ProtectionDomain[0]; /** - * Create an instance of a Subject - * with an empty Set of Principals and empty + * Create an instance of a {@code Subject} + * with an empty {@code Set} of Principals and empty * Sets of public and private credentials. * - *

    The newly constructed Sets check whether this Subject + *

    The newly constructed Sets check whether this {@code Subject} * has been set read-only before permitting subsequent modifications. * The newly created Sets also prevent illegal modifications * by ensuring that callers have sufficient permissions. * *

    To modify the Principals Set, the caller must have - * AuthPermission("modifyPrincipals"). + * {@code AuthPermission("modifyPrincipals")}. * To modify the public credential Set, the caller must have - * AuthPermission("modifyPublicCredentials"). + * {@code AuthPermission("modifyPublicCredentials")}. * To modify the private credential Set, the caller must have - * AuthPermission("modifyPrivateCredentials"). + * {@code AuthPermission("modifyPrivateCredentials")}. */ public Subject() { @@ -162,39 +162,39 @@ public final class Subject implements java.io.Serializable { } /** - * Create an instance of a Subject with + * Create an instance of a {@code Subject} with * Principals and credentials. * *

    The Principals and credentials from the specified Sets * are copied into newly constructed Sets. - * These newly created Sets check whether this Subject + * These newly created Sets check whether this {@code Subject} * has been set read-only before permitting subsequent modifications. * The newly created Sets also prevent illegal modifications * by ensuring that callers have sufficient permissions. * *

    To modify the Principals Set, the caller must have - * AuthPermission("modifyPrincipals"). + * {@code AuthPermission("modifyPrincipals")}. * To modify the public credential Set, the caller must have - * AuthPermission("modifyPublicCredentials"). + * {@code AuthPermission("modifyPublicCredentials")}. * To modify the private credential Set, the caller must have - * AuthPermission("modifyPrivateCredentials"). + * {@code AuthPermission("modifyPrivateCredentials")}. *

    * - * @param readOnly true if the Subject is to be read-only, + * @param readOnly true if the {@code Subject} is to be read-only, * and false otherwise.

    * - * @param principals the Set of Principals - * to be associated with this Subject.

    + * @param principals the {@code Set} of Principals + * to be associated with this {@code Subject}.

    * - * @param pubCredentials the Set of public credentials - * to be associated with this Subject.

    + * @param pubCredentials the {@code Set} of public credentials + * to be associated with this {@code Subject}.

    * - * @param privCredentials the Set of private credentials - * to be associated with this Subject. + * @param privCredentials the {@code Set} of private credentials + * to be associated with this {@code Subject}. * * @exception NullPointerException if the specified - * principals, pubCredentials, - * or privCredentials are null. + * {@code principals}, {@code pubCredentials}, + * or {@code privCredentials} are {@code null}. */ public Subject(boolean readOnly, Set principals, Set pubCredentials, Set privCredentials) @@ -216,24 +216,24 @@ public final class Subject implements java.io.Serializable { } /** - * Set this Subject to be read-only. + * Set this {@code Subject} to be read-only. * *

    Modifications (additions and removals) to this Subject's - * Principal Set and + * {@code Principal} {@code Set} and * credential Sets will be disallowed. - * The destroy operation on this Subject's credentials will + * The {@code destroy} operation on this Subject's credentials will * still be permitted. * - *

    Subsequent attempts to modify the Subject's Principal + *

    Subsequent attempts to modify the Subject's {@code Principal} * and credential Sets will result in an - * IllegalStateException being thrown. - * Also, once a Subject is read-only, + * {@code IllegalStateException} being thrown. + * Also, once a {@code Subject} is read-only, * it can not be reset to being writable again. * *

    * * @exception SecurityException if the caller does not have permission - * to set this Subject to be read-only. + * to set this {@code Subject} to be read-only. */ public void setReadOnly() { java.lang.SecurityManager sm = System.getSecurityManager(); @@ -245,40 +245,40 @@ public final class Subject implements java.io.Serializable { } /** - * Query whether this Subject is read-only. + * Query whether this {@code Subject} is read-only. * *

    * - * @return true if this Subject is read-only, false otherwise. + * @return true if this {@code Subject} is read-only, false otherwise. */ public boolean isReadOnly() { return this.readOnly; } /** - * Get the Subject associated with the provided - * AccessControlContext. + * Get the {@code Subject} associated with the provided + * {@code AccessControlContext}. * - *

    The AccessControlContext may contain many - * Subjects (from nested doAs calls). - * In this situation, the most recent Subject associated - * with the AccessControlContext is returned. + *

    The {@code AccessControlContext} may contain many + * Subjects (from nested {@code doAs} calls). + * In this situation, the most recent {@code Subject} associated + * with the {@code AccessControlContext} is returned. * *

    * - * @param acc the AccessControlContext from which to retrieve - * the Subject. + * @param acc the {@code AccessControlContext} from which to retrieve + * the {@code Subject}. * - * @return the Subject associated with the provided - * AccessControlContext, or null - * if no Subject is associated - * with the provided AccessControlContext. + * @return the {@code Subject} associated with the provided + * {@code AccessControlContext}, or {@code null} + * if no {@code Subject} is associated + * with the provided {@code AccessControlContext}. * * @exception SecurityException if the caller does not have permission - * to get the Subject.

    + * to get the {@code Subject}.

    * * @exception NullPointerException if the provided - * AccessControlContext is null. + * {@code AccessControlContext} is {@code null}. */ public static Subject getSubject(final AccessControlContext acc) { @@ -306,36 +306,36 @@ public final class Subject implements java.io.Serializable { } /** - * Perform work as a particular Subject. + * Perform work as a particular {@code Subject}. * *

    This method first retrieves the current Thread's - * AccessControlContext via - * AccessController.getContext, - * and then instantiates a new AccessControlContext + * {@code AccessControlContext} via + * {@code AccessController.getContext}, + * and then instantiates a new {@code AccessControlContext} * using the retrieved context along with a new - * SubjectDomainCombiner (constructed using - * the provided Subject). - * Finally, this method invokes AccessController.doPrivileged, - * passing it the provided PrivilegedAction, - * as well as the newly constructed AccessControlContext. + * {@code SubjectDomainCombiner} (constructed using + * the provided {@code Subject}). + * Finally, this method invokes {@code AccessController.doPrivileged}, + * passing it the provided {@code PrivilegedAction}, + * as well as the newly constructed {@code AccessControlContext}. * *

    * - * @param subject the Subject that the specified - * action will run as. This parameter - * may be null.

    + * @param subject the {@code Subject} that the specified + * {@code action} will run as. This parameter + * may be {@code null}.

    * * @param the type of the value returned by the PrivilegedAction's * {@code run} method. * * @param action the code to be run as the specified - * Subject.

    + * {@code Subject}.

    * * @return the value returned by the PrivilegedAction's - * run method. + * {@code run} method. * - * @exception NullPointerException if the PrivilegedAction - * is null.

    + * @exception NullPointerException if the {@code PrivilegedAction} + * is {@code null}.

    * * @exception SecurityException if the caller does not have permission * to invoke this method. @@ -362,41 +362,41 @@ public final class Subject implements java.io.Serializable { } /** - * Perform work as a particular Subject. + * Perform work as a particular {@code Subject}. * *

    This method first retrieves the current Thread's - * AccessControlContext via - * AccessController.getContext, - * and then instantiates a new AccessControlContext + * {@code AccessControlContext} via + * {@code AccessController.getContext}, + * and then instantiates a new {@code AccessControlContext} * using the retrieved context along with a new - * SubjectDomainCombiner (constructed using - * the provided Subject). - * Finally, this method invokes AccessController.doPrivileged, - * passing it the provided PrivilegedExceptionAction, - * as well as the newly constructed AccessControlContext. + * {@code SubjectDomainCombiner} (constructed using + * the provided {@code Subject}). + * Finally, this method invokes {@code AccessController.doPrivileged}, + * passing it the provided {@code PrivilegedExceptionAction}, + * as well as the newly constructed {@code AccessControlContext}. * *

    * - * @param subject the Subject that the specified - * action will run as. This parameter - * may be null.

    + * @param subject the {@code Subject} that the specified + * {@code action} will run as. This parameter + * may be {@code null}.

    * * @param the type of the value returned by the * PrivilegedExceptionAction's {@code run} method. * * @param action the code to be run as the specified - * Subject.

    + * {@code Subject}.

    * * @return the value returned by the - * PrivilegedExceptionAction's run method. + * PrivilegedExceptionAction's {@code run} method. * * @exception PrivilegedActionException if the - * PrivilegedExceptionAction.run + * {@code PrivilegedExceptionAction.run} * method throws a checked exception.

    * * @exception NullPointerException if the specified - * PrivilegedExceptionAction is - * null.

    + * {@code PrivilegedExceptionAction} is + * {@code null}.

    * * @exception SecurityException if the caller does not have permission * to invoke this method. @@ -424,36 +424,36 @@ public final class Subject implements java.io.Serializable { } /** - * Perform privileged work as a particular Subject. + * Perform privileged work as a particular {@code Subject}. * - *

    This method behaves exactly as Subject.doAs, + *

    This method behaves exactly as {@code Subject.doAs}, * except that instead of retrieving the current Thread's - * AccessControlContext, it uses the provided - * AccessControlContext. If the provided - * AccessControlContext is null, - * this method instantiates a new AccessControlContext + * {@code AccessControlContext}, it uses the provided + * {@code AccessControlContext}. If the provided + * {@code AccessControlContext} is {@code null}, + * this method instantiates a new {@code AccessControlContext} * with an empty collection of ProtectionDomains. * *

    * - * @param subject the Subject that the specified - * action will run as. This parameter - * may be null.

    + * @param subject the {@code Subject} that the specified + * {@code action} will run as. This parameter + * may be {@code null}.

    * * @param the type of the value returned by the PrivilegedAction's * {@code run} method. * * @param action the code to be run as the specified - * Subject.

    + * {@code Subject}.

    * - * @param acc the AccessControlContext to be tied to the + * @param acc the {@code AccessControlContext} to be tied to the * specified subject and action.

    * * @return the value returned by the PrivilegedAction's - * run method. + * {@code run} method. * - * @exception NullPointerException if the PrivilegedAction - * is null.

    + * @exception NullPointerException if the {@code PrivilegedAction} + * is {@code null}.

    * * @exception SecurityException if the caller does not have permission * to invoke this method. @@ -485,41 +485,41 @@ public final class Subject implements java.io.Serializable { } /** - * Perform privileged work as a particular Subject. + * Perform privileged work as a particular {@code Subject}. * - *

    This method behaves exactly as Subject.doAs, + *

    This method behaves exactly as {@code Subject.doAs}, * except that instead of retrieving the current Thread's - * AccessControlContext, it uses the provided - * AccessControlContext. If the provided - * AccessControlContext is null, - * this method instantiates a new AccessControlContext + * {@code AccessControlContext}, it uses the provided + * {@code AccessControlContext}. If the provided + * {@code AccessControlContext} is {@code null}, + * this method instantiates a new {@code AccessControlContext} * with an empty collection of ProtectionDomains. * *

    * - * @param subject the Subject that the specified - * action will run as. This parameter - * may be null.

    + * @param subject the {@code Subject} that the specified + * {@code action} will run as. This parameter + * may be {@code null}.

    * * @param the type of the value returned by the * PrivilegedExceptionAction's {@code run} method. * * @param action the code to be run as the specified - * Subject.

    + * {@code Subject}.

    * - * @param acc the AccessControlContext to be tied to the + * @param acc the {@code AccessControlContext} to be tied to the * specified subject and action.

    * * @return the value returned by the - * PrivilegedExceptionAction's run method. + * PrivilegedExceptionAction's {@code run} method. * * @exception PrivilegedActionException if the - * PrivilegedExceptionAction.run + * {@code PrivilegedExceptionAction.run} * method throws a checked exception.

    * * @exception NullPointerException if the specified - * PrivilegedExceptionAction is - * null.

    + * {@code PrivilegedExceptionAction} is + * {@code null}.

    * * @exception SecurityException if the caller does not have permission * to invoke this method. @@ -568,19 +568,19 @@ public final class Subject implements java.io.Serializable { } /** - * Return the Set of Principals associated with this - * Subject. Each Principal represents - * an identity for this Subject. + * Return the {@code Set} of Principals associated with this + * {@code Subject}. Each {@code Principal} represents + * an identity for this {@code Subject}. * - *

    The returned Set is backed by this Subject's - * internal Principal Set. Any modification - * to the returned Set affects the internal - * Principal Set as well. + *

    The returned {@code Set} is backed by this Subject's + * internal {@code Principal} {@code Set}. Any modification + * to the returned {@code Set} affects the internal + * {@code Principal} {@code Set} as well. * *

    * - * @return The Set of Principals associated with this - * Subject. + * @return The {@code Set} of Principals associated with this + * {@code Subject}. */ public Set getPrincipals() { @@ -590,28 +590,28 @@ public final class Subject implements java.io.Serializable { } /** - * Return a Set of Principals associated with this - * Subject that are instances or subclasses of the specified - * Class. + * Return a {@code Set} of Principals associated with this + * {@code Subject} that are instances or subclasses of the specified + * {@code Class}. * - *

    The returned Set is not backed by this Subject's - * internal Principal Set. A new - * Set is created and returned for each method invocation. - * Modifications to the returned Set - * will not affect the internal Principal Set. + *

    The returned {@code Set} is not backed by this Subject's + * internal {@code Principal} {@code Set}. A new + * {@code Set} is created and returned for each method invocation. + * Modifications to the returned {@code Set} + * will not affect the internal {@code Principal} {@code Set}. * *

    * * @param the type of the class modeled by {@code c} * - * @param c the returned Set of Principals will all be + * @param c the returned {@code Set} of Principals will all be * instances of this class. * - * @return a Set of Principals that are instances of the - * specified Class. + * @return a {@code Set} of Principals that are instances of the + * specified {@code Class}. * - * @exception NullPointerException if the specified Class - * is null. + * @exception NullPointerException if the specified {@code Class} + * is {@code null}. */ public Set getPrincipals(Class c) { @@ -625,18 +625,18 @@ public final class Subject implements java.io.Serializable { } /** - * Return the Set of public credentials held by this - * Subject. + * Return the {@code Set} of public credentials held by this + * {@code Subject}. * - *

    The returned Set is backed by this Subject's - * internal public Credential Set. Any modification - * to the returned Set affects the internal public - * Credential Set as well. + *

    The returned {@code Set} is backed by this Subject's + * internal public Credential {@code Set}. Any modification + * to the returned {@code Set} affects the internal public + * Credential {@code Set} as well. * *

    * - * @return A Set of public credentials held by this - * Subject. + * @return A {@code Set} of public credentials held by this + * {@code Subject}. */ public Set getPublicCredentials() { @@ -646,29 +646,29 @@ public final class Subject implements java.io.Serializable { } /** - * Return the Set of private credentials held by this - * Subject. + * Return the {@code Set} of private credentials held by this + * {@code Subject}. * - *

    The returned Set is backed by this Subject's - * internal private Credential Set. Any modification - * to the returned Set affects the internal private - * Credential Set as well. + *

    The returned {@code Set} is backed by this Subject's + * internal private Credential {@code Set}. Any modification + * to the returned {@code Set} affects the internal private + * Credential {@code Set} as well. * *

    A caller requires permissions to access the Credentials - * in the returned Set, or to modify the - * Set itself. A SecurityException + * in the returned {@code Set}, or to modify the + * {@code Set} itself. A {@code SecurityException} * is thrown if the caller does not have the proper permissions. * - *

    While iterating through the Set, - * a SecurityException is thrown + *

    While iterating through the {@code Set}, + * a {@code SecurityException} is thrown * if the caller does not have permission to access a - * particular Credential. The Iterator - * is nevertheless advanced to next element in the Set. + * particular Credential. The {@code Iterator} + * is nevertheless advanced to next element in the {@code Set}. * *

    * - * @return A Set of private credentials held by this - * Subject. + * @return A {@code Set} of private credentials held by this + * {@code Subject}. */ public Set getPrivateCredentials() { @@ -686,28 +686,28 @@ public final class Subject implements java.io.Serializable { } /** - * Return a Set of public credentials associated with this - * Subject that are instances or subclasses of the specified - * Class. + * Return a {@code Set} of public credentials associated with this + * {@code Subject} that are instances or subclasses of the specified + * {@code Class}. * - *

    The returned Set is not backed by this Subject's - * internal public Credential Set. A new - * Set is created and returned for each method invocation. - * Modifications to the returned Set - * will not affect the internal public Credential Set. + *

    The returned {@code Set} is not backed by this Subject's + * internal public Credential {@code Set}. A new + * {@code Set} is created and returned for each method invocation. + * Modifications to the returned {@code Set} + * will not affect the internal public Credential {@code Set}. * *

    * * @param the type of the class modeled by {@code c} * - * @param c the returned Set of public credentials will all be + * @param c the returned {@code Set} of public credentials will all be * instances of this class. * - * @return a Set of public credentials that are instances - * of the specified Class. + * @return a {@code Set} of public credentials that are instances + * of the specified {@code Class}. * - * @exception NullPointerException if the specified Class - * is null. + * @exception NullPointerException if the specified {@code Class} + * is {@code null}. */ public Set getPublicCredentials(Class c) { @@ -721,32 +721,32 @@ public final class Subject implements java.io.Serializable { } /** - * Return a Set of private credentials associated with this - * Subject that are instances or subclasses of the specified - * Class. + * Return a {@code Set} of private credentials associated with this + * {@code Subject} that are instances or subclasses of the specified + * {@code Class}. * *

    The caller must have permission to access all of the - * requested Credentials, or a SecurityException + * requested Credentials, or a {@code SecurityException} * will be thrown. * - *

    The returned Set is not backed by this Subject's - * internal private Credential Set. A new - * Set is created and returned for each method invocation. - * Modifications to the returned Set - * will not affect the internal private Credential Set. + *

    The returned {@code Set} is not backed by this Subject's + * internal private Credential {@code Set}. A new + * {@code Set} is created and returned for each method invocation. + * Modifications to the returned {@code Set} + * will not affect the internal private Credential {@code Set}. * *

    * * @param the type of the class modeled by {@code c} * - * @param c the returned Set of private credentials will all be + * @param c the returned {@code Set} of private credentials will all be * instances of this class. * - * @return a Set of private credentials that are instances - * of the specified Class. + * @return a {@code Set} of private credentials that are instances + * of the specified {@code Class}. * - * @exception NullPointerException if the specified Class - * is null. + * @exception NullPointerException if the specified {@code Class} + * is {@code null}. */ public Set getPrivateCredentials(Class c) { @@ -768,25 +768,25 @@ public final class Subject implements java.io.Serializable { } /** - * Compares the specified Object with this Subject + * Compares the specified Object with this {@code Subject} * for equality. Returns true if the given object is also a Subject - * and the two Subject instances are equivalent. - * More formally, two Subject instances are - * equal if their Principal and Credential + * and the two {@code Subject} instances are equivalent. + * More formally, two {@code Subject} instances are + * equal if their {@code Principal} and {@code Credential} * Sets are equal. * *

    * * @param o Object to be compared for equality with this - * Subject. + * {@code Subject}. * * @return true if the specified Object is equal to this - * Subject. + * {@code Subject}. * * @exception SecurityException if the caller does not have permission - * to access the private credentials for this Subject, + * to access the private credentials for this {@code Subject}, * or if the caller does not have permission to access the - * private credentials for the provided Subject. + * private credentials for the provided {@code Subject}. */ public boolean equals(Object o) { @@ -833,11 +833,11 @@ public final class Subject implements java.io.Serializable { } /** - * Return the String representation of this Subject. + * Return the String representation of this {@code Subject}. * *

    * - * @return the String representation of this Subject. + * @return the String representation of this {@code Subject}. */ public String toString() { return toString(true); @@ -894,11 +894,11 @@ public final class Subject implements java.io.Serializable { } /** - * Returns a hashcode for this Subject. + * Returns a hashcode for this {@code Subject}. * *

    * - * @return a hashcode for this Subject. + * @return a hashcode for this {@code Subject}. * * @exception SecurityException if the caller does not have permission * to access this Subject's private credentials. @@ -910,10 +910,10 @@ public final class Subject implements java.io.Serializable { * hashcodes of this Subject's Principals and credentials. * * If a particular credential was destroyed - * (credential.hashCode() throws an - * IllegalStateException), + * ({@code credential.hashCode()} throws an + * {@code IllegalStateException}), * the hashcode for that credential is derived via: - * credential.getClass().toString().hashCode(). + * {@code credential.getClass().toString().hashCode()}. */ int hashCode = 0; @@ -964,7 +964,7 @@ public final class Subject implements java.io.Serializable { s.defaultReadObject(); - // The Credential Set is not serialized, but we do not + // The Credential {@code Set} is not serialized, but we do not // want the default deserialization routine to set it to null. this.pubCredentials = Collections.synchronizedSet (new SecureSet(this, PUB_CREDENTIAL_SET)); @@ -998,13 +998,13 @@ public final class Subject implements java.io.Serializable { /** * @serial An integer identifying the type of objects contained - * in this set. If which == 1, + * in this set. If {@code which == 1}, * this is a Principal set and all the elements are - * of type java.security.Principal. - * If which == 2, this is a public credential - * set and all the elements are of type Object. - * If which == 3, this is a private credential - * set and all the elements are of type Object. + * of type {@code java.security.Principal}. + * If {@code which == 2}, this is a public credential + * set and all the elements are of type {@code Object}. + * If {@code which == 3}, this is a private credential + * set and all the elements are of type {@code Object}. */ private int which; @@ -1321,7 +1321,7 @@ public final class Subject implements java.io.Serializable { } /** - * This class implements a Set which returns only + * This class implements a {@code Set} which returns only * members that are an instance of a specified Class. */ private class ClassSet extends AbstractSet { diff --git a/jdk/src/share/classes/javax/security/auth/SubjectDomainCombiner.java b/jdk/src/share/classes/javax/security/auth/SubjectDomainCombiner.java index 9da411cc1bd..da75d683425 100644 --- a/jdk/src/share/classes/javax/security/auth/SubjectDomainCombiner.java +++ b/jdk/src/share/classes/javax/security/auth/SubjectDomainCombiner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,9 +39,9 @@ import java.util.WeakHashMap; import java.lang.ref.WeakReference; /** - * A SubjectDomainCombiner updates ProtectionDomains - * with Principals from the Subject associated with this - * SubjectDomainCombiner. + * A {@code SubjectDomainCombiner} updates ProtectionDomains + * with Principals from the {@code Subject} associated with this + * {@code SubjectDomainCombiner}. * */ public class SubjectDomainCombiner implements java.security.DomainCombiner { @@ -66,13 +66,13 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner { (useJavaxPolicy && cachePolicy()); /** - * Associate the provided Subject with this - * SubjectDomainCombiner. + * Associate the provided {@code Subject} with this + * {@code SubjectDomainCombiner}. * *

    * - * @param subject the Subject to be associated with - * with this SubjectDomainCombiner. + * @param subject the {@code Subject} to be associated with + * with this {@code SubjectDomainCombiner}. */ public SubjectDomainCombiner(Subject subject) { this.subject = subject; @@ -85,19 +85,19 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner { } /** - * Get the Subject associated with this - * SubjectDomainCombiner. + * Get the {@code Subject} associated with this + * {@code SubjectDomainCombiner}. * *

    * - * @return the Subject associated with this - * SubjectDomainCombiner, or null - * if no Subject is associated with this - * SubjectDomainCombiner. + * @return the {@code Subject} associated with this + * {@code SubjectDomainCombiner}, or {@code null} + * if no {@code Subject} is associated with this + * {@code SubjectDomainCombiner}. * * @exception SecurityException if the caller does not have permission - * to get the Subject associated with this - * SubjectDomainCombiner. + * to get the {@code Subject} associated with this + * {@code SubjectDomainCombiner}. */ public Subject getSubject() { java.lang.SecurityManager sm = System.getSecurityManager(); @@ -110,18 +110,18 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner { /** * Update the relevant ProtectionDomains with the Principals - * from the Subject associated with this - * SubjectDomainCombiner. + * from the {@code Subject} associated with this + * {@code SubjectDomainCombiner}. * - *

    A new ProtectionDomain instance is created - * for each ProtectionDomain in the - * currentDomains array. Each new ProtectionDomain - * instance is created using the CodeSource, - * Permissions and ClassLoader - * from the corresponding ProtectionDomain in + *

    A new {@code ProtectionDomain} instance is created + * for each {@code ProtectionDomain} in the + * currentDomains array. Each new {@code ProtectionDomain} + * instance is created using the {@code CodeSource}, + * {@code Permission}s and {@code ClassLoader} + * from the corresponding {@code ProtectionDomain} in * currentDomains, as well as with the Principals from - * the Subject associated with this - * SubjectDomainCombiner. + * the {@code Subject} associated with this + * {@code SubjectDomainCombiner}. * *

    All of the newly instantiated ProtectionDomains are * combined into a new array. The ProtectionDomains from the @@ -136,23 +136,23 @@ public class SubjectDomainCombiner implements java.security.DomainCombiner { * * @param currentDomains the ProtectionDomains associated with the * current execution Thread, up to the most recent - * privileged ProtectionDomain. + * privileged {@code ProtectionDomain}. * The ProtectionDomains are are listed in order of execution, - * with the most recently executing ProtectionDomain + * with the most recently executing {@code ProtectionDomain} * residing at the beginning of the array. This parameter may - * be null if the current execution Thread + * be {@code null} if the current execution Thread * has no associated ProtectionDomains.

    * * @param assignedDomains the ProtectionDomains inherited from the * parent Thread, or the ProtectionDomains from the * privileged context, if a call to * AccessController.doPrivileged(..., context) - * had occurred This parameter may be null + * had occurred This parameter may be {@code null} * if there were no ProtectionDomains inherited from the * parent Thread, or from the privileged context. * * @return a new array consisting of the updated ProtectionDomains, - * or null. + * or {@code null}. */ public ProtectionDomain[] combine(ProtectionDomain[] currentDomains, ProtectionDomain[] assignedDomains) { diff --git a/jdk/src/share/classes/javax/security/auth/callback/Callback.java b/jdk/src/share/classes/javax/security/auth/callback/Callback.java index 43f884f049d..83855ca0484 100644 --- a/jdk/src/share/classes/javax/security/auth/callback/Callback.java +++ b/jdk/src/share/classes/javax/security/auth/callback/Callback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,14 +28,14 @@ package javax.security.auth.callback; /** *

    Implementations of this interface are passed to a - * CallbackHandler, allowing underlying security services + * {@code CallbackHandler}, allowing underlying security services * the ability to interact with a calling application to retrieve specific * authentication data such as usernames and passwords, or to display * certain information, such as error and warning messages. * - *

    Callback implementations do not retrieve or + *

    {@code Callback} implementations do not retrieve or * display the information requested by underlying security services. - * Callback implementations simply provide the means + * {@code Callback} implementations simply provide the means * to pass such requests to applications, and for applications, * if appropriate, to return requested information back to the * underlying security services. diff --git a/jdk/src/share/classes/javax/security/auth/callback/CallbackHandler.java b/jdk/src/share/classes/javax/security/auth/callback/CallbackHandler.java index 843accac99b..af024962ec4 100644 --- a/jdk/src/share/classes/javax/security/auth/callback/CallbackHandler.java +++ b/jdk/src/share/classes/javax/security/auth/callback/CallbackHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ package javax.security.auth.callback; /** - *

    An application implements a CallbackHandler and passes + *

    An application implements a {@code CallbackHandler} and passes * it to underlying security services so that they may interact with * the application to retrieve specific authentication data, * such as usernames and passwords, or to display certain information, @@ -40,12 +40,12 @@ package javax.security.auth.callback; * *

    Underlying security services make requests for different types * of information by passing individual Callbacks to the - * CallbackHandler. The CallbackHandler + * {@code CallbackHandler}. The {@code CallbackHandler} * implementation decides how to retrieve and display information * depending on the Callbacks passed to it. For example, * if the underlying service needs a username and password to - * authenticate a user, it uses a NameCallback and - * PasswordCallback. The CallbackHandler + * authenticate a user, it uses a {@code NameCallback} and + * {@code PasswordCallback}. The {@code CallbackHandler} * can then choose to prompt for a username and password serially, * or to prompt for both in a single window. * @@ -54,10 +54,10 @@ package javax.security.auth.callback; * {@code auth.login.defaultCallbackHandler} security property. * *

    If the security property is set to the fully qualified name of a - * CallbackHandler implementation class, - * then a LoginContext will load the specified - * CallbackHandler and pass it to the underlying LoginModules. - * The LoginContext only loads the default handler + * {@code CallbackHandler} implementation class, + * then a {@code LoginContext} will load the specified + * {@code CallbackHandler} and pass it to the underlying LoginModules. + * The {@code LoginContext} only loads the default handler * if it was not provided one. * *

    All default handler implementations must provide a public @@ -71,11 +71,11 @@ public interface CallbackHandler { *

    Retrieve or display the information requested in the * provided Callbacks. * - *

    The handle method implementation checks the - * instance(s) of the Callback object(s) passed in + *

    The {@code handle} method implementation checks the + * instance(s) of the {@code Callback} object(s) passed in * to retrieve or display the requested information. * The following example is provided to help demonstrate what an - * handle method implementation might look like. + * {@code handle} method implementation might look like. * This example code is for guidance only. Many details, * including proper error handling, are left out for simplicity. * @@ -135,7 +135,7 @@ public interface CallbackHandler { * } * } * - * @param callbacks an array of Callback objects provided + * @param callbacks an array of {@code Callback} objects provided * by an underlying security service which contains * the information requested to be retrieved or displayed. * @@ -143,7 +143,7 @@ public interface CallbackHandler { * * @exception UnsupportedCallbackException if the implementation of this * method does not support one or more of the Callbacks - * specified in the callbacks parameter. + * specified in the {@code callbacks} parameter. */ void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException; diff --git a/jdk/src/share/classes/javax/security/auth/callback/ChoiceCallback.java b/jdk/src/share/classes/javax/security/auth/callback/ChoiceCallback.java index 422e50cb841..215a8dd790e 100644 --- a/jdk/src/share/classes/javax/security/auth/callback/ChoiceCallback.java +++ b/jdk/src/share/classes/javax/security/auth/callback/ChoiceCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ package javax.security.auth.callback; /** *

    Underlying security services instantiate and pass a - * ChoiceCallback to the handle - * method of a CallbackHandler to display a list of choices + * {@code ChoiceCallback} to the {@code handle} + * method of a {@code CallbackHandler} to display a list of choices * and to retrieve the selected choice(s). * * @see javax.security.auth.callback.CallbackHandler @@ -60,13 +60,13 @@ public class ChoiceCallback implements Callback, java.io.Serializable { private boolean multipleSelectionsAllowed; /** * @serial the selected choices, represented as indexes into the - * choices list. + * {@code choices} list. * @since 1.4 */ private int[] selections; /** - * Construct a ChoiceCallback with a prompt, + * Construct a {@code ChoiceCallback} with a prompt, * a list of choices, a default choice, and a boolean specifying * whether or not multiple selections from the list of choices are allowed. * @@ -79,21 +79,21 @@ public class ChoiceCallback implements Callback, java.io.Serializable { * @param defaultChoice the choice to be used as the default choice * when the list of choices are displayed. This value * is represented as an index into the - * choices array.

    + * {@code choices} array.

    * * @param multipleSelectionsAllowed boolean specifying whether or * not multiple selections can be made from the * list of choices. * - * @exception IllegalArgumentException if prompt is null, - * if prompt has a length of 0, - * if choices is null, - * if choices has a length of 0, - * if any element from choices is null, - * if any element from choices - * has a length of 0 or if defaultChoice + * @exception IllegalArgumentException if {@code prompt} is null, + * if {@code prompt} has a length of 0, + * if {@code choices} is null, + * if {@code choices} has a length of 0, + * if any element from {@code choices} is null, + * if any element from {@code choices} + * has a length of 0 or if {@code defaultChoice} * does not fall within the array boundaries of - * choices. + * {@code choices}. */ public ChoiceCallback(String prompt, String[] choices, int defaultChoice, boolean multipleSelectionsAllowed) { @@ -142,7 +142,7 @@ public class ChoiceCallback implements Callback, java.io.Serializable { *

    * * @return the defaultChoice, represented as an index into - * the choices list. + * the {@code choices} list. */ public int getDefaultChoice() { return defaultChoice; @@ -150,7 +150,7 @@ public class ChoiceCallback implements Callback, java.io.Serializable { /** * Get the boolean determining whether multiple selections from - * the choices list are allowed. + * the {@code choices} list are allowed. * *

    * @@ -166,7 +166,7 @@ public class ChoiceCallback implements Callback, java.io.Serializable { *

    * * @param selection the selection represented as an index into the - * choices list. + * {@code choices} list. * * @see #getSelectedIndexes */ @@ -181,11 +181,11 @@ public class ChoiceCallback implements Callback, java.io.Serializable { *

    * * @param selections the selections represented as indexes into the - * choices list. + * {@code choices} list. * * @exception UnsupportedOperationException if multiple selections are * not allowed, as determined by - * allowMultipleSelections. + * {@code allowMultipleSelections}. * * @see #getSelectedIndexes */ @@ -201,7 +201,7 @@ public class ChoiceCallback implements Callback, java.io.Serializable { *

    * * @return the selected choices, represented as indexes into the - * choices list. + * {@code choices} list. * * @see #setSelectedIndexes */ diff --git a/jdk/src/share/classes/javax/security/auth/callback/ConfirmationCallback.java b/jdk/src/share/classes/javax/security/auth/callback/ConfirmationCallback.java index a410c7b92cf..2d85c463ca9 100644 --- a/jdk/src/share/classes/javax/security/auth/callback/ConfirmationCallback.java +++ b/jdk/src/share/classes/javax/security/auth/callback/ConfirmationCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ package javax.security.auth.callback; /** *

    Underlying security services instantiate and pass a - * ConfirmationCallback to the handle - * method of a CallbackHandler to ask for YES/NO, + * {@code ConfirmationCallback} to the {@code handle} + * method of a {@code CallbackHandler} to ask for YES/NO, * OK/CANCEL, YES/NO/CANCEL or other similar confirmations. * * @see javax.security.auth.callback.CallbackHandler @@ -40,9 +40,9 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { /** * Unspecified option type. * - *

    The getOptionType method returns this - * value if this ConfirmationCallback was instantiated - * with options instead of an optionType. + *

    The {@code getOptionType} method returns this + * value if this {@code ConfirmationCallback} was instantiated + * with {@code options} instead of an {@code optionType}. */ public static final int UNSPECIFIED_OPTION = -1; @@ -50,9 +50,9 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { * YES/NO confirmation option. * *

    An underlying security service specifies this as the - * optionType to a ConfirmationCallback + * {@code optionType} to a {@code ConfirmationCallback} * constructor if it requires a confirmation which can be answered - * with either YES or NO. + * with either {@code YES} or {@code NO}. */ public static final int YES_NO_OPTION = 0; @@ -60,9 +60,9 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { * YES/NO/CANCEL confirmation confirmation option. * *

    An underlying security service specifies this as the - * optionType to a ConfirmationCallback + * {@code optionType} to a {@code ConfirmationCallback} * constructor if it requires a confirmation which can be answered - * with either YES, NO or CANCEL. + * with either {@code YES}, {@code NO} or {@code CANCEL}. */ public static final int YES_NO_CANCEL_OPTION = 1; @@ -70,45 +70,45 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { * OK/CANCEL confirmation confirmation option. * *

    An underlying security service specifies this as the - * optionType to a ConfirmationCallback + * {@code optionType} to a {@code ConfirmationCallback} * constructor if it requires a confirmation which can be answered - * with either OK or CANCEL. + * with either {@code OK} or {@code CANCEL}. */ public static final int OK_CANCEL_OPTION = 2; /** * YES option. * - *

    If an optionType was specified to this - * ConfirmationCallback, this option may be specified as a - * defaultOption or returned as the selected index. + *

    If an {@code optionType} was specified to this + * {@code ConfirmationCallback}, this option may be specified as a + * {@code defaultOption} or returned as the selected index. */ public static final int YES = 0; /** * NO option. * - *

    If an optionType was specified to this - * ConfirmationCallback, this option may be specified as a - * defaultOption or returned as the selected index. + *

    If an {@code optionType} was specified to this + * {@code ConfirmationCallback}, this option may be specified as a + * {@code defaultOption} or returned as the selected index. */ public static final int NO = 1; /** * CANCEL option. * - *

    If an optionType was specified to this - * ConfirmationCallback, this option may be specified as a - * defaultOption or returned as the selected index. + *

    If an {@code optionType} was specified to this + * {@code ConfirmationCallback}, this option may be specified as a + * {@code defaultOption} or returned as the selected index. */ public static final int CANCEL = 2; /** * OK option. * - *

    If an optionType was specified to this - * ConfirmationCallback, this option may be specified as a - * defaultOption or returned as the selected index. + *

    If an {@code optionType} was specified to this + * {@code ConfirmationCallback}, this option may be specified as a + * {@code defaultOption} or returned as the selected index. */ public static final int OK = 3; @@ -152,7 +152,7 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { private int selection; /** - * Construct a ConfirmationCallback with a + * Construct a {@code ConfirmationCallback} with a * message type, an option type and a default option. * *

    Underlying security services use this constructor if @@ -161,27 +161,27 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { * *

    * - * @param messageType the message type (INFORMATION, - * WARNING or ERROR).

    + * @param messageType the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}).

    * - * @param optionType the option type (YES_NO_OPTION, - * YES_NO_CANCEL_OPTION or - * OK_CANCEL_OPTION).

    + * @param optionType the option type ({@code YES_NO_OPTION}, + * {@code YES_NO_CANCEL_OPTION} or + * {@code OK_CANCEL_OPTION}).

    * * @param defaultOption the default option - * from the provided optionType (YES, - * NO, CANCEL or - * OK). + * from the provided optionType ({@code YES}, + * {@code NO}, {@code CANCEL} or + * {@code OK}). * * @exception IllegalArgumentException if messageType is not either - * INFORMATION, WARNING, - * or ERROR, if optionType is not either - * YES_NO_OPTION, - * YES_NO_CANCEL_OPTION, or - * OK_CANCEL_OPTION, - * or if defaultOption + * {@code INFORMATION}, {@code WARNING}, + * or {@code ERROR}, if optionType is not either + * {@code YES_NO_OPTION}, + * {@code YES_NO_CANCEL_OPTION}, or + * {@code OK_CANCEL_OPTION}, + * or if {@code defaultOption} * does not correspond to one of the options in - * optionType. + * {@code optionType}. */ public ConfirmationCallback(int messageType, int optionType, int defaultOption) { @@ -212,35 +212,35 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { } /** - * Construct a ConfirmationCallback with a + * Construct a {@code ConfirmationCallback} with a * message type, a list of options and a default option. * *

    Underlying security services use this constructor if * they require a confirmation different from the available preset * confirmations provided (for example, CONTINUE/ABORT or STOP/GO). - * The confirmation options are listed in the options array, - * and are displayed by the CallbackHandler implementation + * The confirmation options are listed in the {@code options} array, + * and are displayed by the {@code CallbackHandler} implementation * in a manner consistent with the way preset options are displayed. * *

    * - * @param messageType the message type (INFORMATION, - * WARNING or ERROR).

    + * @param messageType the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}).

    * * @param options the list of confirmation options.

    * * @param defaultOption the default option, represented as an index - * into the options array. + * into the {@code options} array. * * @exception IllegalArgumentException if messageType is not either - * INFORMATION, WARNING, - * or ERROR, if options is null, - * if options has a length of 0, - * if any element from options is null, - * if any element from options - * has a length of 0, or if defaultOption + * {@code INFORMATION}, {@code WARNING}, + * or {@code ERROR}, if {@code options} is null, + * if {@code options} has a length of 0, + * if any element from {@code options} is null, + * if any element from {@code options} + * has a length of 0, or if {@code defaultOption} * does not lie within the array boundaries of - * options. + * {@code options}. */ public ConfirmationCallback(int messageType, String[] options, int defaultOption) { @@ -261,7 +261,7 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { } /** - * Construct a ConfirmationCallback with a prompt, + * Construct a {@code ConfirmationCallback} with a prompt, * message type, an option type and a default option. * *

    Underlying security services use this constructor if @@ -272,29 +272,29 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { * * @param prompt the prompt used to describe the list of options.

    * - * @param messageType the message type (INFORMATION, - * WARNING or ERROR).

    + * @param messageType the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}).

    * - * @param optionType the option type (YES_NO_OPTION, - * YES_NO_CANCEL_OPTION or - * OK_CANCEL_OPTION).

    + * @param optionType the option type ({@code YES_NO_OPTION}, + * {@code YES_NO_CANCEL_OPTION} or + * {@code OK_CANCEL_OPTION}).

    * * @param defaultOption the default option - * from the provided optionType (YES, - * NO, CANCEL or - * OK). + * from the provided optionType ({@code YES}, + * {@code NO}, {@code CANCEL} or + * {@code OK}). * - * @exception IllegalArgumentException if prompt is null, - * if prompt has a length of 0, + * @exception IllegalArgumentException if {@code prompt} is null, + * if {@code prompt} has a length of 0, * if messageType is not either - * INFORMATION, WARNING, - * or ERROR, if optionType is not either - * YES_NO_OPTION, - * YES_NO_CANCEL_OPTION, or - * OK_CANCEL_OPTION, - * or if defaultOption + * {@code INFORMATION}, {@code WARNING}, + * or {@code ERROR}, if optionType is not either + * {@code YES_NO_OPTION}, + * {@code YES_NO_CANCEL_OPTION}, or + * {@code OK_CANCEL_OPTION}, + * or if {@code defaultOption} * does not correspond to one of the options in - * optionType. + * {@code optionType}. */ public ConfirmationCallback(String prompt, int messageType, int optionType, int defaultOption) { @@ -327,39 +327,39 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { } /** - * Construct a ConfirmationCallback with a prompt, + * Construct a {@code ConfirmationCallback} with a prompt, * message type, a list of options and a default option. * *

    Underlying security services use this constructor if * they require a confirmation different from the available preset * confirmations provided (for example, CONTINUE/ABORT or STOP/GO). - * The confirmation options are listed in the options array, - * and are displayed by the CallbackHandler implementation + * The confirmation options are listed in the {@code options} array, + * and are displayed by the {@code CallbackHandler} implementation * in a manner consistent with the way preset options are displayed. * *

    * * @param prompt the prompt used to describe the list of options.

    * - * @param messageType the message type (INFORMATION, - * WARNING or ERROR).

    + * @param messageType the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}).

    * * @param options the list of confirmation options.

    * * @param defaultOption the default option, represented as an index - * into the options array. + * into the {@code options} array. * - * @exception IllegalArgumentException if prompt is null, - * if prompt has a length of 0, + * @exception IllegalArgumentException if {@code prompt} is null, + * if {@code prompt} has a length of 0, * if messageType is not either - * INFORMATION, WARNING, - * or ERROR, if options is null, - * if options has a length of 0, - * if any element from options is null, - * if any element from options - * has a length of 0, or if defaultOption + * {@code INFORMATION}, {@code WARNING}, + * or {@code ERROR}, if {@code options} is null, + * if {@code options} has a length of 0, + * if any element from {@code options} is null, + * if any element from {@code options} + * has a length of 0, or if {@code defaultOption} * does not lie within the array boundaries of - * options. + * {@code options}. */ public ConfirmationCallback(String prompt, int messageType, String[] options, int defaultOption) { @@ -386,8 +386,8 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { * *

    * - * @return the prompt, or null if this ConfirmationCallback - * was instantiated without a prompt. + * @return the prompt, or null if this {@code ConfirmationCallback} + * was instantiated without a {@code prompt}. */ public String getPrompt() { return prompt; @@ -398,8 +398,8 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { * *

    * - * @return the message type (INFORMATION, - * WARNING or ERROR). + * @return the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}). */ public int getMessageType() { return messageType; @@ -408,20 +408,20 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { /** * Get the option type. * - *

    If this method returns UNSPECIFIED_OPTION, then this - * ConfirmationCallback was instantiated with - * options instead of an optionType. - * In this case, invoke the getOptions method + *

    If this method returns {@code UNSPECIFIED_OPTION}, then this + * {@code ConfirmationCallback} was instantiated with + * {@code options} instead of an {@code optionType}. + * In this case, invoke the {@code getOptions} method * to determine which confirmation options to display. * *

    * - * @return the option type (YES_NO_OPTION, - * YES_NO_CANCEL_OPTION or - * OK_CANCEL_OPTION), or - * UNSPECIFIED_OPTION if this - * ConfirmationCallback was instantiated with - * options instead of an optionType. + * @return the option type ({@code YES_NO_OPTION}, + * {@code YES_NO_CANCEL_OPTION} or + * {@code OK_CANCEL_OPTION}), or + * {@code UNSPECIFIED_OPTION} if this + * {@code ConfirmationCallback} was instantiated with + * {@code options} instead of an {@code optionType}. */ public int getOptionType() { return optionType; @@ -433,8 +433,8 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { *

    * * @return the list of confirmation options, or null if this - * ConfirmationCallback was instantiated with - * an optionType instead of options. + * {@code ConfirmationCallback} was instantiated with + * an {@code optionType} instead of {@code options}. */ public String[] getOptions() { return options; @@ -446,14 +446,14 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { *

    * * @return the default option, represented as - * YES, NO, OK or - * CANCEL if an optionType + * {@code YES}, {@code NO}, {@code OK} or + * {@code CANCEL} if an {@code optionType} * was specified to the constructor of this - * ConfirmationCallback. + * {@code ConfirmationCallback}. * Otherwise, this method returns the default option as * an index into the - * options array specified to the constructor - * of this ConfirmationCallback. + * {@code options} array specified to the constructor + * of this {@code ConfirmationCallback}. */ public int getDefaultOption() { return defaultOption; @@ -464,13 +464,13 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { * *

    * - * @param selection the selection represented as YES, - * NO, OK or CANCEL - * if an optionType was specified to the constructor - * of this ConfirmationCallback. + * @param selection the selection represented as {@code YES}, + * {@code NO}, {@code OK} or {@code CANCEL} + * if an {@code optionType} was specified to the constructor + * of this {@code ConfirmationCallback}. * Otherwise, the selection represents the index into the - * options array specified to the constructor - * of this ConfirmationCallback. + * {@code options} array specified to the constructor + * of this {@code ConfirmationCallback}. * * @see #getSelectedIndex */ @@ -484,14 +484,14 @@ public class ConfirmationCallback implements Callback, java.io.Serializable { *

    * * @return the selected confirmation option represented as - * YES, NO, OK or - * CANCEL if an optionType + * {@code YES}, {@code NO}, {@code OK} or + * {@code CANCEL} if an {@code optionType} * was specified to the constructor of this - * ConfirmationCallback. + * {@code ConfirmationCallback}. * Otherwise, this method returns the selected confirmation * option as an index into the - * options array specified to the constructor - * of this ConfirmationCallback. + * {@code options} array specified to the constructor + * of this {@code ConfirmationCallback}. * * @see #setSelectedIndex */ diff --git a/jdk/src/share/classes/javax/security/auth/callback/LanguageCallback.java b/jdk/src/share/classes/javax/security/auth/callback/LanguageCallback.java index 8bcdb0900a8..007b8993420 100644 --- a/jdk/src/share/classes/javax/security/auth/callback/LanguageCallback.java +++ b/jdk/src/share/classes/javax/security/auth/callback/LanguageCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,8 @@ import java.util.Locale; /** *

    Underlying security services instantiate and pass a - * LanguageCallback to the handle - * method of a CallbackHandler to retrieve the Locale + * {@code LanguageCallback} to the {@code handle} + * method of a {@code CallbackHandler} to retrieve the {@code Locale} * used for localizing text. * * @see javax.security.auth.callback.CallbackHandler @@ -46,16 +46,16 @@ public class LanguageCallback implements Callback, java.io.Serializable { private Locale locale; /** - * Construct a LanguageCallback. + * Construct a {@code LanguageCallback}. */ public LanguageCallback() { } /** - * Set the retrieved Locale. + * Set the retrieved {@code Locale}. * *

    * - * @param locale the retrieved Locale. + * @param locale the retrieved {@code Locale}. * * @see #getLocale */ @@ -64,12 +64,12 @@ public class LanguageCallback implements Callback, java.io.Serializable { } /** - * Get the retrieved Locale. + * Get the retrieved {@code Locale}. * *

    * - * @return the retrieved Locale, or null - * if no Locale could be retrieved. + * @return the retrieved {@code Locale}, or null + * if no {@code Locale} could be retrieved. * * @see #setLocale */ diff --git a/jdk/src/share/classes/javax/security/auth/callback/NameCallback.java b/jdk/src/share/classes/javax/security/auth/callback/NameCallback.java index b8e92c6c40a..3dd380dc57b 100644 --- a/jdk/src/share/classes/javax/security/auth/callback/NameCallback.java +++ b/jdk/src/share/classes/javax/security/auth/callback/NameCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ package javax.security.auth.callback; /** *

    Underlying security services instantiate and pass a - * NameCallback to the handle - * method of a CallbackHandler to retrieve name information. + * {@code NameCallback} to the {@code handle} + * method of a {@code CallbackHandler} to retrieve name information. * * @see javax.security.auth.callback.CallbackHandler */ @@ -53,14 +53,14 @@ public class NameCallback implements Callback, java.io.Serializable { private String inputName; /** - * Construct a NameCallback with a prompt. + * Construct a {@code NameCallback} with a prompt. * *

    * * @param prompt the prompt used to request the name. * - * @exception IllegalArgumentException if prompt is null - * or if prompt has a length of 0. + * @exception IllegalArgumentException if {@code prompt} is null + * or if {@code prompt} has a length of 0. */ public NameCallback(String prompt) { if (prompt == null || prompt.length() == 0) @@ -69,7 +69,7 @@ public class NameCallback implements Callback, java.io.Serializable { } /** - * Construct a NameCallback with a prompt + * Construct a {@code NameCallback} with a prompt * and default name. * *

    @@ -79,10 +79,10 @@ public class NameCallback implements Callback, java.io.Serializable { * @param defaultName the name to be used as the default name displayed * with the prompt. * - * @exception IllegalArgumentException if prompt is null, - * if prompt has a length of 0, - * if defaultName is null, - * or if defaultName has a length of 0. + * @exception IllegalArgumentException if {@code prompt} is null, + * if {@code prompt} has a length of 0, + * if {@code defaultName} is null, + * or if {@code defaultName} has a length of 0. */ public NameCallback(String prompt, String defaultName) { if (prompt == null || prompt.length() == 0 || @@ -109,8 +109,8 @@ public class NameCallback implements Callback, java.io.Serializable { * *

    * - * @return the default name, or null if this NameCallback - * was not instantiated with a defaultName. + * @return the default name, or null if this {@code NameCallback} + * was not instantiated with a {@code defaultName}. */ public String getDefaultName() { return defaultName; diff --git a/jdk/src/share/classes/javax/security/auth/callback/PasswordCallback.java b/jdk/src/share/classes/javax/security/auth/callback/PasswordCallback.java index d0407403365..0e8fb7bd794 100644 --- a/jdk/src/share/classes/javax/security/auth/callback/PasswordCallback.java +++ b/jdk/src/share/classes/javax/security/auth/callback/PasswordCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ package javax.security.auth.callback; /** *

    Underlying security services instantiate and pass a - * PasswordCallback to the handle - * method of a CallbackHandler to retrieve password information. + * {@code PasswordCallback} to the {@code handle} + * method of a {@code CallbackHandler} to retrieve password information. * * @see javax.security.auth.callback.CallbackHandler */ @@ -53,7 +53,7 @@ public class PasswordCallback implements Callback, java.io.Serializable { private char[] inputPassword; /** - * Construct a PasswordCallback with a prompt + * Construct a {@code PasswordCallback} with a prompt * and a boolean specifying whether the password should be displayed * as it is being typed. * @@ -64,8 +64,8 @@ public class PasswordCallback implements Callback, java.io.Serializable { * @param echoOn true if the password should be displayed * as it is being typed. * - * @exception IllegalArgumentException if prompt is null or - * if prompt has a length of 0. + * @exception IllegalArgumentException if {@code prompt} is null or + * if {@code prompt} has a length of 0. */ public PasswordCallback(String prompt, boolean echoOn) { if (prompt == null || prompt.length() == 0) diff --git a/jdk/src/share/classes/javax/security/auth/callback/TextInputCallback.java b/jdk/src/share/classes/javax/security/auth/callback/TextInputCallback.java index a611beae8e4..eb4e81eac51 100644 --- a/jdk/src/share/classes/javax/security/auth/callback/TextInputCallback.java +++ b/jdk/src/share/classes/javax/security/auth/callback/TextInputCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ package javax.security.auth.callback; /** *

    Underlying security services instantiate and pass a - * TextInputCallback to the handle - * method of a CallbackHandler to retrieve generic text + * {@code TextInputCallback} to the {@code handle} + * method of a {@code CallbackHandler} to retrieve generic text * information. * * @see javax.security.auth.callback.CallbackHandler @@ -54,14 +54,14 @@ public class TextInputCallback implements Callback, java.io.Serializable { private String inputText; /** - * Construct a TextInputCallback with a prompt. + * Construct a {@code TextInputCallback} with a prompt. * *

    * * @param prompt the prompt used to request the information. * - * @exception IllegalArgumentException if prompt is null - * or if prompt has a length of 0. + * @exception IllegalArgumentException if {@code prompt} is null + * or if {@code prompt} has a length of 0. */ public TextInputCallback(String prompt) { if (prompt == null || prompt.length() == 0) @@ -70,7 +70,7 @@ public class TextInputCallback implements Callback, java.io.Serializable { } /** - * Construct a TextInputCallback with a prompt + * Construct a {@code TextInputCallback} with a prompt * and default input value. * *

    @@ -80,10 +80,10 @@ public class TextInputCallback implements Callback, java.io.Serializable { * @param defaultText the text to be used as the default text displayed * with the prompt. * - * @exception IllegalArgumentException if prompt is null, - * if prompt has a length of 0, - * if defaultText is null - * or if defaultText has a length of 0. + * @exception IllegalArgumentException if {@code prompt} is null, + * if {@code prompt} has a length of 0, + * if {@code defaultText} is null + * or if {@code defaultText} has a length of 0. */ public TextInputCallback(String prompt, String defaultText) { if (prompt == null || prompt.length() == 0 || @@ -110,8 +110,8 @@ public class TextInputCallback implements Callback, java.io.Serializable { * *

    * - * @return the default text, or null if this TextInputCallback - * was not instantiated with defaultText. + * @return the default text, or null if this {@code TextInputCallback} + * was not instantiated with {@code defaultText}. */ public String getDefaultText() { return defaultText; diff --git a/jdk/src/share/classes/javax/security/auth/callback/TextOutputCallback.java b/jdk/src/share/classes/javax/security/auth/callback/TextOutputCallback.java index f8bc4605d71..f83295574c2 100644 --- a/jdk/src/share/classes/javax/security/auth/callback/TextOutputCallback.java +++ b/jdk/src/share/classes/javax/security/auth/callback/TextOutputCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ package javax.security.auth.callback; /** *

    Underlying security services instantiate and pass a - * TextOutputCallback to the handle - * method of a CallbackHandler to display information messages, + * {@code TextOutputCallback} to the {@code handle} + * method of a {@code CallbackHandler} to display information messages, * warning messages and error messages. * * @see javax.security.auth.callback.CallbackHandler @@ -61,16 +61,16 @@ public class TextOutputCallback implements Callback, java.io.Serializable { * *

    * - * @param messageType the message type (INFORMATION, - * WARNING or ERROR).

    + * @param messageType the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}).

    * * @param message the message to be displayed.

    * - * @exception IllegalArgumentException if messageType - * is not either INFORMATION, - * WARNING or ERROR, - * if message is null, - * or if message has a length of 0. + * @exception IllegalArgumentException if {@code messageType} + * is not either {@code INFORMATION}, + * {@code WARNING} or {@code ERROR}, + * if {@code message} is null, + * or if {@code message} has a length of 0. */ public TextOutputCallback(int messageType, String message) { if ((messageType != INFORMATION && @@ -87,8 +87,8 @@ public class TextOutputCallback implements Callback, java.io.Serializable { * *

    * - * @return the message type (INFORMATION, - * WARNING or ERROR). + * @return the message type ({@code INFORMATION}, + * {@code WARNING} or {@code ERROR}). */ public int getMessageType() { return messageType; diff --git a/jdk/src/share/classes/javax/security/auth/callback/UnsupportedCallbackException.java b/jdk/src/share/classes/javax/security/auth/callback/UnsupportedCallbackException.java index cb9b66b0000..0a9fa5120b1 100644 --- a/jdk/src/share/classes/javax/security/auth/callback/UnsupportedCallbackException.java +++ b/jdk/src/share/classes/javax/security/auth/callback/UnsupportedCallbackException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * 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,8 +26,8 @@ package javax.security.auth.callback; /** - * Signals that a CallbackHandler does not - * recognize a particular Callback. + * Signals that a {@code CallbackHandler} does not + * recognize a particular {@code Callback}. * */ public class UnsupportedCallbackException extends Exception { @@ -40,12 +40,12 @@ public class UnsupportedCallbackException extends Exception { private Callback callback; /** - * Constructs a UnsupportedCallbackException + * Constructs a {@code UnsupportedCallbackException} * with no detail message. * *

    * - * @param callback the unrecognized Callback. + * @param callback the unrecognized {@code Callback}. */ public UnsupportedCallbackException(Callback callback) { super(); @@ -59,7 +59,7 @@ public class UnsupportedCallbackException extends Exception { * *

    * - * @param callback the unrecognized Callback.

    + * @param callback the unrecognized {@code Callback}.

    * * @param msg the detail message. */ @@ -69,11 +69,11 @@ public class UnsupportedCallbackException extends Exception { } /** - * Get the unrecognized Callback. + * Get the unrecognized {@code Callback}. * *

    * - * @return the unrecognized Callback. + * @return the unrecognized {@code Callback}. */ public Callback getCallback() { return callback; diff --git a/jdk/src/share/classes/javax/security/auth/callback/package-info.java b/jdk/src/share/classes/javax/security/auth/callback/package-info.java new file mode 100644 index 00000000000..4cd5daf621e --- /dev/null +++ b/jdk/src/share/classes/javax/security/auth/callback/package-info.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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. + */ + +/** + * This package provides the classes necessary for services + * to interact with applications in order to retrieve + * information (authentication data including usernames + * or passwords, for example) or to display information + * (error and warning messages, for example). + * + * @since JDK1.4 + */ +package javax.security.auth.callback; diff --git a/jdk/src/share/classes/javax/security/auth/callback/package.html b/jdk/src/share/classes/javax/security/auth/callback/package.html deleted file mode 100644 index 66d58e4f055..00000000000 --- a/jdk/src/share/classes/javax/security/auth/callback/package.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - This package provides the classes necessary for services - to interact with applications in order to retrieve - information (authentication data including usernames - or passwords, for example) or to display information - (error and warning messages, for example). - - - -@since JDK1.4 - - diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/DelegationPermission.java b/jdk/src/share/classes/javax/security/auth/kerberos/DelegationPermission.java index 689175acd48..77aabb8b9d6 100644 --- a/jdk/src/share/classes/javax/security/auth/kerberos/DelegationPermission.java +++ b/jdk/src/share/classes/javax/security/auth/kerberos/DelegationPermission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ import java.io.IOException; * This class is used to restrict the usage of the Kerberos * delegation model, ie: forwardable and proxiable tickets. *

    - * The target name of this Permission specifies a pair of + * The target name of this {@code Permission} specifies a pair of * kerberos service principals. The first is the subordinate service principal * being entrusted to use the TGT. The second service principal designates * the target service the subordinate service principal is to @@ -71,15 +71,15 @@ public final class DelegationPermission extends BasicPermission private transient String subordinate, service; /** - * Create a new DelegationPermission + * Create a new {@code DelegationPermission} * with the specified subordinate and target principals. * *

    * * @param principals the name of the subordinate and target principals * - * @throws NullPointerException if principals is null. - * @throws IllegalArgumentException if principals is empty. + * @throws NullPointerException if {@code principals} is {@code null}. + * @throws IllegalArgumentException if {@code principals} is empty. */ public DelegationPermission(String principals) { super(principals); @@ -87,7 +87,7 @@ public final class DelegationPermission extends BasicPermission } /** - * Create a new DelegationPermission + * Create a new {@code DelegationPermission} * with the specified subordinate and target principals. *

    * @@ -95,8 +95,8 @@ public final class DelegationPermission extends BasicPermission *

    * @param actions should be null. * - * @throws NullPointerException if principals is null. - * @throws IllegalArgumentException if principals is empty. + * @throws NullPointerException if {@code principals} is {@code null}. + * @throws IllegalArgumentException if {@code principals} is empty. */ public DelegationPermission(String principals, String actions) { super(principals, actions); @@ -134,7 +134,7 @@ public final class DelegationPermission extends BasicPermission * Checks if this Kerberos delegation permission object "implies" the * specified permission. *

    - * If none of the above are true, implies returns false. + * If none of the above are true, {@code implies} returns false. * @param p the permission to check against. * * @return true if the specified permission is implied by this object, diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosKey.java b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosKey.java index ba530f9583c..5c8b65f2703 100644 --- a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosKey.java +++ b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,7 @@ public class KerberosKey implements SecretKey, Destroyable { private int versionNum; /** - * KeyImpl is serialized by writing out the ASN1 Encoded bytes + * {@code KeyImpl} is serialized by writing out the ASN1 Encoded bytes * of the encryption key. * The ASN1 encoding is defined in RFC4120 and as follows: *

    @@ -241,7 +241,7 @@ public class KerberosKey implements SecretKey, Destroyable {
         /**
          * Returns a hashcode for this KerberosKey.
          *
    -     * @return a hashCode() for the KerberosKey
    +     * @return a hashCode() for the {@code KerberosKey}
          * @since 1.6
          */
         public int hashCode() {
    @@ -260,8 +260,8 @@ public class KerberosKey implements SecretKey, Destroyable {
         /**
          * Compares the specified Object with this KerberosKey for equality.
          * Returns true if the given object is also a
    -     * KerberosKey and the two
    -     * KerberosKey instances are equivalent.
    +     * {@code KerberosKey} and the two
    +     * {@code KerberosKey} instances are equivalent.
          *
          * @param other the Object to compare to
          * @return true if the specified object is equal to this KerberosKey,
    diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java
    index fac9097500d..6962f2a43d3 100644
    --- a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java
    +++ b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -181,11 +181,11 @@ public final class KerberosPrincipal
         /**
          * Returns a hashcode for this principal. The hash code is defined to
          * be the result of the following  calculation:
    -     * 
    
    +     * 
    {@code
          *  hashCode = getName().hashCode();
    -     * 
    + * }
    * - * @return a hashCode() for the KerberosPrincipal + * @return a hashCode() for the {@code KerberosPrincipal} */ public int hashCode() { return getName().hashCode(); @@ -194,11 +194,11 @@ public final class KerberosPrincipal /** * Compares the specified Object with this Principal for equality. * Returns true if the given object is also a - * KerberosPrincipal and the two - * KerberosPrincipal instances are equivalent. - * More formally two KerberosPrincipal instances are equal - * if the values returned by getName() are equal and the - * values returned by getNameType() are equal. + * {@code KerberosPrincipal} and the two + * {@code KerberosPrincipal} instances are equivalent. + * More formally two {@code KerberosPrincipal} instances are equal + * if the values returned by {@code getName()} are equal and the + * values returned by {@code getNameType()} are equal. * * @param other the Object to compare to * @return true if the Object passed in represents the same principal @@ -225,7 +225,7 @@ public final class KerberosPrincipal /** * Save the KerberosPrincipal object to a stream * - * @serialData this KerberosPrincipal is serialized + * @serialData this {@code KerberosPrincipal} is serialized * by writing out the PrincipalName and the * realm in their DER-encoded form as specified in Section 5.2.2 of * RFC4120. diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java index e7e4821bd69..c9e2b283e98 100644 --- a/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java +++ b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,7 +103,7 @@ public class KerberosTicket implements Destroyable, Refreshable, private byte[] asn1Encoding; /** - *KeyImpl is serialized by writing out the ASN1 Encoded bytes + *{@code KeyImpl} is serialized by writing out the ASN1 Encoded bytes * of the encryption key. The ASN1 encoding is defined in RFC4120 and as * follows: *
    @@ -667,7 +667,7 @@ public class KerberosTicket implements Destroyable, Refreshable,
         /**
          * Returns a hashcode for this KerberosTicket.
          *
    -     * @return a hashCode() for the KerberosTicket
    +     * @return a hashCode() for the {@code KerberosTicket}
          * @since 1.6
          */
         public int hashCode() {
    @@ -704,8 +704,8 @@ public class KerberosTicket implements Destroyable, Refreshable,
         /**
          * Compares the specified Object with this KerberosTicket for equality.
          * Returns true if the given object is also a
    -     * KerberosTicket and the two
    -     * KerberosTicket instances are equivalent.
    +     * {@code KerberosTicket} and the two
    +     * {@code KerberosTicket} instances are equivalent.
          *
          * @param other the Object to compare to
          * @return true if the specified object is equal to this KerberosTicket,
    diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java b/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java
    index 9755cb0a738..f4ee947212b 100644
    --- a/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java
    +++ b/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -166,7 +166,7 @@ class KeyImpl implements SecretKey, Destroyable, Serializable {
         }
     
         /**
    -     * @serialData this KeyImpl is serialized by
    +     * @serialData this {@code KeyImpl} is serialized by
          * writing out the ASN1 Encoded bytes of the encryption key.
          * The ASN1 encoding is defined in RFC4120 and as  follows:
          * EncryptionKey   ::= SEQUENCE {
    diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/KeyTab.java b/jdk/src/share/classes/javax/security/auth/kerberos/KeyTab.java
    index 32f644b5906..631b7d02275 100644
    --- a/jdk/src/share/classes/javax/security/auth/kerberos/KeyTab.java
    +++ b/jdk/src/share/classes/javax/security/auth/kerberos/KeyTab.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -312,7 +312,7 @@ public final class KeyTab {
         /**
          * Returns a hashcode for this KeyTab.
          *
    -     * @return a hashCode() for the KeyTab
    +     * @return a hashCode() for the {@code KeyTab}
          */
         public int hashCode() {
             return Objects.hash(file, princ, bound);
    @@ -321,8 +321,8 @@ public final class KeyTab {
         /**
          * Compares the specified Object with this KeyTab for equality.
          * Returns true if the given object is also a
    -     * KeyTab and the two
    -     * KeyTab instances are equivalent.
    +     * {@code KeyTab} and the two
    +     * {@code KeyTab} instances are equivalent.
          *
          * @param other the Object to compare to
          * @return true if the specified object is equal to this KeyTab
    diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/ServicePermission.java b/jdk/src/share/classes/javax/security/auth/kerberos/ServicePermission.java
    index 43296586f68..50a0517fa44 100644
    --- a/jdk/src/share/classes/javax/security/auth/kerberos/ServicePermission.java
    +++ b/jdk/src/share/classes/javax/security/auth/kerberos/ServicePermission.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -50,7 +50,7 @@ import java.io.IOException;
      * used within.
      * 

    * The service principal name is the canonical name of the - * KereberosPrincipal supplying the service, that is + * {@code KereberosPrincipal} supplying the service, that is * the KerberosPrincipal represents a Kerberos service * principal. This name is treated in a case sensitive manner. * An asterisk may appear by itself, to signify any service principal. @@ -135,9 +135,9 @@ public final class ServicePermission extends Permission // created and re-used in the getAction function. /** - * Create a new ServicePermission - * with the specified servicePrincipal - * and action. + * Create a new {@code ServicePermission} + * with the specified {@code servicePrincipal} + * and {@code action}. * * @param servicePrincipal the name of the service principal. * An asterisk may appear by itself, to signify any service principal. @@ -169,7 +169,7 @@ public final class ServicePermission extends Permission * Checks if this Kerberos service permission object "implies" the * specified permission. *

    - * If none of the above are true, implies returns false. + * If none of the above are true, {@code implies} returns false. * @param p the permission to check against. * * @return true if the specified permission is implied by this object, diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/package-info.java b/jdk/src/share/classes/javax/security/auth/kerberos/package-info.java new file mode 100644 index 00000000000..293745479d8 --- /dev/null +++ b/jdk/src/share/classes/javax/security/auth/kerberos/package-info.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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. + */ + +/** + * This package contains utility classes related to the Kerberos network + * authentication protocol. They do not provide much Kerberos support + * themselves.

    + * + * The Kerberos network authentication protocol is defined in + * RFC 4120. The Java + * platform contains support for the client side of Kerberos via the + * {@link org.ietf.jgss} package. There might also be + * a login module that implements + * {@link javax.security.auth.spi.LoginModule LoginModule} to authenticate + * Kerberos principals.

    + * + * You can provide the name of your default realm and Key Distribution + * Center (KDC) host for that realm using the system properties + * {@code java.security.krb5.realm} and {@code java.security.krb5.kdc}. + * Both properties must be set. + * Alternatively, the {@code java.security.krb5.conf} system property can + * be set to the location of an MIT style {@code krb5.conf} configuration + * file. If none of these system properties are set, the {@code krb5.conf} + * file is searched for in an implementation-specific manner. Typically, + * an implementation will first look for a {@code krb5.conf} file in + * {@code /lib/security} and failing that, in an OS-specific + * location.

    + * + * @since JDK1.4 + */ +package javax.security.auth.kerberos; diff --git a/jdk/src/share/classes/javax/security/auth/kerberos/package.html b/jdk/src/share/classes/javax/security/auth/kerberos/package.html deleted file mode 100644 index 2f8e92a5316..00000000000 --- a/jdk/src/share/classes/javax/security/auth/kerberos/package.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - This package contains utility classes related to the Kerberos network - authentication protocol. They do not provide much Kerberos support - themselves.

    - - The Kerberos network authentication protocol is defined in - RFC 4120. The Java - platform contains support for the client side of Kerberos via the - {@link org.ietf.jgss} package. There might also be - a login module that implements - {@link javax.security.auth.spi.LoginModule LoginModule} to authenticate - Kerberos principals.

    - - You can provide the name of your default realm and Key Distribution - Center (KDC) host for that realm using the system properties - {@code java.security.krb5.realm} and {@code java.security.krb5.kdc}. - Both properties must be set. - Alternatively, the {@code java.security.krb5.conf} system property can - be set to the location of an MIT style {@code krb5.conf} configuration - file. If none of these system properties are set, the {@code krb5.conf} - file is searched for in an implementation-specific manner. Typically, - an implementation will first look for a {@code krb5.conf} file in - {@code /lib/security} and failing that, in an OS-specific - location.

    - - -@since JDK1.4 - - diff --git a/jdk/src/share/classes/javax/security/auth/login/AccountExpiredException.java b/jdk/src/share/classes/javax/security/auth/login/AccountExpiredException.java index 40e8a138c85..e55536da025 100644 --- a/jdk/src/share/classes/javax/security/auth/login/AccountExpiredException.java +++ b/jdk/src/share/classes/javax/security/auth/login/AccountExpiredException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,9 +29,9 @@ package javax.security.auth.login; * Signals that a user account has expired. * *

    This exception is thrown by LoginModules when they determine - * that an account has expired. For example, a LoginModule, + * that an account has expired. For example, a {@code LoginModule}, * after successfully authenticating a user, may determine that the - * user's account has expired. In this case the LoginModule + * user's account has expired. In this case the {@code LoginModule} * throws this exception to notify the application. The application can * then take the appropriate steps to notify the user. * diff --git a/jdk/src/share/classes/javax/security/auth/login/AppConfigurationEntry.java b/jdk/src/share/classes/javax/security/auth/login/AppConfigurationEntry.java index 7c70d580cb9..05374db2e95 100644 --- a/jdk/src/share/classes/javax/security/auth/login/AppConfigurationEntry.java +++ b/jdk/src/share/classes/javax/security/auth/login/AppConfigurationEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,14 +29,14 @@ import java.util.Map; import java.util.Collections; /** - * This class represents a single LoginModule entry + * This class represents a single {@code LoginModule} entry * configured for the application specified in the - * getAppConfigurationEntry(String appName) - * method in the Configuration class. Each respective - * AppConfigurationEntry contains a LoginModule name, - * a control flag (specifying whether this LoginModule is + * {@code getAppConfigurationEntry(String appName)} + * method in the {@code Configuration} class. Each respective + * {@code AppConfigurationEntry} contains a {@code LoginModule} name, + * a control flag (specifying whether this {@code LoginModule} is * REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL), and LoginModule-specific - * options. Please refer to the Configuration class for + * options. Please refer to the {@code Configuration} class for * more information on the different control flags and their semantics. * * @see javax.security.auth.login.Configuration @@ -50,25 +50,25 @@ public class AppConfigurationEntry { /** * Default constructor for this class. * - *

    This entry represents a single LoginModule + *

    This entry represents a single {@code LoginModule} * entry configured for the application specified in the - * getAppConfigurationEntry(String appName) - * method from the Configuration class. + * {@code getAppConfigurationEntry(String appName)} + * method from the {@code Configuration} class. * * @param loginModuleName String representing the class name of the - * LoginModule configured for the + * {@code LoginModule} configured for the * specified application.

    * * @param controlFlag either REQUIRED, REQUISITE, SUFFICIENT, * or OPTIONAL.

    * - * @param options the options configured for this LoginModule. + * @param options the options configured for this {@code LoginModule}. * - * @exception IllegalArgumentException if loginModuleName - * is null, if LoginModuleName - * has a length of 0, if controlFlag + * @exception IllegalArgumentException if {@code loginModuleName} + * is null, if {@code LoginModuleName} + * has a length of 0, if {@code controlFlag} * is not either REQUIRED, REQUISITE, SUFFICIENT - * or OPTIONAL, or if options is null. + * or OPTIONAL, or if {@code options} is null. */ public AppConfigurationEntry(String loginModuleName, LoginModuleControlFlag controlFlag, @@ -88,9 +88,9 @@ public class AppConfigurationEntry { } /** - * Get the class name of the configured LoginModule. + * Get the class name of the configured {@code LoginModule}. * - * @return the class name of the configured LoginModule as + * @return the class name of the configured {@code LoginModule} as * a String. */ public String getLoginModuleName() { @@ -100,28 +100,28 @@ public class AppConfigurationEntry { /** * Return the controlFlag * (either REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL) - * for this LoginModule. + * for this {@code LoginModule}. * * @return the controlFlag * (either REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL) - * for this LoginModule. + * for this {@code LoginModule}. */ public LoginModuleControlFlag getControlFlag() { return controlFlag; } /** - * Get the options configured for this LoginModule. + * Get the options configured for this {@code LoginModule}. * - * @return the options configured for this LoginModule - * as an unmodifiable Map. + * @return the options configured for this {@code LoginModule} + * as an unmodifiable {@code Map}. */ public Map getOptions() { return options; } /** - * This class represents whether or not a LoginModule + * This class represents whether or not a {@code LoginModule} * is REQUIRED, REQUISITE, SUFFICIENT or OPTIONAL. */ public static class LoginModuleControlFlag { @@ -129,25 +129,25 @@ public class AppConfigurationEntry { private String controlFlag; /** - * Required LoginModule. + * Required {@code LoginModule}. */ public static final LoginModuleControlFlag REQUIRED = new LoginModuleControlFlag("required"); /** - * Requisite LoginModule. + * Requisite {@code LoginModule}. */ public static final LoginModuleControlFlag REQUISITE = new LoginModuleControlFlag("requisite"); /** - * Sufficient LoginModule. + * Sufficient {@code LoginModule}. */ public static final LoginModuleControlFlag SUFFICIENT = new LoginModuleControlFlag("sufficient"); /** - * Optional LoginModule. + * Optional {@code LoginModule}. */ public static final LoginModuleControlFlag OPTIONAL = new LoginModuleControlFlag("optional"); diff --git a/jdk/src/share/classes/javax/security/auth/login/Configuration.java b/jdk/src/share/classes/javax/security/auth/login/Configuration.java index ddfdd0a2a03..ff10a3bbf14 100644 --- a/jdk/src/share/classes/javax/security/auth/login/Configuration.java +++ b/jdk/src/share/classes/javax/security/auth/login/Configuration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,9 +49,9 @@ import sun.security.jca.GetInstance; * *

    A login configuration contains the following information. * Note that this example only represents the default syntax for the - * Configuration. Subclass implementations of this class + * {@code Configuration}. Subclass implementations of this class * may implement alternative syntaxes and may retrieve the - * Configuration from any source such as files, databases, + * {@code Configuration} from any source such as files, databases, * or servers. * *

    @@ -70,9 +70,9 @@ import sun.security.jca.GetInstance;
      *      };
      * 
    * - *

    Each entry in the Configuration is indexed via an + *

    Each entry in the {@code Configuration} is indexed via an * application name, Name, and contains a list of - * LoginModules configured for that application. Each LoginModule + * LoginModules configured for that application. Each {@code LoginModule} * is specified via its fully qualified class name. * Authentication proceeds down the module list in the exact order specified. * If an application does not have specific entry, @@ -83,55 +83,55 @@ import sun.security.jca.GetInstance; * valid values for Flag and their respective semantics: * *

    - *      1) Required     - The LoginModule is required to succeed.
    + *      1) Required     - The {@code LoginModule} is required to succeed.
      *                      If it succeeds or fails, authentication still continues
    - *                      to proceed down the LoginModule list.
    + *                      to proceed down the {@code LoginModule} list.
      *
    - *      2) Requisite    - The LoginModule is required to succeed.
    + *      2) Requisite    - The {@code LoginModule} is required to succeed.
      *                      If it succeeds, authentication continues down the
    - *                      LoginModule list.  If it fails,
    + *                      {@code LoginModule} list.  If it fails,
      *                      control immediately returns to the application
      *                      (authentication does not proceed down the
    - *                      LoginModule list).
    + *                      {@code LoginModule} list).
      *
    - *      3) Sufficient   - The LoginModule is not required to
    + *      3) Sufficient   - The {@code LoginModule} is not required to
      *                      succeed.  If it does succeed, control immediately
      *                      returns to the application (authentication does not
    - *                      proceed down the LoginModule list).
    + *                      proceed down the {@code LoginModule} list).
      *                      If it fails, authentication continues down the
    - *                      LoginModule list.
    + *                      {@code LoginModule} list.
      *
    - *      4) Optional     - The LoginModule is not required to
    + *      4) Optional     - The {@code LoginModule} is not required to
      *                      succeed.  If it succeeds or fails,
      *                      authentication still continues to proceed down the
    - *                      LoginModule list.
    + *                      {@code LoginModule} list.
      * 
    * *

    The overall authentication succeeds only if all Required and * Requisite LoginModules succeed. If a Sufficient - * LoginModule is configured and succeeds, + * {@code LoginModule} is configured and succeeds, * then only the Required and Requisite LoginModules prior to - * that Sufficient LoginModule need to have succeeded for + * that Sufficient {@code LoginModule} need to have succeeded for * the overall authentication to succeed. If no Required or * Requisite LoginModules are configured for an application, * then at least one Sufficient or Optional - * LoginModule must succeed. + * {@code LoginModule} must succeed. * *

    ModuleOptions is a space separated list of - * LoginModule-specific values which are passed directly to + * {@code LoginModule}-specific values which are passed directly to * the underlying LoginModules. Options are defined by the - * LoginModule itself, and control the behavior within it. - * For example, a LoginModule may define options to support + * {@code LoginModule} itself, and control the behavior within it. + * For example, a {@code LoginModule} may define options to support * debugging/testing capabilities. The correct way to specify options in the - * Configuration is by using the following key-value pairing: + * {@code Configuration} is by using the following key-value pairing: * debug="true". The key and value should be separated by an * 'equals' symbol, and the value should be surrounded by double quotes. * If a String in the form, ${system.property}, occurs in the value, * it will be expanded to the value of the system property. * Note that there is no limit to the number of - * options a LoginModule may define. + * options a {@code LoginModule} may define. * - *

    The following represents an example Configuration entry + *

    The following represents an example {@code Configuration} entry * based on the syntax above: * *

    @@ -143,7 +143,7 @@ import sun.security.jca.GetInstance;
      * };
      * 
    * - *

    This Configuration specifies that an application named, + *

    This {@code Configuration} specifies that an application named, * "Login", requires users to first authenticate to the * com.sun.security.auth.module.UnixLoginModule, which is * required to succeed. Even if the UnixLoginModule @@ -165,11 +165,11 @@ import sun.security.jca.GetInstance; * *

    There is only one Configuration object installed in the runtime at any * given time. A Configuration object can be installed by calling the - * setConfiguration method. The installed Configuration object - * can be obtained by calling the getConfiguration method. + * {@code setConfiguration} method. The installed Configuration object + * can be obtained by calling the {@code getConfiguration} method. * *

    If no Configuration object has been installed in the runtime, a call to - * getConfiguration installs an instance of the default + * {@code getConfiguration} installs an instance of the default * Configuration implementation (a default subclass implementation of this * abstract class). * The default Configuration implementation can be changed by setting the value @@ -178,7 +178,7 @@ import sun.security.jca.GetInstance; * *

    Application code can directly subclass Configuration to provide a custom * implementation. In addition, an instance of a Configuration object can be - * constructed by invoking one of the getInstance factory methods + * constructed by invoking one of the {@code getInstance} factory methods * with a standard type. The default policy type is "JavaLoginConfig". * See the Configuration section in the @@ -222,7 +222,7 @@ public abstract class Configuration { *

    * * @return the login Configuration. If a Configuration object was set - * via the Configuration.setConfiguration method, + * via the {@code Configuration.setConfiguration} method, * then that object is returned. Otherwise, a default * Configuration object is returned. * @@ -286,14 +286,14 @@ public abstract class Configuration { } /** - * Set the login Configuration. + * Set the login {@code Configuration}. * *

    * - * @param configuration the new Configuration + * @param configuration the new {@code Configuration} * * @exception SecurityException if the current thread does not have - * Permission to set the Configuration. + * Permission to set the {@code Configuration}. * * @see #getConfiguration */ @@ -505,7 +505,7 @@ public abstract class Configuration { * Return the Provider of this Configuration. * *

    This Configuration instance will only have a Provider if it - * was obtained via a call to Configuration.getInstance. + * was obtained via a call to {@code Configuration.getInstance}. * Otherwise this method returns null. * * @return the Provider of this Configuration, or null. @@ -520,7 +520,7 @@ public abstract class Configuration { * Return the type of this Configuration. * *

    This Configuration instance will only have a type if it - * was obtained via a call to Configuration.getInstance. + * was obtained via a call to {@code Configuration.getInstance}. * Otherwise this method returns null. * * @return the type of this Configuration, or null. @@ -535,7 +535,7 @@ public abstract class Configuration { * Return Configuration parameters. * *

    This Configuration instance will only have parameters if it - * was obtained via a call to Configuration.getInstance. + * was obtained via a call to {@code Configuration.getInstance}. * Otherwise this method returns null. * * @return Configuration parameters, or null. @@ -567,7 +567,7 @@ public abstract class Configuration { *

    This method causes this Configuration object to refresh/reload its * contents in an implementation-dependent manner. * For example, if this Configuration object stores its entries in a file, - * calling refresh may cause the file to be re-read. + * calling {@code refresh} may cause the file to be re-read. * *

    The default implementation of this method does nothing. * This method should be overridden if a refresh operation is supported diff --git a/jdk/src/share/classes/javax/security/auth/login/ConfigurationSpi.java b/jdk/src/share/classes/javax/security/auth/login/ConfigurationSpi.java index d7047d9b8e9..70c3e93302e 100644 --- a/jdk/src/share/classes/javax/security/auth/login/ConfigurationSpi.java +++ b/jdk/src/share/classes/javax/security/auth/login/ConfigurationSpi.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,15 +28,15 @@ package javax.security.auth.login; /** * This class defines the Service Provider Interface (SPI) - * for the Configuration class. + * for the {@code Configuration} class. * All the abstract methods in this class must be implemented by each * service provider who wishes to supply a Configuration implementation. * *

    Subclass implementations of this abstract class must provide - * a public constructor that takes a Configuration.Parameters + * a public constructor that takes a {@code Configuration.Parameters} * object as an input parameter. This constructor also must throw * an IllegalArgumentException if it does not understand the - * Configuration.Parameters input. + * {@code Configuration.Parameters} input. * * * @since 1.6 @@ -62,7 +62,7 @@ public abstract class ConfigurationSpi { *

    This method causes this Configuration object to refresh/reload its * contents in an implementation-dependent manner. * For example, if this Configuration object stores its entries in a file, - * calling refresh may cause the file to be re-read. + * calling {@code refresh} may cause the file to be re-read. * *

    The default implementation of this method does nothing. * This method should be overridden if a refresh operation is supported diff --git a/jdk/src/share/classes/javax/security/auth/login/CredentialExpiredException.java b/jdk/src/share/classes/javax/security/auth/login/CredentialExpiredException.java index c3298c00e16..1ab7ae8d52c 100644 --- a/jdk/src/share/classes/javax/security/auth/login/CredentialExpiredException.java +++ b/jdk/src/share/classes/javax/security/auth/login/CredentialExpiredException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * 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,14 +26,14 @@ package javax.security.auth.login; /** - * Signals that a Credential has expired. + * Signals that a {@code Credential} has expired. * *

    This exception is thrown by LoginModules when they determine - * that a Credential has expired. - * For example, a LoginModule authenticating a user - * in its login method may determine that the user's + * that a {@code Credential} has expired. + * For example, a {@code LoginModule} authenticating a user + * in its {@code login} method may determine that the user's * password, although entered correctly, has expired. In this case - * the LoginModule throws this exception to notify + * the {@code LoginModule} throws this exception to notify * the application. The application can then take the appropriate * steps to assist the user in updating the password. * diff --git a/jdk/src/share/classes/javax/security/auth/login/FailedLoginException.java b/jdk/src/share/classes/javax/security/auth/login/FailedLoginException.java index 5c632bbeedc..4c6f74cc2de 100644 --- a/jdk/src/share/classes/javax/security/auth/login/FailedLoginException.java +++ b/jdk/src/share/classes/javax/security/auth/login/FailedLoginException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ package javax.security.auth.login; * Signals that user authentication failed. * *

    This exception is thrown by LoginModules if authentication failed. - * For example, a LoginModule throws this exception if + * For example, a {@code LoginModule} throws this exception if * the user entered an incorrect password. * */ diff --git a/jdk/src/share/classes/javax/security/auth/login/LoginContext.java b/jdk/src/share/classes/javax/security/auth/login/LoginContext.java index e3729d2645b..a9685bca811 100644 --- a/jdk/src/share/classes/javax/security/auth/login/LoginContext.java +++ b/jdk/src/share/classes/javax/security/auth/login/LoginContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,11 +41,11 @@ import sun.security.util.PendingException; import sun.security.util.ResourcesMgr; /** - *

    The LoginContext class describes the basic methods used + *

    The {@code LoginContext} class describes the basic methods used * to authenticate Subjects and provides a way to develop an * application independent of the underlying authentication technology. - * A Configuration specifies the authentication technology, or - * LoginModule, to be used with a particular application. + * A {@code Configuration} specifies the authentication technology, or + * {@code LoginModule}, to be used with a particular application. * Different LoginModules can be plugged in under an application * without requiring any modifications to the application itself. * @@ -57,36 +57,36 @@ import sun.security.util.ResourcesMgr; * LoginModule under an application. * *

    A typical caller instantiates a LoginContext with - * a name and a CallbackHandler. + * a name and a {@code CallbackHandler}. * LoginContext uses the name as the index into a * Configuration to determine which LoginModules should be used, * and which ones must succeed in order for the overall authentication to - * succeed. The CallbackHandler is passed to the underlying + * succeed. The {@code CallbackHandler} is passed to the underlying * LoginModules so they may communicate and interact with users * (prompting for a username and password via a graphical user interface, * for example). * *

    Once the caller has instantiated a LoginContext, - * it invokes the login method to authenticate - * a Subject. The login method invokes + * it invokes the {@code login} method to authenticate + * a {@code Subject}. The {@code login} method invokes * the configured modules to perform their respective types of authentication * (username/password, smart card pin verification, etc.). * Note that the LoginModules will not attempt authentication retries nor * introduce delays if the authentication fails. * Such tasks belong to the LoginContext caller. * - *

    If the login method returns without + *

    If the {@code login} method returns without * throwing an exception, then the overall authentication succeeded. * The caller can then retrieve * the newly authenticated Subject by invoking the - * getSubject method. Principals and Credentials associated + * {@code getSubject} method. Principals and Credentials associated * with the Subject may be retrieved by invoking the Subject's - * respective getPrincipals, getPublicCredentials, - * and getPrivateCredentials methods. + * respective {@code getPrincipals}, {@code getPublicCredentials}, + * and {@code getPrivateCredentials} methods. * *

    To logout the Subject, the caller calls - * the logout method. As with the login - * method, this logout method invokes the logout + * the {@code logout} method. As with the {@code login} + * method, this {@code logout} method invokes the {@code logout} * method for the configured modules. * *

    A LoginContext should not be used to authenticate @@ -96,14 +96,14 @@ import sun.security.util.ResourcesMgr; *

    The following documentation applies to all LoginContext constructors: *

      * - *
    1. Subject + *
    2. {@code Subject} *
        *
      • If the constructor has a Subject * input parameter, the LoginContext uses the caller-specified * Subject object. *

        - *

      • If the caller specifies a null Subject - * and a null value is permitted, + *
      • If the caller specifies a {@code null} Subject + * and a {@code null} value is permitted, * the LoginContext instantiates a new Subject. *

        *

      • If the constructor does not have a Subject @@ -111,14 +111,14 @@ import sun.security.util.ResourcesMgr; *

        *

      * - *
    3. Configuration + *
    4. {@code Configuration} *
        *
      • If the constructor has a Configuration * input parameter and the caller specifies a non-null Configuration, * the LoginContext uses the caller-specified Configuration. *

        * If the constructor does not have a Configuration - * input parameter, or if the caller specifies a null + * input parameter, or if the caller specifies a {@code null} * Configuration object, the constructor uses the following call to * get the installed Configuration: *

        @@ -126,42 +126,42 @@ import sun.security.util.ResourcesMgr;
          * 
        * For both cases, * the name argument given to the constructor is passed to the - * Configuration.getAppConfigurationEntry method. + * {@code Configuration.getAppConfigurationEntry} method. * If the Configuration has no entries for the specified name, - * then the LoginContext calls - * getAppConfigurationEntry with the name, "other" + * then the {@code LoginContext} calls + * {@code getAppConfigurationEntry} with the name, "other" * (the default entry name). If there is no entry for "other", - * then a LoginException is thrown. + * then a {@code LoginException} is thrown. *

        *

      • When LoginContext uses the installed Configuration, the caller * requires the createLoginContext.name and possibly * createLoginContext.other AuthPermissions. Furthermore, the * LoginContext will invoke configured modules from within an - * AccessController.doPrivileged call so that modules that + * {@code AccessController.doPrivileged} call so that modules that * perform security-sensitive tasks (such as connecting to remote hosts, * and updating the Subject) will require the respective permissions, but * the callers of the LoginContext will not require those permissions. *

        *

      • When LoginContext uses a caller-specified Configuration, the caller * does not require any createLoginContext AuthPermission. The LoginContext - * saves the AccessControlContext for the caller, + * saves the {@code AccessControlContext} for the caller, * and invokes the configured modules from within an - * AccessController.doPrivileged call constrained by that context. + * {@code AccessController.doPrivileged} call constrained by that context. * This means the caller context (stored when the LoginContext was created) * must have sufficient permissions to perform any security-sensitive tasks * that the modules may perform. *

        *

      * - *
    5. CallbackHandler + *
    6. {@code CallbackHandler} *
        *
      • If the constructor has a CallbackHandler * input parameter, the LoginContext uses the caller-specified * CallbackHandler object. *

        *

      • If the constructor does not have a CallbackHandler - * input parameter, or if the caller specifies a null - * CallbackHandler object (and a null value is permitted), + * input parameter, or if the caller specifies a {@code null} + * CallbackHandler object (and a {@code null} value is permitted), * the LoginContext queries the * {@code auth.login.defaultCallbackHandler} security property for the * fully qualified class name of a default handler @@ -177,10 +177,10 @@ import sun.security.util.ResourcesMgr; * then this LoginContext must wrap any * caller-specified or default CallbackHandler implementation * in a new CallbackHandler implementation - * whose handle method implementation invokes the - * specified CallbackHandler's handle method in a - * java.security.AccessController.doPrivileged call - * constrained by the caller's current AccessControlContext. + * whose {@code handle} method implementation invokes the + * specified CallbackHandler's {@code handle} method in a + * {@code java.security.AccessController.doPrivileged} call + * constrained by the caller's current {@code AccessControlContext}. *
      *
    * @@ -317,14 +317,14 @@ public class LoginContext { } /** - * Instantiate a new LoginContext object with a name. + * Instantiate a new {@code LoginContext} object with a name. * * @param name the name used as the index into the - * Configuration. + * {@code Configuration}. * - * @exception LoginException if the caller-specified name - * does not appear in the Configuration - * and there is no Configuration entry + * @exception LoginException if the caller-specified {@code name} + * does not appear in the {@code Configuration} + * and there is no {@code Configuration} entry * for "other", or if the * auth.login.defaultCallbackHandler * security property was set, but the implementation @@ -343,21 +343,21 @@ public class LoginContext { } /** - * Instantiate a new LoginContext object with a name - * and a Subject object. + * Instantiate a new {@code LoginContext} object with a name + * and a {@code Subject} object. * *

    * * @param name the name used as the index into the - * Configuration.

    + * {@code Configuration}.

    * - * @param subject the Subject to authenticate. + * @param subject the {@code Subject} to authenticate. * - * @exception LoginException if the caller-specified name - * does not appear in the Configuration - * and there is no Configuration entry - * for "other", if the caller-specified subject - * is null, or if the + * @exception LoginException if the caller-specified {@code name} + * does not appear in the {@code Configuration} + * and there is no {@code Configuration} entry + * for "other", if the caller-specified {@code subject} + * is {@code null}, or if the * auth.login.defaultCallbackHandler * security property was set, but the implementation * class could not be loaded. @@ -381,22 +381,22 @@ public class LoginContext { } /** - * Instantiate a new LoginContext object with a name - * and a CallbackHandler object. + * Instantiate a new {@code LoginContext} object with a name + * and a {@code CallbackHandler} object. * *

    * * @param name the name used as the index into the - * Configuration.

    + * {@code Configuration}.

    * - * @param callbackHandler the CallbackHandler object used by + * @param callbackHandler the {@code CallbackHandler} object used by * LoginModules to communicate with the user. * - * @exception LoginException if the caller-specified name - * does not appear in the Configuration - * and there is no Configuration entry + * @exception LoginException if the caller-specified {@code name} + * does not appear in the {@code Configuration} + * and there is no {@code Configuration} entry * for "other", or if the caller-specified - * callbackHandler is null. + * {@code callbackHandler} is {@code null}. *

    * @exception SecurityException if a SecurityManager is set and * the caller does not have @@ -417,27 +417,27 @@ public class LoginContext { } /** - * Instantiate a new LoginContext object with a name, - * a Subject to be authenticated, and a - * CallbackHandler object. + * Instantiate a new {@code LoginContext} object with a name, + * a {@code Subject} to be authenticated, and a + * {@code CallbackHandler} object. * *

    * * @param name the name used as the index into the - * Configuration.

    + * {@code Configuration}.

    * - * @param subject the Subject to authenticate.

    + * @param subject the {@code Subject} to authenticate.

    * - * @param callbackHandler the CallbackHandler object used by + * @param callbackHandler the {@code CallbackHandler} object used by * LoginModules to communicate with the user. * - * @exception LoginException if the caller-specified name - * does not appear in the Configuration - * and there is no Configuration entry + * @exception LoginException if the caller-specified {@code name} + * does not appear in the {@code Configuration} + * and there is no {@code Configuration} entry * for "other", or if the caller-specified - * subject is null, + * {@code subject} is {@code null}, * or if the caller-specified - * callbackHandler is null. + * {@code callbackHandler} is {@code null}. *

    * @exception SecurityException if a SecurityManager is set and * the caller does not have @@ -458,34 +458,34 @@ public class LoginContext { } /** - * Instantiate a new LoginContext object with a name, - * a Subject to be authenticated, - * a CallbackHandler object, and a login - * Configuration. + * Instantiate a new {@code LoginContext} object with a name, + * a {@code Subject} to be authenticated, + * a {@code CallbackHandler} object, and a login + * {@code Configuration}. * *

    * * @param name the name used as the index into the caller-specified - * Configuration.

    + * {@code Configuration}.

    * - * @param subject the Subject to authenticate, - * or null.

    + * @param subject the {@code Subject} to authenticate, + * or {@code null}.

    * - * @param callbackHandler the CallbackHandler object used by - * LoginModules to communicate with the user, or null. + * @param callbackHandler the {@code CallbackHandler} object used by + * LoginModules to communicate with the user, or {@code null}. *

    * - * @param config the Configuration that lists the + * @param config the {@code Configuration} that lists the * login modules to be called to perform the authentication, - * or null. + * or {@code null}. * - * @exception LoginException if the caller-specified name - * does not appear in the Configuration - * and there is no Configuration entry + * @exception LoginException if the caller-specified {@code name} + * does not appear in the {@code Configuration} + * and there is no {@code Configuration} entry * for "other". *

    * @exception SecurityException if a SecurityManager is set, - * config is null, + * config is {@code null}, * and either the caller does not have * AuthPermission("createLoginContext.name"), * or if a configuration entry for name does not exist and @@ -522,46 +522,46 @@ public class LoginContext { /** * Perform the authentication. * - *

    This method invokes the login method for each + *

    This method invokes the {@code login} method for each * LoginModule configured for the name specified to the - * LoginContext constructor, as determined by the login - * Configuration. Each LoginModule + * {@code LoginContext} constructor, as determined by the login + * {@code Configuration}. Each {@code LoginModule} * then performs its respective type of authentication * (username/password, smart card pin verification, etc.). * *

    This method completes a 2-phase authentication process by - * calling each configured LoginModule's commit method + * calling each configured LoginModule's {@code commit} method * if the overall authentication succeeded (the relevant REQUIRED, * REQUISITE, SUFFICIENT, and OPTIONAL LoginModules succeeded), - * or by calling each configured LoginModule's abort method + * or by calling each configured LoginModule's {@code abort} method * if the overall authentication failed. If authentication succeeded, - * each successful LoginModule's commit method associates - * the relevant Principals and Credentials with the Subject. - * If authentication failed, each LoginModule's abort method + * each successful LoginModule's {@code commit} method associates + * the relevant Principals and Credentials with the {@code Subject}. + * If authentication failed, each LoginModule's {@code abort} method * removes/destroys any previously stored state. * - *

    If the commit phase of the authentication process + *

    If the {@code commit} phase of the authentication process * fails, then the overall authentication fails and this method - * invokes the abort method for each configured - * LoginModule. + * invokes the {@code abort} method for each configured + * {@code LoginModule}. * - *

    If the abort phase + *

    If the {@code abort} phase * fails for any reason, then this method propagates the - * original exception thrown either during the login phase - * or the commit phase. In either case, the overall + * original exception thrown either during the {@code login} phase + * or the {@code commit} phase. In either case, the overall * authentication fails. * *

    In the case where multiple LoginModules fail, * this method propagates the exception raised by the first - * LoginModule which failed. + * {@code LoginModule} which failed. * - *

    Note that if this method enters the abort phase - * (either the login or commit phase failed), + *

    Note that if this method enters the {@code abort} phase + * (either the {@code login} or {@code commit} phase failed), * this method invokes all LoginModules configured for the - * application regardless of their respective Configuration - * flag parameters. Essentially this means that Requisite - * and Sufficient semantics are ignored during the - * abort phase. This guarantees that proper cleanup + * application regardless of their respective {@code Configuration} + * flag parameters. Essentially this means that {@code Requisite} + * and {@code Sufficient} semantics are ignored during the + * {@code abort} phase. This guarantees that proper cleanup * and state restoration can take place. * *

    @@ -602,19 +602,19 @@ public class LoginContext { } /** - * Logout the Subject. + * Logout the {@code Subject}. * - *

    This method invokes the logout method for each - * LoginModule configured for this LoginContext. - * Each LoginModule performs its respective logout procedure + *

    This method invokes the {@code logout} method for each + * {@code LoginModule} configured for this {@code LoginContext}. + * Each {@code LoginModule} performs its respective logout procedure * which may include removing/destroying - * Principal and Credential information - * from the Subject and state cleanup. + * {@code Principal} and {@code Credential} information + * from the {@code Subject} and state cleanup. * *

    Note that this method invokes all LoginModules configured for the * application regardless of their respective - * Configuration flag parameters. Essentially this means - * that Requisite and Sufficient semantics are + * {@code Configuration} flag parameters. Essentially this means + * that {@code Requisite} and {@code Sufficient} semantics are * ignored for this method. This guarantees that proper cleanup * and state restoration can take place. * diff --git a/jdk/src/share/classes/javax/security/auth/login/package-info.java b/jdk/src/share/classes/javax/security/auth/login/package-info.java new file mode 100644 index 00000000000..5b43480dc0a --- /dev/null +++ b/jdk/src/share/classes/javax/security/auth/login/package-info.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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. + */ + +/** + * This package provides a pluggable authentication framework. + *

    Package Specification

    + * + *
    + * + * @since 1.4 + */ +package javax.security.auth.login; diff --git a/jdk/src/share/classes/javax/security/auth/login/package.html b/jdk/src/share/classes/javax/security/auth/login/package.html deleted file mode 100644 index 0088f0771a5..00000000000 --- a/jdk/src/share/classes/javax/security/auth/login/package.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - This package provides a pluggable authentication framework. -

    Package Specification

    - - - - - -@since 1.4 - - diff --git a/jdk/src/share/classes/javax/security/auth/package-info.java b/jdk/src/share/classes/javax/security/auth/package-info.java new file mode 100644 index 00000000000..b4ac0827d22 --- /dev/null +++ b/jdk/src/share/classes/javax/security/auth/package-info.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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. + */ + +/** + * This package provides a framework for authentication and + * authorization. The framework allows + * authentication to be performed in pluggable fashion. Different + * authentication modules can be plugged under an application without + * requiring modifications to the application itself. The + * authorization component allows specification of access controls + * based on code location, code signers and code executors + * (Subjects). + * + * @since JDK1.4 + */ +package javax.security.auth; diff --git a/jdk/src/share/classes/javax/security/auth/package.html b/jdk/src/share/classes/javax/security/auth/package.html deleted file mode 100644 index dc8801f35ef..00000000000 --- a/jdk/src/share/classes/javax/security/auth/package.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - This package provides a framework for authentication and - authorization. The framework allows - authentication to be performed in pluggable fashion. Different - authentication modules can be plugged under an application without - requiring modifications to the application itself. The - authorization component allows specification of access controls - based on code location, code signers and code executors - (Subjects). - - - - -@since JDK1.4 - - diff --git a/jdk/src/share/classes/javax/security/auth/spi/LoginModule.java b/jdk/src/share/classes/javax/security/auth/spi/LoginModule.java index e8074973382..37b99086120 100644 --- a/jdk/src/share/classes/javax/security/auth/spi/LoginModule.java +++ b/jdk/src/share/classes/javax/security/auth/spi/LoginModule.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * 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,95 +32,95 @@ import javax.security.auth.login.*; import java.util.Map; /** - *

    LoginModule describes the interface + *

    {@code LoginModule} describes the interface * implemented by authentication technology providers. LoginModules * are plugged in under applications to provide a particular type of * authentication. * - *

    While applications write to the LoginContext API, + *

    While applications write to the {@code LoginContext} API, * authentication technology providers implement the - * LoginModule interface. - * A Configuration specifies the LoginModule(s) + * {@code LoginModule} interface. + * A {@code Configuration} specifies the LoginModule(s) * to be used with a particular login application. Therefore different * LoginModules can be plugged in under the application without * requiring any modifications to the application itself. * - *

    The LoginContext is responsible for reading the - * Configuration and instantiating the appropriate - * LoginModules. Each LoginModule is initialized with - * a Subject, a CallbackHandler, shared - * LoginModule state, and LoginModule-specific options. + *

    The {@code LoginContext} is responsible for reading the + * {@code Configuration} and instantiating the appropriate + * LoginModules. Each {@code LoginModule} is initialized with + * a {@code Subject}, a {@code CallbackHandler}, shared + * {@code LoginModule} state, and LoginModule-specific options. * - * The Subject represents the - * Subject currently being authenticated and is updated + * The {@code Subject} represents the + * {@code Subject} currently being authenticated and is updated * with relevant Credentials if authentication succeeds. - * LoginModules use the CallbackHandler to - * communicate with users. The CallbackHandler may be + * LoginModules use the {@code CallbackHandler} to + * communicate with users. The {@code CallbackHandler} may be * used to prompt for usernames and passwords, for example. - * Note that the CallbackHandler may be null. LoginModules - * which absolutely require a CallbackHandler to authenticate - * the Subject may throw a LoginException. + * Note that the {@code CallbackHandler} may be null. LoginModules + * which absolutely require a {@code CallbackHandler} to authenticate + * the {@code Subject} may throw a {@code LoginException}. * LoginModules optionally use the shared state to share information * or data among themselves. * *

    The LoginModule-specific options represent the options - * configured for this LoginModule by an administrator or user - * in the login Configuration. - * The options are defined by the LoginModule itself + * configured for this {@code LoginModule} by an administrator or user + * in the login {@code Configuration}. + * The options are defined by the {@code LoginModule} itself * and control the behavior within it. For example, a - * LoginModule may define options to support debugging/testing + * {@code LoginModule} may define options to support debugging/testing * capabilities. Options are defined using a key-value syntax, - * such as debug=true. The LoginModule - * stores the options as a Map so that the values may + * such as debug=true. The {@code LoginModule} + * stores the options as a {@code Map} so that the values may * be retrieved using the key. Note that there is no limit to the number - * of options a LoginModule chooses to define. + * of options a {@code LoginModule} chooses to define. * *

    The calling application sees the authentication process as a single * operation. However, the authentication process within the - * LoginModule proceeds in two distinct phases. + * {@code LoginModule} proceeds in two distinct phases. * In the first phase, the LoginModule's - * login method gets invoked by the LoginContext's - * login method. The login - * method for the LoginModule then performs + * {@code login} method gets invoked by the LoginContext's + * {@code login} method. The {@code login} + * method for the {@code LoginModule} then performs * the actual authentication (prompt for and verify a password for example) * and saves its authentication status as private state - * information. Once finished, the LoginModule's login - * method either returns true (if it succeeded) or - * false (if it should be ignored), or throws a - * LoginException to specify a failure. - * In the failure case, the LoginModule must not retry the + * information. Once finished, the LoginModule's {@code login} + * method either returns {@code true} (if it succeeded) or + * {@code false} (if it should be ignored), or throws a + * {@code LoginException} to specify a failure. + * In the failure case, the {@code LoginModule} must not retry the * authentication or introduce delays. The responsibility of such tasks * belongs to the application. If the application attempts to retry - * the authentication, the LoginModule's login method will be + * the authentication, the LoginModule's {@code login} method will be * called again. * *

    In the second phase, if the LoginContext's overall authentication * succeeded (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL - * LoginModules succeeded), then the commit - * method for the LoginModule gets invoked. - * The commit method for a LoginModule checks its + * LoginModules succeeded), then the {@code commit} + * method for the {@code LoginModule} gets invoked. + * The {@code commit} method for a {@code LoginModule} checks its * privately saved state to see if its own authentication succeeded. - * If the overall LoginContext authentication succeeded + * If the overall {@code LoginContext} authentication succeeded * and the LoginModule's own authentication succeeded, then the - * commit method associates the relevant + * {@code commit} method associates the relevant * Principals (authenticated identities) and Credentials (authentication data - * such as cryptographic keys) with the Subject - * located within the LoginModule. + * such as cryptographic keys) with the {@code Subject} + * located within the {@code LoginModule}. * *

    If the LoginContext's overall authentication failed (the relevant * REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules did not succeed), - * then the abort method for each LoginModule - * gets invoked. In this case, the LoginModule removes/destroys + * then the {@code abort} method for each {@code LoginModule} + * gets invoked. In this case, the {@code LoginModule} removes/destroys * any authentication state originally saved. * - *

    Logging out a Subject involves only one phase. - * The LoginContext invokes the LoginModule's logout - * method. The logout method for the LoginModule + *

    Logging out a {@code Subject} involves only one phase. + * The {@code LoginContext} invokes the LoginModule's {@code logout} + * method. The {@code logout} method for the {@code LoginModule} * then performs the logout procedures, such as removing Principals or - * Credentials from the Subject or logging session information. + * Credentials from the {@code Subject} or logging session information. * - *

    A LoginModule implementation must have a constructor with - * no arguments. This allows classes which load the LoginModule + *

    A {@code LoginModule} implementation must have a constructor with + * no arguments. This allows classes which load the {@code LoginModule} * to instantiate it. * * @see javax.security.auth.login.LoginContext @@ -131,38 +131,38 @@ public interface LoginModule { /** * Initialize this LoginModule. * - *

    This method is called by the LoginContext - * after this LoginModule has been instantiated. + *

    This method is called by the {@code LoginContext} + * after this {@code LoginModule} has been instantiated. * The purpose of this method is to initialize this - * LoginModule with the relevant information. - * If this LoginModule does not understand - * any of the data stored in sharedState or - * options parameters, they can be ignored. + * {@code LoginModule} with the relevant information. + * If this {@code LoginModule} does not understand + * any of the data stored in {@code sharedState} or + * {@code options} parameters, they can be ignored. * *

    * - * @param subject the Subject to be authenticated.

    + * @param subject the {@code Subject} to be authenticated.

    * - * @param callbackHandler a CallbackHandler for communicating + * @param callbackHandler a {@code CallbackHandler} for communicating * with the end user (prompting for usernames and * passwords, for example).

    * * @param sharedState state shared with other configured LoginModules.

    * * @param options options specified in the login - * Configuration for this particular - * LoginModule. + * {@code Configuration} for this particular + * {@code LoginModule}. */ void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options); /** - * Method to authenticate a Subject (phase 1). + * Method to authenticate a {@code Subject} (phase 1). * *

    The implementation of this method authenticates - * a Subject. For example, it may prompt for - * Subject information such + * a {@code Subject}. For example, it may prompt for + * {@code Subject} information such * as a username and password and then attempt to verify the password. * This method saves the result of the authentication attempt * as private state within the LoginModule. @@ -172,7 +172,7 @@ public interface LoginModule { * @exception LoginException if the authentication fails * * @return true if the authentication succeeded, or false if this - * LoginModule should be ignored. + * {@code LoginModule} should be ignored. */ boolean login() throws LoginException; @@ -186,9 +186,9 @@ public interface LoginModule { * *

    If this LoginModule's own authentication attempt * succeeded (checked by retrieving the private state saved by the - * login method), then this method associates relevant - * Principals and Credentials with the Subject located in the - * LoginModule. If this LoginModule's own + * {@code login} method), then this method associates relevant + * Principals and Credentials with the {@code Subject} located in the + * {@code LoginModule}. If this LoginModule's own * authentication attempted failed, then this method removes/destroys * any state that was originally saved. * @@ -197,7 +197,7 @@ public interface LoginModule { * @exception LoginException if the commit fails * * @return true if this method succeeded, or false if this - * LoginModule should be ignored. + * {@code LoginModule} should be ignored. */ boolean commit() throws LoginException; @@ -211,7 +211,7 @@ public interface LoginModule { * *

    If this LoginModule's own authentication attempt * succeeded (checked by retrieving the private state saved by the - * login method), then this method cleans up any state + * {@code login} method), then this method cleans up any state * that was originally saved. * *

    @@ -219,12 +219,12 @@ public interface LoginModule { * @exception LoginException if the abort fails * * @return true if this method succeeded, or false if this - * LoginModule should be ignored. + * {@code LoginModule} should be ignored. */ boolean abort() throws LoginException; /** - * Method which logs out a Subject. + * Method which logs out a {@code Subject}. * *

    An implementation of this method might remove/destroy a Subject's * Principals and Credentials. @@ -234,7 +234,7 @@ public interface LoginModule { * @exception LoginException if the logout fails * * @return true if this method succeeded, or false if this - * LoginModule should be ignored. + * {@code LoginModule} should be ignored. */ boolean logout() throws LoginException; } diff --git a/jdk/src/share/classes/javax/security/auth/spi/package-info.java b/jdk/src/share/classes/javax/security/auth/spi/package-info.java new file mode 100644 index 00000000000..da7cbcb8b0c --- /dev/null +++ b/jdk/src/share/classes/javax/security/auth/spi/package-info.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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. + */ + +/** + * This package provides the interface to be used for + * implementing pluggable authentication modules. + * + * @since JDK1.4 + */ +package javax.security.auth.spi; diff --git a/jdk/src/share/classes/javax/security/auth/spi/package.html b/jdk/src/share/classes/javax/security/auth/spi/package.html deleted file mode 100644 index f4ca707c066..00000000000 --- a/jdk/src/share/classes/javax/security/auth/spi/package.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - This package provides the interface to be used for - implementing pluggable authentication modules. - - -@since JDK1.4 - - diff --git a/jdk/src/share/classes/javax/security/auth/x500/X500Principal.java b/jdk/src/share/classes/javax/security/auth/x500/X500Principal.java index 4a507197771..5c0a5621261 100644 --- a/jdk/src/share/classes/javax/security/auth/x500/X500Principal.java +++ b/jdk/src/share/classes/javax/security/auth/x500/X500Principal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,8 @@ import sun.security.x509.X500Name; import sun.security.util.*; /** - *

    This class represents an X.500 Principal. - * X500Principals are represented by distinguished names such as + *

    This class represents an X.500 {@code Principal}. + * {@code X500Principal}s are represented by distinguished names such as * "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US". * *

    This class can be instantiated by using a string representation @@ -50,12 +50,12 @@ import sun.security.util.*; * RFC 3280: Internet X.509 * Public Key Infrastructure Certificate and CRL Profile. * - *

    The string representation for this X500Principal - * can be obtained by calling the getName methods. + *

    The string representation for this {@code X500Principal} + * can be obtained by calling the {@code getName} methods. * - *

    Note that the getSubjectX500Principal and - * getIssuerX500Principal methods of - * X509Certificate return X500Principals representing the + *

    Note that the {@code getSubjectX500Principal} and + * {@code getIssuerX500Principal} methods of + * {@code X509Certificate} return X500Principals representing the * issuer and subject fields of the certificate. * * @see java.security.cert.X509Certificate @@ -97,7 +97,7 @@ public final class X500Principal implements Principal, java.io.Serializable { } /** - * Creates an X500Principal from a string representation of + * Creates an {@code X500Principal} from a string representation of * an X.500 distinguished name (ex: * "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"). * The distinguished name must be specified using the grammar defined in @@ -119,9 +119,9 @@ public final class X500Principal implements Principal, java.io.Serializable { *

    {@code numericoid = number 1*( DOT number ) } * * @param name an X.500 distinguished name in RFC 1779 or RFC 2253 format - * @exception NullPointerException if the name - * is null - * @exception IllegalArgumentException if the name + * @exception NullPointerException if the {@code name} + * is {@code null} + * @exception IllegalArgumentException if the {@code name} * is improperly specified */ public X500Principal(String name) { @@ -129,7 +129,7 @@ public final class X500Principal implements Principal, java.io.Serializable { } /** - * Creates an X500Principal from a string representation of + * Creates an {@code X500Principal} from a string representation of * an X.500 distinguished name (ex: * "CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US"). * The distinguished name must be specified using the grammar defined in @@ -137,13 +137,13 @@ public final class X500Principal implements Principal, java.io.Serializable { * *

    This constructor recognizes the attribute type keywords specified * in {@link #X500Principal(String)} and also recognizes additional - * keywords that have entries in the keywordMap parameter. + * keywords that have entries in the {@code keywordMap} parameter. * Keyword entries in the keywordMap take precedence over the default - * keywords recognized by X500Principal(String). Keywords + * keywords recognized by {@code X500Principal(String)}. Keywords * MUST be specified in all upper-case, otherwise they will be ignored. * Improperly specified keywords are ignored; however if a keyword in the * name maps to an improperly specified Object Identifier (OID), an - * IllegalArgumentException is thrown. It is permissible to + * {@code IllegalArgumentException} is thrown. It is permissible to * have 2 different keywords that map to the same OID. * *

    This implementation enforces a more restrictive OID syntax than @@ -157,11 +157,11 @@ public final class X500Principal implements Principal, java.io.Serializable { * @param keywordMap an attribute type keyword map, where each key is a * keyword String that maps to a corresponding object identifier in String * form (a sequence of nonnegative integers separated by periods). The map - * may be empty but never null. - * @exception NullPointerException if name or - * keywordMap is null - * @exception IllegalArgumentException if the name is - * improperly specified or a keyword in the name maps to an + * may be empty but never {@code null}. + * @exception NullPointerException if {@code name} or + * {@code keywordMap} is {@code null} + * @exception IllegalArgumentException if the {@code name} is + * improperly specified or a keyword in the {@code name} maps to an * OID that is not in the correct form * @since 1.6 */ @@ -188,10 +188,10 @@ public final class X500Principal implements Principal, java.io.Serializable { } /** - * Creates an X500Principal from a distinguished name in + * Creates an {@code X500Principal} from a distinguished name in * ASN.1 DER encoded form. The ASN.1 notation for this structure is as * follows. - *

    
    +     * 
    {@code
          * Name ::= CHOICE {
          *   RDNSequence }
          *
    @@ -214,7 +214,7 @@ public final class X500Principal implements Principal, java.io.Serializable {
          *       universalString         UniversalString (SIZE (1..MAX)),
          *       utf8String              UTF8String (SIZE (1.. MAX)),
          *       bmpString               BMPString (SIZE (1..MAX)) }
    -     * 
    + * }
    * * @param name a byte array containing the distinguished name in ASN.1 * DER encoded form @@ -233,7 +233,7 @@ public final class X500Principal implements Principal, java.io.Serializable { } /** - * Creates an X500Principal from an InputStream + * Creates an {@code X500Principal} from an {@code InputStream} * containing the distinguished name in ASN.1 DER encoded form. * The ASN.1 notation for this structure is supplied in the * documentation for @@ -242,11 +242,11 @@ public final class X500Principal implements Principal, java.io.Serializable { *

    The read position of the input stream is positioned * to the next available byte after the encoded distinguished name. * - * @param is an InputStream containing the distinguished + * @param is an {@code InputStream} containing the distinguished * name in ASN.1 DER encoded form * - * @exception NullPointerException if the InputStream - * is null + * @exception NullPointerException if the {@code InputStream} + * is {@code null} * @exception IllegalArgumentException if an encoding error occurs * (incorrect form for DN) */ @@ -284,9 +284,9 @@ public final class X500Principal implements Principal, java.io.Serializable { * the format defined in RFC 2253. * *

    This method is equivalent to calling - * getName(X500Principal.RFC2253). + * {@code getName(X500Principal.RFC2253)}. * - * @return the distinguished name of this X500Principal + * @return the distinguished name of this {@code X500Principal} */ public String getName() { return getName(X500Principal.RFC2253); @@ -338,9 +338,9 @@ public final class X500Principal implements Principal, java.io.Serializable { * those which section 2.4 of RFC 2253 states must be escaped * (they are escaped using a preceding backslash character) *

  • The entire name is converted to upper case - * using String.toUpperCase(Locale.US) + * using {@code String.toUpperCase(Locale.US)} *
  • The entire name is converted to lower case - * using String.toLowerCase(Locale.US) + * using {@code String.toLowerCase(Locale.US)} *
  • The name is finally normalized using normalization form KD, * as described in the Unicode Standard and UAX #15 * @@ -349,7 +349,7 @@ public final class X500Principal implements Principal, java.io.Serializable { * * @param format the format to use * - * @return a string representation of this X500Principal + * @return a string representation of this {@code X500Principal} * using the specified format * @throws IllegalArgumentException if the specified format is invalid * or null @@ -371,16 +371,16 @@ public final class X500Principal implements Principal, java.io.Serializable { * Returns a string representation of the X.500 distinguished name * using the specified format. Valid values for the format are * "RFC1779" and "RFC2253" (case insensitive). "CANONICAL" is not - * permitted and an IllegalArgumentException will be thrown. + * permitted and an {@code IllegalArgumentException} will be thrown. * *

    This method returns Strings in the format as specified in * {@link #getName(String)} and also emits additional attribute type - * keywords for OIDs that have entries in the oidMap + * keywords for OIDs that have entries in the {@code oidMap} * parameter. OID entries in the oidMap take precedence over the default - * OIDs recognized by getName(String). + * OIDs recognized by {@code getName(String)}. * Improperly specified OIDs are ignored; however if an OID * in the name maps to an improperly specified keyword, an - * IllegalArgumentException is thrown. + * {@code IllegalArgumentException} is thrown. * *

    Additional standard formats may be introduced in the future. * @@ -393,12 +393,12 @@ public final class X500Principal implements Principal, java.io.Serializable { * @param oidMap an OID map, where each key is an object identifier in * String form (a sequence of nonnegative integers separated by periods) * that maps to a corresponding attribute type keyword String. - * The map may be empty but never null. - * @return a string representation of this X500Principal + * The map may be empty but never {@code null}. + * @return a string representation of this {@code X500Principal} * using the specified format * @throws IllegalArgumentException if the specified format is invalid, * null, or an OID in the name maps to an improperly specified keyword - * @throws NullPointerException if oidMap is null + * @throws NullPointerException if {@code oidMap} is {@code null} * @since 1.6 */ public String getName(String format, Map oidMap) { @@ -438,31 +438,31 @@ public final class X500Principal implements Principal, java.io.Serializable { /** * Return a user-friendly string representation of this - * X500Principal. + * {@code X500Principal}. * - * @return a string representation of this X500Principal + * @return a string representation of this {@code X500Principal} */ public String toString() { return thisX500Name.toString(); } /** - * Compares the specified Object with this - * X500Principal for equality. + * Compares the specified {@code Object} with this + * {@code X500Principal} for equality. * - *

    Specifically, this method returns true if - * the Object o is an X500Principal + *

    Specifically, this method returns {@code true} if + * the {@code Object} o is an {@code X500Principal} * and if the respective canonical string representations - * (obtained via the getName(X500Principal.CANONICAL) method) + * (obtained via the {@code getName(X500Principal.CANONICAL)} method) * of this object and o are equal. * *

    This implementation is compliant with the requirements of RFC 3280. * * @param o Object to be compared for equality with this - * X500Principal + * {@code X500Principal} * - * @return true if the specified Object is equal - * to this X500Principal, false otherwise + * @return {@code true} if the specified {@code Object} is equal + * to this {@code X500Principal}, {@code false} otherwise */ public boolean equals(Object o) { if (this == o) { @@ -476,12 +476,12 @@ public final class X500Principal implements Principal, java.io.Serializable { } /** - * Return a hash code for this X500Principal. + * Return a hash code for this {@code X500Principal}. * *

    The hash code is calculated via: - * getName(X500Principal.CANONICAL).hashCode() + * {@code getName(X500Principal.CANONICAL).hashCode()} * - * @return a hash code for this X500Principal + * @return a hash code for this {@code X500Principal} */ public int hashCode() { return thisX500Name.hashCode(); @@ -490,9 +490,9 @@ public final class X500Principal implements Principal, java.io.Serializable { /** * Save the X500Principal object to a stream. * - * @serialData this X500Principal is serialized + * @serialData this {@code X500Principal} is serialized * by writing out its DER-encoded form - * (the value of getEncoded is serialized). + * (the value of {@code getEncoded} is serialized). */ private void writeObject(java.io.ObjectOutputStream s) throws IOException { diff --git a/jdk/src/share/classes/javax/security/auth/x500/X500PrivateCredential.java b/jdk/src/share/classes/javax/security/auth/x500/X500PrivateCredential.java index 64bd14295da..56072eda5bc 100644 --- a/jdk/src/share/classes/javax/security/auth/x500/X500PrivateCredential.java +++ b/jdk/src/share/classes/javax/security/auth/x500/X500PrivateCredential.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ import java.security.cert.X509Certificate; import javax.security.auth.Destroyable; /** - *

    This class represents an X500PrivateCredential. + *

    This class represents an {@code X500PrivateCredential}. * It associates an X.509 certificate, corresponding private key and the * KeyStore alias used to reference that exact key pair in the KeyStore. * This enables looking up the private credentials for an X.500 principal @@ -48,8 +48,8 @@ public final class X500PrivateCredential implements Destroyable { *

    * @param cert X509Certificate * @param key PrivateKey for the certificate - * @exception IllegalArgumentException if either cert or - * key is null + * @exception IllegalArgumentException if either {@code cert} or + * {@code key} is null * */ @@ -68,8 +68,8 @@ public final class X500PrivateCredential implements Destroyable { * @param cert X509Certificate * @param key PrivateKey for the certificate * @param alias KeyStore alias - * @exception IllegalArgumentException if either cert, - * key or alias is null + * @exception IllegalArgumentException if either {@code cert}, + * {@code key} or {@code alias} is null * */ public X500PrivateCredential(X509Certificate cert, PrivateKey key, diff --git a/jdk/src/share/classes/javax/security/auth/x500/package-info.java b/jdk/src/share/classes/javax/security/auth/x500/package-info.java new file mode 100644 index 00000000000..12f8a5322d1 --- /dev/null +++ b/jdk/src/share/classes/javax/security/auth/x500/package-info.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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. + */ + +/** + * This package contains the classes that should be used to store + * X500 Principal and X500 Private Credentials in a + * Subject. + * + *

    Package Specification

    + * + * + * + * @since JDK1.4 + */ +package javax.security.auth.x500; diff --git a/jdk/src/share/classes/javax/security/auth/x500/package.html b/jdk/src/share/classes/javax/security/auth/x500/package.html deleted file mode 100644 index 46a9203774f..00000000000 --- a/jdk/src/share/classes/javax/security/auth/x500/package.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - This package contains the classes that should be used to store - X500 Principal and X500 Private Credentials in a - Subject. - -

    Package Specification

    - - - - - -@since JDK1.4 - - diff --git a/jdk/src/share/classes/javax/security/cert/Certificate.java b/jdk/src/share/classes/javax/security/cert/Certificate.java index 651c5bd1024..10fd767c157 100644 --- a/jdk/src/share/classes/javax/security/cert/Certificate.java +++ b/jdk/src/share/classes/javax/security/cert/Certificate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,11 +49,11 @@ import java.security.SignatureException; * sets of information, and they store and retrieve the information in * different ways. * - *

    Note: The classes in the package javax.security.cert + *

    Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * java.security.cert.

    + * {@code java.security.cert}.

    * * @since 1.4 * @see X509Certificate @@ -64,8 +64,8 @@ public abstract class Certificate { /** * Compares this certificate for equality with the specified - * object. If the other object is an - * instanceof Certificate, then + * object. If the {@code other} object is an + * {@code instanceof} {@code Certificate}, then * its encoded form is retrieved and compared with the * encoded form of this certificate. * diff --git a/jdk/src/share/classes/javax/security/cert/CertificateEncodingException.java b/jdk/src/share/classes/javax/security/cert/CertificateEncodingException.java index 8832c3a2ee1..1496c754181 100644 --- a/jdk/src/share/classes/javax/security/cert/CertificateEncodingException.java +++ b/jdk/src/share/classes/javax/security/cert/CertificateEncodingException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,11 +30,11 @@ package javax.security.cert; * Certificate Encoding Exception. This is thrown whenever an error * occurs whilst attempting to encode a certificate. * - *

    Note: The classes in the package javax.security.cert + *

    Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * java.security.cert.

    + * {@code java.security.cert}.

    * * @since 1.4 * @author Hemma Prafullchandra diff --git a/jdk/src/share/classes/javax/security/cert/CertificateException.java b/jdk/src/share/classes/javax/security/cert/CertificateException.java index 7e250558ed0..68ee6798b8c 100644 --- a/jdk/src/share/classes/javax/security/cert/CertificateException.java +++ b/jdk/src/share/classes/javax/security/cert/CertificateException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,11 +29,11 @@ package javax.security.cert; /** * This exception indicates one of a variety of certificate problems. * - *

    Note: The classes in the package javax.security.cert + *

    Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * java.security.cert.

    + * {@code java.security.cert}.

    * * @author Hemma Prafullchandra * @since 1.4 diff --git a/jdk/src/share/classes/javax/security/cert/CertificateExpiredException.java b/jdk/src/share/classes/javax/security/cert/CertificateExpiredException.java index 601dc6bb1db..7e4579f2ebe 100644 --- a/jdk/src/share/classes/javax/security/cert/CertificateExpiredException.java +++ b/jdk/src/share/classes/javax/security/cert/CertificateExpiredException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,15 +28,15 @@ package javax.security.cert; /** * Certificate Expired Exception. This is thrown whenever the current - * Date or the specified Date is after the - * notAfter date/time specified in the validity period + * {@code Date} or the specified {@code Date} is after the + * {@code notAfter} date/time specified in the validity period * of the certificate. * - *

    Note: The classes in the package javax.security.cert + *

    Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * java.security.cert.

    + * {@code java.security.cert}.

    * * @since 1.4 * @author Hemma Prafullchandra diff --git a/jdk/src/share/classes/javax/security/cert/CertificateNotYetValidException.java b/jdk/src/share/classes/javax/security/cert/CertificateNotYetValidException.java index 2a0861580a3..9a53daa661d 100644 --- a/jdk/src/share/classes/javax/security/cert/CertificateNotYetValidException.java +++ b/jdk/src/share/classes/javax/security/cert/CertificateNotYetValidException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,15 +28,15 @@ package javax.security.cert; /** * Certificate is not yet valid exception. This is thrown whenever - * the current Date or the specified Date - * is before the notBefore date/time in the Certificate + * the current {@code Date} or the specified {@code Date} + * is before the {@code notBefore} date/time in the Certificate * validity period. * - *

    Note: The classes in the package javax.security.cert + *

    Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * java.security.cert.

    + * {@code java.security.cert}.

    * * @since 1.4 * @author Hemma Prafullchandra diff --git a/jdk/src/share/classes/javax/security/cert/CertificateParsingException.java b/jdk/src/share/classes/javax/security/cert/CertificateParsingException.java index c60ffe4f1f5..4378587bb70 100644 --- a/jdk/src/share/classes/javax/security/cert/CertificateParsingException.java +++ b/jdk/src/share/classes/javax/security/cert/CertificateParsingException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,11 +31,11 @@ package javax.security.cert; * invalid DER encoded certificate is parsed or unsupported DER features * are found in the Certificate. * - *

    Note: The classes in the package javax.security.cert + *

    Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * java.security.cert.

    + * {@code java.security.cert}.

    * * @since 1.4 * @author Hemma Prafullchandra diff --git a/jdk/src/share/classes/javax/security/cert/X509Certificate.java b/jdk/src/share/classes/javax/security/cert/X509Certificate.java index 16fb0149801..1ef7ddcb56a 100644 --- a/jdk/src/share/classes/javax/security/cert/X509Certificate.java +++ b/jdk/src/share/classes/javax/security/cert/X509Certificate.java @@ -70,7 +70,7 @@ import java.util.Date; * CA certificates are either signed by themselves, or by some other * CA such as a "root" CA. *

    - * The ASN.1 definition of tbsCertificate is: + * The ASN.1 definition of {@code tbsCertificate} is: *

      * TBSCertificate  ::=  SEQUENCE  {
      *     version         [0]  EXPLICIT Version DEFAULT v1,
    @@ -113,11 +113,11 @@ import java.util.Date;
      * initialization time and will fallback on a default implementation if
      * the Security property is not accessible.
      *
    - * 

    Note: The classes in the package javax.security.cert + *

    Note: The classes in the package {@code javax.security.cert} * exist for compatibility with earlier versions of the * Java Secure Sockets Extension (JSSE). New applications should instead * use the standard Java SE certificate classes located in - * java.security.cert.

    + * {@code java.security.cert}.

    * * @author Hemma Prafullchandra * @since 1.4 @@ -150,7 +150,7 @@ public abstract class X509Certificate extends Certificate { /** * Instantiates an X509Certificate object, and initializes it with - * the data read from the input stream inStream. + * the data read from the input stream {@code inStream}. * The implementation (X509Certificate is an abstract class) is * provided by the class specified as the value of the * {@code cert.provider.x509v1} security property. @@ -191,7 +191,7 @@ public abstract class X509Certificate extends Certificate { * @param certData a byte array containing the DER-encoded * certificate. * @return an X509Certificate object initialized with the data - * from certData. + * from {@code certData}. * @exception CertificateException if a class initialization * or certificate parsing error occurs. */ @@ -281,16 +281,16 @@ public abstract class X509Certificate extends Certificate { * @param date the Date to check against to see if this certificate * is valid at that date/time. * @exception CertificateExpiredException if the certificate has expired - * with respect to the date supplied. + * with respect to the {@code date} supplied. * @exception CertificateNotYetValidException if the certificate is not - * yet valid with respect to the date supplied. + * yet valid with respect to the {@code date} supplied. * @see #checkValidity() */ public abstract void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException; /** - * Gets the version (version number) value from the + * Gets the {@code version} (version number) value from the * certificate. The ASN.1 definition for this is: *
          * version         [0]  EXPLICIT Version DEFAULT v1
    @@ -303,7 +303,7 @@ public abstract class X509Certificate extends Certificate {
         public abstract int getVersion();
     
         /**
    -     * Gets the serialNumber value from the certificate.
    +     * Gets the {@code serialNumber} value from the certificate.
          * The serial number is an integer assigned by the certification
          * authority to each certificate. It must be unique for each
          * certificate issued by a given CA (i.e., the issuer name and
    @@ -320,7 +320,7 @@ public abstract class X509Certificate extends Certificate {
         public abstract BigInteger getSerialNumber();
     
         /**
    -     * Gets the issuer (issuer distinguished name) value from
    +     * Gets the {@code issuer} (issuer distinguished name) value from
          * the certificate. The issuer name identifies the entity that signed (and
          * issued) the certificate.
          *
    @@ -341,27 +341,27 @@ public abstract class X509Certificate extends Certificate {
          * AttributeType ::= OBJECT IDENTIFIER
          * AttributeValue ::= ANY
          * 
    - * The Name describes a hierarchical name composed of + * The {@code Name} describes a hierarchical name composed of * attributes, such as country name, and corresponding values, such as US. - * The type of the AttributeValue component is determined by - * the AttributeType; in general it will be a - * directoryString. A directoryString is usually - * one of PrintableString, - * TeletexString or UniversalString. + * The type of the {@code AttributeValue} component is determined by + * the {@code AttributeType}; in general it will be a + * {@code directoryString}. A {@code directoryString} is usually + * one of {@code PrintableString}, + * {@code TeletexString} or {@code UniversalString}. * * @return a Principal whose name is the issuer distinguished name. */ public abstract Principal getIssuerDN(); /** - * Gets the subject (subject distinguished name) value + * Gets the {@code subject} (subject distinguished name) value * from the certificate. * The ASN.1 definition for this is: *
          * subject    Name
          * 
    * - *

    See {@link #getIssuerDN() getIssuerDN} for Name + *

    See {@link #getIssuerDN() getIssuerDN} for {@code Name} * and other relevant definitions. * * @return a Principal whose name is the subject name. @@ -370,7 +370,7 @@ public abstract class X509Certificate extends Certificate { public abstract Principal getSubjectDN(); /** - * Gets the notBefore date from the validity period of + * Gets the {@code notBefore} date from the validity period of * the certificate. * The relevant ASN.1 definitions are: *

    @@ -391,7 +391,7 @@ public abstract class X509Certificate extends Certificate {
         public abstract Date getNotBefore();
     
         /**
    -     * Gets the notAfter date from the validity period of
    +     * Gets the {@code notAfter} date from the validity period of
          * the certificate. See {@link #getNotBefore() getNotBefore}
          * for relevant ASN.1 definitions.
          *
    @@ -415,7 +415,7 @@ public abstract class X509Certificate extends Certificate {
          *                             -- algorithm object identifier value
          * 
    * - *

    The algorithm name is determined from the algorithm + *

    The algorithm name is determined from the {@code algorithm} * OID string. * * @return the signature algorithm name. diff --git a/jdk/src/share/classes/javax/security/cert/package-info.java b/jdk/src/share/classes/javax/security/cert/package-info.java new file mode 100644 index 00000000000..c09a0eafabc --- /dev/null +++ b/jdk/src/share/classes/javax/security/cert/package-info.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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 classes for public key certificates. + * + * These classes include a simplified version of the + * java.security.cert package. These classes were developed + * as part of the Java Secure Socket + * Extension (JSSE). When JSSE was added to the J2SE version 1.4, this + * package was added for backward-compatibility reasons only. + * + * New applications should not use this package, but rather + * java.security.cert. + * + * @since 1.4 + */ +package javax.security.cert; diff --git a/jdk/src/share/classes/javax/security/cert/package.html b/jdk/src/share/classes/javax/security/cert/package.html deleted file mode 100644 index 06c25e0d1aa..00000000000 --- a/jdk/src/share/classes/javax/security/cert/package.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - -Provides classes for public key certificates. - -

    - -These classes include a simplified version of the -java.security.cert package. These classes were developed -as part of the Java Secure Socket -Extension (JSSE). When JSSE was added to the J2SE version 1.4, this -package was added for backward-compatibility reasons only. - -

    - -New applications should not use this package, but rather -java.security.cert. - - -@since 1.4 - - diff --git a/jdk/src/share/classes/javax/security/sasl/AuthenticationException.java b/jdk/src/share/classes/javax/security/sasl/AuthenticationException.java index ea76d1a783c..b61981bc16f 100644 --- a/jdk/src/share/classes/javax/security/sasl/AuthenticationException.java +++ b/jdk/src/share/classes/javax/security/sasl/AuthenticationException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ package javax.security.sasl; */ public class AuthenticationException extends SaslException { /** - * Constructs a new instance of AuthenticationException. + * Constructs a new instance of {@code AuthenticationException}. * The root exception and the detailed message are null. */ public AuthenticationException () { @@ -53,7 +53,7 @@ public class AuthenticationException extends SaslException { } /** - * Constructs a new instance of AuthenticationException + * Constructs a new instance of {@code AuthenticationException} * with a detailed message. * The root exception is null. * @param detail A possibly null string containing details of the exception. @@ -65,7 +65,7 @@ public class AuthenticationException extends SaslException { } /** - * Constructs a new instance of AuthenticationException with a detailed message + * Constructs a new instance of {@code AuthenticationException} with a detailed message * and a root exception. * * @param detail A possibly null string containing details of the exception. diff --git a/jdk/src/share/classes/javax/security/sasl/AuthorizeCallback.java b/jdk/src/share/classes/javax/security/sasl/AuthorizeCallback.java index 0824cb2c087..e2342d64e6d 100644 --- a/jdk/src/share/classes/javax/security/sasl/AuthorizeCallback.java +++ b/jdk/src/share/classes/javax/security/sasl/AuthorizeCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ package javax.security.sasl; import javax.security.auth.callback.Callback; /** - * This callback is used by SaslServer to determine whether + * This callback is used by {@code SaslServer} to determine whether * one entity (identified by an authenticated authentication id) * can act on * behalf of another entity (identified by an authorization id). @@ -66,7 +66,7 @@ public class AuthorizeCallback implements Callback, java.io.Serializable { private boolean authorized; /** - * Constructs an instance of AuthorizeCallback. + * Constructs an instance of {@code AuthorizeCallback}. * * @param authnID The (authenticated) authentication id. * @param authzID The authorization id. @@ -96,7 +96,7 @@ public class AuthorizeCallback implements Callback, java.io.Serializable { * Determines whether the authentication id is allowed to * act on behalf of the authorization id. * - * @return true if authorization is allowed; false otherwise + * @return {@code true} if authorization is allowed; {@code false} otherwise * @see #setAuthorized(boolean) * @see #getAuthorizedID() */ @@ -106,7 +106,7 @@ public class AuthorizeCallback implements Callback, java.io.Serializable { /** * Sets whether the authorization is allowed. - * @param ok true if authorization is allowed; false otherwise + * @param ok {@code true} if authorization is allowed; {@code false} otherwise * @see #isAuthorized * @see #setAuthorizedID(java.lang.String) */ @@ -116,7 +116,7 @@ public class AuthorizeCallback implements Callback, java.io.Serializable { /** * Returns the id of the authorized user. - * @return The id of the authorized user. null means the + * @return The id of the authorized user. {@code null} means the * authorization failed. * @see #setAuthorized(boolean) * @see #setAuthorizedID(java.lang.String) diff --git a/jdk/src/share/classes/javax/security/sasl/RealmCallback.java b/jdk/src/share/classes/javax/security/sasl/RealmCallback.java index b9d30d1a3f4..b3af0998e5e 100644 --- a/jdk/src/share/classes/javax/security/sasl/RealmCallback.java +++ b/jdk/src/share/classes/javax/security/sasl/RealmCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ package javax.security.sasl; import javax.security.auth.callback.TextInputCallback; /** - * This callback is used by SaslClient and SaslServer + * This callback is used by {@code SaslClient} and {@code SaslServer} * to retrieve realm information. * * @since 1.5 @@ -39,10 +39,10 @@ import javax.security.auth.callback.TextInputCallback; public class RealmCallback extends TextInputCallback { /** - * Constructs a RealmCallback with a prompt. + * Constructs a {@code RealmCallback} with a prompt. * * @param prompt The non-null prompt to use to request the realm information. - * @throws IllegalArgumentException If prompt is null or + * @throws IllegalArgumentException If {@code prompt} is null or * the empty string. */ public RealmCallback(String prompt) { @@ -50,14 +50,14 @@ public class RealmCallback extends TextInputCallback { } /** - * Constructs a RealmCallback with a prompt and default + * Constructs a {@code RealmCallback} with a prompt and default * realm information. * * @param prompt The non-null prompt to use to request the realm information. * @param defaultRealmInfo The non-null default realm information to use. - * @throws IllegalArgumentException If prompt is null or + * @throws IllegalArgumentException If {@code prompt} is null or * the empty string, - * or if defaultRealm is empty or null. + * or if {@code defaultRealm} is empty or null. */ public RealmCallback(String prompt, String defaultRealmInfo) { super(prompt, defaultRealmInfo); diff --git a/jdk/src/share/classes/javax/security/sasl/RealmChoiceCallback.java b/jdk/src/share/classes/javax/security/sasl/RealmChoiceCallback.java index 3ee292a1582..7954109f541 100644 --- a/jdk/src/share/classes/javax/security/sasl/RealmChoiceCallback.java +++ b/jdk/src/share/classes/javax/security/sasl/RealmChoiceCallback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ package javax.security.sasl; import javax.security.auth.callback.ChoiceCallback; /** - * This callback is used by SaslClient and SaslServer + * This callback is used by {@code SaslClient} and {@code SaslServer} * to obtain a realm given a list of realm choices. * * @since 1.5 @@ -39,19 +39,19 @@ import javax.security.auth.callback.ChoiceCallback; public class RealmChoiceCallback extends ChoiceCallback { /** - * Constructs a RealmChoiceCallback with a prompt, a list of + * Constructs a {@code RealmChoiceCallback} with a prompt, a list of * choices and a default choice. * * @param prompt the non-null prompt to use to request the realm. * @param choices the non-null list of realms to choose from. * @param defaultChoice the choice to be used as the default choice * when the list of choices is displayed. It is an index into - * the choices arary. + * the {@code choices} arary. * @param multiple true if multiple choices allowed; false otherwise - * @throws IllegalArgumentException If prompt is null or the empty string, - * if choices has a length of 0, if any element from - * choices is null or empty, or if defaultChoice - * does not fall within the array boundary of choices + * @throws IllegalArgumentException If {@code prompt} is null or the empty string, + * if {@code choices} has a length of 0, if any element from + * {@code choices} is null or empty, or if {@code defaultChoice} + * does not fall within the array boundary of {@code choices} */ public RealmChoiceCallback(String prompt, String[]choices, int defaultChoice, boolean multiple) { diff --git a/jdk/src/share/classes/javax/security/sasl/Sasl.java b/jdk/src/share/classes/javax/security/sasl/Sasl.java index bb9fb2eec04..77edc108792 100644 --- a/jdk/src/share/classes/javax/security/sasl/Sasl.java +++ b/jdk/src/share/classes/javax/security/sasl/Sasl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,15 +72,15 @@ public class Sasl { * of quality-of-protection values that the * client or server is willing to support. A qop value is one of *

      - *
    • "auth" - authentication only
    • - *
    • "auth-int" - authentication plus integrity protection
    • - *
    • "auth-conf" - authentication plus integrity and confidentiality + *
    • {@code "auth"} - authentication only
    • + *
    • {@code "auth-int"} - authentication plus integrity protection
    • + *
    • {@code "auth-conf"} - authentication plus integrity and confidentiality * protection
    • *
    * * The order of the list specifies the preference order of the client or - * server. If this property is absent, the default qop is "auth". - * The value of this constant is "javax.security.sasl.qop". + * server. If this property is absent, the default qop is {@code "auth"}. + * The value of this constant is {@code "javax.security.sasl.qop"}. */ public static final String QOP = "javax.security.sasl.qop"; @@ -90,9 +90,9 @@ public class Sasl { * of cipher strength values that * the client or server is willing to support. A strength value is one of *
      - *
    • "low"
    • - *
    • "medium"
    • - *
    • "high"
    • + *
    • {@code "low"}
    • + *
    • {@code "medium"}
    • + *
    • {@code "high"}
    • *
    * The order of the list specifies the preference order of the client or * server. An implementation should allow configuration of the meaning @@ -101,19 +101,19 @@ public class Sasl { * cipher suites that match the strength values. *
    * If this property is absent, the default strength is - * "high,medium,low". - * The value of this constant is "javax.security.sasl.strength". + * {@code "high,medium,low"}. + * The value of this constant is {@code "javax.security.sasl.strength"}. */ public static final String STRENGTH = "javax.security.sasl.strength"; /** * The name of a property that specifies whether the * server must authenticate to the client. The property contains - * "true" if the server must - * authenticate the to client; "false" otherwise. - * The default is "false". + * {@code "true"} if the server must + * authenticate the to client; {@code "false"} otherwise. + * The default is {@code "false"}. *
    The value of this constant is - * "javax.security.sasl.server.authentication". + * {@code "javax.security.sasl.server.authentication"}. */ public static final String SERVER_AUTH = "javax.security.sasl.server.authentication"; @@ -125,28 +125,28 @@ public class Sasl { * The property contains the bound host name after the authentication * exchange has completed. It is only available on the server side. *
    The value of this constant is - * "javax.security.sasl.bound.server.name". + * {@code "javax.security.sasl.bound.server.name"}. */ public static final String BOUND_SERVER_NAME = "javax.security.sasl.bound.server.name"; /** * The name of a property that specifies the maximum size of the receive - * buffer in bytes of SaslClient/SaslServer. + * buffer in bytes of {@code SaslClient}/{@code SaslServer}. * The property contains the string representation of an integer. *
    If this property is absent, the default size * is defined by the mechanism. - *
    The value of this constant is "javax.security.sasl.maxbuffer". + *
    The value of this constant is {@code "javax.security.sasl.maxbuffer"}. */ public static final String MAX_BUFFER = "javax.security.sasl.maxbuffer"; /** * The name of a property that specifies the maximum size of the raw send - * buffer in bytes of SaslClient/SaslServer. + * buffer in bytes of {@code SaslClient}/{@code SaslServer}. * The property contains the string representation of an integer. * The value of this property is negotiated between the client and server * during the authentication exchange. - *
    The value of this constant is "javax.security.sasl.rawsendsize". + *
    The value of this constant is {@code "javax.security.sasl.rawsendsize"}. */ public static final String RAW_SEND_SIZE = "javax.security.sasl.rawsendsize"; @@ -181,11 +181,11 @@ public class Sasl { * The name of a property that specifies * whether mechanisms susceptible to simple plain passive attacks (e.g., * "PLAIN") are not permitted. The property - * contains "true" if such mechanisms are not permitted; - * "false" if such mechanisms are permitted. - * The default is "false". + * contains {@code "true"} if such mechanisms are not permitted; + * {@code "false"} if such mechanisms are permitted. + * The default is {@code "false"}. *
    The value of this constant is - * "javax.security.sasl.policy.noplaintext". + * {@code "javax.security.sasl.policy.noplaintext"}. */ public static final String POLICY_NOPLAINTEXT = "javax.security.sasl.policy.noplaintext"; @@ -194,12 +194,12 @@ public class Sasl { * The name of a property that specifies whether * mechanisms susceptible to active (non-dictionary) attacks * are not permitted. - * The property contains "true" + * The property contains {@code "true"} * if mechanisms susceptible to active attacks - * are not permitted; "false" if such mechanisms are permitted. - * The default is "false". + * are not permitted; {@code "false"} if such mechanisms are permitted. + * The default is {@code "false"}. *
    The value of this constant is - * "javax.security.sasl.policy.noactive". + * {@code "javax.security.sasl.policy.noactive"}. */ public static final String POLICY_NOACTIVE = "javax.security.sasl.policy.noactive"; @@ -207,26 +207,26 @@ public class Sasl { /** * The name of a property that specifies whether * mechanisms susceptible to passive dictionary attacks are not permitted. - * The property contains "true" + * The property contains {@code "true"} * if mechanisms susceptible to dictionary attacks are not permitted; - * "false" if such mechanisms are permitted. - * The default is "false". + * {@code "false"} if such mechanisms are permitted. + * The default is {@code "false"}. *
    * The value of this constant is - * "javax.security.sasl.policy.nodictionary". + * {@code "javax.security.sasl.policy.nodictionary"}. */ public static final String POLICY_NODICTIONARY = "javax.security.sasl.policy.nodictionary"; /** * The name of a property that specifies whether mechanisms that accept - * anonymous login are not permitted. The property contains "true" + * anonymous login are not permitted. The property contains {@code "true"} * if mechanisms that accept anonymous login are not permitted; - * "false" - * if such mechanisms are permitted. The default is "false". + * {@code "false"} + * if such mechanisms are permitted. The default is {@code "false"}. *
    * The value of this constant is - * "javax.security.sasl.policy.noanonymous". + * {@code "javax.security.sasl.policy.noanonymous"}. */ public static final String POLICY_NOANONYMOUS = "javax.security.sasl.policy.noanonymous"; @@ -237,12 +237,12 @@ public class Sasl { * means that breaking into one session will not automatically * provide information for breaking into future sessions. * The property - * contains "true" if mechanisms that implement forward secrecy - * between sessions are required; "false" if such mechanisms - * are not required. The default is "false". + * contains {@code "true"} if mechanisms that implement forward secrecy + * between sessions are required; {@code "false"} if such mechanisms + * are not required. The default is {@code "false"}. *
    * The value of this constant is - * "javax.security.sasl.policy.forward". + * {@code "javax.security.sasl.policy.forward"}. */ public static final String POLICY_FORWARD_SECRECY = "javax.security.sasl.policy.forward"; @@ -250,12 +250,12 @@ public class Sasl { /** * The name of a property that specifies whether * mechanisms that pass client credentials are required. The property - * contains "true" if mechanisms that pass - * client credentials are required; "false" - * if such mechanisms are not required. The default is "false". + * contains {@code "true"} if mechanisms that pass + * client credentials are required; {@code "false"} + * if such mechanisms are not required. The default is {@code "false"}. *
    * The value of this constant is - * "javax.security.sasl.policy.credentials". + * {@code "javax.security.sasl.policy.credentials"}. */ public static final String POLICY_PASS_CREDENTIALS = "javax.security.sasl.policy.credentials"; @@ -269,38 +269,38 @@ public class Sasl { * supports delegated authentication. *
    * The value of this constant is - * "javax.security.sasl.credentials". + * {@code "javax.security.sasl.credentials"}. */ public static final String CREDENTIALS = "javax.security.sasl.credentials"; /** - * Creates a SaslClient using the parameters supplied. + * Creates a {@code SaslClient} using the parameters supplied. * * This method uses the JCA Security Provider Framework, described in the * "Java Cryptography Architecture API Specification & Reference", for - * locating and selecting a SaslClient implementation. + * locating and selecting a {@code SaslClient} implementation. * * First, it - * obtains an ordered list of SaslClientFactory instances from + * obtains an ordered list of {@code SaslClientFactory} instances from * the registered security providers for the "SaslClientFactory" service * and the specified SASL mechanism(s). It then invokes - * createSaslClient() on each factory instance on the list - * until one produces a non-null SaslClient instance. It returns - * the non-null SaslClient instance, or null if the search fails - * to produce a non-null SaslClient instance. + * {@code createSaslClient()} on each factory instance on the list + * until one produces a non-null {@code SaslClient} instance. It returns + * the non-null {@code SaslClient} instance, or null if the search fails + * to produce a non-null {@code SaslClient} instance. *

    * A security provider for SaslClientFactory registers with the * JCA Security Provider Framework keys of the form
    - * SaslClientFactory.mechanism_name + * {@code SaslClientFactory.}{@code mechanism_name} *
    * and values that are class names of implementations of - * javax.security.sasl.SaslClientFactory. + * {@code javax.security.sasl.SaslClientFactory}. * * For example, a provider that contains a factory class, - * com.wiz.sasl.digest.ClientFactory, that supports the + * {@code com.wiz.sasl.digest.ClientFactory}, that supports the * "DIGEST-MD5" mechanism would register the following entry with the JCA: - * SaslClientFactory.DIGEST-MD5 com.wiz.sasl.digest.ClientFactory + * {@code SaslClientFactory.DIGEST-MD5 com.wiz.sasl.digest.ClientFactory} *

    * See the * "Java Cryptography Architecture API Specification & Reference" @@ -325,9 +325,9 @@ public class Sasl { * @param props The possibly null set of properties used to * select the SASL mechanism and to configure the authentication * exchange of the selected mechanism. - * For example, if props contains the - * Sasl.POLICY_NOPLAINTEXT property with the value - * "true", then the selected + * For example, if {@code props} contains the + * {@code Sasl.POLICY_NOPLAINTEXT} property with the value + * {@code "true"}, then the selected * SASL mechanism must not be susceptible to simple plain passive attacks. * In addition to the standard properties declared in this class, * other, possibly mechanism-specific, properties can be included. @@ -338,16 +338,16 @@ public class Sasl { * mechanisms to get further information from the application/library * to complete the authentication. For example, a SASL mechanism might * require the authentication ID, password and realm from the caller. - * The authentication ID is requested by using a NameCallback. - * The password is requested by using a PasswordCallback. - * The realm is requested by using a RealmChoiceCallback if there is a list - * of realms to choose from, and by using a RealmCallback if + * The authentication ID is requested by using a {@code NameCallback}. + * The password is requested by using a {@code PasswordCallback}. + * The realm is requested by using a {@code RealmChoiceCallback} if there is a list + * of realms to choose from, and by using a {@code RealmCallback} if * the realm must be entered. * - *@return A possibly null SaslClient created using the parameters - * supplied. If null, cannot find a SaslClientFactory + *@return A possibly null {@code SaslClient} created using the parameters + * supplied. If null, cannot find a {@code SaslClientFactory} * that will produce one. - *@exception SaslException If cannot create a SaslClient because + *@exception SaslException If cannot create a {@code SaslClient} because * of an error. */ public static SaslClient createSaslClient( @@ -423,34 +423,34 @@ public class Sasl { /** - * Creates a SaslServer for the specified mechanism. + * Creates a {@code SaslServer} for the specified mechanism. * * This method uses the JCA Security Provider Framework, * described in the * "Java Cryptography Architecture API Specification & Reference", for - * locating and selecting a SaslServer implementation. + * locating and selecting a {@code SaslServer} implementation. * * First, it - * obtains an ordered list of SaslServerFactory instances from + * obtains an ordered list of {@code SaslServerFactory} instances from * the registered security providers for the "SaslServerFactory" service * and the specified mechanism. It then invokes - * createSaslServer() on each factory instance on the list - * until one produces a non-null SaslServer instance. It returns - * the non-null SaslServer instance, or null if the search fails - * to produce a non-null SaslServer instance. + * {@code createSaslServer()} on each factory instance on the list + * until one produces a non-null {@code SaslServer} instance. It returns + * the non-null {@code SaslServer} instance, or null if the search fails + * to produce a non-null {@code SaslServer} instance. *

    * A security provider for SaslServerFactory registers with the * JCA Security Provider Framework keys of the form
    - * SaslServerFactory.mechanism_name + * {@code SaslServerFactory.}{@code mechanism_name} *
    * and values that are class names of implementations of - * javax.security.sasl.SaslServerFactory. + * {@code javax.security.sasl.SaslServerFactory}. * * For example, a provider that contains a factory class, - * com.wiz.sasl.digest.ServerFactory, that supports the + * {@code com.wiz.sasl.digest.ServerFactory}, that supports the * "DIGEST-MD5" mechanism would register the following entry with the JCA: - * SaslServerFactory.DIGEST-MD5 com.wiz.sasl.digest.ServerFactory + * {@code SaslServerFactory.DIGEST-MD5 com.wiz.sasl.digest.ServerFactory} *

    * See the * "Java Cryptography Architecture API Specification & Reference" @@ -463,14 +463,14 @@ public class Sasl { * the authentication is being performed (e.g., "ldap"). * @param serverName The fully qualified host name of the server, or null * if the server is not bound to any specific host name. If the mechanism - * does not allow an unbound server, a SaslException will + * does not allow an unbound server, a {@code SaslException} will * be thrown. * @param props The possibly null set of properties used to * select the SASL mechanism and to configure the authentication * exchange of the selected mechanism. - * For example, if props contains the - * Sasl.POLICY_NOPLAINTEXT property with the value - * "true", then the selected + * For example, if {@code props} contains the + * {@code Sasl.POLICY_NOPLAINTEXT} property with the value + * {@code "true"}, then the selected * SASL mechanism must not be susceptible to simple plain passive attacks. * In addition to the standard properties declared in this class, * other, possibly mechanism-specific, properties can be included. @@ -481,16 +481,16 @@ public class Sasl { * mechanisms to get further information from the application/library * to complete the authentication. For example, a SASL mechanism might * require the authentication ID, password and realm from the caller. - * The authentication ID is requested by using a NameCallback. - * The password is requested by using a PasswordCallback. - * The realm is requested by using a RealmChoiceCallback if there is a list - * of realms to choose from, and by using a RealmCallback if + * The authentication ID is requested by using a {@code NameCallback}. + * The password is requested by using a {@code PasswordCallback}. + * The realm is requested by using a {@code RealmChoiceCallback} if there is a list + * of realms to choose from, and by using a {@code RealmCallback} if * the realm must be entered. * - *@return A possibly null SaslServer created using the parameters - * supplied. If null, cannot find a SaslServerFactory + *@return A possibly null {@code SaslServer} created using the parameters + * supplied. If null, cannot find a {@code SaslServerFactory} * that will produce one. - *@exception SaslException If cannot create a SaslServer because + *@exception SaslException If cannot create a {@code SaslServer} because * of an error. **/ public static SaslServer @@ -533,11 +533,11 @@ public class Sasl { } /** - * Gets an enumeration of known factories for producing SaslClient. + * Gets an enumeration of known factories for producing {@code SaslClient}. * This method uses the same algorithm for locating factories as - * createSaslClient(). + * {@code createSaslClient()}. * @return A non-null enumeration of known factories for producing - * SaslClient. + * {@code SaslClient}. * @see #createSaslClient */ public static Enumeration getSaslClientFactories() { @@ -554,11 +554,11 @@ public class Sasl { } /** - * Gets an enumeration of known factories for producing SaslServer. + * Gets an enumeration of known factories for producing {@code SaslServer}. * This method uses the same algorithm for locating factories as - * createSaslServer(). + * {@code createSaslServer()}. * @return A non-null enumeration of known factories for producing - * SaslServer. + * {@code SaslServer}. * @see #createSaslServer */ public static Enumeration getSaslServerFactories() { diff --git a/jdk/src/share/classes/javax/security/sasl/SaslClient.java b/jdk/src/share/classes/javax/security/sasl/SaslClient.java index 10f8d3dc3c2..e6786097228 100644 --- a/jdk/src/share/classes/javax/security/sasl/SaslClient.java +++ b/jdk/src/share/classes/javax/security/sasl/SaslClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,14 +30,14 @@ package javax.security.sasl; *

    * A protocol library such as one for LDAP gets an instance of this * class in order to perform authentication defined by a specific SASL - * mechanism. Invoking methods on the SaslClient instance + * mechanism. Invoking methods on the {@code SaslClient} instance * process challenges and create responses according to the SASL - * mechanism implemented by the SaslClient. + * mechanism implemented by the {@code SaslClient}. * As the authentication proceeds, the instance * encapsulates the state of a SASL client's authentication exchange. *

    - * Here's an example of how an LDAP library might use a SaslClient. - * It first gets an instance of a SaslClient: + * Here's an example of how an LDAP library might use a {@code SaslClient}. + * It first gets an instance of a {@code SaslClient}: *

    {@code
      * SaslClient sc = Sasl.createSaslClient(mechanisms,
      *     authorizationId, protocol, serverName, props, callbackHandler);
    @@ -77,16 +77,16 @@ package javax.security.sasl;
      *}
    * * If the mechanism has an initial response, the library invokes - * evaluateChallenge() with an empty + * {@code evaluateChallenge()} with an empty * challenge and to get initial response. * Protocols such as IMAP4, which do not include an initial response with * their first authentication command to the server, initiates the - * authentication without first calling hasInitialResponse() - * or evaluateChallenge(). + * authentication without first calling {@code hasInitialResponse()} + * or {@code evaluateChallenge()}. * When the server responds to the command, it sends an initial challenge. * For a SASL mechanism in which the client sends data first, the server should * have issued a challenge with no data. This will then result in a call - * (on the client) to evaluateChallenge() with an empty challenge. + * (on the client) to {@code evaluateChallenge()} with an empty challenge. * * @since 1.5 * @@ -107,7 +107,7 @@ public abstract interface SaslClient { /** * Determines whether this mechanism has an optional initial response. - * If true, caller should call evaluateChallenge() with an + * If true, caller should call {@code evaluateChallenge()} with an * empty array to get the initial response. * * @return true if this mechanism has an initial response. @@ -148,22 +148,22 @@ public abstract interface SaslClient { /** * Unwraps a byte array received from the server. * This method can be called only after the authentication exchange has - * completed (i.e., when isComplete() returns true) and only if + * completed (i.e., when {@code isComplete()} returns true) and only if * the authentication exchange has negotiated integrity and/or privacy * as the quality of protection; otherwise, an - * IllegalStateException is thrown. + * {@code IllegalStateException} is thrown. *

    - * incoming is the contents of the SASL buffer as defined in RFC 2222 + * {@code incoming} is the contents of the SASL buffer as defined in RFC 2222 * without the leading four octet field that represents the length. - * offset and len specify the portion of incoming + * {@code offset} and {@code len} specify the portion of {@code incoming} * to use. * * @param incoming A non-null byte array containing the encoded bytes * from the server. - * @param offset The starting position at incoming of the bytes to use. - * @param len The number of bytes from incoming to use. + * @param offset The starting position at {@code incoming} of the bytes to use. + * @param len The number of bytes from {@code incoming} to use. * @return A non-null byte array containing the decoded bytes. - * @exception SaslException if incoming cannot be successfully + * @exception SaslException if {@code incoming} cannot be successfully * unwrapped. * @exception IllegalStateException if the authentication exchange has * not completed, or if the negotiated quality of protection @@ -175,22 +175,22 @@ public abstract interface SaslClient { /** * Wraps a byte array to be sent to the server. * This method can be called only after the authentication exchange has - * completed (i.e., when isComplete() returns true) and only if + * completed (i.e., when {@code isComplete()} returns true) and only if * the authentication exchange has negotiated integrity and/or privacy * as the quality of protection; otherwise, an - * IllegalStateException is thrown. + * {@code IllegalStateException} is thrown. *

    * The result of this method will make up the contents of the SASL buffer * as defined in RFC 2222 without the leading four octet field that * represents the length. - * offset and len specify the portion of outgoing + * {@code offset} and {@code len} specify the portion of {@code outgoing} * to use. * * @param outgoing A non-null byte array containing the bytes to encode. - * @param offset The starting position at outgoing of the bytes to use. - * @param len The number of bytes from outgoing to use. + * @param offset The starting position at {@code outgoing} of the bytes to use. + * @param len The number of bytes from {@code outgoing} to use. * @return A non-null byte array containing the encoded bytes. - * @exception SaslException if outgoing cannot be successfully + * @exception SaslException if {@code outgoing} cannot be successfully * wrapped. * @exception IllegalStateException if the authentication exchange has * not completed, or if the negotiated quality of protection @@ -202,8 +202,8 @@ public abstract interface SaslClient { /** * Retrieves the negotiated property. * This method can be called only after the authentication exchange has - * completed (i.e., when isComplete() returns true); otherwise, an - * IllegalStateException is thrown. + * completed (i.e., when {@code isComplete()} returns true); otherwise, an + * {@code IllegalStateException} is thrown. * * @param propName The non-null property name. * @return The value of the negotiated property. If null, the property was diff --git a/jdk/src/share/classes/javax/security/sasl/SaslClientFactory.java b/jdk/src/share/classes/javax/security/sasl/SaslClientFactory.java index e32b34cc0d6..731ed6f1121 100644 --- a/jdk/src/share/classes/javax/security/sasl/SaslClientFactory.java +++ b/jdk/src/share/classes/javax/security/sasl/SaslClientFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,16 +29,16 @@ import java.util.Map; import javax.security.auth.callback.CallbackHandler; /** - * An interface for creating instances of SaslClient. + * An interface for creating instances of {@code SaslClient}. * A class that implements this interface * must be thread-safe and handle multiple simultaneous * requests. It must also have a public constructor that accepts no * argument. *

    * This interface is not normally accessed directly by a client, which will use the - * Sasl static methods + * {@code Sasl} static methods * instead. However, a particular environment may provide and install a - * new or different SaslClientFactory. + * new or different {@code SaslClientFactory}. * * @since 1.5 * @@ -66,7 +66,7 @@ public abstract interface SaslClientFactory { * of the server to authenticate to. * @param props The possibly null set of properties used to select the SASL * mechanism and to configure the authentication exchange of the selected - * mechanism. See the Sasl class for a list of standard properties. + * mechanism. See the {@code Sasl} class for a list of standard properties. * Other, possibly mechanism-specific, properties can be included. * Properties not relevant to the selected mechanism are ignored, * including any map entries with non-String keys. @@ -75,16 +75,16 @@ public abstract interface SaslClientFactory { * mechanisms to get further information from the application/library * to complete the authentication. For example, a SASL mechanism might * require the authentication ID, password and realm from the caller. - * The authentication ID is requested by using a NameCallback. - * The password is requested by using a PasswordCallback. - * The realm is requested by using a RealmChoiceCallback if there is a list - * of realms to choose from, and by using a RealmCallback if + * The authentication ID is requested by using a {@code NameCallback}. + * The password is requested by using a {@code PasswordCallback}. + * The realm is requested by using a {@code RealmChoiceCallback} if there is a list + * of realms to choose from, and by using a {@code RealmCallback} if * the realm must be entered. * - *@return A possibly null SaslClient created using the parameters - * supplied. If null, this factory cannot produce a SaslClient + *@return A possibly null {@code SaslClient} created using the parameters + * supplied. If null, this factory cannot produce a {@code SaslClient} * using the parameters supplied. - *@exception SaslException If cannot create a SaslClient because + *@exception SaslException If cannot create a {@code SaslClient} because * of an error. */ public abstract SaslClient createSaslClient( @@ -99,12 +99,12 @@ public abstract interface SaslClientFactory { * Returns an array of names of mechanisms that match the specified * mechanism selection policies. * @param props The possibly null set of properties used to specify the - * security policy of the SASL mechanisms. For example, if props - * contains the Sasl.POLICY_NOPLAINTEXT property with the value - * "true", then the factory must not return any SASL mechanisms + * security policy of the SASL mechanisms. For example, if {@code props} + * contains the {@code Sasl.POLICY_NOPLAINTEXT} property with the value + * {@code "true"}, then the factory must not return any SASL mechanisms * that are susceptible to simple plain passive attacks. - * See the Sasl class for a complete list of policy properties. - * Non-policy related properties, if present in props, are ignored, + * See the {@code Sasl} class for a complete list of policy properties. + * Non-policy related properties, if present in {@code props}, are ignored, * including any map entries with non-String keys. * @return A non-null array containing a IANA-registered SASL mechanism names. */ diff --git a/jdk/src/share/classes/javax/security/sasl/SaslException.java b/jdk/src/share/classes/javax/security/sasl/SaslException.java index ee82c6ea8c7..87fed3cec58 100644 --- a/jdk/src/share/classes/javax/security/sasl/SaslException.java +++ b/jdk/src/share/classes/javax/security/sasl/SaslException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ public class SaslException extends IOException { private Throwable _exception; /** - * Constructs a new instance of SaslException. + * Constructs a new instance of {@code SaslException}. * The root exception and the detailed message are null. */ public SaslException () { @@ -53,7 +53,7 @@ public class SaslException extends IOException { } /** - * Constructs a new instance of SaslException with a detailed message. + * Constructs a new instance of {@code SaslException} with a detailed message. * The root exception is null. * @param detail A possibly null string containing details of the exception. * @@ -64,7 +64,7 @@ public class SaslException extends IOException { } /** - * Constructs a new instance of SaslException with a detailed message + * Constructs a new instance of {@code SaslException} with a detailed message * and a root exception. * For example, a SaslException might result from a problem with * the callback handler, which might throw a NoSuchCallbackException if diff --git a/jdk/src/share/classes/javax/security/sasl/SaslServer.java b/jdk/src/share/classes/javax/security/sasl/SaslServer.java index ec5d20a230d..818ae999654 100644 --- a/jdk/src/share/classes/javax/security/sasl/SaslServer.java +++ b/jdk/src/share/classes/javax/security/sasl/SaslServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,14 +30,14 @@ package javax.security.sasl; *

    * A server such an LDAP server gets an instance of this * class in order to perform authentication defined by a specific SASL - * mechanism. Invoking methods on the SaslServer instance + * mechanism. Invoking methods on the {@code SaslServer} instance * generates challenges according to the SASL - * mechanism implemented by the SaslServer. + * mechanism implemented by the {@code SaslServer}. * As the authentication proceeds, the instance * encapsulates the state of a SASL server's authentication exchange. *

    - * Here's an example of how an LDAP server might use a SaslServer. - * It first gets an instance of a SaslServer for the SASL mechanism + * Here's an example of how an LDAP server might use a {@code SaslServer}. + * It first gets an instance of a {@code SaslServer} for the SASL mechanism * requested by the client: *

      * SaslServer ss = Sasl.createSaslServer(mechanism,
    @@ -104,8 +104,8 @@ public abstract interface SaslServer {
          * to the client. It is non-null if the authentication must be continued
          * by sending a challenge to the client, or if the authentication has
          * succeeded but challenge data needs to be processed by the client.
    -     * isComplete() should be called
    -     * after each call to evaluateResponse(),to determine if any further
    +     * {@code isComplete()} should be called
    +     * after each call to {@code evaluateResponse()},to determine if any further
          * response is needed from the client.
          *
          * @param response The non-null (but possibly empty) response sent
    @@ -123,7 +123,7 @@ public abstract interface SaslServer {
         /**
           * Determines whether the authentication exchange has completed.
           * This method is typically called after each invocation of
    -      * evaluateResponse() to determine whether the
    +      * {@code evaluateResponse()} to determine whether the
           * authentication has completed successfully or should be continued.
           * @return true if the authentication exchange has completed; false otherwise.
           */
    @@ -141,22 +141,22 @@ public abstract interface SaslServer {
         /**
          * Unwraps a byte array received from the client.
          * This method can be called only after the authentication exchange has
    -     * completed (i.e., when isComplete() returns true) and only if
    +     * completed (i.e., when {@code isComplete()} returns true) and only if
          * the authentication exchange has negotiated integrity and/or privacy
          * as the quality of protection; otherwise,
    -     * an IllegalStateException is thrown.
    +     * an {@code IllegalStateException} is thrown.
          *

    - * incoming is the contents of the SASL buffer as defined in RFC 2222 + * {@code incoming} is the contents of the SASL buffer as defined in RFC 2222 * without the leading four octet field that represents the length. - * offset and len specify the portion of incoming + * {@code offset} and {@code len} specify the portion of {@code incoming} * to use. * * @param incoming A non-null byte array containing the encoded bytes * from the client. - * @param offset The starting position at incoming of the bytes to use. - * @param len The number of bytes from incoming to use. + * @param offset The starting position at {@code incoming} of the bytes to use. + * @param len The number of bytes from {@code incoming} to use. * @return A non-null byte array containing the decoded bytes. - * @exception SaslException if incoming cannot be successfully + * @exception SaslException if {@code incoming} cannot be successfully * unwrapped. * @exception IllegalStateException if the authentication exchange has * not completed, or if the negotiated quality of protection @@ -168,21 +168,21 @@ public abstract interface SaslServer { /** * Wraps a byte array to be sent to the client. * This method can be called only after the authentication exchange has - * completed (i.e., when isComplete() returns true) and only if + * completed (i.e., when {@code isComplete()} returns true) and only if * the authentication exchange has negotiated integrity and/or privacy - * as the quality of protection; otherwise, a SaslException is thrown. + * as the quality of protection; otherwise, a {@code SaslException} is thrown. *

    * The result of this method * will make up the contents of the SASL buffer as defined in RFC 2222 * without the leading four octet field that represents the length. - * offset and len specify the portion of outgoing + * {@code offset} and {@code len} specify the portion of {@code outgoing} * to use. * * @param outgoing A non-null byte array containing the bytes to encode. - * @param offset The starting position at outgoing of the bytes to use. - * @param len The number of bytes from outgoing to use. + * @param offset The starting position at {@code outgoing} of the bytes to use. + * @param len The number of bytes from {@code outgoing} to use. * @return A non-null byte array containing the encoded bytes. - * @exception SaslException if outgoing cannot be successfully + * @exception SaslException if {@code outgoing} cannot be successfully * wrapped. * @exception IllegalStateException if the authentication exchange has * not completed, or if the negotiated quality of protection has @@ -194,8 +194,8 @@ public abstract interface SaslServer { /** * Retrieves the negotiated property. * This method can be called only after the authentication exchange has - * completed (i.e., when isComplete() returns true); otherwise, an - * IllegalStateException is thrown. + * completed (i.e., when {@code isComplete()} returns true); otherwise, an + * {@code IllegalStateException} is thrown. * * @param propName the property * @return The value of the negotiated property. If null, the property was diff --git a/jdk/src/share/classes/javax/security/sasl/SaslServerFactory.java b/jdk/src/share/classes/javax/security/sasl/SaslServerFactory.java index 33a01750165..baa8999634d 100644 --- a/jdk/src/share/classes/javax/security/sasl/SaslServerFactory.java +++ b/jdk/src/share/classes/javax/security/sasl/SaslServerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,16 +29,16 @@ import java.util.Map; import javax.security.auth.callback.CallbackHandler; /** - * An interface for creating instances of SaslServer. + * An interface for creating instances of {@code SaslServer}. * A class that implements this interface * must be thread-safe and handle multiple simultaneous * requests. It must also have a public constructor that accepts no * argument. *

    * This interface is not normally accessed directly by a server, which will use the - * Sasl static methods + * {@code Sasl} static methods * instead. However, a particular environment may provide and install a - * new or different SaslServerFactory. + * new or different {@code SaslServerFactory}. * * @since 1.5 * @@ -50,10 +50,10 @@ import javax.security.auth.callback.CallbackHandler; */ public abstract interface SaslServerFactory { /** - * Creates a SaslServer using the parameters supplied. + * Creates a {@code SaslServer} using the parameters supplied. * It returns null - * if no SaslServer can be created using the parameters supplied. - * Throws SaslException if it cannot create a SaslServer + * if no {@code SaslServer} can be created using the parameters supplied. + * Throws {@code SaslException} if it cannot create a {@code SaslServer} * because of an error. * * @param mechanism The non-null @@ -63,10 +63,10 @@ public abstract interface SaslServerFactory { * @param serverName The fully qualified host name of the server to * authenticate to, or null if the server is not bound to any specific host * name. If the mechanism does not allow an unbound server, a - * SaslException will be thrown. + * {@code SaslException} will be thrown. * @param props The possibly null set of properties used to select the SASL * mechanism and to configure the authentication exchange of the selected - * mechanism. See the Sasl class for a list of standard properties. + * mechanism. See the {@code Sasl} class for a list of standard properties. * Other, possibly mechanism-specific, properties can be included. * Properties not relevant to the selected mechanism are ignored, * including any map entries with non-String keys. @@ -75,16 +75,16 @@ public abstract interface SaslServerFactory { * mechanisms to get further information from the application/library * to complete the authentication. For example, a SASL mechanism might * require the authentication ID, password and realm from the caller. - * The authentication ID is requested by using a NameCallback. - * The password is requested by using a PasswordCallback. - * The realm is requested by using a RealmChoiceCallback if there is a list - * of realms to choose from, and by using a RealmCallback if + * The authentication ID is requested by using a {@code NameCallback}. + * The password is requested by using a {@code PasswordCallback}. + * The realm is requested by using a {@code RealmChoiceCallback} if there is a list + * of realms to choose from, and by using a {@code RealmCallback} if * the realm must be entered. * - *@return A possibly null SaslServer created using the parameters - * supplied. If null, this factory cannot produce a SaslServer + *@return A possibly null {@code SaslServer} created using the parameters + * supplied. If null, this factory cannot produce a {@code SaslServer} * using the parameters supplied. - *@exception SaslException If cannot create a SaslServer because + *@exception SaslException If cannot create a {@code SaslServer} because * of an error. */ public abstract SaslServer createSaslServer( @@ -98,12 +98,12 @@ public abstract interface SaslServerFactory { * Returns an array of names of mechanisms that match the specified * mechanism selection policies. * @param props The possibly null set of properties used to specify the - * security policy of the SASL mechanisms. For example, if props - * contains the Sasl.POLICY_NOPLAINTEXT property with the value - * "true", then the factory must not return any SASL mechanisms + * security policy of the SASL mechanisms. For example, if {@code props} + * contains the {@code Sasl.POLICY_NOPLAINTEXT} property with the value + * {@code "true"}, then the factory must not return any SASL mechanisms * that are susceptible to simple plain passive attacks. - * See the Sasl class for a complete list of policy properties. - * Non-policy related properties, if present in props, are ignored, + * See the {@code Sasl} class for a complete list of policy properties. + * Non-policy related properties, if present in {@code props}, are ignored, * including any map entries with non-String keys. * @return A non-null array containing a IANA-registered SASL mechanism names. */ diff --git a/jdk/src/share/classes/javax/security/sasl/package-info.java b/jdk/src/share/classes/javax/security/sasl/package-info.java new file mode 100644 index 00000000000..f8e42b7120c --- /dev/null +++ b/jdk/src/share/classes/javax/security/sasl/package-info.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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. + */ + +/** + * Contains class and interfaces for supporting SASL. + * + * This package defines classes and interfaces for SASL mechanisms. + * It is used by developers to add authentication support for + * connection-based protocols that use SASL. + * + *

    SASL Overview

    + * + * Simple Authentication and Security Layer (SASL) specifies a + * challenge-response protocol in which data is exchanged between the + * client and the server for the purposes of + * authentication and (optional) establishment of a security layer on + * which to carry on subsequent communications. It is used with + * connection-based protocols such as LDAPv3 or IMAPv4. SASL is + * described in + * RFC 2222. + * + * + * There are various mechanisms defined for SASL. + * Each mechanism defines the data that must be exchanged between the + * client and server in order for the authentication to succeed. + * This data exchange required for a particular mechanism is referred to + * to as its protocol profile. + * The following are some examples of mechanisms that have been defined by + * the Internet standards community. + *
      + *
    • DIGEST-MD5 (RFC 2831). + * This mechanism defines how HTTP Digest Authentication can be used as a SASL + * mechanism. + *
    • Anonymous (RFC 2245). + * This mechanism is anonymous authentication in which no credentials are + * necessary. + *
    • External (RFC 2222). + * This mechanism obtains authentication information + * from an external source (such as TLS or IPsec). + *
    • S/Key (RFC 2222). + * This mechanism uses the MD4 digest algorithm to exchange data based on + * a shared secret. + *
    • GSSAPI (RFC 2222). + * This mechanism uses the + * GSSAPI + * for obtaining authentication information. + *
    + * + * Some of these mechanisms provide both authentication and establishment + * of a security layer, others only authentication. Anonymous and + * S/Key do not provide for any security layers. GSSAPI and DIGEST-MD5 + * allow negotiation of the security layer. For External, the + * security layer is determined by the external protocol. + * + *

    Usage

    + * + * Users of this API are typically developers who produce + * client library implementations for connection-based protocols, + * such as LDAPv3 and IMAPv4, + * and developers who write servers (such as LDAP servers and IMAP servers). + * Developers who write client libraries use the + * {@code SaslClient} and {@code SaslClientFactory} interfaces. + * Developers who write servers use the + * {@code SaslServer} and {@code SaslServerFactory} interfaces. + * + * Among these two groups of users, each can be further divided into two groups: + * those who produce the SASL mechanisms and those + * who use the SASL mechanisms. + * The producers of SASL mechanisms need to provide implementations + * for these interfaces, while users of the SASL mechanisms use + * the APIs in this package to access those implementations. + * + *

    Related Documentation

    + * + * Please refer to the + * Java + * SASL Programming Guide for information on how to use this API. + * + * @since 1.5 + */ +package javax.security.sasl; diff --git a/jdk/src/share/classes/javax/security/sasl/package.html b/jdk/src/share/classes/javax/security/sasl/package.html deleted file mode 100644 index cf497ebe380..00000000000 --- a/jdk/src/share/classes/javax/security/sasl/package.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - -Contains class and interfaces for supporting SASL. - -This package defines classes and interfaces for SASL mechanisms. -It is used by developers to add authentication support for -connection-based protocols that use SASL. - -

    SASL Overview

    -

    - -Simple Authentication and Security Layer (SASL) specifies a -challenge-response protocol in which data is exchanged between the -client and the server for the purposes of -authentication and (optional) establishment of a security layer on -which to carry on subsequent communications. It is used with -connection-based protocols such as LDAPv3 or IMAPv4. SASL is -described in -RFC 2222. - -

    -There are various mechanisms defined for SASL. -Each mechanism defines the data that must be exchanged between the -client and server in order for the authentication to succeed. -This data exchange required for a particular mechanism is referred to -to as its protocol profile. -The following are some examples of mechanims that have been defined by -the Internet standards community. -

      -
    • DIGEST-MD5 (RFC 2831). -This mechanism defines how HTTP Digest Authentication can be used as a SASL -mechanism. -
    • Anonymous (RFC 2245). -This mechamism is anonymous authentication in which no credentials are -necessary. -
    • External (RFC 2222). -This mechanism obtains authentication information -from an external source (such as TLS or IPsec). -
    • S/Key (RFC 2222). -This mechanism uses the MD4 digest algorithm to exchange data based on -a shared secret. -
    • GSSAPI (RFC 2222). -This mechanism uses the -GSSAPI -for obtaining authentication information. -
    - -

    -Some of these mechanisms provide both authentication and establishment -of a security layer, others only authentication. Anonymous and -S/Key do not provide for any security layers. GSSAPI and DIGEST-MD5 -allow negotiation of the security layer. For External, the -security layer is determined by the external protocol. - -

    Usage

    - -

    -Users of this API are typically developers who produce -client library implementations for connection-based protocols, -such as LDAPv3 and IMAPv4, -and developers who write servers (such as LDAP servers and IMAP servers). -Developers who write client libraries use the -SaslClient and SaslClientFactory interfaces. -Developers who write servers use the -SaslServer and SaslServerFactory interfaces. -

    -Among these two groups of users, each can be further divided into two groups: -those who produce the SASL mechanisms and those -who use the SASL mechanisms. -The producers of SASL mechanisms need to provide implementations -for these interfaces, while users of the SASL mechanisms use -the APIs in this package to access those implementations. - -

    Related Documentation

    - -Please refer to the -Java -SASL Programming Guide for information on how to use this API. - - -@since 1.5 - - - - - diff --git a/jdk/src/share/lib/hijrah-config-umalqura.properties b/jdk/src/share/lib/hijrah-config-umalqura.properties index ac16c7e222f..1786c14de97 100644 --- a/jdk/src/share/lib/hijrah-config-umalqura.properties +++ b/jdk/src/share/lib/hijrah-config-umalqura.properties @@ -1,58 +1,369 @@ -# -# hijrah-config-umalqura.properties -# -# -# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. -# -# This properties file defines a Hijrah calendar variant. -# -# Fields: -# -# ::= 'version' '=' -# ::= 'id' '=' -# ::= 'type' '=' -# ::= 'iso-start' '=' -# ::= '=' -# -# version ... (Required) -# -# id ... (Required) -# Identifies the Java Chronology -# -# type ... (Required) -# Identifies the type of calendar in the standard calendar ID scheme -# iso-start ... (Required) -# Specifies the corresponding ISO date to the first Hijrah day -# in the defined range of dates -# -# year ... (Required) -# Number of days for each month of a Hijrah year -# * Each line defines a year. The years must be in the chronological -# order and no gap is allowed. -# * Each line is in the form indicated above. is a Hijrah year and -# nn is the number of days for a month listed in the order of the months. -# * Each year must have 12 months. -# * Each month should be 29 or 30 days long. -# * There must be one or more space characters between the months. -# - -# indicates the version of this definition -version=1.8.0_1 - -# Java chronology ID -id=Hijrah-umalqura - -# Standard calendar type specification -type=islamic-umalqura - -# defines the corresponding ISO date to the earliest Hijrah date -iso-start=2010-12-07 - -# -# the data section; defines the dates with the number of days for each month -# -# Placeholder data until full Umm alQura data can be validated -1432=29 30 30 30 29 30 29 30 29 30 29 29 -1433=30 29 30 30 29 30 30 29 30 29 30 29 -1434=29 30 29 30 29 30 30 29 30 30 29 29 -1435=30 29 30 29 30 29 30 29 30 30 29 30 +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute 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. +# +# This properties file defines a Hijrah calendar variant. +# +# Fields: +# +# ::= 'version' '=' +# ::= 'id' '=' +# ::= 'type' '=' +# ::= 'iso-start' '=' +# ::= '=' +# +# version ... (Required) +# +# id ... (Required) +# Identifies the Java Chronology +# +# type ... (Required) +# Identifies the type of calendar in the standard calendar ID scheme +# iso-start ... (Required) +# Specifies the corresponding ISO date to the first Hijrah day +# in the defined range of dates +# +# year ... (Required) +# Number of days for each month of a Hijrah year +# * Each line defines a year. The years must be in chronological +# order and no gap is allowed. +# * Each line is in the form indicated above. is a Hijrah year and +# nn is the number of days for a month listed in the order of the months. +# * Each year must have 12 months. +# * Each month should be 29 or 30 days long. +# * There must be one or more space characters between the months. +# + +# Version of this definition +version=1.8.0_1 + +# Java chronology ID +id=Hijrah-umalqura + +# Standard calendar type specification +type=islamic-umalqura + +# defines the corresponding ISO date to the earliest Hijrah date +iso-start=1882-11-12 + +# 1 2 3 4 5 6 7 8 9 10 11 12 +1300=30 29 30 29 30 29 30 29 30 29 30 29 +1301=30 30 29 30 29 30 29 30 29 30 29 29 +1302=30 30 30 29 30 30 29 29 30 29 29 30 +1303=29 30 30 29 30 30 29 30 29 30 29 29 +1304=29 30 30 29 30 30 30 29 30 29 30 29 +1305=29 29 30 30 29 30 30 29 30 30 29 29 +1306=30 29 30 29 30 29 30 29 30 30 29 30 +1307=29 30 29 30 29 30 29 30 29 30 29 30 +1308=29 30 30 29 30 29 30 29 30 29 29 30 +1309=29 30 30 30 30 29 29 30 29 29 30 29 +1310=30 29 30 30 30 29 30 29 30 29 29 30 +1311=29 30 29 30 30 30 29 30 29 30 29 29 +1312=30 29 30 29 30 30 29 30 30 29 30 29 +1313=29 30 29 30 29 30 29 30 30 30 29 29 +1314=30 30 29 30 29 29 30 29 30 30 29 30 +1315=29 30 30 29 30 29 29 30 29 30 29 30 +1316=29 30 30 30 29 30 29 29 30 29 30 29 +1317=30 29 30 30 29 30 29 30 29 30 29 29 +1318=30 29 30 30 29 30 30 29 30 29 30 29 +1319=29 30 29 30 30 29 30 29 30 30 29 30 +1320=29 30 29 29 30 29 30 29 30 30 30 29 +1321=30 29 30 29 29 30 29 29 30 30 30 30 +1322=29 30 29 30 29 29 29 30 29 30 30 30 +1323=29 30 30 29 30 29 29 29 30 29 30 30 +1324=29 30 30 29 30 29 30 29 29 30 29 30 +1325=30 29 30 29 30 30 29 30 29 30 29 30 +1326=29 29 30 29 30 30 29 30 29 30 30 29 +1327=30 29 29 30 29 30 29 30 30 29 30 30 +1328=29 30 29 29 30 29 29 30 30 30 29 30 +1329=30 29 30 29 29 30 29 29 30 30 29 30 +1330=30 30 29 30 29 29 30 29 29 30 30 29 +1331=30 30 29 30 30 29 29 30 29 30 29 30 +1332=29 30 29 30 30 29 30 29 30 30 29 29 +1333=30 29 29 30 30 29 30 30 29 30 30 29 +1334=29 29 30 29 30 29 30 30 30 29 30 29 +1335=30 29 30 29 29 30 29 30 30 29 30 30 +1336=29 30 29 30 29 29 30 29 30 29 30 30 +1337=30 29 30 29 30 29 29 30 29 30 29 30 +1338=29 30 30 29 30 30 29 29 30 29 30 29 +1339=30 29 30 29 30 30 30 29 30 29 29 30 +1340=29 29 30 29 30 30 30 30 29 30 29 29 +1341=30 29 29 30 29 30 30 30 29 30 30 29 +1342=29 29 30 29 30 29 30 30 29 30 30 29 +1343=30 29 29 30 29 30 29 30 29 30 30 29 +1344=30 29 30 29 30 30 29 29 30 29 30 29 +1345=30 29 30 30 30 29 30 29 29 30 29 29 +1346=30 29 30 30 30 30 29 30 29 29 30 29 +1347=29 30 29 30 30 30 29 30 30 29 29 30 +1348=29 29 30 29 30 30 29 30 30 30 29 29 +1349=30 29 29 30 29 30 30 29 30 30 29 30 +1350=29 30 29 30 29 30 29 29 30 30 29 30 +1351=30 29 30 29 30 29 30 29 29 30 29 30 +1352=30 29 30 30 29 30 29 30 29 29 30 29 +1353=30 29 30 30 30 29 30 29 29 30 29 30 +1354=29 30 29 30 30 29 30 30 29 30 29 29 +1355=30 29 29 30 30 29 30 30 29 30 30 29 +1356=29 30 29 30 29 30 29 30 29 30 30 30 +1357=29 29 30 29 30 29 29 30 29 30 30 30 +1358=29 30 29 30 29 30 29 29 30 29 30 30 +1359=29 30 30 29 30 29 30 29 29 29 30 30 +1360=29 30 30 30 29 30 29 30 29 29 30 29 +1361=30 29 30 30 29 30 30 29 29 30 29 30 +1362=29 30 29 30 29 30 30 29 30 29 30 29 +1363=30 29 30 29 30 29 30 29 30 29 30 30 +1364=29 30 29 30 29 29 30 29 30 29 30 30 +1365=30 30 29 29 30 29 29 30 29 30 29 30 +1366=30 30 29 30 29 30 29 29 30 29 30 29 +1367=30 30 29 30 30 29 30 29 29 30 29 30 +1368=29 30 29 30 30 30 29 29 30 29 30 29 +1369=30 29 30 29 30 30 29 30 29 30 30 29 +1370=30 29 29 30 29 30 29 30 29 30 30 30 +1371=29 30 29 29 30 29 30 29 30 29 30 30 +1372=30 29 29 30 29 30 29 29 30 29 30 30 +1373=30 29 30 29 30 29 30 29 29 30 29 30 +1374=30 29 30 30 29 30 29 30 29 29 30 29 +1375=30 29 30 30 29 30 30 29 30 29 30 29 +1376=29 30 29 30 29 30 30 30 29 30 29 30 +1377=29 29 30 29 29 30 30 30 29 30 30 29 +1378=30 29 29 29 30 29 30 30 29 30 30 30 +1379=29 30 29 29 29 30 29 30 30 29 30 30 +1380=29 30 29 30 29 30 29 30 29 30 29 30 +1381=29 30 29 30 30 29 30 29 30 29 29 30 +1382=29 30 29 30 30 29 30 30 29 30 29 29 +1383=30 29 29 30 30 30 29 30 30 29 30 29 +1384=29 30 29 29 30 30 29 30 30 30 29 30 +1385=29 29 30 29 29 30 30 29 30 30 30 29 +1386=30 29 29 30 29 29 30 30 29 30 30 29 +1387=30 29 30 29 30 29 30 29 30 29 30 29 +1388=30 30 29 30 29 30 29 30 29 30 29 29 +1389=30 30 29 30 30 29 30 30 29 29 30 29 +1390=29 30 29 30 30 30 29 30 29 30 29 30 +1391=29 29 30 29 30 30 29 30 30 29 30 29 +1392=30 29 29 30 29 30 29 30 30 29 30 30 +1393=29 30 29 29 30 29 30 29 30 29 30 30 +1394=30 29 30 29 29 30 29 30 29 30 29 30 +1395=30 29 30 30 29 30 29 29 30 29 29 30 +1396=30 29 30 30 29 30 30 29 29 30 29 29 +1397=30 29 30 30 29 30 30 30 29 29 29 30 +1398=29 30 29 30 30 29 30 30 29 30 29 29 +1399=30 29 30 29 30 29 30 30 29 30 29 30 +1400=30 29 30 29 29 30 29 30 29 30 29 30 +1401=30 30 29 30 29 29 30 29 29 30 29 30 +1402=30 30 30 29 30 29 29 30 29 29 30 29 +1403=30 30 30 29 30 30 29 29 30 29 29 30 +1404=29 30 30 29 30 30 29 30 29 30 29 29 +1405=30 29 30 29 30 30 30 29 30 29 29 30 +1406=30 29 29 30 29 30 30 29 30 29 30 30 +1407=29 30 29 29 30 29 30 29 30 29 30 30 +1408=30 29 30 29 30 29 29 30 29 29 30 30 +1409=30 30 29 30 29 30 29 29 30 29 29 30 +1410=30 30 29 30 30 29 30 29 29 30 29 29 +1411=30 30 29 30 30 29 30 30 29 29 30 29 +1412=30 29 30 29 30 29 30 30 30 29 29 30 +1413=29 30 29 29 30 29 30 30 30 29 30 29 +1414=30 29 30 29 29 30 29 30 30 29 30 30 +1415=29 30 29 30 29 29 30 29 30 29 30 30 +1416=30 29 30 29 30 29 29 30 29 30 29 30 +1417=30 29 30 30 29 29 30 29 30 29 30 29 +1418=30 29 30 30 29 30 29 30 29 30 29 30 +1419=29 30 29 30 29 30 29 30 30 30 29 29 +1420=29 30 29 29 30 29 30 30 30 30 29 30 +1421=29 29 30 29 29 29 30 30 30 30 29 30 +1422=30 29 29 30 29 29 29 30 30 30 29 30 +1423=30 29 30 29 30 29 29 30 29 30 29 30 +1424=30 29 30 30 29 30 29 29 30 29 30 29 +1425=30 29 30 30 29 30 29 30 30 29 30 29 +1426=29 30 29 30 29 30 30 29 30 30 29 30 +1427=29 29 30 29 30 29 30 30 29 30 30 29 +1428=30 29 29 30 29 29 30 30 30 29 30 30 +1429=29 30 29 29 30 29 29 30 30 29 30 30 +1430=29 30 30 29 29 30 29 30 29 30 29 30 +1431=29 30 30 29 30 29 30 29 30 29 29 30 +1432=29 30 30 30 29 30 29 30 29 30 29 29 +1433=30 29 30 30 29 30 30 29 30 29 30 29 +1434=29 30 29 30 29 30 30 29 30 30 29 29 +1435=30 29 30 29 30 29 30 29 30 30 29 30 +1436=29 30 29 30 29 30 29 30 29 30 29 30 +1437=30 29 30 30 29 29 30 29 30 29 29 30 +1438=30 29 30 30 30 29 29 30 29 29 30 29 +1439=30 29 30 30 30 29 30 29 30 29 29 30 +1440=29 30 29 30 30 30 29 30 29 30 29 29 +1441=30 29 30 29 30 30 29 30 30 29 30 29 +1442=29 30 29 30 29 30 29 30 30 29 30 29 +1443=30 29 30 29 30 29 30 29 30 29 30 30 +1444=29 30 29 30 30 29 29 30 29 30 29 30 +1445=29 30 30 30 29 30 29 29 30 29 29 30 +1446=29 30 30 30 29 30 30 29 29 30 29 29 +1447=30 29 30 30 30 29 30 29 30 29 30 29 +1448=29 30 29 30 30 29 30 30 29 30 29 30 +1449=29 29 30 29 30 29 30 30 29 30 30 29 +1450=30 29 30 29 29 30 29 30 29 30 30 29 +1451=30 30 30 29 29 30 29 29 30 30 29 30 +1452=30 29 30 30 29 29 30 29 29 30 29 30 +1453=30 29 30 30 29 30 29 30 29 29 30 29 +1454=30 29 30 30 29 30 30 29 30 29 30 29 +1455=29 30 29 30 30 29 30 29 30 30 29 30 +1456=29 29 30 29 30 29 30 29 30 30 30 29 +1457=30 29 29 30 29 29 30 29 30 30 30 30 +1458=29 30 29 29 30 29 29 30 29 30 30 30 +1459=29 30 30 29 29 30 29 29 30 29 30 30 +1460=29 30 30 29 30 29 30 29 29 30 29 30 +1461=29 30 30 29 30 29 30 29 30 30 29 29 +1462=30 29 30 29 30 30 29 30 29 30 30 29 +1463=29 30 29 30 29 30 29 30 30 30 29 30 +1464=29 30 29 29 30 29 29 30 30 30 29 30 +1465=30 29 30 29 29 30 29 29 30 30 29 30 +1466=30 30 29 30 29 29 29 30 29 30 30 29 +1467=30 30 29 30 30 29 29 30 29 30 29 30 +1468=29 30 29 30 30 29 30 29 30 29 30 29 +1469=29 30 29 30 30 29 30 30 29 30 29 30 +1470=29 29 30 29 30 30 29 30 30 29 30 29 +1471=30 29 29 30 29 30 29 30 30 29 30 30 +1472=29 30 29 29 30 29 30 29 30 30 29 30 +1473=29 30 29 30 30 29 29 30 29 30 29 30 +1474=29 30 30 29 30 30 29 29 30 29 30 29 +1475=29 30 30 29 30 30 30 29 29 30 29 29 +1476=30 29 30 29 30 30 30 29 30 29 30 29 +1477=29 30 29 29 30 30 30 30 29 30 29 30 +1478=29 29 30 29 30 29 30 30 29 30 30 29 +1479=30 29 29 30 29 30 29 30 29 30 30 29 +1480=30 29 30 29 30 29 30 29 30 29 30 29 +1481=30 29 30 30 29 30 29 30 29 30 29 29 +1482=30 29 30 30 30 30 29 30 29 29 30 29 +1483=29 30 29 30 30 30 29 30 30 29 29 30 +1484=29 29 30 29 30 30 30 29 30 29 30 29 +1485=30 29 29 30 29 30 30 29 30 30 29 30 +1486=29 30 29 29 30 29 30 29 30 30 29 30 +1487=30 29 30 29 30 29 29 30 29 30 29 30 +1488=30 29 30 30 29 30 29 29 30 29 30 29 +1489=30 29 30 30 30 29 30 29 29 30 29 30 +1490=29 30 29 30 30 29 30 30 29 29 30 29 +1491=30 29 29 30 30 29 30 30 29 30 29 30 +1492=29 30 29 29 30 30 29 30 29 30 30 29 +1493=30 29 30 29 30 29 29 30 29 30 30 30 +1494=29 30 29 30 29 30 29 29 29 30 30 30 +1495=29 30 30 29 30 29 29 30 29 29 30 30 +1496=29 30 30 30 29 30 29 29 30 29 29 30 +1497=30 29 30 30 29 30 29 30 29 30 29 30 +1498=29 30 29 30 29 30 30 29 30 29 30 29 +1499=30 29 30 29 29 30 30 29 30 29 30 30 +1500=29 30 29 30 29 29 30 29 30 29 30 30 +1501=30 29 30 29 30 29 29 29 30 29 30 30 +1502=30 30 29 30 29 30 29 29 29 30 30 29 +1503=30 30 29 30 30 29 30 29 29 29 30 30 +1504=29 30 29 30 30 30 29 29 30 29 30 29 +1505=30 29 30 29 30 30 29 30 29 30 30 29 +1506=29 30 29 29 30 30 29 30 30 29 30 30 +1507=29 29 30 29 29 30 30 29 30 29 30 30 +1508=30 29 29 30 29 30 29 29 30 29 30 30 +1509=30 29 30 29 30 29 30 29 29 30 29 30 +1510=30 29 30 30 29 30 29 30 29 29 30 29 +1511=30 29 30 30 29 30 30 29 30 29 29 30 +1512=29 30 29 30 29 30 30 30 29 30 29 30 +1513=29 29 29 30 29 30 30 30 29 30 30 29 +1514=30 29 29 29 30 29 30 30 29 30 30 30 +1515=29 29 30 29 29 30 29 30 30 29 30 30 +1516=29 30 29 30 29 29 30 29 30 29 30 30 +1517=29 30 29 30 29 30 30 29 29 30 29 30 +1518=29 30 29 30 30 29 30 30 29 30 29 29 +1519=30 29 29 30 30 30 29 30 30 29 30 29 +1520=29 30 29 29 30 30 30 29 30 30 29 30 +1521=29 29 29 30 29 30 30 29 30 30 29 30 +1522=30 29 29 29 30 29 30 30 29 30 30 29 +1523=30 29 30 29 30 29 30 29 29 30 30 29 +1524=30 30 29 30 29 30 29 30 29 29 30 29 +1525=30 30 29 30 30 29 30 29 30 29 29 30 +1526=29 30 29 30 30 30 29 30 29 30 29 29 +1527=30 29 30 29 30 30 29 30 30 29 30 29 +1528=30 29 29 30 29 30 29 30 30 29 30 30 +1529=29 30 29 29 30 29 30 29 30 29 30 30 +1530=29 30 30 29 29 30 29 30 29 29 30 30 +1531=29 30 30 30 29 29 30 29 30 29 29 30 +1532=29 30 30 30 29 30 30 29 29 29 30 29 +1533=30 29 30 30 30 29 30 29 30 29 29 30 +1534=29 30 29 30 30 29 30 30 29 29 30 29 +1535=30 29 30 29 30 29 30 30 29 30 29 30 +1536=29 30 29 30 29 30 29 30 29 30 29 30 +1537=30 29 30 30 29 29 30 29 29 30 29 30 +1538=30 30 29 30 30 29 29 30 29 29 30 29 +1539=30 30 30 29 30 30 29 29 30 29 29 30 +1540=29 30 30 29 30 30 29 30 29 29 30 29 +1541=30 29 30 29 30 30 30 29 30 29 29 30 +1542=29 30 29 30 29 30 30 29 30 29 30 30 +1543=29 30 29 29 30 29 30 29 30 29 30 30 +1544=30 29 30 29 29 30 29 30 29 30 29 30 +1545=30 30 29 30 29 29 30 29 30 29 29 30 +1546=30 30 29 30 29 30 29 30 29 30 29 29 +1547=30 30 29 30 30 29 30 29 30 29 30 29 +1548=30 29 29 30 30 29 30 30 29 30 29 30 +1549=29 30 29 29 30 29 30 30 30 29 30 29 +1550=30 29 30 29 29 29 30 30 30 29 30 30 +1551=29 30 29 29 30 29 29 30 30 29 30 30 +1552=30 29 30 29 29 30 29 29 30 30 29 30 +1553=30 29 30 29 30 29 30 29 30 29 30 29 +1554=30 29 30 29 30 30 29 30 29 30 29 30 +1555=29 29 30 29 30 30 29 30 30 29 30 29 +1556=30 29 29 30 29 30 29 30 30 30 29 30 +1557=29 30 29 29 29 30 29 30 30 30 30 29 +1558=30 29 30 29 29 29 30 29 30 30 30 29 +1559=30 30 29 29 30 29 29 30 30 29 30 29 +1560=30 30 29 30 29 30 29 30 29 30 29 30 +1561=29 30 30 29 30 29 30 30 29 29 30 29 +1562=29 30 30 29 30 29 30 30 30 29 29 30 +1563=29 30 29 29 30 29 30 30 30 29 30 29 +1564=30 29 30 29 29 30 29 30 30 30 29 30 +1565=29 30 29 30 29 29 30 29 30 30 29 30 +1566=30 29 30 29 30 29 29 30 29 30 29 30 +1567=30 29 30 30 29 30 29 30 29 29 30 29 +1568=30 29 30 30 30 29 30 29 30 29 29 29 +1569=30 29 30 30 30 29 30 30 29 30 29 29 +1570=29 30 29 30 30 29 30 30 30 29 29 30 +1571=29 29 30 29 30 30 29 30 30 29 30 29 +1572=30 29 29 30 29 30 29 30 30 29 30 29 +1573=30 29 30 30 29 30 29 29 30 29 30 29 +1574=30 30 29 30 30 29 30 29 29 30 29 29 +1575=30 30 30 29 30 30 29 30 29 29 29 30 +1576=29 30 30 29 30 30 30 29 30 29 29 29 +1577=30 29 30 30 29 30 30 29 30 29 30 29 +1578=29 30 29 30 29 30 30 29 30 30 29 30 +1579=29 30 29 30 29 29 30 30 29 30 29 30 +1580=29 30 30 29 30 29 29 30 29 30 29 30 +1581=30 30 29 30 29 30 29 29 30 29 30 29 +1582=30 30 29 30 30 29 30 29 30 29 29 29 +1583=30 30 29 30 30 30 29 30 29 30 29 29 +1584=29 30 30 29 30 30 29 30 30 29 30 29 +1585=29 30 29 30 29 30 29 30 30 29 30 30 +1586=29 29 30 29 30 29 29 30 30 30 29 30 +1587=29 30 30 29 29 29 30 29 30 29 30 30 +1588=30 29 30 30 29 29 29 30 29 30 29 30 +1589=30 29 30 30 29 30 29 29 30 29 30 29 +1590=30 29 30 30 30 29 29 30 29 30 29 30 +1591=29 30 29 30 30 29 30 29 30 29 30 29 +1592=30 29 30 29 30 29 30 29 30 30 30 29 +1593=30 29 29 30 29 29 30 29 30 30 30 29 +1594=30 30 29 29 30 29 29 29 30 30 30 30 +1595=29 30 29 30 29 29 30 29 29 30 30 30 +1596=29 30 30 29 30 29 29 30 29 30 29 30 +1597=29 30 30 29 30 29 30 29 30 29 30 29 +1598=30 29 30 29 30 30 29 30 29 30 30 29 +1599=29 30 29 30 29 30 29 30 30 30 29 30 +1600=29 29 30 29 30 29 29 30 30 30 29 30 diff --git a/jdk/src/share/native/java/io/io_util.c b/jdk/src/share/native/java/io/io_util.c index 9a9ca7d292d..5dd822382f0 100644 --- a/jdk/src/share/native/java/io/io_util.c +++ b/jdk/src/share/native/java/io/io_util.c @@ -211,7 +211,11 @@ throwFileNotFoundException(JNIEnv *env, jstring path) n = getLastErrorString(buf, sizeof(buf)); if (n > 0) { +#ifdef WIN32 + why = (*env)->NewStringUTF(env, buf); +#else why = JNU_NewStringPlatform(env, buf); +#endif } x = JNU_NewObjectByName(env, "java/io/FileNotFoundException", diff --git a/jdk/src/share/native/java/net/net_util.c b/jdk/src/share/native/java/net/net_util.c index 5d15f9d9b0e..2f99a342ddd 100644 --- a/jdk/src/share/native/java/net/net_util.c +++ b/jdk/src/share/native/java/net/net_util.c @@ -75,7 +75,7 @@ JNI_OnLoad(JavaVM *vm, void *reserved) static int initialized = 0; -void init(JNIEnv *env) { +static void initInetAddrs(JNIEnv *env) { if (!initialized) { Java_java_net_InetAddress_init(env, 0); Java_java_net_Inet4Address_init(env, 0); @@ -96,42 +96,43 @@ extern jfieldID iac_familyID; void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address) { jobject holder; - init(env); + initInetAddrs(env); holder = (*env)->GetObjectField(env, iaObj, ia_holderID); (*env)->SetIntField(env, holder, iac_addressID, address); } void setInetAddress_family(JNIEnv *env, jobject iaObj, int family) { jobject holder; - init(env); + initInetAddrs(env); holder = (*env)->GetObjectField(env, iaObj, ia_holderID); (*env)->SetIntField(env, holder, iac_familyID, family); } void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject host) { jobject holder; - init(env); + initInetAddrs(env); holder = (*env)->GetObjectField(env, iaObj, ia_holderID); (*env)->SetObjectField(env, holder, iac_hostNameID, host); } int getInetAddress_addr(JNIEnv *env, jobject iaObj) { jobject holder; - init(env); + initInetAddrs(env); holder = (*env)->GetObjectField(env, iaObj, ia_holderID); return (*env)->GetIntField(env, holder, iac_addressID); } int getInetAddress_family(JNIEnv *env, jobject iaObj) { jobject holder; - init(env); + + initInetAddrs(env); holder = (*env)->GetObjectField(env, iaObj, ia_holderID); return (*env)->GetIntField(env, holder, iac_familyID); } jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj) { jobject holder; - init(env); + initInetAddrs(env); holder = (*env)->GetObjectField(env, iaObj, ia_holderID); return (*env)->GetObjectField(env, holder, iac_hostNameID); } @@ -139,7 +140,7 @@ jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj) { JNIEXPORT jobject JNICALL NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) { jobject iaObj; - init(env); + initInetAddrs(env); #ifdef AF_INET6 if (him->sa_family == AF_INET6) { jbyteArray ipaddress; diff --git a/jdk/src/windows/native/java/io/io_util_md.c b/jdk/src/windows/native/java/io/io_util_md.c index 3e9aef352f7..d886aea9f62 100644 --- a/jdk/src/windows/native/java/io/io_util_md.c +++ b/jdk/src/windows/native/java/io/io_util_md.c @@ -29,6 +29,7 @@ #include "io_util.h" #include "io_util_md.h" #include +#include #include #include @@ -40,6 +41,7 @@ #include #include + static DWORD MAX_INPUT_EVENTS = 2000; /* If this returns NULL then an exception is pending */ @@ -569,42 +571,75 @@ handleLseek(FD fd, jlong offset, jint whence) } size_t -getLastErrorString(char *buf, size_t len) +getLastErrorString(char *utf8_jvmErrorMsg, size_t cbErrorMsg) { - DWORD errval; - if (len > 0) { - if ((errval = GetLastError()) != 0) { - // DOS error - size_t n = (size_t)FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - errval, - 0, - buf, - (DWORD)len, - NULL); - if (n > 3) { - // Drop final '.', CR, LF - if (buf[n - 1] == '\n') n--; - if (buf[n - 1] == '\r') n--; - if (buf[n - 1] == '.') n--; - buf[n] = '\0'; + size_t n = 0; + if (cbErrorMsg > 0) { + BOOLEAN noError = FALSE; + WCHAR *utf16_osErrorMsg = (WCHAR *)malloc(cbErrorMsg*sizeof(WCHAR)); + if (utf16_osErrorMsg == NULL) { + // OOM accident + strncpy(utf8_jvmErrorMsg, "Out of memory", cbErrorMsg); + // truncate if too long + utf8_jvmErrorMsg[cbErrorMsg - 1] = '\0'; + n = strlen(utf8_jvmErrorMsg); + } else { + DWORD errval = GetLastError(); + if (errval != 0) { + // WIN32 error + n = (size_t)FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + errval, + 0, + utf16_osErrorMsg, + (DWORD)cbErrorMsg, + NULL); + if (n > 3) { + // Drop final '.', CR, LF + if (utf16_osErrorMsg[n - 1] == L'\n') --n; + if (utf16_osErrorMsg[n - 1] == L'\r') --n; + if (utf16_osErrorMsg[n - 1] == L'.') --n; + utf16_osErrorMsg[n] = L'\0'; + } + } else if (errno != 0) { + // C runtime error that has no corresponding WIN32 error code + const WCHAR *rtError = _wcserror(errno); + if (rtError != NULL) { + wcsncpy(utf16_osErrorMsg, rtError, cbErrorMsg); + // truncate if too long + utf16_osErrorMsg[cbErrorMsg - 1] = L'\0'; + n = wcslen(utf16_osErrorMsg); + } + } else + noError = TRUE; //OS has no error to report + + if (!noError) { + if (n > 0) { + n = WideCharToMultiByte( + CP_UTF8, + 0, + utf16_osErrorMsg, + n, + utf8_jvmErrorMsg, + cbErrorMsg, + NULL, + NULL); + + // no way to die + if (n > 0) + utf8_jvmErrorMsg[min(cbErrorMsg - 1, n)] = '\0'; + } + + if (n <= 0) { + strncpy(utf8_jvmErrorMsg, "Secondary error while OS message extraction", cbErrorMsg); + // truncate if too long + utf8_jvmErrorMsg[cbErrorMsg - 1] = '\0'; + n = strlen(utf8_jvmErrorMsg); + } } - return n; - } - - if (errno != 0) { - // C runtime error that has no corresponding DOS error code - const char *err = strerror(errno); - size_t n = strlen(err); - if (n >= len) - n = len - 1; - - strncpy(buf, err, n); - buf[n] = '\0'; - return n; + free(utf16_osErrorMsg); } } - - return 0; + return n; } diff --git a/jdk/src/windows/native/java/lang/ProcessImpl_md.c b/jdk/src/windows/native/java/lang/ProcessImpl_md.c index 5b45f8f24f2..c372013456c 100644 --- a/jdk/src/windows/native/java/lang/ProcessImpl_md.c +++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c @@ -40,20 +40,70 @@ */ #define PIPE_SIZE (4096+24) +/* We have THREE locales in action: + * 1. Thread default locale - dictates UNICODE-to-8bit conversion + * 2. System locale that defines the message localization + * 3. The file name locale + * Each locale could be an extended locale, that means that text cannot be + * mapped to 8bit sequence without multibyte encoding. + * VM is ready for that, if text is UTF-8. + * Here we make the work right from the beginning. + */ +size_t os_error_message(int errnum, WCHAR* utf16_OSErrorMsg, size_t maxMsgLength) { + size_t n = (size_t)FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + (DWORD)errnum, + 0, + utf16_OSErrorMsg, + (DWORD)maxMsgLength, + NULL); + if (n > 3) { + // Drop final '.', CR, LF + if (utf16_OSErrorMsg[n - 1] == L'\n') --n; + if (utf16_OSErrorMsg[n - 1] == L'\r') --n; + if (utf16_OSErrorMsg[n - 1] == L'.') --n; + utf16_OSErrorMsg[n] = L'\0'; + } + return n; +} + +#define MESSAGE_LENGTH (256 + 100) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x)) + static void -win32Error(JNIEnv *env, const char *functionName) +win32Error(JNIEnv *env, const WCHAR *functionName) { - static const char * const format = "%s error=%d, %s"; - static const char * const fallbackFormat = "%s failed, error=%d"; - char buf[256]; - char errmsg[sizeof(buf) + 100]; - const int errnum = GetLastError(); - const int n = JVM_GetLastErrorString(buf, sizeof(buf)); - if (n > 0) - sprintf(errmsg, format, functionName, errnum, buf); - else - sprintf(errmsg, fallbackFormat, functionName, errnum); - JNU_ThrowIOException(env, errmsg); + WCHAR utf16_OSErrorMsg[MESSAGE_LENGTH - 100]; + WCHAR utf16_javaMessage[MESSAGE_LENGTH]; + /*Good suggestion about 2-bytes-per-symbol in localized error reports*/ + char utf8_javaMessage[MESSAGE_LENGTH*2]; + const int errnum = (int)GetLastError(); + int n = os_error_message(errnum, utf16_OSErrorMsg, ARRAY_SIZE(utf16_OSErrorMsg)); + n = (n > 0) + ? swprintf(utf16_javaMessage, MESSAGE_LENGTH, L"%s error=%d, %s", functionName, errnum, utf16_OSErrorMsg) + : swprintf(utf16_javaMessage, MESSAGE_LENGTH, L"%s failed, error=%d", functionName, errnum); + + if (n > 0) /*terminate '\0' is not a part of conversion procedure*/ + n = WideCharToMultiByte( + CP_UTF8, + 0, + utf16_javaMessage, + n, /*by creation n <= MESSAGE_LENGTH*/ + utf8_javaMessage, + MESSAGE_LENGTH*2, + NULL, + NULL); + + /*no way to die*/ + { + const char *errorMessage = "Secondary error while OS message extraction"; + if (n > 0) { + utf8_javaMessage[min(MESSAGE_LENGTH*2 - 1, n)] = '\0'; + errorMessage = utf8_javaMessage; + } + JNU_ThrowIOException(env, errorMessage); + } } static void @@ -116,7 +166,7 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, handles[0] = (jlong) -1; } else { if (! CreatePipe(&inRead, &inWrite, &sa, PIPE_SIZE)) { - win32Error(env, "CreatePipe"); + win32Error(env, L"CreatePipe"); goto Catch; } si.hStdInput = inRead; @@ -132,7 +182,7 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, handles[1] = (jlong) -1; } else { if (! CreatePipe(&outRead, &outWrite, &sa, PIPE_SIZE)) { - win32Error(env, "CreatePipe"); + win32Error(env, L"CreatePipe"); goto Catch; } si.hStdOutput = outWrite; @@ -151,7 +201,7 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, handles[2] = (jlong) -1; } else { if (! CreatePipe(&errRead, &errWrite, &sa, PIPE_SIZE)) { - win32Error(env, "CreatePipe"); + win32Error(env, L"CreatePipe"); goto Catch; } si.hStdError = errWrite; @@ -174,7 +224,7 @@ Java_java_lang_ProcessImpl_create(JNIEnv *env, jclass ignored, &si, /* (in) startup information */ &pi); /* (out) process information */ if (!ret) { - win32Error(env, "CreateProcess"); + win32Error(env, L"CreateProcess"); goto Catch; } @@ -210,7 +260,7 @@ Java_java_lang_ProcessImpl_getExitCodeProcess(JNIEnv *env, jclass ignored, jlong { DWORD exit_code; if (GetExitCodeProcess((HANDLE) handle, &exit_code) == 0) - win32Error(env, "GetExitCodeProcess"); + win32Error(env, L"GetExitCodeProcess"); return exit_code; } @@ -231,7 +281,7 @@ Java_java_lang_ProcessImpl_waitForInterruptibly(JNIEnv *env, jclass ignored, jlo FALSE, /* Wait for ANY event */ INFINITE) /* Wait forever */ == WAIT_FAILED) - win32Error(env, "WaitForMultipleObjects"); + win32Error(env, L"WaitForMultipleObjects"); } JNIEXPORT void JNICALL @@ -250,7 +300,7 @@ Java_java_lang_ProcessImpl_waitForTimeoutInterruptibly(JNIEnv *env, dwTimeout); /* Wait for dwTimeout */ if (result == WAIT_FAILED) - win32Error(env, "WaitForMultipleObjects"); + win32Error(env, L"WaitForMultipleObjects"); } JNIEXPORT void JNICALL @@ -263,7 +313,7 @@ JNIEXPORT jboolean JNICALL Java_java_lang_ProcessImpl_isProcessAlive(JNIEnv *env, jclass ignored, jlong handle) { DWORD dwExitStatus; - GetExitCodeProcess(handle, &dwExitStatus); + GetExitCodeProcess((HANDLE) handle, &dwExitStatus); return dwExitStatus == STILL_ACTIVE; } diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 8c98dbda37a..1574a648c9c 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -137,6 +137,11 @@ java/lang/Class/asSubclass/BasicUnit.java generic-all # 8015780 java/lang/reflect/Method/GenericStringTest.java generic-all +# 8019845 due to memleak not related to the tested fix +java/lang/instrument/RedefineBigClass.sh linux-x64 +java/lang/instrument/RetransformBigClass.sh linux-x64 + + ############################################################################ # jdk_management diff --git a/jdk/test/java/lang/instrument/RedefineBigClass.sh b/jdk/test/java/lang/instrument/RedefineBigClass.sh index 6b71271e7b9..145be056eb2 100644 --- a/jdk/test/java/lang/instrument/RedefineBigClass.sh +++ b/jdk/test/java/lang/instrument/RedefineBigClass.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved. # 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 7121600 +# @bug 7121600 8016838 # @summary Redefine a big class. # @author Daniel D. Daugherty # diff --git a/jdk/test/java/lang/instrument/RedefineBigClassApp.java b/jdk/test/java/lang/instrument/RedefineBigClassApp.java index 6f2233aebde..81416303fc0 100644 --- a/jdk/test/java/lang/instrument/RedefineBigClassApp.java +++ b/jdk/test/java/lang/instrument/RedefineBigClassApp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved. * 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,12 +21,21 @@ * questions. */ +import java.io.*; + public class RedefineBigClassApp { + /** + * Memory leak is assumed, if application consumes more than specified amount of memory during its execution. + * The number is given in Kb. + */ + private static final long MEM_LEAK_THRESHOLD = 32 * 1024; // 32Mb + public static void main(String[] args) throws Exception { System.out.println("Creating instance of " + RedefineBigClassAgent.clz); RedefineBigClassAgent.clz.newInstance(); + long vMemBefore = getVMemSize(); int count = 0; while (!RedefineBigClassAgent.doneRedefining) { System.out.println("App loop count: " + ++count); @@ -37,6 +46,39 @@ public class RedefineBigClassApp { } System.out.println("App looped " + count + " times."); + long vMemAfter = getVMemSize(); + if (vMemBefore == 0 || vMemAfter == 0) { + System.err.println("WARNING: Cannot perform memory leak detection on this OS"); + } else { + long vMemDelta = vMemAfter - vMemBefore; + if (vMemDelta > MEM_LEAK_THRESHOLD) { + System.err.println("FAIL: Virtual memory usage increased by " + vMemDelta + "Kb " + + "(greater than " + MEM_LEAK_THRESHOLD + "Kb)"); + System.exit(1); + } + System.err.println("PASS: Virtual memory usage increased by " + vMemDelta + "Kb " + + "(not greater than " + MEM_LEAK_THRESHOLD + "Kb)"); + } System.exit(0); } + + /** + * Return size of virtual memory allocated to the process in Kb. + * Linux specific. On other platforms and in case of any errors return 0. + */ + private static long getVMemSize() { + + // Refer to the Linux proc(5) man page for details about /proc/self/stat file + // + // In short, this file contains status information about the current process + // written in one line. The fields are separated with spaces. + // The 23rd field is defined as 'vsize %lu Virtual memory size in bytes' + + try (FileReader fileReader = new FileReader("/proc/self/stat"); + BufferedReader bufferedReader = new BufferedReader(fileReader)) { + String line = bufferedReader.readLine(); + return Long.parseLong(line.split(" ")[22]) / 1024; + } catch (Exception ex) {} + return 0; + } } diff --git a/jdk/test/java/lang/instrument/RetransformBigClass.sh b/jdk/test/java/lang/instrument/RetransformBigClass.sh index acaa5ae0d0c..dddde89c785 100644 --- a/jdk/test/java/lang/instrument/RetransformBigClass.sh +++ b/jdk/test/java/lang/instrument/RetransformBigClass.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved. # 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 7122253 +# @bug 7122253 8016838 # @summary Retransform a big class. # @author Daniel D. Daugherty # diff --git a/jdk/test/java/lang/instrument/RetransformBigClassApp.java b/jdk/test/java/lang/instrument/RetransformBigClassApp.java index 37a40e97bd0..3f777bbb20e 100644 --- a/jdk/test/java/lang/instrument/RetransformBigClassApp.java +++ b/jdk/test/java/lang/instrument/RetransformBigClassApp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved. * 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,12 +21,21 @@ * questions. */ +import java.io.*; + public class RetransformBigClassApp { + /** + * Memory leak is assumed, if application consumes more than specified amount of memory during its execution. + * The number is given in Kb. + */ + private static final long MEM_LEAK_THRESHOLD = 32 * 1024; // 32Mb + public static void main(String[] args) throws Exception { System.out.println("Creating instance of " + RetransformBigClassAgent.clz); RetransformBigClassAgent.clz.newInstance(); + long vMemBefore = getVMemSize(); int count = 0; while (!RetransformBigClassAgent.doneRetransforming) { System.out.println("App loop count: " + ++count); @@ -37,6 +46,39 @@ public class RetransformBigClassApp { } System.out.println("App looped " + count + " times."); + long vMemAfter = getVMemSize(); + if (vMemBefore == 0 || vMemAfter == 0) { + System.err.println("WARNING: Cannot perform memory leak detection on this OS"); + } else { + long vMemDelta = vMemAfter - vMemBefore; + if (vMemDelta > MEM_LEAK_THRESHOLD) { + System.err.println("FAIL: Virtual memory usage increased by " + vMemDelta + "Kb " + + "(greater than " + MEM_LEAK_THRESHOLD + "Kb)"); + System.exit(1); + } + System.err.println("PASS: Virtual memory usage increased by " + vMemDelta + "Kb " + + "(not greater than " + MEM_LEAK_THRESHOLD + "Kb)"); + } System.exit(0); } + + /** + * Return size of virtual memory allocated to the process in Kb. + * Linux specific. On other platforms and in case of any errors return 0. + */ + private static long getVMemSize() { + + // Refer to the Linux proc(5) man page for details about /proc/self/stat file + // + // In short, this file contains status information about the current process + // written in one line. The fields are separated with spaces. + // The 23rd field is defined as 'vsize %lu Virtual memory size in bytes' + + try (FileReader fileReader = new FileReader("/proc/self/stat"); + BufferedReader bufferedReader = new BufferedReader(fileReader)) { + String line = bufferedReader.readLine(); + return Long.parseLong(line.split(" ")[22]) / 1024; + } catch (Exception ex) {} + return 0; + } } diff --git a/jdk/test/java/time/tck/java/time/MockSimplePeriod.java b/jdk/test/java/time/tck/java/time/MockSimplePeriod.java index 7b008341592..1548e2e98f9 100644 --- a/jdk/test/java/time/tck/java/time/MockSimplePeriod.java +++ b/jdk/test/java/time/tck/java/time/MockSimplePeriod.java @@ -176,7 +176,7 @@ public final class MockSimplePeriod @Override public String toString() { - return amount + " " + unit.getName(); + return amount + " " + unit; } } diff --git a/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java b/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java index 13cc7b4093d..ef9f12acc47 100644 --- a/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java +++ b/jdk/test/java/time/tck/java/time/TCKClock_Fixed.java @@ -91,6 +91,7 @@ public class TCKClock_Fixed extends AbstractTCKTest { Clock test = Clock.fixed(INSTANT, PARIS); assertEquals(test.instant(), INSTANT); assertEquals(test.getZone(), PARIS); + assertEquals(test.instant().getEpochSecond()*1000, test.millis()); } @Test(expectedExceptions = NullPointerException.class) diff --git a/jdk/test/java/time/tck/java/time/TCKDayOfWeek.java b/jdk/test/java/time/tck/java/time/TCKDayOfWeek.java index 671d9ec53e9..3bf782ba954 100644 --- a/jdk/test/java/time/tck/java/time/TCKDayOfWeek.java +++ b/jdk/test/java/time/tck/java/time/TCKDayOfWeek.java @@ -158,6 +158,44 @@ public class TCKDayOfWeek extends AbstractDateTimeTest { DayOfWeek.from((TemporalAccessor) null); } + //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(DayOfWeek.THURSDAY.isSupported((TemporalField) null), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.NANO_OF_SECOND), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.NANO_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MICRO_OF_SECOND), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MICRO_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MILLI_OF_SECOND), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MILLI_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.SECOND_OF_MINUTE), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.SECOND_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MINUTE_OF_HOUR), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MINUTE_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.HOUR_OF_AMPM), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.HOUR_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.AMPM_OF_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.DAY_OF_WEEK), true); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.DAY_OF_MONTH), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.MONTH_OF_YEAR), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.PROLEPTIC_MONTH), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.YEAR), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.YEAR_OF_ERA), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.ERA), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(DayOfWeek.THURSDAY.isSupported(ChronoField.OFFSET_SECONDS), false); + } + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKInstant.java b/jdk/test/java/time/tck/java/time/TCKInstant.java index bdf5fcccb70..05d7b83fcf1 100644 --- a/jdk/test/java/time/tck/java/time/TCKInstant.java +++ b/jdk/test/java/time/tck/java/time/TCKInstant.java @@ -569,10 +569,6 @@ public class TCKInstant extends AbstractDateTimeTest { // truncated(TemporalUnit) //----------------------------------------------------------------------- TemporalUnit NINETY_MINS = new TemporalUnit() { - @Override - public String getName() { - return "NinetyMins"; - } @Override public Duration getDuration() { return Duration.ofMinutes(90); @@ -582,6 +578,14 @@ public class TCKInstant extends AbstractDateTimeTest { return false; } @Override + public boolean isDateBased() { + return false; + } + @Override + public boolean isTimeBased() { + return true; + } + @Override public boolean isSupportedBy(Temporal temporal) { return false; } @@ -593,13 +597,13 @@ public class TCKInstant extends AbstractDateTimeTest { public long between(Temporal temporal1, Temporal temporal2) { throw new UnsupportedOperationException(); } + @Override + public String toString() { + return "NinetyMins"; + } }; TemporalUnit NINETY_FIVE_MINS = new TemporalUnit() { - @Override - public String getName() { - return "NinetyFiveMins"; - } @Override public Duration getDuration() { return Duration.ofMinutes(95); @@ -609,6 +613,14 @@ public class TCKInstant extends AbstractDateTimeTest { return false; } @Override + public boolean isDateBased() { + return false; + } + @Override + public boolean isTimeBased() { + return false; + } + @Override public boolean isSupportedBy(Temporal temporal) { return false; } @@ -620,6 +632,10 @@ public class TCKInstant extends AbstractDateTimeTest { public long between(Temporal temporal1, Temporal temporal2) { throw new UnsupportedOperationException(); } + @Override + public String toString() { + return "NinetyFiveMins"; + } }; @DataProvider(name="truncatedToValid") @@ -1709,7 +1725,7 @@ public class TCKInstant extends AbstractDateTimeTest { } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -1805,7 +1821,7 @@ public class TCKInstant extends AbstractDateTimeTest { public void test_periodUntil_TemporalUnit(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { Instant i1 = Instant.ofEpochSecond(seconds1, nanos1); Instant i2 = Instant.ofEpochSecond(seconds2, nanos2); - long amount = i1.periodUntil(i2, unit); + long amount = i1.until(i2, unit); assertEquals(amount, expected); } @@ -1813,23 +1829,23 @@ public class TCKInstant extends AbstractDateTimeTest { public void test_periodUntil_TemporalUnit_negated(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) { Instant i1 = Instant.ofEpochSecond(seconds1, nanos1); Instant i2 = Instant.ofEpochSecond(seconds2, nanos2); - long amount = i2.periodUntil(i1, unit); + long amount = i2.until(i1, unit); assertEquals(amount, -expected); } @Test(expectedExceptions = UnsupportedTemporalTypeException.class) public void test_periodUntil_TemporalUnit_unsupportedUnit() { - TEST_12345_123456789.periodUntil(TEST_12345_123456789, MONTHS); + TEST_12345_123456789.until(TEST_12345_123456789, MONTHS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullEnd() { - TEST_12345_123456789.periodUntil(null, HOURS); + TEST_12345_123456789.until(null, HOURS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullUnit() { - TEST_12345_123456789.periodUntil(TEST_12345_123456789, null); + TEST_12345_123456789.until(TEST_12345_123456789, null); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKLocalDate.java b/jdk/test/java/time/tck/java/time/TCKLocalDate.java index 926aca4a761..597dd4f6574 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalDate.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalDate.java @@ -619,6 +619,68 @@ public class TCKLocalDate extends AbstractDateTimeTest { LocalDate.parse("ANY", null); } + //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_2007_07_15.isSupported((TemporalField) null), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.NANO_OF_SECOND), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.NANO_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MICRO_OF_SECOND), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MICRO_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MILLI_OF_SECOND), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MILLI_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.SECOND_OF_MINUTE), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.SECOND_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MINUTE_OF_HOUR), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MINUTE_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.HOUR_OF_AMPM), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.HOUR_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.AMPM_OF_DAY), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.DAY_OF_WEEK), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.DAY_OF_MONTH), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.DAY_OF_YEAR), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.EPOCH_DAY), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.PROLEPTIC_MONTH), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.YEAR), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.YEAR_OF_ERA), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.ERA), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoField.OFFSET_SECONDS), false); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_2007_07_15.isSupported((TemporalUnit) null), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.NANOS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MICROS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MILLIS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.SECONDS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MINUTES), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.HOURS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.HALF_DAYS), false); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.DAYS), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.WEEKS), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MONTHS), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.YEARS), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.DECADES), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.CENTURIES), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MILLENNIA), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.ERAS), true); + assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.FOREVER), false); + } + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @@ -1635,7 +1697,7 @@ public class TCKLocalDate extends AbstractDateTimeTest { } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -1684,35 +1746,35 @@ public class TCKLocalDate extends AbstractDateTimeTest { @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { - long amount = date1.periodUntil(date2, unit); + long amount = date1.until(date2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit_negated(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) { - long amount = date2.periodUntil(date1, unit); + long amount = date2.until(date1, unit); assertEquals(amount, -expected); } @Test(expectedExceptions = UnsupportedTemporalTypeException.class) public void test_periodUntil_TemporalUnit_unsupportedUnit() { - TEST_2007_07_15.periodUntil(TEST_2007_07_15, HOURS); + TEST_2007_07_15.until(TEST_2007_07_15, HOURS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullEnd() { - TEST_2007_07_15.periodUntil(null, DAYS); + TEST_2007_07_15.until(null, DAYS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullUnit() { - TEST_2007_07_15.periodUntil(TEST_2007_07_15, null); + TEST_2007_07_15.until(TEST_2007_07_15, null); } //----------------------------------------------------------------------- - // periodUntil(ChronoLocalDate) + // until(ChronoLocalDate) //----------------------------------------------------------------------- - @DataProvider(name="periodUntil") + @DataProvider(name="until") Object[][] data_periodUntil() { return new Object[][] { {2010, 1, 1, 2010, 1, 1, 0, 0, 0}, @@ -1799,11 +1861,11 @@ public class TCKLocalDate extends AbstractDateTimeTest { }; } - @Test(dataProvider="periodUntil") + @Test(dataProvider="until") public void test_periodUntil_LocalDate(int y1, int m1, int d1, int y2, int m2, int d2, int ye, int me, int de) { LocalDate start = LocalDate.of(y1, m1, d1); LocalDate end = LocalDate.of(y2, m2, d2); - Period test = start.periodUntil(end); + Period test = start.until(end); assertEquals(test.getYears(), ye); assertEquals(test.getMonths(), me); assertEquals(test.getDays(), de); @@ -1812,12 +1874,12 @@ public class TCKLocalDate extends AbstractDateTimeTest { @Test public void test_periodUntil_LocalDate_max() { int years = Math.toIntExact((long) Year.MAX_VALUE - (long) Year.MIN_VALUE); - assertEquals(LocalDate.MIN.periodUntil(LocalDate.MAX), Period.of(years, 11, 30)); + assertEquals(LocalDate.MIN.until(LocalDate.MAX), Period.of(years, 11, 30)); } @Test(expectedExceptions=NullPointerException.class) public void test_periodUntil_LocalDate_null() { - TEST_2007_07_15.periodUntil(null); + TEST_2007_07_15.until(null); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java b/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java index f7d5c9ed1f4..f55bdb4a961 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalDateTime.java @@ -937,6 +937,68 @@ public class TCKLocalDateTime extends AbstractDateTimeTest { LocalDateTime.parse("ANY", null); } + //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported((TemporalField) null), false); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.NANO_OF_SECOND), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.NANO_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_SECOND), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_SECOND), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_MINUTE), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_HOUR), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_AMPM), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.AMPM_OF_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.DAY_OF_WEEK), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.DAY_OF_MONTH), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.DAY_OF_YEAR), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.EPOCH_DAY), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.PROLEPTIC_MONTH), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.YEAR), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.YEAR_OF_ERA), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ERA), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.OFFSET_SECONDS), false); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported((TemporalUnit) null), false); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.NANOS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MICROS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MILLIS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.SECONDS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MINUTES), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.HOURS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.HALF_DAYS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.DAYS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.WEEKS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MONTHS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.YEARS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.DECADES), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.CENTURIES), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MILLENNIA), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.ERAS), true); + assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.FOREVER), false); + } + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @@ -2717,7 +2779,7 @@ public class TCKLocalDateTime extends AbstractDateTimeTest { } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -2859,24 +2921,24 @@ public class TCKLocalDateTime extends AbstractDateTimeTest { @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { - long amount = dt1.periodUntil(dt2, unit); + long amount = dt1.until(dt2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit_negated(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) { - long amount = dt2.periodUntil(dt1, unit); + long amount = dt2.until(dt1, unit); assertEquals(amount, -expected); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullEnd() { - TEST_2007_07_15_12_30_40_987654321.periodUntil(null, HOURS); + TEST_2007_07_15_12_30_40_987654321.until(null, HOURS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullUnit() { - TEST_2007_07_15_12_30_40_987654321.periodUntil(TEST_2007_07_15_12_30_40_987654321, null); + TEST_2007_07_15_12_30_40_987654321.until(TEST_2007_07_15_12_30_40_987654321, null); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKLocalTime.java b/jdk/test/java/time/tck/java/time/TCKLocalTime.java index 28c59491501..e0ef94cdadc 100644 --- a/jdk/test/java/time/tck/java/time/TCKLocalTime.java +++ b/jdk/test/java/time/tck/java/time/TCKLocalTime.java @@ -619,6 +619,68 @@ public class TCKLocalTime extends AbstractDateTimeTest { LocalTime.parse("ANY", null); } + //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_12_30_40_987654321.isSupported((TemporalField) null), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.NANO_OF_SECOND), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.NANO_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_SECOND), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_SECOND), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_MINUTE), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_HOUR), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_AMPM), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.AMPM_OF_DAY), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.DAY_OF_WEEK), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.DAY_OF_MONTH), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MONTH_OF_YEAR), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.PROLEPTIC_MONTH), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.YEAR), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.YEAR_OF_ERA), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ERA), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.OFFSET_SECONDS), false); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_12_30_40_987654321.isSupported((TemporalUnit) null), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.NANOS), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MICROS), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MILLIS), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.SECONDS), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MINUTES), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.HOURS), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.HALF_DAYS), true); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.DAYS), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.WEEKS), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MONTHS), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.YEARS), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.DECADES), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.CENTURIES), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MILLENNIA), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.ERAS), false); + assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.FOREVER), false); + } + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @@ -952,10 +1014,6 @@ public class TCKLocalTime extends AbstractDateTimeTest { // truncated(TemporalUnit) //----------------------------------------------------------------------- TemporalUnit NINETY_MINS = new TemporalUnit() { - @Override - public String getName() { - return "NinetyMins"; - } @Override public Duration getDuration() { return Duration.ofMinutes(90); @@ -965,6 +1023,14 @@ public class TCKLocalTime extends AbstractDateTimeTest { return false; } @Override + public boolean isDateBased() { + return false; + } + @Override + public boolean isTimeBased() { + return true; + } + @Override public boolean isSupportedBy(Temporal temporal) { return false; } @@ -976,13 +1042,13 @@ public class TCKLocalTime extends AbstractDateTimeTest { public long between(Temporal temporal1, Temporal temporal2) { throw new UnsupportedOperationException(); } + @Override + public String toString() { + return "NinetyMins"; + } }; TemporalUnit NINETY_FIVE_MINS = new TemporalUnit() { - @Override - public String getName() { - return "NinetyFiveMins"; - } @Override public Duration getDuration() { return Duration.ofMinutes(95); @@ -992,6 +1058,14 @@ public class TCKLocalTime extends AbstractDateTimeTest { return false; } @Override + public boolean isDateBased() { + return false; + } + @Override + public boolean isTimeBased() { + return false; + } + @Override public boolean isSupportedBy(Temporal temporal) { return false; } @@ -1003,6 +1077,10 @@ public class TCKLocalTime extends AbstractDateTimeTest { public long between(Temporal temporal1, Temporal temporal2) { throw new UnsupportedOperationException(); } + @Override + public String toString() { + return "NinetyFiveMins"; + } }; @DataProvider(name="truncatedToValid") @@ -1922,7 +2000,7 @@ public class TCKLocalTime extends AbstractDateTimeTest { } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -1962,29 +2040,29 @@ public class TCKLocalTime extends AbstractDateTimeTest { @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { - long amount = time1.periodUntil(time2, unit); + long amount = time1.until(time2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit_negated(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) { - long amount = time2.periodUntil(time1, unit); + long amount = time2.until(time1, unit); assertEquals(amount, -expected); } @Test(expectedExceptions = UnsupportedTemporalTypeException.class) public void test_periodUntil_TemporalUnit_unsupportedUnit() { - TEST_12_30_40_987654321.periodUntil(TEST_12_30_40_987654321, DAYS); + TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, DAYS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullEnd() { - TEST_12_30_40_987654321.periodUntil(null, HOURS); + TEST_12_30_40_987654321.until(null, HOURS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullUnit() { - TEST_12_30_40_987654321.periodUntil(TEST_12_30_40_987654321, null); + TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, null); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKMonth.java b/jdk/test/java/time/tck/java/time/TCKMonth.java index 77e9eef7a96..3bff8c9beb6 100644 --- a/jdk/test/java/time/tck/java/time/TCKMonth.java +++ b/jdk/test/java/time/tck/java/time/TCKMonth.java @@ -150,6 +150,44 @@ public class TCKMonth extends AbstractDateTimeTest { Month.from((TemporalAccessor) null); } + //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(Month.AUGUST.isSupported((TemporalField) null), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.NANO_OF_SECOND), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.NANO_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MICRO_OF_SECOND), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MICRO_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MILLI_OF_SECOND), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MILLI_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.SECOND_OF_MINUTE), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.SECOND_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MINUTE_OF_HOUR), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MINUTE_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.HOUR_OF_AMPM), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.HOUR_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.AMPM_OF_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.DAY_OF_WEEK), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.DAY_OF_MONTH), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(Month.AUGUST.isSupported(ChronoField.PROLEPTIC_MONTH), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.YEAR), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.YEAR_OF_ERA), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.ERA), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(Month.AUGUST.isSupported(ChronoField.OFFSET_SECONDS), false); + } + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKMonthDay.java b/jdk/test/java/time/tck/java/time/TCKMonthDay.java index 0bcbdef8195..f2a2b93f473 100644 --- a/jdk/test/java/time/tck/java/time/TCKMonthDay.java +++ b/jdk/test/java/time/tck/java/time/TCKMonthDay.java @@ -387,6 +387,44 @@ public class TCKMonthDay extends AbstractDateTimeTest { MonthDay.parse("ANY", null); } + //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_07_15.isSupported((TemporalField) null), false); + assertEquals(TEST_07_15.isSupported(ChronoField.NANO_OF_SECOND), false); + assertEquals(TEST_07_15.isSupported(ChronoField.NANO_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MICRO_OF_SECOND), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MICRO_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MILLI_OF_SECOND), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MILLI_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.SECOND_OF_MINUTE), false); + assertEquals(TEST_07_15.isSupported(ChronoField.SECOND_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MINUTE_OF_HOUR), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MINUTE_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.HOUR_OF_AMPM), false); + assertEquals(TEST_07_15.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false); + assertEquals(TEST_07_15.isSupported(ChronoField.HOUR_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.AMPM_OF_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.DAY_OF_WEEK), false); + assertEquals(TEST_07_15.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(TEST_07_15.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(TEST_07_15.isSupported(ChronoField.DAY_OF_MONTH), true); + assertEquals(TEST_07_15.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(TEST_07_15.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(TEST_07_15.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(TEST_07_15.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(TEST_07_15.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(TEST_07_15.isSupported(ChronoField.PROLEPTIC_MONTH), false); + assertEquals(TEST_07_15.isSupported(ChronoField.YEAR), false); + assertEquals(TEST_07_15.isSupported(ChronoField.YEAR_OF_ERA), false); + assertEquals(TEST_07_15.isSupported(ChronoField.ERA), false); + assertEquals(TEST_07_15.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_07_15.isSupported(ChronoField.OFFSET_SECONDS), false); + } + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java index a6bb7c30418..7cfc2a61dec 100644 --- a/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java @@ -126,6 +126,7 @@ import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; +import java.time.temporal.TemporalUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -554,6 +555,68 @@ public class TCKOffsetDateTime extends AbstractDateTimeTest { assertEquals(a.toString(), localDateTime.toString() + offset.toString()); } + //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported((TemporalField) null), false); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.NANO_OF_SECOND), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.NANO_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MICRO_OF_SECOND), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MICRO_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MILLI_OF_SECOND), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MILLI_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.SECOND_OF_MINUTE), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.SECOND_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MINUTE_OF_HOUR), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MINUTE_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.HOUR_OF_AMPM), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.HOUR_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.AMPM_OF_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.DAY_OF_WEEK), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.DAY_OF_MONTH), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.DAY_OF_YEAR), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.EPOCH_DAY), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.PROLEPTIC_MONTH), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.YEAR), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.YEAR_OF_ERA), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.ERA), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.INSTANT_SECONDS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoField.OFFSET_SECONDS), true); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported((TemporalUnit) null), false); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.NANOS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.MICROS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.MILLIS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.SECONDS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.MINUTES), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.HOURS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.HALF_DAYS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.DAYS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.WEEKS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.MONTHS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.YEARS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.DECADES), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.CENTURIES), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.MILLENNIA), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.ERAS), true); + assertEquals(TEST_2008_6_30_11_30_59_000000500.isSupported(ChronoUnit.FOREVER), false); + } + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @@ -1203,6 +1266,7 @@ public class TCKOffsetDateTime extends AbstractDateTimeTest { assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); } @Test @@ -1214,6 +1278,7 @@ public class TCKOffsetDateTime extends AbstractDateTimeTest { assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); } @Test @@ -1225,6 +1290,7 @@ public class TCKOffsetDateTime extends AbstractDateTimeTest { assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); } @Test @@ -1236,6 +1302,7 @@ public class TCKOffsetDateTime extends AbstractDateTimeTest { assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); } @Test @@ -1247,6 +1314,7 @@ public class TCKOffsetDateTime extends AbstractDateTimeTest { assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); } @Test @@ -1258,6 +1326,7 @@ public class TCKOffsetDateTime extends AbstractDateTimeTest { assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); } @Test @@ -1269,6 +1338,14 @@ public class TCKOffsetDateTime extends AbstractDateTimeTest { assertEquals(a.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(a.toInstant().compareTo(b.toInstant()) < 0, true); + assertEquals(OffsetDateTime.timeLineOrder().compare(a, b) < 0, true); + } + + @Test + public void test_compareTo_bothInstantComparator() { + OffsetDateTime a = OffsetDateTime.of(2008, 6, 30, 11, 20, 40, 4, OFFSET_PTWO); + OffsetDateTime b = OffsetDateTime.of(2008, 6, 30, 10, 20, 40, 5, OFFSET_PONE); + assertEquals(a.compareTo(b), OffsetDateTime.timeLineOrder().compare(a,b), "for nano != nano, compareTo and timeLineOrder() should be the same"); } @Test diff --git a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java index 7b97380e4de..b3d7e5b26a9 100644 --- a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java +++ b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java @@ -542,6 +542,68 @@ public class TCKOffsetTime extends AbstractDateTimeTest { assertEquals(a.getNano(), localTime.getNano()); } + //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_11_30_59_500_PONE.isSupported((TemporalField) null), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.NANO_OF_SECOND), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.NANO_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MICRO_OF_SECOND), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MICRO_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MILLI_OF_SECOND), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MILLI_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.SECOND_OF_MINUTE), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.SECOND_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MINUTE_OF_HOUR), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MINUTE_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.HOUR_OF_AMPM), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.HOUR_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.AMPM_OF_DAY), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.DAY_OF_WEEK), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.DAY_OF_MONTH), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.MONTH_OF_YEAR), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.PROLEPTIC_MONTH), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.YEAR), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.YEAR_OF_ERA), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.ERA), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoField.OFFSET_SECONDS), true); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_11_30_59_500_PONE.isSupported((TemporalUnit) null), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.NANOS), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.MICROS), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.MILLIS), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.SECONDS), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.MINUTES), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.HOURS), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.HALF_DAYS), true); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.DAYS), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.WEEKS), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.MONTHS), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.YEARS), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.DECADES), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.CENTURIES), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.MILLENNIA), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.ERAS), false); + assertEquals(TEST_11_30_59_500_PONE.isSupported(ChronoUnit.FOREVER), false); + } + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @@ -1038,7 +1100,7 @@ public class TCKOffsetTime extends AbstractDateTimeTest { } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -1063,13 +1125,13 @@ public class TCKOffsetTime extends AbstractDateTimeTest { @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { - long amount = offsetTime1.periodUntil(offsetTime2, unit); + long amount = offsetTime1.until(offsetTime2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit_negated(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) { - long amount = offsetTime2.periodUntil(offsetTime1, unit); + long amount = offsetTime2.until(offsetTime1, unit); assertEquals(amount, -expected); } @@ -1077,14 +1139,14 @@ public class TCKOffsetTime extends AbstractDateTimeTest { public void test_periodUntil_InvalidType() { OffsetTime offsetTime = OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)); OffsetDateTime offsetDateTime = offsetTime.atDate(LocalDate.of(1980, 2, 10)); - offsetTime.periodUntil(offsetDateTime, SECONDS); + offsetTime.until(offsetDateTime, SECONDS); } @Test(expectedExceptions=DateTimeException.class) public void test_periodUntil_InvalidTemporalUnit() { OffsetTime offsetTime1 = OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)); OffsetTime offsetTime2 = OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)); - offsetTime1.periodUntil(offsetTime2, MONTHS); + offsetTime1.until(offsetTime2, MONTHS); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKPeriod.java b/jdk/test/java/time/tck/java/time/TCKPeriod.java index 95907b237a7..7a06b95e6ef 100644 --- a/jdk/test/java/time/tck/java/time/TCKPeriod.java +++ b/jdk/test/java/time/tck/java/time/TCKPeriod.java @@ -120,11 +120,24 @@ public class TCKPeriod extends AbstractTCKTest { assertPeriod(Period.ofMonths(Integer.MIN_VALUE), 0, Integer.MIN_VALUE, 0); } + //----------------------------------------------------------------------- + // ofWeeks(int) + //----------------------------------------------------------------------- + @Test + public void factory_ofWeeks_int() { + assertPeriod(Period.ofWeeks(0), 0, 0, 0); + assertPeriod(Period.ofWeeks(1), 0, 0, 7); + assertPeriod(Period.ofWeeks(234), 0, 0, 234 * 7); + assertPeriod(Period.ofWeeks(-100), 0, 0, -100 * 7); + assertPeriod(Period.ofWeeks(Integer.MAX_VALUE / 7), 0, 0, (Integer.MAX_VALUE / 7) * 7); + assertPeriod(Period.ofWeeks(Integer.MIN_VALUE / 7), 0, 0, (Integer.MIN_VALUE / 7) * 7); + } + //----------------------------------------------------------------------- // ofDays(int) //----------------------------------------------------------------------- @Test - public void factory_ofDay_int() { + public void factory_ofDays_int() { assertPeriod(Period.ofDays(0), 0, 0, 0); assertPeriod(Period.ofDays(1), 0, 0, 1); assertPeriod(Period.ofDays(234), 0, 0, 234); @@ -251,6 +264,18 @@ public class TCKPeriod extends AbstractTCKTest { {"P" + Integer.MAX_VALUE + "M", Period.ofMonths(Integer.MAX_VALUE)}, {"P" + Integer.MIN_VALUE + "M", Period.ofMonths(Integer.MIN_VALUE)}, + {"P1W", Period.ofDays(1 * 7)}, + {"P12W", Period.ofDays(12 * 7)}, + {"P7654321W", Period.ofDays(7654321 * 7)}, + {"P+1W", Period.ofDays(1 * 7)}, + {"P+12W", Period.ofDays(12 * 7)}, + {"P+7654321W", Period.ofDays(7654321 * 7)}, + {"P+0W", Period.ofDays(0)}, + {"P0W", Period.ofDays(0)}, + {"P-0W", Period.ofDays(0)}, + {"P-25W", Period.ofDays(-25 * 7)}, + {"P-7654321W", Period.ofDays(-7654321 * 7)}, + {"P1D", Period.ofDays(1)}, {"P12D", Period.ofDays(12)}, {"P987654321D", Period.ofDays(987654321)}, @@ -274,6 +299,10 @@ public class TCKPeriod extends AbstractTCKTest { {"P2Y-3M25D", Period.of(2, -3, 25)}, {"P2Y3M-25D", Period.of(2, 3, -25)}, {"P-2Y-3M-25D", Period.of(-2, -3, -25)}, + + {"P0Y0M0W0D", Period.of(0, 0, 0)}, + {"P2Y3M4W25D", Period.of(2, 3, 4 * 7 + 25)}, + {"P-2Y-3M-4W-25D", Period.of(-2, -3, -4 * 7 - 25)}, }; } @@ -334,6 +363,13 @@ public class TCKPeriod extends AbstractTCKTest { {"P1Y2Y"}, {"PT1M+3S"}, + {"P1M2Y"}, + {"P1W2Y"}, + {"P1D2Y"}, + {"P1W2M"}, + {"P1D2M"}, + {"P1D2W"}, + {"PT1S1"}, {"PT1S."}, {"PT1SA"}, diff --git a/jdk/test/java/time/tck/java/time/TCKYear.java b/jdk/test/java/time/tck/java/time/TCKYear.java index ac25f0b4fb3..53f0db0b56e 100644 --- a/jdk/test/java/time/tck/java/time/TCKYear.java +++ b/jdk/test/java/time/tck/java/time/TCKYear.java @@ -347,6 +347,68 @@ public class TCKYear extends AbstractDateTimeTest { Year.parse("ANY", null); } + //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_2008.isSupported((TemporalField) null), false); + assertEquals(TEST_2008.isSupported(ChronoField.NANO_OF_SECOND), false); + assertEquals(TEST_2008.isSupported(ChronoField.NANO_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.MICRO_OF_SECOND), false); + assertEquals(TEST_2008.isSupported(ChronoField.MICRO_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.MILLI_OF_SECOND), false); + assertEquals(TEST_2008.isSupported(ChronoField.MILLI_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.SECOND_OF_MINUTE), false); + assertEquals(TEST_2008.isSupported(ChronoField.SECOND_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.MINUTE_OF_HOUR), false); + assertEquals(TEST_2008.isSupported(ChronoField.MINUTE_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.HOUR_OF_AMPM), false); + assertEquals(TEST_2008.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false); + assertEquals(TEST_2008.isSupported(ChronoField.HOUR_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.AMPM_OF_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.DAY_OF_WEEK), false); + assertEquals(TEST_2008.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(TEST_2008.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(TEST_2008.isSupported(ChronoField.DAY_OF_MONTH), false); + assertEquals(TEST_2008.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(TEST_2008.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(TEST_2008.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(TEST_2008.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(TEST_2008.isSupported(ChronoField.MONTH_OF_YEAR), false); + assertEquals(TEST_2008.isSupported(ChronoField.PROLEPTIC_MONTH), false); + assertEquals(TEST_2008.isSupported(ChronoField.YEAR), true); + assertEquals(TEST_2008.isSupported(ChronoField.YEAR_OF_ERA), true); + assertEquals(TEST_2008.isSupported(ChronoField.ERA), true); + assertEquals(TEST_2008.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_2008.isSupported(ChronoField.OFFSET_SECONDS), false); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_2008.isSupported((TemporalUnit) null), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.NANOS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.MICROS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.MILLIS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.SECONDS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.MINUTES), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.HOURS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.HALF_DAYS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.DAYS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.WEEKS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.MONTHS), false); + assertEquals(TEST_2008.isSupported(ChronoUnit.YEARS), true); + assertEquals(TEST_2008.isSupported(ChronoUnit.DECADES), true); + assertEquals(TEST_2008.isSupported(ChronoUnit.CENTURIES), true); + assertEquals(TEST_2008.isSupported(ChronoUnit.MILLENNIA), true); + assertEquals(TEST_2008.isSupported(ChronoUnit.ERAS), true); + assertEquals(TEST_2008.isSupported(ChronoUnit.FOREVER), false); + } + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @@ -829,7 +891,7 @@ public class TCKYear extends AbstractDateTimeTest { } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -881,29 +943,29 @@ public class TCKYear extends AbstractDateTimeTest { @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit(Year year1, Year year2, TemporalUnit unit, long expected) { - long amount = year1.periodUntil(year2, unit); + long amount = year1.until(year2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit_negated(Year year1, Year year2, TemporalUnit unit, long expected) { - long amount = year2.periodUntil(year1, unit); + long amount = year2.until(year1, unit); assertEquals(amount, -expected); } @Test(expectedExceptions = UnsupportedTemporalTypeException.class) public void test_periodUntil_TemporalUnit_unsupportedUnit() { - TEST_2008.periodUntil(TEST_2008, MONTHS); + TEST_2008.until(TEST_2008, MONTHS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullEnd() { - TEST_2008.periodUntil(null, DAYS); + TEST_2008.until(null, DAYS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullUnit() { - TEST_2008.periodUntil(TEST_2008, null); + TEST_2008.until(TEST_2008, null); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKYearMonth.java b/jdk/test/java/time/tck/java/time/TCKYearMonth.java index 14ccc774b27..66f691b0746 100644 --- a/jdk/test/java/time/tck/java/time/TCKYearMonth.java +++ b/jdk/test/java/time/tck/java/time/TCKYearMonth.java @@ -407,6 +407,68 @@ public class TCKYearMonth extends AbstractDateTimeTest { YearMonth.parse("ANY", null); } + //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_2008_06.isSupported((TemporalField) null), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.NANO_OF_SECOND), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.NANO_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MICRO_OF_SECOND), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MICRO_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MILLI_OF_SECOND), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MILLI_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.SECOND_OF_MINUTE), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.SECOND_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MINUTE_OF_HOUR), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MINUTE_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.HOUR_OF_AMPM), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.HOUR_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.AMPM_OF_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.DAY_OF_WEEK), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.DAY_OF_MONTH), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.DAY_OF_YEAR), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.EPOCH_DAY), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(TEST_2008_06.isSupported(ChronoField.PROLEPTIC_MONTH), true); + assertEquals(TEST_2008_06.isSupported(ChronoField.YEAR), true); + assertEquals(TEST_2008_06.isSupported(ChronoField.YEAR_OF_ERA), true); + assertEquals(TEST_2008_06.isSupported(ChronoField.ERA), true); + assertEquals(TEST_2008_06.isSupported(ChronoField.INSTANT_SECONDS), false); + assertEquals(TEST_2008_06.isSupported(ChronoField.OFFSET_SECONDS), false); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_2008_06.isSupported((TemporalUnit) null), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.NANOS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.MICROS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.MILLIS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.SECONDS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.MINUTES), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.HOURS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.HALF_DAYS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.DAYS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.WEEKS), false); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.MONTHS), true); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.YEARS), true); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.DECADES), true); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.CENTURIES), true); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.MILLENNIA), true); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.ERAS), true); + assertEquals(TEST_2008_06.isSupported(ChronoUnit.FOREVER), false); + } + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @@ -1120,7 +1182,7 @@ public class TCKYearMonth extends AbstractDateTimeTest { } //----------------------------------------------------------------------- - // periodUntil(Temporal, TemporalUnit) + // until(Temporal, TemporalUnit) //----------------------------------------------------------------------- @DataProvider(name="periodUntilUnit") Object[][] data_periodUntilUnit() { @@ -1200,29 +1262,29 @@ public class TCKYearMonth extends AbstractDateTimeTest { @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { - long amount = ym1.periodUntil(ym2, unit); + long amount = ym1.until(ym2, unit); assertEquals(amount, expected); } @Test(dataProvider="periodUntilUnit") public void test_periodUntil_TemporalUnit_negated(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) { - long amount = ym2.periodUntil(ym1, unit); + long amount = ym2.until(ym1, unit); assertEquals(amount, -expected); } @Test(expectedExceptions = UnsupportedTemporalTypeException.class) public void test_periodUntil_TemporalUnit_unsupportedUnit() { - TEST_2008_06.periodUntil(TEST_2008_06, HOURS); + TEST_2008_06.until(TEST_2008_06, HOURS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullEnd() { - TEST_2008_06.periodUntil(null, DAYS); + TEST_2008_06.until(null, DAYS); } @Test(expectedExceptions = NullPointerException.class) public void test_periodUntil_TemporalUnit_nullUnit() { - TEST_2008_06.periodUntil(TEST_2008_06, null); + TEST_2008_06.until(TEST_2008_06, null); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/TCKZoneId.java b/jdk/test/java/time/tck/java/time/TCKZoneId.java index dd37d804dff..c63b393d29d 100644 --- a/jdk/test/java/time/tck/java/time/TCKZoneId.java +++ b/jdk/test/java/time/tck/java/time/TCKZoneId.java @@ -464,6 +464,53 @@ public class TCKZoneId extends AbstractTCKTest { return id; } + //----------------------------------------------------------------------- + @DataProvider(name="prefixValid") + Object[][] data_prefixValid() { + return new Object[][] { + {"GMT", "+01:00"}, + {"UTC", "+01:00"}, + {"UT", "+01:00"}, + {"", "+01:00"}, + }; + } + + @Test(dataProvider="prefixValid") + public void test_prefixOfOffset(String prefix, String offset) { + ZoneOffset zoff = ZoneOffset.of(offset); + ZoneId zoneId = ZoneId.ofOffset(prefix, zoff); + assertEquals(zoneId.getId(), prefix + zoff.getId(), "in correct id for : " + prefix + ", zoff: " + zoff); + + } + + //----------------------------------------------------------------------- + @DataProvider(name="prefixInvalid") + Object[][] data_prefixInvalid() { + return new Object[][] { + {"GM", "+01:00"}, + {"U", "+01:00"}, + {"UTC0", "+01:00"}, + {"A", "+01:00"}, + }; + } + + @Test(dataProvider="prefixInvalid", expectedExceptions=java.lang.IllegalArgumentException.class) + public void test_invalidPrefixOfOffset(String prefix, String offset) { + ZoneOffset zoff = ZoneOffset.of(offset); + ZoneId zoneId = ZoneId.ofOffset(prefix, zoff); + fail("should have thrown an exception for prefix: " + prefix); + } + + @Test(expectedExceptions=java.lang.NullPointerException.class) + public void test_nullPrefixOfOffset() { + ZoneId.ofOffset(null, ZoneOffset.ofTotalSeconds(1)); + } + + @Test(expectedExceptions=java.lang.NullPointerException.class) + public void test_nullOffsetOfOffset() { + ZoneId.ofOffset("GMT", null); + } + //----------------------------------------------------------------------- @DataProvider(name="offsetBasedValidOther") Object[][] data_offsetBasedValidOther() { diff --git a/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java b/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java index 3bf1dbfa6e6..d1db67fca90 100644 --- a/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java +++ b/jdk/test/java/time/tck/java/time/TCKZonedDateTime.java @@ -127,6 +127,7 @@ import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalAmount; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; +import java.time.temporal.TemporalUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -723,10 +724,12 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { public boolean isSupported(TemporalField field) { return TEST_DATE_TIME_PARIS.toLocalDateTime().isSupported(field); } + @Override public long getLong(TemporalField field) { return TEST_DATE_TIME_PARIS.toLocalDateTime().getLong(field); } + @SuppressWarnings("unchecked") @Override public R query(TemporalQuery query) { @@ -791,17 +794,18 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { @DataProvider(name="parseAdditional") Object[][] data_parseAdditional() { return new Object[][] { - {"2012-06-30T12:30:40Z[GMT]", 2012, 6, 30, 12, 30, 40, 0, "Z"}, - {"2012-06-30T12:30:40Z[UT]", 2012, 6, 30, 12, 30, 40, 0, "Z"}, - {"2012-06-30T12:30:40Z[UTC]", 2012, 6, 30, 12, 30, 40, 0, "Z"}, + {"2012-06-30T12:30:40Z[GMT]", 2012, 6, 30, 12, 30, 40, 0, "GMT"}, + {"2012-06-30T12:30:40Z[UT]", 2012, 6, 30, 12, 30, 40, 0, "UT"}, + {"2012-06-30T12:30:40Z[UTC]", 2012, 6, 30, 12, 30, 40, 0, "UTC"}, + {"2012-06-30T12:30:40+01:00[Z]", 2012, 6, 30, 12, 30, 40, 0, "Z"}, {"2012-06-30T12:30:40+01:00[+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"}, - {"2012-06-30T12:30:40+01:00[GMT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"}, - {"2012-06-30T12:30:40+01:00[UT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"}, - {"2012-06-30T12:30:40+01:00[UTC+01:00]", 2012, 6, 30, 12, 30, 40, 0, "+01:00"}, + {"2012-06-30T12:30:40+01:00[GMT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "GMT+01:00"}, + {"2012-06-30T12:30:40+01:00[UT+01:00]", 2012, 6, 30, 12, 30, 40, 0, "UT+01:00"}, + {"2012-06-30T12:30:40+01:00[UTC+01:00]", 2012, 6, 30, 12, 30, 40, 0, "UTC+01:00"}, {"2012-06-30T12:30:40-01:00[-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"}, - {"2012-06-30T12:30:40-01:00[GMT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"}, - {"2012-06-30T12:30:40-01:00[UT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"}, - {"2012-06-30T12:30:40-01:00[UTC-01:00]", 2012, 6, 30, 12, 30, 40, 0, "-01:00"}, + {"2012-06-30T12:30:40-01:00[GMT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "GMT-01:00"}, + {"2012-06-30T12:30:40-01:00[UT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "UT-01:00"}, + {"2012-06-30T12:30:40-01:00[UTC-01:00]", 2012, 6, 30, 12, 30, 40, 0, "UTC-01:00"}, {"2012-06-30T12:30:40+01:00[Europe/London]", 2012, 6, 30, 12, 30, 40, 0, "Europe/London"}, }; } @@ -899,6 +903,68 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { } } + //----------------------------------------------------------------------- + // isSupported(TemporalField) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalField() { + assertEquals(TEST_DATE_TIME.isSupported((TemporalField) null), false); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.NANO_OF_SECOND), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.NANO_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MICRO_OF_SECOND), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MICRO_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MILLI_OF_SECOND), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MILLI_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.SECOND_OF_MINUTE), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.SECOND_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MINUTE_OF_HOUR), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MINUTE_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.HOUR_OF_AMPM), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.HOUR_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.AMPM_OF_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.DAY_OF_WEEK), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.DAY_OF_MONTH), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.DAY_OF_YEAR), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.EPOCH_DAY), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.MONTH_OF_YEAR), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.PROLEPTIC_MONTH), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.YEAR), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.YEAR_OF_ERA), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.ERA), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.INSTANT_SECONDS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoField.OFFSET_SECONDS), true); + } + + //----------------------------------------------------------------------- + // isSupported(TemporalUnit) + //----------------------------------------------------------------------- + @Test + public void test_isSupported_TemporalUnit() { + assertEquals(TEST_DATE_TIME.isSupported((TemporalUnit) null), false); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.NANOS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MICROS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MILLIS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.SECONDS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MINUTES), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.HOURS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.HALF_DAYS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.DAYS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.WEEKS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MONTHS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.YEARS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.DECADES), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.CENTURIES), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.MILLENNIA), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.ERAS), true); + assertEquals(TEST_DATE_TIME.isSupported(ChronoUnit.FOREVER), false); + } + //----------------------------------------------------------------------- // get(TemporalField) //----------------------------------------------------------------------- @@ -1977,37 +2043,37 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { } //----------------------------------------------------------------------- - // periodUntil(Temporal,TemporalUnit) + // until(Temporal,TemporalUnit) //----------------------------------------------------------------------- // TODO: more tests for period between two different zones - // compare results to OffsetDateTime.periodUntil, especially wrt dates + // compare results to OffsetDateTime.until, especially wrt dates @Test(dataProvider="plusDays") public void test_periodUntil_days(ZonedDateTime base, long expected, ZonedDateTime end) { if (base.toLocalTime().equals(end.toLocalTime()) == false) { return; // avoid DST gap input values } - assertEquals(base.periodUntil(end, DAYS), expected); + assertEquals(base.until(end, DAYS), expected); } @Test(dataProvider="plusTime") public void test_periodUntil_hours(ZonedDateTime base, long expected, ZonedDateTime end) { - assertEquals(base.periodUntil(end, HOURS), expected); + assertEquals(base.until(end, HOURS), expected); } @Test(dataProvider="plusTime") public void test_periodUntil_minutes(ZonedDateTime base, long expected, ZonedDateTime end) { - assertEquals(base.periodUntil(end, MINUTES), expected * 60); + assertEquals(base.until(end, MINUTES), expected * 60); } @Test(dataProvider="plusTime") public void test_periodUntil_seconds(ZonedDateTime base, long expected, ZonedDateTime end) { - assertEquals(base.periodUntil(end, SECONDS), expected * 3600); + assertEquals(base.until(end, SECONDS), expected * 3600); } @Test(dataProvider="plusTime") public void test_periodUntil_nanos(ZonedDateTime base, long expected, ZonedDateTime end) { - assertEquals(base.periodUntil(end, NANOS), expected * 3600_000_000_000L); + assertEquals(base.until(end, NANOS), expected * 3600_000_000_000L); } @Test @@ -2017,13 +2083,13 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { ZonedDateTime oneAm1 = LocalDateTime.of(2012, 6, 29, 1, 0).atZone(ZONE_PARIS); ZonedDateTime midnightParis2 = LocalDate.of(2012, 6, 30).atStartOfDay(ZONE_PARIS); - assertEquals(midnightLondon.periodUntil(midnightParis1, HOURS), 23); - assertEquals(midnightLondon.periodUntil(oneAm1, HOURS), 24); - assertEquals(midnightLondon.periodUntil(midnightParis2, HOURS), 23 + 24); + assertEquals(midnightLondon.until(midnightParis1, HOURS), 23); + assertEquals(midnightLondon.until(oneAm1, HOURS), 24); + assertEquals(midnightLondon.until(midnightParis2, HOURS), 23 + 24); - assertEquals(midnightLondon.periodUntil(midnightParis1, DAYS), 0); - assertEquals(midnightLondon.periodUntil(oneAm1, DAYS), 1); - assertEquals(midnightLondon.periodUntil(midnightParis2, DAYS), 1); + assertEquals(midnightLondon.until(midnightParis1, DAYS), 0); + assertEquals(midnightLondon.until(oneAm1, DAYS), 1); + assertEquals(midnightLondon.until(midnightParis2, DAYS), 1); } @Test @@ -2031,8 +2097,8 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { ZonedDateTime before = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS); ZonedDateTime after = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS); - assertEquals(before.periodUntil(after, HOURS), 23); - assertEquals(before.periodUntil(after, DAYS), 1); + assertEquals(before.until(after, HOURS), 23); + assertEquals(before.until(after, DAYS), 1); } @Test @@ -2040,23 +2106,23 @@ public class TCKZonedDateTime extends AbstractDateTimeTest { ZonedDateTime before = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS); ZonedDateTime after = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS); - assertEquals(before.periodUntil(after, HOURS), 25); - assertEquals(before.periodUntil(after, DAYS), 1); + assertEquals(before.until(after, HOURS), 25); + assertEquals(before.until(after, DAYS), 1); } @Test(expectedExceptions=DateTimeException.class) public void test_periodUntil_differentType() { - TEST_DATE_TIME_PARIS.periodUntil(TEST_LOCAL_2008_06_30_11_30_59_500, DAYS); + TEST_DATE_TIME_PARIS.until(TEST_LOCAL_2008_06_30_11_30_59_500, DAYS); } @Test(expectedExceptions=NullPointerException.class) public void test_periodUntil_nullTemporal() { - TEST_DATE_TIME_PARIS.periodUntil(null, DAYS); + TEST_DATE_TIME_PARIS.until(null, DAYS); } @Test(expectedExceptions=NullPointerException.class) public void test_periodUntil_nullUnit() { - TEST_DATE_TIME_PARIS.periodUntil(TEST_DATE_TIME_PARIS, null); + TEST_DATE_TIME_PARIS.until(TEST_DATE_TIME_PARIS, null); } //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/tck/java/time/chrono/CopticDate.java b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java index aa2d627058c..eca228adecb 100644 --- a/jdk/test/java/time/tck/java/time/chrono/CopticDate.java +++ b/jdk/test/java/time/tck/java/time/chrono/CopticDate.java @@ -87,7 +87,7 @@ import java.time.temporal.UnsupportedTemporalTypeException; * This class is immutable and thread-safe. */ public final class CopticDate - implements ChronoLocalDate, Serializable { + implements ChronoLocalDate, Serializable { /** * Serialization version. @@ -202,7 +202,7 @@ public final class CopticDate } return getChronology().range(f); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); } @@ -224,7 +224,7 @@ public final class CopticDate case YEAR: return prolepticYear; case ERA: return (prolepticYear >= 1 ? 1 : 0); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.getFrom(this); } @@ -249,7 +249,7 @@ public final class CopticDate case YEAR: return resolvePreviousValid(nvalue, month, day); case ERA: return resolvePreviousValid(1 - prolepticYear, month, day); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.adjustInto(this, newValue); } @@ -268,7 +268,7 @@ public final class CopticDate case CENTURIES: return plusYears(Math.multiplyExact(amountToAdd, 100)); case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000)); } - throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName()); + throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); } return unit.addTo(this, amountToAdd); } @@ -297,22 +297,22 @@ public final class CopticDate } @Override - public long periodUntil(Temporal endDateTime, TemporalUnit unit) { + public long until(Temporal endDateTime, TemporalUnit unit) { if (endDateTime instanceof ChronoLocalDate == false) { throw new DateTimeException("Unable to calculate period between objects of two different types"); } - ChronoLocalDate end = (ChronoLocalDate) endDateTime; + ChronoLocalDate end = (ChronoLocalDate) endDateTime; if (getChronology().equals(end.getChronology()) == false) { throw new DateTimeException("Unable to calculate period between two different chronologies"); } if (unit instanceof ChronoUnit) { - return LocalDate.from(this).periodUntil(end, unit); // TODO: this is wrong + return LocalDate.from(this).until(end, unit); // TODO: this is wrong } return unit.between(this, endDateTime); } @Override - public Period periodUntil(ChronoLocalDate endDate) { + public Period until(ChronoLocalDate endDate) { // TODO: untested CopticDate end = (CopticDate) getChronology().date(endDate); long totalMonths = (end.prolepticYear - this.prolepticYear) * 13 + (end.month - this.month); // safe diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java index b30a255995c..92f083ef6f4 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java @@ -113,10 +113,10 @@ public class TCKChronoLocalDate { @Test(dataProvider="calendars") public void test_badWithAdjusterChrono(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate date = chrono.date(refDate); + ChronoLocalDate date = chrono.date(refDate); for (Chronology[] clist : data_of_calendars()) { Chronology chrono2 = clist[0]; - ChronoLocalDate date2 = chrono2.date(refDate); + ChronoLocalDate date2 = chrono2.date(refDate); TemporalAdjuster adjuster = new FixedAdjuster(date2); if (chrono != chrono2) { try { @@ -127,7 +127,7 @@ public class TCKChronoLocalDate { } } else { // Same chronology, - ChronoLocalDate result = date.with(adjuster); + ChronoLocalDate result = date.with(adjuster); assertEquals(result, date2, "WithAdjuster failed to replace date"); } } @@ -136,10 +136,10 @@ public class TCKChronoLocalDate { @Test(dataProvider="calendars") public void test_badPlusAdjusterChrono(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate date = chrono.date(refDate); + ChronoLocalDate date = chrono.date(refDate); for (Chronology[] clist : data_of_calendars()) { Chronology chrono2 = clist[0]; - ChronoLocalDate date2 = chrono2.date(refDate); + ChronoLocalDate date2 = chrono2.date(refDate); TemporalAmount adjuster = new FixedAdjuster(date2); if (chrono != chrono2) { try { @@ -150,7 +150,7 @@ public class TCKChronoLocalDate { } } else { // Same chronology, - ChronoLocalDate result = date.plus(adjuster); + ChronoLocalDate result = date.plus(adjuster); assertEquals(result, date2, "WithAdjuster failed to replace date"); } } @@ -159,10 +159,10 @@ public class TCKChronoLocalDate { @Test(dataProvider="calendars") public void test_badMinusAdjusterChrono(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate date = chrono.date(refDate); + ChronoLocalDate date = chrono.date(refDate); for (Chronology[] clist : data_of_calendars()) { Chronology chrono2 = clist[0]; - ChronoLocalDate date2 = chrono2.date(refDate); + ChronoLocalDate date2 = chrono2.date(refDate); TemporalAmount adjuster = new FixedAdjuster(date2); if (chrono != chrono2) { try { @@ -173,7 +173,7 @@ public class TCKChronoLocalDate { } } else { // Same chronology, - ChronoLocalDate result = date.minus(adjuster); + ChronoLocalDate result = date.minus(adjuster); assertEquals(result, date2, "WithAdjuster failed to replace date"); } } @@ -182,10 +182,10 @@ public class TCKChronoLocalDate { @Test(dataProvider="calendars") public void test_badPlusTemporalUnitChrono(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate date = chrono.date(refDate); + ChronoLocalDate date = chrono.date(refDate); for (Chronology[] clist : data_of_calendars()) { Chronology chrono2 = clist[0]; - ChronoLocalDate date2 = chrono2.date(refDate); + ChronoLocalDate date2 = chrono2.date(refDate); TemporalUnit adjuster = new FixedTemporalUnit(date2); if (chrono != chrono2) { try { @@ -197,7 +197,7 @@ public class TCKChronoLocalDate { } } else { // Same chronology, - ChronoLocalDate result = date.plus(1, adjuster); + ChronoLocalDate result = date.plus(1, adjuster); assertEquals(result, date2, "WithAdjuster failed to replace date"); } } @@ -206,10 +206,10 @@ public class TCKChronoLocalDate { @Test(dataProvider="calendars") public void test_badMinusTemporalUnitChrono(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate date = chrono.date(refDate); + ChronoLocalDate date = chrono.date(refDate); for (Chronology[] clist : data_of_calendars()) { Chronology chrono2 = clist[0]; - ChronoLocalDate date2 = chrono2.date(refDate); + ChronoLocalDate date2 = chrono2.date(refDate); TemporalUnit adjuster = new FixedTemporalUnit(date2); if (chrono != chrono2) { try { @@ -221,7 +221,7 @@ public class TCKChronoLocalDate { } } else { // Same chronology, - ChronoLocalDate result = date.minus(1, adjuster); + ChronoLocalDate result = date.minus(1, adjuster); assertEquals(result, date2, "WithAdjuster failed to replace date"); } } @@ -230,10 +230,10 @@ public class TCKChronoLocalDate { @Test(dataProvider="calendars") public void test_badTemporalFieldChrono(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate date = chrono.date(refDate); + ChronoLocalDate date = chrono.date(refDate); for (Chronology[] clist : data_of_calendars()) { Chronology chrono2 = clist[0]; - ChronoLocalDate date2 = chrono2.date(refDate); + ChronoLocalDate date2 = chrono2.date(refDate); TemporalField adjuster = new FixedTemporalField(date2); if (chrono != chrono2) { try { @@ -245,7 +245,7 @@ public class TCKChronoLocalDate { } } else { // Same chronology, - ChronoLocalDate result = date.with(adjuster, 1); + ChronoLocalDate result = date.with(adjuster, 1); assertEquals(result, date2, "TemporalField doSet failed to replace date"); } } @@ -258,7 +258,7 @@ public class TCKChronoLocalDate { public void test_date_comparisons(Chronology chrono) { List dates = new ArrayList<>(); - ChronoLocalDate date = chrono.date(LocalDate.of(2013, 1, 1)); + ChronoLocalDate date = chrono.date(LocalDate.of(2013, 1, 1)); // Insert dates in order, no duplicates dates.add(date.minus(1, ChronoUnit.YEARS)); @@ -273,17 +273,17 @@ public class TCKChronoLocalDate { // Check these dates against the corresponding dates for every calendar for (Chronology[] clist : data_of_calendars()) { - List> otherDates = new ArrayList<>(); + List otherDates = new ArrayList<>(); Chronology chrono2 = clist[0]; - for (ChronoLocalDate d : dates) { + for (ChronoLocalDate d : dates) { otherDates.add(chrono2.date(d)); } // Now compare the sequence of original dates with the sequence of converted dates for (int i = 0; i < dates.size(); i++) { - ChronoLocalDate a = dates.get(i); + ChronoLocalDate a = dates.get(i); for (int j = 0; j < otherDates.size(); j++) { - ChronoLocalDate b = otherDates.get(j); + ChronoLocalDate b = otherDates.get(j); int cmp = ChronoLocalDate.timeLineOrder().compare(a, b); if (i < j) { assertTrue(cmp < 0, a + " compare " + b); @@ -312,7 +312,7 @@ public class TCKChronoLocalDate { @Test( dataProvider="calendars") public void test_ChronoSerialization(Chronology chrono) throws Exception { LocalDate ref = LocalDate.of(2013, 1, 5); - ChronoLocalDate orginal = chrono.date(ref); + ChronoLocalDate orginal = chrono.date(ref); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(baos); out.writeObject(orginal); @@ -320,7 +320,7 @@ public class TCKChronoLocalDate { ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream in = new ObjectInputStream(bais); @SuppressWarnings("unchecked") - ChronoLocalDate ser = (ChronoLocalDate) in.readObject(); + ChronoLocalDate ser = (ChronoLocalDate) in.readObject(); assertEquals(ser, orginal, "deserialized date is wrong"); } @@ -328,12 +328,12 @@ public class TCKChronoLocalDate { @Test(dataProvider="calendars") public void test_from_TemporalAccessor(Chronology chrono) { LocalDate refDate = LocalDate.of(2013, 1, 1); - ChronoLocalDate date = chrono.date(refDate); - ChronoLocalDate test1 = ChronoLocalDate.from(date); + ChronoLocalDate date = chrono.date(refDate); + ChronoLocalDate test1 = ChronoLocalDate.from(date); assertEquals(test1, date); - ChronoLocalDate test2 = ChronoLocalDate.from(date.atTime(LocalTime.of(12, 30))); + ChronoLocalDate test2 = ChronoLocalDate.from(date.atTime(LocalTime.of(12, 30))); assertEquals(test2, date); - ChronoLocalDate test3 = ChronoLocalDate.from(date.atTime(LocalTime.of(12, 30)).atZone(ZoneOffset.UTC)); + ChronoLocalDate test3 = ChronoLocalDate.from(date.atTime(LocalTime.of(12, 30)).atZone(ZoneOffset.UTC)); assertEquals(test3, date); } @@ -396,11 +396,6 @@ public class TCKChronoLocalDate { this.temporal = temporal; } - @Override - public String getName() { - return "FixedTemporalUnit"; - } - @Override public Duration getDuration() { throw new UnsupportedOperationException("Not supported yet."); @@ -411,6 +406,16 @@ public class TCKChronoLocalDate { throw new UnsupportedOperationException("Not supported yet."); } + @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + @Override public boolean isSupportedBy(Temporal temporal) { throw new UnsupportedOperationException("Not supported yet."); @@ -426,6 +431,11 @@ public class TCKChronoLocalDate { public long between(Temporal temporal1, Temporal temporal2) { throw new UnsupportedOperationException("Not supported yet."); } + + @Override + public String toString() { + return "FixedTemporalUnit"; + } } /** @@ -438,11 +448,6 @@ public class TCKChronoLocalDate { this.temporal = temporal; } - @Override - public String getName() { - return "FixedTemporalField"; - } - @Override public TemporalUnit getBaseUnit() { throw new UnsupportedOperationException("Not supported yet."); @@ -458,6 +463,16 @@ public class TCKChronoLocalDate { throw new UnsupportedOperationException("Not supported yet."); } + @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + @Override public boolean isSupportedBy(TemporalAccessor temporal) { throw new UnsupportedOperationException("Not supported yet."); @@ -478,5 +493,10 @@ public class TCKChronoLocalDate { public R adjustInto(R temporal, long newValue) { return (R) this.temporal; } + + @Override + public String toString() { + return "FixedTemporalField"; + } } } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java index 251c071d318..129a1903998 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java @@ -410,11 +410,6 @@ public class TCKChronoLocalDateTime { this.temporal = temporal; } - @Override - public String getName() { - return "FixedTemporalUnit"; - } - @Override public Duration getDuration() { throw new UnsupportedOperationException("Not supported yet."); @@ -425,6 +420,16 @@ public class TCKChronoLocalDateTime { throw new UnsupportedOperationException("Not supported yet."); } + @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + @Override public boolean isSupportedBy(Temporal temporal) { throw new UnsupportedOperationException("Not supported yet."); @@ -440,6 +445,11 @@ public class TCKChronoLocalDateTime { public long between(Temporal temporal1, Temporal temporal2) { throw new UnsupportedOperationException("Not supported yet."); } + + @Override + public String toString() { + return "FixedTemporalUnit"; + } } /** @@ -452,11 +462,6 @@ public class TCKChronoLocalDateTime { this.temporal = temporal; } - @Override - public String getName() { - return "FixedTemporalField"; - } - @Override public TemporalUnit getBaseUnit() { throw new UnsupportedOperationException("Not supported yet."); @@ -472,6 +477,16 @@ public class TCKChronoLocalDateTime { throw new UnsupportedOperationException("Not supported yet."); } + @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + @Override public boolean isSupportedBy(TemporalAccessor temporal) { throw new UnsupportedOperationException("Not supported yet."); @@ -492,5 +507,10 @@ public class TCKChronoLocalDateTime { public R adjustInto(R temporal, long newValue) { return (R) this.temporal; } + + @Override + public String toString() { + return "FixedTemporalField"; + } } } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java index 611c9258df9..3b89857fa45 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java @@ -256,7 +256,7 @@ public class TCKChronoZonedDateTime { } //----------------------------------------------------------------------- - // isBefore, isAfter, isEqual, INSTANT_COMPARATOR test a Chronology against the other Chronos + // isBefore, isAfter, isEqual, timeLineOrder() test a Chronology against the other Chronos //----------------------------------------------------------------------- @Test(dataProvider="calendars") public void test_zonedDateTime_comparisons(Chronology chrono) { @@ -412,11 +412,6 @@ public class TCKChronoZonedDateTime { this.temporal = temporal; } - @Override - public String getName() { - return "FixedTemporalUnit"; - } - @Override public Duration getDuration() { throw new UnsupportedOperationException("Not supported yet."); @@ -427,6 +422,16 @@ public class TCKChronoZonedDateTime { throw new UnsupportedOperationException("Not supported yet."); } + @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + @Override public boolean isSupportedBy(Temporal temporal) { throw new UnsupportedOperationException("Not supported yet."); @@ -442,6 +447,12 @@ public class TCKChronoZonedDateTime { public long between(Temporal temporal1, Temporal temporal2) { throw new UnsupportedOperationException("Not supported yet."); } + + @Override + public String toString() { + return "FixedTemporalUnit"; + } + } /** @@ -454,11 +465,6 @@ public class TCKChronoZonedDateTime { this.temporal = temporal; } - @Override - public String getName() { - return "FixedTemporalField"; - } - @Override public TemporalUnit getBaseUnit() { throw new UnsupportedOperationException("Not supported yet."); @@ -474,6 +480,16 @@ public class TCKChronoZonedDateTime { throw new UnsupportedOperationException("Not supported yet."); } + @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + @Override public boolean isSupportedBy(TemporalAccessor temporal) { throw new UnsupportedOperationException("Not supported yet."); @@ -494,5 +510,10 @@ public class TCKChronoZonedDateTime { public R adjustInto(R temporal, long newValue) { return (R) this.temporal; } + + @Override + public String toString() { + return "FixedTemporalField"; + } } } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java index 0077be55315..c705f9794ce 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java @@ -64,18 +64,27 @@ import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; +import java.util.Locale; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.time.ZoneId; +import java.time.Clock; import java.time.DateTimeException; import java.time.chrono.ChronoLocalDate; import java.time.chrono.Chronology; import java.time.chrono.HijrahChronology; +import java.time.chrono.HijrahEra; import java.time.chrono.IsoChronology; +import java.time.chrono.IsoEra; import java.time.chrono.JapaneseChronology; +import java.time.chrono.JapaneseEra; import java.time.chrono.MinguoChronology; +import java.time.chrono.MinguoEra; import java.time.chrono.ThaiBuddhistChronology; +import java.time.chrono.ThaiBuddhistEra; +import java.time.format.TextStyle; import java.time.temporal.ChronoField; import java.util.Locale; import java.util.Set; @@ -133,15 +142,35 @@ public class TCKChronology { + ", expected >= " + data_of_calendars().length); } + //----------------------------------------------------------------------- + // getDisplayName() + //----------------------------------------------------------------------- + @DataProvider(name = "calendarDisplayName") + Object[][] data_of_calendarDisplayNames() { + return new Object[][] { + {"Hijrah", "Hijrah-umalqura"}, + {"ISO", "ISO"}, + {"Japanese", "Japanese Calendar"}, + {"Minguo", "Minguo Calendar"}, + {"ThaiBuddhist", "Buddhist Calendar"}, + }; + } + + @Test(dataProvider = "calendarDisplayName") + public void test_getDisplayName(String chronoId, String calendarDisplayName) { + Chronology chrono = Chronology.of(chronoId); + assertEquals(chrono.getDisplayName(TextStyle.FULL, Locale.ENGLISH), calendarDisplayName); + } + /** * Compute the number of days from the Epoch and compute the date from the number of days. */ @Test(dataProvider = "calendarNameAndType") public void test_epoch(String name, String alias) { Chronology chrono = Chronology.of(name); // a chronology. In practice this is rarely hardcoded - ChronoLocalDate date1 = chrono.dateNow(); + ChronoLocalDate date1 = chrono.dateNow(); long epoch1 = date1.getLong(ChronoField.EPOCH_DAY); - ChronoLocalDate date2 = date1.with(ChronoField.EPOCH_DAY, epoch1); + ChronoLocalDate date2 = date1.with(ChronoField.EPOCH_DAY, epoch1); assertEquals(date1, date2, "Date from epoch day is not same date: " + date1 + " != " + date2); long epoch2 = date1.getLong(ChronoField.EPOCH_DAY); assertEquals(epoch1, epoch2, "Epoch day not the same: " + epoch1 + " != " + epoch2); @@ -150,9 +179,9 @@ public class TCKChronology { @Test(dataProvider = "calendarNameAndType") public void test_dateEpochDay(String name, String alias) { Chronology chrono = Chronology.of(name); - ChronoLocalDate date = chrono.dateNow(); + ChronoLocalDate date = chrono.dateNow(); long epochDay = date.getLong(ChronoField.EPOCH_DAY); - ChronoLocalDate test = chrono.dateEpochDay(epochDay); + ChronoLocalDate test = chrono.dateEpochDay(epochDay); assertEquals(test, date); } @@ -184,6 +213,101 @@ public class TCKChronology { assertEquals(Chronology.ofLocale(locale), chrono); } + //----------------------------------------------------------------------- + // dateNow() + //----------------------------------------------------------------------- + @Test + public void test_MinguoChronology_dateNow() { + ZoneId zoneId_paris = ZoneId.of("Europe/Paris"); + Clock clock = Clock.system(zoneId_paris); + + Chronology chrono = Chronology.of("Minguo"); + assertEquals(chrono.dateNow(), MinguoChronology.INSTANCE.dateNow()); + assertEquals(chrono.dateNow(zoneId_paris), MinguoChronology.INSTANCE.dateNow(zoneId_paris)); + assertEquals(chrono.dateNow(clock), MinguoChronology.INSTANCE.dateNow(clock)); + } + + @Test + public void test_IsoChronology_dateNow() { + ZoneId zoneId_paris = ZoneId.of("Europe/Paris"); + Clock clock = Clock.system(zoneId_paris); + + Chronology chrono = Chronology.of("ISO"); + assertEquals(chrono.dateNow(), IsoChronology.INSTANCE.dateNow()); + assertEquals(chrono.dateNow(zoneId_paris), IsoChronology.INSTANCE.dateNow(zoneId_paris)); + assertEquals(chrono.dateNow(clock), IsoChronology.INSTANCE.dateNow(clock)); + } + + @Test + public void test_JapaneseChronology_dateNow() { + ZoneId zoneId_paris = ZoneId.of("Europe/Paris"); + Clock clock = Clock.system(zoneId_paris); + + Chronology chrono = Chronology.of("Japanese"); + assertEquals(chrono.dateNow(), JapaneseChronology.INSTANCE.dateNow()); + assertEquals(chrono.dateNow(zoneId_paris), JapaneseChronology.INSTANCE.dateNow(zoneId_paris)); + assertEquals(chrono.dateNow(clock), JapaneseChronology.INSTANCE.dateNow(clock)); + } + + @Test + public void test_ThaiBuddhistChronology_dateNow() { + ZoneId zoneId_paris = ZoneId.of("Europe/Paris"); + Clock clock = Clock.system(zoneId_paris); + + Chronology chrono = Chronology.of("ThaiBuddhist"); + assertEquals(chrono.dateNow(), ThaiBuddhistChronology.INSTANCE.dateNow()); + assertEquals(chrono.dateNow(zoneId_paris), ThaiBuddhistChronology.INSTANCE.dateNow(zoneId_paris)); + assertEquals(chrono.dateNow(clock), ThaiBuddhistChronology.INSTANCE.dateNow(clock)); + } + + //----------------------------------------------------------------------- + // dateYearDay() and date() + //----------------------------------------------------------------------- + @Test + public void test_HijrahChronology_dateYearDay() { + Chronology chrono = Chronology.of("Hijrah"); + ChronoLocalDate date1 = chrono.dateYearDay(HijrahEra.AH, 1434, 178); + ChronoLocalDate date2 = chrono.date(HijrahEra.AH, 1434, 7, 1); + assertEquals(date1, HijrahChronology.INSTANCE.dateYearDay(HijrahEra.AH, 1434, 178)); + assertEquals(date2, HijrahChronology.INSTANCE.dateYearDay(HijrahEra.AH, 1434, 178)); + } + + @Test + public void test_MinguoChronology_dateYearDay() { + Chronology chrono = Chronology.of("Minguo"); + ChronoLocalDate date1 = chrono.dateYearDay(MinguoEra.ROC, 5, 60); + ChronoLocalDate date2 = chrono.date(MinguoEra.ROC, 5, 2, 29); + assertEquals(date1, MinguoChronology.INSTANCE.dateYearDay(MinguoEra.ROC, 5, 60)); + assertEquals(date2, MinguoChronology.INSTANCE.dateYearDay(MinguoEra.ROC, 5, 60)); + } + + @Test + public void test_IsoChronology_dateYearDay() { + Chronology chrono = Chronology.of("ISO"); + ChronoLocalDate date1 = chrono.dateYearDay(IsoEra.CE, 5, 60); + ChronoLocalDate date2 = chrono.date(IsoEra.CE, 5, 3, 1); + assertEquals(date1, IsoChronology.INSTANCE.dateYearDay(IsoEra.CE, 5, 60)); + assertEquals(date2, IsoChronology.INSTANCE.dateYearDay(IsoEra.CE, 5, 60)); + } + + @Test + public void test_JapaneseChronology_dateYearDay() { + Chronology chrono = Chronology.of("Japanese"); + ChronoLocalDate date1 = chrono.dateYearDay(JapaneseEra.HEISEI, 8, 60); + ChronoLocalDate date2 = chrono.date(JapaneseEra.HEISEI, 8, 2, 29); + assertEquals(date1, JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.HEISEI, 8, 60)); + assertEquals(date2, JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.HEISEI, 8, 60)); + } + + @Test + public void test_ThaiBuddhistChronology_dateYearDay() { + Chronology chrono = Chronology.of("ThaiBuddhist"); + ChronoLocalDate date1 = chrono.dateYearDay(ThaiBuddhistEra.BE, 2459, 60); + ChronoLocalDate date2 = chrono.date(ThaiBuddhistEra.BE, 2459, 2, 29); + assertEquals(date1, ThaiBuddhistChronology.INSTANCE.dateYearDay(ThaiBuddhistEra.BE, 2459, 60)); + assertEquals(date2, ThaiBuddhistChronology.INSTANCE.dateYearDay(ThaiBuddhistEra.BE, 2459, 60)); + } + /** * Test lookup by calendarType of each chronology. * Verify that the calendar can be found by {@link java.time.chrono.Chronology#ofLocale}. diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKHijrahChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKHijrahChronology.java index 81b3ab740ae..61c19ab16cf 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKHijrahChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKHijrahChronology.java @@ -56,18 +56,13 @@ */ package tck.java.time.chrono; -import static java.time.temporal.ChronoField.DAY_OF_WEEK; +import java.time.Clock; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; -import java.time.Clock; import java.time.DateTimeException; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.Month; -import java.time.Period; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.chrono.ChronoLocalDate; @@ -77,11 +72,12 @@ import java.time.chrono.HijrahChronology; import java.time.chrono.HijrahDate; import java.time.chrono.HijrahEra; import java.time.chrono.IsoChronology; -import java.time.chrono.MinguoChronology; -import java.time.chrono.MinguoDate; -import java.time.temporal.ChronoUnit; -import java.time.temporal.TemporalAdjuster; +import java.time.format.ResolverStyle; +import java.time.temporal.ChronoField; +import java.time.temporal.TemporalField; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.testng.Assert; import org.testng.annotations.DataProvider; @@ -106,49 +102,7 @@ public class TCKHijrahChronology { Assert.assertEquals(test, c); } - //----------------------------------------------------------------------- - // creation, toLocalDate() - //----------------------------------------------------------------------- - @DataProvider(name="samples") - Object[][] data_samples() { - return new Object[][] { - //{HijrahChronology.INSTANCE.date(1320, 1, 1), LocalDate.of(1902, 4, 9)}, - //{HijrahChronology.INSTANCE.date(1320, 1, 2), LocalDate.of(1902, 4, 10)}, - //{HijrahChronology.INSTANCE.date(1320, 1, 3), LocalDate.of(1902, 4, 11)}, - - //{HijrahChronology.INSTANCE.date(1322, 1, 1), LocalDate.of(1904, 3, 18)}, - //{HijrahChronology.INSTANCE.date(1323, 1, 1), LocalDate.of(1905, 3, 7)}, - //{HijrahChronology.INSTANCE.date(1323, 12, 6), LocalDate.of(1906, 1, 30)}, - //{HijrahChronology.INSTANCE.date(1324, 1, 1), LocalDate.of(1906, 2, 24)}, - //{HijrahChronology.INSTANCE.date(1324, 7, 3), LocalDate.of(1906, 8, 23)}, - //{HijrahChronology.INSTANCE.date(1324, 7, 4), LocalDate.of(1906, 8, 24)}, - //{HijrahChronology.INSTANCE.date(1325, 1, 1), LocalDate.of(1907, 2, 13)}, - - {HijrahChronology.INSTANCE.date(1434, 7, 1), LocalDate.of(2013, 5, 11)}, - {HijrahChronology.INSTANCE.date(HijrahEra.AH, 1434, 7, 1), LocalDate.of(2013, 5, 11)}, - {HijrahChronology.INSTANCE.dateYearDay(HijrahEra.AH, 1434, 178), LocalDate.of(2013, 5, 11)}, - {HijrahChronology.INSTANCE.dateYearDay(1434, 178), LocalDate.of(2013, 5, 11)}, - //{HijrahChronology.INSTANCE.date(1500, 3, 3), LocalDate.of(2079, 1, 5)}, - //{HijrahChronology.INSTANCE.date(1500, 10, 28), LocalDate.of(2079, 8, 25)}, - //{HijrahChronology.INSTANCE.date(1500, 10, 29), LocalDate.of(2079, 8, 26)}, - }; - } - - @Test(dataProvider="samples") - public void test_toLocalDate(ChronoLocalDate hijrahDate, LocalDate iso) { - assertEquals(LocalDate.from(hijrahDate), iso); - } - - @Test(dataProvider="samples") - public void test_fromCalendrical(ChronoLocalDate hijrahDate, LocalDate iso) { - assertEquals(HijrahChronology.INSTANCE.date(iso), hijrahDate); - } - - @Test(dataProvider="samples") - public void test_dayOfWeekEqualIsoDayOfWeek(ChronoLocalDate hijrahDate, LocalDate iso) { - assertEquals(hijrahDate.get(DAY_OF_WEEK), iso.get(DAY_OF_WEEK), "Hijrah day of week should be same as ISO day of week"); - } - + // Tests for dateNow() method @Test public void test_dateNow(){ assertEquals(HijrahChronology.INSTANCE.dateNow(), HijrahDate.now()) ; @@ -169,31 +123,41 @@ public class TCKHijrahChronology { assertEquals(HijrahChronology.INSTANCE.dateNow(ZoneId.of(ZoneOffset.UTC.getId())), HijrahChronology.INSTANCE.dateNow(Clock.systemUTC())) ; } + // Sample invalid dates @DataProvider(name="badDates") Object[][] data_badDates() { return new Object[][] { - {1434, 0, 0}, - + {1299, 12, 29}, + {1320, 1, 29 + 1}, + {1320, 12, 29 + 1}, {1434, -1, 1}, + {1605, 1, 29}, {1434, 0, 1}, {1434, 14, 1}, {1434, 15, 1}, - {1434, 1, -1}, {1434, 1, 0}, {1434, 1, 32}, - {1434, 12, -1}, {1434, 12, 0}, {1434, 12, 32}, }; } + // This is a negative test to verify if the API throws exception if an invalid date is provided @Test(dataProvider="badDates", expectedExceptions=DateTimeException.class) public void test_badDates(int year, int month, int dom) { HijrahChronology.INSTANCE.date(year, month, dom); } + // Negative test or dateYearDay with day too large + @Test(expectedExceptions=java.time.DateTimeException.class) + public void test_ofYearDayTooLarge() { + int year = 1435; + int lengthOfYear = HijrahChronology.INSTANCE.dateYearDay(year, 1).lengthOfYear(); + HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(year, lengthOfYear + 1); + } + //----------------------------------------------------------------------- // Bad Era for Chronology.date(era,...) and Chronology.prolepticYear(Era,...) //----------------------------------------------------------------------- @@ -213,7 +177,7 @@ public class TCKHijrahChronology { ; // ignore expected exception } - /* TODO: Test for missing HijrahDate.of(Era, y, m, d) method. + /* TODO: Test for checking HijrahDate.of(Era, y, m, d) method if it is added. try { @SuppressWarnings("unused") HijrahDate jdate = HijrahDate.of(era, 1, 1, 1); @@ -233,102 +197,344 @@ public class TCKHijrahChronology { } } } - //----------------------------------------------------------------------- - // with(WithAdjuster) + // Tests for HijrahChronology resolve //----------------------------------------------------------------------- - @Test - public void test_adjust1() { - ChronoLocalDate base = HijrahChronology.INSTANCE.date(1434, 5, 15); - ChronoLocalDate test = base.with(TemporalAdjuster.lastDayOfMonth()); - assertEquals(test, HijrahChronology.INSTANCE.date(1434, 5, 29)); + @DataProvider(name = "resolve_styleByEra") + Object[][] data_resolve_styleByEra() { + Object[][] result = new Object[ResolverStyle.values().length * HijrahEra.values().length][]; + int i = 0; + for (ResolverStyle style : ResolverStyle.values()) { + for (HijrahEra era : HijrahEra.values()) { + result[i++] = new Object[] {style, era}; + } + } + return result; } - @Test - public void test_adjust2() { - ChronoLocalDate base = HijrahChronology.INSTANCE.date(1434, 6, 2); - ChronoLocalDate test = base.with(TemporalAdjuster.lastDayOfMonth()); - assertEquals(test, HijrahChronology.INSTANCE.date(1434, 6, 30)); + @Test(dataProvider = "resolve_styleByEra") + public void test_resolve_yearOfEra_eraOnly_valid(ResolverStyle style, HijrahEra era) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.ERA), (Long) (long) era.getValue()); + assertEquals(fieldValues.size(), 1); + } + + @Test(dataProvider = "resolve_styleByEra") + public void test_resolve_yearOfEra_eraAndYearOfEraOnly_valid(ResolverStyle style, HijrahEra era) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + fieldValues.put(ChronoField.YEAR_OF_ERA, 1343L); + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.ERA), null); + assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), null); + assertEquals(fieldValues.get(ChronoField.YEAR), (Long) 1343L); + assertEquals(fieldValues.size(), 1); + } + + @Test(dataProvider = "resolve_styleByEra") + public void test_resolve_yearOfEra_eraAndYearOnly_valid(ResolverStyle style, HijrahEra era) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + fieldValues.put(ChronoField.YEAR, 1343L); + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.ERA), (Long) (long) era.getValue()); + assertEquals(fieldValues.get(ChronoField.YEAR), (Long) 1343L); + assertEquals(fieldValues.size(), 2); + } + + @DataProvider(name = "resolve_styles") + Object[][] data_resolve_styles() { + Object[][] result = new Object[ResolverStyle.values().length][]; + int i = 0; + for (ResolverStyle style : ResolverStyle.values()) { + result[i++] = new Object[] {style}; + } + return result; + } + + @Test(dataProvider = "resolve_styles") + public void test_resolve_yearOfEra_yearOfEraOnly_valid(ResolverStyle style) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR_OF_ERA, 1343L); + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), (style != ResolverStyle.STRICT) ? null : (Long) 1343L); + assertEquals(fieldValues.get(ChronoField.YEAR), (style == ResolverStyle.STRICT) ? null : (Long) 1343L); + assertEquals(fieldValues.size(), 1); + } + + @Test(dataProvider = "resolve_styles") + public void test_resolve_yearOfEra_yearOfEraAndYearOnly_valid(ResolverStyle style) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR_OF_ERA, 1343L); + fieldValues.put(ChronoField.YEAR, 1343L); + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), null); + assertEquals(fieldValues.get(ChronoField.YEAR), (Long) 1343L); + assertEquals(fieldValues.size(), 1); } //----------------------------------------------------------------------- - // HijrahDate.with(Local*) + // Sample Hijrah Calendar data; official data is in lib/hijrah-ummalqura.properties + // 1432=29 30 30 30 29 30 29 30 29 30 29 29 total = 354 + // 1433=30 29 30 30 29 30 30 29 30 29 30 29 total = 355 + // 1434=29 30 29 30 29 30 30 29 30 30 29 29 total = 354 + // 1435=30 29 30 29 30 29 30 29 30 30 29 30 total = 355 //----------------------------------------------------------------------- - @Test - public void test_adjust_toLocalDate() { - ChronoLocalDate hijrahDate = HijrahChronology.INSTANCE.date(1435, 1, 4); - ChronoLocalDate test = hijrahDate.with(LocalDate.of(2012, 7, 6)); - assertEquals(test, HijrahChronology.INSTANCE.date(1433, 8, 16)); - } + @DataProvider(name = "resolve_ymd") + Object[][] data_resolve_ymd() { + // Compute the number of days in various month and years so that test cases + // are not dependent on specific calendar data + // Month numbers are always 1..12 so they can be used literally + final int year = 1434; + final int yearP1 = year + 1; + final int yearP2 = year + 2; + final int yearM1 = year - 1; + final int yearM2 = year - 2; + final int lastDayInYear = dateYearDay(year, 1).lengthOfYear(); + final int lastDayInYearP1 = dateYearDay(yearP1, 1).lengthOfYear(); + final int lastDayInYearM1 = dateYearDay(yearM1, 1).lengthOfYear(); + final int lastDayInYearM2 = dateYearDay(yearM2, 1).lengthOfYear(); + final int lastDayInMonthM1 = date(yearM1, 12, 1).lengthOfMonth(); + final int lastDayInMonthM2 = date(yearM1, 11, 1).lengthOfMonth(); + final int lastDayInMonthM11 = date(yearM1, 2, 1).lengthOfMonth(); - @Test(expectedExceptions=DateTimeException.class) - public void test_adjust_toMonth() { - ChronoLocalDate hijrahDate = HijrahChronology.INSTANCE.date(1435, 1, 4); - hijrahDate.with(Month.APRIL); - } + final int lastDayInMonth1 = date(year, 1, 1).lengthOfMonth(); + final int lastDayInMonth2 = date(year, 2, 1).lengthOfMonth(); + final int lastDayInMonth4 = date(year, 4, 1).lengthOfMonth(); + final int lastDayInMonth5 = date(year, 5, 1).lengthOfMonth(); + final int lastDayInMonth6 = date(year, 6, 1).lengthOfMonth(); + final int lastDayInMonth7 = date(year, 7, 1).lengthOfMonth(); - //----------------------------------------------------------------------- - // LocalDate.with(HijrahDate) - //----------------------------------------------------------------------- - @Test - public void test_LocalDate_adjustToHijrahDate() { - ChronoLocalDate hijrahDate = HijrahChronology.INSTANCE.date(1434, 5, 15); - LocalDate test = LocalDate.MIN.with(hijrahDate); - assertEquals(test, LocalDate.of(2013, 3, 27)); - } - - @Test - public void test_LocalDateTime_adjustToHijrahDate() { - ChronoLocalDate hijrahDate = HijrahChronology.INSTANCE.date(1435, 5, 15); - LocalDateTime test = LocalDateTime.MIN.with(hijrahDate); - assertEquals(test, LocalDateTime.of(2014, 3, 16, 0, 0)); - } - - //----------------------------------------------------------------------- - // PeriodUntil() - //----------------------------------------------------------------------- - @Test - public void test_periodUntilDate() { - HijrahDate mdate1 = HijrahDate.of(1434, 1, 1); - HijrahDate mdate2 = HijrahDate.of(1435, 2, 2); - Period period = mdate1.periodUntil(mdate2); - assertEquals(period, Period.of(1, 1, 1)); - } - - @Test - public void test_periodUntilUnit() { - HijrahDate mdate1 = HijrahDate.of(1434, 1, 1); - HijrahDate mdate2 = HijrahDate.of(1435, 2, 2); - long months = mdate1.periodUntil(mdate2, ChronoUnit.MONTHS); - assertEquals(months, 13); - } - - @Test - public void test_periodUntilDiffChrono() { - HijrahDate mdate1 = HijrahDate.of(1434, 1, 1); - HijrahDate mdate2 = HijrahDate.of(1435, 2, 2); - MinguoDate ldate2 = MinguoChronology.INSTANCE.date(mdate2); - Period period = mdate1.periodUntil(ldate2); - assertEquals(period, Period.of(1, 1, 1)); - } - - //----------------------------------------------------------------------- - // toString() - //----------------------------------------------------------------------- - @DataProvider(name="toString") - Object[][] data_toString() { return new Object[][] { - //{HijrahChronology.INSTANCE.date(1320, 1, 1), "Hijrah AH 1320-01-01"}, - //{HijrahChronology.INSTANCE.date(1500, 10, 28), "Hijrah AH 1500-10-28"}, - //{HijrahChronology.INSTANCE.date(1500, 10, 29), "Hijrah AH 1500-10-29"}, - {HijrahChronology.INSTANCE.date(1434, 12, 5), "Hijrah-umalqura AH 1434-12-05"}, - {HijrahChronology.INSTANCE.date(1434, 12, 6), "Hijrah-umalqura AH 1434-12-06"}, + {year, 1, -lastDayInYearM1, dateYearDay(yearM2, lastDayInYearM2), false, false}, + {year, 1, -lastDayInYearM1 + 1, date(yearM1, 1, 1), false, false}, + {year, 1, -lastDayInMonthM1, date(yearM1, 11, lastDayInMonthM2), false, false}, + {year, 1, -lastDayInMonthM1 + 1, date(yearM1, 12, 1), false, false}, + {year, 1, -12, date(yearM1, 12, lastDayInMonthM1 - 12), false, false}, + {year, 1, 1, date(year, 1, 1), true, true}, + {year, 1, lastDayInMonth1 + lastDayInMonth2 - 1, date(year, 2, lastDayInMonth2 - 1), false, false}, + {year, 1, lastDayInMonth1 + lastDayInMonth2, date(year, 2, lastDayInMonth2), false, false}, + {year, 1, lastDayInMonth1 + lastDayInMonth2 + 1 , date(year, 3, 1), false, false}, + {year, 1, lastDayInYear, dateYearDay(year, lastDayInYear), false, false}, + {year, 1, lastDayInYear + 1, date(1435, 1, 1), false, false}, + {year, 1, lastDayInYear + lastDayInYearP1, dateYearDay(yearP1, lastDayInYearP1), false, false}, + {year, 1, lastDayInYear + lastDayInYearP1 + 1, date(yearP2, 1, 1), false, false}, + + {year, 2, 1, date(year, 2, 1), true, true}, + {year, 2, lastDayInMonth2 - 2, date(year, 2, lastDayInMonth2 - 2), true, true}, + {year, 2, lastDayInMonth2 - 1, date(year, 2, lastDayInMonth2 - 1), true, true}, + {year, 2, lastDayInMonth2, date(year, 2, lastDayInMonth2), date(year, 2, lastDayInMonth2), true}, + {year, 2, lastDayInMonth2 + 1, date(year, 3, 1), false, false}, + + {year, -12, 1, date(yearM2, 12, 1), false, false}, + {year, -11, 1, date(yearM1, 1, 1), false, false}, + {year, -1, 1, date(yearM1, 11, 1), false, false}, + {year, 0, 1, date(yearM1, 12, 1), false, false}, + {year, 1, 1, date(year, 1, 1), true, true}, + {year, 12, 1, date(year, 12, 1), true, true}, + {year, 13, 1, date(yearP1, 1, 1), false, false}, + {year, 24, 1, date(yearP1, 12, 1), false, false}, + {year, 25, 1, date(yearP2, 1, 1), false, false}, + + {year, 6, -lastDayInMonth5, date(year, 4, lastDayInMonth4), false, false}, + {year, 6, -lastDayInMonth5 + 1, date(year, 5, 1), false, false}, + {year, 6, -1, date(year, 5, lastDayInMonth5 - 1), false, false}, + {year, 6, 0, date(year, 5, lastDayInMonth5), false, false}, + {year, 6, 1, date(year, 6, 1), true, true}, + {year, 6, lastDayInMonth6 - 1 , date(year, 6, lastDayInMonth6 - 1), true, true}, + {year, 6, lastDayInMonth6, date(year, 6, lastDayInMonth6), date(year, 6, lastDayInMonth6), true}, + {year, 6, lastDayInMonth6 + 1, date(year, 7, 1), false, false}, + {year, 6, lastDayInMonth6 + lastDayInMonth7 , date(year, 7, lastDayInMonth7), false, false}, + {year, 6, lastDayInMonth6 + lastDayInMonth7 + 1, date(year, 8, 1), false, false}, + + {yearM1, 2, 1, date(yearM1, 2, 1), true, true}, + {yearM1, 2, lastDayInMonthM11 - 1, date(yearM1, 2, lastDayInMonthM11 - 1), true, true}, + {yearM1, 2, lastDayInMonthM11, date(yearM1, 2, lastDayInMonthM11), true, true}, + {yearM1, 2, lastDayInMonthM11 + 1, date(yearM1, 3, 1), date(yearM1, 2, lastDayInMonthM11), false}, + {yearM1, 2, lastDayInMonthM11 + 2, date(yearM1, 3, 2), false, false}, + // Bad dates + {1299, 12, 1, null, false, false}, + {1601, 1, 1, null, false, false}, + }; } - @Test(dataProvider="toString") - public void test_toString(ChronoLocalDate hijrahDate, String expected) { - assertEquals(hijrahDate.toString(), expected); + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_lenient(int y, int m, int d, HijrahDate expected, Object smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + + if (expected != null) { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + fail("Should have failed, returned: " + date); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_smart(int y, int m, int d, HijrahDate expected, Object smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (Boolean.TRUE.equals(smart)) { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else if (smart instanceof HijrahDate) { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, smart); + } else { + try { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed, returned: " + date); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_strict(int y, int m, int d, HijrahDate expected, Object smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (strict) { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected, "Resolved to incorrect date"); + assertEquals(fieldValues.size(), 0); + } else { + try { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed, returned: " + date); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_yd") + Object[][] data_resolve_yd() { + // Compute the number of days in various month and years so that test cases + // are not dependent on specific calendar data + // Month numbers are always 1..12 so they can be used literally + final int year = 1343; + final int yearP1 = year + 1; + final int yearP2 = year + 2; + final int yearM1 = year - 1; + final int yearM2 = year - 2; + final int lastDayInYear = dateYearDay(year, 1).lengthOfYear(); + final int lastDayInYearP1 = dateYearDay(yearP1, 1).lengthOfYear(); + final int lastDayInYearM1 = dateYearDay(yearM1, 1).lengthOfYear(); + final int lastDayInYearM2 = dateYearDay(yearM2, 1).lengthOfYear(); + + final int lastDayInMonthM1 = date(yearM1, 12, 1).lengthOfMonth(); + final int lastDayInMonthM2 = date(yearM1, 11, 1).lengthOfMonth(); + final int lastDayInMonthM11 = date(yearM1, 2, 1).lengthOfMonth(); + + final int lastDayInMonth1 = date(year, 1, 1).lengthOfMonth(); + final int lastDayInMonth2 = date(year, 2, 1).lengthOfMonth(); + final int lastDayInMonth4 = date(year, 4, 1).lengthOfMonth(); + final int lastDayInMonth5 = date(year, 5, 1).lengthOfMonth(); + final int lastDayInMonth6 = date(year, 6, 1).lengthOfMonth(); + final int lastDayInMonth7 = date(year, 7, 1).lengthOfMonth(); + + return new Object[][] { + {year, -lastDayInYearM1, dateYearDay(yearM2, lastDayInYearM2), false, false}, + {year, -lastDayInYearM1 + 1, date(yearM1, 1, 1), false, false}, + {year, -lastDayInMonthM1, date(yearM1, 11, lastDayInMonthM2), false, false}, + {year, -lastDayInMonthM1 + 1, date(yearM1, 12, 1), false, false}, + {year, -12, date(yearM1, 12, lastDayInMonthM1 - 12), false, false}, + {year, -1, date(yearM1, 12, lastDayInMonthM1 - 1), false, false}, + {year, 0, date(yearM1, 12, lastDayInMonthM1), false, false}, + {year, 1, date(year, 1, 1), true, true}, + {year, 2, date(year, 1, 2), true, true}, + {year, lastDayInMonth1, date(year, 1, lastDayInMonth1), true, true}, + {year, lastDayInMonth1 + 1, date(year, 2, 1), true, true}, + {year, lastDayInMonth1 + lastDayInMonth2 - 1, date(year, 2, lastDayInMonth2 - 1), true, true}, + {year, lastDayInMonth1 + lastDayInMonth2, date(year, 2, lastDayInMonth2), true, true}, + {year, lastDayInMonth1 + lastDayInMonth2 + 1, date(year, 3, 1), true, true}, + {year, lastDayInYear - 1, dateYearDay(year, lastDayInYear - 1), true, true}, + {year, lastDayInYear, dateYearDay(year, lastDayInYear), true, true}, + {year, lastDayInYear + 1, date(yearP1, 1, 1), false, false}, + {year, lastDayInYear + lastDayInYearP1, dateYearDay(yearP1, lastDayInYearP1), false, false}, + {year, lastDayInYear + lastDayInYearP1 + 1, date(yearP2, 1, 1), false, false}, + }; + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_lenient(int y, int d, HijrahDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_smart(int y, int d, HijrahDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (smart) { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed, returned date: " + date); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_strict(int y, int d, HijrahDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (strict) { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + HijrahDate date = HijrahChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed, returned date: " + date); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + private static HijrahDate date(int y, int m, int d) { + return HijrahDate.of(y, m, d); + } + + private static HijrahDate dateYearDay(int y, int doy) { + return HijrahChronology.INSTANCE.dateYearDay(y, doy); } //----------------------------------------------------------------------- @@ -343,5 +549,4 @@ public class TCKHijrahChronology { public void test_equals_false() { assertFalse(HijrahChronology.INSTANCE.equals(IsoChronology.INSTANCE)); } - } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKHijrahEra.java b/jdk/test/java/time/tck/java/time/chrono/TCKHijrahEra.java index 569eff0f3f4..23eaf3aaed8 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKHijrahEra.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKHijrahEra.java @@ -85,6 +85,8 @@ public class TCKHijrahEra { @Test(dataProvider="HijrahEras") public void test_valueOf(HijrahEra era , String eraName, int eraValue) { assertEquals(era.getValue(), eraValue); + + assertEquals(HijrahChronology.INSTANCE.eraOf(eraValue), era); assertEquals(HijrahEra.of(eraValue), era); assertEquals(HijrahEra.valueOf(eraName), era); } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKIsoChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKIsoChronology.java index b30c1ffbfcc..a69f556b5cd 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKIsoChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKIsoChronology.java @@ -278,91 +278,88 @@ public class TCKIsoChronology { @DataProvider(name = "resolve_yearOfEra") Object[][] data_resolve_yearOfEra() { return new Object[][] { - {-1, 2012, null, null, false, false}, - {0, 2012, null, -2011, true, true}, - {1, 2012, null, 2012, true, true}, - {2, 2012, null, null, false, false}, + // era only + {ResolverStyle.STRICT, -1, null, null, null, null}, + {ResolverStyle.SMART, -1, null, null, null, null}, + {ResolverStyle.LENIENT, -1, null, null, null, null}, - {null, 2012, null, 2012, true, null}, - {null, 2012, 2012, 2012, true, true}, - {null, 2012, -2011, -2011, true, true}, - {null, 2012, 2013, null, false, false}, - {null, 2012, -2013, null, false, false}, + {ResolverStyle.STRICT, 0, null, null, ChronoField.ERA, 0}, + {ResolverStyle.SMART, 0, null, null, ChronoField.ERA, 0}, + {ResolverStyle.LENIENT, 0, null, null, ChronoField.ERA, 0}, + + {ResolverStyle.STRICT, 1, null, null, ChronoField.ERA, 1}, + {ResolverStyle.SMART, 1, null, null, ChronoField.ERA, 1}, + {ResolverStyle.LENIENT, 1, null, null, ChronoField.ERA, 1}, + + {ResolverStyle.STRICT, 2, null, null, null, null}, + {ResolverStyle.SMART, 2, null, null, null, null}, + {ResolverStyle.LENIENT, 2, null, null, null, null}, + + // era and year-of-era + {ResolverStyle.STRICT, -1, 2012, null, null, null}, + {ResolverStyle.SMART, -1, 2012, null, null, null}, + {ResolverStyle.LENIENT, -1, 2012, null, null, null}, + + {ResolverStyle.STRICT, 0, 2012, null, ChronoField.YEAR, -2011}, + {ResolverStyle.SMART, 0, 2012, null, ChronoField.YEAR, -2011}, + {ResolverStyle.LENIENT, 0, 2012, null, ChronoField.YEAR, -2011}, + + {ResolverStyle.STRICT, 1, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.SMART, 1, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, 1, 2012, null, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, 2, 2012, null, null, null}, + {ResolverStyle.SMART, 2, 2012, null, null, null}, + {ResolverStyle.LENIENT, 2, 2012, null, null, null}, + + // year-of-era only + {ResolverStyle.STRICT, null, 2012, null, ChronoField.YEAR_OF_ERA, 2012}, + {ResolverStyle.SMART, null, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, null, 2012, null, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, null, Integer.MAX_VALUE, null, null, null}, + {ResolverStyle.SMART, null, Integer.MAX_VALUE, null, null, null}, + {ResolverStyle.LENIENT, null, Integer.MAX_VALUE, null, ChronoField.YEAR, Integer.MAX_VALUE}, + + // year-of-era and year + {ResolverStyle.STRICT, null, 2012, 2012, ChronoField.YEAR, 2012}, + {ResolverStyle.SMART, null, 2012, 2012, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, null, 2012, 2012, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, null, 2012, -2011, ChronoField.YEAR, -2011}, + {ResolverStyle.SMART, null, 2012, -2011, ChronoField.YEAR, -2011}, + {ResolverStyle.LENIENT, null, 2012, -2011, ChronoField.YEAR, -2011}, + + {ResolverStyle.STRICT, null, 2012, 2013, null, null}, + {ResolverStyle.SMART, null, 2012, 2013, null, null}, + {ResolverStyle.LENIENT, null, 2012, 2013, null, null}, + + {ResolverStyle.STRICT, null, 2012, -2013, null, null}, + {ResolverStyle.SMART, null, 2012, -2013, null, null}, + {ResolverStyle.LENIENT, null, 2012, -2013, null, null}, }; } @Test(dataProvider = "resolve_yearOfEra") - public void test_resolve_yearOfEra_lenient(Integer e, int yoe, Integer y, Integer expected, boolean smart, Boolean strict) { + public void test_resolve_yearOfEra(ResolverStyle style, Integer e, Integer yoe, Integer y, ChronoField field, Integer expected) { Map fieldValues = new HashMap<>(); if (e != null) { fieldValues.put(ChronoField.ERA, (long) e); } - fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); + if (yoe != null) { + fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); + } if (y != null) { fieldValues.put(ChronoField.YEAR, (long) y); } - if (smart) { - LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + if (field != null) { + LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, style); assertEquals(date, null); - assertEquals(fieldValues.get(ChronoField.YEAR), (Long) (long) expected); + assertEquals(fieldValues.get(field), (Long) expected.longValue()); assertEquals(fieldValues.size(), 1); } else { try { - IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); - fail("Should have failed"); - } catch (DateTimeException ex) { - // expected - } - } - } - - @Test(dataProvider = "resolve_yearOfEra") - public void test_resolve_yearOfEra_smart(Integer e, int yoe, Integer y, Integer expected, boolean smart, Boolean strict) { - Map fieldValues = new HashMap<>(); - if (e != null) { - fieldValues.put(ChronoField.ERA, (long) e); - } - fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); - if (y != null) { - fieldValues.put(ChronoField.YEAR, (long) y); - } - if (smart) { - LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); - assertEquals(date, null); - assertEquals(fieldValues.get(ChronoField.YEAR), (Long) (long) expected); - assertEquals(fieldValues.size(), 1); - } else { - try { - IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); - fail("Should have failed"); - } catch (DateTimeException ex) { - // expected - } - } - } - - @Test(dataProvider = "resolve_yearOfEra") - public void test_resolve_yearOfEra_strict(Integer e, int yoe, Integer y, Integer expected, boolean smart, Boolean strict) { - Map fieldValues = new HashMap<>(); - if (e != null) { - fieldValues.put(ChronoField.ERA, (long) e); - } - fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); - if (y != null) { - fieldValues.put(ChronoField.YEAR, (long) y); - } - if (strict == null) { - LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); - assertEquals(date, null); - assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), (Long) (long) yoe); - } else if (strict) { - LocalDate date = IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); - assertEquals(date, null); - assertEquals(fieldValues.get(ChronoField.YEAR), (Long) (long) expected); - assertEquals(fieldValues.size(), 1); - } else { - try { - IsoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + IsoChronology.INSTANCE.resolveDate(fieldValues, style); fail("Should have failed"); } catch (DateTimeException ex) { // expected @@ -381,6 +378,11 @@ public class TCKIsoChronology { {2012, 1, -30, date(2011, 12, 1), false, false}, {2012, 1, -12, date(2011, 12, 19), false, false}, {2012, 1, 1, date(2012, 1, 1), true, true}, + {2012, 1, 27, date(2012, 1, 27), true, true}, + {2012, 1, 28, date(2012, 1, 28), true, true}, + {2012, 1, 29, date(2012, 1, 29), true, true}, + {2012, 1, 30, date(2012, 1, 30), true, true}, + {2012, 1, 31, date(2012, 1, 31), true, true}, {2012, 1, 59, date(2012, 2, 28), false, false}, {2012, 1, 60, date(2012, 2, 29), false, false}, {2012, 1, 61, date(2012, 3, 1), false, false}, diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java index 7802e5bab52..e9d963c73af 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java @@ -57,12 +57,15 @@ package tck.java.time.chrono; import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; +import static java.time.temporal.ChronoField.EPOCH_DAY; import static java.time.temporal.ChronoField.ERA; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -84,10 +87,19 @@ import java.time.chrono.JapaneseDate; import java.time.chrono.JapaneseEra; import java.time.chrono.MinguoChronology; import java.time.chrono.MinguoDate; +import java.time.format.ResolverStyle; +import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; +import java.time.temporal.Temporal; import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalField; +import java.time.temporal.TemporalQuery; +import java.time.temporal.ValueRange; + +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import org.testng.Assert; import org.testng.annotations.DataProvider; @@ -155,59 +167,145 @@ public class TCKJapaneseChronology { } //----------------------------------------------------------------------- - // creation, toLocalDate() + // creation and cross-checks //----------------------------------------------------------------------- - @DataProvider(name="samples") - Object[][] data_samples() { + @DataProvider(name="createByEra") + Object[][] data_createByEra() { return new Object[][] { - {JapaneseChronology.INSTANCE.date(1, 1, 1), LocalDate.of(1, 1, 1)}, - {JapaneseChronology.INSTANCE.date(1, 1, 2), LocalDate.of(1, 1, 2)}, - {JapaneseChronology.INSTANCE.date(1, 1, 3), LocalDate.of(1, 1, 3)}, - - {JapaneseChronology.INSTANCE.date(2, 1, 1), LocalDate.of(2, 1, 1)}, - {JapaneseChronology.INSTANCE.date(3, 1, 1), LocalDate.of(3, 1, 1)}, - {JapaneseChronology.INSTANCE.date(3, 12, 6), LocalDate.of(3, 12, 6)}, - {JapaneseChronology.INSTANCE.date(4, 1, 1), LocalDate.of(4, 1, 1)}, - {JapaneseChronology.INSTANCE.date(4, 7, 3), LocalDate.of(4, 7, 3)}, - {JapaneseChronology.INSTANCE.date(4, 7, 4), LocalDate.of(4, 7, 4)}, - {JapaneseChronology.INSTANCE.date(5, 1, 1), LocalDate.of(5, 1, 1)}, - {JapaneseChronology.INSTANCE.date(1662, 3, 3), LocalDate.of(1662, 3, 3)}, - {JapaneseChronology.INSTANCE.date(1728, 10, 28), LocalDate.of(1728, 10, 28)}, - {JapaneseChronology.INSTANCE.date(1728, 10, 29), LocalDate.of(1728, 10, 29)}, - - {JapaneseChronology.INSTANCE.date(JapaneseEra.HEISEI, 1996 - YDIFF_HEISEI, 2, 29), LocalDate.of(1996, 2, 29)}, - {JapaneseChronology.INSTANCE.date(JapaneseEra.HEISEI, 2000 - YDIFF_HEISEI, 2, 29), LocalDate.of(2000, 2, 29)}, - {JapaneseChronology.INSTANCE.date(JapaneseEra.MEIJI, 1868 - YDIFF_MEIJI, 2, 29), LocalDate.of(1868, 2, 29)}, - {JapaneseChronology.INSTANCE.date(JapaneseEra.SHOWA, 1928 - YDIFF_SHOWA, 12, 25), LocalDate.of(1928, 12, 25)}, - {JapaneseChronology.INSTANCE.date(JapaneseEra.TAISHO, 1912 - YDIFF_TAISHO, 7, 30), LocalDate.of(1912, 7, 30)}, - - {JapaneseChronology.INSTANCE.dateYearDay(1996, 60), LocalDate.of(1996, 2, 29)}, - {JapaneseChronology.INSTANCE.dateYearDay(1868, 60), LocalDate.of(1868, 2, 29)}, - {JapaneseChronology.INSTANCE.dateYearDay(1928, 60), LocalDate.of(1928, 2, 29)}, - {JapaneseChronology.INSTANCE.dateYearDay(1912, 60), LocalDate.of(1912, 2, 29)}, - - {JapaneseDate.ofYearDay(1996, 60), LocalDate.of(1996, 2, 29)}, - {JapaneseDate.ofYearDay(1868, 60), LocalDate.of(1868, 2, 29)}, - {JapaneseDate.ofYearDay(1928, 60), LocalDate.of(1928, 2, 29)}, - {JapaneseDate.ofYearDay(1912, 60), LocalDate.of(1912, 2, 29)}, - - {JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.HEISEI, 1996 - YDIFF_HEISEI, 60), LocalDate.of(1996, 2, 29)}, - {JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.MEIJI, 1868 - YDIFF_MEIJI, 60), LocalDate.of(1868, 2, 29)}, - {JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.SHOWA, 1928 - YDIFF_SHOWA, 60), LocalDate.of(1928, 2, 29)}, -// {JapaneseChronology.INSTANCE.dateYearDay(JapaneseEra.TAISHO, 1916 - YDIFF_TAISHO, 60), LocalDate.of(1912, 2, 29)}, + {JapaneseEra.HEISEI, 1996 - YDIFF_HEISEI, 2, 29, 60, LocalDate.of(1996, 2, 29)}, + {JapaneseEra.HEISEI, 2000 - YDIFF_HEISEI, 2, 29, 60, LocalDate.of(2000, 2, 29)}, + {JapaneseEra.MEIJI, 1874 - YDIFF_MEIJI, 2, 28, 59, LocalDate.of(1874, 2, 28)}, + {JapaneseEra.SHOWA, 1928 - YDIFF_SHOWA, 12, 25, 360, LocalDate.of(1928, 12, 25)}, + {JapaneseEra.TAISHO, 1916 - YDIFF_TAISHO, 7, 30, 212, LocalDate.of(1916, 7, 30)}, + {JapaneseEra.MEIJI, 6, 1, 1, 1, LocalDate.of(1873, 1, 1)}, + {JapaneseEra.MEIJI, 45, 7, 29, 211, LocalDate.of(1912, 7, 29)}, + {JapaneseEra.TAISHO, 1, 7, 30, 1, LocalDate.of(1912, 7, 30)}, + {JapaneseEra.TAISHO, 15, 12, 24, 358, LocalDate.of(1926, 12, 24)}, + {JapaneseEra.SHOWA, 1, 12, 25, 1, LocalDate.of(1926, 12, 25)}, + {JapaneseEra.SHOWA, 64, 1, 7, 7, LocalDate.of(1989, 1, 7)}, + {JapaneseEra.HEISEI, 1, 1, 8, 1, LocalDate.of(1989, 1, 8)}, }; } - @Test(dataProvider="samples") - public void test_toLocalDate(JapaneseDate jdate, LocalDate iso) { - assertEquals(LocalDate.from(jdate), iso); + @Test(dataProvider="createByEra") + public void test_createEymd(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate dateByChronoFactory = JapaneseChronology.INSTANCE.date(era, yoe, moy, dom); + JapaneseDate dateByDateFactory = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(dateByChronoFactory, dateByDateFactory); + assertEquals(dateByChronoFactory.hashCode(), dateByDateFactory.hashCode()); } - @Test(dataProvider="samples") - public void test_fromCalendrical(JapaneseDate jdate, LocalDate iso) { - assertEquals(JapaneseChronology.INSTANCE.date(iso), jdate); + @Test(dataProvider="createByEra") + public void test_createEyd(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate dateByChronoFactory = JapaneseChronology.INSTANCE.dateYearDay(era, yoe, doy); + JapaneseDate dateByDateFactory = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(dateByChronoFactory, dateByDateFactory); + assertEquals(dateByChronoFactory.hashCode(), dateByDateFactory.hashCode()); } + @Test(dataProvider="createByEra") + public void test_createByEra_isEqual(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(test.isEqual(iso), true); + assertEquals(iso.isEqual(test), true); + } + + @Test(dataProvider="createByEra") + public void test_createByEra_chronologyTemporalFactory(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(IsoChronology.INSTANCE.date(test), iso); + assertEquals(JapaneseChronology.INSTANCE.date(iso), test); + } + + @Test(dataProvider="createByEra") + public void test_createByEra_dateFrom(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(LocalDate.from(test), iso); + assertEquals(JapaneseDate.from(iso), test); + } + + @Test(dataProvider="createByEra") + public void test_createByEra_query(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(test.query(TemporalQuery.localDate()), iso); + } + + @Test(dataProvider="createByEra") + public void test_createByEra_epochDay(JapaneseEra era, int yoe, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(era, yoe, moy, dom); + assertEquals(test.getLong(EPOCH_DAY), iso.getLong(EPOCH_DAY)); + assertEquals(test.toEpochDay(), iso.toEpochDay()); + } + + //----------------------------------------------------------------------- + @DataProvider(name="createByProleptic") + Object[][] data_createByProleptic() { + return new Object[][] { + {1928, 2, 28, 59, LocalDate.of(1928, 2, 28)}, + {1928, 2, 29, 60, LocalDate.of(1928, 2, 29)}, + + {1873, 9, 7, 250, LocalDate.of(1873, 9, 7)}, + {1873, 9, 8, 251, LocalDate.of(1873, 9, 8)}, + {1912, 7, 29, 211, LocalDate.of(1912, 7, 29)}, + {1912, 7, 30, 212, LocalDate.of(1912, 7, 30)}, + {1926, 12, 24, 358, LocalDate.of(1926, 12, 24)}, + {1926, 12, 25, 359, LocalDate.of(1926, 12, 25)}, + {1989, 1, 7, 7, LocalDate.of(1989, 1, 7)}, + {1989, 1, 8, 8, LocalDate.of(1989, 1, 8)}, + }; + } + + @Test(dataProvider="createByProleptic") + public void test_createYmd(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate dateByChronoFactory = JapaneseChronology.INSTANCE.date(y, moy, dom); + JapaneseDate dateByDateFactory = JapaneseDate.of(y, moy, dom); + assertEquals(dateByChronoFactory, dateByDateFactory); + assertEquals(dateByChronoFactory.hashCode(), dateByDateFactory.hashCode()); + } + + @Test(dataProvider="createByProleptic") + public void test_createYd(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate dateByChronoFactory = JapaneseChronology.INSTANCE.dateYearDay(y, doy); + JapaneseDate dateByDateFactory = JapaneseDate.of(y, moy, dom); + assertEquals(dateByChronoFactory, dateByDateFactory); + assertEquals(dateByChronoFactory.hashCode(), dateByDateFactory.hashCode()); + } + + @Test(dataProvider="createByProleptic") + public void test_createByProleptic_isEqual(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(y, moy, dom); + assertEquals(test.isEqual(iso), true); + assertEquals(iso.isEqual(test), true); + } + + @Test(dataProvider="createByProleptic") + public void test_createByProleptic_chronologyTemporalFactory(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(y, moy, dom); + assertEquals(IsoChronology.INSTANCE.date(test), iso); + assertEquals(JapaneseChronology.INSTANCE.date(iso), test); + } + + @Test(dataProvider="createByProleptic") + public void test_createByProleptic_dateFrom(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(y, moy, dom); + assertEquals(LocalDate.from(test), iso); + assertEquals(JapaneseDate.from(iso), test); + } + + @Test(dataProvider="createByProleptic") + public void test_createByProleptic_query(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(y, moy, dom); + assertEquals(test.query(TemporalQuery.localDate()), iso); + } + + @Test(dataProvider="createByProleptic") + public void test_createByProleptic_epochDay(int y, int moy, int dom, int doy, LocalDate iso) { + JapaneseDate test = JapaneseDate.of(y, moy, dom); + assertEquals(test.getLong(EPOCH_DAY), iso.getLong(EPOCH_DAY)); + assertEquals(test.toEpochDay(), iso.toEpochDay()); + } + + //----------------------------------------------------------------------- @Test public void test_dateNow(){ assertEquals(JapaneseChronology.INSTANCE.dateNow(), JapaneseDate.now()) ; @@ -228,27 +326,30 @@ public class TCKJapaneseChronology { assertEquals(JapaneseChronology.INSTANCE.dateNow(ZoneId.of(ZoneOffset.UTC.getId())), JapaneseChronology.INSTANCE.dateNow(Clock.systemUTC())) ; } + //----------------------------------------------------------------------- @DataProvider(name="badDates") Object[][] data_badDates() { return new Object[][] { - {1728, 0, 0}, + {1928, 0, 0}, - {1728, -1, 1}, - {1728, 0, 1}, - {1728, 14, 1}, - {1728, 15, 1}, + {1928, -1, 1}, + {1928, 0, 1}, + {1928, 14, 1}, + {1928, 15, 1}, - {1728, 1, -1}, - {1728, 1, 0}, - {1728, 1, 32}, + {1928, 1, -1}, + {1928, 1, 0}, + {1928, 1, 32}, - {1728, 12, -1}, - {1728, 12, 0}, - {1728, 12, 32}, + {1928, 12, -1}, + {1928, 12, 0}, + {1928, 12, 32}, {1725, 2, 29}, {500, 2, 29}, {2100, 2, 29}, + + {1872, 12, 31}, // Last day of MEIJI 5 }; } @@ -266,8 +367,8 @@ public class TCKJapaneseChronology { {2, JapaneseEra.HEISEI, 1, 1 + YDIFF_HEISEI, false}, {2, JapaneseEra.HEISEI, 100, 100 + YDIFF_HEISEI, true}, - {-1, JapaneseEra.MEIJI, 1, 1 + YDIFF_MEIJI, true}, - {-1, JapaneseEra.MEIJI, 4, 4 + YDIFF_MEIJI, false}, + {-1, JapaneseEra.MEIJI, 9, 9 + YDIFF_MEIJI, true}, + {-1, JapaneseEra.MEIJI, 10, 10 + YDIFF_MEIJI, false}, {1, JapaneseEra.SHOWA, 1, 1 + YDIFF_SHOWA, false}, {1, JapaneseEra.SHOWA, 7, 7 + YDIFF_SHOWA, true}, @@ -279,12 +380,24 @@ public class TCKJapaneseChronology { @Test(dataProvider="prolepticYear") public void test_prolepticYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { - Era eraObj = JapaneseChronology.INSTANCE.eraOf(eraValue) ; + Era eraObj = JapaneseChronology.INSTANCE.eraOf(eraValue); assertTrue(JapaneseChronology.INSTANCE.eras().contains(eraObj)); assertEquals(eraObj, era); assertEquals(JapaneseChronology.INSTANCE.prolepticYear(era, yearOfEra), expectedProlepticYear); - assertEquals(JapaneseChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear) ; - assertEquals(JapaneseChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear).isLeap()) ; + } + + @Test(dataProvider="prolepticYear") + public void test_isLeapYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { + assertEquals(JapaneseChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear); + assertEquals(JapaneseChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear).isLeap()); + + JapaneseDate jdate = JapaneseDate.now(); + jdate = jdate.with(ChronoField.YEAR, expectedProlepticYear).with(ChronoField.MONTH_OF_YEAR, 2); + if (isLeapYear) { + assertEquals(jdate.lengthOfMonth(), 29); + } else { + assertEquals(jdate.lengthOfMonth(), 28); + } } @DataProvider(name="prolepticYearError") @@ -327,15 +440,6 @@ public class TCKJapaneseChronology { } catch (ClassCastException cex) { ; // ignore expected exception } - - try { - @SuppressWarnings("unused") - JapaneseDate jdate = JapaneseDate.of(era, 1, 1, 1); - fail("JapaneseDate.of did not throw ClassCastException for Era: " + era); - } catch (ClassCastException cex) { - ; // ignore expected exception - } - try { @SuppressWarnings("unused") int year = JapaneseChronology.INSTANCE.prolepticYear(era, 1); @@ -388,16 +492,16 @@ public class TCKJapaneseChronology { //----------------------------------------------------------------------- @Test public void test_adjust1() { - JapaneseDate base = JapaneseChronology.INSTANCE.date(1728, 10, 29); + JapaneseDate base = JapaneseChronology.INSTANCE.date(1928, 10, 29); JapaneseDate test = base.with(TemporalAdjuster.lastDayOfMonth()); - assertEquals(test, JapaneseChronology.INSTANCE.date(1728, 10, 31)); + assertEquals(test, JapaneseChronology.INSTANCE.date(1928, 10, 31)); } @Test public void test_adjust2() { - JapaneseDate base = JapaneseChronology.INSTANCE.date(1728, 12, 2); + JapaneseDate base = JapaneseChronology.INSTANCE.date(1928, 12, 2); JapaneseDate test = base.with(TemporalAdjuster.lastDayOfMonth()); - assertEquals(test, JapaneseChronology.INSTANCE.date(1728, 12, 31)); + assertEquals(test, JapaneseChronology.INSTANCE.date(1928, 12, 31)); } //----------------------------------------------------------------------- @@ -405,14 +509,14 @@ public class TCKJapaneseChronology { //----------------------------------------------------------------------- @Test public void test_adjust_toLocalDate() { - JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1726, 1, 4); + JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1926, 1, 4); JapaneseDate test = jdate.with(LocalDate.of(2012, 7, 6)); assertEquals(test, JapaneseChronology.INSTANCE.date(2012, 7, 6)); } @Test(expectedExceptions=DateTimeException.class) public void test_adjust_toMonth() { - JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1726, 1, 4); + JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1926, 1, 4); jdate.with(Month.APRIL); } @@ -421,16 +525,16 @@ public class TCKJapaneseChronology { //----------------------------------------------------------------------- @Test public void test_LocalDate_adjustToJapaneseDate() { - JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1728, 10, 29); + JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1928, 10, 29); LocalDate test = LocalDate.MIN.with(jdate); - assertEquals(test, LocalDate.of(1728, 10, 29)); + assertEquals(test, LocalDate.of(1928, 10, 29)); } @Test public void test_LocalDateTime_adjustToJapaneseDate() { - JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1728, 10, 29); + JapaneseDate jdate = JapaneseChronology.INSTANCE.date(1928, 10, 29); LocalDateTime test = LocalDateTime.MIN.with(jdate); - assertEquals(test, LocalDateTime.of(1728, 10, 29, 0, 0)); + assertEquals(test, LocalDateTime.of(1928, 10, 29, 0, 0)); } //----------------------------------------------------------------------- @@ -439,7 +543,6 @@ public class TCKJapaneseChronology { @DataProvider(name="japaneseEras") Object[][] data_japanseseEras() { return new Object[][] { - { JapaneseEra.SEIREKI, -999, "Seireki"}, { JapaneseEra.MEIJI, -1, "Meiji"}, { JapaneseEra.TAISHO, 0, "Taisho"}, { JapaneseEra.SHOWA, 1, "Showa"}, @@ -512,7 +615,7 @@ public class TCKJapaneseChronology { public void test_periodUntilDate() { JapaneseDate mdate1 = JapaneseDate.of(1970, 1, 1); JapaneseDate mdate2 = JapaneseDate.of(1971, 2, 2); - Period period = mdate1.periodUntil(mdate2); + Period period = mdate1.until(mdate2); assertEquals(period, Period.of(1, 1, 1)); } @@ -520,7 +623,7 @@ public class TCKJapaneseChronology { public void test_periodUntilUnit() { JapaneseDate mdate1 = JapaneseDate.of(1970, 1, 1); JapaneseDate mdate2 = JapaneseDate.of(1971, 2, 2); - long months = mdate1.periodUntil(mdate2, ChronoUnit.MONTHS); + long months = mdate1.until(mdate2, ChronoUnit.MONTHS); assertEquals(months, 13); } @@ -529,22 +632,49 @@ public class TCKJapaneseChronology { JapaneseDate mdate1 = JapaneseDate.of(1970, 1, 1); JapaneseDate mdate2 = JapaneseDate.of(1971, 2, 2); MinguoDate ldate2 = MinguoChronology.INSTANCE.date(mdate2); - Period period = mdate1.periodUntil(ldate2); + Period period = mdate1.until(ldate2); assertEquals(period, Period.of(1, 1, 1)); } + //----------------------------------------------------------------------- + // JapaneseChronology.dateYearDay, getDayOfYear + //----------------------------------------------------------------------- + @Test + public void test_getDayOfYear() { + // Test all the Eras + for (JapaneseEra era : JapaneseEra.values()) { + int firstYear = (era == JapaneseEra.MEIJI) ? 6 : 1; // Until Era supports range(YEAR_OF_ERA) + JapaneseDate hd1 = JapaneseChronology.INSTANCE.dateYearDay(era, firstYear, 1); + ValueRange range = hd1.range(DAY_OF_YEAR); + assertEquals(range.getMaximum(), hd1.lengthOfYear(), "lengthOfYear should match range.getMaximum()"); + + for (int i = 1; i <= hd1.lengthOfYear(); i++) { + JapaneseDate hd = JapaneseChronology.INSTANCE.dateYearDay(era, firstYear, i); + int doy = hd.get(DAY_OF_YEAR); + assertEquals(doy, i, "get(DAY_OF_YEAR) incorrect for " + i + ", of date: " + hd); + } + } + } + + @Test + public void test_withDayOfYear() { + JapaneseDate hd = JapaneseChronology.INSTANCE.dateYearDay(1990, 1); + for (int i = 1; i <= hd.lengthOfYear(); i++) { + JapaneseDate hd2 = hd.with(DAY_OF_YEAR, i); + int doy = hd2.get(DAY_OF_YEAR); + assertEquals(doy, i, "with(DAY_OF_YEAR) incorrect for " + i + " " + hd2); + } + } + //----------------------------------------------------------------------- // toString() //----------------------------------------------------------------------- @DataProvider(name="toString") Object[][] data_toString() { return new Object[][] { - {JapaneseChronology.INSTANCE.date(0001, 1, 1), "Japanese 0001-01-01"}, - {JapaneseChronology.INSTANCE.date(1728, 10, 28), "Japanese 1728-10-28"}, - {JapaneseChronology.INSTANCE.date(1728, 10, 29), "Japanese 1728-10-29"}, - {JapaneseChronology.INSTANCE.date(1727, 12, 5), "Japanese 1727-12-05"}, - {JapaneseChronology.INSTANCE.date(1727, 12, 6), "Japanese 1727-12-06"}, - {JapaneseChronology.INSTANCE.date(1868, 9, 8), "Japanese Meiji 1-09-08"}, + {JapaneseChronology.INSTANCE.date(1873, 12, 5), "Japanese Meiji 6-12-05"}, + {JapaneseChronology.INSTANCE.date(1873, 12, 6), "Japanese Meiji 6-12-06"}, + {JapaneseChronology.INSTANCE.date(1873, 9, 8), "Japanese Meiji 6-09-08"}, {JapaneseChronology.INSTANCE.date(1912, 7, 29), "Japanese Meiji 45-07-29"}, {JapaneseChronology.INSTANCE.date(1912, 7, 30), "Japanese Taisho 1-07-30"}, {JapaneseChronology.INSTANCE.date(1926, 12, 24), "Japanese Taisho 15-12-24"}, @@ -573,4 +703,476 @@ public class TCKJapaneseChronology { assertFalse(JapaneseChronology.INSTANCE.equals(IsoChronology.INSTANCE)); } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_styleByEra") + Object[][] data_resolve_styleByEra() { + Object[][] result = new Object[ResolverStyle.values().length * JapaneseEra.values().length][]; + int i = 0; + for (ResolverStyle style : ResolverStyle.values()) { + for (JapaneseEra era : JapaneseEra.values()) { + result[i++] = new Object[] {style, era}; + } + } + return result; + } + + @Test(dataProvider = "resolve_styleByEra") + public void test_resolve_yearOfEra_eraOnly_valid(ResolverStyle style, JapaneseEra era) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.ERA), (Long) (long) era.getValue()); + assertEquals(fieldValues.size(), 1); + } + + @Test(dataProvider = "resolve_styleByEra") + public void test_resolve_yearOfEra_eraAndYearOfEraOnly_valid(ResolverStyle style, JapaneseEra era) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + fieldValues.put(ChronoField.YEAR_OF_ERA, 1L); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.ERA), (Long) (long) era.getValue()); + assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), (Long) 1L); + assertEquals(fieldValues.size(), 2); + } + + @Test(dataProvider = "resolve_styleByEra") + public void test_resolve_yearOfEra_eraAndYearOnly_valid(ResolverStyle style, JapaneseEra era) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + fieldValues.put(ChronoField.YEAR, 1L); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.ERA), (Long) (long) era.getValue()); + assertEquals(fieldValues.get(ChronoField.YEAR), (Long) 1L); + assertEquals(fieldValues.size(), 2); + } + + @DataProvider(name = "resolve_styles") + Object[][] data_resolve_styles() { + Object[][] result = new Object[ResolverStyle.values().length][]; + int i = 0; + for (ResolverStyle style : ResolverStyle.values()) { + result[i++] = new Object[] {style}; + } + return result; + } + + @Test(dataProvider = "resolve_styles") + public void test_resolve_yearOfEra_yearOfEraOnly_valid(ResolverStyle style) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR_OF_ERA, 1L); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), (Long) 1L); + assertEquals(fieldValues.size(), 1); + } + + @Test(dataProvider = "resolve_styles") + public void test_resolve_yearOfEra_yearOfEraAndYearOnly_valid(ResolverStyle style) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR_OF_ERA, 1L); + fieldValues.put(ChronoField.YEAR, 2012L); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(ChronoField.YEAR_OF_ERA), (Long) 1L); + assertEquals(fieldValues.get(ChronoField.YEAR), (Long) 2012L); + assertEquals(fieldValues.size(), 2); + } + + public void test_resolve_yearOfEra_eraOnly_invalidTooSmall() { + for (ResolverStyle style : ResolverStyle.values()) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, JapaneseEra.MEIJI.getValue() - 1L); + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + fail("Should have failed: " + style); + } catch (DateTimeException ex) { + // expected + } + } + } + + public void test_resolve_yearOfEra_eraOnly_invalidTooLarge() { + for (ResolverStyle style : ResolverStyle.values()) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, JapaneseEra.values()[JapaneseEra.values().length - 1].getValue() + 1L); + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + fail("Should have failed: " + style); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_ymd") + Object[][] data_resolve_ymd() { + return new Object[][] { + {2012, 1, -365, date(2010, 12, 31), false, false}, + {2012, 1, -364, date(2011, 1, 1), false, false}, + {2012, 1, -31, date(2011, 11, 30), false, false}, + {2012, 1, -30, date(2011, 12, 1), false, false}, + {2012, 1, -12, date(2011, 12, 19), false, false}, + {2012, 1, 1, date(2012, 1, 1), true, true}, + {2012, 1, 59, date(2012, 2, 28), false, false}, + {2012, 1, 60, date(2012, 2, 29), false, false}, + {2012, 1, 61, date(2012, 3, 1), false, false}, + {2012, 1, 365, date(2012, 12, 30), false, false}, + {2012, 1, 366, date(2012, 12, 31), false, false}, + {2012, 1, 367, date(2013, 1, 1), false, false}, + {2012, 1, 367 + 364, date(2013, 12, 31), false, false}, + {2012, 1, 367 + 365, date(2014, 1, 1), false, false}, + + {2012, 2, 1, date(2012, 2, 1), true, true}, + {2012, 2, 28, date(2012, 2, 28), true, true}, + {2012, 2, 29, date(2012, 2, 29), true, true}, + {2012, 2, 30, date(2012, 3, 1), date(2012, 2, 29), false}, + {2012, 2, 31, date(2012, 3, 2), date(2012, 2, 29), false}, + {2012, 2, 32, date(2012, 3, 3), false, false}, + + {2012, -12, 1, date(2010, 12, 1), false, false}, + {2012, -11, 1, date(2011, 1, 1), false, false}, + {2012, -1, 1, date(2011, 11, 1), false, false}, + {2012, 0, 1, date(2011, 12, 1), false, false}, + {2012, 1, 1, date(2012, 1, 1), true, true}, + {2012, 12, 1, date(2012, 12, 1), true, true}, + {2012, 13, 1, date(2013, 1, 1), false, false}, + {2012, 24, 1, date(2013, 12, 1), false, false}, + {2012, 25, 1, date(2014, 1, 1), false, false}, + + {2012, 6, -31, date(2012, 4, 30), false, false}, + {2012, 6, -30, date(2012, 5, 1), false, false}, + {2012, 6, -1, date(2012, 5, 30), false, false}, + {2012, 6, 0, date(2012, 5, 31), false, false}, + {2012, 6, 1, date(2012, 6, 1), true, true}, + {2012, 6, 30, date(2012, 6, 30), true, true}, + {2012, 6, 31, date(2012, 7, 1), date(2012, 6, 30), false}, + {2012, 6, 61, date(2012, 7, 31), false, false}, + {2012, 6, 62, date(2012, 8, 1), false, false}, + + {2011, 2, 1, date(2011, 2, 1), true, true}, + {2011, 2, 28, date(2011, 2, 28), true, true}, + {2011, 2, 29, date(2011, 3, 1), date(2011, 2, 28), false}, + {2011, 2, 30, date(2011, 3, 2), date(2011, 2, 28), false}, + {2011, 2, 31, date(2011, 3, 3), date(2011, 2, 28), false}, + {2011, 2, 32, date(2011, 3, 4), false, false}, + }; + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_lenient(int y, int m, int d, JapaneseDate expected, Object smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_smart(int y, int m, int d, JapaneseDate expected, Object smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (Boolean.TRUE.equals(smart)) { + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else if (smart instanceof JapaneseDate) { + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, smart); + } else { + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_strict(int y, int m, int d, JapaneseDate expected, Object smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (strict) { + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_yd") + Object[][] data_resolve_yd() { + return new Object[][] { + {2012, -365, date(2010, 12, 31), false, false}, + {2012, -364, date(2011, 1, 1), false, false}, + {2012, -31, date(2011, 11, 30), false, false}, + {2012, -30, date(2011, 12, 1), false, false}, + {2012, -12, date(2011, 12, 19), false, false}, + {2012, -1, date(2011, 12, 30), false, false}, + {2012, 0, date(2011, 12, 31), false, false}, + {2012, 1, date(2012, 1, 1), true, true}, + {2012, 2, date(2012, 1, 2), true, true}, + {2012, 31, date(2012, 1, 31), true, true}, + {2012, 32, date(2012, 2, 1), true, true}, + {2012, 59, date(2012, 2, 28), true, true}, + {2012, 60, date(2012, 2, 29), true, true}, + {2012, 61, date(2012, 3, 1), true, true}, + {2012, 365, date(2012, 12, 30), true, true}, + {2012, 366, date(2012, 12, 31), true, true}, + {2012, 367, date(2013, 1, 1), false, false}, + {2012, 367 + 364, date(2013, 12, 31), false, false}, + {2012, 367 + 365, date(2014, 1, 1), false, false}, + + {2011, 59, date(2011, 2, 28), true, true}, + {2011, 60, date(2011, 3, 1), true, true}, + }; + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_lenient(int y, int d, JapaneseDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_smart(int y, int d, JapaneseDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (smart) { + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_strict(int y, int d, JapaneseDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (strict) { + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_eymd") + Object[][] data_resolve_eymd() { + return new Object[][] { + // lenient + {ResolverStyle.LENIENT, JapaneseEra.HEISEI, 1, 1, 1, date(1989, 1, 1)}, // SHOWA, not HEISEI + {ResolverStyle.LENIENT, JapaneseEra.HEISEI, 1, 1, 7, date(1989, 1, 7)}, // SHOWA, not HEISEI + {ResolverStyle.LENIENT, JapaneseEra.HEISEI, 1, 1, 8, date(1989, 1, 8)}, + {ResolverStyle.LENIENT, JapaneseEra.HEISEI, 1, 12, 31, date(1989, 12, 31)}, + {ResolverStyle.LENIENT, JapaneseEra.HEISEI, 2, 1, 1, date(1990, 1, 1)}, + + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 1, date(1989, 1, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 7, date(1989, 1, 7)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 8, date(1989, 1, 8)}, // HEISEI, not SHOWA + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 12, 31, date(1989, 12, 31)}, // HEISEI, not SHOWA + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 65, 1, 1, date(1990, 1, 1)}, // HEISEI, not SHOWA + + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, -366, date(1987, 12, 31)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, -365, date(1988, 1, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, -31, date(1988, 11, 30)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, -30, date(1988, 12, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 0, date(1988, 12, 31)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 1, date(1989, 1, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 27, date(1989, 1, 27)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 28, date(1989, 1, 28)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 29, date(1989, 1, 29)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 30, date(1989, 1, 30)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 31, date(1989, 1, 31)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 32, date(1989, 2, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 58, date(1989, 2, 27)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 59, date(1989, 2, 28)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 60, date(1989, 3, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 365, date(1989, 12, 31)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 1, 366, date(1990, 1, 1)}, + + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 1, date(1988, 1, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 31, date(1988, 1, 31)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 32, date(1988, 2, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 58, date(1988, 2, 27)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 59, date(1988, 2, 28)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 60, date(1988, 2, 29)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 1, 61, date(1988, 3, 1)}, + + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 2, 1, date(1989, 2, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 2, 28, date(1989, 2, 28)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 64, 2, 29, date(1989, 3, 1)}, + + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 2, 1, date(1988, 2, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 2, 28, date(1988, 2, 28)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 2, 29, date(1988, 2, 29)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 63, 2, 30, date(1988, 3, 1)}, + + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 62, -11, 1, date(1986, 1, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 62, -1, 1, date(1986, 11, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 62, 0, 1, date(1986, 12, 1)}, + {ResolverStyle.LENIENT, JapaneseEra.SHOWA, 62, 13, 1, date(1988, 1, 1)}, + + // smart + {ResolverStyle.SMART, JapaneseEra.HEISEI, 0, 1, 1, null}, + {ResolverStyle.SMART, JapaneseEra.HEISEI, 1, 1, 1, date(1989, 1, 1)}, // SHOWA, not HEISEI + {ResolverStyle.SMART, JapaneseEra.HEISEI, 1, 1, 7, date(1989, 1, 7)}, // SHOWA, not HEISEI + {ResolverStyle.SMART, JapaneseEra.HEISEI, 1, 1, 8, date(1989, 1, 8)}, + {ResolverStyle.SMART, JapaneseEra.HEISEI, 1, 12, 31, date(1989, 12, 31)}, + {ResolverStyle.SMART, JapaneseEra.HEISEI, 2, 1, 1, date(1990, 1, 1)}, + + {ResolverStyle.SMART, JapaneseEra.SHOWA, 64, 1, 1, date(1989, 1, 1)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 64, 1, 7, date(1989, 1, 7)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 64, 1, 8, date(1989, 1, 8)}, // HEISEI, not SHOWA + {ResolverStyle.SMART, JapaneseEra.SHOWA, 64, 12, 31, date(1989, 12, 31)}, // HEISEI, not SHOWA + {ResolverStyle.SMART, JapaneseEra.SHOWA, 65, 1, 1, null}, // HEISEI, not SHOWA + + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 0, null}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 1, date(1987, 1, 1)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 27, date(1987, 1, 27)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 28, date(1987, 1, 28)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 29, date(1987, 1, 29)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 30, date(1987, 1, 30)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 31, date(1987, 1, 31)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 1, 32, null}, + + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 0, null}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 1, date(1987, 2, 1)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 27, date(1987, 2, 27)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 28, date(1987, 2, 28)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 29, date(1987, 2, 28)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 30, date(1987, 2, 28)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 31, date(1987, 2, 28)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 2, 32, null}, + + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 0, null}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 1, date(1988, 2, 1)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 27, date(1988, 2, 27)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 28, date(1988, 2, 28)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 29, date(1988, 2, 29)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 30, date(1988, 2, 29)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 31, date(1988, 2, 29)}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 63, 2, 32, null}, + + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, -12, 1, null}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, -1, 1, null}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 0, 1, null}, + {ResolverStyle.SMART, JapaneseEra.SHOWA, 62, 13, 1, null}, + + // strict + {ResolverStyle.STRICT, JapaneseEra.HEISEI, 0, 1, 1, null}, + {ResolverStyle.STRICT, JapaneseEra.HEISEI, 1, 1, 1, null}, // SHOWA, not HEISEI + {ResolverStyle.STRICT, JapaneseEra.HEISEI, 1, 1, 7, null}, // SHOWA, not HEISEI + {ResolverStyle.STRICT, JapaneseEra.HEISEI, 1, 1, 8, date(1989, 1, 8)}, + {ResolverStyle.STRICT, JapaneseEra.HEISEI, 1, 12, 31, date(1989, 12, 31)}, + {ResolverStyle.STRICT, JapaneseEra.HEISEI, 2, 1, 1, date(1990, 1, 1)}, + + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 64, 1, 1, date(1989, 1, 1)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 64, 1, 7, date(1989, 1, 7)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 64, 1, 8, null}, // HEISEI, not SHOWA + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 64, 12, 31, null}, // HEISEI, not SHOWA + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 65, 1, 1, null}, // HEISEI, not SHOWA + + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 0, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 1, date(1987, 1, 1)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 27, date(1987, 1, 27)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 28, date(1987, 1, 28)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 29, date(1987, 1, 29)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 30, date(1987, 1, 30)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 31, date(1987, 1, 31)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 1, 32, null}, + + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 0, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 1, date(1987, 2, 1)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 27, date(1987, 2, 27)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 28, date(1987, 2, 28)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 29, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 30, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 31, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 2, 32, null}, + + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 0, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 1, date(1988, 2, 1)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 27, date(1988, 2, 27)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 28, date(1988, 2, 28)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 29, date(1988, 2, 29)}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 30, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 31, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 63, 2, 32, null}, + + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, -12, 1, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, -1, 1, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 0, 1, null}, + {ResolverStyle.STRICT, JapaneseEra.SHOWA, 62, 13, 1, null}, + }; + } + + @Test(dataProvider = "resolve_eymd") + public void test_resolve_eymd(ResolverStyle style, JapaneseEra era, int yoe, int m, int d, JapaneseDate expected) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.ERA, (long) era.getValue()); + fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (expected != null) { + JapaneseDate date = JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + JapaneseChronology.INSTANCE.resolveDate(fieldValues, style); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + private static JapaneseDate date(int y, int m, int d) { + return JapaneseDate.of(y, m, d); + } + } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java b/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java index 1aa1df360f6..de83e1d3bc3 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKJapaneseEra.java @@ -81,7 +81,6 @@ public class TCKJapaneseEra { {JapaneseEra.SHOWA, "Showa", 1}, {JapaneseEra.TAISHO, "Taisho", 0}, {JapaneseEra.MEIJI, "Meiji", -1}, - {JapaneseEra.SEIREKI, "Seireki", -999}, }; } @@ -112,8 +111,8 @@ public class TCKJapaneseEra { public void test_range() { // eras may be added after release for (JapaneseEra era : JapaneseEra.values()) { - assertEquals(era.range(ERA).getMinimum(), -999); - assertEquals(era.range(ERA).getLargestMinimum(), -999); + assertEquals(era.range(ERA).getMinimum(), -1); + assertEquals(era.range(ERA).getLargestMinimum(), -1); assertEquals(era.range(ERA).getSmallestMaximum(), era.range(ERA).getMaximum()); assertEquals(era.range(ERA).getMaximum() >= 2, true); } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java index cad29d76f29..50ddf70cb3e 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java @@ -58,6 +58,7 @@ package tck.java.time.chrono; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -83,12 +84,19 @@ import java.time.chrono.JapaneseDate; import java.time.chrono.MinguoChronology; import java.time.chrono.MinguoDate; import java.time.chrono.MinguoEra; +import java.time.chrono.MinguoChronology; +import java.time.chrono.MinguoDate; import java.time.chrono.ThaiBuddhistChronology; import java.time.chrono.ThaiBuddhistDate; +import java.time.format.ResolverStyle; +import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalField; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.testng.Assert; import org.testng.annotations.DataProvider; @@ -162,6 +170,18 @@ public class TCKMinguoChronology { @Test(dataProvider="samples") public void test_fromCalendrical(MinguoDate minguo, LocalDate iso) { assertEquals(MinguoChronology.INSTANCE.date(iso), minguo); + assertEquals(MinguoDate.from(iso), minguo); + } + + @Test(dataProvider="samples") + public void test_isEqual(MinguoDate minguo, LocalDate iso) { + assertTrue(minguo.isEqual(iso)); + } + + @Test(dataProvider="samples") + public void test_date_equals(MinguoDate minguo, LocalDate iso) { + assertFalse(minguo.equals(iso)); + assertNotEquals(minguo.hashCode(), iso.hashCode()); } @Test @@ -276,12 +296,24 @@ public class TCKMinguoChronology { @Test(dataProvider="prolepticYear") public void test_prolepticYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { - Era eraObj = MinguoChronology.INSTANCE.eraOf(eraValue) ; + Era eraObj = MinguoChronology.INSTANCE.eraOf(eraValue); assertTrue(MinguoChronology.INSTANCE.eras().contains(eraObj)); assertEquals(eraObj, era); assertEquals(MinguoChronology.INSTANCE.prolepticYear(era, yearOfEra), expectedProlepticYear); - assertEquals(MinguoChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear) ; - assertEquals(MinguoChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear + YDIFF).isLeap()) ; + } + + @Test(dataProvider="prolepticYear") + public void test_isLeapYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { + assertEquals(MinguoChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear); + assertEquals(MinguoChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear + YDIFF).isLeap()); + + MinguoDate minguo = MinguoDate.now(); + minguo = minguo.with(ChronoField.YEAR, expectedProlepticYear).with(ChronoField.MONTH_OF_YEAR, 2); + if (isLeapYear) { + assertEquals(minguo.lengthOfMonth(), 29); + } else { + assertEquals(minguo.lengthOfMonth(), 28); + } } //----------------------------------------------------------------------- @@ -467,7 +499,7 @@ public class TCKMinguoChronology { public void test_periodUntilDate() { MinguoDate mdate1 = MinguoDate.of(1970, 1, 1); MinguoDate mdate2 = MinguoDate.of(1971, 2, 2); - Period period = mdate1.periodUntil(mdate2); + Period period = mdate1.until(mdate2); assertEquals(period, Period.of(1, 1, 1)); } @@ -475,7 +507,7 @@ public class TCKMinguoChronology { public void test_periodUntilUnit() { MinguoDate mdate1 = MinguoDate.of(1970, 1, 1); MinguoDate mdate2 = MinguoDate.of(1971, 2, 2); - long months = mdate1.periodUntil(mdate2, ChronoUnit.MONTHS); + long months = mdate1.until(mdate2, ChronoUnit.MONTHS); assertEquals(months, 13); } @@ -484,7 +516,7 @@ public class TCKMinguoChronology { MinguoDate mdate1 = MinguoDate.of(1970, 1, 1); MinguoDate mdate2 = MinguoDate.of(1971, 2, 2); ThaiBuddhistDate ldate2 = ThaiBuddhistChronology.INSTANCE.date(mdate2); - Period period = mdate1.periodUntil(ldate2); + Period period = mdate1.until(ldate2); assertEquals(period, Period.of(1, 1, 1)); } @@ -520,4 +552,409 @@ public class TCKMinguoChronology { assertFalse(MinguoChronology.INSTANCE.equals(IsoChronology.INSTANCE)); } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_yearOfEra") + Object[][] data_resolve_yearOfEra() { + return new Object[][] { + // era only + {ResolverStyle.STRICT, -1, null, null, null, null}, + {ResolverStyle.SMART, -1, null, null, null, null}, + {ResolverStyle.LENIENT, -1, null, null, null, null}, + + {ResolverStyle.STRICT, 0, null, null, ChronoField.ERA, 0}, + {ResolverStyle.SMART, 0, null, null, ChronoField.ERA, 0}, + {ResolverStyle.LENIENT, 0, null, null, ChronoField.ERA, 0}, + + {ResolverStyle.STRICT, 1, null, null, ChronoField.ERA, 1}, + {ResolverStyle.SMART, 1, null, null, ChronoField.ERA, 1}, + {ResolverStyle.LENIENT, 1, null, null, ChronoField.ERA, 1}, + + {ResolverStyle.STRICT, 2, null, null, null, null}, + {ResolverStyle.SMART, 2, null, null, null, null}, + {ResolverStyle.LENIENT, 2, null, null, null, null}, + + // era and year-of-era + {ResolverStyle.STRICT, -1, 2012, null, null, null}, + {ResolverStyle.SMART, -1, 2012, null, null, null}, + {ResolverStyle.LENIENT, -1, 2012, null, null, null}, + + {ResolverStyle.STRICT, 0, 2012, null, ChronoField.YEAR, -2011}, + {ResolverStyle.SMART, 0, 2012, null, ChronoField.YEAR, -2011}, + {ResolverStyle.LENIENT, 0, 2012, null, ChronoField.YEAR, -2011}, + + {ResolverStyle.STRICT, 1, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.SMART, 1, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, 1, 2012, null, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, 2, 2012, null, null, null}, + {ResolverStyle.SMART, 2, 2012, null, null, null}, + {ResolverStyle.LENIENT, 2, 2012, null, null, null}, + + // year-of-era only + {ResolverStyle.STRICT, null, 2012, null, ChronoField.YEAR_OF_ERA, 2012}, + {ResolverStyle.SMART, null, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, null, 2012, null, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, null, Integer.MAX_VALUE, null, null, null}, + {ResolverStyle.SMART, null, Integer.MAX_VALUE, null, null, null}, + {ResolverStyle.LENIENT, null, Integer.MAX_VALUE, null, ChronoField.YEAR, Integer.MAX_VALUE}, + + // year-of-era and year + {ResolverStyle.STRICT, null, 2012, 2012, ChronoField.YEAR, 2012}, + {ResolverStyle.SMART, null, 2012, 2012, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, null, 2012, 2012, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, null, 2012, -2011, ChronoField.YEAR, -2011}, + {ResolverStyle.SMART, null, 2012, -2011, ChronoField.YEAR, -2011}, + {ResolverStyle.LENIENT, null, 2012, -2011, ChronoField.YEAR, -2011}, + + {ResolverStyle.STRICT, null, 2012, 2013, null, null}, + {ResolverStyle.SMART, null, 2012, 2013, null, null}, + {ResolverStyle.LENIENT, null, 2012, 2013, null, null}, + + {ResolverStyle.STRICT, null, 2012, -2013, null, null}, + {ResolverStyle.SMART, null, 2012, -2013, null, null}, + {ResolverStyle.LENIENT, null, 2012, -2013, null, null}, + }; + } + + @Test(dataProvider = "resolve_yearOfEra") + public void test_resolve_yearOfEra(ResolverStyle style, Integer e, Integer yoe, Integer y, ChronoField field, Integer expected) { + Map fieldValues = new HashMap<>(); + if (e != null) { + fieldValues.put(ChronoField.ERA, (long) e); + } + if (yoe != null) { + fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); + } + if (y != null) { + fieldValues.put(ChronoField.YEAR, (long) y); + } + if (field != null) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(field), (Long) expected.longValue()); + assertEquals(fieldValues.size(), 1); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, style); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_ymd") + Object[][] data_resolve_ymd() { + return new Object[][] { + {2012 - YDIFF, 1, -365, date(2010 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, -364, date(2011 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 1, -31, date(2011 - YDIFF, 11, 30), false, false}, + {2012 - YDIFF, 1, -30, date(2011 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, 1, -12, date(2011 - YDIFF, 12, 19), false, false}, + {2012 - YDIFF, 1, 1, date(2012 - YDIFF, 1, 1), true, true}, + {2012 - YDIFF, 1, 27, date(2012 - YDIFF, 1, 27), true, true}, + {2012 - YDIFF, 1, 28, date(2012 - YDIFF, 1, 28), true, true}, + {2012 - YDIFF, 1, 29, date(2012 - YDIFF, 1, 29), true, true}, + {2012 - YDIFF, 1, 30, date(2012 - YDIFF, 1, 30), true, true}, + {2012 - YDIFF, 1, 31, date(2012 - YDIFF, 1, 31), true, true}, + {2012 - YDIFF, 1, 59, date(2012 - YDIFF, 2, 28), false, false}, + {2012 - YDIFF, 1, 60, date(2012 - YDIFF, 2, 29), false, false}, + {2012 - YDIFF, 1, 61, date(2012 - YDIFF, 3, 1), false, false}, + {2012 - YDIFF, 1, 365, date(2012 - YDIFF, 12, 30), false, false}, + {2012 - YDIFF, 1, 366, date(2012 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, 367, date(2013 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 1, 367 + 364, date(2013 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, 367 + 365, date(2014 - YDIFF, 1, 1), false, false}, + + {2012 - YDIFF, 2, 1, date(2012 - YDIFF, 2, 1), true, true}, + {2012 - YDIFF, 2, 28, date(2012 - YDIFF, 2, 28), true, true}, + {2012 - YDIFF, 2, 29, date(2012 - YDIFF, 2, 29), true, true}, + {2012 - YDIFF, 2, 30, date(2012 - YDIFF, 3, 1), date(2012 - YDIFF, 2, 29), false}, + {2012 - YDIFF, 2, 31, date(2012 - YDIFF, 3, 2), date(2012 - YDIFF, 2, 29), false}, + {2012 - YDIFF, 2, 32, date(2012 - YDIFF, 3, 3), false, false}, + + {2012 - YDIFF, -12, 1, date(2010 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, -11, 1, date(2011 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, -1, 1, date(2011 - YDIFF, 11, 1), false, false}, + {2012 - YDIFF, 0, 1, date(2011 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, 1, 1, date(2012 - YDIFF, 1, 1), true, true}, + {2012 - YDIFF, 12, 1, date(2012 - YDIFF, 12, 1), true, true}, + {2012 - YDIFF, 13, 1, date(2013 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 24, 1, date(2013 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, 25, 1, date(2014 - YDIFF, 1, 1), false, false}, + + {2012 - YDIFF, 6, -31, date(2012 - YDIFF, 4, 30), false, false}, + {2012 - YDIFF, 6, -30, date(2012 - YDIFF, 5, 1), false, false}, + {2012 - YDIFF, 6, -1, date(2012 - YDIFF, 5, 30), false, false}, + {2012 - YDIFF, 6, 0, date(2012 - YDIFF, 5, 31), false, false}, + {2012 - YDIFF, 6, 1, date(2012 - YDIFF, 6, 1), true, true}, + {2012 - YDIFF, 6, 30, date(2012 - YDIFF, 6, 30), true, true}, + {2012 - YDIFF, 6, 31, date(2012 - YDIFF, 7, 1), date(2012 - YDIFF, 6, 30), false}, + {2012 - YDIFF, 6, 61, date(2012 - YDIFF, 7, 31), false, false}, + {2012 - YDIFF, 6, 62, date(2012 - YDIFF, 8, 1), false, false}, + + {2011 - YDIFF, 2, 1, date(2011 - YDIFF, 2, 1), true, true}, + {2011 - YDIFF, 2, 28, date(2011 - YDIFF, 2, 28), true, true}, + {2011 - YDIFF, 2, 29, date(2011 - YDIFF, 3, 1), date(2011 - YDIFF, 2, 28), false}, + {2011 - YDIFF, 2, 30, date(2011 - YDIFF, 3, 2), date(2011 - YDIFF, 2, 28), false}, + {2011 - YDIFF, 2, 31, date(2011 - YDIFF, 3, 3), date(2011 - YDIFF, 2, 28), false}, + {2011 - YDIFF, 2, 32, date(2011 - YDIFF, 3, 4), false, false}, + }; + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_lenient(int y, int m, int d, MinguoDate expected, Object smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_smart(int y, int m, int d, MinguoDate expected, Object smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (Boolean.TRUE.equals(smart)) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else if (smart instanceof MinguoDate) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, smart); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_strict(int y, int m, int d, MinguoDate expected, Object smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (strict) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_yd") + Object[][] data_resolve_yd() { + return new Object[][] { + {2012 - YDIFF, -365, date(2010 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, -364, date(2011 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, -31, date(2011 - YDIFF, 11, 30), false, false}, + {2012 - YDIFF, -30, date(2011 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, -12, date(2011 - YDIFF, 12, 19), false, false}, + {2012 - YDIFF, -1, date(2011 - YDIFF, 12, 30), false, false}, + {2012 - YDIFF, 0, date(2011 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, date(2012 - YDIFF, 1, 1), true, true}, + {2012 - YDIFF, 2, date(2012 - YDIFF, 1, 2), true, true}, + {2012 - YDIFF, 31, date(2012 - YDIFF, 1, 31), true, true}, + {2012 - YDIFF, 32, date(2012 - YDIFF, 2, 1), true, true}, + {2012 - YDIFF, 59, date(2012 - YDIFF, 2, 28), true, true}, + {2012 - YDIFF, 60, date(2012 - YDIFF, 2, 29), true, true}, + {2012 - YDIFF, 61, date(2012 - YDIFF, 3, 1), true, true}, + {2012 - YDIFF, 365, date(2012 - YDIFF, 12, 30), true, true}, + {2012 - YDIFF, 366, date(2012 - YDIFF, 12, 31), true, true}, + {2012 - YDIFF, 367, date(2013 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 367 + 364, date(2013 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 367 + 365, date(2014 - YDIFF, 1, 1), false, false}, + + {2011 - YDIFF, 59, date(2011 - YDIFF, 2, 28), true, true}, + {2011 - YDIFF, 60, date(2011 - YDIFF, 3, 1), true, true}, + }; + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_lenient(int y, int d, MinguoDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_smart(int y, int d, MinguoDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (smart) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_strict(int y, int d, MinguoDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (strict) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_ymaa") + Object[][] data_resolve_ymaa() { + return new Object[][] { + {2012 - YDIFF, 1, 1, -365, date(2010 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, 1, -364, date(2011 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 1, 1, -31, date(2011 - YDIFF, 11, 30), false, false}, + {2012 - YDIFF, 1, 1, -30, date(2011 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, 1, 1, -12, date(2011 - YDIFF, 12, 19), false, false}, + {2012 - YDIFF, 1, 1, 1, date(2012 - YDIFF, 1, 1), true, true}, + {2012 - YDIFF, 1, 1, 59, date(2012 - YDIFF, 2, 28), false, false}, + {2012 - YDIFF, 1, 1, 60, date(2012 - YDIFF, 2, 29), false, false}, + {2012 - YDIFF, 1, 1, 61, date(2012 - YDIFF, 3, 1), false, false}, + {2012 - YDIFF, 1, 1, 365, date(2012 - YDIFF, 12, 30), false, false}, + {2012 - YDIFF, 1, 1, 366, date(2012 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, 1, 367, date(2013 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 1, 1, 367 + 364, date(2013 - YDIFF, 12, 31), false, false}, + {2012 - YDIFF, 1, 1, 367 + 365, date(2014 - YDIFF, 1, 1), false, false}, + + {2012 - YDIFF, 2, 0, 1, date(2012 - YDIFF, 1, 25), false, false}, + {2012 - YDIFF, 2, 0, 7, date(2012 - YDIFF, 1, 31), false, false}, + {2012 - YDIFF, 2, 1, 1, date(2012 - YDIFF, 2, 1), true, true}, + {2012 - YDIFF, 2, 1, 7, date(2012 - YDIFF, 2, 7), true, true}, + {2012 - YDIFF, 2, 2, 1, date(2012 - YDIFF, 2, 8), true, true}, + {2012 - YDIFF, 2, 2, 7, date(2012 - YDIFF, 2, 14), true, true}, + {2012 - YDIFF, 2, 3, 1, date(2012 - YDIFF, 2, 15), true, true}, + {2012 - YDIFF, 2, 3, 7, date(2012 - YDIFF, 2, 21), true, true}, + {2012 - YDIFF, 2, 4, 1, date(2012 - YDIFF, 2, 22), true, true}, + {2012 - YDIFF, 2, 4, 7, date(2012 - YDIFF, 2, 28), true, true}, + {2012 - YDIFF, 2, 5, 1, date(2012 - YDIFF, 2, 29), true, true}, + {2012 - YDIFF, 2, 5, 2, date(2012 - YDIFF, 3, 1), true, false}, + {2012 - YDIFF, 2, 5, 7, date(2012 - YDIFF, 3, 6), true, false}, + {2012 - YDIFF, 2, 6, 1, date(2012 - YDIFF, 3, 7), false, false}, + {2012 - YDIFF, 2, 6, 7, date(2012 - YDIFF, 3, 13), false, false}, + + {2012 - YDIFF, 12, 1, 1, date(2012 - YDIFF, 12, 1), true, true}, + {2012 - YDIFF, 12, 5, 1, date(2012 - YDIFF, 12, 29), true, true}, + {2012 - YDIFF, 12, 5, 2, date(2012 - YDIFF, 12, 30), true, true}, + {2012 - YDIFF, 12, 5, 3, date(2012 - YDIFF, 12, 31), true, true}, + {2012 - YDIFF, 12, 5, 4, date(2013 - YDIFF, 1, 1), true, false}, + {2012 - YDIFF, 12, 5, 7, date(2013 - YDIFF, 1, 4), true, false}, + + {2012 - YDIFF, -12, 1, 1, date(2010 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, -11, 1, 1, date(2011 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, -1, 1, 1, date(2011 - YDIFF, 11, 1), false, false}, + {2012 - YDIFF, 0, 1, 1, date(2011 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, 1, 1, 1, date(2012 - YDIFF, 1, 1), true, true}, + {2012 - YDIFF, 12, 1, 1, date(2012 - YDIFF, 12, 1), true, true}, + {2012 - YDIFF, 13, 1, 1, date(2013 - YDIFF, 1, 1), false, false}, + {2012 - YDIFF, 24, 1, 1, date(2013 - YDIFF, 12, 1), false, false}, + {2012 - YDIFF, 25, 1, 1, date(2014 - YDIFF, 1, 1), false, false}, + + {2011 - YDIFF, 2, 1, 1, date(2011 - YDIFF, 2, 1), true, true}, + {2011 - YDIFF, 2, 4, 7, date(2011 - YDIFF, 2, 28), true, true}, + {2011 - YDIFF, 2, 5, 1, date(2011 - YDIFF, 3, 1), true, false}, + }; + } + + @Test(dataProvider = "resolve_ymaa") + public void test_resolve_ymaa_lenient(int y, int m, int w, int d, MinguoDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w); + fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d); + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_ymaa") + public void test_resolve_ymaa_smart(int y, int m, int w, int d, MinguoDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w); + fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d); + if (smart) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymaa") + public void test_resolve_ymaa_strict(int y, int m, int w, int d, MinguoDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w); + fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d); + if (strict) { + MinguoDate date = MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + MinguoChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + private static MinguoDate date(int y, int m, int d) { + return MinguoDate.of(y, m, d); + } + } diff --git a/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java b/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java index f6c79449638..e57847c0619 100644 --- a/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java +++ b/jdk/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java @@ -63,6 +63,7 @@ import static java.time.temporal.ChronoField.YEAR; import static java.time.temporal.ChronoField.YEAR_OF_ERA; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @@ -84,12 +85,16 @@ import java.time.chrono.MinguoDate; import java.time.chrono.ThaiBuddhistChronology; import java.time.chrono.ThaiBuddhistDate; import java.time.chrono.ThaiBuddhistEra; +import java.time.format.ResolverStyle; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAdjuster; +import java.time.temporal.TemporalField; import java.time.temporal.ValueRange; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import org.testng.Assert; import org.testng.annotations.DataProvider; @@ -200,6 +205,18 @@ public class TCKThaiBuddhistChronology { @Test(dataProvider="samples") public void test_fromCalendrical(ThaiBuddhistDate jdate, LocalDate iso) { assertEquals(ThaiBuddhistChronology.INSTANCE.date(iso), jdate); + assertEquals(ThaiBuddhistDate.from(iso), jdate); + } + + @Test(dataProvider="samples") + public void test_isEqual(ThaiBuddhistDate jdate, LocalDate iso) { + assertTrue(jdate.isEqual(iso)); + } + + @Test(dataProvider="samples") + public void test_date_equals(ThaiBuddhistDate jdate, LocalDate iso) { + assertFalse(jdate.equals(iso)); + assertNotEquals(jdate.hashCode(), iso.hashCode()); } @Test @@ -251,46 +268,58 @@ public class TCKThaiBuddhistChronology { ThaiBuddhistChronology.INSTANCE.date(year, month, dom); } - //----------------------------------------------------------------------- - // prolepticYear() and is LeapYear() - //----------------------------------------------------------------------- - @DataProvider(name="prolepticYear") - Object[][] data_prolepticYear() { - return new Object[][] { - {1, ThaiBuddhistEra.BE, 4 + YDIFF, 4 + YDIFF, true}, - {1, ThaiBuddhistEra.BE, 7 + YDIFF, 7 + YDIFF, false}, - {1, ThaiBuddhistEra.BE, 8 + YDIFF, 8 + YDIFF, true}, - {1, ThaiBuddhistEra.BE, 1000 + YDIFF, 1000 + YDIFF, false}, - {1, ThaiBuddhistEra.BE, 2000 + YDIFF, 2000 + YDIFF, true}, - {1, ThaiBuddhistEra.BE, 0, 0, false}, - {1, ThaiBuddhistEra.BE, -4 + YDIFF, -4 + YDIFF, true}, - {1, ThaiBuddhistEra.BE, -7 + YDIFF, -7 + YDIFF, false}, - {1, ThaiBuddhistEra.BE, -100 + YDIFF, -100 + YDIFF, false}, - {1, ThaiBuddhistEra.BE, -800 + YDIFF, -800 + YDIFF, true}, + //----------------------------------------------------------------------- + // prolepticYear() and is LeapYear() + //----------------------------------------------------------------------- + @DataProvider(name="prolepticYear") + Object[][] data_prolepticYear() { + return new Object[][] { + {1, ThaiBuddhistEra.BE, 4 + YDIFF, 4 + YDIFF, true}, + {1, ThaiBuddhistEra.BE, 7 + YDIFF, 7 + YDIFF, false}, + {1, ThaiBuddhistEra.BE, 8 + YDIFF, 8 + YDIFF, true}, + {1, ThaiBuddhistEra.BE, 1000 + YDIFF, 1000 + YDIFF, false}, + {1, ThaiBuddhistEra.BE, 2000 + YDIFF, 2000 + YDIFF, true}, + {1, ThaiBuddhistEra.BE, 0, 0, false}, + {1, ThaiBuddhistEra.BE, -4 + YDIFF, -4 + YDIFF, true}, + {1, ThaiBuddhistEra.BE, -7 + YDIFF, -7 + YDIFF, false}, + {1, ThaiBuddhistEra.BE, -100 + YDIFF, -100 + YDIFF, false}, + {1, ThaiBuddhistEra.BE, -800 + YDIFF, -800 + YDIFF, true}, - {0, ThaiBuddhistEra.BEFORE_BE, -3 - YDIFF, 4 + YDIFF, true}, - {0, ThaiBuddhistEra.BEFORE_BE, -6 - YDIFF, 7 + YDIFF, false}, - {0, ThaiBuddhistEra.BEFORE_BE, -7 - YDIFF, 8 + YDIFF, true}, - {0, ThaiBuddhistEra.BEFORE_BE, -999 - YDIFF, 1000 + YDIFF, false}, - {0, ThaiBuddhistEra.BEFORE_BE, -1999 - YDIFF, 2000 + YDIFF, true}, - {0, ThaiBuddhistEra.BEFORE_BE, 1, 0, false}, - {0, ThaiBuddhistEra.BEFORE_BE, 5 - YDIFF, -4 + YDIFF, true}, - {0, ThaiBuddhistEra.BEFORE_BE, 8 - YDIFF, -7 + YDIFF, false}, - {0, ThaiBuddhistEra.BEFORE_BE, 101 - YDIFF, -100 + YDIFF, false}, - {0, ThaiBuddhistEra.BEFORE_BE, 801 - YDIFF, -800 + YDIFF, true}, + {0, ThaiBuddhistEra.BEFORE_BE, -3 - YDIFF, 4 + YDIFF, true}, + {0, ThaiBuddhistEra.BEFORE_BE, -6 - YDIFF, 7 + YDIFF, false}, + {0, ThaiBuddhistEra.BEFORE_BE, -7 - YDIFF, 8 + YDIFF, true}, + {0, ThaiBuddhistEra.BEFORE_BE, -999 - YDIFF, 1000 + YDIFF, false}, + {0, ThaiBuddhistEra.BEFORE_BE, -1999 - YDIFF, 2000 + YDIFF, true}, + {0, ThaiBuddhistEra.BEFORE_BE, 1, 0, false}, + {0, ThaiBuddhistEra.BEFORE_BE, 5 - YDIFF, -4 + YDIFF, true}, + {0, ThaiBuddhistEra.BEFORE_BE, 8 - YDIFF, -7 + YDIFF, false}, + {0, ThaiBuddhistEra.BEFORE_BE, 101 - YDIFF, -100 + YDIFF, false}, + {0, ThaiBuddhistEra.BEFORE_BE, 801 - YDIFF, -800 + YDIFF, true}, - }; - } + }; + } - @Test(dataProvider="prolepticYear") - public void test_prolepticYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { - Era eraObj = ThaiBuddhistChronology.INSTANCE.eraOf(eraValue) ; - assertTrue(ThaiBuddhistChronology.INSTANCE.eras().contains(eraObj)); - assertEquals(eraObj, era); - assertEquals(ThaiBuddhistChronology.INSTANCE.prolepticYear(era, yearOfEra), expectedProlepticYear); - assertEquals(ThaiBuddhistChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear) ; - assertEquals(ThaiBuddhistChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear - YDIFF).isLeap()) ; - } + @Test(dataProvider="prolepticYear") + public void test_prolepticYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { + Era eraObj = ThaiBuddhistChronology.INSTANCE.eraOf(eraValue); + assertTrue(ThaiBuddhistChronology.INSTANCE.eras().contains(eraObj)); + assertEquals(eraObj, era); + assertEquals(ThaiBuddhistChronology.INSTANCE.prolepticYear(era, yearOfEra), expectedProlepticYear); + } + + @Test(dataProvider="prolepticYear") + public void test_isLeapYear(int eraValue, Era era, int yearOfEra, int expectedProlepticYear, boolean isLeapYear) { + assertEquals(ThaiBuddhistChronology.INSTANCE.isLeapYear(expectedProlepticYear), isLeapYear) ; + assertEquals(ThaiBuddhistChronology.INSTANCE.isLeapYear(expectedProlepticYear), Year.of(expectedProlepticYear - YDIFF).isLeap()); + + ThaiBuddhistDate jdate = ThaiBuddhistDate.now(); + jdate = jdate.with(ChronoField.YEAR, expectedProlepticYear).with(ChronoField.MONTH_OF_YEAR, 2); + if (isLeapYear) { + assertEquals(jdate.lengthOfMonth(), 29); + } else { + assertEquals(jdate.lengthOfMonth(), 28); + } + } //----------------------------------------------------------------------- // Bad Era for Chronology.date(era,...) and Chronology.prolepticYear(Era,...) @@ -429,7 +458,7 @@ public class TCKThaiBuddhistChronology { public void test_periodUntilDate() { ThaiBuddhistDate mdate1 = ThaiBuddhistDate.of(1, 1, 1); ThaiBuddhistDate mdate2 = ThaiBuddhistDate.of(2, 2, 2); - Period period = mdate1.periodUntil(mdate2); + Period period = mdate1.until(mdate2); assertEquals(period, Period.of(1, 1, 1)); } @@ -437,7 +466,7 @@ public class TCKThaiBuddhistChronology { public void test_periodUntilUnit() { ThaiBuddhistDate mdate1 = ThaiBuddhistDate.of(1, 1, 1); ThaiBuddhistDate mdate2 = ThaiBuddhistDate.of(2, 2, 2); - long months = mdate1.periodUntil(mdate2, ChronoUnit.MONTHS); + long months = mdate1.until(mdate2, ChronoUnit.MONTHS); assertEquals(months, 13); } @@ -446,7 +475,7 @@ public class TCKThaiBuddhistChronology { ThaiBuddhistDate mdate1 = ThaiBuddhistDate.of(1, 1, 1); ThaiBuddhistDate mdate2 = ThaiBuddhistDate.of(2, 2, 2); MinguoDate ldate2 = MinguoChronology.INSTANCE.date(mdate2); - Period period = mdate1.periodUntil(ldate2); + Period period = mdate1.until(ldate2); assertEquals(period, Period.of(1, 1, 1)); } @@ -497,4 +526,409 @@ public class TCKThaiBuddhistChronology { assertFalse(ThaiBuddhistChronology.INSTANCE.equals(IsoChronology.INSTANCE)); } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_yearOfEra") + Object[][] data_resolve_yearOfEra() { + return new Object[][] { + // era only + {ResolverStyle.STRICT, -1, null, null, null, null}, + {ResolverStyle.SMART, -1, null, null, null, null}, + {ResolverStyle.LENIENT, -1, null, null, null, null}, + + {ResolverStyle.STRICT, 0, null, null, ChronoField.ERA, 0}, + {ResolverStyle.SMART, 0, null, null, ChronoField.ERA, 0}, + {ResolverStyle.LENIENT, 0, null, null, ChronoField.ERA, 0}, + + {ResolverStyle.STRICT, 1, null, null, ChronoField.ERA, 1}, + {ResolverStyle.SMART, 1, null, null, ChronoField.ERA, 1}, + {ResolverStyle.LENIENT, 1, null, null, ChronoField.ERA, 1}, + + {ResolverStyle.STRICT, 2, null, null, null, null}, + {ResolverStyle.SMART, 2, null, null, null, null}, + {ResolverStyle.LENIENT, 2, null, null, null, null}, + + // era and year-of-era + {ResolverStyle.STRICT, -1, 2012, null, null, null}, + {ResolverStyle.SMART, -1, 2012, null, null, null}, + {ResolverStyle.LENIENT, -1, 2012, null, null, null}, + + {ResolverStyle.STRICT, 0, 2012, null, ChronoField.YEAR, -2011}, + {ResolverStyle.SMART, 0, 2012, null, ChronoField.YEAR, -2011}, + {ResolverStyle.LENIENT, 0, 2012, null, ChronoField.YEAR, -2011}, + + {ResolverStyle.STRICT, 1, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.SMART, 1, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, 1, 2012, null, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, 2, 2012, null, null, null}, + {ResolverStyle.SMART, 2, 2012, null, null, null}, + {ResolverStyle.LENIENT, 2, 2012, null, null, null}, + + // year-of-era only + {ResolverStyle.STRICT, null, 2012, null, ChronoField.YEAR_OF_ERA, 2012}, + {ResolverStyle.SMART, null, 2012, null, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, null, 2012, null, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, null, Integer.MAX_VALUE, null, null, null}, + {ResolverStyle.SMART, null, Integer.MAX_VALUE, null, null, null}, + {ResolverStyle.LENIENT, null, Integer.MAX_VALUE, null, ChronoField.YEAR, Integer.MAX_VALUE}, + + // year-of-era and year + {ResolverStyle.STRICT, null, 2012, 2012, ChronoField.YEAR, 2012}, + {ResolverStyle.SMART, null, 2012, 2012, ChronoField.YEAR, 2012}, + {ResolverStyle.LENIENT, null, 2012, 2012, ChronoField.YEAR, 2012}, + + {ResolverStyle.STRICT, null, 2012, -2011, ChronoField.YEAR, -2011}, + {ResolverStyle.SMART, null, 2012, -2011, ChronoField.YEAR, -2011}, + {ResolverStyle.LENIENT, null, 2012, -2011, ChronoField.YEAR, -2011}, + + {ResolverStyle.STRICT, null, 2012, 2013, null, null}, + {ResolverStyle.SMART, null, 2012, 2013, null, null}, + {ResolverStyle.LENIENT, null, 2012, 2013, null, null}, + + {ResolverStyle.STRICT, null, 2012, -2013, null, null}, + {ResolverStyle.SMART, null, 2012, -2013, null, null}, + {ResolverStyle.LENIENT, null, 2012, -2013, null, null}, + }; + } + + @Test(dataProvider = "resolve_yearOfEra") + public void test_resolve_yearOfEra(ResolverStyle style, Integer e, Integer yoe, Integer y, ChronoField field, Integer expected) { + Map fieldValues = new HashMap<>(); + if (e != null) { + fieldValues.put(ChronoField.ERA, (long) e); + } + if (yoe != null) { + fieldValues.put(ChronoField.YEAR_OF_ERA, (long) yoe); + } + if (y != null) { + fieldValues.put(ChronoField.YEAR, (long) y); + } + if (field != null) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, style); + assertEquals(date, null); + assertEquals(fieldValues.get(field), (Long) expected.longValue()); + assertEquals(fieldValues.size(), 1); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, style); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_ymd") + Object[][] data_resolve_ymd() { + return new Object[][] { + {YDIFF + 2012, 1, -365, date(YDIFF + 2010, 12, 31), false, false}, + {YDIFF + 2012, 1, -364, date(YDIFF + 2011, 1, 1), false, false}, + {YDIFF + 2012, 1, -31, date(YDIFF + 2011, 11, 30), false, false}, + {YDIFF + 2012, 1, -30, date(YDIFF + 2011, 12, 1), false, false}, + {YDIFF + 2012, 1, -12, date(YDIFF + 2011, 12, 19), false, false}, + {YDIFF + 2012, 1, 1, date(YDIFF + 2012, 1, 1), true, true}, + {YDIFF + 2012, 1, 27, date(YDIFF + 2012, 1, 27), true, true}, + {YDIFF + 2012, 1, 28, date(YDIFF + 2012, 1, 28), true, true}, + {YDIFF + 2012, 1, 29, date(YDIFF + 2012, 1, 29), true, true}, + {YDIFF + 2012, 1, 30, date(YDIFF + 2012, 1, 30), true, true}, + {YDIFF + 2012, 1, 31, date(YDIFF + 2012, 1, 31), true, true}, + {YDIFF + 2012, 1, 59, date(YDIFF + 2012, 2, 28), false, false}, + {YDIFF + 2012, 1, 60, date(YDIFF + 2012, 2, 29), false, false}, + {YDIFF + 2012, 1, 61, date(YDIFF + 2012, 3, 1), false, false}, + {YDIFF + 2012, 1, 365, date(YDIFF + 2012, 12, 30), false, false}, + {YDIFF + 2012, 1, 366, date(YDIFF + 2012, 12, 31), false, false}, + {YDIFF + 2012, 1, 367, date(YDIFF + 2013, 1, 1), false, false}, + {YDIFF + 2012, 1, 367 + 364, date(YDIFF + 2013, 12, 31), false, false}, + {YDIFF + 2012, 1, 367 + 365, date(YDIFF + 2014, 1, 1), false, false}, + + {YDIFF + 2012, 2, 1, date(YDIFF + 2012, 2, 1), true, true}, + {YDIFF + 2012, 2, 28, date(YDIFF + 2012, 2, 28), true, true}, + {YDIFF + 2012, 2, 29, date(YDIFF + 2012, 2, 29), true, true}, + {YDIFF + 2012, 2, 30, date(YDIFF + 2012, 3, 1), date(YDIFF + 2012, 2, 29), false}, + {YDIFF + 2012, 2, 31, date(YDIFF + 2012, 3, 2), date(YDIFF + 2012, 2, 29), false}, + {YDIFF + 2012, 2, 32, date(YDIFF + 2012, 3, 3), false, false}, + + {YDIFF + 2012, -12, 1, date(YDIFF + 2010, 12, 1), false, false}, + {YDIFF + 2012, -11, 1, date(YDIFF + 2011, 1, 1), false, false}, + {YDIFF + 2012, -1, 1, date(YDIFF + 2011, 11, 1), false, false}, + {YDIFF + 2012, 0, 1, date(YDIFF + 2011, 12, 1), false, false}, + {YDIFF + 2012, 1, 1, date(YDIFF + 2012, 1, 1), true, true}, + {YDIFF + 2012, 12, 1, date(YDIFF + 2012, 12, 1), true, true}, + {YDIFF + 2012, 13, 1, date(YDIFF + 2013, 1, 1), false, false}, + {YDIFF + 2012, 24, 1, date(YDIFF + 2013, 12, 1), false, false}, + {YDIFF + 2012, 25, 1, date(YDIFF + 2014, 1, 1), false, false}, + + {YDIFF + 2012, 6, -31, date(YDIFF + 2012, 4, 30), false, false}, + {YDIFF + 2012, 6, -30, date(YDIFF + 2012, 5, 1), false, false}, + {YDIFF + 2012, 6, -1, date(YDIFF + 2012, 5, 30), false, false}, + {YDIFF + 2012, 6, 0, date(YDIFF + 2012, 5, 31), false, false}, + {YDIFF + 2012, 6, 1, date(YDIFF + 2012, 6, 1), true, true}, + {YDIFF + 2012, 6, 30, date(YDIFF + 2012, 6, 30), true, true}, + {YDIFF + 2012, 6, 31, date(YDIFF + 2012, 7, 1), date(YDIFF + 2012, 6, 30), false}, + {YDIFF + 2012, 6, 61, date(YDIFF + 2012, 7, 31), false, false}, + {YDIFF + 2012, 6, 62, date(YDIFF + 2012, 8, 1), false, false}, + + {YDIFF + 2011, 2, 1, date(YDIFF + 2011, 2, 1), true, true}, + {YDIFF + 2011, 2, 28, date(YDIFF + 2011, 2, 28), true, true}, + {YDIFF + 2011, 2, 29, date(YDIFF + 2011, 3, 1), date(YDIFF + 2011, 2, 28), false}, + {YDIFF + 2011, 2, 30, date(YDIFF + 2011, 3, 2), date(YDIFF + 2011, 2, 28), false}, + {YDIFF + 2011, 2, 31, date(YDIFF + 2011, 3, 3), date(YDIFF + 2011, 2, 28), false}, + {YDIFF + 2011, 2, 32, date(YDIFF + 2011, 3, 4), false, false}, + }; + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_lenient(int y, int m, int d, ThaiBuddhistDate expected, Object smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_smart(int y, int m, int d, ThaiBuddhistDate expected, Object smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (Boolean.TRUE.equals(smart)) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else if (smart instanceof ThaiBuddhistDate) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, smart); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymd") + public void test_resolve_ymd_strict(int y, int m, int d, ThaiBuddhistDate expected, Object smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.DAY_OF_MONTH, (long) d); + if (strict) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_yd") + Object[][] data_resolve_yd() { + return new Object[][] { + {YDIFF + 2012, -365, date(YDIFF + 2010, 12, 31), false, false}, + {YDIFF + 2012, -364, date(YDIFF + 2011, 1, 1), false, false}, + {YDIFF + 2012, -31, date(YDIFF + 2011, 11, 30), false, false}, + {YDIFF + 2012, -30, date(YDIFF + 2011, 12, 1), false, false}, + {YDIFF + 2012, -12, date(YDIFF + 2011, 12, 19), false, false}, + {YDIFF + 2012, -1, date(YDIFF + 2011, 12, 30), false, false}, + {YDIFF + 2012, 0, date(YDIFF + 2011, 12, 31), false, false}, + {YDIFF + 2012, 1, date(YDIFF + 2012, 1, 1), true, true}, + {YDIFF + 2012, 2, date(YDIFF + 2012, 1, 2), true, true}, + {YDIFF + 2012, 31, date(YDIFF + 2012, 1, 31), true, true}, + {YDIFF + 2012, 32, date(YDIFF + 2012, 2, 1), true, true}, + {YDIFF + 2012, 59, date(YDIFF + 2012, 2, 28), true, true}, + {YDIFF + 2012, 60, date(YDIFF + 2012, 2, 29), true, true}, + {YDIFF + 2012, 61, date(YDIFF + 2012, 3, 1), true, true}, + {YDIFF + 2012, 365, date(YDIFF + 2012, 12, 30), true, true}, + {YDIFF + 2012, 366, date(YDIFF + 2012, 12, 31), true, true}, + {YDIFF + 2012, 367, date(YDIFF + 2013, 1, 1), false, false}, + {YDIFF + 2012, 367 + 364, date(YDIFF + 2013, 12, 31), false, false}, + {YDIFF + 2012, 367 + 365, date(YDIFF + 2014, 1, 1), false, false}, + + {YDIFF + 2011, 59, date(YDIFF + 2011, 2, 28), true, true}, + {YDIFF + 2011, 60, date(YDIFF + 2011, 3, 1), true, true}, + }; + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_lenient(int y, int d, ThaiBuddhistDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_smart(int y, int d, ThaiBuddhistDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (smart) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_yd") + public void test_resolve_yd_strict(int y, int d, ThaiBuddhistDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.DAY_OF_YEAR, (long) d); + if (strict) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + @DataProvider(name = "resolve_ymaa") + Object[][] data_resolve_ymaa() { + return new Object[][] { + {YDIFF + 2012, 1, 1, -365, date(YDIFF + 2010, 12, 31), false, false}, + {YDIFF + 2012, 1, 1, -364, date(YDIFF + 2011, 1, 1), false, false}, + {YDIFF + 2012, 1, 1, -31, date(YDIFF + 2011, 11, 30), false, false}, + {YDIFF + 2012, 1, 1, -30, date(YDIFF + 2011, 12, 1), false, false}, + {YDIFF + 2012, 1, 1, -12, date(YDIFF + 2011, 12, 19), false, false}, + {YDIFF + 2012, 1, 1, 1, date(YDIFF + 2012, 1, 1), true, true}, + {YDIFF + 2012, 1, 1, 59, date(YDIFF + 2012, 2, 28), false, false}, + {YDIFF + 2012, 1, 1, 60, date(YDIFF + 2012, 2, 29), false, false}, + {YDIFF + 2012, 1, 1, 61, date(YDIFF + 2012, 3, 1), false, false}, + {YDIFF + 2012, 1, 1, 365, date(YDIFF + 2012, 12, 30), false, false}, + {YDIFF + 2012, 1, 1, 366, date(YDIFF + 2012, 12, 31), false, false}, + {YDIFF + 2012, 1, 1, 367, date(YDIFF + 2013, 1, 1), false, false}, + {YDIFF + 2012, 1, 1, 367 + 364, date(YDIFF + 2013, 12, 31), false, false}, + {YDIFF + 2012, 1, 1, 367 + 365, date(YDIFF + 2014, 1, 1), false, false}, + + {YDIFF + 2012, 2, 0, 1, date(YDIFF + 2012, 1, 25), false, false}, + {YDIFF + 2012, 2, 0, 7, date(YDIFF + 2012, 1, 31), false, false}, + {YDIFF + 2012, 2, 1, 1, date(YDIFF + 2012, 2, 1), true, true}, + {YDIFF + 2012, 2, 1, 7, date(YDIFF + 2012, 2, 7), true, true}, + {YDIFF + 2012, 2, 2, 1, date(YDIFF + 2012, 2, 8), true, true}, + {YDIFF + 2012, 2, 2, 7, date(YDIFF + 2012, 2, 14), true, true}, + {YDIFF + 2012, 2, 3, 1, date(YDIFF + 2012, 2, 15), true, true}, + {YDIFF + 2012, 2, 3, 7, date(YDIFF + 2012, 2, 21), true, true}, + {YDIFF + 2012, 2, 4, 1, date(YDIFF + 2012, 2, 22), true, true}, + {YDIFF + 2012, 2, 4, 7, date(YDIFF + 2012, 2, 28), true, true}, + {YDIFF + 2012, 2, 5, 1, date(YDIFF + 2012, 2, 29), true, true}, + {YDIFF + 2012, 2, 5, 2, date(YDIFF + 2012, 3, 1), true, false}, + {YDIFF + 2012, 2, 5, 7, date(YDIFF + 2012, 3, 6), true, false}, + {YDIFF + 2012, 2, 6, 1, date(YDIFF + 2012, 3, 7), false, false}, + {YDIFF + 2012, 2, 6, 7, date(YDIFF + 2012, 3, 13), false, false}, + + {YDIFF + 2012, 12, 1, 1, date(YDIFF + 2012, 12, 1), true, true}, + {YDIFF + 2012, 12, 5, 1, date(YDIFF + 2012, 12, 29), true, true}, + {YDIFF + 2012, 12, 5, 2, date(YDIFF + 2012, 12, 30), true, true}, + {YDIFF + 2012, 12, 5, 3, date(YDIFF + 2012, 12, 31), true, true}, + {YDIFF + 2012, 12, 5, 4, date(YDIFF + 2013, 1, 1), true, false}, + {YDIFF + 2012, 12, 5, 7, date(YDIFF + 2013, 1, 4), true, false}, + + {YDIFF + 2012, -12, 1, 1, date(YDIFF + 2010, 12, 1), false, false}, + {YDIFF + 2012, -11, 1, 1, date(YDIFF + 2011, 1, 1), false, false}, + {YDIFF + 2012, -1, 1, 1, date(YDIFF + 2011, 11, 1), false, false}, + {YDIFF + 2012, 0, 1, 1, date(YDIFF + 2011, 12, 1), false, false}, + {YDIFF + 2012, 1, 1, 1, date(YDIFF + 2012, 1, 1), true, true}, + {YDIFF + 2012, 12, 1, 1, date(YDIFF + 2012, 12, 1), true, true}, + {YDIFF + 2012, 13, 1, 1, date(YDIFF + 2013, 1, 1), false, false}, + {YDIFF + 2012, 24, 1, 1, date(YDIFF + 2013, 12, 1), false, false}, + {YDIFF + 2012, 25, 1, 1, date(YDIFF + 2014, 1, 1), false, false}, + + {YDIFF + 2011, 2, 1, 1, date(YDIFF + 2011, 2, 1), true, true}, + {YDIFF + 2011, 2, 4, 7, date(YDIFF + 2011, 2, 28), true, true}, + {YDIFF + 2011, 2, 5, 1, date(YDIFF + 2011, 3, 1), true, false}, + }; + } + + @Test(dataProvider = "resolve_ymaa") + public void test_resolve_ymaa_lenient(int y, int m, int w, int d, ThaiBuddhistDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w); + fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d); + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.LENIENT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } + + @Test(dataProvider = "resolve_ymaa") + public void test_resolve_ymaa_smart(int y, int m, int w, int d, ThaiBuddhistDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w); + fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d); + if (smart) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.SMART); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + @Test(dataProvider = "resolve_ymaa") + public void test_resolve_ymaa_strict(int y, int m, int w, int d, ThaiBuddhistDate expected, boolean smart, boolean strict) { + Map fieldValues = new HashMap<>(); + fieldValues.put(ChronoField.YEAR, (long) y); + fieldValues.put(ChronoField.MONTH_OF_YEAR, (long) m); + fieldValues.put(ChronoField.ALIGNED_WEEK_OF_MONTH, (long) w); + fieldValues.put(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH, (long) d); + if (strict) { + ThaiBuddhistDate date = ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + assertEquals(date, expected); + assertEquals(fieldValues.size(), 0); + } else { + try { + ThaiBuddhistChronology.INSTANCE.resolveDate(fieldValues, ResolverStyle.STRICT); + fail("Should have failed"); + } catch (DateTimeException ex) { + // expected + } + } + } + + //----------------------------------------------------------------------- + private static ThaiBuddhistDate date(int y, int m, int d) { + return ThaiBuddhistDate.of(y, m, d); + } + } diff --git a/jdk/test/java/time/tck/java/time/format/TCKFormatStyle.java b/jdk/test/java/time/tck/java/time/format/TCKFormatStyle.java new file mode 100644 index 00000000000..280dd0999de --- /dev/null +++ b/jdk/test/java/time/tck/java/time/format/TCKFormatStyle.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * 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. + * + * * Redistributions 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 JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.format; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.FormatStyle; +import java.time.temporal.Temporal; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Test. + */ +@Test +public class TCKFormatStyle { + + private static final ZoneId ZONEID_PARIS = ZoneId.of("Europe/Paris"); + private static final ZoneId OFFSET_PTWO = ZoneOffset.of("+02:00"); + + //----------------------------------------------------------------------- + // valueOf() + //----------------------------------------------------------------------- + @Test + public void test_valueOf() { + for (FormatStyle style : FormatStyle.values()) { + assertEquals(FormatStyle.valueOf(style.name()), style); + } + } + + @DataProvider(name="formatStyle") + Object[][] data_formatStyle() { + return new Object[][] { + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), ZONEID_PARIS), FormatStyle.FULL, "Tuesday, October 2, 2001 1:02:03 AM CEST Europe/Paris"}, + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), ZONEID_PARIS), FormatStyle.LONG, "October 2, 2001 1:02:03 AM CEST Europe/Paris"}, + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), ZONEID_PARIS), FormatStyle.MEDIUM, "Oct 2, 2001 1:02:03 AM Europe/Paris"}, + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), ZONEID_PARIS), FormatStyle.SHORT, "10/2/01 1:02 AM Europe/Paris"}, + + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), OFFSET_PTWO), FormatStyle.FULL, "Tuesday, October 2, 2001 1:02:03 AM +02:00 +02:00"}, + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), OFFSET_PTWO), FormatStyle.LONG, "October 2, 2001 1:02:03 AM +02:00 +02:00"}, + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), OFFSET_PTWO), FormatStyle.MEDIUM, "Oct 2, 2001 1:02:03 AM +02:00"}, + {ZonedDateTime.of(LocalDateTime.of(2001, 10, 2, 1, 2, 3), OFFSET_PTWO), FormatStyle.SHORT, "10/2/01 1:02 AM +02:00"}, + }; + } + + @Test(dataProvider = "formatStyle") + public void test_formatStyle(Temporal temporal, FormatStyle style, String formattedStr) { + DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder(); + DateTimeFormatter formatter = builder.appendLocalized(style, style).appendLiteral(" ").appendZoneOrOffsetId().toFormatter(); + assertEquals(formatter.format(temporal), formattedStr); + } +} diff --git a/jdk/test/java/time/tck/java/time/format/TCKResolverStyle.java b/jdk/test/java/time/tck/java/time/format/TCKResolverStyle.java new file mode 100644 index 00000000000..ef4bbb24b2d --- /dev/null +++ b/jdk/test/java/time/tck/java/time/format/TCKResolverStyle.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * 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. + * + * * Redistributions 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 JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.format; + +import java.util.HashMap; +import java.util.Map; + +import java.time.DateTimeException; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.ResolverStyle; +import java.time.temporal.ChronoField; +import java.time.temporal.TemporalAccessor; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Test. + */ +@Test +public class TCKResolverStyle { + + //----------------------------------------------------------------------- + // valueOf() + //----------------------------------------------------------------------- + @Test + public void test_valueOf() { + for (ResolverStyle style : ResolverStyle.values()) { + assertEquals(ResolverStyle.valueOf(style.name()), style); + } + } + + @DataProvider(name="resolverStyle") + Object[][] data_resolverStyle() { + return new Object[][] { + {"2000/15/30", ResolverStyle.LENIENT, null, 2001, 3, 30}, + {"2000/02/30", ResolverStyle.SMART, null, 2000, 2, 29}, + {"2000/02/29", ResolverStyle.STRICT, null, 2000, 2, 29}, + + {"2000/15/30 CE", ResolverStyle.LENIENT, null, 2001, 3, 30}, + {"2000/02/30 CE", ResolverStyle.SMART, null, 2000, 2, 29}, + {"5/02/29 BCE", ResolverStyle.STRICT, null, 5, 2, 29}, + + {"4/02/29 BCE", ResolverStyle.STRICT, DateTimeException.class, -1, -1, -1}, + {"2000/02/30 CE", ResolverStyle.STRICT, DateTimeException.class, -1, -1, -1}, + + }; + } + + @Test(dataProvider = "resolverStyle") + public void test_resolverStyle(String str, ResolverStyle style, Class expectedEx, int year, int month, int day) { + DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder(); + builder.appendValue(ChronoField.YEAR_OF_ERA); + builder.appendLiteral("/"); + builder.appendValue(ChronoField.MONTH_OF_YEAR); + builder.appendLiteral("/"); + builder.appendValue(ChronoField.DAY_OF_MONTH); + + Map eraMap = new HashMap(); + eraMap.put(1L, "CE"); + eraMap.put(0L, "BCE"); + DateTimeFormatter optionalFormatter = new DateTimeFormatterBuilder().appendLiteral(" ").appendText(ChronoField.ERA, eraMap).toFormatter(); + + DateTimeFormatter formatter = builder.appendOptional(optionalFormatter).toFormatter(); + formatter = formatter.withResolverStyle(style); + if (expectedEx == null) { + TemporalAccessor accessor = formatter.parse(str); + assertEquals(accessor.get(ChronoField.YEAR_OF_ERA), year); + assertEquals(accessor.get(ChronoField.MONTH_OF_YEAR), month); + assertEquals(accessor.get(ChronoField.DAY_OF_MONTH), day); + } else { + try { + formatter.parse(str); + fail(); + } catch (Exception ex) { + assertTrue(expectedEx.isInstance(ex)); + } + } + } +} diff --git a/jdk/test/java/time/tck/java/time/format/TCKSignStyle.java b/jdk/test/java/time/tck/java/time/format/TCKSignStyle.java new file mode 100644 index 00000000000..a6faec3fd83 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/format/TCKSignStyle.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * 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. + * + * * Redistributions 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 JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.format; + +import java.time.DateTimeException; +import java.time.LocalDate; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.format.SignStyle; +import java.time.temporal.ChronoField; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Test. + */ +@Test +public class TCKSignStyle { + + //----------------------------------------------------------------------- + // valueOf() + //----------------------------------------------------------------------- + @Test + public void test_valueOf() { + for (SignStyle style : SignStyle.values()) { + assertEquals(SignStyle.valueOf(style.name()), style); + } + } + + @DataProvider(name="signStyle") + Object[][] data_signStyle() { + return new Object[][] { + {LocalDate.of(0, 10, 2), SignStyle.ALWAYS, null, "+00"}, + {LocalDate.of(2001, 10, 2), SignStyle.ALWAYS, null, "+2001"}, + {LocalDate.of(-2001, 10, 2), SignStyle.ALWAYS, null, "-2001"}, + + {LocalDate.of(2001, 10, 2), SignStyle.NORMAL, null, "2001"}, + {LocalDate.of(-2001, 10, 2), SignStyle.NORMAL, null, "-2001"}, + + {LocalDate.of(2001, 10, 2), SignStyle.NEVER, null, "2001"}, + {LocalDate.of(-2001, 10, 2), SignStyle.NEVER, null, "2001"}, + + {LocalDate.of(2001, 10, 2), SignStyle.NOT_NEGATIVE, null, "2001"}, + {LocalDate.of(-2001, 10, 2), SignStyle.NOT_NEGATIVE, DateTimeException.class, ""}, + + {LocalDate.of(0, 10, 2), SignStyle.EXCEEDS_PAD, null, "00"}, + {LocalDate.of(1, 10, 2), SignStyle.EXCEEDS_PAD, null, "01"}, + {LocalDate.of(-1, 10, 2), SignStyle.EXCEEDS_PAD, null, "-01"}, + + {LocalDate.of(20001, 10, 2), SignStyle.ALWAYS, DateTimeException.class, ""}, + {LocalDate.of(20001, 10, 2), SignStyle.NORMAL, DateTimeException.class, ""}, + {LocalDate.of(20001, 10, 2), SignStyle.NEVER, DateTimeException.class, ""}, + {LocalDate.of(20001, 10, 2), SignStyle.EXCEEDS_PAD, DateTimeException.class, ""}, + {LocalDate.of(20001, 10, 2), SignStyle.NOT_NEGATIVE, DateTimeException.class, ""}, + }; + } + + @Test(dataProvider = "signStyle") + public void test_signStyle(LocalDate localDate, SignStyle style, Class expectedEx, String expectedStr) { + DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder(); + DateTimeFormatter formatter = builder.appendValue(ChronoField.YEAR, 2, 4, style) + .toFormatter(); + formatter = formatter.withZone(ZoneOffset.UTC); + if (expectedEx == null) { + String output = formatter.format(localDate); + assertEquals(output, expectedStr); + } else { + try { + formatter.format(localDate); + fail(); + } catch (Exception ex) { + assertTrue(expectedEx.isInstance(ex)); + } + } + } + +} diff --git a/jdk/test/java/time/tck/java/time/format/TCKTextStyle.java b/jdk/test/java/time/tck/java/time/format/TCKTextStyle.java index 344a8709ca2..68da619751a 100644 --- a/jdk/test/java/time/tck/java/time/format/TCKTextStyle.java +++ b/jdk/test/java/time/tck/java/time/format/TCKTextStyle.java @@ -91,4 +91,14 @@ public class TCKTextStyle { assertTrue(!TextStyle.NARROW.isStandalone()); } + //----------------------------------------------------------------------- + // valueOf() + //----------------------------------------------------------------------- + @Test + public void test_valueOf() { + for (TextStyle style : TextStyle.values()) { + assertEquals(TextStyle.valueOf(style.name()), style); + } + } + } diff --git a/jdk/test/java/time/tck/java/time/format/TCKZoneIdPrinterParser.java b/jdk/test/java/time/tck/java/time/format/TCKZoneIdPrinterParser.java index f6c4c46f2a1..414d390c610 100644 --- a/jdk/test/java/time/tck/java/time/format/TCKZoneIdPrinterParser.java +++ b/jdk/test/java/time/tck/java/time/format/TCKZoneIdPrinterParser.java @@ -60,16 +60,20 @@ package tck.java.time.format; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; import java.text.ParsePosition; +import java.time.DateTimeException; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalQuery; import java.util.Locale; +import java.util.Objects; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; @@ -148,43 +152,44 @@ public class TCKZoneIdPrinterParser { @DataProvider(name="parseSuccess") Object[][] data_parseSuccess() { return new Object[][] { - {"Z", 1, -1, ZoneOffset.UTC}, - {"UTC", 3, -1, ZoneOffset.UTC}, - {"UT", 2, -1, ZoneOffset.UTC}, - {"GMT", 3, -1, ZoneOffset.UTC}, - {"UTC0", 4, -1, ZoneOffset.UTC}, - {"UT0", 3, -1, ZoneOffset.UTC}, - {"GMT0", 4, -1, ZoneOffset.UTC}, + {"Z", 1, -1, ZoneId.of("Z")}, + {"UTC", 3, -1, ZoneId.of("UTC")}, + {"UT", 2, -1, ZoneId.of("UT")}, + {"GMT", 3, -1, ZoneId.of("GMT")}, {"+00:00", 6, -1, ZoneOffset.UTC}, - {"UTC+00:00", 9, -1, ZoneOffset.UTC}, - {"UT+00:00", 8, -1, ZoneOffset.UTC}, - {"GMT+00:00", 9, -1, ZoneOffset.UTC}, + {"UTC+00:00", 9, -1, ZoneId.of("UTC")}, + {"UT+00:00", 8, -1, ZoneId.of("UT")}, + {"GMT+00:00", 9, -1, ZoneId.of("GMT")}, {"-00:00", 6, -1, ZoneOffset.UTC}, - {"UTC-00:00", 9, -1, ZoneOffset.UTC}, - {"UT-00:00", 8, -1, ZoneOffset.UTC}, - {"GMT-00:00", 9, -1, ZoneOffset.UTC}, + {"UTC-00:00", 9, -1, ZoneId.of("UTC")}, + {"UT-00:00", 8, -1, ZoneId.of("UT")}, + {"GMT-00:00", 9, -1, ZoneId.of("GMT")}, {"+01:30", 6, -1, ZoneOffset.ofHoursMinutes(1, 30)}, - {"UTC+01:30", 9, -1, ZoneOffset.ofHoursMinutes(1, 30)}, - {"UT+02:30", 8, -1, ZoneOffset.ofHoursMinutes(2, 30)}, - {"GMT+03:30", 9, -1, ZoneOffset.ofHoursMinutes(3, 30)}, + {"UTC+01:30", 9, -1, ZoneId.of("UTC+01:30")}, + {"UT+02:30", 8, -1, ZoneId.of("UT+02:30")}, + {"GMT+03:30", 9, -1, ZoneId.of("GMT+03:30")}, {"-01:30", 6, -1, ZoneOffset.ofHoursMinutes(-1, -30)}, - {"UTC-01:30", 9, -1, ZoneOffset.ofHoursMinutes(-1, -30)}, - {"UT-02:30", 8, -1, ZoneOffset.ofHoursMinutes(-2, -30)}, - {"GMT-03:30", 9, -1, ZoneOffset.ofHoursMinutes(-3, -30)}, + {"UTC-01:30", 9, -1, ZoneId.of("UTC-01:30")}, + {"UT-02:30", 8, -1, ZoneId.of("UT-02:30")}, + {"GMT-03:30", 9, -1, ZoneId.of("GMT-03:30")}, // fallback to UTC - {"UTC-01:WW", 3, -1, ZoneOffset.UTC}, - {"UT-02:WW", 2, -1, ZoneOffset.UTC}, - {"GMT-03:WW", 3, -1, ZoneOffset.UTC}, + {"UTC-01:WW", 3, -1, ZoneId.of("UTC")}, + {"UT-02:WW", 2, -1, ZoneId.of("UT")}, + {"GMT-03:WW", 3, -1, ZoneId.of("GMT")}, {"Z0", 1, -1, ZoneOffset.UTC}, - {"UTC1", 3, -1, ZoneOffset.UTC}, + {"UTC1", 3, -1, ZoneId.of("UTC")}, // Z not parsed as zero - {"UTCZ", 3, -1, ZoneOffset.UTC}, - {"UTZ", 2, -1, ZoneOffset.UTC}, - {"GMTZ", 3, -1, ZoneOffset.UTC}, + {"UTCZ", 3, -1, ZoneId.of("UTC")}, + {"UTZ", 2, -1, ZoneId.of("UT")}, + {"GMTZ", 3, -1, ZoneId.of("GMT")}, + + // 0 not parsed + {"UTC0", 3, -1, ZoneId.of("UTC")}, + {"UT0", 2, -1, ZoneId.of("UT")}, // fail to parse {"", 0, 0, null}, @@ -206,12 +211,12 @@ public class TCKZoneIdPrinterParser { public void test_parseSuccess_plain(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) { builder.appendZoneId(); TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text, pos); - assertEquals(pos.getErrorIndex(), expectedErrorIndex); - assertEquals(pos.getIndex(), expectedIndex); + assertEquals(pos.getErrorIndex(), expectedErrorIndex, "Incorrect error index parsing: " + text); + assertEquals(pos.getIndex(), expectedIndex, "Incorrect index parsing: " + text); if (expected != null) { - assertEquals(parsed.query(TemporalQuery.zoneId()), expected); - assertEquals(parsed.query(TemporalQuery.offset()), null); - assertEquals(parsed.query(TemporalQuery.zone()), expected); + assertEquals(parsed.query(TemporalQuery.zoneId()), expected, "Incorrect zoneId parsing: " + text); + assertEquals(parsed.query(TemporalQuery.offset()), null, "Incorrect offset parsing: " + text); + assertEquals(parsed.query(TemporalQuery.zone()), expected, "Incorrect zone parsing: " + text); } else { assertEquals(parsed, null); } @@ -221,13 +226,14 @@ public class TCKZoneIdPrinterParser { public void test_parseSuccess_prefix(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) { builder.appendZoneId(); pos.setIndex(3); - TemporalAccessor parsed = builder.toFormatter().parseUnresolved("XXX" + text, pos); - assertEquals(pos.getErrorIndex(), expectedErrorIndex >= 0 ? expectedErrorIndex + 3 : expectedErrorIndex); - assertEquals(pos.getIndex(), expectedIndex + 3); + String prefixText = "XXX" + text; + TemporalAccessor parsed = builder.toFormatter().parseUnresolved(prefixText, pos); + assertEquals(pos.getErrorIndex(), expectedErrorIndex >= 0 ? expectedErrorIndex + 3 : expectedErrorIndex, "Incorrect error index parsing: " + prefixText); + assertEquals(pos.getIndex(), expectedIndex + 3, "Incorrect index parsing: " + prefixText); if (expected != null) { - assertEquals(parsed.query(TemporalQuery.zoneId()), expected); - assertEquals(parsed.query(TemporalQuery.offset()), null); - assertEquals(parsed.query(TemporalQuery.zone()), expected); + assertEquals(parsed.query(TemporalQuery.zoneId()), expected, "Incorrect zoneId parsing: " + prefixText); + assertEquals(parsed.query(TemporalQuery.offset()), null, "Incorrect offset parsing: " + prefixText); + assertEquals(parsed.query(TemporalQuery.zone()), expected, "Incorrect zone parsing: " + prefixText); } else { assertEquals(parsed, null); } @@ -236,13 +242,14 @@ public class TCKZoneIdPrinterParser { @Test(dataProvider="parseSuccess") public void test_parseSuccess_suffix(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) { builder.appendZoneId(); - TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text + "XXX", pos); - assertEquals(pos.getErrorIndex(), expectedErrorIndex); - assertEquals(pos.getIndex(), expectedIndex); + String suffixText = text + "XXX"; + TemporalAccessor parsed = builder.toFormatter().parseUnresolved(suffixText, pos); + assertEquals(pos.getErrorIndex(), expectedErrorIndex, "Incorrect error index parsing: " + suffixText); + assertEquals(pos.getIndex(), expectedIndex, "Incorrect index parsing: " + suffixText); if (expected != null) { - assertEquals(parsed.query(TemporalQuery.zoneId()), expected); - assertEquals(parsed.query(TemporalQuery.offset()), null); - assertEquals(parsed.query(TemporalQuery.zone()), expected); + assertEquals(parsed.query(TemporalQuery.zoneId()), expected, "Incorrect zoneId parsing: " + suffixText); + assertEquals(parsed.query(TemporalQuery.offset()), null, "Incorrect offset parsing: " + suffixText); + assertEquals(parsed.query(TemporalQuery.zone()), expected, "Incorrect zone parsing: " + suffixText); } else { assertEquals(parsed, null); } @@ -251,15 +258,16 @@ public class TCKZoneIdPrinterParser { @Test(dataProvider="parseSuccess") public void test_parseSuccess_caseSensitive(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) { builder.parseCaseSensitive().appendZoneId(); - TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text.toLowerCase(Locale.ENGLISH), pos); + String lcText = text.toLowerCase(Locale.ENGLISH); + TemporalAccessor parsed = builder.toFormatter().parseUnresolved(lcText, pos); if (text.matches("[^A-Z]*[A-Z].*")) { // if input has letters assertEquals(pos.getErrorIndex() >= 0, true); assertEquals(pos.getIndex(), 0); assertEquals(parsed, null); } else { // case sensitive made no difference - assertEquals(pos.getIndex(), expectedIndex); - assertEquals(pos.getErrorIndex(), expectedErrorIndex); + assertEquals(pos.getIndex(), expectedIndex, "Incorrect index parsing: " + lcText); + assertEquals(pos.getErrorIndex(), expectedErrorIndex, "Incorrect error index parsing: " + lcText); if (expected != null) { assertEquals(parsed.query(TemporalQuery.zoneId()), expected); assertEquals(parsed.query(TemporalQuery.offset()), null); @@ -273,13 +281,15 @@ public class TCKZoneIdPrinterParser { @Test(dataProvider="parseSuccess") public void test_parseSuccess_caseInsensitive(String text, int expectedIndex, int expectedErrorIndex, ZoneId expected) { builder.parseCaseInsensitive().appendZoneId(); - TemporalAccessor parsed = builder.toFormatter().parseUnresolved(text.toLowerCase(Locale.ENGLISH), pos); - assertEquals(pos.getErrorIndex(), expectedErrorIndex); - assertEquals(pos.getIndex(), expectedIndex); + String lcText = text.toLowerCase(Locale.ENGLISH); + TemporalAccessor parsed = builder.toFormatter().parseUnresolved(lcText, pos); + assertEquals(pos.getErrorIndex(), expectedErrorIndex, "Incorrect error index parsing: " + lcText); + assertEquals(pos.getIndex(), expectedIndex, "Incorrect index parsing: " + lcText); if (expected != null) { - assertEquals(parsed.query(TemporalQuery.zoneId()), expected); - assertEquals(parsed.query(TemporalQuery.offset()), null); - assertEquals(parsed.query(TemporalQuery.zone()), expected); + ZoneId zid = parsed.query(TemporalQuery.zoneId()); + assertEquals(parsed.query(TemporalQuery.zoneId()), expected, "Incorrect zoneId parsing: " + lcText); + assertEquals(parsed.query(TemporalQuery.offset()), null, "Incorrect offset parsing: " + lcText); + assertEquals(parsed.query(TemporalQuery.zone()), expected, "Incorrect zone parsing: " + lcText); } else { assertEquals(parsed, null); } diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKChronoField.java b/jdk/test/java/time/tck/java/time/temporal/TCKChronoField.java new file mode 100644 index 00000000000..1e6c9ea874b --- /dev/null +++ b/jdk/test/java/time/tck/java/time/temporal/TCKChronoField.java @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * 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. + * + * * Redistributions 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 JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal; + +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; +import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; +import static java.time.temporal.ChronoField.AMPM_OF_DAY; +import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_DAY; +import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM; +import static java.time.temporal.ChronoField.DAY_OF_MONTH; +import static java.time.temporal.ChronoField.DAY_OF_WEEK; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; +import static java.time.temporal.ChronoField.EPOCH_DAY; +import static java.time.temporal.ChronoField.HOUR_OF_DAY; +import static java.time.temporal.ChronoField.HOUR_OF_AMPM; +import static java.time.temporal.ChronoField.MICRO_OF_DAY; +import static java.time.temporal.ChronoField.MICRO_OF_SECOND; +import static java.time.temporal.ChronoField.MILLI_OF_DAY; +import static java.time.temporal.ChronoField.MILLI_OF_SECOND; +import static java.time.temporal.ChronoField.MINUTE_OF_DAY; +import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; +import static java.time.temporal.ChronoField.MONTH_OF_YEAR; +import static java.time.temporal.ChronoField.NANO_OF_DAY; +import static java.time.temporal.ChronoField.NANO_OF_SECOND; +import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; +import static java.time.temporal.ChronoField.SECOND_OF_DAY; +import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; +import static java.time.temporal.ChronoField.YEAR; +import static java.time.temporal.ChronoField.YEAR_OF_ERA; +import static java.time.temporal.ChronoField.ERA; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.FOREVER; +import static java.time.temporal.ChronoUnit.HOURS; +import static java.time.temporal.ChronoUnit.MICROS; +import static java.time.temporal.ChronoUnit.MILLIS; +import static java.time.temporal.ChronoUnit.MINUTES; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.NANOS; +import static java.time.temporal.ChronoUnit.SECONDS; +import static java.time.temporal.ChronoUnit.WEEKS; +import static java.time.temporal.ChronoUnit.YEARS; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.temporal.ChronoField; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.ValueRange; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Test. + */ +@Test +public class TCKChronoField { + + //----------------------------------------------------------------------- + // getBaseUnit() and getRangeUnit() + //----------------------------------------------------------------------- + @DataProvider(name="fieldUnit") + Object[][] data_fieldUnit() { + return new Object[][] { + {YEAR, YEARS, FOREVER}, + {MONTH_OF_YEAR, MONTHS, YEARS}, + {DAY_OF_MONTH, DAYS, MONTHS}, + {DAY_OF_WEEK, DAYS, WEEKS}, + {DAY_OF_YEAR, DAYS, YEARS}, + {HOUR_OF_DAY, HOURS, DAYS}, + {MINUTE_OF_DAY, MINUTES, DAYS}, + {MINUTE_OF_HOUR, MINUTES, HOURS}, + {SECOND_OF_DAY, SECONDS, DAYS}, + {SECOND_OF_MINUTE, SECONDS, MINUTES}, + {MILLI_OF_DAY, MILLIS, DAYS}, + {MILLI_OF_SECOND, MILLIS, SECONDS}, + {MICRO_OF_SECOND, MICROS, SECONDS}, + {MICRO_OF_DAY, MICROS, DAYS}, + {NANO_OF_SECOND, NANOS, SECONDS}, + {NANO_OF_DAY, NANOS, DAYS}, + + }; + } + + @Test(dataProvider = "fieldUnit") + public void test_getBaseUnit(ChronoField field, ChronoUnit baseUnit, ChronoUnit rangeUnit) { + assertEquals(field.getBaseUnit(), baseUnit); + assertEquals(field.getRangeUnit(), rangeUnit); + } + + //----------------------------------------------------------------------- + // isDateBased() and isTimeBased() + //----------------------------------------------------------------------- + @DataProvider(name="fieldBased") + Object[][] data_fieldBased() { + return new Object[][] { + {DAY_OF_WEEK, true, false}, + {ALIGNED_DAY_OF_WEEK_IN_MONTH, true, false}, + {ALIGNED_DAY_OF_WEEK_IN_YEAR, true, false}, + {DAY_OF_MONTH, true, false}, + {DAY_OF_YEAR, true, false}, + {EPOCH_DAY, true, false}, + {ALIGNED_WEEK_OF_MONTH, true, false}, + {ALIGNED_WEEK_OF_YEAR, true, false}, + {MONTH_OF_YEAR, true, false}, + {PROLEPTIC_MONTH, true, false}, + {YEAR_OF_ERA, true, false}, + {YEAR, true, false}, + {ERA, true, false}, + + {AMPM_OF_DAY, false, true}, + {CLOCK_HOUR_OF_DAY, false, true}, + {HOUR_OF_DAY, false, true}, + {CLOCK_HOUR_OF_AMPM, false, true}, + {HOUR_OF_AMPM, false, true}, + {MINUTE_OF_DAY, false, true}, + {MINUTE_OF_HOUR, false, true}, + {SECOND_OF_DAY, false, true}, + {SECOND_OF_MINUTE, false, true}, + {MILLI_OF_DAY, false, true}, + {MILLI_OF_SECOND, false, true}, + {MICRO_OF_DAY, false, true}, + {MICRO_OF_SECOND, false, true}, + {NANO_OF_DAY, false, true}, + {NANO_OF_SECOND, false, true}, + }; + } + + @Test(dataProvider = "fieldBased") + public void test_isDateBased(ChronoField field, boolean isDateBased, boolean isTimeBased) { + assertEquals(field.isDateBased(), isDateBased); + assertEquals(field.isTimeBased(), isTimeBased); + } + + //----------------------------------------------------------------------- + // isSupportedBy(TemporalAccessor temporal) and getFrom(TemporalAccessor temporal) + //----------------------------------------------------------------------- + @DataProvider(name="fieldAndAccessor") + Object[][] data_fieldAndAccessor() { + return new Object[][] { + {YEAR, LocalDate.of(2000, 2, 29), true, 2000}, + {YEAR, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 2000}, + {MONTH_OF_YEAR, LocalDate.of(2000, 2, 29), true, 2}, + {MONTH_OF_YEAR, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 2}, + {DAY_OF_MONTH, LocalDate.of(2000, 2, 29), true, 29}, + {DAY_OF_MONTH, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 29}, + {DAY_OF_YEAR, LocalDate.of(2000, 2, 29), true, 60}, + {DAY_OF_YEAR, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 60}, + + {HOUR_OF_DAY, LocalTime.of(5, 4, 3, 200), true, 5}, + {HOUR_OF_DAY, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 5}, + + {MINUTE_OF_DAY, LocalTime.of(5, 4, 3, 200), true, 5*60 + 4}, + {MINUTE_OF_DAY, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 5*60 + 4}, + {MINUTE_OF_HOUR, LocalTime.of(5, 4, 3, 200), true, 4}, + {MINUTE_OF_HOUR, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 4}, + + {SECOND_OF_DAY, LocalTime.of(5, 4, 3, 200), true, 5*3600 + 4*60 + 3}, + {SECOND_OF_DAY, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 5*3600 + 4*60 + 3}, + {SECOND_OF_MINUTE, LocalTime.of(5, 4, 3, 200), true, 3}, + {SECOND_OF_MINUTE, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 3}, + + {NANO_OF_SECOND, LocalTime.of(5, 4, 3, 200), true, 200}, + {NANO_OF_SECOND, LocalDateTime.of(2000, 2, 29, 5, 4, 3, 200), true, 200}, + + {YEAR, LocalTime.of(5, 4, 3, 200), false, -1}, + {MONTH_OF_YEAR, LocalTime.of(5, 4, 3, 200), false, -1}, + {DAY_OF_MONTH, LocalTime.of(5, 4, 3, 200), false, -1}, + {DAY_OF_YEAR, LocalTime.of(5, 4, 3, 200), false, -1}, + {HOUR_OF_DAY, LocalDate.of(2000, 2, 29), false, -1}, + {MINUTE_OF_DAY, LocalDate.of(2000, 2, 29), false, -1}, + {MINUTE_OF_HOUR, LocalDate.of(2000, 2, 29), false, -1}, + {SECOND_OF_DAY, LocalDate.of(2000, 2, 29), false, -1}, + {SECOND_OF_MINUTE, LocalDate.of(2000, 2, 29), false, -1}, + {NANO_OF_SECOND, LocalDate.of(2000, 2, 29), false, -1}, + }; + } + + @Test(dataProvider = "fieldAndAccessor") + public void test_supportedAccessor(ChronoField field, TemporalAccessor accessor, boolean isSupported, long value) { + assertEquals(field.isSupportedBy(accessor), isSupported); + if (isSupported) { + assertEquals(field.getFrom(accessor), value); + } + } + + //----------------------------------------------------------------------- + // range() and rangeRefinedBy(TemporalAccessor temporal) + //----------------------------------------------------------------------- + @Test + public void test_range() { + assertEquals(MONTH_OF_YEAR.range(), ValueRange.of(1, 12)); + assertEquals(MONTH_OF_YEAR.rangeRefinedBy(LocalDate.of(2000, 2, 29)), ValueRange.of(1, 12)); + + assertEquals(DAY_OF_MONTH.range(), ValueRange.of(1, 28, 31)); + assertEquals(DAY_OF_MONTH.rangeRefinedBy(LocalDate.of(2000, 2, 29)), ValueRange.of(1, 29)); + } + + //----------------------------------------------------------------------- + // valueOf() + //----------------------------------------------------------------------- + @Test + public void test_valueOf() { + for (ChronoField field : ChronoField.values()) { + assertEquals(ChronoField.valueOf(field.name()), field); + } + } +} diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKChronoUnit.java b/jdk/test/java/time/tck/java/time/temporal/TCKChronoUnit.java new file mode 100644 index 00000000000..a117030dda1 --- /dev/null +++ b/jdk/test/java/time/tck/java/time/temporal/TCKChronoUnit.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute 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. + */ + +/* + * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos + * + * 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. + * + * * Redistributions 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 JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package tck.java.time.temporal; + +import static java.time.temporal.ChronoUnit.CENTURIES; +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.DECADES; +import static java.time.temporal.ChronoUnit.ERAS; +import static java.time.temporal.ChronoUnit.FOREVER; +import static java.time.temporal.ChronoUnit.HALF_DAYS; +import static java.time.temporal.ChronoUnit.HOURS; +import static java.time.temporal.ChronoUnit.MICROS; +import static java.time.temporal.ChronoUnit.MILLENNIA; +import static java.time.temporal.ChronoUnit.MILLIS; +import static java.time.temporal.ChronoUnit.MINUTES; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.NANOS; +import static java.time.temporal.ChronoUnit.SECONDS; +import static java.time.temporal.ChronoUnit.WEEKS; +import static java.time.temporal.ChronoUnit.YEARS; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.temporal.ChronoField; +import java.time.temporal.ChronoUnit; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAccessor; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * Test. + */ +@Test +public class TCKChronoUnit { + + //----------------------------------------------------------------------- + // isDateBased(), isTimeBased() and isDurationEstimated() + //----------------------------------------------------------------------- + @DataProvider(name="chronoUnit") + Object[][] data_chronoUnit() { + return new Object[][] { + {FOREVER, false, false, true}, + {ERAS, true, false, true}, + {MILLENNIA, true, false, true}, + {CENTURIES, true, false, true}, + {DECADES, true, false, true}, + {YEARS, true, false, true}, + {MONTHS, true, false, true}, + {WEEKS, true, false, true}, + {DAYS, true, false, true}, + + {HALF_DAYS, false, true, false}, + {HOURS, false, true, false}, + {MINUTES, false, true, false}, + {SECONDS, false, true, false}, + {MICROS, false, true, false}, + {MILLIS, false, true, false}, + {NANOS, false, true, false}, + + }; + } + + @Test(dataProvider = "chronoUnit") + public void test_unitType(ChronoUnit unit, boolean isDateBased, boolean isTimeBased, boolean isDurationEstimated) { + assertEquals(unit.isDateBased(), isDateBased); + assertEquals(unit.isTimeBased(), isTimeBased); + assertEquals(unit.isDurationEstimated(), isDurationEstimated); + } + + //----------------------------------------------------------------------- + // isSupportedBy(), addTo() and between() + //----------------------------------------------------------------------- + @DataProvider(name="unitAndTemporal") + Object[][] data_unitAndTemporal() { + return new Object[][] { + {CENTURIES, LocalDate.of(2000, 1, 10), true, 1, LocalDate.of(2100, 1, 10)}, + {DECADES, LocalDate.of(2000, 1, 10), true, 1, LocalDate.of(2010, 1, 10)}, + {YEARS, LocalDate.of(2000, 1, 10), true, 1, LocalDate.of(2001, 1, 10)}, + {MONTHS, LocalDate.of(2000, 1, 10), true, 1, LocalDate.of(2000, 2, 10)}, + {WEEKS, LocalDate.of(2000, 1, 10), true, 1, LocalDate.of(2000, 1, 17)}, + {DAYS, LocalDate.of(2000, 1, 10), true, 1, LocalDate.of(2000, 1, 11)}, + + {HALF_DAYS, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(13, 2, 3, 400)}, + {HOURS, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(2, 2, 3, 400)}, + {MINUTES, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(1, 3, 3, 400)}, + {SECONDS, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(1, 2, 4, 400)}, + {MICROS, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(1, 2, 3, 1000 + 400)}, + {MILLIS, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(1, 2, 3, 1000*1000 + 400)}, + {NANOS, LocalTime.of(1, 2, 3, 400), true, 1, LocalTime.of(1, 2, 3, 1 + 400)}, + + {CENTURIES, LocalTime.of(1, 2, 3, 400), false, 1, null}, + {DECADES, LocalTime.of(1, 2, 3, 400), false, 1, null}, + {YEARS, LocalTime.of(1, 2, 3, 400), false, 1, null}, + {MONTHS, LocalTime.of(1, 2, 3, 400), false, 1, null}, + {WEEKS, LocalTime.of(1, 2, 3, 400), false, 1, null}, + {DAYS, LocalTime.of(1, 2, 3, 400), false, 1, null}, + + {HALF_DAYS, LocalDate.of(2000, 2, 29), false, 1, null}, + {HOURS, LocalDate.of(2000, 2, 29), false, 1, null}, + {MINUTES, LocalDate.of(2000, 2, 29), false, 1, null}, + {SECONDS, LocalDate.of(2000, 2, 29), false, 1, null}, + {MICROS, LocalDate.of(2000, 2, 29), false, 1, null}, + {MILLIS, LocalDate.of(2000, 2, 29), false, 1, null}, + {NANOS, LocalDate.of(2000, 2, 29), false, 1, null}, + + }; + } + + @Test(dataProvider = "unitAndTemporal") + public void test_unitAndTemporal(ChronoUnit unit, Temporal base, boolean isSupportedBy, long amount, Temporal target) { + assertEquals(unit.isSupportedBy(base), isSupportedBy); + if (isSupportedBy) { + Temporal result = unit.addTo(base, amount); + assertEquals(result, target); + assertEquals(unit.between(base, result), amount); + } + } + + //----------------------------------------------------------------------- + // valueOf() + //----------------------------------------------------------------------- + @Test + public void test_valueOf() { + for (ChronoUnit unit : ChronoUnit.values()) { + assertEquals(ChronoUnit.valueOf(unit.name()), unit); + } + } +} diff --git a/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java b/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java index ccb1a4ca7b9..4367ee92511 100644 --- a/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java +++ b/jdk/test/java/time/tck/java/time/temporal/TCKWeekFields.java @@ -56,16 +56,22 @@ */ package tck.java.time.temporal; +import static java.time.format.ResolverStyle.LENIENT; +import static java.time.format.ResolverStyle.SMART; +import static java.time.format.ResolverStyle.STRICT; import static java.time.temporal.ChronoField.DAY_OF_MONTH; import static java.time.temporal.ChronoField.DAY_OF_WEEK; import static java.time.temporal.ChronoField.DAY_OF_YEAR; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.YEAR; - import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertSame; +import static org.testng.Assert.assertTrue; import java.io.IOException; +import java.time.DateTimeException; import java.time.DayOfWeek; import java.time.LocalDate; import java.time.format.DateTimeFormatter; @@ -376,14 +382,13 @@ public class TCKWeekFields extends AbstractTCKTest { TemporalField womField = week.weekOfMonth(); for (int i = 1; i <= 60; i++) { - // Test that with dayOfWeek and Week of month it computes the date DateTimeFormatter f = new DateTimeFormatterBuilder() - .appendValue(YEAR).appendLiteral('-') - .appendValue(MONTH_OF_YEAR).appendLiteral('-') - .appendValue(womField).appendLiteral('-') - .appendValue(DAY_OF_WEEK).toFormatter(); - String str = date.getYear() + "-" + date.getMonthValue() + "-" + - date.get(womField) + "-" + date.get(DAY_OF_WEEK); + .appendValue(YEAR).appendLiteral(':') + .appendValue(MONTH_OF_YEAR).appendLiteral(':') + .appendValue(womField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(SMART); + String str = date.getYear() + ":" + date.getMonthValue() + ":" + + date.get(womField) + ":" + date.get(DAY_OF_WEEK); LocalDate parsed = LocalDate.parse(str, f); assertEquals(parsed, date, " ::" + str + "::" + i); @@ -391,6 +396,52 @@ public class TCKWeekFields extends AbstractTCKTest { } } + @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWom_lenient(DayOfWeek firstDayOfWeek, int minDays) { + LocalDate date = LocalDate.of(2012, 12, 15); + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField womField = week.weekOfMonth(); + + for (int i = 1; i <= 60; i++) { + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(YEAR).appendLiteral(':') + .appendValue(MONTH_OF_YEAR).appendLiteral(':') + .appendValue(womField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(LENIENT); + int wom = date.get(womField); + int dow = date.get(DAY_OF_WEEK); + for (int j = wom - 10; j < wom + 10; j++) { + String str = date.getYear() + ":" + date.getMonthValue() + ":" + j + ":" + dow; + LocalDate parsed = LocalDate.parse(str, f); + assertEquals(parsed, date.plusWeeks(j - wom), " ::" + str + ": :" + i + "::" + j); + } + + date = date.plusDays(1); + } + } + + @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWom_strict(DayOfWeek firstDayOfWeek, int minDays) { + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField womField = week.weekOfMonth(); + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(YEAR).appendLiteral(':') + .appendValue(MONTH_OF_YEAR).appendLiteral(':') + .appendValue(womField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(STRICT); + String str = "2012:1:0:1"; + try { + LocalDate date = LocalDate.parse(str, f); + assertEquals(date.getYear(), 2012); + assertEquals(date.getMonthValue(), 1); + assertEquals(date.get(womField), 0); + assertEquals(date.get(DAY_OF_WEEK), 1); + } catch (DateTimeException ex) { + // expected + } + } + + //----------------------------------------------------------------------- @Test(dataProvider="weekFields") public void test_parse_resolve_localizedWomDow(DayOfWeek firstDayOfWeek, int minDays) { LocalDate date = LocalDate.of(2012, 12, 15); @@ -399,14 +450,13 @@ public class TCKWeekFields extends AbstractTCKTest { TemporalField womField = week.weekOfMonth(); for (int i = 1; i <= 15; i++) { - // Test that with dayOfWeek and Week of month it computes the date DateTimeFormatter f = new DateTimeFormatterBuilder() - .appendValue(YEAR).appendLiteral('-') - .appendValue(MONTH_OF_YEAR).appendLiteral('-') - .appendValue(womField).appendLiteral('-') + .appendValue(YEAR).appendLiteral(':') + .appendValue(MONTH_OF_YEAR).appendLiteral(':') + .appendValue(womField).appendLiteral(':') .appendValue(dowField).toFormatter(); - String str = date.getYear() + "-" + date.getMonthValue() + "-" + - date.get(womField) + "-" + date.get(dowField); + String str = date.getYear() + ":" + date.getMonthValue() + ":" + + date.get(womField) + ":" + date.get(dowField); LocalDate parsed = LocalDate.parse(str, f); assertEquals(parsed, date, " :: " + str + " " + i); @@ -414,6 +464,32 @@ public class TCKWeekFields extends AbstractTCKTest { } } + @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWomDow_lenient(DayOfWeek firstDayOfWeek, int minDays) { + LocalDate date = LocalDate.of(2012, 12, 15); + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField dowField = week.dayOfWeek(); + TemporalField womField = week.weekOfMonth(); + + for (int i = 1; i <= 60; i++) { + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(YEAR).appendLiteral(':') + .appendValue(MONTH_OF_YEAR).appendLiteral(':') + .appendValue(womField).appendLiteral(':') + .appendValue(dowField).toFormatter().withResolverStyle(LENIENT); + int wom = date.get(womField); + int dow = date.get(dowField); + for (int j = wom - 10; j < wom + 10; j++) { + String str = date.getYear() + ":" + date.getMonthValue() + ":" + j + ":" + dow; + LocalDate parsed = LocalDate.parse(str, f); + assertEquals(parsed, date.plusWeeks(j - wom), " ::" + str + ": :" + i + "::" + j); + } + + date = date.plusDays(1); + } + } + + //----------------------------------------------------------------------- @Test(dataProvider="weekFields") public void test_parse_resolve_localizedWoy(DayOfWeek firstDayOfWeek, int minDays) { LocalDate date = LocalDate.of(2012, 12, 15); @@ -421,14 +497,12 @@ public class TCKWeekFields extends AbstractTCKTest { TemporalField woyField = week.weekOfYear(); for (int i = 1; i <= 60; i++) { - // Test that with dayOfWeek and Week of month it computes the date DateTimeFormatter f = new DateTimeFormatterBuilder() - .appendValue(YEAR).appendLiteral('-') - .appendValue(MONTH_OF_YEAR).appendLiteral('-') - .appendValue(woyField).appendLiteral('-') + .appendValue(YEAR).appendLiteral(':') + .appendValue(woyField).appendLiteral(':') .appendValue(DAY_OF_WEEK).toFormatter(); - String str = date.getYear() + "-" + date.getMonthValue() + "-" + - date.get(woyField) + "-" + date.get(DAY_OF_WEEK); + String str = date.getYear() + ":" + + date.get(woyField) + ":" + date.get(DAY_OF_WEEK); LocalDate parsed = LocalDate.parse(str, f); assertEquals(parsed, date, " :: " + str + " " + i); @@ -436,6 +510,49 @@ public class TCKWeekFields extends AbstractTCKTest { } } + @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWoy_lenient(DayOfWeek firstDayOfWeek, int minDays) { + LocalDate date = LocalDate.of(2012, 12, 15); + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField woyField = week.weekOfYear(); + + for (int i = 1; i <= 60; i++) { + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(YEAR).appendLiteral(':') + .appendValue(woyField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(LENIENT); + int woy = date.get(woyField); + int dow = date.get(DAY_OF_WEEK); + for (int j = woy - 60; j < woy + 60; j++) { + String str = date.getYear() + ":" + j + ":" + dow; + LocalDate parsed = LocalDate.parse(str, f); + assertEquals(parsed, date.plusWeeks(j - woy), " ::" + str + ": :" + i + "::" + j); + } + + date = date.plusDays(1); + } + } + + @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWoy_strict(DayOfWeek firstDayOfWeek, int minDays) { + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField woyField = week.weekOfYear(); + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(YEAR).appendLiteral(':') + .appendValue(woyField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(STRICT); + String str = "2012:0:1"; + try { + LocalDate date = LocalDate.parse(str, f); + assertEquals(date.getYear(), 2012); + assertEquals(date.get(woyField), 0); + assertEquals(date.get(DAY_OF_WEEK), 1); + } catch (DateTimeException ex) { + // expected + } + } + + //----------------------------------------------------------------------- @Test(dataProvider="weekFields") public void test_parse_resolve_localizedWoyDow(DayOfWeek firstDayOfWeek, int minDays) { LocalDate date = LocalDate.of(2012, 12, 15); @@ -444,14 +561,13 @@ public class TCKWeekFields extends AbstractTCKTest { TemporalField woyField = week.weekOfYear(); for (int i = 1; i <= 60; i++) { - // Test that with dayOfWeek and Week of month it computes the date DateTimeFormatter f = new DateTimeFormatterBuilder() - .appendValue(YEAR).appendLiteral('-') - .appendValue(MONTH_OF_YEAR).appendLiteral('-') - .appendValue(woyField).appendLiteral('-') + .appendValue(YEAR).appendLiteral(':') + .appendValue(MONTH_OF_YEAR).appendLiteral(':') + .appendValue(woyField).appendLiteral(':') .appendValue(dowField).toFormatter(); - String str = date.getYear() + "-" + date.getMonthValue() + "-" + - date.get(woyField) + "-" + date.get(dowField); + String str = date.getYear() + ":" + date.getMonthValue() + ":" + + date.get(woyField) + ":" + date.get(dowField); LocalDate parsed = LocalDate.parse(str, f); assertEquals(parsed, date, " :: " + str + " " + i); @@ -459,6 +575,31 @@ public class TCKWeekFields extends AbstractTCKTest { } } + @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWoyDow_lenient(DayOfWeek firstDayOfWeek, int minDays) { + LocalDate date = LocalDate.of(2012, 12, 15); + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField dowField = week.dayOfWeek(); + TemporalField woyField = week.weekOfYear(); + + for (int i = 1; i <= 60; i++) { + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(YEAR).appendLiteral(':') + .appendValue(woyField).appendLiteral(':') + .appendValue(dowField).toFormatter().withResolverStyle(LENIENT); + int woy = date.get(woyField); + int dow = date.get(dowField); + for (int j = woy - 60; j < woy + 60; j++) { + String str = date.getYear() + ":" + j + ":" + dow; + LocalDate parsed = LocalDate.parse(str, f); + assertEquals(parsed, date.plusWeeks(j - woy), " ::" + str + ": :" + i + "::" + j); + } + + date = date.plusDays(1); + } + } + + //----------------------------------------------------------------------- @Test(dataProvider="weekFields") public void test_parse_resolve_localizedWoWBY(DayOfWeek firstDayOfWeek, int minDays) { LocalDate date = LocalDate.of(2012, 12, 31); @@ -467,12 +608,11 @@ public class TCKWeekFields extends AbstractTCKTest { TemporalField yowbyField = week.weekBasedYear(); for (int i = 1; i <= 60; i++) { - // Test that with dayOfWeek, week of year and year of week-based-year it computes the date DateTimeFormatter f = new DateTimeFormatterBuilder() - .appendValue(yowbyField).appendLiteral('-') - .appendValue(wowbyField).appendLiteral('-') + .appendValue(yowbyField).appendLiteral(':') + .appendValue(wowbyField).appendLiteral(':') .appendValue(DAY_OF_WEEK).toFormatter(); - String str = date.get(yowbyField) + "-" + date.get(wowbyField) + "-" + + String str = date.get(yowbyField) + ":" + date.get(wowbyField) + ":" + date.get(DAY_OF_WEEK); LocalDate parsed = LocalDate.parse(str, f); assertEquals(parsed, date, " :: " + str + " " + i); @@ -481,6 +621,51 @@ public class TCKWeekFields extends AbstractTCKTest { } } + @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWoWBY_lenient(DayOfWeek firstDayOfWeek, int minDays) { + LocalDate date = LocalDate.of(2012, 12, 31); + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField wowbyField = week.weekOfWeekBasedYear(); + TemporalField yowbyField = week.weekBasedYear(); + + for (int i = 1; i <= 60; i++) { + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(yowbyField).appendLiteral(':') + .appendValue(wowbyField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(LENIENT); + int wowby = date.get(wowbyField); + int dow = date.get(DAY_OF_WEEK); + for (int j = wowby - 60; j < wowby + 60; j++) { + String str = date.get(yowbyField) + ":" + j + ":" + dow; + LocalDate parsed = LocalDate.parse(str, f); + assertEquals(parsed, date.plusWeeks(j - wowby), " ::" + str + ": :" + i + "::" + j); + } + + date = date.plusDays(1); + } + } + + @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWoWBY_strict(DayOfWeek firstDayOfWeek, int minDays) { + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField wowbyField = week.weekOfWeekBasedYear(); + TemporalField yowbyField = week.weekBasedYear(); + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(yowbyField).appendLiteral(':') + .appendValue(wowbyField).appendLiteral(':') + .appendValue(DAY_OF_WEEK).toFormatter().withResolverStyle(STRICT); + String str = "2012:0:1"; + try { + LocalDate date = LocalDate.parse(str, f); + assertEquals(date.get(yowbyField), 2012); + assertEquals(date.get(wowbyField), 0); + assertEquals(date.get(DAY_OF_WEEK), 1); + } catch (DateTimeException ex) { + // expected + } + } + + //----------------------------------------------------------------------- @Test(dataProvider="weekFields") public void test_parse_resolve_localizedWoWBYDow(DayOfWeek firstDayOfWeek, int minDays) { LocalDate date = LocalDate.of(2012, 12, 31); @@ -490,12 +675,11 @@ public class TCKWeekFields extends AbstractTCKTest { TemporalField yowbyField = week.weekBasedYear(); for (int i = 1; i <= 60; i++) { - // Test that with dayOfWeek, week of year and year of week-based-year it computes the date DateTimeFormatter f = new DateTimeFormatterBuilder() - .appendValue(yowbyField).appendLiteral('-') - .appendValue(wowbyField).appendLiteral('-') + .appendValue(yowbyField).appendLiteral(':') + .appendValue(wowbyField).appendLiteral(':') .appendValue(dowField).toFormatter(); - String str = date.get(yowbyField) + "-" + date.get(wowbyField) + "-" + + String str = date.get(yowbyField) + ":" + date.get(wowbyField) + ":" + date.get(dowField); LocalDate parsed = LocalDate.parse(str, f); assertEquals(parsed, date, " :: " + str + " " + i); @@ -504,6 +688,31 @@ public class TCKWeekFields extends AbstractTCKTest { } } + @Test(dataProvider="weekFields") + public void test_parse_resolve_localizedWoWBYDow_lenient(DayOfWeek firstDayOfWeek, int minDays) { + LocalDate date = LocalDate.of(2012, 12, 31); + WeekFields week = WeekFields.of(firstDayOfWeek, minDays); + TemporalField dowField = week.dayOfWeek(); + TemporalField wowbyField = week.weekOfWeekBasedYear(); + TemporalField yowbyField = week.weekBasedYear(); + + for (int i = 1; i <= 60; i++) { + DateTimeFormatter f = new DateTimeFormatterBuilder() + .appendValue(yowbyField).appendLiteral(':') + .appendValue(wowbyField).appendLiteral(':') + .appendValue(dowField).toFormatter().withResolverStyle(LENIENT); + int wowby = date.get(wowbyField); + int dow = date.get(dowField); + for (int j = wowby - 60; j < wowby + 60; j++) { + String str = date.get(yowbyField) + ":" + j + ":" + dow; + LocalDate parsed = LocalDate.parse(str, f); + assertEquals(parsed, date.plusWeeks(j - wowby), " ::" + str + ": :" + i + "::" + j); + } + + date = date.plusDays(1); + } + } + //----------------------------------------------------------------------- @Test(dataProvider="weekFields") public void test_serializable_singleton(DayOfWeek firstDayOfWeek, int minDays) throws IOException, ClassNotFoundException { @@ -587,4 +796,21 @@ public class TCKWeekFields extends AbstractTCKTest { assertEquals(date.get(yowbyField), wby); } + //----------------------------------------------------------------------- + // equals() and hashCode(). + //----------------------------------------------------------------------- + @Test + public void test_equals() { + WeekFields weekDef_iso = WeekFields.ISO; + WeekFields weekDef_sundayStart = WeekFields.SUNDAY_START; + + assertTrue(weekDef_iso.equals(WeekFields.of(DayOfWeek.MONDAY, 4))); + assertTrue(weekDef_sundayStart.equals(WeekFields.of(DayOfWeek.SUNDAY, 1))); + assertEquals(weekDef_iso.hashCode(), WeekFields.of(DayOfWeek.MONDAY, 4).hashCode()); + assertEquals(weekDef_sundayStart.hashCode(), WeekFields.of(DayOfWeek.SUNDAY, 1).hashCode()); + + assertFalse(weekDef_iso.equals(weekDef_sundayStart)); + assertNotEquals(weekDef_iso.hashCode(), weekDef_sundayStart.hashCode()); + } + } diff --git a/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java b/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java index 4cc630d50be..af07063ebe7 100644 --- a/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java +++ b/jdk/test/java/time/tck/java/time/zone/TCKZoneRules.java @@ -75,6 +75,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Month; +import java.time.OffsetDateTime; import java.time.Year; import java.time.ZoneId; import java.time.ZoneOffset; @@ -83,6 +84,7 @@ import java.time.zone.ZoneOffsetTransition; import java.time.zone.ZoneOffsetTransitionRule; import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition; import java.time.zone.ZoneRules; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -918,6 +920,65 @@ public class TCKZoneRules { assertEquals(test.nextTransition(last.getInstant()), null); } + //----------------------------------------------------------------------- + // Apia + //----------------------------------------------------------------------- + private ZoneRules pacificApia() { + return ZoneId.of("Pacific/Apia").getRules(); + } + + public void test_Apia_nextTransition_historic() { + ZoneRules test = pacificApia(); + List trans = test.getTransitions(); + + ZoneOffsetTransition first = trans.get(0); + assertEquals(test.nextTransition(first.getInstant().minusNanos(1)), first); + + for (int i = 0; i < trans.size() - 1; i++) { + ZoneOffsetTransition cur = trans.get(i); + ZoneOffsetTransition next = trans.get(i + 1); + + assertEquals(test.nextTransition(cur.getInstant()), next); + assertEquals(test.nextTransition(next.getInstant().minusNanos(1)), next); + } + } + + public void test_Apia_jumpOverInternationalDateLine_M10_to_P14() { + // transition occurred at 2011-12-30T00:00-10:00 + ZoneRules test = pacificApia(); + Instant instantBefore = LocalDate.of(2011, 12, 27).atStartOfDay(ZoneOffset.UTC).toInstant(); + ZoneOffsetTransition trans = test.nextTransition(instantBefore); + assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2011, 12, 30, 0, 0)); + assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2011, 12, 31, 0, 0)); + assertEquals(trans.isGap(), true); + assertEquals(trans.isOverlap(), false); + assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-10)), false); + assertEquals(trans.isValidOffset(ZoneOffset.ofHours(+14)), false); + assertEquals(trans.getDuration(), Duration.ofHours(24)); + assertEquals(trans.getInstant(), LocalDateTime.of(2011, 12, 31, 0, 0).toInstant(ZoneOffset.ofHours(+14))); + + ZonedDateTime zdt = ZonedDateTime.of(2011, 12, 29, 23, 0, 0, 0, ZoneId.of("Pacific/Apia")); + assertEquals(zdt.plusHours(2).toLocalDateTime(), LocalDateTime.of(2011, 12, 31, 1, 0)); + } + + public void test_Apia_jumpForwardOverInternationalDateLine_P12_to_M12() { + // transition occurred at 1879-07-04T00:00+12:33:04 + ZoneRules test = pacificApia(); + Instant instantBefore = LocalDate.of(1879, 7, 2).atStartOfDay(ZoneOffset.UTC).toInstant(); + ZoneOffsetTransition trans = test.nextTransition(instantBefore); + assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(1879, 7, 5, 0, 0)); + assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(1879, 7, 4, 0, 0)); + assertEquals(trans.isGap(), false); + assertEquals(trans.isOverlap(), true); + assertEquals(trans.isValidOffset(ZoneOffset.ofHoursMinutesSeconds(+12, 33, 4)), true); + assertEquals(trans.isValidOffset(ZoneOffset.ofHoursMinutesSeconds(-11, -26, -56)), true); + assertEquals(trans.getDuration(), Duration.ofHours(-24)); + assertEquals(trans.getInstant(), LocalDateTime.of(1879, 7, 4, 0, 0).toInstant(ZoneOffset.ofHoursMinutesSeconds(-11, -26, -56))); + + ZonedDateTime zdt = ZonedDateTime.of(1879, 7, 4, 23, 0, 0, 0, ZoneId.of("Pacific/Apia")); + assertEquals(zdt.plusHours(2).toLocalDateTime(), LocalDateTime.of(1879, 7, 4, 1, 0, 0)); + } + //------------------------------------------------------------------------- @Test(expectedExceptions=UnsupportedOperationException.class) public void test_getTransitions_immutable() { @@ -931,6 +992,81 @@ public class TCKZoneRules { test.getTransitionRules().clear(); } + //----------------------------------------------------------------------- + // of() + //----------------------------------------------------------------------- + public void test_of(){ + //used for standard offset + ZoneOffset stdOffset1 = ZoneOffset.UTC; + ZoneOffset stdOffset2 = ZoneOffset.ofHours(1); + LocalDateTime time_of_stdOffsetTransition1 = LocalDateTime.of(2013, 1, 5, 1, 0); + ZoneOffsetTransition stdOffsetTransition1 = ZoneOffsetTransition.of(time_of_stdOffsetTransition1, stdOffset1, stdOffset2); + List stdOffsetTransition_list = new ArrayList(); + stdOffsetTransition_list.add(stdOffsetTransition1); + + //used for wall offset + ZoneOffset wallOffset1 = ZoneOffset.ofHours(2); + ZoneOffset wallOffset2 = ZoneOffset.ofHours(4); + ZoneOffset wallOffset3 = ZoneOffset.ofHours(7); + + LocalDateTime time_of_wallOffsetTransition1 = LocalDateTime.of(2013, 2, 5, 1, 0); + LocalDateTime time_of_wallOffsetTransition2 = LocalDateTime.of(2013, 3, 5, 1, 0); + LocalDateTime time_of_wallOffsetTransition3 = LocalDateTime.of(2013, 10, 5, 1, 0); + + ZoneOffsetTransition wallOffsetTransition1 = ZoneOffsetTransition.of(time_of_wallOffsetTransition1, wallOffset1, wallOffset2); + ZoneOffsetTransition wallOffsetTransition2 = ZoneOffsetTransition.of(time_of_wallOffsetTransition2, wallOffset2, wallOffset3); + ZoneOffsetTransition wallOffsetTransition3 = ZoneOffsetTransition.of(time_of_wallOffsetTransition3, wallOffset3, wallOffset1); + + List wallOffsetTransition_list = new ArrayList(); + wallOffsetTransition_list.add(wallOffsetTransition1); + wallOffsetTransition_list.add(wallOffsetTransition2); + wallOffsetTransition_list.add(wallOffsetTransition3); + + //used for ZoneOffsetTransitionRule + ZoneOffset ruleOffset = ZoneOffset.ofHours(3); + ZoneOffsetTransitionRule.TimeDefinition timeDefinition = ZoneOffsetTransitionRule.TimeDefinition.valueOf("WALL"); + ZoneOffsetTransitionRule rule1 = ZoneOffsetTransitionRule.of(Month.FEBRUARY, + 2, + DayOfWeek.MONDAY, + LocalTime.of(1, 0), + false, + timeDefinition, + ZoneOffset.UTC, + ZoneOffset.UTC, + ruleOffset + ); + List rule_list = new ArrayList(); + rule_list.add(rule1); + + //Begin verification + ZoneRules zoneRule = ZoneRules.of(stdOffset1, + wallOffset1, + stdOffsetTransition_list, + wallOffsetTransition_list, + rule_list + ); + + OffsetDateTime before_time_of_stdOffsetTransition1 = OffsetDateTime.of(time_of_stdOffsetTransition1, stdOffset1).minusSeconds(1); + OffsetDateTime after_time_of_stdOffsetTransition1 = OffsetDateTime.of(time_of_stdOffsetTransition1, stdOffset1).plusSeconds(1);; + assertEquals(zoneRule.getStandardOffset(before_time_of_stdOffsetTransition1.toInstant()), stdOffset1); + assertEquals(zoneRule.getStandardOffset(after_time_of_stdOffsetTransition1.toInstant()), stdOffset2); + + OffsetDateTime before_time_of_wallOffsetTransition1 = OffsetDateTime.of(time_of_wallOffsetTransition1, wallOffset1).minusSeconds(1); + OffsetDateTime after_time_of_wallOffsetTransition1 = OffsetDateTime.of(time_of_wallOffsetTransition1, wallOffset1).plusSeconds(1); + assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition1.toInstant()), wallOffsetTransition1); + assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition1.toInstant()), wallOffsetTransition2); + + OffsetDateTime before_time_of_wallOffsetTransition2 = OffsetDateTime.of(time_of_wallOffsetTransition2, wallOffset2).minusSeconds(1); + OffsetDateTime after_time_of_wallOffsetTransition2 = OffsetDateTime.of(time_of_wallOffsetTransition2, wallOffset2).plusSeconds(1); + assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition2.toInstant()), wallOffsetTransition2); + assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition2.toInstant()), wallOffsetTransition3); + + OffsetDateTime before_time_of_wallOffsetTransition3 = OffsetDateTime.of(time_of_wallOffsetTransition3, wallOffset3).minusSeconds(1); + OffsetDateTime after_time_of_wallOffsetTransition3 = OffsetDateTime.of(time_of_wallOffsetTransition3, wallOffset3).plusSeconds(1); + assertEquals(zoneRule.nextTransition(before_time_of_wallOffsetTransition3.toInstant()), wallOffsetTransition3); + assertEquals(zoneRule.nextTransition(after_time_of_wallOffsetTransition3.toInstant()), rule1.createTransition(2014)); + } + //----------------------------------------------------------------------- // equals() / hashCode() //----------------------------------------------------------------------- diff --git a/jdk/test/java/time/test/java/time/MockSimplePeriod.java b/jdk/test/java/time/test/java/time/MockSimplePeriod.java index 2d8f7d5ba9c..7df760847e2 100644 --- a/jdk/test/java/time/test/java/time/MockSimplePeriod.java +++ b/jdk/test/java/time/test/java/time/MockSimplePeriod.java @@ -176,7 +176,7 @@ public final class MockSimplePeriod @Override public String toString() { - return amount + " " + unit.getName(); + return amount + " " + unit; } } diff --git a/jdk/test/java/time/test/java/time/chrono/TestChronoLocalDate.java b/jdk/test/java/time/test/java/time/chrono/TestChronoLocalDate.java index 7865985998e..971b3157fe6 100644 --- a/jdk/test/java/time/test/java/time/chrono/TestChronoLocalDate.java +++ b/jdk/test/java/time/test/java/time/chrono/TestChronoLocalDate.java @@ -60,7 +60,9 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoLocalDateTime; import java.time.chrono.Chronology; import java.time.chrono.ThaiBuddhistChronology; import java.time.chrono.ThaiBuddhistDate; @@ -80,8 +82,8 @@ public class TestChronoLocalDate { //----------------------------------------------------------------------- public void test_date_comparator_checkGenerics_ISO() { - List> dates = new ArrayList<>(); - ChronoLocalDate date = LocalDate.of(2013, 1, 1); + List dates = new ArrayList<>(); + ChronoLocalDate date = LocalDate.of(2013, 1, 1); // Insert dates in order, no duplicates dates.add(date.minus(10, ChronoUnit.YEARS)); @@ -96,55 +98,7 @@ public class TestChronoLocalDate { dates.add(date.plus(1, ChronoUnit.YEARS)); dates.add(date.plus(10, ChronoUnit.YEARS)); - List> copy = new ArrayList<>(dates); - Collections.shuffle(copy); - Collections.sort(copy, ChronoLocalDate.timeLineOrder()); - assertEquals(copy, dates); - assertTrue(ChronoLocalDate.timeLineOrder().compare(copy.get(0), copy.get(1)) < 0); - } - - public void test_date_comparator_checkGenerics_unknown() { - List> dates = new ArrayList<>(); - ChronoLocalDate date = LocalDate.of(2013, 1, 1); - - // Insert dates in order, no duplicates - dates.add(date.minus(10, ChronoUnit.YEARS)); - dates.add(date.minus(1, ChronoUnit.YEARS)); - dates.add(date.minus(1, ChronoUnit.MONTHS)); - dates.add(date.minus(1, ChronoUnit.WEEKS)); - dates.add(date.minus(1, ChronoUnit.DAYS)); - dates.add(date); - dates.add(date.plus(1, ChronoUnit.DAYS)); - dates.add(date.plus(1, ChronoUnit.WEEKS)); - dates.add(date.plus(1, ChronoUnit.MONTHS)); - dates.add(date.plus(1, ChronoUnit.YEARS)); - dates.add(date.plus(10, ChronoUnit.YEARS)); - - List> copy = new ArrayList<>(dates); - Collections.shuffle(copy); - Collections.sort(copy, ChronoLocalDate.timeLineOrder()); - assertEquals(copy, dates); - assertTrue(ChronoLocalDate.timeLineOrder().compare(copy.get(0), copy.get(1)) < 0); - } - - public > void test_date_comparator_checkGenerics_unknownExtends() { - List> dates = new ArrayList<>(); - ChronoLocalDate date = (ChronoLocalDate) LocalDate.of(2013, 1, 1); // TODO generics raw type - - // Insert dates in order, no duplicates - dates.add(date.minus(10, ChronoUnit.YEARS)); - dates.add(date.minus(1, ChronoUnit.YEARS)); - dates.add(date.minus(1, ChronoUnit.MONTHS)); - dates.add(date.minus(1, ChronoUnit.WEEKS)); - dates.add(date.minus(1, ChronoUnit.DAYS)); - dates.add(date); - dates.add(date.plus(1, ChronoUnit.DAYS)); - dates.add(date.plus(1, ChronoUnit.WEEKS)); - dates.add(date.plus(1, ChronoUnit.MONTHS)); - dates.add(date.plus(1, ChronoUnit.YEARS)); - dates.add(date.plus(10, ChronoUnit.YEARS)); - - List> copy = new ArrayList<>(dates); + List copy = new ArrayList<>(dates); Collections.shuffle(copy); Collections.sort(copy, ChronoLocalDate.timeLineOrder()); assertEquals(copy, dates); @@ -178,13 +132,12 @@ public class TestChronoLocalDate { //----------------------------------------------------------------------- public void test_date_checkGenerics_genericsMethod() { Chronology chrono = ThaiBuddhistChronology.INSTANCE; - ChronoLocalDate date = chrono.dateNow(); - // date = processOK(date); // does not compile + ChronoLocalDate date = chrono.dateNow(); + date = processOK(date); date = processClassOK(ThaiBuddhistDate.class); date = dateSupplier(); - // date = processWeird(date); // does not compile (correct) - // date = processClassWeird(ThaiBuddhistDate.class); // does not compile (correct) + date = processClassWeird(ThaiBuddhistDate.class); } public void test_date_checkGenerics_genericsMethod_concreteType() { @@ -195,12 +148,12 @@ public class TestChronoLocalDate { date = processClassOK(ThaiBuddhistDate.class); date = dateSupplier(); - // date = processWeird(date); // does not compile (correct) // date = processClassWeird(ThaiBuddhistDate.class); // does not compile (correct) } - public > void test_date_checkGenerics_genericsMethod_withType() { + public void test_date_checkGenerics_genericsMethod_withType() { Chronology chrono = ThaiBuddhistChronology.INSTANCE; + @SuppressWarnings("unchecked") D date = (D) chrono.dateNow(); date = processOK(date); // date = processClassOK(ThaiBuddhistDate.class); // does not compile (correct) @@ -210,24 +163,40 @@ public class TestChronoLocalDate { // date = processClassWeird(ThaiBuddhistDate.class); // does not compile (correct) } - private > D dateSupplier() { - return (D) (ChronoLocalDate) ThaiBuddhistChronology.INSTANCE.dateNow(); // TODO raw types + @SuppressWarnings("unchecked") + private D dateSupplier() { + return (D) ThaiBuddhistChronology.INSTANCE.dateNow(); } // decent generics signatures that need to work - private > D processOK(D date) { - return date; + @SuppressWarnings("unchecked") + private D processOK(D date) { + return (D) date.plus(1, ChronoUnit.DAYS); } - private > D processClassOK(Class cls) { + private D processClassOK(Class cls) { return null; } // weird generics signatures that shouldn't really work - private > ChronoLocalDate processWeird(ChronoLocalDate date) { - return date; - } - private > ChronoLocalDate processClassWeird(Class cls) { + private ChronoLocalDate processClassWeird(Class cls) { return null; } + public void test_date_checkGenerics_chronoLocalDateTime1() { + LocalDateTime now = LocalDateTime.now(); + Chronology chrono = ThaiBuddhistChronology.INSTANCE; + ChronoLocalDateTime ldt = chrono.localDateTime(now); + ldt = processCLDT(ldt); + } + + public void test_date_checkGenerics_chronoLocalDateTime2() { + LocalDateTime now = LocalDateTime.now(); + Chronology chrono = ThaiBuddhistChronology.INSTANCE; + ChronoLocalDateTime ldt = chrono.localDateTime(now); + ldt = processCLDT(ldt); + } + + private ChronoLocalDateTime processCLDT(ChronoLocalDateTime dt) { + return dt; + } } diff --git a/jdk/test/java/time/test/java/time/chrono/TestExampleCode.java b/jdk/test/java/time/test/java/time/chrono/TestExampleCode.java index cfa478f488d..434e272da33 100644 --- a/jdk/test/java/time/test/java/time/chrono/TestExampleCode.java +++ b/jdk/test/java/time/test/java/time/chrono/TestExampleCode.java @@ -59,10 +59,14 @@ package test.java.time.chrono; import static org.testng.Assert.assertEquals; +import java.time.LocalDate; import java.time.LocalTime; +import java.time.ZoneId; import java.time.chrono.ChronoLocalDate; import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoZonedDateTime; import java.time.chrono.Chronology; +import java.time.chrono.HijrahChronology; import java.time.chrono.HijrahDate; import java.time.chrono.ThaiBuddhistDate; import java.time.temporal.ChronoField; @@ -82,7 +86,7 @@ public class TestExampleCode { @Test public void test_chronoPackageExample() { // Print the Thai Buddhist date - ChronoLocalDate now1 = Chronology.of("ThaiBuddhist").dateNow(); + ChronoLocalDate now1 = Chronology.of("ThaiBuddhist").dateNow(); int day = now1.get(ChronoField.DAY_OF_MONTH); int dow = now1.get(ChronoField.DAY_OF_WEEK); int month = now1.get(ChronoField.MONTH_OF_YEAR); @@ -93,15 +97,15 @@ public class TestExampleCode { // Enumerate the list of available calendars and print today for each Set chronos = Chronology.getAvailableChronologies(); for (Chronology chrono : chronos) { - ChronoLocalDate date = chrono.dateNow(); + ChronoLocalDate date = chrono.dateNow(); System.out.printf(" %20s: %s%n", chrono.getId(), date.toString()); } // Print today's date and the last day of the year for the Thai Buddhist Calendar. - ChronoLocalDate first = now1 + ChronoLocalDate first = now1 .with(ChronoField.DAY_OF_MONTH, 1) .with(ChronoField.MONTH_OF_YEAR, 1); - ChronoLocalDate last = first + ChronoLocalDate last = first .plus(1, ChronoUnit.YEARS) .minus(1, ChronoUnit.DAYS); System.out.printf(" %s: 1st of year: %s; end of year: %s%n", last.getChronology().getId(), @@ -137,7 +141,7 @@ public class TestExampleCode { // Enumerate the list of available calendars and print today for each Set chronos = Chronology.getAvailableChronologies(); for (Chronology chrono : chronos) { - ChronoLocalDate date = chrono.dateNow(); + ChronoLocalDate date = chrono.dateNow(); System.out.printf(" %20s: %s%n", chrono.getId(), date.toString()); } @@ -161,11 +165,31 @@ public class TestExampleCode { first, last); } + void HijrahExample1() { + HijrahDate hd2 = HijrahChronology.INSTANCE.date(1200, 1, 1); + + ChronoLocalDateTime hdt = hd2.atTime(LocalTime.MIDNIGHT); + ChronoZonedDateTime zhdt = hdt.atZone(ZoneId.of("GMT")); + HijrahDate hd3 = zhdt.toLocalDate(); + ChronoLocalDateTime hdt2 = zhdt.toLocalDateTime(); + HijrahDate hd4 = hdt2.toLocalDate(); + + HijrahDate hd5 = next(hd2); + } + + void test_unknownChronologyWithDateTime() { + ChronoLocalDate date = LocalDate.now(); + ChronoLocalDateTime cldt = date.atTime(LocalTime.NOON); + ChronoLocalDate ld = cldt.toLocalDate(); + ChronoLocalDateTime noonTomorrow = tomorrowNoon(ld); + } + @Test public void test_library() { HijrahDate date = HijrahDate.now(); HijrahDate next = next(date); ChronoLocalDateTime noonTomorrow = tomorrowNoon(date); + HijrahDate hd3 = noonTomorrow.toLocalDate(); System.out.printf(" now: %s, noon tomorrow: %s%n", date, noonTomorrow); } @@ -175,8 +199,9 @@ public class TestExampleCode { * @param date a specific date extending ChronoLocalDate * @return a new date in the same chronology. */ - private > D next(D date) { - return date.plus(1, ChronoUnit.DAYS); + @SuppressWarnings("unchecked") + private D next(D date) { + return (D) date.plus(1, ChronoUnit.DAYS); } /** @@ -186,7 +211,8 @@ public class TestExampleCode { * @param date a specific date extending ChronoLocalDate * @return a [@code ChronoLocalDateTime} using the change chronology. */ - private > ChronoLocalDateTime tomorrowNoon(D date) { - return date.plus(1, ChronoUnit.DAYS).atTime(LocalTime.of(12, 0)); + @SuppressWarnings("unchecked") + private ChronoLocalDateTime tomorrowNoon(D date) { + return (ChronoLocalDateTime) date.plus(1, ChronoUnit.DAYS).atTime(LocalTime.of(12, 0)); } } diff --git a/jdk/test/java/time/test/java/time/chrono/TestJapaneseChronoImpl.java b/jdk/test/java/time/test/java/time/chrono/TestJapaneseChronoImpl.java index 282a9f2231d..bcde051e1b9 100644 --- a/jdk/test/java/time/test/java/time/chrono/TestJapaneseChronoImpl.java +++ b/jdk/test/java/time/test/java/time/chrono/TestJapaneseChronoImpl.java @@ -61,12 +61,15 @@ import static org.testng.Assert.assertEquals; import java.time.LocalDate; import java.time.LocalTime; import java.time.OffsetDateTime; +import java.time.ZonedDateTime; import java.time.ZoneOffset; import java.time.chrono.JapaneseChronology; +import java.time.chrono.JapaneseEra; import java.time.chrono.JapaneseDate; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; import java.util.Calendar; +import java.util.GregorianCalendar; import java.util.Locale; import java.util.TimeZone; @@ -85,7 +88,7 @@ public class TestJapaneseChronoImpl { @DataProvider(name="RangeVersusCalendar") Object[][] provider_rangeVersusCalendar() { return new Object[][] { - {LocalDate.of(1868, 1, 1), LocalDate.of(2100, 1, 1)}, + {LocalDate.of(1873, 1, 1), LocalDate.of(2100, 1, 1)}, }; } @@ -118,4 +121,32 @@ public class TestJapaneseChronoImpl { } } + //----------------------------------------------------------------------- + // Verify Japanese Calendar matches java.util.Calendar for number of days + // in years 1 and 2. + //----------------------------------------------------------------------- + @Test + public void test_dayOfYearVsCalendar() { + Locale locale = Locale.forLanguageTag("ja-JP-u-ca-japanese"); + Calendar cal = java.util.Calendar.getInstance(locale); + + for (JapaneseEra era : JapaneseEra.values()) { + for (int year : new int[] {6, 7}) { + JapaneseDate jd = JapaneseChronology.INSTANCE.dateYearDay(era, year, 1); + OffsetDateTime jodt = OffsetDateTime.of(LocalDate.from(jd), LocalTime.MIN, ZoneOffset.UTC); + long millis = jodt.toInstant().toEpochMilli(); + cal.setTimeZone(TimeZone.getTimeZone("GMT+00")); + cal.setTimeInMillis(millis); + + assertEquals(jd.get(ChronoField.DAY_OF_YEAR), cal.get(Calendar.DAY_OF_YEAR), + "different DAY_OF_YEAR values in " + era + ", year: " + year); + assertEquals(jd.range(ChronoField.DAY_OF_YEAR).getMaximum(), cal.getActualMaximum(Calendar.DAY_OF_YEAR), + "different maximum for DAY_OF_YEAR in " + era + ", year: " + year); + assertEquals(jd.range(ChronoField.DAY_OF_YEAR).getMinimum(), cal.getActualMinimum(Calendar.DAY_OF_YEAR), + "different minimum for DAY_OF_YEAR in " + era + ", year: " + year); + } + } + + } + } diff --git a/jdk/test/java/time/test/java/time/chrono/TestJapaneseChronology.java b/jdk/test/java/time/test/java/time/chrono/TestJapaneseChronology.java index b87555dcb51..3fbf8532318 100644 --- a/jdk/test/java/time/test/java/time/chrono/TestJapaneseChronology.java +++ b/jdk/test/java/time/test/java/time/chrono/TestJapaneseChronology.java @@ -47,9 +47,6 @@ public class TestJapaneseChronology { Object[][] transitionData() { return new Object[][] { // Japanese era, yearOfEra, month, dayOfMonth, gregorianYear - { JapaneseEra.SEIREKI, Year.MIN_VALUE, 1, 1, Year.MIN_VALUE }, - { JapaneseEra.SEIREKI, 1867, 12, 31, 1867 }, - { JapaneseEra.MEIJI, 1, 1, 25, 1868 }, // Note: the dates of Meiji 1 to 5 are incorrect { JapaneseEra.MEIJI, 6, 1, 1, 1873 }, // Meiji-Taisho transition isn't accurate. 1912-07-30 is the last day of Meiji // and the first day of Taisho. @@ -84,9 +81,10 @@ public class TestJapaneseChronology { Object[][] rangeData() { return new Object[][] { // field, minSmallest, minLargest, maxSmallest, maxLargest - { ChronoField.ERA, -999, -999, 2, 2}, - { ChronoField.YEAR_OF_ERA, -999999999, 1, 15, 999999999-1989 }, // depends on the current era + { ChronoField.ERA, -1, -1, 2, 2}, + { ChronoField.YEAR_OF_ERA, 1, 1, 15, 999999999-1989 }, // depends on the current era { ChronoField.DAY_OF_YEAR, 1, 1, 7, 366}, + { ChronoField.YEAR, 1873, 1873, 999999999, 999999999}, }; } @@ -94,9 +92,6 @@ public class TestJapaneseChronology { Object[][] invalidDatesData() { return new Object[][] { // Japanese era, yearOfEra, month, dayOfMonth - { JapaneseEra.SEIREKI, Year.MIN_VALUE - 1, 1, 1 }, - { JapaneseEra.SEIREKI, 1855, 2, 29 }, - { JapaneseEra.SEIREKI, 1868, 1, 25 }, { JapaneseEra.MEIJI, 6, 2, 29 }, { JapaneseEra.MEIJI, 45, 7, 30 }, { JapaneseEra.MEIJI, 46, 1, 1 }, @@ -118,8 +113,6 @@ public class TestJapaneseChronology { Object[][] invalidEraYearData() { return new Object[][] { // Japanese era, yearOfEra - { JapaneseEra.SEIREKI, Year.MIN_VALUE - 1 }, - { JapaneseEra.SEIREKI, 2012 }, { JapaneseEra.MEIJI, -1 }, { JapaneseEra.MEIJI, 0 }, { JapaneseEra.MEIJI, 46 }, diff --git a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java index 3e1b8a85803..63e433f7ac4 100644 --- a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java +++ b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java @@ -28,27 +28,57 @@ package test.java.time.chrono; import static java.time.temporal.ChronoField.DAY_OF_MONTH; import static java.time.temporal.ChronoField.MONTH_OF_YEAR; import static java.time.temporal.ChronoField.YEAR; +import static java.time.temporal.ChronoField.DAY_OF_YEAR; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; import java.time.DateTimeException; +import java.time.DayOfWeek; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.Period; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoLocalDateTime; +import java.time.chrono.ChronoZonedDateTime; import java.time.chrono.Chronology; import java.time.chrono.HijrahChronology; import java.time.chrono.HijrahDate; +import java.time.chrono.JapaneseChronology; +import java.time.chrono.JapaneseDate; +import java.time.chrono.MinguoChronology; +import java.time.chrono.MinguoDate; +import java.time.chrono.ThaiBuddhistChronology; +import java.time.chrono.ThaiBuddhistDate; +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalAdjuster; import java.time.temporal.ValueRange; +import java.time.temporal.WeekFields; +import java.util.Locale; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** - * Tests for the Umm alQura chronology and data + * Tests for the Umm alQura chronology and data. + * Note: The dates used for testing are just a sample of calendar data. */ @Test public class TestUmmAlQuraChronology { + private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2); + private static final ZoneId ZONE_RIYADH = ZoneId.of("Asia/Riyadh"); + + // Test for HijrahChronology Aliases @Test public void test_aliases() { HijrahChronology hc = (HijrahChronology) Chronology.of("Hijrah"); @@ -57,49 +87,43 @@ public class TestUmmAlQuraChronology { assertEquals(hc, HijrahChronology.INSTANCE, "Alias for Hijrah-umalqura"); } - //----------------------------------------------------------------------- + // Test to check if the exception is thrown for an incorrect chronology id + @Test(expectedExceptions=DateTimeException.class) + public void test_badChronology() { + Chronology test = Chronology.of("Hijrah-ummalqura"); + } + + //-------------------------------------------------------------------------- // regular data factory for Umm alQura dates and the corresponding ISO dates - //----------------------------------------------------------------------- - @DataProvider(name = "UmmalQuraVsISODates") - Object[][] data_of_ummalqura() { - return new Object[][]{ - - //{1318, 01, 01, 1900, 04, 30}, - //{1318, 01, 02, 1900, 05, 01}, - - //{1318, 12, 29, 1901, 04, 18}, - //{1319, 01, 01, 1901, 04, 19}, - - //{1433, 12, 29, 2012, 11, 14}, - //{1434, 01, 01, 2012, 11, 15}, - - {1434, 02, 18, 2012, 12, 31}, - {1434, 02, 19, 2013, 01, 01}, - - //{1502, 12, 30, 2079, 10, 25}, - // not in Umm alQura data {1503, 01, 01, 2079, 10, 26}, - - // not in Umm alQura data {1503, 06, 28, 2080, 04, 18}, - // not in Umm alQura data ~/ws/Downloads + //-------------------------------------------------------------------------- + @DataProvider(name = "UmmAlQuraVsISODates") + Object[][] data_UmmAlQuraVsISODates() { + return new Object[][] { + {HijrahDate.of(1318, 1, 1), LocalDate.of(1900, 04, 30)}, + {HijrahDate.of(1318, 12, 29), LocalDate.of(1901, 04, 19)}, + {HijrahDate.of(1319, 01, 01), LocalDate.of(1901, 04, 20)}, + {HijrahDate.of(1433, 12, 29), LocalDate.of(2012, 11, 14)}, + {HijrahDate.of(1434, 01, 01), LocalDate.of(2012, 11, 15)}, + {HijrahDate.of(1434, 02, 18), LocalDate.of(2012, 12, 31)}, + {HijrahDate.of(1502, 12, 29), LocalDate.of(2079, 10, 25)}, }; } - @Test(dataProvider="UmmalQuraVsISODates") - public void Test_UmmAlQuraDatesVsISO(int h_year, int h_month, int h_day, int iso_year, int iso_month, int iso_day) { - HijrahDate hd = HijrahDate.of(h_year, h_month, h_day); - LocalDate ld = LocalDate.of(iso_year, iso_month, iso_day); + // Test to verify the epoch days for given Hijrah & ISO date instances + @Test(dataProvider="UmmAlQuraVsISODates") + public void Test_UmmAlQuraVsISODates(HijrahDate hd, LocalDate ld) { assertEquals(hd.toEpochDay(), ld.toEpochDay(), "Umm alQura date and ISO date should have same epochDay"); } - + // UmmAlQura chronology ranges for year, month and days for the HijrahChronology @Test public void Test_UmmAlQuraChronoRange() { HijrahChronology chrono = HijrahChronology.INSTANCE; ValueRange year = chrono.range(YEAR); - assertEquals(year.getMinimum(), 1432, "Minimum year"); - assertEquals(year.getLargestMinimum(), 1432, "Largest minimum year"); - assertEquals(year.getMaximum(), 1435, "Largest year"); - assertEquals(year.getSmallestMaximum(), 1435, "Smallest Maximum year"); + assertEquals(year.getMinimum(), 1300, "Minimum year"); + assertEquals(year.getLargestMinimum(), 1300, "Largest minimum year"); + assertEquals(year.getMaximum(), 1600, "Largest year"); + assertEquals(year.getSmallestMaximum(), 1600, "Smallest Maximum year"); ValueRange month = chrono.range(MONTH_OF_YEAR); assertEquals(month.getMinimum(), 1, "Minimum month"); @@ -118,13 +142,17 @@ public class TestUmmAlQuraChronology { // regular data factory for dates and the corresponding range values //----------------------------------------------------------------------- @DataProvider(name = "dates") - Object[][] data_of_calendars() { + Object[][] data_dates() { return new Object[][]{ - {HijrahDate.of(1434, 5, 1), 1432, 1435, 1, 12, 1, 29, 30}, - {HijrahDate.of(1434, 6, 1), 1432, 1435, 1, 12, 1, 30, 30}, + {HijrahDate.of(1300, 5, 1), 1300, 1600, 1, 12, 1, 30, 30}, + {HijrahDate.of(1300, 6, 1), 1300, 1600, 1, 12, 1, 29, 30}, + {HijrahDate.of(1434, 12, 1), 1300, 1600, 1, 12, 1, 29, 30}, + {HijrahDate.of(1500, 4, 1), 1300, 1600, 1, 12, 1, 30, 30}, + {HijrahDate.of(1600, 6, 1), 1300, 1600, 1, 12, 1, 29, 30}, }; } + // Test to verify the min/max field ranges for given dates @Test(dataProvider="dates") public void Test_UmmAlQuraRanges(HijrahDate date, int minYear, int maxYear, @@ -163,6 +191,7 @@ public class TestUmmAlQuraChronology { } + // Check the date limits @Test public void test_hijrahDateLimits() { HijrahChronology chrono = HijrahChronology.INSTANCE; @@ -193,33 +222,547 @@ public class TestUmmAlQuraChronology { } } - @DataProvider(name="badDates") - Object[][] data_badDates() { + // Data provider to verify the dateYearDay() method + @DataProvider(name="dateYearDay") + Object[][] data_dateYearDay() { return new Object[][] { - {1317, 12, 29}, - {1317, 12, 30}, - - {1320, 1, 29 + 1}, - {1320, 2, 30 + 1}, - {1320, 3, 29 + 1}, - {1320, 4, 29 + 1}, - {1320, 5, 30 + 1}, - {1320, 6, 29 + 1}, - {1320, 7, 30 + 1}, - {1320, 8, 30 + 1}, - {1320, 9, 29 + 1}, - {1320, 10, 30 + 1}, - {1320, 11, 30 + 1}, - {1320, 12, 30 + 1}, + {HijrahChronology.INSTANCE.dateYearDay(1434, 42), HijrahChronology.INSTANCE.date(1434, 02, 13)}, + {HijrahChronology.INSTANCE.dateYearDay(1330, 354), HijrahChronology.INSTANCE.date(1330, 12, 29)}, + {HijrahChronology.INSTANCE.dateYearDay(1600, 1), HijrahChronology.INSTANCE.date(1600, 1, 1)}, + {HijrahChronology.INSTANCE.dateYearDay(1400, 175), HijrahChronology.INSTANCE.date(1400, 6, 28)}, + {HijrahChronology.INSTANCE.dateYearDay(1520, 190), HijrahChronology.INSTANCE.date(1520, 7, 13)}, + {HijrahChronology.INSTANCE.dateYearDay(1521, 112), HijrahChronology.INSTANCE.date(1521, 4, 25)}, }; } - @Test(dataProvider="badDates", expectedExceptions=DateTimeException.class) - public void test_badDates(int year, int month, int dom) { - HijrahChronology.INSTANCE.date(year, month, dom); + // Test to verify the dateYearDay() method + @Test(dataProvider="dateYearDay") + public void test_DateYearDay(ChronoLocalDate date1, ChronoLocalDate date2) { + assertEquals(date1, date2); } - void printRange(ValueRange range, Object obj, ChronoField field) { - System.err.printf(" range: min: %d, max: %d; of: %s, field: %s%n", range.getMinimum(), range.getMaximum(), obj.toString(), field.toString()); + //----------------------------------------------------------------------- + // HijrahDate.with(DAY_OF_YEAR, n) + //----------------------------------------------------------------------- + @Test + public void test_getDayOfYear() { + HijrahDate hd1 = HijrahChronology.INSTANCE.dateYearDay(1434, 1); + for (int i = 1; i <= hd1.lengthOfYear(); i++) { + HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(1434, i); + int doy = hd.get(DAY_OF_YEAR); + assertEquals(doy, i, "get(DAY_OF_YEAR) incorrect for " + i); + } + } + + @Test + public void test_withDayOfYear() { + HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(1434, 1); + for (int i = 1; i <= hd.lengthOfYear(); i++) { + HijrahDate hd2 = hd.with(DAY_OF_YEAR, i); + int doy = hd2.get(DAY_OF_YEAR); + assertEquals(doy, i, "with(DAY_OF_YEAR) incorrect for " + i + " " + hd2); + } + } + + @Test(expectedExceptions=java.time.DateTimeException.class) + public void test_withDayOfYearTooSmall() { + HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(1435, 1); + HijrahDate hd2 = hd.with(DAY_OF_YEAR, 0); + } + + @Test(expectedExceptions=java.time.DateTimeException.class) + public void test_withDayOfYearTooLarge() { + HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(1435, 1); + HijrahDate hd2 = hd.with(DAY_OF_YEAR, hd.lengthOfYear() + 1); + } + + // Test to verify the with() method with ChronoField is set to DAY_OF_WEEK + @Test + public void test_adjustWithDayOfWeek() { + assertEquals(HijrahChronology.INSTANCE.date(1320, 1, 15).with(ChronoField.DAY_OF_WEEK, 4), HijrahDate.of(1320, 1, 15)); + assertEquals(HijrahChronology.INSTANCE.date(1421, 11, 15).with(ChronoField.DAY_OF_WEEK, 1), HijrahDate.of(1421, 11, 11)); + assertEquals(HijrahChronology.INSTANCE.date(1529, 7, 18).with(ChronoField.DAY_OF_WEEK, 6), HijrahDate.of(1529, 7, 20)); + assertEquals(HijrahChronology.INSTANCE.date(1534, 2, 10).with(ChronoField.DAY_OF_WEEK, 5), HijrahDate.of(1534, 2, 12)); + assertEquals(HijrahChronology.INSTANCE.date(1552, 4, 1).with(ChronoField.DAY_OF_WEEK, 2), HijrahDate.of(1552, 3, 26)); + } + + // Test to verify the with() method with ChronoField is set to DAY_OF_MONTH + @Test + public void test_adjustWithDayOfMonth() { + assertEquals(HijrahChronology.INSTANCE.date(1320, 1, 15).with(ChronoField.DAY_OF_MONTH, 2), HijrahDate.of(1320, 1, 2)); + assertEquals(HijrahChronology.INSTANCE.date(1421, 11, 15).with(ChronoField.DAY_OF_MONTH, 9), HijrahDate.of(1421, 11, 9)); + assertEquals(HijrahChronology.INSTANCE.date(1529, 7, 18).with(ChronoField.DAY_OF_MONTH, 13), HijrahDate.of(1529, 7, 13)); + assertEquals(HijrahChronology.INSTANCE.date(1534, 12, 10).with(ChronoField.DAY_OF_MONTH, 29), HijrahDate.of(1534, 12, 29)); + assertEquals(HijrahChronology.INSTANCE.date(1552, 4, 1).with(ChronoField.DAY_OF_MONTH, 6), HijrahDate.of(1552, 4, 6)); + } + + // Test to verify the with() method with ChronoField is set to DAY_OF_YEAR + @Test + public void test_adjustWithDayOfYear() { + assertEquals(HijrahChronology.INSTANCE.date(1320, 1, 15).with(ChronoField.DAY_OF_YEAR, 24), HijrahDate.of(1320, 1, 24)); + assertEquals(HijrahChronology.INSTANCE.date(1421, 11, 15).with(ChronoField.DAY_OF_YEAR, 135), HijrahDate.of(1421, 5, 18)); + assertEquals(HijrahChronology.INSTANCE.date(1529, 7, 18).with(ChronoField.DAY_OF_YEAR, 64), HijrahDate.of(1529, 3, 5)); + assertEquals(HijrahChronology.INSTANCE.date(1534, 2, 10).with(ChronoField.DAY_OF_YEAR, 354), HijrahDate.of(1534, 12, 29)); + assertEquals(HijrahChronology.INSTANCE.date(1552, 4, 1).with(ChronoField.DAY_OF_YEAR, 291), HijrahDate.of(1552, 10, 26)); + } + + // Data provider to get the difference between two dates in terms of days, months and years + @DataProvider(name="datesForDiff") + Object[][] data_datesForDiffs() { + return new Object[][] { + {HijrahDate.of(1350, 5, 15), HijrahDate.of(1351, 12, 29), 574, 19, 1}, + {HijrahDate.of(1434, 5, 1), HijrahDate.of(1434,6, 12), 40, 1, 0}, + {HijrahDate.of(1436, 1, 1), HijrahDate.of(1475, 12, 29), 14173, 479, 39}, + {HijrahDate.of(1500, 6, 12), HijrahDate.of(1551, 7, 12), 18102, 613, 51}, + {HijrahDate.of(1550, 3, 11), HijrahDate.of(1551, 4, 11), 384, 13, 1}, + }; + } + + // Test to verify the difference between two given dates in terms of days, months and years + @Test(dataProvider="datesForDiff") + public void test_diffBetweenDates(ChronoLocalDate from, ChronoLocalDate to, long days, long months, long years) { + assertEquals(from.until(to, ChronoUnit.DAYS), days); + assertEquals(from.until(to, ChronoUnit.MONTHS), months); + assertEquals(from.until(to, ChronoUnit.YEARS), years); + } + + // Data provider to get the difference between two dates as a period + @DataProvider(name="datesForPeriod") + Object[][] data_Period() { + return new Object[][] { + {HijrahDate.of(1350, 5, 15), HijrahDate.of(1434, 7, 20), Period.of(84, 2, 5)}, + {HijrahDate.of(1403, 5, 28), HijrahDate.of(1434, 7, 20), Period.of(31, 1, 22)}, + {HijrahDate.of(1434, 7, 20), HijrahDate.of(1484, 2, 15), Period.of(49, 6, 24)}, + {HijrahDate.of(1500, 6, 12), HijrahDate.of(1450, 4, 21), Period.of(-50, -1, -20)}, + {HijrahDate.of(1549, 3, 11), HijrahDate.of(1550, 3, 10), Period.of(0, 11, 28)}, + }; + } + + // Test to get the Period between two given dates + @Test(dataProvider="datesForPeriod") + public void test_until(HijrahDate h1, HijrahDate h2, Period p) { + Period period = h1.until(h2); + assertEquals(period, p); + } + + // Test to get the Period between dates in different chronologies + @Test(dataProvider="datesForPeriod") + public void test_periodUntilDiffChrono(HijrahDate h1, HijrahDate h2, Period p) { + MinguoDate m = MinguoChronology.INSTANCE.date(h2); + Period period = h1.until(m); + assertEquals(period, p); + } + + // Test to get the adjusted date from a given date using TemporalAdjuster methods + @Test + public void test_temporalDayAdjustments() { + HijrahDate date = HijrahDate.of(1554, 7, 21); + assertEquals(date.with(TemporalAdjuster.firstDayOfMonth()), HijrahDate.of(1554, 7, 1)); + assertEquals(date.with(TemporalAdjuster.lastDayOfMonth()), HijrahDate.of(1554, 7, 29)); + assertEquals(date.with(TemporalAdjuster.firstDayOfNextMonth()), HijrahDate.of(1554, 8, 1)); + assertEquals(date.with(TemporalAdjuster.firstDayOfNextYear()), HijrahDate.of(1555, 1, 1)); + assertEquals(date.with(TemporalAdjuster.firstDayOfYear()), HijrahDate.of(1554, 1, 1)); + assertEquals(date.with(TemporalAdjuster.lastDayOfYear()), HijrahDate.of(1554, 12, 30)); + } + + // Data provider for string representation of the date instances + @DataProvider(name="toString") + Object[][] data_toString() { + return new Object[][] { + {HijrahChronology.INSTANCE.date(1320, 1, 1), "Hijrah-umalqura AH 1320-01-01"}, + {HijrahChronology.INSTANCE.date(1500, 10, 28), "Hijrah-umalqura AH 1500-10-28"}, + {HijrahChronology.INSTANCE.date(1500, 10, 29), "Hijrah-umalqura AH 1500-10-29"}, + {HijrahChronology.INSTANCE.date(1434, 12, 5), "Hijrah-umalqura AH 1434-12-05"}, + {HijrahChronology.INSTANCE.date(1434, 12, 6), "Hijrah-umalqura AH 1434-12-06"}, + }; + } + + // Test to verify the returned string value of a given date instance + @Test(dataProvider="toString") + public void test_toString(ChronoLocalDate hijrahDate, String expected) { + assertEquals(hijrahDate.toString(), expected); + } + + // Data provider for maximum number of days + @DataProvider(name="monthDays") + Object[][] data_monthDays() { + return new Object[][] { + {1432, 1, 29}, + {1432, 4, 30}, + {1433, 12, 29}, + {1434, 1, 29}, + {1435, 8, 29}, + {1435, 9, 30}, + }; + } + + // Test to verify the maximum number of days by adding one month to a given date + @Test (dataProvider="monthDays") + public void test_valueRange_monthDays(int year, int month, int maxlength) { + ChronoLocalDate date = HijrahChronology.INSTANCE.date(year, month, 1); + ValueRange range = null; + for (int i=1; i<=12; i++) { + range = date.range(ChronoField.DAY_OF_MONTH); + date = date.plus(1, ChronoUnit.MONTHS); + assertEquals(range.getMaximum(), month, maxlength); + } + } + + // Test to get the last day of the month by adjusting the date with lastDayOfMonth() method + @Test(dataProvider="monthDays") + public void test_lastDayOfMonth(int year, int month, int numDays) { + HijrahDate hDate = HijrahChronology.INSTANCE.date(year, month, 1); + hDate = hDate.with(TemporalAdjuster.lastDayOfMonth()); + assertEquals(hDate.get(ChronoField.DAY_OF_MONTH), numDays); + } + + // Data provider for the 12 islamic month names in a formatted date + @DataProvider(name="patternMonthNames") + Object[][] data_patternMonthNames() { + return new Object[][] { + {1434, 1, 1, "01 AH Thu Muharram 1434"}, + {1434, 2, 1, "01 AH Fri Safar 1434"}, + {1434, 3, 1, "01 AH Sun Rabi\u02bb I 1434"},//the actual month name is Rabi Al-Awwal, but the locale data contains short form. + {1434, 4, 1, "01 AH Mon Rabi\u02bb II 1434"},//the actual month name is Rabi Al-Akhar, but the locale data contains short form. + {1434, 5, 1, "01 AH Wed Jumada I 1434"},//the actual month name is Jumada Al-Awwal, but the locale data contains short form. + {1434, 6, 1, "01 AH Thu Jumada II 1434"},//the actual month name is Jumada Al-Akhar, but the locale data contains short form. + {1434, 7, 1, "01 AH Sat Rajab 1434"}, + {1434, 8, 1, "01 AH Mon Sha\u02bbban 1434"}, + {1434, 9, 1, "01 AH Tue Ramadan 1434"}, + {1434, 10, 1, "01 AH Thu Shawwal 1434"}, + {1434, 11, 1, "01 AH Sat Dhu\u02bbl-Qi\u02bbdah 1434"}, + {1434, 12, 1, "01 AH Sun Dhu\u02bbl-Hijjah 1434"}, + }; + } + + // Test to verify the formatted dates + @Test(dataProvider="patternMonthNames") + public void test_ofPattern(int year, int month, int day, String expected) { + DateTimeFormatter test = DateTimeFormatter.ofPattern("dd G E MMMM yyyy"); + assertEquals(test.format(HijrahDate.of(year, month, day)), expected); + } + + // Data provider for localized dates + @DataProvider(name="chronoDateTimes") + Object[][] data_chronodatetimes() { + return new Object[][] { + {1432, 12, 29, "Safar 1, 1434 AH"}, + {1433, 1, 30, "Safar 30, 1434 AH"}, + {1434, 6, 30, "Rajab 30, 1435 AH"}, + }; + } + + // Test to verify the localized dates using ofLocalizedDate() method + @Test(dataProvider="chronoDateTimes") + public void test_formatterOfLocalizedDate(int year, int month, int day, String expected) { + HijrahDate hd = HijrahChronology.INSTANCE.date(year, month, day); + ChronoLocalDateTime hdt = hd.atTime(LocalTime.NOON); + hdt = hdt.plus(1, ChronoUnit.YEARS); + hdt = hdt.plus(1, ChronoUnit.MONTHS); + hdt = hdt.plus(1, ChronoUnit.DAYS); + hdt = hdt.plus(1, ChronoUnit.HOURS); + hdt = hdt.plus(1, ChronoUnit.MINUTES); + hdt = hdt.plus(1, ChronoUnit.SECONDS); + DateTimeFormatter df = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).withChronology(Chronology.of("Hijrah-umalqura")).withLocale(Locale.forLanguageTag("en-US")); + assertEquals(df.format(hdt), expected); + } + + // Data provider to get the day of the week in a given date + // The day of the week varies if the week starts with a saturday or sunday + @DataProvider(name="dayOfWeek") + Object[][] data_dayOfweek() { + return new Object[][] { + {HijrahDate.of(1434, 6, 24), 1, 7}, + {HijrahDate.of(1432, 9, 3), 5, 4}, + {HijrahDate.of(1334, 12, 29), 7, 6}, + {HijrahDate.of(1354, 5, 24), 1, 7}, + {HijrahDate.of(1465, 10, 2), 2, 1}, + }; + } + + // Test to get the day of the week based on a Saturday/Sunday as the first day of the week + @Test(dataProvider="dayOfWeek") + public void test_dayOfWeek(HijrahDate date, int satStart, int sunStart) { + assertEquals(date.get(WeekFields.of(DayOfWeek.SATURDAY, 7).dayOfWeek()), satStart); + assertEquals(date.get(WeekFields.of(DayOfWeek.SUNDAY, 7).dayOfWeek()), sunStart); + } + + // Data sample to get the epoch days of a date instance + @DataProvider(name="epochDays") + Object[][] data_epochdays() { + return new Object[][] { + {1332, -20486}, + {1334, -19777}, + {1336, -19068}, + {1432, 14950}, + {1434, 15659}, + {1534, 51096}, + {1535, 51450}, + }; + } + + // Test to verify the number of epoch days of a date instance + @Test(dataProvider="epochDays") + public void test_epochDays(int y, long epoch) { + HijrahDate date = HijrahDate.of(y, 1, 1); + assertEquals(date.toEpochDay(), epoch); + } + + // Data provider to verify whether a given hijrah year is a leap year or not + @DataProvider(name="leapYears") + Object[][] data_leapyears() { + return new Object[][] { + {1302, true}, + {1305, false}, + {1315, false}, + {1534, false}, + {1411, true}, + {1429, false}, + {1433, true}, + {1443, true}, + }; + } + + // Test to verify whether a given hijrah year is a leap year or not + @Test(dataProvider="leapYears") + public void test_leapYears(int y, boolean leapyear) { + HijrahDate date = HijrahDate.of(y, 1, 1); + assertEquals(date.isLeapYear(), leapyear); + } + + // Date samples to convert HijrahDate to LocalDate and vice versa + @DataProvider(name="samples") + Object[][] data_samples() { + return new Object[][] { + {HijrahChronology.INSTANCE.date(1319, 12, 30), LocalDate.of(1902, 4, 9)}, + {HijrahChronology.INSTANCE.date(1320, 1, 1), LocalDate.of(1902, 4, 10)}, + {HijrahChronology.INSTANCE.date(1321, 12, 30), LocalDate.of(1904, 3, 18)}, + {HijrahChronology.INSTANCE.date(1433, 7, 29), LocalDate.of(2012, 6, 19)}, + {HijrahChronology.INSTANCE.date(1434, 10, 12), LocalDate.of(2013, 8, 19)}, + {HijrahChronology.INSTANCE.date(1500, 3, 3), LocalDate.of(2077, 1, 28)}, + }; + } + + // Test to get LocalDate instance from a given HijrahDate + @Test(dataProvider="samples") + public void test_toLocalDate(ChronoLocalDate hijrahDate, LocalDate iso) { + assertEquals(LocalDate.from(hijrahDate), iso); + } + + // Test to adjust HijrahDate with a given LocalDate + @Test(dataProvider="samples") + public void test_adjust_toLocalDate(ChronoLocalDate hijrahDate, LocalDate iso) { + assertEquals(hijrahDate.with(iso), hijrahDate); + } + + // Test to get a HijrahDate from a calendrical + @Test(dataProvider="samples") + public void test_fromCalendrical(ChronoLocalDate hijrahDate, LocalDate iso) { + assertEquals(HijrahChronology.INSTANCE.date(iso), hijrahDate); + } + + // Test to verify the day of week of a given HijrahDate and LocalDate + @Test(dataProvider="samples") + public void test_dayOfWeekEqualIsoDayOfWeek(ChronoLocalDate hijrahDate, LocalDate iso) { + assertEquals(hijrahDate.get(ChronoField.DAY_OF_WEEK), iso.get(ChronoField.DAY_OF_WEEK), "Hijrah day of week should be same as ISO day of week"); + } + + // Test to get the local date by applying the MIN adjustment with hijrah date + @Test(dataProvider="samples") + public void test_LocalDate_adjustToHijrahDate(ChronoLocalDate hijrahDate, LocalDate localDate) { + LocalDate test = LocalDate.MIN.with(hijrahDate); + assertEquals(test, localDate); + } + + // Test to get the local date time by applying the MIN adjustment with hijrah date + @Test(dataProvider="samples") + public void test_LocalDateTime_adjustToHijrahDate(ChronoLocalDate hijrahDate, LocalDate localDate) { + LocalDateTime test = LocalDateTime.MIN.with(hijrahDate); + assertEquals(test, LocalDateTime.of(localDate, LocalTime.MIDNIGHT)); + } + + // Sample dates for comparison + @DataProvider(name="datesForComparison") + Object[][] data_datesForComparison() { + return new Object[][] { + {HijrahChronology.INSTANCE.date(1434, 6, 26), LocalDate.of(2013, 5, 5), -1, 1}, + {HijrahChronology.INSTANCE.date(1433, 4, 15), LocalDate.of(2012, 3, 15), 1, -1}, + {HijrahChronology.INSTANCE.date(1432, 5, 21), LocalDate.of(2011, 4, 22), -1, 1}, + {HijrahChronology.INSTANCE.date(1433, 7, 29), LocalDate.of(2012, 6, 2), -1, 1}, + {HijrahChronology.INSTANCE.date(1434, 10, 12), LocalDate.of(2013, 8, 2), -1, 1}, + }; + } + + // Test to compare dates in both forward and reverse order + @Test(dataProvider="datesForComparison") + public void test_compareDates(HijrahDate hdate, LocalDate ldate, int result1, int result2) { + assertEquals(ldate.compareTo(hdate), result1); + assertEquals(hdate.compareTo(ldate), result2); + } + + // Test to verify the values of various chrono fields for a given hijrah date instance + @Test + public void test_chronoFields() { + ChronoLocalDate hdate = HijrahChronology.INSTANCE.date(1434, 6, 28); + assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), 3); + assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), 7); + assertEquals(hdate.get(ChronoField.ALIGNED_WEEK_OF_MONTH), 4); + assertEquals(hdate.get(ChronoField.ALIGNED_WEEK_OF_YEAR), 25); + assertEquals(hdate.get(ChronoField.ERA), 1); + assertEquals(hdate.get(ChronoField.YEAR_OF_ERA), 1434); + assertEquals(hdate.get(ChronoField.MONTH_OF_YEAR), 6); + assertEquals(hdate.get(ChronoField.DAY_OF_MONTH), 28); + assertEquals(hdate.get(ChronoField.DAY_OF_WEEK), 3); + assertEquals(hdate.get(ChronoField.DAY_OF_YEAR), 175); + } + + // Test to verify the returned hijrah date after adjusting the day of week as Saturday + @Test + public void test_adjustInto() { + assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1434, 6, 28)), HijrahDate.of(1434, 7, 1)); + assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1432, 4, 13)), HijrahDate.of(1432, 4, 14)); + assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1433, 11, 29)), HijrahDate.of(1433, 12, 4)); + assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1434, 5, 10)), HijrahDate.of(1434, 5, 11)); + assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1434, 9, 11)), HijrahDate.of(1434, 9, 12)); + } + + //----------------------------------------------------------------------- + // zonedDateTime(TemporalAccessor) + //----------------------------------------------------------------------- + @DataProvider(name="zonedDateTime") + Object[][] data_zonedDateTime() { + return new Object[][] { + {ZonedDateTime.of(2012, 2, 29, 2, 7, 1, 1, ZONE_RIYADH), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7, 1, 1), null}, + {OffsetDateTime.of(2012, 2, 29, 2, 7, 1, 1, OFFSET_PTWO), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7, 1, 1), null}, + {LocalDateTime.of(2012, 2, 29, 2, 7), null, null, DateTimeException.class}, + {JapaneseDate.of(2012, 2, 29), null, null, DateTimeException.class}, + {ThaiBuddhistDate.of(2012 + 543, 2, 29), null, null, DateTimeException.class}, + {LocalDate.of(2012, 2, 29), null, null, DateTimeException.class}, + {LocalTime.of(20, 30, 29, 0), null, null, DateTimeException.class}, + }; + } + + // Test to check the zoned date times + @Test(dataProvider="zonedDateTime") + public void test_zonedDateTime(TemporalAccessor accessor, HijrahDate expectedDate, LocalTime expectedTime, Class expectedEx) { + if (expectedEx == null) { + ChronoZonedDateTime result = HijrahChronology.INSTANCE.zonedDateTime(accessor); + assertEquals(result.toLocalDate(), expectedDate); + assertEquals(HijrahDate.from(accessor), expectedDate); + assertEquals(result.toLocalTime(), expectedTime); + + } else { + try { + ChronoZonedDateTime result = HijrahChronology.INSTANCE.zonedDateTime(accessor); + fail(); + } catch (Exception ex) { + assertTrue(expectedEx.isInstance(ex)); + } + } + } + + //----------------------------------------------------------------------- + // zonedDateTime(Instant, ZoneId ) + //----------------------------------------------------------------------- + @Test + public void test_Instant_zonedDateTime() { + OffsetDateTime offsetDateTime = OffsetDateTime.of(2012, 2, 29, 2, 7, 1, 1, OFFSET_PTWO); + ZonedDateTime zonedDateTime = ZonedDateTime.of(2012, 2, 29, 2, 7, 1, 1, ZONE_RIYADH); + + ChronoZonedDateTime result = HijrahChronology.INSTANCE.zonedDateTime(offsetDateTime.toInstant(), offsetDateTime.getOffset()); + assertEquals(result.toLocalDate(), HijrahChronology.INSTANCE.date(1433, 4, 7)); + assertEquals(result.toLocalTime(), LocalTime.of(2, 7, 1, 1)); + + result = HijrahChronology.INSTANCE.zonedDateTime(zonedDateTime.toInstant(), zonedDateTime.getOffset()); + assertEquals(result.toLocalDate(), HijrahChronology.INSTANCE.date(1433, 4, 7)); + assertEquals(result.toLocalTime(), LocalTime.of(2, 7, 1, 1)); + } + + //----------------------------------------------------------------------- + // localDateTime() + //----------------------------------------------------------------------- + @DataProvider(name="localDateTime") + Object[][] data_localDateTime() { + return new Object[][] { + {LocalDateTime.of(2012, 2, 29, 2, 7), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7), null}, + {ZonedDateTime.of(2012, 2, 29, 2, 7, 1, 1, ZONE_RIYADH), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7, 1, 1), null}, + {OffsetDateTime.of(2012, 2, 29, 2, 7, 1, 1, OFFSET_PTWO), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7, 1, 1), null}, + {JapaneseDate.of(2012, 2, 29), null, null, DateTimeException.class}, + {ThaiBuddhistDate.of(2012 + 543, 2, 29), null, null, DateTimeException.class}, + {LocalDate.of(2012, 2, 29), null, null, DateTimeException.class}, + {LocalTime.of(20, 30, 29, 0), null, null, DateTimeException.class}, + }; + } + + // Test to verify local date time values from various date instances defined in the localDateTime data provider + @Test(dataProvider="localDateTime") + public void test_localDateTime(TemporalAccessor accessor, HijrahDate expectedDate, LocalTime expectedTime, Class expectedEx) { + if (expectedEx == null) { + ChronoLocalDateTime result = HijrahChronology.INSTANCE.localDateTime(accessor); + assertEquals(result.toLocalDate(), expectedDate); + assertEquals(HijrahDate.from(accessor), expectedDate); + assertEquals(result.toLocalTime(), expectedTime); + } else { + try { + ChronoLocalDateTime result = HijrahChronology.INSTANCE.localDateTime(accessor); + fail(); + } catch (Exception ex) { + assertTrue(expectedEx.isInstance(ex)); + } + } + } + + // Sample Hijrah & Minguo Dates + @DataProvider(name="hijrahToMinguo") + Object[][] data_hijrahToMinguo() { + return new Object[][] { + {HijrahDate.of(1350,5,15), MinguoDate.of(20,9,28)}, + {HijrahDate.of(1434,5,1), MinguoDate.of(102,3,13)}, + {HijrahDate.of(1436,1,1), MinguoDate.of(103,10,25)}, + {HijrahDate.of(1500,6,12), MinguoDate.of(166,5,5)}, + {HijrahDate.of(1550,3,11), MinguoDate.of(214,8,11)}, + }; + } + + // Test to verify the date conversion from Hijrah to Minguo chronology + @Test(dataProvider="hijrahToMinguo") + public void test_hijrahToMinguo(HijrahDate hijrah, MinguoDate minguo) { + assertEquals(MinguoChronology.INSTANCE.date(hijrah), minguo); + } + + // Sample Hijrah & Thai Dates + @DataProvider(name="hijrahToThai") + Object[][] data_hijrahToThai() { + return new Object[][] { + {HijrahDate.of(1350,5,15), ThaiBuddhistDate.of(2474,9,28)}, + {HijrahDate.of(1434,5,1), ThaiBuddhistDate.of(2556,3,13)}, + {HijrahDate.of(1436,1,1), ThaiBuddhistDate.of(2557,10,25)}, + {HijrahDate.of(1500,6,12), ThaiBuddhistDate.of(2620,5,5)}, + {HijrahDate.of(1550,3,11), ThaiBuddhistDate.of(2668,8,11)}, + }; + } + + // Test to verify the date conversion from Hijrah to Thai chronology + @Test(dataProvider="hijrahToThai") + public void test_hijrahToThai(HijrahDate hijrah, ThaiBuddhistDate thai) { + assertEquals(ThaiBuddhistChronology.INSTANCE.date(hijrah), thai); + } + + // Sample Hijrah & Japanese Dates + @DataProvider(name="hijrahToJapanese") + Object[][] data_hijrahToJapanese() { + return new Object[][] { + {HijrahDate.of(1350,5,15), "Japanese Showa 6-09-28"}, + {HijrahDate.of(1434,5,1), "Japanese Heisei 25-03-13"}, + {HijrahDate.of(1436,1,1), "Japanese Heisei 26-10-25"}, + {HijrahDate.of(1500,6,12), "Japanese Heisei 89-05-05"}, + {HijrahDate.of(1550,3,11), "Japanese Heisei 137-08-11"}, + }; + } + + // Test to verify the date conversion from Hijrah to Japanese chronology + @Test(dataProvider="hijrahToJapanese") + public void test_hijrahToJapanese(HijrahDate hijrah, String japanese) { + assertEquals(JapaneseChronology.INSTANCE.date(hijrah).toString(), japanese); } } diff --git a/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java b/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java index 056dfa22dcd..aebccfddc12 100644 --- a/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java +++ b/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java @@ -131,18 +131,18 @@ public class TestDateTimeTextProvider extends AbstractTestPrinterParser { {MONTH_OF_YEAR, 11, TextStyle.SHORT, enUS, "Nov"}, {MONTH_OF_YEAR, 12, TextStyle.SHORT, enUS, "Dec"}, - {MONTH_OF_YEAR, 1, TextStyle.SHORT, ptBR, "Jan"}, - {MONTH_OF_YEAR, 2, TextStyle.SHORT, ptBR, "Fev"}, - {MONTH_OF_YEAR, 3, TextStyle.SHORT, ptBR, "Mar"}, - {MONTH_OF_YEAR, 4, TextStyle.SHORT, ptBR, "Abr"}, - {MONTH_OF_YEAR, 5, TextStyle.SHORT, ptBR, "Mai"}, - {MONTH_OF_YEAR, 6, TextStyle.SHORT, ptBR, "Jun"}, - {MONTH_OF_YEAR, 7, TextStyle.SHORT, ptBR, "Jul"}, - {MONTH_OF_YEAR, 8, TextStyle.SHORT, ptBR, "Ago"}, - {MONTH_OF_YEAR, 9, TextStyle.SHORT, ptBR, "Set"}, - {MONTH_OF_YEAR, 10, TextStyle.SHORT, ptBR, "Out"}, - {MONTH_OF_YEAR, 11, TextStyle.SHORT, ptBR, "Nov"}, - {MONTH_OF_YEAR, 12, TextStyle.SHORT, ptBR, "Dez"}, + {MONTH_OF_YEAR, 1, TextStyle.SHORT, ptBR, "jan"}, + {MONTH_OF_YEAR, 2, TextStyle.SHORT, ptBR, "fev"}, + {MONTH_OF_YEAR, 3, TextStyle.SHORT, ptBR, "mar"}, + {MONTH_OF_YEAR, 4, TextStyle.SHORT, ptBR, "abr"}, + {MONTH_OF_YEAR, 5, TextStyle.SHORT, ptBR, "mai"}, + {MONTH_OF_YEAR, 6, TextStyle.SHORT, ptBR, "jun"}, + {MONTH_OF_YEAR, 7, TextStyle.SHORT, ptBR, "jul"}, + {MONTH_OF_YEAR, 8, TextStyle.SHORT, ptBR, "ago"}, + {MONTH_OF_YEAR, 9, TextStyle.SHORT, ptBR, "set"}, + {MONTH_OF_YEAR, 10, TextStyle.SHORT, ptBR, "out"}, + {MONTH_OF_YEAR, 11, TextStyle.SHORT, ptBR, "nov"}, + {MONTH_OF_YEAR, 12, TextStyle.SHORT, ptBR, "dez"}, {MONTH_OF_YEAR, 1, TextStyle.FULL, enUS, "January"}, {MONTH_OF_YEAR, 2, TextStyle.FULL, enUS, "February"}, diff --git a/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java b/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java index 49ec4d6554f..af6be84ef92 100644 --- a/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java +++ b/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java @@ -126,7 +126,7 @@ public class TestNonIsoFormatter { @Test(dataProvider="format_data") public void test_formatLocalizedDate(Chronology chrono, Locale formatLocale, Locale numberingLocale, - ChronoLocalDate date, String expected) { + ChronoLocalDate date, String expected) { DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL) .withChronology(chrono).withLocale(formatLocale) .withDecimalStyle(DecimalStyle.of(numberingLocale)); @@ -136,12 +136,12 @@ public class TestNonIsoFormatter { @Test(dataProvider="format_data") public void test_parseLocalizedText(Chronology chrono, Locale formatLocale, Locale numberingLocale, - ChronoLocalDate expected, String text) { + ChronoLocalDate expected, String text) { DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL) .withChronology(chrono).withLocale(formatLocale) .withDecimalStyle(DecimalStyle.of(numberingLocale)); TemporalAccessor temporal = dtf.parse(text); - ChronoLocalDate date = chrono.date(temporal); + ChronoLocalDate date = chrono.date(temporal); assertEquals(date, expected); } diff --git a/jdk/test/java/time/test/java/time/format/TestNumberPrinter.java b/jdk/test/java/time/test/java/time/format/TestNumberPrinter.java index 9d686472ab6..dedcc37e2ce 100644 --- a/jdk/test/java/time/test/java/time/format/TestNumberPrinter.java +++ b/jdk/test/java/time/test/java/time/format/TestNumberPrinter.java @@ -191,7 +191,7 @@ public class TestNumberPrinter extends AbstractTestPrinterParser { assertEquals(buf.toString(), result); } catch (DateTimeException ex) { if (result == null || value < 0) { - assertEquals(ex.getMessage().contains(DAY_OF_MONTH.getName()), true); + assertEquals(ex.getMessage().contains(DAY_OF_MONTH.toString()), true); } else { throw ex; } @@ -210,7 +210,7 @@ public class TestNumberPrinter extends AbstractTestPrinterParser { if (result != null) { throw ex; } - assertEquals(ex.getMessage().contains(DAY_OF_MONTH.getName()), true); + assertEquals(ex.getMessage().contains(DAY_OF_MONTH.toString()), true); } } @@ -226,7 +226,7 @@ public class TestNumberPrinter extends AbstractTestPrinterParser { if (result != null) { throw ex; } - assertEquals(ex.getMessage().contains(DAY_OF_MONTH.getName()), true); + assertEquals(ex.getMessage().contains(DAY_OF_MONTH.toString()), true); } } @@ -242,7 +242,7 @@ public class TestNumberPrinter extends AbstractTestPrinterParser { if (result != null) { throw ex; } - assertEquals(ex.getMessage().contains(DAY_OF_MONTH.getName()), true); + assertEquals(ex.getMessage().contains(DAY_OF_MONTH.toString()), true); } } @@ -262,7 +262,7 @@ public class TestNumberPrinter extends AbstractTestPrinterParser { if (result != null) { throw ex; } - assertEquals(ex.getMessage().contains(DAY_OF_MONTH.getName()), true); + assertEquals(ex.getMessage().contains(DAY_OF_MONTH.toString()), true); } } diff --git a/jdk/test/java/time/test/java/time/format/TestReducedPrinter.java b/jdk/test/java/time/test/java/time/format/TestReducedPrinter.java index 5ff2cd5eed8..c23cff27373 100644 --- a/jdk/test/java/time/test/java/time/format/TestReducedPrinter.java +++ b/jdk/test/java/time/test/java/time/format/TestReducedPrinter.java @@ -185,7 +185,7 @@ public class TestReducedPrinter extends AbstractTestPrinterParser { assertEquals(buf.toString(), result); } catch (DateTimeException ex) { if (result == null || value < 0) { - assertEquals(ex.getMessage().contains(YEAR.getName()), true); + assertEquals(ex.getMessage().contains(YEAR.toString()), true); } else { throw ex; } diff --git a/jdk/test/java/time/test/java/time/temporal/MockFieldNoValue.java b/jdk/test/java/time/test/java/time/temporal/MockFieldNoValue.java index eb97313ae19..ed2f6d59b10 100644 --- a/jdk/test/java/time/test/java/time/temporal/MockFieldNoValue.java +++ b/jdk/test/java/time/test/java/time/temporal/MockFieldNoValue.java @@ -76,11 +76,6 @@ public enum MockFieldNoValue implements TemporalField { INSTANCE; - @Override - public String getName() { - return null; - } - @Override public TemporalUnit getBaseUnit() { return WEEKS; @@ -96,6 +91,16 @@ public enum MockFieldNoValue implements TemporalField { return ValueRange.of(1, 20); } + @Override + public boolean isDateBased() { + return false; + } + + @Override + public boolean isTimeBased() { + return false; + } + //----------------------------------------------------------------------- @Override public boolean isSupportedBy(TemporalAccessor temporal) { @@ -117,4 +122,9 @@ public enum MockFieldNoValue implements TemporalField { throw new DateTimeException("Mock"); } + @Override + public String toString() { + return null; + } + } diff --git a/jdk/test/java/time/test/java/time/temporal/MockFieldValue.java b/jdk/test/java/time/test/java/time/temporal/MockFieldValue.java index 0cd79d7f1e9..7747bda7714 100644 --- a/jdk/test/java/time/test/java/time/temporal/MockFieldValue.java +++ b/jdk/test/java/time/test/java/time/temporal/MockFieldValue.java @@ -89,7 +89,7 @@ public final class MockFieldValue implements TemporalAccessor { if (isSupported(field)) { return field.range(); } - throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName()); + throw new UnsupportedTemporalTypeException("Unsupported field: " + field); } return field.rangeRefinedBy(this); } diff --git a/langtools/.hgtags b/langtools/.hgtags index 9cd182f694a..d8403722780 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -218,3 +218,4 @@ e19283cd30a43fca94d8f7639c73ef66db493b1e jdk8-b90 48c6e6ab7c815fd41d747f0218f8041c22f3a460 jdk8-b94 4cb1136231275a1f8af53f5bfdef0b488e4b5bab jdk8-b95 988aef3a8c3adac482363293f65e77ec4c5ce98d jdk8-b96 +6a11a81a8824c17f6cd2ec8f8492e1229b694e96 jdk8-b97 diff --git a/langtools/make/build.properties b/langtools/make/build.properties index 7fd5ffcb371..d16be20b724 100644 --- a/langtools/make/build.properties +++ b/langtools/make/build.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ boot.javac.target = 7 target.java = ${target.java.home}/bin/java # Version info -- override as needed -jdk.version = 1.7.0 +jdk.version = 1.8.0 build.number = b00 milestone = internal @@ -60,8 +60,8 @@ full.version = ${release}-${build.number} bootstrap.full.version = ${bootstrap.release}-${build.number} # options for the tasks used to compile the tools -javac.source = 7 -javac.target = 7 +javac.source = 8 +javac.target = 8 javac.debug = true javac.debuglevel = source,lines javac.no.jdk.warnings = -XDignore.symbol.file=true diff --git a/langtools/src/share/classes/com/sun/source/util/TreePath.java b/langtools/src/share/classes/com/sun/source/util/TreePath.java index d7df6a96b03..1d23b08fde6 100644 --- a/langtools/src/share/classes/com/sun/source/util/TreePath.java +++ b/langtools/src/share/classes/com/sun/source/util/TreePath.java @@ -125,18 +125,25 @@ public class TreePath implements Iterable { return parent; } + /** + * Iterates from leaves to root. + */ + @Override public Iterator iterator() { return new Iterator() { + @Override public boolean hasNext() { return next != null; } + @Override public Tree next() { Tree t = next.leaf; next = next.parent; return t; } + @Override public void remove() { throw new UnsupportedOperationException(); } diff --git a/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java b/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java index 3f854395f9b..dc4fc9d0137 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java @@ -77,10 +77,12 @@ public abstract class Attribute { public Attribute createAttribute(ClassReader cr, int name_index, byte[] data) throws IOException { - if (standardAttributes == null) + if (standardAttributes == null) { init(); + } ConstantPool cp = cr.getConstantPool(); + String reasonForDefaultAttr; try { String name = cp.getUTF8Value(name_index); Class attrClass = standardAttributes.get(name); @@ -90,14 +92,18 @@ public abstract class Attribute { Constructor constr = attrClass.getDeclaredConstructor(constrArgTypes); return constr.newInstance(new Object[] { cr, name_index, data.length }); } catch (Throwable t) { + reasonForDefaultAttr = t.toString(); // fall through and use DefaultAttribute // t.printStackTrace(); } + } else { + reasonForDefaultAttr = "unknown attribute"; } } catch (ConstantPoolException e) { + reasonForDefaultAttr = e.toString(); // fall through and use DefaultAttribute } - return new DefaultAttribute(cr, name_index, data); + return new DefaultAttribute(cr, name_index, data, reasonForDefaultAttr); } protected void init() { diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java b/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java index e8b5fc8d85a..52aefca5469 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java @@ -26,9 +26,9 @@ package com.sun.tools.classfile; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; import java.nio.file.Path; import static com.sun.tools.classfile.AccessFlags.*; @@ -44,26 +44,24 @@ import static com.sun.tools.classfile.AccessFlags.*; public class ClassFile { public static ClassFile read(File file) throws IOException, ConstantPoolException { - return read(file, new Attribute.Factory()); + return read(file.toPath(), new Attribute.Factory()); } - public static ClassFile read(Path path) + public static ClassFile read(Path input) throws IOException, ConstantPoolException { - return read(path.toFile(), new Attribute.Factory()); + return read(input, new Attribute.Factory()); + } + + public static ClassFile read(Path input, Attribute.Factory attributeFactory) + throws IOException, ConstantPoolException { + try (InputStream in = Files.newInputStream(input)) { + return new ClassFile(in, attributeFactory); + } } public static ClassFile read(File file, Attribute.Factory attributeFactory) throws IOException, ConstantPoolException { - FileInputStream in = new FileInputStream(file); - try { - return new ClassFile(in, attributeFactory); - } finally { - try { - in.close(); - } catch (IOException e) { - // ignore - } - } + return read(file.toPath(), attributeFactory); } public static ClassFile read(InputStream in) diff --git a/langtools/src/share/classes/com/sun/tools/classfile/DefaultAttribute.java b/langtools/src/share/classes/com/sun/tools/classfile/DefaultAttribute.java index fba1700f35e..16fdeb9824d 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/DefaultAttribute.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/DefaultAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,13 +33,24 @@ package com.sun.tools.classfile; */ public class DefaultAttribute extends Attribute { DefaultAttribute(ClassReader cr, int name_index, byte[] data) { + this(cr, name_index, data, null); + } + + DefaultAttribute(ClassReader cr, int name_index, byte[] data, String reason) { super(name_index, data.length); info = data; + this.reason = reason; } public DefaultAttribute(ConstantPool constant_pool, int name_index, byte[] info) { + this(constant_pool, name_index, info, null); + } + + public DefaultAttribute(ConstantPool constant_pool, int name_index, + byte[] info, String reason) { super(name_index, info.length); this.info = info; + this.reason = reason; } public R accept(Visitor visitor, P p) { @@ -47,4 +58,7 @@ public class DefaultAttribute extends Attribute { } public final byte[] info; + /** Why did we need to generate a DefaultAttribute + */ + public final String reason; } diff --git a/langtools/src/share/classes/com/sun/tools/classfile/SourceDebugExtension_attribute.java b/langtools/src/share/classes/com/sun/tools/classfile/SourceDebugExtension_attribute.java index ba1f2aa870f..6744500f1c2 100644 --- a/langtools/src/share/classes/com/sun/tools/classfile/SourceDebugExtension_attribute.java +++ b/langtools/src/share/classes/com/sun/tools/classfile/SourceDebugExtension_attribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ package com.sun.tools.classfile; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; +import java.nio.charset.Charset; /** * See JVMS, section 4.8.15. @@ -38,6 +39,8 @@ import java.io.IOException; * deletion without notice. */ public class SourceDebugExtension_attribute extends Attribute { + private static final Charset UTF8 = Charset.forName("UTF-8"); + SourceDebugExtension_attribute(ClassReader cr, int name_index, int length) throws IOException { super(name_index, length); debug_extension = new byte[attribute_length]; @@ -55,12 +58,7 @@ public class SourceDebugExtension_attribute extends Attribute { } public String getValue() { - DataInputStream d = new DataInputStream(new ByteArrayInputStream(debug_extension)); - try { - return d.readUTF(); - } catch (IOException e) { - return null; - } + return new String(debug_extension, UTF8); } public R accept(Visitor visitor, D data) { diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java index b0d64d59beb..719aace1556 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/ClassBuilder.java @@ -289,7 +289,8 @@ public class ClassBuilder extends AbstractBuilder { * @param classInfoTree the content tree to which the documentation will be added */ public void buildClassSignature(XMLNode node, Content classInfoTree) { - StringBuilder modifiers = new StringBuilder(classDoc.modifiers() + " "); + StringBuilder modifiers = new StringBuilder(classDoc.modifiers()); + modifiers.append(modifiers.length() == 0 ? "" : " "); if (isEnum) { modifiers.append("enum "); int index; diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java index 0eb548ff9e8..8edb5dd2bad 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/MemberSummaryBuilder.java @@ -385,15 +385,21 @@ public class MemberSummaryBuilder extends AbstractMemberBuilder { } commentTextBuilder.append(propertyDoc.commentText()); - Tag[] tags = propertyDoc.tags("@defaultValue"); - if (tags != null) { - for (Tag tag: tags) { - commentTextBuilder.append("\n") - .append(tag.name()) - .append(" ") - .append(tag.text()); + // copy certain tags + List allTags = new LinkedList(); + String[] tagNames = {"@defaultValue", "@since"}; + for (String tagName: tagNames) { + Tag[] tags = propertyDoc.tags(tagName); + if (tags != null) { + allTags.addAll(Arrays.asList(tags)); } } + for (Tag tag: allTags) { + commentTextBuilder.append("\n") + .append(tag.name()) + .append(" ") + .append(tag.text()); + } //add @see tags if (!isGetter && !isSetter) { diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css index 97c67415bc2..6634d8aedfe 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/stylesheet.css @@ -371,6 +371,7 @@ Table styles overflow:hidden; padding:0px; margin:0px; + white-space:pre; } caption a:link, caption a:hover, caption a:active, caption a:visited { color:#FFFFFF; diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java index 377cd670dee..b6af4746e03 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java @@ -631,6 +631,10 @@ public class TagletManager { * Initialize standard Javadoc tags for ordering purposes. */ private void initStandardTaglets() { + if (javafx) { + initJavaFXTaglets(); + } + Taglet temp; addStandardTaglet(new ParamTaglet()); addStandardTaglet(new ReturnTaglet()); @@ -664,10 +668,6 @@ public class TagletManager { standardTags.add("serial"); standardTags.add("serialField"); standardTags.add("Text"); - - if (javafx) { - initJavaFXTaglets(); - } } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java index 19dde2aef0d..ef03f718cc0 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java +++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java @@ -69,6 +69,7 @@ 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.TypeTag; import com.sun.tools.javac.code.Types.TypeRelation; import com.sun.tools.javac.comp.Attr; import com.sun.tools.javac.comp.AttrContext; @@ -653,8 +654,7 @@ public class JavacTrees extends DocTrees { 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(); - + return t.hasTag(s.getTag()); default: throw new AssertionError("fuzzyMatcher " + t.getTag()); } @@ -668,7 +668,7 @@ public class JavacTrees extends DocTrees { if (s.isPartial()) return visit(s, t); - return s.getTag() == ARRAY + return s.hasTag(ARRAY) && visit(t.elemtype, types.elemtype(s)); } @@ -685,7 +685,7 @@ public class JavacTrees extends DocTrees { @Override public Boolean visitErrorType(ErrorType t, Type s) { - return s.getTag() == CLASS + return s.hasTag(CLASS) && t.tsym.name == ((ClassType) s).tsym.name; } }; diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java index ec76bbf7637..bb29eeaa530 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java @@ -83,7 +83,7 @@ public abstract class Attribute implements AnnotationValue { return v.visitString((String) value, p); if (value instanceof Integer) { int i = (Integer) value; - switch (type.tag) { + switch (type.getTag()) { case BOOLEAN: return v.visitBoolean(i != 0, p); case CHAR: return v.visitChar((char) i, p); case BYTE: return v.visitByte((byte) i, p); @@ -91,7 +91,7 @@ public abstract class Attribute implements AnnotationValue { case INT: return v.visitInt(i, p); } } - switch (type.tag) { + switch (type.getTag()) { case LONG: return v.visitLong((Long) value, p); case FLOAT: return v.visitFloat((Float) value, p); case DOUBLE: return v.visitDouble((Double) value, p); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java b/langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java index 08fbd1a57e4..1ea1d4e47f5 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Kinds.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,9 +73,13 @@ public class Kinds { */ public final static int MTH = 1 << 4; + /** Poly kind, for deferred types. + */ + public final static int POLY = 1 << 5; + /** The error kind, which includes all other kinds. */ - public final static int ERR = (1 << 5) - 1; + public final static int ERR = (1 << 6) - 1; /** The set of all kinds. */ @@ -83,7 +87,7 @@ public class Kinds { /** Kinds for erroneous symbols that complement the above */ - public static final int ERRONEOUS = 1 << 6; + public static final int ERRONEOUS = 1 << 7; public static final int AMBIGUOUS = ERRONEOUS+1; // ambiguous reference public static final int HIDDEN = ERRONEOUS+2; // hidden method or field public static final int STATICERR = ERRONEOUS+3; // nonstatic member from static context @@ -214,10 +218,10 @@ public class Kinds { /** A KindName representing the kind of a given class/interface type. */ public static KindName typeKindName(Type t) { - if (t.tag == TYPEVAR || - t.tag == CLASS && (t.tsym.flags() & COMPOUND) != 0) + if (t.hasTag(TYPEVAR) || + t.hasTag(CLASS) && (t.tsym.flags() & COMPOUND) != 0) return KindName.BOUND; - else if (t.tag == PACKAGE) + else if (t.hasTag(PACKAGE)) return KindName.PACKAGE; else if ((t.tsym.flags_field & ANNOTATION) != 0) return KindName.ANNOTATION; diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java index 76e54103062..be0b5038018 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Printer.java @@ -215,7 +215,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi @Override public String visitClassType(ClassType t, Locale locale) { StringBuilder buf = new StringBuilder(); - if (t.getEnclosingType().tag == CLASS && t.tsym.owner.kind == Kinds.TYP) { + if (t.getEnclosingType().hasTag(CLASS) && t.tsym.owner.kind == Kinds.TYP) { buf.append(visit(t.getEnclosingType(), locale)); buf.append('.'); buf.append(className(t, false, locale)); @@ -379,7 +379,7 @@ public abstract class Printer implements Type.Visitor, Symbol.Vi ? s.owner.name.toString() : s.name.toString(); if (s.type != null) { - if (s.type.tag == FORALL) { + if (s.type.hasTag(FORALL)) { ms = "<" + visitTypes(s.type.getTypeArguments(), locale) + ">" + ms; } ms += "(" + printMethodArgs( diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java index 972210c66d8..e05418e4001 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java @@ -699,17 +699,17 @@ public abstract class Symbol implements Element { public final boolean precedes(TypeSymbol that, Types types) { if (this == that) return false; - if (this.type.tag == that.type.tag) { - if (this.type.hasTag(CLASS)) { + if (type.hasTag(that.type.getTag())) { + if (type.hasTag(CLASS)) { return types.rank(that.type) < types.rank(this.type) || types.rank(that.type) == types.rank(this.type) && that.getQualifiedName().compareTo(this.getQualifiedName()) < 0; - } else if (this.type.hasTag(TYPEVAR)) { + } else if (type.hasTag(TYPEVAR)) { return types.isSubtype(this.type, that.type); } } - return this.type.hasTag(TYPEVAR); + return type.hasTag(TYPEVAR); } @Override diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java index 6f666825692..3130ad0d27e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java @@ -28,7 +28,6 @@ package com.sun.tools.javac.code; import java.util.*; import javax.lang.model.element.ElementVisitor; -import javax.lang.model.type.TypeVisitor; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; @@ -65,16 +64,16 @@ public class Symtab { /** Builtin types. */ - public final Type byteType = new Type(BYTE, null); - public final Type charType = new Type(CHAR, null); - public final Type shortType = new Type(SHORT, null); - public final Type intType = new Type(INT, null); - public final Type longType = new Type(LONG, null); - public final Type floatType = new Type(FLOAT, null); - public final Type doubleType = new Type(DOUBLE, null); - public final Type booleanType = new Type(BOOLEAN, null); + public final JCPrimitiveType byteType = new JCPrimitiveType(BYTE, null); + public final JCPrimitiveType charType = new JCPrimitiveType(CHAR, null); + public final JCPrimitiveType shortType = new JCPrimitiveType(SHORT, null); + public final JCPrimitiveType intType = new JCPrimitiveType(INT, null); + public final JCPrimitiveType longType = new JCPrimitiveType(LONG, null); + public final JCPrimitiveType floatType = new JCPrimitiveType(FLOAT, null); + public final JCPrimitiveType doubleType = new JCPrimitiveType(DOUBLE, null); + public final JCPrimitiveType booleanType = new JCPrimitiveType(BOOLEAN, null); public final Type botType = new BottomType(); - public final JCNoType voidType = new JCNoType(VOID); + public final JCVoidType voidType = new JCVoidType(); private final Names names; private final ClassReader reader; @@ -208,7 +207,7 @@ public class Symtab { public void initType(Type type, ClassSymbol c) { type.tsym = c; - typeOfTag[type.tag.ordinal()] = type; + typeOfTag[type.getTag().ordinal()] = type; } public void initType(Type type, String name) { @@ -220,7 +219,7 @@ public class Symtab { public void initType(Type type, String name, String bname) { initType(type, name); - boxedName[type.tag.ordinal()] = names.fromString("java.lang." + bname); + boxedName[type.getTag().ordinal()] = names.fromString("java.lang." + bname); } /** The class symbol that owns all predefined symbols. @@ -330,7 +329,7 @@ public class Symtab { } public void synthesizeBoxTypeIfMissing(final Type type) { - ClassSymbol sym = reader.enterClass(boxedName[type.tag.ordinal()]); + ClassSymbol sym = reader.enterClass(boxedName[type.getTag().ordinal()]); final Completer completer = sym.completer; if (completer != null) { sym.completer = new Completer() { @@ -388,12 +387,7 @@ public class Symtab { target = Target.instance(context); // Create the unknown type - unknownType = new Type(UNKNOWN, null) { - @Override - public R accept(TypeVisitor v, P p) { - return v.visitUnknown(this, p); - } - }; + unknownType = new UnknownType(); // create the basic builtin symbols rootPackage = new PackageSymbol(names.empty, null); diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java index f868290b5b3..a89f86eed50 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java @@ -70,25 +70,19 @@ import static com.sun.tools.javac.code.TypeTag.*; * * @see TypeTag */ -public class Type implements PrimitiveType { +public abstract class Type implements TypeMirror { /** Constant type: no type at all. */ - public static final JCNoType noType = new JCNoType(NONE); + public static final JCNoType noType = new JCNoType(); /** Constant type: special type to be used during recovery of deferred expressions. */ - public static final JCNoType recoveryType = new JCNoType(NONE); + public static final JCNoType recoveryType = new JCNoType(); /** If this switch is turned on, the names of type variables * and anonymous classes are printed with hashcodes appended. */ public static boolean moreInfo = false; - /** The tag of this type. - * - * @see TypeTag - */ - protected TypeTag tag; - /** The defining class / interface / package / type variable. */ public TypeSymbol tsym; @@ -98,39 +92,37 @@ public class Type implements PrimitiveType { * @return true if tag is equal to the current type tag. */ public boolean hasTag(TypeTag tag) { - return this.tag == tag; + return tag == getTag(); } /** * Returns the current type tag. * @return the value of the current type tag. */ - public TypeTag getTag() { - return tag; - } + public abstract TypeTag getTag(); public boolean isNumeric() { - return tag.isNumeric; + return false; } public boolean isPrimitive() { - return tag.isPrimitive; + return false; } public boolean isPrimitiveOrVoid() { - return tag.isPrimitiveOrVoid; + return false; } public boolean isReference() { - return tag.isReference; + return false; } public boolean isNullOrReference() { - return (tag.isReference || tag == BOT); + return false; } public boolean isPartial() { - return tag.isPartial; + return false; } /** @@ -143,6 +135,18 @@ public class Type implements PrimitiveType { return null; } + /** Is this a constant type whose value is false? + */ + public boolean isFalse() { + return false; + } + + /** Is this a constant type whose value is true? + */ + public boolean isTrue() { + return false; + } + /** * Get the representation of this type used for modelling purposes. * By default, this is itself. For ErrorType, a different value @@ -153,7 +157,7 @@ public class Type implements PrimitiveType { } public static List getModelTypes(List ts) { - ListBuffer lb = new ListBuffer(); + ListBuffer lb = new ListBuffer<>(); for (Type t: ts) lb.append(t.getModelType()); return lb.toList(); @@ -163,8 +167,7 @@ public class Type implements PrimitiveType { /** Define a type given its tag and type symbol */ - public Type(TypeTag tag, TypeSymbol tsym) { - this.tag = tag; + public Type(TypeSymbol tsym) { this.tsym = tsym; } @@ -203,18 +206,7 @@ public class Type implements PrimitiveType { * and with given constant value */ public Type constType(Object constValue) { - final Object value = constValue; - Assert.check(isPrimitive()); - return new Type(tag, tsym) { - @Override - public Object constValue() { - return value; - } - @Override - public Type baseType() { - return tsym.type; - } - }; + throw new AssertionError(); } /** @@ -272,7 +264,9 @@ public class Type implements PrimitiveType { String s = (tsym == null || tsym.name == null) ? "" : tsym.name.toString(); - if (moreInfo && tag == TYPEVAR) s = s + hashCode(); + if (moreInfo && hasTag(TYPEVAR)) { + s = s + hashCode(); + } return s; } @@ -298,12 +292,7 @@ public class Type implements PrimitiveType { */ public String stringValue() { Object cv = Assert.checkNonNull(constValue()); - if (tag == BOOLEAN) - return ((Integer) cv).intValue() == 0 ? "false" : "true"; - else if (tag == CHAR) - return String.valueOf((char) ((Integer) cv).intValue()); - else - return cv.toString(); + return cv.toString(); } /** @@ -321,24 +310,6 @@ public class Type implements PrimitiveType { return super.hashCode(); } - /** Is this a constant type whose value is false? - */ - public boolean isFalse() { - return - tag == BOOLEAN && - constValue() != null && - ((Integer)constValue()).intValue() == 0; - } - - /** Is this a constant type whose value is true? - */ - public boolean isTrue() { - return - tag == BOOLEAN && - constValue() != null && - ((Integer)constValue()).intValue() != 0; - } - public String argtypes(boolean varargs) { List args = getParameterTypes(); if (!varargs) return args.toString(); @@ -348,7 +319,7 @@ public class Type implements PrimitiveType { args = args.tail; buf.append(','); } - if (args.head.unannotatedType().tag == ARRAY) { + if (args.head.unannotatedType().hasTag(ARRAY)) { buf.append(((ArrayType)args.head.unannotatedType()).elemtype); if (args.head.getAnnotationMirrors().nonEmpty()) { buf.append(args.head.getAnnotationMirrors()); @@ -485,28 +456,122 @@ public class Type implements PrimitiveType { return tsym; } + @Override public TypeKind getKind() { - switch (tag) { - case BYTE: return TypeKind.BYTE; - case CHAR: return TypeKind.CHAR; - case SHORT: return TypeKind.SHORT; - case INT: return TypeKind.INT; - case LONG: return TypeKind.LONG; - case FLOAT: return TypeKind.FLOAT; - case DOUBLE: return TypeKind.DOUBLE; - case BOOLEAN: return TypeKind.BOOLEAN; - case VOID: return TypeKind.VOID; - case BOT: return TypeKind.NULL; - case NONE: return TypeKind.NONE; - default: return TypeKind.OTHER; - } + return TypeKind.OTHER; } + @Override public R accept(TypeVisitor v, P p) { - if (isPrimitive()) + throw new AssertionError(); + } + + public static class JCPrimitiveType extends Type + implements javax.lang.model.type.PrimitiveType { + + TypeTag tag; + + public JCPrimitiveType(TypeTag tag, TypeSymbol tsym) { + super(tsym); + this.tag = tag; + Assert.check(tag.isPrimitive); + } + + @Override + public boolean isNumeric() { + return tag != BOOLEAN; + } + + @Override + public boolean isPrimitive() { + return true; + } + + @Override + public TypeTag getTag() { + return tag; + } + + @Override + public boolean isPrimitiveOrVoid() { + return true; + } + + /** Define a constant type, of the same kind as this type + * and with given constant value + */ + @Override + public Type constType(Object constValue) { + final Object value = constValue; + return new JCPrimitiveType(tag, tsym) { + @Override + public Object constValue() { + return value; + } + @Override + public Type baseType() { + return tsym.type; + } + }; + } + + /** + * The constant value of this type, converted to String + */ + @Override + public String stringValue() { + Object cv = Assert.checkNonNull(constValue()); + if (tag == BOOLEAN) { + return ((Integer) cv).intValue() == 0 ? "false" : "true"; + } + else if (tag == CHAR) { + return String.valueOf((char) ((Integer) cv).intValue()); + } + else { + return cv.toString(); + } + } + + /** Is this a constant type whose value is false? + */ + @Override + public boolean isFalse() { + return + tag == BOOLEAN && + constValue() != null && + ((Integer)constValue()).intValue() == 0; + } + + /** Is this a constant type whose value is true? + */ + @Override + public boolean isTrue() { + return + tag == BOOLEAN && + constValue() != null && + ((Integer)constValue()).intValue() != 0; + } + + @Override + public R accept(TypeVisitor v, P p) { return v.visitPrimitive(this, p); - else + } + + @Override + public TypeKind getKind() { + switch (tag) { + case BYTE: return TypeKind.BYTE; + case CHAR: return TypeKind.CHAR; + case SHORT: return TypeKind.SHORT; + case INT: return TypeKind.INT; + case LONG: return TypeKind.LONG; + case FLOAT: return TypeKind.FLOAT; + case DOUBLE: return TypeKind.DOUBLE; + case BOOLEAN: return TypeKind.BOOLEAN; + } throw new AssertionError(); + } + } public static class WildcardType extends Type @@ -522,7 +587,7 @@ public class Type implements PrimitiveType { } public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) { - super(WILDCARD, tsym); + super(tsym); this.type = Assert.checkNonNull(type); this.kind = kind; } @@ -535,6 +600,12 @@ public class Type implements PrimitiveType { this.bound = bound; } + @Override + public TypeTag getTag() { + return WILDCARD; + } + + @Override public boolean contains(Type t) { return kind != UNBOUND && type.contains(t); } @@ -551,6 +622,17 @@ public class Type implements PrimitiveType { return kind == UNBOUND; } + @Override + public boolean isReference() { + return true; + } + + @Override + public boolean isNullOrReference() { + return true; + } + + @Override public Type withTypeVar(Type t) { //-System.err.println(this+".withTypeVar("+t+");");//DEBUG if (bound == t) @@ -640,7 +722,7 @@ public class Type implements PrimitiveType { public List all_interfaces_field; public ClassType(Type outer, List typarams, TypeSymbol tsym) { - super(CLASS, tsym); + super(tsym); this.outer_field = outer; this.typarams_field = typarams; this.allparams_field = null; @@ -657,6 +739,11 @@ public class Type implements PrimitiveType { */ } + @Override + public TypeTag getTag() { + return CLASS; + } + @Override public R accept(Type.Visitor v, S s) { return v.visitClassType(this, s); @@ -680,7 +767,7 @@ public class Type implements PrimitiveType { */ public String toString() { StringBuilder buf = new StringBuilder(); - if (getEnclosingType().tag == CLASS && tsym.owner.kind == TYP) { + if (getEnclosingType().hasTag(CLASS) && tsym.owner.kind == TYP) { buf.append(getEnclosingType().toString()); buf.append("."); buf.append(className(tsym, false)); @@ -765,6 +852,16 @@ public class Type implements PrimitiveType { // optimization, was: allparams().nonEmpty(); } + @Override + public boolean isReference() { + return true; + } + + @Override + public boolean isNullOrReference() { + return true; + } + /** A cache for the rank. */ int rank_field = -1; @@ -909,11 +1006,15 @@ public class Type implements PrimitiveType { public Type elemtype; public ArrayType(Type elemtype, TypeSymbol arrayClass) { - super(ARRAY, arrayClass); + super(arrayClass); this.elemtype = elemtype; } @Override + public TypeTag getTag() { + return ARRAY; + } + public R accept(Type.Visitor v, S s) { return v.visitArrayType(this, s); } @@ -947,6 +1048,16 @@ public class Type implements PrimitiveType { return elemtype.isParameterized(); } + @Override + public boolean isReference() { + return true; + } + + @Override + public boolean isNullOrReference() { + return true; + } + public boolean isRaw() { return elemtype.isRaw(); } @@ -1001,13 +1112,17 @@ public class Type implements PrimitiveType { Type restype, List thrown, TypeSymbol methodClass) { - super(METHOD, methodClass); + super(methodClass); this.argtypes = argtypes; this.restype = restype; this.thrown = thrown; } @Override + public TypeTag getTag() { + return METHOD; + } + public R accept(Type.Visitor v, S s) { return v.visitMethodType(this, s); } @@ -1077,7 +1192,12 @@ public class Type implements PrimitiveType { public static class PackageType extends Type implements NoType { PackageType(TypeSymbol tsym) { - super(PACKAGE, tsym); + super(tsym); + } + + @Override + public TypeTag getTag() { + return PACKAGE; } @Override @@ -1120,17 +1240,22 @@ public class Type implements PrimitiveType { public Type lower; public TypeVar(Name name, Symbol owner, Type lower) { - super(TYPEVAR, null); + super(null); tsym = new TypeVariableSymbol(0, name, this, owner); this.lower = lower; } public TypeVar(TypeSymbol tsym, Type bound, Type lower) { - super(TYPEVAR, tsym); + super(tsym); this.bound = bound; this.lower = lower; } + @Override + public TypeTag getTag() { + return TYPEVAR; + } + @Override public R accept(Type.Visitor v, S s) { return v.visitTypeVar(this, s); @@ -1138,8 +1263,9 @@ public class Type implements PrimitiveType { @Override public Type getUpperBound() { - if ((bound == null || bound.tag == NONE) && this != tsym.type) + if ((bound == null || bound.hasTag(NONE)) && this != tsym.type) { bound = tsym.type.getUpperBound(); + } return bound; } @@ -1158,6 +1284,17 @@ public class Type implements PrimitiveType { return false; } + @Override + public boolean isReference() { + return true; + } + + @Override + public boolean isNullOrReference() { + return true; + } + + @Override public R accept(TypeVisitor v, P p) { return v.visitTypeVariable(this, p); } @@ -1203,10 +1340,13 @@ public class Type implements PrimitiveType { public static abstract class DelegatedType extends Type { public Type qtype; + public TypeTag tag; public DelegatedType(TypeTag tag, Type qtype) { - super(tag, qtype.tsym); + super(qtype.tsym); + this.tag = tag; this.qtype = qtype; } + public TypeTag getTag() { return tag; } public String toString() { return qtype.toString(); } public List getTypeArguments() { return qtype.getTypeArguments(); } public Type getEnclosingType() { return qtype.getEnclosingType(); } @@ -1340,6 +1480,12 @@ public class Type implements PrimitiveType { else return qtype + "?"; } + @Override + public boolean isPartial() { + return true; + } + + @Override public Type baseType() { if (inst != null) return inst.baseType(); else return this; @@ -1439,21 +1585,21 @@ public class Type implements PrimitiveType { } } - /** Represents VOID or NONE. + /** Represents NONE. */ - static class JCNoType extends Type implements NoType { - public JCNoType(TypeTag tag) { - super(tag, null); + public static class JCNoType extends Type implements NoType { + public JCNoType() { + super(null); + } + + @Override + public TypeTag getTag() { + return NONE; } @Override public TypeKind getKind() { - switch (tag) { - case VOID: return TypeKind.VOID; - case NONE: return TypeKind.NONE; - default: - throw new AssertionError("Unexpected tag: " + tag); - } + return TypeKind.NONE; } @Override @@ -1462,9 +1608,43 @@ public class Type implements PrimitiveType { } } + /** Represents VOID. + */ + public static class JCVoidType extends Type implements NoType { + + public JCVoidType() { + super(null); + } + + @Override + public TypeTag getTag() { + return VOID; + } + + @Override + public TypeKind getKind() { + return TypeKind.VOID; + } + + @Override + public R accept(TypeVisitor v, P p) { + return v.visitNoType(this, p); + } + + @Override + public boolean isPrimitiveOrVoid() { + return true; + } + } + static class BottomType extends Type implements NullType { public BottomType() { - super(BOT, null); + super(null); + } + + @Override + public TypeTag getTag() { + return BOT; } @Override @@ -1486,6 +1666,12 @@ public class Type implements PrimitiveType { public String stringValue() { return "null"; } + + @Override + public boolean isNullOrReference() { + return true; + } + } public static class ErrorType extends ClassType @@ -1495,7 +1681,6 @@ public class Type implements PrimitiveType { public ErrorType(Type originalType, TypeSymbol tsym) { super(noType, List.nil(), null); - tag = ERROR; this.tsym = tsym; this.originalType = (originalType == null ? noType : originalType); } @@ -1507,6 +1692,26 @@ public class Type implements PrimitiveType { c.members_field = new Scope.ErrorScope(c); } + @Override + public TypeTag getTag() { + return ERROR; + } + + @Override + public boolean isPartial() { + return true; + } + + @Override + public boolean isReference() { + return true; + } + + @Override + public boolean isNullOrReference() { + return true; + } + public ErrorType(Name name, TypeSymbol container, Type originalType) { this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType); } @@ -1559,7 +1764,7 @@ public class Type implements PrimitiveType { public Type underlyingType; public AnnotatedType(Type underlyingType) { - super(underlyingType.tag, underlyingType.tsym); + super(underlyingType.tsym); this.typeAnnotations = List.nil(); this.underlyingType = underlyingType; Assert.check(!underlyingType.isAnnotated(), @@ -1568,7 +1773,7 @@ public class Type implements PrimitiveType { public AnnotatedType(List typeAnnotations, Type underlyingType) { - super(underlyingType.tag, underlyingType.tsym); + super(underlyingType.tsym); this.typeAnnotations = typeAnnotations; this.underlyingType = underlyingType; Assert.check(!underlyingType.isAnnotated(), @@ -1576,6 +1781,11 @@ public class Type implements PrimitiveType { "; adding: " + typeAnnotations); } + @Override + public TypeTag getTag() { + return underlyingType.getTag(); + } + @Override public boolean isAnnotated() { return true; @@ -1651,10 +1861,18 @@ public class Type implements PrimitiveType { @Override public List allparams() { return underlyingType.allparams(); } @Override + public boolean isPrimitive() { return underlyingType.isPrimitive(); } + @Override + public boolean isPrimitiveOrVoid() { return underlyingType.isPrimitiveOrVoid(); } + @Override public boolean isNumeric() { return underlyingType.isNumeric(); } @Override public boolean isReference() { return underlyingType.isReference(); } @Override + public boolean isNullOrReference() { return underlyingType.isNullOrReference(); } + @Override + public boolean isPartial() { return underlyingType.isPartial(); } + @Override public boolean isParameterized() { return underlyingType.isParameterized(); } @Override public boolean isRaw() { return underlyingType.isRaw(); } @@ -1719,6 +1937,28 @@ public class Type implements PrimitiveType { public TypeMirror getSuperBound() { return ((WildcardType)underlyingType).getSuperBound(); } } + public static class UnknownType extends Type { + + public UnknownType() { + super(null); + } + + @Override + public TypeTag getTag() { + return UNKNOWN; + } + + @Override + public R accept(TypeVisitor v, P p) { + return v.visitUnknown(this, p); + } + + @Override + public boolean isPartial() { + return true; + } + } + /** * A visitor for types. A visitor is used to implement operations * (or relations) on types. Most common operations on types are diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/TypeTag.java b/langtools/src/share/classes/com/sun/tools/javac/code/TypeTag.java index 7fbfd8edbc1..418f1e13406 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeTag.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeTag.java @@ -42,132 +42,107 @@ import static com.sun.tools.javac.code.TypeTag.NumericClasses.*; public enum TypeTag { /** The tag of the basic type `byte'. */ - BYTE(BYTE_CLASS, BYTE_SUPERCLASSES, - TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), + BYTE(BYTE_CLASS, BYTE_SUPERCLASSES, true), /** The tag of the basic type `char'. */ - CHAR(CHAR_CLASS, CHAR_SUPERCLASSES, - TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), + CHAR(CHAR_CLASS, CHAR_SUPERCLASSES, true), /** The tag of the basic type `short'. */ - SHORT(SHORT_CLASS, SHORT_SUPERCLASSES, - TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), - - /** The tag of the basic type `int'. - */ - INT(INT_CLASS, INT_SUPERCLASSES, - TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), + SHORT(SHORT_CLASS, SHORT_SUPERCLASSES, true), /** The tag of the basic type `long'. */ - LONG(LONG_CLASS, LONG_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), + LONG(LONG_CLASS, LONG_SUPERCLASSES, true), /** The tag of the basic type `float'. */ - FLOAT(FLOAT_CLASS, FLOAT_SUPERCLASSES, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), - + FLOAT(FLOAT_CLASS, FLOAT_SUPERCLASSES, true), + /** The tag of the basic type `int'. + */ + INT(INT_CLASS, INT_SUPERCLASSES, true), /** The tag of the basic type `double'. */ - DOUBLE(DOUBLE_CLASS, DOUBLE_CLASS, TypeTagKind.PRIMITIVE | TypeTagKind.NUMERIC), - + DOUBLE(DOUBLE_CLASS, DOUBLE_CLASS, true), /** The tag of the basic type `boolean'. */ - BOOLEAN(TypeTagKind.PRIMITIVE), + BOOLEAN(0, 0, true), /** The tag of the type `void'. */ - VOID(TypeTagKind.VOID), + VOID, /** The tag of all class and interface types. */ - CLASS(TypeTagKind.REFERENCE), + CLASS, /** The tag of all array types. */ - ARRAY(TypeTagKind.REFERENCE), + ARRAY, /** The tag of all (monomorphic) method types. */ - METHOD(TypeTagKind.OTHER), + METHOD, /** The tag of all package "types". */ - PACKAGE(TypeTagKind.OTHER), + PACKAGE, /** The tag of all (source-level) type variables. */ - TYPEVAR(TypeTagKind.REFERENCE), + TYPEVAR, /** The tag of all type arguments. */ - WILDCARD(TypeTagKind.REFERENCE), + WILDCARD, /** The tag of all polymorphic (method-) types. */ - FORALL(TypeTagKind.OTHER), + FORALL, /** The tag of deferred expression types in method context */ - DEFERRED(TypeTagKind.OTHER), + DEFERRED, /** The tag of the bottom type {@code }. */ - BOT(TypeTagKind.OTHER), + BOT, /** The tag of a missing type. */ - NONE(TypeTagKind.OTHER), + NONE, /** The tag of the error type. */ - ERROR(TypeTagKind.REFERENCE | TypeTagKind.PARTIAL), + ERROR, /** The tag of an unknown type */ - UNKNOWN(TypeTagKind.PARTIAL), + UNKNOWN, /** The tag of all instantiatable type variables. */ - UNDETVAR(TypeTagKind.PARTIAL), + UNDETVAR, /** Pseudo-types, these are special tags */ - UNINITIALIZED_THIS(TypeTagKind.OTHER), + UNINITIALIZED_THIS, - UNINITIALIZED_OBJECT(TypeTagKind.OTHER); + UNINITIALIZED_OBJECT; - final boolean isPrimitive; - final boolean isNumeric; - final boolean isPartial; - final boolean isReference; - final boolean isPrimitiveOrVoid; final int superClasses; final int numericClass; + final boolean isPrimitive; - private TypeTag(int kind) { - this(0, 0, kind); + private TypeTag() { + this(0, 0, false); } - private TypeTag(int numericClass, int superClasses, int kind) { - isPrimitive = (kind & TypeTagKind.PRIMITIVE) != 0; - isNumeric = (kind & TypeTagKind.NUMERIC) != 0; - isPartial = (kind & TypeTagKind.PARTIAL) != 0; - isReference = (kind & TypeTagKind.REFERENCE) != 0; - isPrimitiveOrVoid = ((kind & TypeTagKind.PRIMITIVE) != 0) || - ((kind & TypeTagKind.VOID) != 0); - this.superClasses = superClasses; - this.numericClass = numericClass; - } - - static class TypeTagKind { - static final int PRIMITIVE = 1; - static final int NUMERIC = 2; - static final int REFERENCE = 4; - static final int PARTIAL = 8; - static final int OTHER = 16; - static final int VOID = 32; + private TypeTag(int numericClass, int superClasses, boolean isPrimitive) { + this.superClasses = superClasses; + this.numericClass = numericClass; + this.isPrimitive = isPrimitive; } public static class NumericClasses { @@ -261,4 +236,5 @@ public enum TypeTag { throw new AssertionError("unknown primitive type " + this); } } + } diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 331046e7b8c..8a3b4235714 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -286,8 +286,9 @@ public class Types { * conversion to s? */ public boolean isConvertible(Type t, Type s, Warner warn) { - if (t.tag == ERROR) + if (t.hasTag(ERROR)) { return true; + } boolean tPrimitive = t.isPrimitive(); boolean sPrimitive = s.isPrimitive(); if (tPrimitive == sPrimitive) { @@ -396,7 +397,8 @@ public class Types { /** * Compute the function descriptor associated with a given functional interface */ - public FunctionDescriptor findDescriptorInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError { + public FunctionDescriptor findDescriptorInternal(TypeSymbol origin, + CompoundScope membersCache) throws FunctionDescriptorLookupError { if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) { //t must be an interface throw failure("not.a.functional.intf", origin); @@ -655,17 +657,16 @@ public class Types { } } else if (isSubtype(t, s)) { return true; - } - else if (t.tag == TYPEVAR) { + } else if (t.hasTag(TYPEVAR)) { return isSubtypeUnchecked(t.getUpperBound(), s, warn); - } - else if (!s.isRaw()) { + } else if (!s.isRaw()) { Type t2 = asSuper(t, s.tsym); if (t2 != null && t2.isRaw()) { - if (isReifiable(s)) + if (isReifiable(s)) { warn.silentWarn(LintCategory.UNCHECKED); - else + } else { warn.warn(LintCategory.UNCHECKED); + } return true; } } @@ -673,13 +674,14 @@ public class Types { } private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) { - if (t.tag != ARRAY || isReifiable(t)) + if (!t.hasTag(ARRAY) || isReifiable(t)) { return; + } t = t.unannotatedType(); s = s.unannotatedType(); ArrayType from = (ArrayType)t; boolean shouldWarn = false; - switch (s.tag) { + switch (s.getTag()) { case ARRAY: ArrayType to = (ArrayType)s; shouldWarn = from.isVarargs() && @@ -735,8 +737,9 @@ public class Types { // where private TypeRelation isSubtype = new TypeRelation() { + @Override public Boolean visitType(Type t, Type s) { - switch (t.tag) { + switch (t.getTag()) { case BYTE: return (!s.hasTag(CHAR) && t.getTag().isSubRangeOf(s.getTag())); case CHAR: @@ -756,7 +759,7 @@ public class Types { case NONE: return false; default: - throw new AssertionError("isSubtype " + t.tag); + throw new AssertionError("isSubtype " + t.getTag()); } } @@ -826,14 +829,14 @@ public class Types { @Override public Boolean visitArrayType(ArrayType t, Type s) { - if (s.tag == ARRAY) { + if (s.hasTag(ARRAY)) { if (t.elemtype.isPrimitive()) return isSameType(t.elemtype, elemtype(s)); else return isSubtypeNoCapture(t.elemtype, elemtype(s)); } - if (s.tag == CLASS) { + if (s.hasTag(CLASS)) { Name sname = s.tsym.getQualifiedName(); return sname == names.java_lang_Object || sname == names.java_lang_Cloneable @@ -846,9 +849,9 @@ public class Types { @Override public Boolean visitUndetVar(UndetVar t, Type s) { //todo: test against origin needed? or replace with substitution? - if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN) { + if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) { return true; - } else if (s.tag == BOT) { + } else if (s.hasTag(BOT)) { //if 's' is 'null' there's no instantiated type U for which //U <: s (but 'null' itself, which is not a valid type) return false; @@ -913,15 +916,17 @@ public class Types { * Is t a supertype of s? */ public boolean isSuperType(Type t, Type s) { - switch (t.tag) { + switch (t.getTag()) { case ERROR: return true; case UNDETVAR: { UndetVar undet = (UndetVar)t; if (t == s || undet.qtype == s || - s.tag == ERROR || - s.tag == BOT) return true; + s.hasTag(ERROR) || + s.hasTag(BOT)) { + return true; + } undet.addBound(InferenceBound.LOWER, s, this); return true; } @@ -990,12 +995,12 @@ public class Types { if (s.isPartial()) return visit(s, t); - switch (t.tag) { + 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.tag == s.tag; + return t.hasTag(s.getTag()); case TYPEVAR: { - if (s.tag == TYPEVAR) { + if (s.hasTag(TYPEVAR)) { //type-substitution does not preserve type-var types //check that type var symbols and bounds are indeed the same return sameTypeVars((TypeVar)t.unannotatedType(), (TypeVar)s.unannotatedType()); @@ -1009,7 +1014,7 @@ public class Types { } } default: - throw new AssertionError("isSameType " + t.tag); + throw new AssertionError("isSameType " + t.getTag()); } } @@ -1080,8 +1085,9 @@ public class Types { @Override public Boolean visitForAll(ForAll t, Type s) { - if (s.tag != FORALL) + if (!s.hasTag(FORALL)) { return false; + } ForAll forAll = (ForAll)s; return hasSameBounds(t, forAll) @@ -1090,12 +1096,14 @@ public class Types { @Override public Boolean visitUndetVar(UndetVar t, Type s) { - if (s.tag == WILDCARD) + if (s.hasTag(WILDCARD)) { // FIXME, this might be leftovers from before capture conversion return false; + } - if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN) + if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) { return true; + } t.addBound(InferenceBound.EQ, s, Types.this); @@ -1171,9 +1179,9 @@ public class Types { // public boolean containedBy(Type t, Type s) { - switch (t.tag) { + switch (t.getTag()) { case UNDETVAR: - if (s.tag == WILDCARD) { + if (s.hasTag(WILDCARD)) { UndetVar undetvar = (UndetVar)t; WildcardType wt = (WildcardType)s.unannotatedType(); switch(wt.kind) { @@ -1241,7 +1249,7 @@ public class Types { private TypeRelation containsType = new TypeRelation() { private Type U(Type t) { - while (t.tag == WILDCARD) { + while (t.hasTag(WILDCARD)) { WildcardType w = (WildcardType)t.unannotatedType(); if (w.isSuperBound()) return w.bound == null ? syms.objectType : w.bound.bound; @@ -1252,7 +1260,7 @@ public class Types { } private Type L(Type t) { - while (t.tag == WILDCARD) { + while (t.hasTag(WILDCARD)) { WildcardType w = (WildcardType)t.unannotatedType(); if (w.isExtendsBound()) return syms.botType; @@ -1298,10 +1306,11 @@ public class Types { @Override public Boolean visitUndetVar(UndetVar t, Type s) { - if (s.tag != WILDCARD) + if (!s.hasTag(WILDCARD)) { return isSameType(t, s); - else + } else { return false; + } } @Override @@ -1311,13 +1320,13 @@ public class Types { }; public boolean isCaptureOf(Type s, WildcardType t) { - if (s.tag != TYPEVAR || !((TypeVar)s.unannotatedType()).isCaptured()) + if (!s.hasTag(TYPEVAR) || !((TypeVar)s.unannotatedType()).isCaptured()) return false; return isSameWildcard(t, ((CapturedType)s.unannotatedType()).wildcard); } public boolean isSameWildcard(WildcardType t, Type s) { - if (s.tag != WILDCARD) + if (!s.hasTag(WILDCARD)) return false; WildcardType w = (WildcardType)s.unannotatedType(); return w.kind == t.kind && w.type == t.type; @@ -1333,6 +1342,26 @@ public class Types { } // + /** + * Can t and s be compared for equality? Any primitive == + * primitive or primitive == object comparisons here are an error. + * Unboxing and correct primitive == primitive comparisons are + * already dealt with in Attr.visitBinary. + * + */ + public boolean isEqualityComparable(Type s, Type t, Warner warn) { + if (t.isNumeric() && s.isNumeric()) + return true; + + boolean tPrimitive = t.isPrimitive(); + boolean sPrimitive = s.isPrimitive(); + if (!tPrimitive && !sPrimitive) { + return isCastable(s, t, warn) || isCastable(t, s, warn); + } else { + return false; + } + } + // public boolean isCastable(Type t, Type s) { return isCastable(t, s, noWarnings); @@ -1369,15 +1398,15 @@ public class Types { private TypeRelation isCastable = new TypeRelation() { public Boolean visitType(Type t, Type s) { - if (s.tag == ERROR) + if (s.hasTag(ERROR)) return true; - switch (t.tag) { + switch (t.getTag()) { case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: case DOUBLE: return s.isNumeric(); case BOOLEAN: - return s.tag == BOOLEAN; + return s.hasTag(BOOLEAN); case VOID: return false; case BOT: @@ -1394,10 +1423,10 @@ public class Types { @Override public Boolean visitClassType(ClassType t, Type s) { - if (s.tag == ERROR || s.tag == BOT) + if (s.hasTag(ERROR) || s.hasTag(BOT)) return true; - if (s.tag == TYPEVAR) { + if (s.hasTag(TYPEVAR)) { if (isCastable(t, s.getUpperBound(), noWarnings)) { warnStack.head.warn(LintCategory.UNCHECKED); return true; @@ -1412,11 +1441,11 @@ public class Types { visitIntersectionType((IntersectionClassType)t.unannotatedType(), s, false); } - if (s.tag == CLASS || s.tag == ARRAY) { + if (s.hasTag(CLASS) || s.hasTag(ARRAY)) { boolean upcast; if ((upcast = isSubtype(erasure(t), erasure(s))) || isSubtype(erasure(s), erasure(t))) { - if (!upcast && s.tag == ARRAY) { + if (!upcast && s.hasTag(ARRAY)) { if (!isReifiable(s)) warnStack.head.warn(LintCategory.UNCHECKED); return true; @@ -1469,7 +1498,7 @@ public class Types { } // Sidecast - if (s.tag == CLASS) { + if (s.hasTag(CLASS)) { if ((s.tsym.flags() & INTERFACE) != 0) { return ((t.tsym.flags() & FINAL) == 0) ? sideCast(t, s, warnStack.head) @@ -1501,7 +1530,7 @@ public class Types { @Override public Boolean visitArrayType(ArrayType t, Type s) { - switch (s.tag) { + switch (s.getTag()) { case ERROR: case BOT: return true; @@ -1516,7 +1545,7 @@ public class Types { return isSubtype(t, s); case ARRAY: if (elemtype(t).isPrimitive() || elemtype(s).isPrimitive()) { - return elemtype(t).tag == elemtype(s).tag; + return elemtype(t).hasTag(elemtype(s).getTag()); } else { return visit(elemtype(t), elemtype(s)); } @@ -1527,7 +1556,7 @@ public class Types { @Override public Boolean visitTypeVar(TypeVar t, Type s) { - switch (s.tag) { + switch (s.getTag()) { case ERROR: case BOT: return true; @@ -1579,8 +1608,9 @@ public class Types { private Set cache = new HashSet(); + @Override public Boolean visitType(Type t, Type s) { - if (s.tag == WILDCARD) + if (s.hasTag(WILDCARD)) return visit(s, t); else return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t); @@ -1617,10 +1647,10 @@ public class Types { if (t.isUnbound()) return false; - if (s.tag != WILDCARD) { + if (!s.hasTag(WILDCARD)) { if (t.isExtendsBound()) return notSoftSubtypeRecursive(s, t.type); - else // isSuperBound() + else return notSoftSubtypeRecursive(t.type, s); } @@ -1669,21 +1699,21 @@ public class Types { */ public boolean notSoftSubtype(Type t, Type s) { if (t == s) return false; - if (t.tag == TYPEVAR) { + if (t.hasTag(TYPEVAR)) { TypeVar tv = (TypeVar) t; return !isCastable(tv.bound, relaxBound(s), noWarnings); } - if (s.tag != WILDCARD) + if (!s.hasTag(WILDCARD)) s = upperBound(s); return !isSubtype(t, relaxBound(s)); } private Type relaxBound(Type t) { - if (t.tag == TYPEVAR) { - while (t.tag == TYPEVAR) + if (t.hasTag(TYPEVAR)) { + while (t.hasTag(TYPEVAR)) t = t.getUpperBound(); t = rewriteQuantifiers(t, true, true); } @@ -1732,16 +1762,16 @@ public class Types { // public boolean isArray(Type t) { - while (t.tag == WILDCARD) + while (t.hasTag(WILDCARD)) t = upperBound(t); - return t.tag == ARRAY; + return t.hasTag(ARRAY); } /** * The element type of an array. */ public Type elemtype(Type t) { - switch (t.tag) { + switch (t.getTag()) { case WILDCARD: return elemtype(upperBound(t)); case ARRAY: @@ -1775,7 +1805,7 @@ public class Types { */ public int dimensions(Type t) { int result = 0; - while (t.tag == ARRAY) { + while (t.hasTag(ARRAY)) { result++; t = elemtype(t); } @@ -1789,8 +1819,7 @@ public class Types { * @return the ArrayType for the given component */ public ArrayType makeArrayType(Type t) { - if (t.tag == VOID || - t.tag == PACKAGE) { + if (t.hasTag(VOID) || t.hasTag(PACKAGE)) { Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString()); } return new ArrayType(t, syms.arrayClass); @@ -1821,7 +1850,7 @@ public class Types { return t; Type st = supertype(t); - if (st.tag == CLASS || st.tag == TYPEVAR || st.tag == ERROR) { + if (st.hasTag(CLASS) || st.hasTag(TYPEVAR) || st.hasTag(ERROR)) { Type x = asSuper(st, sym); if (x != null) return x; @@ -1863,13 +1892,13 @@ public class Types { * @param sym a symbol */ public Type asOuterSuper(Type t, Symbol sym) { - switch (t.tag) { + switch (t.getTag()) { case CLASS: do { Type s = asSuper(t, sym); if (s != null) return s; t = t.getEnclosingType(); - } while (t.tag == CLASS); + } while (t.hasTag(CLASS)); return null; case ARRAY: return isSubtype(t, sym.type) ? sym.type : null; @@ -1890,16 +1919,16 @@ public class Types { * @param sym a symbol */ public Type asEnclosingSuper(Type t, Symbol sym) { - switch (t.tag) { + switch (t.getTag()) { case CLASS: do { Type s = asSuper(t, sym); if (s != null) return s; Type outer = t.getEnclosingType(); - t = (outer.tag == CLASS) ? outer : + t = (outer.hasTag(CLASS)) ? outer : (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type : Type.noType; - } while (t.tag == CLASS); + } while (t.hasTag(CLASS)); return null; case ARRAY: return isSubtype(t, sym.type) ? sym.type : null; @@ -1987,11 +2016,11 @@ public class Types { * (not defined for Method and ForAll types) */ public boolean isAssignable(Type t, Type s, Warner warn) { - if (t.tag == ERROR) + if (t.hasTag(ERROR)) return true; - if (t.tag.isSubRangeOf(INT) && t.constValue() != null) { + if (t.getTag().isSubRangeOf(INT) && t.constValue() != null) { int value = ((Number)t.constValue()).intValue(); - switch (s.tag) { + switch (s.getTag()) { case BYTE: if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE) return true; @@ -2007,7 +2036,7 @@ public class Types { case INT: return true; case CLASS: - switch (unboxedType(s).tag) { + switch (unboxedType(s).getTag()) { case BYTE: case CHAR: case SHORT: @@ -2135,7 +2164,7 @@ public class Types { null, syms.noSymbol); bc.type = new IntersectionClassType(bounds, bc, allInterfaces); - bc.erasure_field = (bounds.head.tag == TYPEVAR) ? + bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ? syms.objectType : // error condition, recover erasure(firstExplicitBound); bc.members_field = new Scope(bc); @@ -2198,7 +2227,7 @@ public class Types { */ @Override public Type visitTypeVar(TypeVar t, Void ignored) { - if (t.bound.tag == TYPEVAR || + if (t.bound.hasTag(TYPEVAR) || (!t.bound.isCompound() && !t.bound.isInterface())) { return t.bound; } else { @@ -2502,8 +2531,8 @@ public class Types { } private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter implFilter) { - for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = supertype(t)) { - while (t.tag == TYPEVAR) + for (Type t = origin.type; t.hasTag(CLASS) || t.hasTag(TYPEVAR); t = supertype(t)) { + while (t.hasTag(TYPEVAR)) t = t.getUpperBound(); TypeSymbol c = t.tsym; for (Scope.Entry e = c.members().lookup(ms.name, implFilter); @@ -2684,13 +2713,13 @@ public class Types { @Override public Boolean visitMethodType(MethodType t, Type s) { - return s.tag == METHOD + return s.hasTag(METHOD) && containsTypeEquivalent(t.argtypes, s.getParameterTypes()); } @Override public Boolean visitForAll(ForAll t, Type s) { - if (s.tag != FORALL) + if (!s.hasTag(FORALL)) return strict ? false : visitMethodType(t.asMethodType(), s); ForAll forAll = (ForAll)s; @@ -3025,7 +3054,7 @@ public class Types { */ public int rank(Type t) { t = t.unannotatedType(); - switch(t.tag) { + switch(t.getTag()) { case CLASS: { ClassType cls = (ClassType)t; if (cls.rank_field < 0) { @@ -3091,7 +3120,7 @@ public class Types { */ @Deprecated public String toString(Type t) { - if (t.tag == FORALL) { + if (t.hasTag(FORALL)) { ForAll forAll = (ForAll)t; return typaramsString(forAll.tvars) + forAll.qtype; } @@ -3157,9 +3186,9 @@ public class Types { if (cl == null) { Type st = supertype(t); if (!t.isCompound()) { - if (st.tag == CLASS) { + if (st.hasTag(CLASS)) { cl = insert(closure(st), t); - } else if (st.tag == TYPEVAR) { + } else if (st.hasTag(TYPEVAR)) { cl = closure(st).prepend(t); } else { cl = List.of(t); @@ -3219,7 +3248,7 @@ public class Types { if (isSameType(cl1.head, cl2.head)) return intersect(cl1.tail, cl2.tail).prepend(cl1.head); if (cl1.head.tsym == cl2.head.tsym && - cl1.head.tag == CLASS && cl2.head.tag == CLASS) { + cl1.head.hasTag(CLASS) && cl2.head.hasTag(CLASS)) { if (cl1.head.isParameterized() && cl2.head.isParameterized()) { Type merge = merge(cl1.head,cl2.head); return intersect(cl1.tail, cl2.tail).prepend(merge); @@ -3343,7 +3372,7 @@ public class Types { final int CLASS_BOUND = 2; int boundkind = 0; for (Type t : ts) { - switch (t.tag) { + switch (t.getTag()) { case CLASS: boundkind |= CLASS_BOUND; break; @@ -3353,8 +3382,8 @@ public class Types { case TYPEVAR: do { t = t.getUpperBound(); - } while (t.tag == TYPEVAR); - if (t.tag == ARRAY) { + } while (t.hasTag(TYPEVAR)); + if (t.hasTag(ARRAY)) { boundkind |= ARRAY_BOUND; } else { boundkind |= CLASS_BOUND; @@ -3394,13 +3423,14 @@ public class Types { case CLASS_BOUND: // calculate lub(A, B) - while (ts.head.tag != CLASS && ts.head.tag != TYPEVAR) + while (!ts.head.hasTag(CLASS) && !ts.head.hasTag(TYPEVAR)) { ts = ts.tail; + } Assert.check(!ts.isEmpty()); //step 1 - compute erased candidate set (EC) List cl = erasedSupertypes(ts.head); for (Type t : ts.tail) { - if (t.tag == CLASS || t.tag == TYPEVAR) + if (t.hasTag(CLASS) || t.hasTag(TYPEVAR)) cl = intersect(cl, erasedSupertypes(t)); } //step 2 - compute minimal erased candidate set (MEC) @@ -3422,7 +3452,7 @@ public class Types { // calculate lub(A, B[]) List classes = List.of(arraySuperType()); for (Type t : ts) { - if (t.tag != ARRAY) // Filter out any arrays + if (!t.hasTag(ARRAY)) // Filter out any arrays classes = classes.prepend(t); } // lub(A, B[]) is lub(A, arraySuperType) @@ -3433,7 +3463,7 @@ public class Types { List erasedSupertypes(Type t) { ListBuffer buf = lb(); for (Type sup : closure(t)) { - if (sup.tag == TYPEVAR) { + if (sup.hasTag(TYPEVAR)) { buf.append(sup); } else { buf.append(erasure(sup)); @@ -3509,7 +3539,7 @@ public class Types { private static final UnaryVisitor hashCode = new UnaryVisitor() { public Integer visitType(Type t, Void ignored) { - return t.tag.ordinal(); + return t.getTag().ordinal(); } @Override @@ -3635,7 +3665,7 @@ public class Types { * Return the class that boxes the given primitive. */ public ClassSymbol boxedClass(Type t) { - return reader.enterClass(syms.boxedName[t.tag.ordinal()]); + return reader.enterClass(syms.boxedName[t.getTag().ordinal()]); } /** @@ -3667,7 +3697,7 @@ public class Types { */ public Type unboxedTypeOrType(Type t) { Type unboxedType = unboxedType(t); - return unboxedType.tag == NONE ? t : unboxedType; + return unboxedType.hasTag(NONE) ? t : unboxedType; } // @@ -3717,7 +3747,7 @@ public class Types { return buf.reverse(); } public Type capture(Type t) { - if (t.tag != CLASS) + if (!t.hasTag(CLASS)) return t; if (t.getEnclosingType() != Type.noType) { Type capturedEncl = capture(t.getEnclosingType()); @@ -3783,7 +3813,7 @@ public class Types { public List freshTypeVariables(List types) { ListBuffer result = lb(); for (Type t : types) { - if (t.tag == WILDCARD) { + if (t.hasTag(WILDCARD)) { t = t.unannotatedType(); Type bound = ((WildcardType)t).getExtendsBound(); if (bound == null) @@ -3953,14 +3983,14 @@ public class Types { @Override public Void visitClassType(ClassType source, Type target) throws AdaptFailure { - if (target.tag == CLASS) + if (target.hasTag(CLASS)) adaptRecursive(source.allparams(), target.allparams()); return null; } @Override public Void visitArrayType(ArrayType source, Type target) throws AdaptFailure { - if (target.tag == ARRAY) + if (target.hasTag(ARRAY)) adaptRecursive(elemtype(source), elemtype(target)); return null; } @@ -4142,7 +4172,7 @@ public class Types { } Type B(Type t) { - while (t.tag == WILDCARD) { + while (t.hasTag(WILDCARD)) { WildcardType w = (WildcardType)t.unannotatedType(); t = high ? w.getExtendsBound() : @@ -4187,7 +4217,7 @@ public class Types { * substituted by the wildcard */ private WildcardType makeSuperWildcard(Type bound, TypeVar formal) { - if (bound.tag == BOT) { + if (bound.hasTag(BOT)) { return new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index e24a69a4d99..1be8604319f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -134,6 +134,7 @@ public class Attr extends JCTree.Visitor { allowAnonOuterThis = source.allowAnonOuterThis(); allowStringsInSwitch = source.allowStringsInSwitch(); allowPoly = source.allowPoly(); + allowTypeAnnos = source.allowTypeAnnotations(); allowLambda = source.allowLambda(); allowDefaultMethods = source.allowDefaultMethods(); sourceName = source.name; @@ -147,6 +148,7 @@ public class Attr extends JCTree.Visitor { statInfo = new ResultInfo(NIL, Type.noType); varInfo = new ResultInfo(VAR, Type.noType); unknownExprInfo = new ResultInfo(VAL, Type.noType); + unknownAnyPolyInfo = new ResultInfo(VAL, Infer.anyPoly); unknownTypeInfo = new ResultInfo(TYP, Type.noType); unknownTypeExprInfo = new ResultInfo(Kinds.TYP | Kinds.VAL, Type.noType); recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext); @@ -160,6 +162,10 @@ public class Attr extends JCTree.Visitor { */ boolean allowPoly; + /** Switch: support type annotations. + */ + boolean allowTypeAnnos; + /** Switch: support generics? */ boolean allowGenerics; @@ -240,7 +246,7 @@ public class Attr extends JCTree.Visitor { InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext(); Type owntype = found; if (!owntype.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) { - if (inferenceContext.free(found)) { + if (allowPoly && inferenceContext.free(found)) { inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() { @Override public void typesInferred(InferenceContext inferenceContext) { @@ -558,6 +564,7 @@ public class Attr extends JCTree.Visitor { final ResultInfo statInfo; final ResultInfo varInfo; + final ResultInfo unknownAnyPolyInfo; final ResultInfo unknownExprInfo; final ResultInfo unknownTypeInfo; final ResultInfo unknownTypeExprInfo; @@ -664,17 +671,21 @@ public class Attr extends JCTree.Visitor { attribStat(l.head, env); } - /** Attribute the arguments in a method call, returning a list of types. + /** Attribute the arguments in a method call, returning the method kind. */ - List attribArgs(List trees, Env env) { - ListBuffer argtypes = new ListBuffer(); + int attribArgs(List trees, Env env, ListBuffer argtypes) { + int kind = VAL; for (JCExpression arg : trees) { - Type argtype = allowPoly && deferredAttr.isDeferred(env, arg) ? - deferredAttr.new DeferredType(arg, env) : - chk.checkNonVoid(arg, attribExpr(arg, env, Infer.anyPoly)); + Type argtype; + if (allowPoly && deferredAttr.isDeferred(env, arg)) { + argtype = deferredAttr.new DeferredType(arg, env); + kind |= POLY; + } else { + argtype = chk.checkNonVoid(arg, attribTree(arg, env, unknownAnyPolyInfo)); + } argtypes.append(argtype); } - return argtypes.toList(); + return kind; } /** Attribute a type argument list, returning a list of types. @@ -745,25 +756,15 @@ public class Attr extends JCTree.Visitor { JCTree.JCExpression initializer, Type type) { - // in case no lint value has been set up for this env, scan up - // env stack looking for smallest enclosing env for which it is set. - Env lintEnv = env; - while (lintEnv.info.lint == null) - lintEnv = lintEnv.next; + /* When this env was created, it didn't have the correct lint nor had + * annotations has been processed. + * But now at this phase we have already processed annotations and the + * correct lint must have been set in chk, so we should use that one to + * attribute the initializer. + */ + Lint prevLint = env.info.lint; + env.info.lint = chk.getLint(); - // Having found the enclosing lint value, we can initialize the lint value for this class - // ... but ... - // There's a problem with evaluating annotations in the right order, such that - // env.info.enclVar.attributes_field might not yet have been evaluated, and so might be - // null. In that case, calling augment will throw an NPE. To avoid this, for now we - // revert to the jdk 6 behavior and ignore the (unevaluated) attributes. - if (env.info.enclVar.annotationsPendingCompletion()) { - env.info.lint = lintEnv.info.lint; - } else { - env.info.lint = lintEnv.info.lint.augment(env.info.enclVar); - } - - Lint prevLint = chk.setLint(env.info.lint); JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile); try { @@ -775,10 +776,11 @@ public class Attr extends JCTree.Visitor { memberEnter.typeAnnotate(initializer, env, null); annotate.flush(); Type itype = attribExpr(initializer, env, type); - if (itype.constValue() != null) + if (itype.constValue() != null) { return coerce(itype, type).constValue(); - else + } else { return null; + } } finally { env.info.lint = prevLint; log.useSource(prevSource); @@ -1739,6 +1741,7 @@ public class Attr extends JCTree.Visitor { boolean isConstructorCall = methName == names._this || methName == names._super; + ListBuffer argtypesBuf = ListBuffer.lb(); if (isConstructorCall) { // We are seeing a ...this(...) or ...super(...) call. // Check that this is the first statement in a constructor. @@ -1749,7 +1752,8 @@ public class Attr extends JCTree.Visitor { localEnv.info.isSelfCall = true; // Attribute arguments, yielding list of argument types. - argtypes = attribArgs(tree.args, localEnv); + attribArgs(tree.args, localEnv, argtypesBuf); + argtypes = argtypesBuf.toList(); typeargtypes = attribTypes(tree.typeargs, localEnv); // Variable `site' points to the class in which the called @@ -1821,7 +1825,8 @@ public class Attr extends JCTree.Visitor { } else { // Otherwise, we are seeing a regular method call. // Attribute the arguments, yielding list of argument types, ... - argtypes = attribArgs(tree.args, localEnv); + int kind = attribArgs(tree.args, localEnv, argtypesBuf); + argtypes = argtypesBuf.toList(); typeargtypes = attribAnyTypes(tree.typeargs, localEnv); // ... and attribute the method using as a prototype a methodtype @@ -1829,7 +1834,7 @@ public class Attr extends JCTree.Visitor { // arguments (this will also set the method symbol). Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes); localEnv.info.pendingResolutionPhase = null; - Type mtype = attribTree(tree.meth, localEnv, new ResultInfo(VAL, mpt, resultInfo.checkContext)); + Type mtype = attribTree(tree.meth, localEnv, new ResultInfo(kind, mpt, resultInfo.checkContext)); // Compute the result type. Type restype = mtype.getReturnType(); @@ -1999,7 +2004,9 @@ public class Attr extends JCTree.Visitor { } // Attribute constructor arguments. - List argtypes = attribArgs(tree.args, localEnv); + ListBuffer argtypesBuf = ListBuffer.lb(); + int pkind = attribArgs(tree.args, localEnv, argtypesBuf); + List argtypes = argtypesBuf.toList(); List typeargtypes = attribTypes(tree.typeargs, localEnv); // If we have made no mistakes in the class type... @@ -2086,11 +2093,16 @@ public class Attr extends JCTree.Visitor { clazztype, tree.constructor, rsEnv, - new ResultInfo(MTH, newMethodTemplate(syms.voidType, argtypes, typeargtypes))); + new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes))); if (rsEnv.info.lastResolveVarargs()) Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null); } - findDiamondIfNeeded(localEnv, tree, clazztype); + if (cdef == null && + !clazztype.isErroneous() && + clazztype.getTypeArguments().nonEmpty() && + findDiamonds) { + findDiamond(localEnv, tree, clazztype); + } } if (cdef != null) { @@ -2157,7 +2169,7 @@ public class Attr extends JCTree.Visitor { clazztype, tree.constructor, localEnv, - new ResultInfo(VAL, newMethodTemplate(syms.voidType, argtypes, typeargtypes))); + new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes))); } else { if (tree.clazz.hasTag(ANNOTATED_TYPE)) { checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations, @@ -2172,32 +2184,27 @@ public class Attr extends JCTree.Visitor { chk.validate(tree.typeargs, localEnv); } //where - void findDiamondIfNeeded(Env env, JCNewClass tree, Type clazztype) { - if (tree.def == null && - !clazztype.isErroneous() && - clazztype.getTypeArguments().nonEmpty() && - findDiamonds) { - JCTypeApply ta = (JCTypeApply)tree.clazz; - List prevTypeargs = ta.arguments; - try { - //create a 'fake' diamond AST node by removing type-argument trees - ta.arguments = List.nil(); - ResultInfo findDiamondResult = new ResultInfo(VAL, - resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt()); - Type inferred = deferredAttr.attribSpeculative(tree, env, findDiamondResult).type; - Type polyPt = allowPoly ? - syms.objectType : - clazztype; - if (!inferred.isErroneous() && - types.isAssignable(inferred, pt().hasTag(NONE) ? polyPt : pt(), types.noWarnings)) { - String key = types.isSameType(clazztype, inferred) ? - "diamond.redundant.args" : - "diamond.redundant.args.1"; - log.warning(tree.clazz.pos(), key, clazztype, inferred); - } - } finally { - ta.arguments = prevTypeargs; + void findDiamond(Env env, JCNewClass tree, Type clazztype) { + JCTypeApply ta = (JCTypeApply)tree.clazz; + List prevTypeargs = ta.arguments; + try { + //create a 'fake' diamond AST node by removing type-argument trees + ta.arguments = List.nil(); + ResultInfo findDiamondResult = new ResultInfo(VAL, + resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt()); + Type inferred = deferredAttr.attribSpeculative(tree, env, findDiamondResult).type; + Type polyPt = allowPoly ? + syms.objectType : + clazztype; + if (!inferred.isErroneous() && + types.isAssignable(inferred, pt().hasTag(NONE) ? polyPt : pt(), types.noWarnings)) { + String key = types.isSameType(clazztype, inferred) ? + "diamond.redundant.args" : + "diamond.redundant.args.1"; + log.warning(tree.clazz.pos(), key, clazztype, inferred); } + } finally { + ta.arguments = prevTypeargs; } } @@ -3003,6 +3010,8 @@ public class Attr extends JCTree.Visitor { !left.isErroneous() && !right.isErroneous()) { owntype = operator.type.getReturnType(); + // This will figure out when unboxing can happen and + // choose the right comparison operator. int opc = chk.checkOperator(tree.lhs.pos(), (OperatorSymbol)operator, tree.getTag(), @@ -3030,9 +3039,11 @@ public class Attr extends JCTree.Visitor { } // Check that argument types of a reference ==, != are - // castable to each other, (JLS???). + // castable to each other, (JLS 15.21). Note: unboxing + // comparisons will not have an acmp* opc at this point. if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) { - if (!types.isCastable(left, right, new Warner(tree.pos()))) { + if (!types.isEqualityComparable(left, right, + new Warner(tree.pos()))) { log.error(tree.pos(), "incomparable.types", left, right); } } @@ -3051,7 +3062,7 @@ public class Attr extends JCTree.Visitor { //should we propagate the target type? final ResultInfo castInfo; JCExpression expr = TreeInfo.skipParens(tree.expr); - boolean isPoly = expr.hasTag(LAMBDA) || expr.hasTag(REFERENCE); + boolean isPoly = allowPoly && (expr.hasTag(LAMBDA) || expr.hasTag(REFERENCE)); if (isPoly) { //expression is a poly - we need to propagate target type info castInfo = new ResultInfo(VAL, clazztype, new Check.NestedCheckContext(resultInfo.checkContext) { @@ -3190,7 +3201,7 @@ public class Attr extends JCTree.Visitor { if (skind == TYP) { Type elt = site; while (elt.hasTag(ARRAY)) - elt = ((ArrayType)elt).elemtype; + elt = ((ArrayType)elt.unannotatedType()).elemtype; if (elt.hasTag(TYPEVAR)) { log.error(tree.pos(), "type.var.cant.be.deref"); result = types.createErrorType(tree.type); @@ -3440,10 +3451,14 @@ public class Attr extends JCTree.Visitor { Symbol sym, Env 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; + if ((resultInfo.pkind & POLY) != 0) { + 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; + } else { + return checkIdInternal(tree, site, sym, resultInfo.pt, env, resultInfo); + } } Type checkIdInternal(JCTree tree, @@ -3541,7 +3556,7 @@ public class Attr extends JCTree.Visitor { break; case MTH: { owntype = checkMethod(site, sym, - new ResultInfo(VAL, resultInfo.pt.getReturnType(), resultInfo.checkContext), + new ResultInfo(resultInfo.pkind, resultInfo.pt.getReturnType(), resultInfo.checkContext), env, TreeInfo.args(env.tree), resultInfo.pt.getParameterTypes(), resultInfo.pt.getTypeArguments()); break; @@ -4289,12 +4304,13 @@ public class Attr extends JCTree.Visitor { (c.flags() & ABSTRACT) == 0) { checkSerialVersionUID(tree, c); } + if (allowTypeAnnos) { + // Correctly organize the postions of the type annotations + TypeAnnotations.organizeTypeAnnotationsBodies(this.syms, this.names, this.log, tree); - // Correctly organize the postions of the type annotations - TypeAnnotations.organizeTypeAnnotationsBodies(this.syms, this.names, this.log, tree); - - // Check type annotations applicability rules - validateTypeAnnotations(tree); + // Check type annotations applicability rules + validateTypeAnnotations(tree); + } } // where /** get a diagnostic position for an attribute of Type t, or null if attribute missing */ diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 65bb3177926..76440d0b7d1 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -218,6 +218,14 @@ public class Check { return prev; } + /* This idiom should be used only in cases when it is needed to set the lint + * of an environment that has been created in a phase previous to annotations + * processing. + */ + Lint getLint() { + return lint; + } + DeferredLintHandler setDeferredLintHandler(DeferredLintHandler newDeferredLintHandler) { DeferredLintHandler prev = deferredLintHandler; deferredLintHandler = newDeferredLintHandler; diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index 0dd6fe3887a..27b0c606fc2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -115,12 +115,17 @@ public class DeferredAttr extends JCTree.Visitor { SpeculativeCache speculativeCache; DeferredType(JCExpression tree, Env env) { - super(DEFERRED, null); + super(null); this.tree = tree; this.env = env.dup(tree, env.info.dup()); this.speculativeCache = new SpeculativeCache(); } + @Override + public TypeTag getTag() { + return DEFERRED; + } + /** * A speculative cache is used to keep track of all overload resolution rounds * that triggered speculative attribution on a given deferred type. Each entry @@ -959,10 +964,8 @@ public class DeferredAttr extends JCTree.Visitor { if (sym.kind == Kinds.AMBIGUOUS) { Resolve.AmbiguityError err = (Resolve.AmbiguityError)sym.baseSymbol(); result = ArgumentExpressionKind.PRIMITIVE; - for (List ambigousSyms = err.ambiguousSyms ; - ambigousSyms.nonEmpty() && !result.isPoly() ; - ambigousSyms = ambigousSyms.tail) { - Symbol s = ambigousSyms.head; + for (Symbol s : err.ambiguousSyms) { + if (result.isPoly()) break; if (s.kind == Kinds.MTH) { result = reduce(ArgumentExpressionKind.methodKind(s, types)); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java index d1280935955..df66e345703 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java @@ -1945,10 +1945,17 @@ public class Flow { } } + /* The analysis of each catch should be independent. + * Each one should have the same initial values of inits and + * uninits. + */ + final Bits initsCatchPrev = new Bits(initsTry); + final Bits uninitsCatchPrev = new Bits(uninitsTry); + for (List l = tree.catchers; l.nonEmpty(); l = l.tail) { JCVariableDecl param = l.head.param; - inits.assign(initsTry); - uninits.assign(uninitsTry); + inits.assign(initsCatchPrev); + uninits.assign(uninitsCatchPrev); scan(param); inits.incl(param.sym.adr); uninits.excl(param.sym.adr); diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java index 5ae41d600f2..c5f4b271f2e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -96,7 +96,7 @@ public class Infer { } /** A value for prototypes that admit any type, including polymorphic ones. */ - public static final Type anyPoly = new Type(NONE, null); + public static final Type anyPoly = new JCNoType(); /** * This exception class is design to store a list of diagnostics corresponding diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index b3961a82939..9b3457c7c83 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -109,15 +109,20 @@ public class MemberEnter extends JCTree.Visitor implements Completer { source = Source.instance(context); target = Target.instance(context); deferredLintHandler = DeferredLintHandler.instance(context); + allowTypeAnnos = source.allowTypeAnnotations(); } + /** Switch: support type annotations. + */ + boolean allowTypeAnnos; + /** A queue for classes whose members still need to be entered into the * symbol table. */ ListBuffer> halfcompleted = new ListBuffer>(); /** Set to true only when the first of a set of classes is - * processed from the halfcompleted queue. + * processed from the half completed queue. */ boolean isFirst = true; @@ -1072,7 +1077,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer { isFirst = true; } } - TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree, annotate); + if (allowTypeAnnos) { + TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree, annotate); + } } /* @@ -1117,7 +1124,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer { } public void typeAnnotate(final JCTree tree, final Env env, final Symbol sym) { - tree.accept(new TypeAnnotate(env, sym)); + if (allowTypeAnnos) { + tree.accept(new TypeAnnotate(env, sym)); + } } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java index 42739986e90..14f9d4bd2b6 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -1573,7 +1573,6 @@ public class Resolve { allowBoxing, useVarargs, operator); - reportVerboseResolutionDiagnostic(env.tree.pos(), name, site, argtypes, typeargtypes, bestSoFar); return bestSoFar; } // where @@ -2224,7 +2223,7 @@ public class Resolve { return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck, new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) { @Override - Symbol lookup(Env env, MethodResolutionPhase phase) { + Symbol doLookup(Env env, MethodResolutionPhase phase) { return findFun(env, name, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()); @@ -2256,7 +2255,7 @@ public class Resolve { List typeargtypes) { return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) { @Override - Symbol lookup(Env env, MethodResolutionPhase phase) { + Symbol doLookup(Env env, MethodResolutionPhase phase) { return findMethod(env, site, name, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired(), false); @@ -2355,7 +2354,7 @@ public class Resolve { List typeargtypes) { return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) { @Override - Symbol lookup(Env env, MethodResolutionPhase phase) { + Symbol doLookup(Env env, MethodResolutionPhase phase) { return findConstructor(pos, env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()); @@ -2413,7 +2412,7 @@ public class Resolve { return lookupMethod(env, pos, site.tsym, resolveMethodCheck, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) { @Override - Symbol lookup(Env env, MethodResolutionPhase phase) { + Symbol doLookup(Env env, MethodResolutionPhase phase) { return findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()); @@ -2503,7 +2502,7 @@ public class Resolve { return lookupMethod(env, pos, syms.predefClass, currentResolutionContext, new BasicLookupHelper(name, syms.predefClass.type, argtypes, null, BOX) { @Override - Symbol lookup(Env env, MethodResolutionPhase phase) { + Symbol doLookup(Env env, MethodResolutionPhase phase) { return findMethod(env, site, name, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired(), true); @@ -2668,6 +2667,13 @@ public class Resolve { */ abstract Symbol lookup(Env env, MethodResolutionPhase phase); + /** + * Dump overload resolution info + */ + void debug(DiagnosticPosition pos, Symbol sym) { + //do nothing + } + /** * Validate the result of the lookup */ @@ -2685,17 +2691,30 @@ public class Resolve { } @Override - Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym) { + final Symbol lookup(Env env, MethodResolutionPhase phase) { + Symbol sym = doLookup(env, phase); if (sym.kind == AMBIGUOUS) { AmbiguityError a_err = (AmbiguityError)sym; sym = a_err.mergeAbstracts(site); } + return sym; + } + + abstract Symbol doLookup(Env env, MethodResolutionPhase phase); + + @Override + Symbol access(Env 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; } + + @Override + void debug(DiagnosticPosition pos, Symbol sym) { + reportVerboseResolutionDiagnostic(pos, name, site, argtypes, typeargtypes, sym); + } } /** @@ -2843,7 +2862,7 @@ public class Resolve { protected Symbol lookup(Env env, MethodResolutionPhase phase) { Scope sc = new Scope(syms.arrayClass); MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym); - arrayConstr.type = new MethodType(List.of(syms.intType), site, List.nil(), syms.methodClass); + arrayConstr.type = new MethodType(List.of(syms.intType), site, List.nil(), syms.methodClass); sc.enter(arrayConstr); return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false, false); } @@ -2924,7 +2943,9 @@ public class Resolve { MethodResolutionPhase prevPhase = currentResolutionContext.step; Symbol prevBest = bestSoFar; currentResolutionContext.step = phase; - bestSoFar = phase.mergeResults(bestSoFar, lookupHelper.lookup(env, phase)); + Symbol sym = lookupHelper.lookup(env, phase); + lookupHelper.debug(pos, sym); + bestSoFar = phase.mergeResults(bestSoFar, sym); env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase; } return lookupHelper.access(env, pos, location, bestSoFar); @@ -3630,35 +3651,39 @@ public class Resolve { * is more specific than the others, attempt to merge their signatures. */ Symbol mergeAbstracts(Type site) { - Symbol fst = ambiguousSyms.last(); - Symbol res = fst; - for (Symbol s : ambiguousSyms.reverse()) { - Type mt1 = types.memberType(site, res); - Type mt2 = types.memberType(site, s); - if ((s.flags() & ABSTRACT) == 0 || - !types.overrideEquivalent(mt1, mt2) || - !types.isSameTypes(fst.erasure(types).getParameterTypes(), - s.erasure(types).getParameterTypes())) { - //ambiguity cannot be resolved - return this; - } else { - Type mst = mostSpecificReturnType(mt1, mt2); - if (mst == null) { - // Theoretically, this can't happen, but it is possible - // due to error recovery or mixing incompatible class files + List ambiguousInOrder = ambiguousSyms.reverse(); + for (Symbol s : ambiguousInOrder) { + Type mt = types.memberType(site, s); + boolean found = true; + List allThrown = mt.getThrownTypes(); + for (Symbol s2 : ambiguousInOrder) { + Type mt2 = types.memberType(site, s2); + if ((s2.flags() & ABSTRACT) == 0 || + !types.overrideEquivalent(mt, mt2) || + !types.isSameTypes(s.erasure(types).getParameterTypes(), + s2.erasure(types).getParameterTypes())) { + //ambiguity cannot be resolved return this; } - Symbol mostSpecific = mst == mt1 ? res : s; - List allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes()); - Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown); - res = new MethodSymbol( - mostSpecific.flags(), - mostSpecific.name, - newSig, - mostSpecific.owner); + Type mst = mostSpecificReturnType(mt, mt2); + if (mst == null || mst != mt) { + found = false; + break; + } + allThrown = chk.intersect(allThrown, mt2.getThrownTypes()); + } + if (found) { + //all ambiguous methods were abstract and one method had + //most specific return type then others + return (allThrown == mt.getThrownTypes()) ? + s : new MethodSymbol( + s.flags(), + s.name, + types.createMethodTypeWithThrown(mt, allThrown), + s.owner); } } - return res; + return this; } @Override diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java index 63cff9ffba6..d151dd46172 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java @@ -919,11 +919,15 @@ public class Code { if (o instanceof Long) return syms.longType; if (o instanceof Double) return syms.doubleType; if (o instanceof ClassSymbol) return syms.classType; - if (o instanceof Type.ArrayType) return syms.classType; - if (o instanceof Type.MethodType) return syms.methodTypeType; - if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type); if (o instanceof Pool.MethodHandle) return syms.methodHandleType; - throw new AssertionError(o); + if (o instanceof UniqueType) return typeForPool(((UniqueType)o).type); + if (o instanceof Type) { + Type ty = ((Type)o).unannotatedType(); + + if (ty instanceof Type.ArrayType) return syms.classType; + if (ty instanceof Type.MethodType) return syms.methodTypeType; + } + throw new AssertionError("Invalid type of constant pool entry: " + o.getClass()); } /** Emit an opcode with a one-byte operand field; @@ -1855,7 +1859,7 @@ public class Code { } } - static final Type jsrReturnValue = new Type(INT, null); + static final Type jsrReturnValue = new JCPrimitiveType(INT, null); /* ************************************************************************** diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java index f9ceb77d33b..241845ec0eb 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -991,9 +991,19 @@ public class Gen extends JCTree.Visitor { */ void genMethod(JCMethodDecl tree, Env env, boolean fatcode) { MethodSymbol meth = tree.sym; -// System.err.println("Generating " + meth + " in " + meth.owner); //DEBUG - if (Code.width(types.erasure(env.enclMethod.sym.type).getParameterTypes()) + - (((tree.mods.flags & STATIC) == 0 || meth.isConstructor()) ? 1 : 0) > + int extras = 0; + // Count up extra parameters + if (meth.isConstructor()) { + extras++; + if (meth.enclClass().isInner() && + !meth.enclClass().isStatic()) { + extras++; + } + } else if ((tree.mods.flags & STATIC) == 0) { + extras++; + } + // System.err.println("Generating " + meth + " in " + meth.owner); //DEBUG + if (Code.width(types.erasure(env.enclMethod.sym.type).getParameterTypes()) + extras > ClassFile.MAX_PARAMETERS) { log.error(tree.pos(), "limit.parameters"); nerrs++; @@ -1773,7 +1783,16 @@ public class Gen extends JCTree.Visitor { r.load(); code.emitop0(ireturn + Code.truncate(Code.typecode(pt))); } else { + /* If we have a statement like: + * + * return; + * + * we need to store the code.pendingStatPos value before generating + * the finalizer. + */ + int tmpPos = code.pendingStatPos; targetEnv = unwind(env.enclMethod, env); + code.pendingStatPos = tmpPos; code.emitop0(return_); } endFinalizerGaps(env, targetEnv); diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java index 44a6cd57dd5..72a279d7173 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java +++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java @@ -377,10 +377,10 @@ public class Main { } public Result compile(String[] args, - String[] classNames, - Context context, - List fileObjects, - Iterable processors) + String[] classNames, + Context context, + List fileObjects, + Iterable processors) { context.put(Log.outKey, out); log = Log.instance(context); diff --git a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java index 76d29eb7531..14e377fb37f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java +++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java @@ -139,7 +139,7 @@ public class JavacTypes implements javax.lang.model.util.Types { Type unboxed = types.unboxedType((Type) t); if (! unboxed.isPrimitive()) // only true primitives, not void throw new IllegalArgumentException(t.toString()); - return unboxed; + return (PrimitiveType)unboxed; } public TypeMirror capture(TypeMirror t) { diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java index 5b5ba0bb3f3..b2472185210 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -2914,7 +2914,9 @@ public class JavacParser implements Parser { pos = token.pos; accept(LBRACE); ListBuffer buf = new ListBuffer(); - if (token.kind != RBRACE) { + if (token.kind == COMMA) { + nextToken(); + } else if (token.kind != RBRACE) { buf.append(annotationValue()); while (token.kind == COMMA) { nextToken(); diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index 83b1ee23bb9..4e966f9b716 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -36,10 +36,7 @@ import java.util.regex.*; import javax.annotation.processing.*; import javax.lang.model.SourceVersion; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.Element; -import javax.lang.model.element.PackageElement; -import javax.lang.model.element.TypeElement; +import javax.lang.model.element.*; import javax.lang.model.util.*; import javax.tools.DiagnosticListener; import javax.tools.JavaFileManager; @@ -762,12 +759,30 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea } @Override - public Set scan(Element e, Set p) { + public Set visitType(TypeElement e, Set p) { + // Type parameters are not considered to be enclosed by a type + scan(e.getTypeParameters(), p); + return scan(e.getEnclosedElements(), p); + } + + @Override + public Set visitExecutable(ExecutableElement e, Set p) { + // Type parameters are not considered to be enclosed by an executable + scan(e.getTypeParameters(), p); + return scan(e.getEnclosedElements(), p); + } + + void addAnnotations(Element e, Set p) { for (AnnotationMirror annotationMirror : elements.getAllAnnotationMirrors(e) ) { Element e2 = annotationMirror.getAnnotationType().asElement(); p.add((TypeElement) e2); } + } + + @Override + public Set scan(Element e, Set p) { + addAnnotations(e, p); return super.scan(e, p); } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java index 157f7eb0125..42d9d44cfa2 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java +++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java @@ -146,6 +146,20 @@ public class JavacRoundEnvironment implements RoundEnvironment { this.typeUtil = typeUtil; } + @Override + public Set visitType(TypeElement e, DeclaredType p) { + // Type parameters are not considered to be enclosed by a type + scan(e.getTypeParameters(), p); + return scan(e.getEnclosedElements(), p); + } + + @Override + public Set visitExecutable(ExecutableElement e, DeclaredType p) { + // Type parameters are not considered to be enclosed by an executable + scan(e.getTypeParameters(), p); + return scan(e.getEnclosedElements(), p); + } + @Override public Set scan(Element e, DeclaredType p) { java.util.List annotationMirrors = @@ -157,7 +171,6 @@ public class JavacRoundEnvironment implements RoundEnvironment { e.accept(this, p); return annotatedElements; } - } /** diff --git a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java index f29faf05cd7..d203f1140bb 100644 --- a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java +++ b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -220,12 +220,6 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { } }, - new HiddenOption(false, "-old") { - void process(JavahTask task, String opt, String arg) { - task.old = true; - } - }, - new HiddenOption(false, "-llni", "-Xllni") { void process(JavahTask task, String opt, String arg) { task.llni = true; @@ -663,7 +657,6 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { boolean llni; boolean doubleAlign; boolean force; - boolean old; Set javac_extras = new LinkedHashSet(); PrintWriter log; diff --git a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java index 94aeb019658..02795a57233 100644 --- a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java +++ b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java @@ -114,6 +114,9 @@ public class AttributeWriter extends BasicWriter } public Void visitDefault(DefaultAttribute attr, Void ignore) { + if (attr.reason != null) { + report(attr.reason); + } byte[] data = attr.info; int i = 0; int j = 0; @@ -365,8 +368,7 @@ public class AttributeWriter extends BasicWriter indent(+1); println("Start Length Slot Name Signature"); for (LocalVariableTable_attribute.Entry entry : attr.local_variable_table) { - Formatter formatter = new Formatter(); - println(formatter.format("%8d %7d %5d %5s %s", + println(String.format("%5d %7d %5d %5s %s", entry.start_pc, entry.length, entry.index, constantWriter.stringValue(entry.name_index), constantWriter.stringValue(entry.descriptor_index))); @@ -511,7 +513,12 @@ public class AttributeWriter extends BasicWriter } public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, Void ignore) { - println("SourceDebugExtension: " + attr.getValue()); + println("SourceDebugExtension:"); + indent(+1); + for (String s: attr.getValue().split("[\r\n]+")) { + println(s); + } + indent(-1); return null; } @@ -609,7 +616,8 @@ public class AttributeWriter extends BasicWriter public Void visit_append_frame(StackMapTable_attribute.append_frame frame, Void p) { printHeader(frame); println(" /* append */"); - println(" offset_delta = " + frame.offset_delta); + indent(+1); + println("offset_delta = " + frame.offset_delta); printMap("locals", frame.locals); return null; } diff --git a/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java b/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java index d559de8a951..d3e8769e7ff 100644 --- a/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java +++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java @@ -136,7 +136,8 @@ public class CompileJavaPackages implements Transformer { // for each compile..... int kbPerFile = 175; String osarch = System.getProperty("os.arch"); - if (osarch.equals("i386")) { + String dataModel = System.getProperty("sun.arch.data.model"); + if ("32".equals(dataModel)) { // For 32 bit platforms, assume it is slightly smaller // because of smaller object headers and pointers. kbPerFile = 119; diff --git a/langtools/src/share/classes/javax/annotation/processing/AbstractProcessor.java b/langtools/src/share/classes/javax/annotation/processing/AbstractProcessor.java index eea03b8c526..0ec4b71b341 100644 --- a/langtools/src/share/classes/javax/annotation/processing/AbstractProcessor.java +++ b/langtools/src/share/classes/javax/annotation/processing/AbstractProcessor.java @@ -38,7 +38,7 @@ import javax.tools.Diagnostic; * superclass for most concrete annotation processors. This class * examines annotation values to compute the {@linkplain * #getSupportedOptions options}, {@linkplain - * #getSupportedAnnotationTypes annotations}, and {@linkplain + * #getSupportedAnnotationTypes annotation types}, and {@linkplain * #getSupportedSourceVersion source version} supported by its * subtypes. * diff --git a/langtools/src/share/classes/javax/annotation/processing/Processor.java b/langtools/src/share/classes/javax/annotation/processing/Processor.java index a466bdd711f..c898e74255f 100644 --- a/langtools/src/share/classes/javax/annotation/processing/Processor.java +++ b/langtools/src/share/classes/javax/annotation/processing/Processor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * 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,8 @@ package javax.annotation.processing; import java.util.Set; +import javax.lang.model.util.Elements; +import javax.lang.model.AnnotatedConstruct; import javax.lang.model.element.*; import javax.lang.model.SourceVersion; @@ -88,23 +90,52 @@ import javax.lang.model.SourceVersion; * configuration mechanisms, such as command line options; for * details, refer to the particular tool's documentation. Which * processors the tool asks to {@linkplain #process run} is a function - * of what annotations are present on the {@linkplain + * of the types of the annotations {@linkplain AnnotatedConstruct present} + * on the {@linkplain * RoundEnvironment#getRootElements root elements}, what {@linkplain * #getSupportedAnnotationTypes annotation types a processor - * processes}, and whether or not a processor {@linkplain #process - * claims the annotations it processes}. A processor will be asked to + * supports}, and whether or not a processor {@linkplain #process + * claims the annotation types it processes}. A processor will be asked to * process a subset of the annotation types it supports, possibly an * empty set. * - * For a given round, the tool computes the set of annotation types on - * the root elements. If there is at least one annotation type - * present, as processors claim annotation types, they are removed - * from the set of unmatched annotations. When the set is empty or no - * more processors are available, the round has run to completion. If + * For a given round, the tool computes the set of annotation types + * that are present on the elements enclosed within the root elements. + * If there is at least one annotation type present, then as + * processors claim annotation types, they are removed from the set of + * unmatched annotation types. When the set is empty or no more + * processors are available, the round has run to completion. If * there are no annotation types present, annotation processing still * occurs but only universal processors which support - * processing {@code "*"} can claim the (empty) set of annotation - * types. + * processing all annotation types, {@code "*"}, can claim the (empty) + * set of annotation types. + * + *

    An annotation type is considered present if there is at least + * one annotation of that type present on an element enclosed within + * the root elements of a round. For this purpose, a type parameter is + * considered to be enclosed by its {@linkplain + * TypeParameterElement#getGenericElement generic + * element}. Annotations on {@linkplain + * java.lang.annotation.ElementType#TYPE_USE type uses}, as opposed to + * annotations on elements, are ignored when computing whether or not + * an annotation type is present. + * + *

    An annotation is present if it meets the definition of being + * present given in {@link AnnotatedConstruct}. In brief, an + * annotation is considered present for the purposes of discovery if + * it is directly present or present via inheritance. An annotation is + * not considered present by virtue of being wrapped by a + * container annotation. Operationally, this is equivalent to an + * annotation being present on an element if and only if it would be + * included in the results of {@link + * Elements#getAllAnnotationMirrors(Element)} called on that element. Since + * annotations inside container annotations are not considered + * present, to properly process {@linkplain + * java.lang.annotation.Repeatable repeatable annotation types}, + * processors are advised to include both the repeatable annotation + * type and its containing annotation type in the set of {@linkplain + * #getSupportedAnnotationTypes() supported annotation types} of a + * processor. * *

    Note that if a processor supports {@code "*"} and returns {@code * true}, all annotations are claimed. Therefore, a universal @@ -257,10 +288,10 @@ public interface Processor { /** * Processes a set of annotation types on type elements * originating from the prior round and returns whether or not - * these annotations are claimed by this processor. If {@code - * true} is returned, the annotations are claimed and subsequent + * these annotation types are claimed by this processor. If {@code + * true} is returned, the annotation types are claimed and subsequent * processors will not be asked to process them; if {@code false} - * is returned, the annotations are unclaimed and subsequent + * is returned, the annotation types are unclaimed and subsequent * processors may be asked to process them. A processor may * always return the same boolean value or may vary the result * based on chosen criteria. @@ -271,7 +302,7 @@ public interface Processor { * * @param annotations the annotation types requested to be processed * @param roundEnv environment for information about the current and prior round - * @return whether or not the set of annotations are claimed by this processor + * @return whether or not the set of annotation types are claimed by this processor */ boolean process(Set annotations, RoundEnvironment roundEnv); diff --git a/langtools/src/share/classes/javax/lang/model/SourceVersion.java b/langtools/src/share/classes/javax/lang/model/SourceVersion.java index e2f3bfd538f..ecb079db75a 100644 --- a/langtools/src/share/classes/javax/lang/model/SourceVersion.java +++ b/langtools/src/share/classes/javax/lang/model/SourceVersion.java @@ -53,6 +53,8 @@ public enum SourceVersion { * 1.4: assert * 1.5: annotations, generics, autoboxing, var-args... * 1.6: no changes + * 1.7: diamond syntax, try-with-resources, etc. + * 1.8: lambda expressions and default methods */ /** @@ -122,6 +124,9 @@ public enum SourceVersion { * The version recognized by the Java Platform, Standard Edition * 7. * + * Additions in this release include, diamond syntax for + * constructors, {@code try}-with-resources, strings in switch, + * binary literals, and multi-catch. * @since 1.7 */ RELEASE_7, @@ -130,6 +135,7 @@ public enum SourceVersion { * The version recognized by the Java Platform, Standard Edition * 8. * + * Additions in this release include lambda expressions and default methods. * @since 1.8 */ RELEASE_8; diff --git a/langtools/test/com/sun/javadoc/testJavaFX/C.java b/langtools/test/com/sun/javadoc/testJavaFX/C.java index 9edfcb3bcee..7005185c2cb 100644 --- a/langtools/test/com/sun/javadoc/testJavaFX/C.java +++ b/langtools/test/com/sun/javadoc/testJavaFX/C.java @@ -57,6 +57,7 @@ public class C { * Defines the direction/speed at which the {@code Timeline} is expected to * be played. * @defaultValue 11 + * @since JavaFX 8.0 */ private DoubleProperty rate; diff --git a/langtools/test/com/sun/javadoc/testJavaFX/TestJavaFX.java b/langtools/test/com/sun/javadoc/testJavaFX/TestJavaFX.java index d6055369f09..18d77db8666 100644 --- a/langtools/test/com/sun/javadoc/testJavaFX/TestJavaFX.java +++ b/langtools/test/com/sun/javadoc/testJavaFX/TestJavaFX.java @@ -54,6 +54,8 @@ public class TestJavaFX extends JavadocTester { {"./" + BUG_ID + "/C.html", "Default value:"}, + {"./" + BUG_ID + "/C.html", + "Since:" + NL + "

    JavaFX 8.0
    " }, {"./" + BUG_ID + "/C.html", "

    Sets the value of the property Property"}, {"./" + BUG_ID + "/C.html", @@ -78,7 +80,7 @@ public class TestJavaFX extends JavadocTester { private static final String[] ARGS = new String[] { - "-d", BUG_ID, "-sourcepath", SRC_DIR, "-private", "-javafx", + "-d", BUG_ID, "-sourcepath", SRC_DIR, "-javafx", SRC_DIR + FS + "C.java", SRC_DIR + FS + "D.java" }; diff --git a/langtools/test/com/sun/javadoc/testNestedInlineTag/TestNestedInlineTag.java b/langtools/test/com/sun/javadoc/testNestedInlineTag/TestNestedInlineTag.java index 2f8e8f68cea..b72d6fbdebe 100644 --- a/langtools/test/com/sun/javadoc/testNestedInlineTag/TestNestedInlineTag.java +++ b/langtools/test/com/sun/javadoc/testNestedInlineTag/TestNestedInlineTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * 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,10 +21,8 @@ * questions. */ -/** - * This should be green, underlined and bold (Class): {@underline {@bold {@green My test}}} . +/* * @test - * @bug 0000000 * @summary Test for nested inline tags. * * @author jamieh * @library ../lib/ @@ -36,6 +34,9 @@ * @run main TestNestedInlineTag */ +/** + * This should be green, underlined and bold (Class): {@underline {@bold {@green My test}}} . + */ public class TestNestedInlineTag extends JavadocTester { /** diff --git a/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java b/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java index f0cf05dcb62..9ff91c2d5c9 100644 --- a/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java +++ b/langtools/test/com/sun/javadoc/testPrivateClasses/TestPrivateClasses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * 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 4780441 4874845 4978816 + * @bug 4780441 4874845 4978816 8014017 * @summary Make sure that when the -private flag is not used, members * inherited from package private class are documented in the child. * @@ -33,17 +33,19 @@ * * Make sure that when a private interface method with generic parameters * is implemented, the comments can be inherited properly. + * + * Make sure when no modifier appear in the class signature, the + * signature is displayed correctly without extra space at the beginning. * @author jamieh * @library ../lib/ - * @build JavadocTester - * @build TestPrivateClasses + * @build JavadocTester TestPrivateClasses * @run main TestPrivateClasses */ public class TestPrivateClasses extends JavadocTester { //Test information. - private static final String BUG_ID = "4780441-4874845-4978816"; + private static final String BUG_ID = "4780441-4874845-4978816-8014017"; //Javadoc arguments. private static final String[] ARGS1 = new String[] { @@ -234,8 +236,19 @@ public class TestPrivateClasses extends JavadocTester { " in interface " + "I" + "<java.lang.String>"}, + + //Make sure when no modifier appear in the class signature, the + //signature is displayed correctly without extra space at the beginning. + {BUG_ID + "-2" + FS + "pkg" + FS + "PrivateParent.html", + "

    class PrivateParent"},
    +
    +      {BUG_ID + "-2" + FS + "pkg" + FS + "PublicChild.html",
    +            "
    public class PublicChild"},
    +    };
    +    private static final String[][] NEGATED_TEST2 = {
    +        {BUG_ID + "-2" + FS + "pkg" + FS + "PrivateParent.html",
    +            "
     class PrivateParent"},
         };
    -    private static final String[][] NEGATED_TEST2 = NO_TEST;
     
         /**
          * The entry point of the test.
    diff --git a/langtools/test/com/sun/javadoc/testStylesheet/TestStylesheet.java b/langtools/test/com/sun/javadoc/testStylesheet/TestStylesheet.java
    index 404fc1fe52e..c4044a53d91 100644
    --- a/langtools/test/com/sun/javadoc/testStylesheet/TestStylesheet.java
    +++ b/langtools/test/com/sun/javadoc/testStylesheet/TestStylesheet.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
      * 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      4494033 7028815 7052425
    + * @bug      4494033 7028815 7052425 8007338
      * @summary  Run tests on doclet stylesheet.
      * @author   jamieh
      * @library  ../lib/
    @@ -34,7 +34,7 @@
     public class TestStylesheet extends JavadocTester {
     
         //Test information.
    -    private static final String BUG_ID = "4494033-7028815-7052425";
    +    private static final String BUG_ID = "4494033-7028815-7052425-8007338";
     
         //Javadoc arguments.
         private static final String[] ARGS = new String[] {
    @@ -44,29 +44,45 @@ public class TestStylesheet extends JavadocTester {
         //Input for string search tests.
         private static final String[][] TEST = {
             {BUG_ID + FS + "stylesheet.css",
    -                "/* Javadoc style sheet */"},
    +            "/* Javadoc style sheet */"},
             {BUG_ID + FS + "stylesheet.css",
    -                "/*" + NL + "Overall document style" + NL + "*/"},
    +            "/*" + NL + "Overall document style" + NL + "*/"},
             {BUG_ID + FS + "stylesheet.css",
    -                "/*" + NL + "Heading styles" + NL + "*/"},
    +            "/*" + NL + "Heading styles" + NL + "*/"},
             {BUG_ID + FS + "stylesheet.css",
    -                "/*" + NL + "Navigation bar styles" + NL + "*/"},
    +            "/*" + NL + "Navigation bar styles" + NL + "*/"},
             {BUG_ID + FS + "stylesheet.css",
    -                "body {" + NL + "    background-color:#ffffff;" + NL +
    -                "    color:#353833;" + NL +
    -                "    font-family:Arial, Helvetica, sans-serif;" + NL +
    -                "    font-size:76%;" + NL + "    margin:0;" + NL + "}"},
    +            "body {" + NL + "    background-color:#ffffff;" + NL +
    +            "    color:#353833;" + NL +
    +            "    font-family:Arial, Helvetica, sans-serif;" + NL +
    +            "    font-size:76%;" + NL + "    margin:0;" + NL + "}"},
             {BUG_ID + FS + "stylesheet.css",
    -                "ul {" + NL + "    list-style-type:disc;" + NL + "}"},
    +            "ul {" + NL + "    list-style-type:disc;" + NL + "}"},
    +        {BUG_ID + FS + "stylesheet.css",
    +            ".overviewSummary caption, .packageSummary caption, " +
    +            ".contentContainer ul.blockList li.blockList caption, " +
    +            ".summary caption, .classUseContainer caption, " +
    +            ".constantValuesContainer caption {" + NL +
    +            "    position:relative;" + NL +
    +            "    text-align:left;" + NL +
    +            "    background-repeat:no-repeat;" + NL +
    +            "    color:#FFFFFF;" + NL +
    +            "    font-weight:bold;" + NL +
    +            "    clear:none;" + NL +
    +            "    overflow:hidden;" + NL +
    +            "    padding:0px;" + NL +
    +            "    margin:0px;" + NL +
    +            "    white-space:pre;" + NL +
    +            "}"},
             // Test whether a link to the stylesheet file is inserted properly
             // in the class documentation.
             {BUG_ID + FS + "pkg" + FS + "A.html",
    -                ""}
    +            ""}
         };
         private static final String[][] NEGATED_TEST = {
             {BUG_ID + FS + "stylesheet.css",
    -                "* {" + NL + "    margin:0;" + NL + "    padding:0;" + NL + "}"}
    +            "* {" + NL + "    margin:0;" + NL + "    padding:0;" + NL + "}"}
         };
     
         /**
    diff --git a/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java b/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java
    index d5f67301b60..77cc77876b5 100644
    --- a/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java
    +++ b/langtools/test/com/sun/javadoc/testTagMisuse/TestTagMisuse.java
    @@ -21,9 +21,8 @@
      * questions.
      */
     
    -/**
    +/*
      * @test
    - * @bug 0000000
      * @summary Determine if proper warning messages are printed when know.
      * @author jamieh
      * @library ../lib/
    diff --git a/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java b/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java
    index 1d3baaa0d1c..61d5758bb5d 100644
    --- a/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java
    +++ b/langtools/test/com/sun/javadoc/testTypeAnnotations/TestTypeAnnotations.java
    @@ -78,7 +78,7 @@ public class TestTypeAnnotations extends JavadocTester {
                 "typeannos\">@ClassParamA java.lang.String>"
             },
             {BUG_ID + FS + "typeannos" + FS + "ExtendsGeneric.html",
    -            "
     class ExtendsGeneric<K extends " +
    +            "
    class ExtendsGeneric<K extends " +
                 "@ClassParamA Unannotated< java.lang.String>>"
             },
             {BUG_ID + FS + "typeannos" + FS + "TwoBounds.html",
    -            "
     class TwoBounds<K extends class TwoBounds<K extends " +
                 "@ClassParamA java.lang.String,V extends @ClassParamB" +
    diff --git a/langtools/test/tools/javac/T6326693/FinalVariableAssignedToInCatchBlockTest.java b/langtools/test/tools/javac/T6326693/FinalVariableAssignedToInCatchBlockTest.java
    new file mode 100644
    index 00000000000..ec1caf3523c
    --- /dev/null
    +++ b/langtools/test/tools/javac/T6326693/FinalVariableAssignedToInCatchBlockTest.java
    @@ -0,0 +1,94 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please 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 6356530
    + * @summary -Xlint:serial does not flag abstract classes with concrete methods/members
    + * @compile/fail/ref=FinalVariableAssignedToInCatchBlockTest.out -XDrawDiagnostics FinalVariableAssignedToInCatchBlockTest.java
    + */
    +
    +import java.io.IOException;
    +
    +public class FinalVariableAssignedToInCatchBlockTest {
    +    public void m1(int o)
    +    {
    +        final int i;
    +        try {
    +            if (o == 1) {
    +                throw new IOException();
    +            } else if (o == 2) {
    +                throw new InterruptedException();
    +            } else {
    +                throw new Exception();
    +            }
    +        } catch (IOException e) {
    +            i = 1;
    +        } catch (InterruptedException ie) {
    +            i = 2;
    +        } catch (Exception e) {
    +            i = 3;
    +        } finally {
    +            i = 4;
    +        }
    +    }
    +
    +    public void m2(int o)
    +    {
    +        final int i;
    +        try {
    +            if (o == 1) {
    +                throw new IOException();
    +            } else if (o == 2) {
    +                throw new InterruptedException();
    +            } else {
    +                throw new Exception();
    +            }
    +        } catch (IOException e) {
    +            i = 1;
    +        } catch (InterruptedException ie) {
    +            i = 2;
    +        } catch (Exception e) {
    +            i = 3;
    +        }
    +    }
    +
    +    public void m3(int o) throws Exception
    +    {
    +        final int i;
    +        try {
    +            if (o == 1) {
    +                throw new IOException();
    +            } else if (o == 2) {
    +                throw new InterruptedException();
    +            } else {
    +                throw new Exception();
    +            }
    +        } catch (IOException e) {
    +            i = 1;
    +        } catch (InterruptedException ie) {
    +            i = 2;
    +        }
    +        i = 3;
    +    }
    +}
    diff --git a/langtools/test/tools/javac/T6326693/FinalVariableAssignedToInCatchBlockTest.out b/langtools/test/tools/javac/T6326693/FinalVariableAssignedToInCatchBlockTest.out
    new file mode 100644
    index 00000000000..58ed58efe31
    --- /dev/null
    +++ b/langtools/test/tools/javac/T6326693/FinalVariableAssignedToInCatchBlockTest.out
    @@ -0,0 +1,3 @@
    +FinalVariableAssignedToInCatchBlockTest.java:52:13: compiler.err.var.might.already.be.assigned: i
    +FinalVariableAssignedToInCatchBlockTest.java:92:9: compiler.err.var.might.already.be.assigned: i
    +2 errors
    diff --git a/langtools/test/tools/javac/T6725036.java b/langtools/test/tools/javac/T6725036.java
    index b27ad886d13..24ea34798da 100644
    --- a/langtools/test/tools/javac/T6725036.java
    +++ b/langtools/test/tools/javac/T6725036.java
    @@ -24,6 +24,7 @@
     /*
      * @test
      * @bug 6725036
    + * @ignore 8016760: failure of regression test langtools/tools/javac/T6725036.java
      * @summary javac returns incorrect value for lastModifiedTime() when
      *          source is a zip file archive
      */
    diff --git a/langtools/test/tools/javac/T7008643/InlinedFinallyConfuseDebuggersTest.java b/langtools/test/tools/javac/T7008643/InlinedFinallyConfuseDebuggersTest.java
    new file mode 100644
    index 00000000000..8557f99a383
    --- /dev/null
    +++ b/langtools/test/tools/javac/T7008643/InlinedFinallyConfuseDebuggersTest.java
    @@ -0,0 +1,117 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please 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 7008643
    + * @summary inlined finally clauses confuse debuggers
    + * @library /tools/javac/lib
    + * @build ToolBox
    + * @run main InlinedFinallyConfuseDebuggersTest
    + */
    +
    +import java.io.File;
    +import java.nio.file.Paths;
    +
    +import com.sun.tools.classfile.ClassFile;
    +import com.sun.tools.classfile.Code_attribute;
    +import com.sun.tools.classfile.LineNumberTable_attribute;
    +import com.sun.tools.classfile.Method;
    +import com.sun.tools.javac.util.Assert;
    +
    +public class InlinedFinallyConfuseDebuggersTest {
    +
    +    static final String testSource =
    +    /* 01 */        "public class InlinedFinallyTest {\n" +
    +    /* 02 */        "    void lookForThisMethod(int value) {\n" +
    +    /* 03 */        "        try {\n" +
    +    /* 04 */        "            if (value > 0) {\n" +
    +    /* 05 */        "                System.out.println(\"if\");\n" +
    +    /* 06 */        "                return;\n" +
    +    /* 07 */        "            }\n" +
    +    /* 08 */        "        } finally {\n" +
    +    /* 09 */        "            System.out.println(\"finally\");\n" +
    +    /* 10 */        "        }\n" +
    +    /* 11 */        "    }\n" +
    +    /* 12 */        "}";
    +
    +    static final int[][] expectedLNT = {
    +    //  {line-number, start-pc},
    +        {4,           0},       //if (value > 0) {
    +        {5,           4},       //    System.out.println("if");
    +        {9,           12},      //System.out.println("finally");
    +        {6,           20},      //    return;
    +        {9,           21},      //System.out.println("finally");
    +        {10,          29},
    +        {9,           32},      //System.out.println("finally");
    +        {11,          43},
    +    };
    +
    +    static final String methodToLookFor = "lookForThisMethod";
    +
    +    public static void main(String[] args) throws Exception {
    +        new InlinedFinallyConfuseDebuggersTest().run();
    +    }
    +
    +    void run() throws Exception {
    +        compileTestClass();
    +        checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
    +                "InlinedFinallyTest.class").toUri()), methodToLookFor);
    +    }
    +
    +    void compileTestClass() throws Exception {
    +        ToolBox.JavaToolArgs javacSuccessArgs =
    +                new ToolBox.JavaToolArgs().setSources(testSource);
    +        ToolBox.javac(javacSuccessArgs);
    +    }
    +
    +    void checkClassFile(final File cfile, String methodToFind) throws Exception {
    +        ClassFile classFile = ClassFile.read(cfile);
    +        boolean methodFound = false;
    +        for (Method method : classFile.methods) {
    +            if (method.getName(classFile.constant_pool).equals(methodToFind)) {
    +                methodFound = true;
    +                Code_attribute code = (Code_attribute) method.attributes.get("Code");
    +                LineNumberTable_attribute lnt =
    +                        (LineNumberTable_attribute) code.attributes.get("LineNumberTable");
    +                Assert.check(lnt.line_number_table_length == expectedLNT.length,
    +                        "The LineNumberTable found has a length different to the expected one");
    +                int i = 0;
    +                for (LineNumberTable_attribute.Entry entry: lnt.line_number_table) {
    +                    Assert.check(entry.line_number == expectedLNT[i][0] &&
    +                            entry.start_pc == expectedLNT[i][1],
    +                            "LNT entry at pos " + i + " differ from expected." +
    +                            "Found " + entry.line_number + ":" + entry.start_pc +
    +                            ". Expected " + expectedLNT[i][0] + ":" + expectedLNT[i][1]);
    +                    i++;
    +                }
    +            }
    +        }
    +        Assert.check(methodFound, "The seek method was not found");
    +    }
    +
    +    void error(String msg) {
    +        throw new AssertionError(msg);
    +    }
    +
    +}
    diff --git a/langtools/test/tools/javac/T8016099/UncheckedWarningRegressionTest.java b/langtools/test/tools/javac/T8016099/UncheckedWarningRegressionTest.java
    new file mode 100644
    index 00000000000..2a66ad45d97
    --- /dev/null
    +++ b/langtools/test/tools/javac/T8016099/UncheckedWarningRegressionTest.java
    @@ -0,0 +1,32 @@
    +/*
    + * @test /nodynamiccopyright/
    + * @bug     8016099
    + * @summary Some SuppressWarnings annotations ignored ( unchecked, rawtypes )
    + * @compile UncheckedWarningRegressionTest.java
    + * @compile/fail/ref=UncheckedWarningRegressionTest.out -XDrawDiagnostics -Werror -Xlint:unchecked UncheckedWarningRegressionTest.java
    + */
    +
    +public class UncheckedWarningRegressionTest {
    +     void suppressedWarningsFinalInitializer() {
    +        @SuppressWarnings("unchecked")
    +        T[] tt = (T[]) FINAL_EMPTY_ARRAY;
    +    }
    +
    +    final Object[] FINAL_EMPTY_ARRAY = {};
    +
    +     void finalInitializer() {
    +        T[] tt = (T[]) FINAL_EMPTY_ARRAY;
    +    }
    +
    +     void suppressedWarningsNonFinalInitializer() {
    +        @SuppressWarnings("unchecked")
    +        T[] tt = (T[]) NON_FINAL_EMPTY_ARRAY;
    +    }
    +
    +    Object[] NON_FINAL_EMPTY_ARRAY = {};
    +
    +     void nonFinalInitializer() {
    +        T[] tt = (T[]) NON_FINAL_EMPTY_ARRAY;
    +    }
    +
    +}
    diff --git a/langtools/test/tools/javac/T8016099/UncheckedWarningRegressionTest.out b/langtools/test/tools/javac/T8016099/UncheckedWarningRegressionTest.out
    new file mode 100644
    index 00000000000..05bd6f7423e
    --- /dev/null
    +++ b/langtools/test/tools/javac/T8016099/UncheckedWarningRegressionTest.out
    @@ -0,0 +1,5 @@
    +UncheckedWarningRegressionTest.java:18:24: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), java.lang.Object[], T[]
    +UncheckedWarningRegressionTest.java:29:24: compiler.warn.prob.found.req: (compiler.misc.unchecked.cast.to.type), java.lang.Object[], T[]
    +- compiler.err.warnings.and.werror
    +1 error
    +2 warnings
    diff --git a/langtools/test/tools/javac/api/6437999/T6437999.java b/langtools/test/tools/javac/api/6437999/T6437999.java
    index db2f46a3e7a..2fbe3211fb9 100644
    --- a/langtools/test/tools/javac/api/6437999/T6437999.java
    +++ b/langtools/test/tools/javac/api/6437999/T6437999.java
    @@ -33,11 +33,28 @@
      */
     
     import java.io.File;
    +import java.io.IOException;
     import java.nio.charset.Charset;
    +import java.nio.file.Files;
    +import java.util.ArrayList;
     import java.util.Collections;
    +import java.util.List;
     import javax.tools.*;
    +import static java.nio.file.StandardOpenOption.*;
     
     public class T6437999 extends ToolTester {
    +    final File testFile = new File("Utf8.java");
    +    T6437999() throws IOException {
    +        createTestFile();
    +    }
    +    final void createTestFile() throws IOException {
    +        List scratch = new ArrayList<>();
    +        scratch.add("// @author Peter von der Ah" + (char) 0xe9);
    +        scratch.add("class Utf8{}");
    +        Files.write(testFile.toPath(), scratch, Charset.forName("UTF-8"),
    +                CREATE, TRUNCATE_EXISTING);
    +    }
    +
         static class MyDiagnosticListener implements DiagnosticListener {
             boolean error = false;
             public void report(Diagnostic diagnostic) {
    @@ -55,7 +72,7 @@ public class T6437999 extends ToolTester {
             dl.error = false;
             fm = getFileManager(tool, dl, Charset.forName("ASCII"));
             fm.handleOption("-source", sourceLevel.iterator());
    -        files = fm.getJavaFileObjects(new File(test_src, "Utf8.java"));
    +        files = fm.getJavaFileObjects(testFile);
             tool.getTask(null, fm, null, null, null, files).call();
             if (!dl.error)
                 throw new AssertionError("No error in ASCII mode");
    @@ -63,12 +80,12 @@ public class T6437999 extends ToolTester {
             dl.error = false;
             fm = getFileManager(tool, dl, Charset.forName("UTF-8"));
             fm.handleOption("-source", sourceLevel.iterator());
    -        files = fm.getJavaFileObjects(new File(test_src, "Utf8.java"));
    +        files = fm.getJavaFileObjects(testFile);
             task = tool.getTask(null, fm, null, null, null, files);
             if (dl.error)
                 throw new AssertionError("Error in UTF-8 mode");
         }
    -    public static void main(String... args) {
    +    public static void main(String... args) throws IOException {
             new T6437999().test(args);
         }
     }
    diff --git a/langtools/test/tools/javac/api/T6306137.java b/langtools/test/tools/javac/api/T6306137.java
    index 826fe51fe96..c17283c99d8 100644
    --- a/langtools/test/tools/javac/api/T6306137.java
    +++ b/langtools/test/tools/javac/api/T6306137.java
    @@ -31,8 +31,14 @@
      */
     
     import java.io.File;
    +import java.io.IOException;
    +import java.nio.charset.Charset;
    +import java.nio.file.Files;
    +import java.util.ArrayList;
     import java.util.Arrays;
    +import java.util.List;
     import javax.tools.*;
    +import static java.nio.file.StandardOpenOption.*;
     
     public class T6306137 {
         boolean error;
    @@ -40,8 +46,9 @@ public class T6306137 {
         final JavaCompiler compiler;
         Iterable files;
         DiagnosticListener dl;
    +    final File testFile = new File("Utf8.java");
     
    -    T6306137() {
    +    T6306137() throws IOException {
             dl = new DiagnosticListener() {
                     public void report(Diagnostic message) {
                         if (message.getKind() == Diagnostic.Kind.ERROR)
    @@ -56,11 +63,17 @@ public class T6306137 {
             };
             compiler = ToolProvider.getSystemJavaCompiler();
             fm = compiler.getStandardFileManager(dl, null, null);
    -        String srcdir = System.getProperty("test.src");
             files =
    -            fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(srcdir, "T6306137.java")));
    +            fm.getJavaFileObjectsFromFiles(Arrays.asList(testFile));
    +        createTestFile();
    +    }
    +    final void createTestFile() throws IOException {
    +        List scratch = new ArrayList<>();
    +        scratch.add("// @author Peter von der Ah" + (char)0xe9);
    +        scratch.add("class Utf8{}");
    +        Files.write(testFile.toPath(), scratch, Charset.forName("UTF-8"),
    +                CREATE, TRUNCATE_EXISTING);
         }
    -
         void test(String encoding, boolean good) {
             error = false;
             Iterable args = Arrays.asList("-source", "6", "-encoding", encoding, "-d", ".");
    @@ -74,7 +87,7 @@ public class T6306137 {
             }
         }
     
    -    public static void main(String[] args) {
    +    public static void main(String[] args) throws IOException {
             T6306137 self = new T6306137();
             self.test("utf-8", true);
             self.test("ascii", false);
    diff --git a/langtools/test/tools/javac/lambda/LambdaConv01.java b/langtools/test/tools/javac/lambda/LambdaConv01.java
    index 73436c2f509..582c99fd383 100644
    --- a/langtools/test/tools/javac/lambda/LambdaConv01.java
    +++ b/langtools/test/tools/javac/lambda/LambdaConv01.java
    @@ -67,7 +67,7 @@ public class LambdaConv01 {
             assertTrue(3 == f1.foo());
             //Covariant returns:
             TU f2 = (Integer x) -> x;
    -        assertTrue(3 == f2.foo(3));
    +        assertTrue(3 == f2.foo(3).intValue());
             //Method resolution with boxing:
             int res = LambdaConv01.exec((Integer x) -> x, 3);
             assertTrue(3 == res);
    @@ -86,7 +86,7 @@ public class LambdaConv01 {
             assertTrue(3 == f1.foo());
             //Covariant returns:
             TU f2 = (Integer x) -> x;
    -        assertTrue(3 == f2.foo(3));
    +        assertTrue(3 == f2.foo(3).intValue());
             //Method resolution with boxing:
             int res = LambdaConv01.exec((Integer x) -> x, 3);
             assertTrue(3 == res);
    @@ -105,7 +105,7 @@ public class LambdaConv01 {
             assertTrue(3 == f1.foo());
             //Covariant returns:
             TU f2 = (Integer x) -> x;
    -        assertTrue(3 == f2.foo(3));
    +        assertTrue(3 == f2.foo(3).intValue());
             //Method resolution with boxing:
             int res = LambdaConv01.exec((Integer x) -> x, 3);
             assertTrue(3 == res);
    @@ -124,7 +124,7 @@ public class LambdaConv01 {
             assertTrue(3 == f1.foo());
             //Covariant returns:
             TU f2 = (Integer x) -> x;
    -        assertTrue(3 == f2.foo(3));
    +        assertTrue(3 == f2.foo(3).intValue());
             //Method resolution with boxing:
             int res = LambdaConv01.exec((Integer x) -> x, 3);
             assertTrue(3 == res);
    diff --git a/langtools/test/tools/javac/lambda/LambdaExpr15.java b/langtools/test/tools/javac/lambda/LambdaExpr15.java
    index fd5f4e14bf0..af00ee5c5d8 100644
    --- a/langtools/test/tools/javac/lambda/LambdaExpr15.java
    +++ b/langtools/test/tools/javac/lambda/LambdaExpr15.java
    @@ -48,7 +48,7 @@ public class LambdaExpr15 {
                 new Object() {
                     String get() { return ""; }
                 };
    -            assertTrue(t == 1);
    +            assertTrue((Integer)t == 1);
             };
             ba1.apply(1);
     
    @@ -58,7 +58,7 @@ public class LambdaExpr15 {
                     String get() { return ""; }
                 };
                 new A();
    -            assertTrue(t == 2);
    +            assertTrue((Integer)t == 2);
             };
             ba2.apply(2);
             assertTrue(assertionCount == 2);
    diff --git a/langtools/test/tools/javac/lambda/typeInference/InferenceTest2b.java b/langtools/test/tools/javac/lambda/typeInference/InferenceTest2b.java
    index 8ab215afbdb..2dbe880a50b 100644
    --- a/langtools/test/tools/javac/lambda/typeInference/InferenceTest2b.java
    +++ b/langtools/test/tools/javac/lambda/typeInference/InferenceTest2b.java
    @@ -64,7 +64,7 @@ public class InferenceTest2b {
     
         void m2(SAM6 s) {
             System.out.println("m2()");
    -        assertTrue(s.m6(1, 2) == 1);
    +        assertTrue(s.m6(1, 2).equals(Integer.valueOf(1)));
         }
     
         void m3(SAM6 s) {
    diff --git a/langtools/test/tools/javac/limits/NestedClassConstructorArgs.java b/langtools/test/tools/javac/limits/NestedClassConstructorArgs.java
    new file mode 100644
    index 00000000000..9b56b6f0e01
    --- /dev/null
    +++ b/langtools/test/tools/javac/limits/NestedClassConstructorArgs.java
    @@ -0,0 +1,45 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please 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 8014230
    + * @summary Compiler silently generates bytecode that exceeds VM limits
    + * @compile NumArgsTest.java
    + * @run main NestedClassConstructorArgs
    + */
    +
    +public class NestedClassConstructorArgs extends NumArgsTest {
    +    private static final NumArgsTest.NestingDef[] nesting = {
    +        classNesting("Inner")
    +    };
    +
    +    private NestedClassConstructorArgs() {
    +        super(253, "NestedClassConstructorArgs", "Inner", nesting);
    +    }
    +
    +    public static void main(String... args) throws Exception {
    +        new NestedClassConstructorArgs().runTest();
    +    }
    +}
    +
    diff --git a/langtools/test/tools/javac/limits/NestedClassMethodArgs.java b/langtools/test/tools/javac/limits/NestedClassMethodArgs.java
    new file mode 100644
    index 00000000000..762ef186d8f
    --- /dev/null
    +++ b/langtools/test/tools/javac/limits/NestedClassMethodArgs.java
    @@ -0,0 +1,45 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please 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 8014230
    + * @summary Compiler silently generates bytecode that exceeds VM limits
    + * @compile NumArgsTest.java
    + * @run main NestedClassMethodArgs
    + */
    +
    +public class NestedClassMethodArgs extends NumArgsTest {
    +    private static final NumArgsTest.NestingDef[] nesting = {
    +        classNesting("Inner")
    +    };
    +
    +    private NestedClassMethodArgs() {
    +        super(254, "void", "test", "NestedClassMethodArgs", nesting);
    +    }
    +
    +    public static void main(String... args) throws Exception {
    +        new NestedClassMethodArgs().runTest();
    +    }
    +}
    +
    diff --git a/langtools/test/tools/javac/limits/NumArgs1.java b/langtools/test/tools/javac/limits/NumArgs1.java
    deleted file mode 100644
    index fe009046bcb..00000000000
    --- a/langtools/test/tools/javac/limits/NumArgs1.java
    +++ /dev/null
    @@ -1,552 +0,0 @@
    -/*
    - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please 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 4309152
    - * @summary Compiler silently generates bytecode that exceeds VM limits
    - * @author gafter
    - *
    - * @compile/fail NumArgs1.java
    - */
    -
    -class NumArgs1 {
    -    void f(
    -           // T1 this,
    -           int x2,
    -           int x3,
    -           int x4,
    -           int x5,
    -           int x6,
    -           int x7,
    -           int x8,
    -           int x9,
    -           int x10,
    -           int x11,
    -           int x12,
    -           int x13,
    -           int x14,
    -           int x15,
    -           int x16,
    -           int x17,
    -           int x18,
    -           int x19,
    -           int x20,
    -           int x21,
    -           int x22,
    -           int x23,
    -           int x24,
    -           int x25,
    -           int x26,
    -           int x27,
    -           int x28,
    -           int x29,
    -           int x30,
    -           int x31,
    -           int x32,
    -           int x33,
    -           int x34,
    -           int x35,
    -           int x36,
    -           int x37,
    -           int x38,
    -           int x39,
    -           int x40,
    -           int x41,
    -           int x42,
    -           int x43,
    -           int x44,
    -           int x45,
    -           int x46,
    -           int x47,
    -           int x48,
    -           int x49,
    -           int x50,
    -           int x51,
    -           int x52,
    -           int x53,
    -           int x54,
    -           int x55,
    -           int x56,
    -           int x57,
    -           int x58,
    -           int x59,
    -           int x60,
    -           int x61,
    -           int x62,
    -           int x63,
    -           int x64,
    -           int x65,
    -           int x66,
    -           int x67,
    -           int x68,
    -           int x69,
    -           int x70,
    -           int x71,
    -           int x72,
    -           int x73,
    -           int x74,
    -           int x75,
    -           int x76,
    -           int x77,
    -           int x78,
    -           int x79,
    -           int x80,
    -           int x81,
    -           int x82,
    -           int x83,
    -           int x84,
    -           int x85,
    -           int x86,
    -           int x87,
    -           int x88,
    -           int x89,
    -           int x90,
    -           int x91,
    -           int x92,
    -           int x93,
    -           int x94,
    -           int x95,
    -           int x96,
    -           int x97,
    -           int x98,
    -           int x99,
    -           int x100,
    -           int x101,
    -           int x102,
    -           int x103,
    -           int x104,
    -           int x105,
    -           int x106,
    -           int x107,
    -           int x108,
    -           int x109,
    -           int x110,
    -           int x111,
    -           int x112,
    -           int x113,
    -           int x114,
    -           int x115,
    -           int x116,
    -           int x117,
    -           int x118,
    -           int x119,
    -           int x120,
    -           int x121,
    -           int x122,
    -           int x123,
    -           int x124,
    -           int x125,
    -           int x126,
    -           int x127,
    -           int x128,
    -           int x129,
    -           int x130,
    -           int x131,
    -           int x132,
    -           int x133,
    -           int x134,
    -           int x135,
    -           int x136,
    -           int x137,
    -           int x138,
    -           int x139,
    -           int x140,
    -           int x141,
    -           int x142,
    -           int x143,
    -           int x144,
    -           int x145,
    -           int x146,
    -           int x147,
    -           int x148,
    -           int x149,
    -           int x150,
    -           int x151,
    -           int x152,
    -           int x153,
    -           int x154,
    -           int x155,
    -           int x156,
    -           int x157,
    -           int x158,
    -           int x159,
    -           int x160,
    -           int x161,
    -           int x162,
    -           int x163,
    -           int x164,
    -           int x165,
    -           int x166,
    -           int x167,
    -           int x168,
    -           int x169,
    -           int x170,
    -           int x171,
    -           int x172,
    -           int x173,
    -           int x174,
    -           int x175,
    -           int x176,
    -           int x177,
    -           int x178,
    -           int x179,
    -           int x180,
    -           int x181,
    -           int x182,
    -           int x183,
    -           int x184,
    -           int x185,
    -           int x186,
    -           int x187,
    -           int x188,
    -           int x189,
    -           int x190,
    -           int x191,
    -           int x192,
    -           int x193,
    -           int x194,
    -           int x195,
    -           int x196,
    -           int x197,
    -           int x198,
    -           int x199,
    -           int x200,
    -           int x201,
    -           int x202,
    -           int x203,
    -           int x204,
    -           int x205,
    -           int x206,
    -           int x207,
    -           int x208,
    -           int x209,
    -           int x210,
    -           int x211,
    -           int x212,
    -           int x213,
    -           int x214,
    -           int x215,
    -           int x216,
    -           int x217,
    -           int x218,
    -           int x219,
    -           int x220,
    -           int x221,
    -           int x222,
    -           int x223,
    -           int x224,
    -           int x225,
    -           int x226,
    -           int x227,
    -           int x228,
    -           int x229,
    -           int x230,
    -           int x231,
    -           int x232,
    -           int x233,
    -           int x234,
    -           int x235,
    -           int x236,
    -           int x237,
    -           int x238,
    -           int x239,
    -           int x240,
    -           int x241,
    -           int x242,
    -           int x243,
    -           int x244,
    -           int x245,
    -           int x246,
    -           int x247,
    -           int x248,
    -           int x249,
    -           int x250,
    -           int x251,
    -           int x252,
    -           int x253,
    -           int x254,
    -           int x255,
    -           int x256
    -    ) {}
    -
    -    static
    -    void g(
    -           int x1,
    -           int x2,
    -           int x3,
    -           int x4,
    -           int x5,
    -           int x6,
    -           int x7,
    -           int x8,
    -           int x9,
    -           int x10,
    -           int x11,
    -           int x12,
    -           int x13,
    -           int x14,
    -           int x15,
    -           int x16,
    -           int x17,
    -           int x18,
    -           int x19,
    -           int x20,
    -           int x21,
    -           int x22,
    -           int x23,
    -           int x24,
    -           int x25,
    -           int x26,
    -           int x27,
    -           int x28,
    -           int x29,
    -           int x30,
    -           int x31,
    -           int x32,
    -           int x33,
    -           int x34,
    -           int x35,
    -           int x36,
    -           int x37,
    -           int x38,
    -           int x39,
    -           int x40,
    -           int x41,
    -           int x42,
    -           int x43,
    -           int x44,
    -           int x45,
    -           int x46,
    -           int x47,
    -           int x48,
    -           int x49,
    -           int x50,
    -           int x51,
    -           int x52,
    -           int x53,
    -           int x54,
    -           int x55,
    -           int x56,
    -           int x57,
    -           int x58,
    -           int x59,
    -           int x60,
    -           int x61,
    -           int x62,
    -           int x63,
    -           int x64,
    -           int x65,
    -           int x66,
    -           int x67,
    -           int x68,
    -           int x69,
    -           int x70,
    -           int x71,
    -           int x72,
    -           int x73,
    -           int x74,
    -           int x75,
    -           int x76,
    -           int x77,
    -           int x78,
    -           int x79,
    -           int x80,
    -           int x81,
    -           int x82,
    -           int x83,
    -           int x84,
    -           int x85,
    -           int x86,
    -           int x87,
    -           int x88,
    -           int x89,
    -           int x90,
    -           int x91,
    -           int x92,
    -           int x93,
    -           int x94,
    -           int x95,
    -           int x96,
    -           int x97,
    -           int x98,
    -           int x99,
    -           int x100,
    -           int x101,
    -           int x102,
    -           int x103,
    -           int x104,
    -           int x105,
    -           int x106,
    -           int x107,
    -           int x108,
    -           int x109,
    -           int x110,
    -           int x111,
    -           int x112,
    -           int x113,
    -           int x114,
    -           int x115,
    -           int x116,
    -           int x117,
    -           int x118,
    -           int x119,
    -           int x120,
    -           int x121,
    -           int x122,
    -           int x123,
    -           int x124,
    -           int x125,
    -           int x126,
    -           int x127,
    -           int x128,
    -           int x129,
    -           int x130,
    -           int x131,
    -           int x132,
    -           int x133,
    -           int x134,
    -           int x135,
    -           int x136,
    -           int x137,
    -           int x138,
    -           int x139,
    -           int x140,
    -           int x141,
    -           int x142,
    -           int x143,
    -           int x144,
    -           int x145,
    -           int x146,
    -           int x147,
    -           int x148,
    -           int x149,
    -           int x150,
    -           int x151,
    -           int x152,
    -           int x153,
    -           int x154,
    -           int x155,
    -           int x156,
    -           int x157,
    -           int x158,
    -           int x159,
    -           int x160,
    -           int x161,
    -           int x162,
    -           int x163,
    -           int x164,
    -           int x165,
    -           int x166,
    -           int x167,
    -           int x168,
    -           int x169,
    -           int x170,
    -           int x171,
    -           int x172,
    -           int x173,
    -           int x174,
    -           int x175,
    -           int x176,
    -           int x177,
    -           int x178,
    -           int x179,
    -           int x180,
    -           int x181,
    -           int x182,
    -           int x183,
    -           int x184,
    -           int x185,
    -           int x186,
    -           int x187,
    -           int x188,
    -           int x189,
    -           int x190,
    -           int x191,
    -           int x192,
    -           int x193,
    -           int x194,
    -           int x195,
    -           int x196,
    -           int x197,
    -           int x198,
    -           int x199,
    -           int x200,
    -           int x201,
    -           int x202,
    -           int x203,
    -           int x204,
    -           int x205,
    -           int x206,
    -           int x207,
    -           int x208,
    -           int x209,
    -           int x210,
    -           int x211,
    -           int x212,
    -           int x213,
    -           int x214,
    -           int x215,
    -           int x216,
    -           int x217,
    -           int x218,
    -           int x219,
    -           int x220,
    -           int x221,
    -           int x222,
    -           int x223,
    -           int x224,
    -           int x225,
    -           int x226,
    -           int x227,
    -           int x228,
    -           int x229,
    -           int x230,
    -           int x231,
    -           int x232,
    -           int x233,
    -           int x234,
    -           int x235,
    -           int x236,
    -           int x237,
    -           int x238,
    -           int x239,
    -           int x240,
    -           int x241,
    -           int x242,
    -           int x243,
    -           int x244,
    -           int x245,
    -           int x246,
    -           int x247,
    -           int x248,
    -           int x249,
    -           int x250,
    -           int x251,
    -           int x252,
    -           int x253,
    -           int x254,
    -           int x255,
    -           int x256
    -    ) {}
    -}
    diff --git a/langtools/test/tools/javac/limits/NumArgs2.java b/langtools/test/tools/javac/limits/NumArgs2.java
    deleted file mode 100644
    index 7692a9bf4c1..00000000000
    --- a/langtools/test/tools/javac/limits/NumArgs2.java
    +++ /dev/null
    @@ -1,550 +0,0 @@
    -/*
    - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please 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 4309152
    - * @summary Compiler silently generates bytecode that exceeds VM limits
    - * @author gafter
    - *
    - * @compile NumArgs2.java
    - */
    -
    -class NumArgs2 {
    -    void f(
    -           // This this,
    -           int x2,
    -           int x3,
    -           int x4,
    -           int x5,
    -           int x6,
    -           int x7,
    -           int x8,
    -           int x9,
    -           int x10,
    -           int x11,
    -           int x12,
    -           int x13,
    -           int x14,
    -           int x15,
    -           int x16,
    -           int x17,
    -           int x18,
    -           int x19,
    -           int x20,
    -           int x21,
    -           int x22,
    -           int x23,
    -           int x24,
    -           int x25,
    -           int x26,
    -           int x27,
    -           int x28,
    -           int x29,
    -           int x30,
    -           int x31,
    -           int x32,
    -           int x33,
    -           int x34,
    -           int x35,
    -           int x36,
    -           int x37,
    -           int x38,
    -           int x39,
    -           int x40,
    -           int x41,
    -           int x42,
    -           int x43,
    -           int x44,
    -           int x45,
    -           int x46,
    -           int x47,
    -           int x48,
    -           int x49,
    -           int x50,
    -           int x51,
    -           int x52,
    -           int x53,
    -           int x54,
    -           int x55,
    -           int x56,
    -           int x57,
    -           int x58,
    -           int x59,
    -           int x60,
    -           int x61,
    -           int x62,
    -           int x63,
    -           int x64,
    -           int x65,
    -           int x66,
    -           int x67,
    -           int x68,
    -           int x69,
    -           int x70,
    -           int x71,
    -           int x72,
    -           int x73,
    -           int x74,
    -           int x75,
    -           int x76,
    -           int x77,
    -           int x78,
    -           int x79,
    -           int x80,
    -           int x81,
    -           int x82,
    -           int x83,
    -           int x84,
    -           int x85,
    -           int x86,
    -           int x87,
    -           int x88,
    -           int x89,
    -           int x90,
    -           int x91,
    -           int x92,
    -           int x93,
    -           int x94,
    -           int x95,
    -           int x96,
    -           int x97,
    -           int x98,
    -           int x99,
    -           int x100,
    -           int x101,
    -           int x102,
    -           int x103,
    -           int x104,
    -           int x105,
    -           int x106,
    -           int x107,
    -           int x108,
    -           int x109,
    -           int x110,
    -           int x111,
    -           int x112,
    -           int x113,
    -           int x114,
    -           int x115,
    -           int x116,
    -           int x117,
    -           int x118,
    -           int x119,
    -           int x120,
    -           int x121,
    -           int x122,
    -           int x123,
    -           int x124,
    -           int x125,
    -           int x126,
    -           int x127,
    -           int x128,
    -           int x129,
    -           int x130,
    -           int x131,
    -           int x132,
    -           int x133,
    -           int x134,
    -           int x135,
    -           int x136,
    -           int x137,
    -           int x138,
    -           int x139,
    -           int x140,
    -           int x141,
    -           int x142,
    -           int x143,
    -           int x144,
    -           int x145,
    -           int x146,
    -           int x147,
    -           int x148,
    -           int x149,
    -           int x150,
    -           int x151,
    -           int x152,
    -           int x153,
    -           int x154,
    -           int x155,
    -           int x156,
    -           int x157,
    -           int x158,
    -           int x159,
    -           int x160,
    -           int x161,
    -           int x162,
    -           int x163,
    -           int x164,
    -           int x165,
    -           int x166,
    -           int x167,
    -           int x168,
    -           int x169,
    -           int x170,
    -           int x171,
    -           int x172,
    -           int x173,
    -           int x174,
    -           int x175,
    -           int x176,
    -           int x177,
    -           int x178,
    -           int x179,
    -           int x180,
    -           int x181,
    -           int x182,
    -           int x183,
    -           int x184,
    -           int x185,
    -           int x186,
    -           int x187,
    -           int x188,
    -           int x189,
    -           int x190,
    -           int x191,
    -           int x192,
    -           int x193,
    -           int x194,
    -           int x195,
    -           int x196,
    -           int x197,
    -           int x198,
    -           int x199,
    -           int x200,
    -           int x201,
    -           int x202,
    -           int x203,
    -           int x204,
    -           int x205,
    -           int x206,
    -           int x207,
    -           int x208,
    -           int x209,
    -           int x210,
    -           int x211,
    -           int x212,
    -           int x213,
    -           int x214,
    -           int x215,
    -           int x216,
    -           int x217,
    -           int x218,
    -           int x219,
    -           int x220,
    -           int x221,
    -           int x222,
    -           int x223,
    -           int x224,
    -           int x225,
    -           int x226,
    -           int x227,
    -           int x228,
    -           int x229,
    -           int x230,
    -           int x231,
    -           int x232,
    -           int x233,
    -           int x234,
    -           int x235,
    -           int x236,
    -           int x237,
    -           int x238,
    -           int x239,
    -           int x240,
    -           int x241,
    -           int x242,
    -           int x243,
    -           int x244,
    -           int x245,
    -           int x246,
    -           int x247,
    -           int x248,
    -           int x249,
    -           int x250,
    -           int x251,
    -           int x252,
    -           int x253,
    -           int x254,
    -           int x255
    -    ) {}
    -
    -    static
    -    void g(
    -           int x1,
    -           int x2,
    -           int x3,
    -           int x4,
    -           int x5,
    -           int x6,
    -           int x7,
    -           int x8,
    -           int x9,
    -           int x10,
    -           int x11,
    -           int x12,
    -           int x13,
    -           int x14,
    -           int x15,
    -           int x16,
    -           int x17,
    -           int x18,
    -           int x19,
    -           int x20,
    -           int x21,
    -           int x22,
    -           int x23,
    -           int x24,
    -           int x25,
    -           int x26,
    -           int x27,
    -           int x28,
    -           int x29,
    -           int x30,
    -           int x31,
    -           int x32,
    -           int x33,
    -           int x34,
    -           int x35,
    -           int x36,
    -           int x37,
    -           int x38,
    -           int x39,
    -           int x40,
    -           int x41,
    -           int x42,
    -           int x43,
    -           int x44,
    -           int x45,
    -           int x46,
    -           int x47,
    -           int x48,
    -           int x49,
    -           int x50,
    -           int x51,
    -           int x52,
    -           int x53,
    -           int x54,
    -           int x55,
    -           int x56,
    -           int x57,
    -           int x58,
    -           int x59,
    -           int x60,
    -           int x61,
    -           int x62,
    -           int x63,
    -           int x64,
    -           int x65,
    -           int x66,
    -           int x67,
    -           int x68,
    -           int x69,
    -           int x70,
    -           int x71,
    -           int x72,
    -           int x73,
    -           int x74,
    -           int x75,
    -           int x76,
    -           int x77,
    -           int x78,
    -           int x79,
    -           int x80,
    -           int x81,
    -           int x82,
    -           int x83,
    -           int x84,
    -           int x85,
    -           int x86,
    -           int x87,
    -           int x88,
    -           int x89,
    -           int x90,
    -           int x91,
    -           int x92,
    -           int x93,
    -           int x94,
    -           int x95,
    -           int x96,
    -           int x97,
    -           int x98,
    -           int x99,
    -           int x100,
    -           int x101,
    -           int x102,
    -           int x103,
    -           int x104,
    -           int x105,
    -           int x106,
    -           int x107,
    -           int x108,
    -           int x109,
    -           int x110,
    -           int x111,
    -           int x112,
    -           int x113,
    -           int x114,
    -           int x115,
    -           int x116,
    -           int x117,
    -           int x118,
    -           int x119,
    -           int x120,
    -           int x121,
    -           int x122,
    -           int x123,
    -           int x124,
    -           int x125,
    -           int x126,
    -           int x127,
    -           int x128,
    -           int x129,
    -           int x130,
    -           int x131,
    -           int x132,
    -           int x133,
    -           int x134,
    -           int x135,
    -           int x136,
    -           int x137,
    -           int x138,
    -           int x139,
    -           int x140,
    -           int x141,
    -           int x142,
    -           int x143,
    -           int x144,
    -           int x145,
    -           int x146,
    -           int x147,
    -           int x148,
    -           int x149,
    -           int x150,
    -           int x151,
    -           int x152,
    -           int x153,
    -           int x154,
    -           int x155,
    -           int x156,
    -           int x157,
    -           int x158,
    -           int x159,
    -           int x160,
    -           int x161,
    -           int x162,
    -           int x163,
    -           int x164,
    -           int x165,
    -           int x166,
    -           int x167,
    -           int x168,
    -           int x169,
    -           int x170,
    -           int x171,
    -           int x172,
    -           int x173,
    -           int x174,
    -           int x175,
    -           int x176,
    -           int x177,
    -           int x178,
    -           int x179,
    -           int x180,
    -           int x181,
    -           int x182,
    -           int x183,
    -           int x184,
    -           int x185,
    -           int x186,
    -           int x187,
    -           int x188,
    -           int x189,
    -           int x190,
    -           int x191,
    -           int x192,
    -           int x193,
    -           int x194,
    -           int x195,
    -           int x196,
    -           int x197,
    -           int x198,
    -           int x199,
    -           int x200,
    -           int x201,
    -           int x202,
    -           int x203,
    -           int x204,
    -           int x205,
    -           int x206,
    -           int x207,
    -           int x208,
    -           int x209,
    -           int x210,
    -           int x211,
    -           int x212,
    -           int x213,
    -           int x214,
    -           int x215,
    -           int x216,
    -           int x217,
    -           int x218,
    -           int x219,
    -           int x220,
    -           int x221,
    -           int x222,
    -           int x223,
    -           int x224,
    -           int x225,
    -           int x226,
    -           int x227,
    -           int x228,
    -           int x229,
    -           int x230,
    -           int x231,
    -           int x232,
    -           int x233,
    -           int x234,
    -           int x235,
    -           int x236,
    -           int x237,
    -           int x238,
    -           int x239,
    -           int x240,
    -           int x241,
    -           int x242,
    -           int x243,
    -           int x244,
    -           int x245,
    -           int x246,
    -           int x247,
    -           int x248,
    -           int x249,
    -           int x250,
    -           int x251,
    -           int x252,
    -           int x253,
    -           int x254,
    -           int x255
    -    ) {}
    -}
    diff --git a/langtools/test/tools/javac/limits/NumArgs3.java b/langtools/test/tools/javac/limits/NumArgs3.java
    deleted file mode 100644
    index c200b1a0f9e..00000000000
    --- a/langtools/test/tools/javac/limits/NumArgs3.java
    +++ /dev/null
    @@ -1,292 +0,0 @@
    -/*
    - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please 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 4309152
    - * @summary Compiler silently generates bytecode that exceeds VM limits
    - * @author gafter
    - *
    - * @compile/fail NumArgs3.java
    - */
    -
    -class NumArgs3 {
    -    void NumArgs3(
    -           // T1 this,
    -           int x2,
    -           int x3,
    -           int x4,
    -           int x5,
    -           int x6,
    -           int x7,
    -           int x8,
    -           int x9,
    -           int x10,
    -           int x11,
    -           int x12,
    -           int x13,
    -           int x14,
    -           int x15,
    -           int x16,
    -           int x17,
    -           int x18,
    -           int x19,
    -           int x20,
    -           int x21,
    -           int x22,
    -           int x23,
    -           int x24,
    -           int x25,
    -           int x26,
    -           int x27,
    -           int x28,
    -           int x29,
    -           int x30,
    -           int x31,
    -           int x32,
    -           int x33,
    -           int x34,
    -           int x35,
    -           int x36,
    -           int x37,
    -           int x38,
    -           int x39,
    -           int x40,
    -           int x41,
    -           int x42,
    -           int x43,
    -           int x44,
    -           int x45,
    -           int x46,
    -           int x47,
    -           int x48,
    -           int x49,
    -           int x50,
    -           int x51,
    -           int x52,
    -           int x53,
    -           int x54,
    -           int x55,
    -           int x56,
    -           int x57,
    -           int x58,
    -           int x59,
    -           int x60,
    -           int x61,
    -           int x62,
    -           int x63,
    -           int x64,
    -           int x65,
    -           int x66,
    -           int x67,
    -           int x68,
    -           int x69,
    -           int x70,
    -           int x71,
    -           int x72,
    -           int x73,
    -           int x74,
    -           int x75,
    -           int x76,
    -           int x77,
    -           int x78,
    -           int x79,
    -           int x80,
    -           int x81,
    -           int x82,
    -           int x83,
    -           int x84,
    -           int x85,
    -           int x86,
    -           int x87,
    -           int x88,
    -           int x89,
    -           int x90,
    -           int x91,
    -           int x92,
    -           int x93,
    -           int x94,
    -           int x95,
    -           int x96,
    -           int x97,
    -           int x98,
    -           int x99,
    -           int x100,
    -           int x101,
    -           int x102,
    -           int x103,
    -           int x104,
    -           int x105,
    -           int x106,
    -           int x107,
    -           int x108,
    -           int x109,
    -           int x110,
    -           int x111,
    -           int x112,
    -           int x113,
    -           int x114,
    -           int x115,
    -           int x116,
    -           int x117,
    -           int x118,
    -           int x119,
    -           int x120,
    -           int x121,
    -           int x122,
    -           int x123,
    -           int x124,
    -           int x125,
    -           int x126,
    -           int x127,
    -           int x128,
    -           int x129,
    -           int x130,
    -           int x131,
    -           int x132,
    -           int x133,
    -           int x134,
    -           int x135,
    -           int x136,
    -           int x137,
    -           int x138,
    -           int x139,
    -           int x140,
    -           int x141,
    -           int x142,
    -           int x143,
    -           int x144,
    -           int x145,
    -           int x146,
    -           int x147,
    -           int x148,
    -           int x149,
    -           int x150,
    -           int x151,
    -           int x152,
    -           int x153,
    -           int x154,
    -           int x155,
    -           int x156,
    -           int x157,
    -           int x158,
    -           int x159,
    -           int x160,
    -           int x161,
    -           int x162,
    -           int x163,
    -           int x164,
    -           int x165,
    -           int x166,
    -           int x167,
    -           int x168,
    -           int x169,
    -           int x170,
    -           int x171,
    -           int x172,
    -           int x173,
    -           int x174,
    -           int x175,
    -           int x176,
    -           int x177,
    -           int x178,
    -           int x179,
    -           int x180,
    -           int x181,
    -           int x182,
    -           int x183,
    -           int x184,
    -           int x185,
    -           int x186,
    -           int x187,
    -           int x188,
    -           int x189,
    -           int x190,
    -           int x191,
    -           int x192,
    -           int x193,
    -           int x194,
    -           int x195,
    -           int x196,
    -           int x197,
    -           int x198,
    -           int x199,
    -           int x200,
    -           int x201,
    -           int x202,
    -           int x203,
    -           int x204,
    -           int x205,
    -           int x206,
    -           int x207,
    -           int x208,
    -           int x209,
    -           int x210,
    -           int x211,
    -           int x212,
    -           int x213,
    -           int x214,
    -           int x215,
    -           int x216,
    -           int x217,
    -           int x218,
    -           int x219,
    -           int x220,
    -           int x221,
    -           int x222,
    -           int x223,
    -           int x224,
    -           int x225,
    -           int x226,
    -           int x227,
    -           int x228,
    -           int x229,
    -           int x230,
    -           int x231,
    -           int x232,
    -           int x233,
    -           int x234,
    -           int x235,
    -           int x236,
    -           int x237,
    -           int x238,
    -           int x239,
    -           int x240,
    -           int x241,
    -           int x242,
    -           int x243,
    -           int x244,
    -           int x245,
    -           int x246,
    -           int x247,
    -           int x248,
    -           int x249,
    -           int x250,
    -           int x251,
    -           int x252,
    -           int x253,
    -           int x254,
    -           int x255,
    -           int x256
    -    ) {}
    -}
    diff --git a/langtools/test/tools/javac/limits/NumArgs4.java b/langtools/test/tools/javac/limits/NumArgs4.java
    deleted file mode 100644
    index 73234dd79eb..00000000000
    --- a/langtools/test/tools/javac/limits/NumArgs4.java
    +++ /dev/null
    @@ -1,291 +0,0 @@
    -/*
    - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please 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 4309152
    - * @summary Compiler silently generates bytecode that exceeds VM limits
    - * @author gafter
    - *
    - * @compile NumArgs4.java
    - */
    -
    -class NumArgs4 {
    -    void NumArgs4(
    -           // T1 this,
    -           int x2,
    -           int x3,
    -           int x4,
    -           int x5,
    -           int x6,
    -           int x7,
    -           int x8,
    -           int x9,
    -           int x10,
    -           int x11,
    -           int x12,
    -           int x13,
    -           int x14,
    -           int x15,
    -           int x16,
    -           int x17,
    -           int x18,
    -           int x19,
    -           int x20,
    -           int x21,
    -           int x22,
    -           int x23,
    -           int x24,
    -           int x25,
    -           int x26,
    -           int x27,
    -           int x28,
    -           int x29,
    -           int x30,
    -           int x31,
    -           int x32,
    -           int x33,
    -           int x34,
    -           int x35,
    -           int x36,
    -           int x37,
    -           int x38,
    -           int x39,
    -           int x40,
    -           int x41,
    -           int x42,
    -           int x43,
    -           int x44,
    -           int x45,
    -           int x46,
    -           int x47,
    -           int x48,
    -           int x49,
    -           int x50,
    -           int x51,
    -           int x52,
    -           int x53,
    -           int x54,
    -           int x55,
    -           int x56,
    -           int x57,
    -           int x58,
    -           int x59,
    -           int x60,
    -           int x61,
    -           int x62,
    -           int x63,
    -           int x64,
    -           int x65,
    -           int x66,
    -           int x67,
    -           int x68,
    -           int x69,
    -           int x70,
    -           int x71,
    -           int x72,
    -           int x73,
    -           int x74,
    -           int x75,
    -           int x76,
    -           int x77,
    -           int x78,
    -           int x79,
    -           int x80,
    -           int x81,
    -           int x82,
    -           int x83,
    -           int x84,
    -           int x85,
    -           int x86,
    -           int x87,
    -           int x88,
    -           int x89,
    -           int x90,
    -           int x91,
    -           int x92,
    -           int x93,
    -           int x94,
    -           int x95,
    -           int x96,
    -           int x97,
    -           int x98,
    -           int x99,
    -           int x100,
    -           int x101,
    -           int x102,
    -           int x103,
    -           int x104,
    -           int x105,
    -           int x106,
    -           int x107,
    -           int x108,
    -           int x109,
    -           int x110,
    -           int x111,
    -           int x112,
    -           int x113,
    -           int x114,
    -           int x115,
    -           int x116,
    -           int x117,
    -           int x118,
    -           int x119,
    -           int x120,
    -           int x121,
    -           int x122,
    -           int x123,
    -           int x124,
    -           int x125,
    -           int x126,
    -           int x127,
    -           int x128,
    -           int x129,
    -           int x130,
    -           int x131,
    -           int x132,
    -           int x133,
    -           int x134,
    -           int x135,
    -           int x136,
    -           int x137,
    -           int x138,
    -           int x139,
    -           int x140,
    -           int x141,
    -           int x142,
    -           int x143,
    -           int x144,
    -           int x145,
    -           int x146,
    -           int x147,
    -           int x148,
    -           int x149,
    -           int x150,
    -           int x151,
    -           int x152,
    -           int x153,
    -           int x154,
    -           int x155,
    -           int x156,
    -           int x157,
    -           int x158,
    -           int x159,
    -           int x160,
    -           int x161,
    -           int x162,
    -           int x163,
    -           int x164,
    -           int x165,
    -           int x166,
    -           int x167,
    -           int x168,
    -           int x169,
    -           int x170,
    -           int x171,
    -           int x172,
    -           int x173,
    -           int x174,
    -           int x175,
    -           int x176,
    -           int x177,
    -           int x178,
    -           int x179,
    -           int x180,
    -           int x181,
    -           int x182,
    -           int x183,
    -           int x184,
    -           int x185,
    -           int x186,
    -           int x187,
    -           int x188,
    -           int x189,
    -           int x190,
    -           int x191,
    -           int x192,
    -           int x193,
    -           int x194,
    -           int x195,
    -           int x196,
    -           int x197,
    -           int x198,
    -           int x199,
    -           int x200,
    -           int x201,
    -           int x202,
    -           int x203,
    -           int x204,
    -           int x205,
    -           int x206,
    -           int x207,
    -           int x208,
    -           int x209,
    -           int x210,
    -           int x211,
    -           int x212,
    -           int x213,
    -           int x214,
    -           int x215,
    -           int x216,
    -           int x217,
    -           int x218,
    -           int x219,
    -           int x220,
    -           int x221,
    -           int x222,
    -           int x223,
    -           int x224,
    -           int x225,
    -           int x226,
    -           int x227,
    -           int x228,
    -           int x229,
    -           int x230,
    -           int x231,
    -           int x232,
    -           int x233,
    -           int x234,
    -           int x235,
    -           int x236,
    -           int x237,
    -           int x238,
    -           int x239,
    -           int x240,
    -           int x241,
    -           int x242,
    -           int x243,
    -           int x244,
    -           int x245,
    -           int x246,
    -           int x247,
    -           int x248,
    -           int x249,
    -           int x250,
    -           int x251,
    -           int x252,
    -           int x253,
    -           int x254,
    -           int x255
    -    ) {}
    -}
    diff --git a/langtools/test/tools/javac/limits/NumArgsTest.java b/langtools/test/tools/javac/limits/NumArgsTest.java
    new file mode 100644
    index 00000000000..751df98d999
    --- /dev/null
    +++ b/langtools/test/tools/javac/limits/NumArgsTest.java
    @@ -0,0 +1,269 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please 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.tools.javac.util.*;
    +import com.sun.tools.javac.api.*;
    +import com.sun.tools.javac.file.*;
    +import java.io.*;
    +import java.util.*;
    +import javax.tools.*;
    +
    +// More general parameter limit testing framework, and designed so
    +// that it could be expanded into a general limits-testing framework
    +// in the future.
    +public class NumArgsTest {
    +
    +    private static final NumArgsTest.NestingDef[] NO_NESTING = {};
    +
    +    // threshold is named as such because "threshold" args is expected
    +    // to pass, and "threshold" + 1 args is expected to fail.
    +    private final int threshold;
    +    private final boolean isStaticMethod;
    +    private final String result;
    +    private final String testName;
    +    private final String methodName;
    +    private final NestingDef[] nesting;
    +    private final File testdir;
    +    private final JavacTool tool = JavacTool.create();
    +    private final JavacFileManager fm =
    +        tool.getStandardFileManager(null, null, null);
    +    private int errors = 0;
    +
    +    public NumArgsTest(final int threshold,
    +                       final boolean isStaticMethod,
    +                       final String result,
    +                       final String methodName,
    +                       final String testName,
    +                       final NestingDef[] nesting) {
    +        this.threshold = threshold;
    +        this.isStaticMethod = isStaticMethod;
    +        this.result = result;
    +        this.methodName = methodName;
    +        this.testName = testName;
    +        this.nesting = nesting;
    +        testdir = new File(testName);
    +        testdir.mkdir();
    +    }
    +
    +    public NumArgsTest(final int threshold,
    +                       final boolean isStaticMethod,
    +                       final String result,
    +                       final String methodName,
    +                       final String testName) {
    +        this(threshold, isStaticMethod, result, methodName,
    +             testName, NO_NESTING);
    +    }
    +
    +    public NumArgsTest(final int threshold,
    +                       final String result,
    +                       final String methodName,
    +                       final String testName,
    +                       final NestingDef[] nesting) {
    +        this(threshold, false, result, methodName, testName, nesting);
    +    }
    +
    +    public NumArgsTest(final int threshold,
    +                       final String result,
    +                       final String methodName,
    +                       final String testName) {
    +        this(threshold, false, result, methodName, testName, NO_NESTING);
    +    }
    +
    +    public NumArgsTest(final int threshold,
    +                       final String testName,
    +                       final NestingDef[] nesting) {
    +        this(threshold, null, null, testName, nesting);
    +    }
    +
    +    public NumArgsTest(final int threshold,
    +                       final String testName) {
    +        this(threshold, null, null, testName, NO_NESTING);
    +    }
    +
    +    public NumArgsTest(final int threshold,
    +                       final String testName,
    +                       final String constructorName,
    +                       final NestingDef[] nesting) {
    +        this(threshold, null, constructorName, testName, nesting);
    +    }
    +
    +    protected void writeArgs(final int num, final PrintWriter stream)
    +        throws IOException {
    +        stream.print("int x1");
    +        for(int i = 1; i < num; i++)
    +            stream.print(", int x" + (i + 1));
    +    }
    +
    +    protected void writeMethod(final int num,
    +                               final String name,
    +                               final PrintWriter stream)
    +        throws IOException {
    +        stream.write("public ");
    +        if (isStaticMethod) stream.write("static ");
    +        if (result == null)
    +            stream.write("");
    +        else {
    +            stream.write(result);
    +            stream.write(" ");
    +        }
    +        stream.write(name);
    +        stream.write("(");
    +        writeArgs(num, stream);
    +        stream.write(") {}\n");
    +    }
    +
    +    protected void writeJavaFile(final int num,
    +                                 final boolean pass,
    +                                 final PrintWriter stream)
    +        throws IOException {
    +        final String fullName = testName + (pass ? "Pass" : "Fail");
    +        stream.write("public class ");
    +        stream.write(fullName);
    +        stream.write(" {\n");
    +        for(int i = 0; i < nesting.length; i++)
    +            nesting[i].writeBefore(stream);
    +        if (null == methodName)
    +            writeMethod(num, fullName, stream);
    +        else
    +            writeMethod(num, methodName, stream);
    +        for(int i = nesting.length - 1; i >= 0; i--)
    +            nesting[i].writeAfter(stream);
    +        stream.write("}\n");
    +    }
    +
    +    public void runTest() throws Exception {
    +        // Run the pass test
    +        final String passTestName = testName + "Pass.java";
    +        final StringWriter passBody = new StringWriter();
    +        final PrintWriter passStream = new PrintWriter(passBody);
    +        final File passFile = new File(testdir, passTestName);
    +        final FileWriter passWriter = new FileWriter(passFile);
    +
    +        writeJavaFile(threshold, true, passStream);
    +        passStream.close();
    +        passWriter.write(passBody.toString());
    +        passWriter.close();
    +
    +        final StringWriter passSW = new StringWriter();
    +        final String[] passArgs = { passFile.toString() };
    +        final Iterable passFiles =
    +            fm.getJavaFileObjectsFromFiles(Arrays.asList(passFile));
    +        final JavaCompiler.CompilationTask passTask =
    +            tool.getTask(passSW, fm, null, null, null, passFiles);
    +
    +        if (!passTask.call()) {
    +            errors++;
    +            System.err.println("Compilation unexpectedly failed. Body:\n" +
    +                               passBody);
    +            System.err.println("Output:\n" + passSW.toString());
    +        }
    +
    +        // Run the fail test
    +        final String failTestName = testName + "Fail.java";
    +        final StringWriter failBody = new StringWriter();
    +        final PrintWriter failStream = new PrintWriter(failBody);
    +        final File failFile = new File(testdir, failTestName);
    +        final FileWriter failWriter = new FileWriter(failFile);
    +
    +        writeJavaFile(threshold + 1, false, failStream);
    +        failStream.close();
    +        failWriter.write(failBody.toString());
    +        failWriter.close();
    +
    +        final StringWriter failSW = new StringWriter();
    +        final TestDiagnosticHandler failDiag =
    +            new TestDiagnosticHandler("compiler.err.limit.parameters");
    +        final Iterable failFiles =
    +            fm.getJavaFileObjectsFromFiles(Arrays.asList(failFile));
    +        final JavaCompiler.CompilationTask failTask =
    +            tool.getTask(failSW,
    +                         tool.getStandardFileManager(null, null, null),
    +                         failDiag,
    +                         null,
    +                         null,
    +                         failFiles);
    +
    +        if (failTask.call()) {
    +            errors++;
    +            System.err.println("Compilation unexpectedly succeeded.");
    +            System.err.println("Input:\n" + failBody);
    +        }
    +
    +        if (!failDiag.sawError) {
    +            errors++;
    +            System.err.println("Did not see expected compile error.");
    +        }
    +
    +        if (errors != 0)
    +            throw new RuntimeException("Test failed with " +
    +                                       errors + " errors");
    +    }
    +
    +    public static NestingDef classNesting(final String name) {
    +        return new NestedClassBuilder(name, false);
    +    }
    +
    +    public static NestingDef classNesting(final String name,
    +                                          final boolean isStatic) {
    +        return new NestedClassBuilder(name, isStatic);
    +    }
    +
    +    protected interface NestingDef {
    +        public abstract void writeBefore(final PrintWriter stream);
    +        public abstract void writeAfter(final PrintWriter stream);
    +    }
    +
    +    private static class NestedClassBuilder implements NestingDef {
    +        private final String name;
    +        private final boolean isStatic;
    +        public NestedClassBuilder(final String name, final boolean isStatic) {
    +            this.name = name;
    +            this.isStatic = isStatic;
    +        }
    +        public void writeBefore(final PrintWriter stream) {
    +            stream.write("public ");
    +            if (isStatic) stream.write("static");
    +            stream.write(" class ");
    +            stream.write(name);
    +            stream.write(" {\n");
    +        }
    +        public void writeAfter(final PrintWriter stream) {
    +            stream.write("}\n");
    +        }
    +    }
    +
    +    public class TestDiagnosticHandler implements DiagnosticListener {
    +        public boolean sawError;
    +        public final String target;
    +
    +        public TestDiagnosticHandler(final String target) {
    +            this.target = target;
    +        }
    +
    +        public void report(final Diagnostic diag) {
    +            if (diag.getCode().equals(target))
    +                sawError = true;
    +        }
    +    }
    +
    +}
    diff --git a/langtools/test/tools/javac/limits/StaticNestedClassConstructorArgs.java b/langtools/test/tools/javac/limits/StaticNestedClassConstructorArgs.java
    new file mode 100644
    index 00000000000..393a37b433e
    --- /dev/null
    +++ b/langtools/test/tools/javac/limits/StaticNestedClassConstructorArgs.java
    @@ -0,0 +1,45 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please 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 8014230
    + * @summary Compiler silently generates bytecode that exceeds VM limits
    + * @compile NumArgsTest.java
    + * @run main StaticNestedClassConstructorArgs
    + */
    +
    +public class StaticNestedClassConstructorArgs extends NumArgsTest {
    +    private static final NumArgsTest.NestingDef[] nesting = {
    +        classNesting("StaticInner", true)
    +    };
    +
    +    private StaticNestedClassConstructorArgs() {
    +        super(254, "StaticNestedClassConstructorArgs", "StaticInner", nesting);
    +    }
    +
    +    public static void main(String... args) throws Exception {
    +        new StaticNestedClassConstructorArgs().runTest();
    +    }
    +}
    +
    diff --git a/langtools/test/tools/javac/limits/TopLevelClassConstructorArgs.java b/langtools/test/tools/javac/limits/TopLevelClassConstructorArgs.java
    new file mode 100644
    index 00000000000..ee567d6030e
    --- /dev/null
    +++ b/langtools/test/tools/javac/limits/TopLevelClassConstructorArgs.java
    @@ -0,0 +1,40 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please 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 4309152
    + * @summary Compiler silently generates bytecode that exceeds VM limits
    + * @compile NumArgsTest.java
    + * @run main TopLevelClassConstructorArgs
    + */
    +
    +public class TopLevelClassConstructorArgs extends NumArgsTest {
    +    private TopLevelClassConstructorArgs() {
    +        super(254, "TopLevelClassConstructorArgs");
    +    }
    +
    +    public static void main(String... args) throws Exception {
    +        new TopLevelClassConstructorArgs().runTest();
    +    }
    +}
    diff --git a/langtools/test/tools/javac/limits/TopLevelClassMethodArgs.java b/langtools/test/tools/javac/limits/TopLevelClassMethodArgs.java
    new file mode 100644
    index 00000000000..7ae66c9108f
    --- /dev/null
    +++ b/langtools/test/tools/javac/limits/TopLevelClassMethodArgs.java
    @@ -0,0 +1,40 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please 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 4309152
    + * @summary Compiler silently generates bytecode that exceeds VM limits
    + * @compile NumArgsTest.java
    + * @run main TopLevelClassMethodArgs
    + */
    +
    +public class TopLevelClassMethodArgs extends NumArgsTest {
    +    private TopLevelClassMethodArgs() {
    +        super(254, "void", "test", "TopLevelClassMethodArgs");
    +    }
    +
    +    public static void main(String... args) throws Exception {
    +        new TopLevelClassMethodArgs().runTest();
    +    }
    +}
    diff --git a/langtools/test/tools/javac/limits/TopLevelClassStaticMethodArgs.java b/langtools/test/tools/javac/limits/TopLevelClassStaticMethodArgs.java
    new file mode 100644
    index 00000000000..f905157dc54
    --- /dev/null
    +++ b/langtools/test/tools/javac/limits/TopLevelClassStaticMethodArgs.java
    @@ -0,0 +1,40 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please 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 4309152
    + * @summary Compiler silently generates bytecode that exceeds VM limits
    + * @compile NumArgsTest.java
    + * @run main TopLevelClassStaticMethodArgs
    + */
    +
    +public class TopLevelClassStaticMethodArgs extends NumArgsTest {
    +    private TopLevelClassStaticMethodArgs() {
    +        super(255, true, "void", "test", "TopLevelClassStaticMethodArgs");
    +    }
    +
    +    public static void main(String... args) throws Exception {
    +        new TopLevelClassStaticMethodArgs().runTest();
    +    }
    +}
    diff --git a/langtools/test/tools/javac/literals/UnderscoreLiterals.java b/langtools/test/tools/javac/literals/UnderscoreLiterals.java
    index 410450cad0e..0e669acedee 100644
    --- a/langtools/test/tools/javac/literals/UnderscoreLiterals.java
    +++ b/langtools/test/tools/javac/literals/UnderscoreLiterals.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -42,6 +42,12 @@ public class UnderscoreLiterals {
             test(1_0_0, 100);
             test(1__0__0, 100);
             test(123_456_789, 123456789);
    +        test(2_147_483_647, Integer.MAX_VALUE);
    +        test(-2_147_483_648, Integer.MIN_VALUE);
    +        test(32_767, Short.MAX_VALUE);
    +        test(-32_768, Short.MIN_VALUE);
    +        test(1_2_7, Byte.MAX_VALUE);
    +        test(-1_2_8, Byte.MIN_VALUE);
     
             // long
             test(1l, 1l);
    @@ -51,6 +57,8 @@ public class UnderscoreLiterals {
             test(1_0_0l, 100l);
             test(1__0__0l, 100l);
             test(123_456_789l, 123456789l);
    +        test(9_223_372_036_854_775_807l, Long.MAX_VALUE);
    +        test(-9_223_372_036_854_775_808l, Long.MIN_VALUE);
     
             // float
             test(.1f, .1f);
    @@ -80,6 +88,8 @@ public class UnderscoreLiterals {
             test(1_1.1_0_0f, 1_1.100f);
             test(1_1.1__0__0f, 1_1.100f);
             test(1_1.123_456_789f, 1_1.123456789f);
    +        test(3.4_028_235E38f, Float.MAX_VALUE);
    +        test(1.4E-4_5f, Float.MIN_VALUE);
     
             // double
             test(.1d, .1d);
    @@ -109,6 +119,8 @@ public class UnderscoreLiterals {
             test(1_1.1_0_0d, 1_1.100d);
             test(1_1.1__0__0d, 1_1.100d);
             test(1_1.123_456_789d, 1_1.123456789d);
    +        test(1.797_6_9_3_1_348_623_157E3_08, Double.MAX_VALUE);
    +        test(4.9E-3_24, Double.MIN_VALUE);
     
             // binary
             test(0b1, 1);
    @@ -118,6 +130,14 @@ public class UnderscoreLiterals {
             test(0b1_0_0, 4);
             test(0b1__0__0, 4);
             test(0b0001_0010_0011, 0x123);
    +        test(0b111_1111_1111_1111_1111_1111_1111_1111, Integer.MAX_VALUE);
    +        test(0b1000_0000_0000_0000_0000_0000_0000_0000, Integer.MIN_VALUE);
    +        test(0b111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111l, Long.MAX_VALUE);
    +        test(0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000l, Long.MIN_VALUE);
    +        test(0b111_1111_1111_1111, Short.MAX_VALUE);
    +        test((short)-0b1000_0000_0000_0000, Short.MIN_VALUE);
    +        test(0b111_1111, Byte.MAX_VALUE);
    +        test((byte)-0b1000_0000, Byte.MIN_VALUE);
     
             // octal
             test(01, 1);
    @@ -133,6 +153,14 @@ public class UnderscoreLiterals {
             test(0_1_0_0, 64);
             test(0_1__0__0, 64);
             test(0_001_002_003, 01002003);
    +        test(0177_7777_7777, Integer.MAX_VALUE);
    +        test(-0200_0000_0000, Integer.MIN_VALUE);
    +        test(077_77_77_77_77_7_77_77_77_77_77l, Long.MAX_VALUE);
    +        test(-010_00_00_00_00_00_00_00_00_00_00l, Long.MIN_VALUE);
    +        test((short)07_77_77, Short.MAX_VALUE);
    +        test((short)-010_00_00, Short.MIN_VALUE);
    +        test(01_77, Byte.MAX_VALUE);
    +        test((byte)-02_00, Byte.MIN_VALUE);
     
             // hexadecimal
             test(0x1, 1);
    @@ -142,6 +170,18 @@ public class UnderscoreLiterals {
             test(0x1_0_0, 256);
             test(0x1__0__0, 256);
             test(0x01_02_03_04, 0x1020304);
    +        test(0x7f_ff_ff_ff, Integer.MAX_VALUE);
    +        test(0x80_00_00_00, Integer.MIN_VALUE);
    +        test(0x1.f_ff_ffep127f, Float.MAX_VALUE);
    +        test(0x0.00_00_02p-126f, Float.MIN_VALUE);
    +        test(0x1.f__ff_ff_ff_ff_ff_ffp1_023, Double.MAX_VALUE);
    +        test(0x0.000_000_000_000_1p-1_022, Double.MIN_VALUE);
    +        test(0x7f_ff_ff_ff_ff_ff_ff_ffl, Long.MAX_VALUE);
    +        test(0x80_00_00_00_00_00_00_00l, Long.MIN_VALUE);
    +        test(0x7f_ff, Short.MAX_VALUE);
    +        test((short)0x80_00, Short.MIN_VALUE);
    +        test(0x7_f, Byte.MAX_VALUE);
    +        test((byte)0x8_0, Byte.MIN_VALUE);
     
             // misc
             long creditCardNumber = 1234_5678_9012_3456L;
    diff --git a/langtools/test/tools/javac/parser/SingleCommaAnnotationValue.java b/langtools/test/tools/javac/parser/SingleCommaAnnotationValue.java
    new file mode 100644
    index 00000000000..53a3a55b486
    --- /dev/null
    +++ b/langtools/test/tools/javac/parser/SingleCommaAnnotationValue.java
    @@ -0,0 +1,39 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please 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 8012722
    + * @summary Single comma in array initializer should parse
    + * @compile SingleCommaAnnotationValue.java
    + */
    +
    +public class SingleCommaAnnotationValue {
    +    @Foo({}) void a() { }
    +    @Foo({,}) void b() { }
    +    @Foo({0}) void c() { }
    +    @Foo({0,}) void d() { }
    +    @Foo({0,0}) void e() { }
    +    @Foo({0,0,}) void f() { }
    +}
    +@interface Foo { int[] value(); }
    diff --git a/langtools/test/tools/javac/parser/SingleCommaAnnotationValueFail.java b/langtools/test/tools/javac/parser/SingleCommaAnnotationValueFail.java
    new file mode 100644
    index 00000000000..4467d98ba71
    --- /dev/null
    +++ b/langtools/test/tools/javac/parser/SingleCommaAnnotationValueFail.java
    @@ -0,0 +1,36 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please 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 8012722
    + * @summary Single comma in array initializer should parse
    + * @compile/fail/ref=SingleCommaAnnotationValueFail.out -XDrawDiagnostics
    + * SingleCommaAnnotationValueFail.java
    + */
    +
    +public class SingleCommaAnnotationValueFail {
    +    // Non-example
    +    @Foo({,0}) void a() { }
    +}
    +@interface Foo { int[] value(); }
    diff --git a/langtools/test/tools/javac/parser/SingleCommaAnnotationValueFail.out b/langtools/test/tools/javac/parser/SingleCommaAnnotationValueFail.out
    new file mode 100644
    index 00000000000..10a8f4dce7c
    --- /dev/null
    +++ b/langtools/test/tools/javac/parser/SingleCommaAnnotationValueFail.out
    @@ -0,0 +1,6 @@
    +SingleCommaAnnotationValueFail.java:34:12: compiler.err.expected: '}'
    +SingleCommaAnnotationValueFail.java:34:13: compiler.err.illegal.start.of.type
    +SingleCommaAnnotationValueFail.java:34:14: compiler.err.expected: token.identifier
    +SingleCommaAnnotationValueFail.java:34:15: compiler.err.expected: ';'
    +SingleCommaAnnotationValueFail.java:34:21: compiler.err.invalid.meth.decl.ret.type.req
    +5 errors
    diff --git a/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java b/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java
    index 71367233484..6ba6ff689e6 100644
    --- a/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java
    +++ b/langtools/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java
    @@ -30,11 +30,13 @@
      * @build   JavacTestingAbstractProcessor
      * @compile TestElementsAnnotatedWith.java
      * @compile InheritedAnnotation.java
    + * @compile TpAnno.java
      * @compile -processor TestElementsAnnotatedWith -proc:only SurfaceAnnotations.java
      * @compile -processor TestElementsAnnotatedWith -proc:only BuriedAnnotations.java
      * @compile -processor TestElementsAnnotatedWith -proc:only Part1.java Part2.java
      * @compile -processor TestElementsAnnotatedWith -proc:only C2.java
      * @compile -processor TestElementsAnnotatedWith -proc:only Foo.java
    + * @compile -processor TestElementsAnnotatedWith -proc:only TypeParameterAnnotations.java
      * @compile Foo.java
      * @compile/process -processor TestElementsAnnotatedWith -proc:only Foo
      */
    diff --git a/langtools/test/tools/javac/processing/environment/round/TpAnno.java b/langtools/test/tools/javac/processing/environment/round/TpAnno.java
    new file mode 100644
    index 00000000000..c8cf52c30c9
    --- /dev/null
    +++ b/langtools/test/tools/javac/processing/environment/round/TpAnno.java
    @@ -0,0 +1,29 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +import java.lang.annotation.*;
    +import static java.lang.annotation.RetentionPolicy.*;
    +
    +@Retention(RUNTIME)
    +@Target(ElementType.TYPE_PARAMETER)
    +public @interface TpAnno {}
    diff --git a/langtools/test/tools/javac/processing/environment/round/TypeParameterAnnotations.java b/langtools/test/tools/javac/processing/environment/round/TypeParameterAnnotations.java
    new file mode 100644
    index 00000000000..0b3ef05ceef
    --- /dev/null
    +++ b/langtools/test/tools/javac/processing/environment/round/TypeParameterAnnotations.java
    @@ -0,0 +1,37 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * Class to hold annotations for ElementsAnnotatedWithTest.
    + */
    +
    +@AnnotatedElementInfo(annotationName="TpAnno",
    +                      expectedSize=4,
    +                      names={"T", "A", "B", "C"})
    +public class TypeParameterAnnotations<@TpAnno T>  {
    +    private <@TpAnno A> TypeParameterAnnotations(A a) {;}
    +
    +    public <@TpAnno B> void foo(B b) {return;}
    +
    +    public static <@TpAnno C> void bar(C b) {return;}
    +}
    diff --git a/langtools/test/tools/javac/resolve/ResolveHarness.java b/langtools/test/tools/javac/resolve/ResolveHarness.java
    index 8db063cdf09..5f761c3b351 100644
    --- a/langtools/test/tools/javac/resolve/ResolveHarness.java
    +++ b/langtools/test/tools/javac/resolve/ResolveHarness.java
    @@ -32,6 +32,8 @@
     
     import com.sun.source.util.JavacTask;
     import com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper;
    +import com.sun.tools.javac.code.Flags;
    +import com.sun.tools.javac.code.Symbol;
     import com.sun.tools.javac.code.Type.MethodType;
     import com.sun.tools.javac.util.JCDiagnostic;
     
    @@ -154,7 +156,7 @@ public class ResolveHarness implements javax.tools.DiagnosticListener entry : candidatesMap.entrySet()) {
                 if (!seenCandidates.contains(entry.getKey())) {
    -                error("Redundant @Candidate annotation on method " + entry.getKey().elem);
    +                error("Redundant @Candidate annotation on method " + entry.getKey().elem + " sig = " + entry.getKey().elem.asType());
                 }
             }
         }
    @@ -250,7 +252,7 @@ public class ResolveHarness implements javax.tools.DiagnosticListener diagnostic) {
                 Element siteSym = getSiteSym(diagnostic);
                 if (siteSym.getSimpleName().length() != 0 &&
    -                    siteSym.getAnnotation(TraceResolve.class) == null) {
    +                    ((Symbol)siteSym).outermostClass().getAnnotation(TraceResolve.class) == null) {
                     return;
                 }
                 int candidateIdx = 0;
    @@ -308,7 +310,11 @@ public class ResolveHarness implements javax.tools.DiagnosticListener diagnostic) {
    -            Element methodSym = methodSym(diagnostic);
    +            Symbol methodSym = (Symbol)methodSym(diagnostic);
    +            if ((methodSym.flags() & Flags.GENERATEDCONSTR) != 0) {
    +                //skip resolution of default constructor (put there by javac)
    +                return;
    +            }
                 Candidate c = getCandidateAtPos(methodSym,
                         asJCDiagnostic(diagnostic).getLineNumber(),
                         asJCDiagnostic(diagnostic).getColumnNumber());
    @@ -470,23 +476,10 @@ public class ResolveHarness implements javax.tools.DiagnosticListener.");
    -                String replacedName = predefTranslationMap.get(e.getSimpleName().toString());
    -                buf.append(e.toString().replace(e.getSimpleName().toString(), replacedName));
    -            } else if (e.getSimpleName().toString().startsWith("_")) {
    -                buf.append(".");
    -                buf.append(e.toString());
    -            } else {
    -                while (e != null) {
    -                    buf.append(e.toString());
    -                    e = e.getEnclosingElement();
    -                }
    -                buf.append(jfo.getName());
    -            }
    -            return buf.toString();
    +            String simpleName = e.getSimpleName().toString();
    +            String opName = predefTranslationMap.get(simpleName);
    +            String name = opName != null ? opName : simpleName;
    +            return name + e.asType();
             }
     
             @Override
    diff --git a/langtools/test/tools/javac/resolve/tests/AbstractMerge.java b/langtools/test/tools/javac/resolve/tests/AbstractMerge.java
    new file mode 100644
    index 00000000000..e6feb08949b
    --- /dev/null
    +++ b/langtools/test/tools/javac/resolve/tests/AbstractMerge.java
    @@ -0,0 +1,107 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please 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
    +class AbstractMerge {
    +
    +    interface A {
    +        @Candidate(applicable=Phase.BASIC)
    +        java.io.Serializable m1();
    +        @Candidate(applicable=Phase.BASIC)
    +        java.io.Serializable m2();
    +        @Candidate(applicable=Phase.BASIC)
    +        java.io.Serializable m3();
    +        @Candidate(applicable=Phase.BASIC)
    +        java.io.Serializable m4();
    +        @Candidate(applicable=Phase.BASIC)
    +        java.io.Serializable m5();
    +        @Candidate(applicable=Phase.BASIC)
    +        java.io.Serializable m6();
    +    }
    +
    +    interface B {
    +        @Candidate(applicable=Phase.BASIC)
    +        Cloneable m1();
    +        @Candidate(applicable=Phase.BASIC)
    +        Cloneable m2();
    +        @Candidate(applicable=Phase.BASIC)
    +        Cloneable m3();
    +        @Candidate(applicable=Phase.BASIC)
    +        Cloneable m4();
    +        @Candidate(applicable=Phase.BASIC)
    +        Cloneable m5();
    +        @Candidate(applicable=Phase.BASIC)
    +        Cloneable m6();
    +    }
    +
    +    interface C {
    +        @Candidate(applicable=Phase.BASIC, mostSpecific=true)
    +        Object[] m1();
    +        @Candidate(applicable=Phase.BASIC, mostSpecific=true)
    +        Object[] m2();
    +        @Candidate(applicable=Phase.BASIC, mostSpecific=true)
    +        Object[] m3();
    +        @Candidate(applicable=Phase.BASIC, mostSpecific=true)
    +        Object[] m4();
    +        @Candidate(applicable=Phase.BASIC, mostSpecific=true)
    +        Object[] m5();
    +        @Candidate(applicable=Phase.BASIC, mostSpecific=true)
    +        Object[] m6();
    +    }
    +
    +    interface ABC extends A, B, C { }
    +    interface ACB extends A, C, B { }
    +    interface BAC extends B, A, C { }
    +    interface BCA extends B, C, A { }
    +    interface CAB extends C, A, B { }
    +    interface CBA extends C, B, A { }
    +
    +    {
    +        ABC abc = null;
    +        abc.m1();
    +    }
    +
    +    {
    +        ACB acb = null;
    +        acb.m2();
    +    }
    +
    +    {
    +        BAC bac = null;
    +        bac.m3();
    +    }
    +
    +    {
    +        BCA bca = null;
    +        bca.m4();
    +    }
    +
    +    {
    +        CAB cab = null;
    +        cab.m5();
    +    }
    +
    +    {
    +        CBA cba = null;
    +        cba.m6();
    +    }
    +}
    diff --git a/langtools/test/tools/javac/resolve/tests/InnerOverOuter.java b/langtools/test/tools/javac/resolve/tests/InnerOverOuter.java
    index 2574c61ab55..9bf72a3fa53 100644
    --- a/langtools/test/tools/javac/resolve/tests/InnerOverOuter.java
    +++ b/langtools/test/tools/javac/resolve/tests/InnerOverOuter.java
    @@ -21,7 +21,7 @@
      * questions.
      */
     
    -@TraceResolve
    +@TraceResolve(keys={"compiler.err.cant.apply.symbol"})
     class Test {
     
         //no annotation here - this should NOT even be considered!
    @@ -30,7 +30,6 @@ class Test {
         //no annotation here - this should NOT even be considered!
         void m(Object... o) { }
     
    -    @TraceResolve(keys={"compiler.err.cant.apply.symbol"})
         class Inner {
             @Candidate
             void m(String s) {
    diff --git a/langtools/test/tools/javac/types/TestComparisons.java b/langtools/test/tools/javac/types/TestComparisons.java
    new file mode 100644
    index 00000000000..46f267b0401
    --- /dev/null
    +++ b/langtools/test/tools/javac/types/TestComparisons.java
    @@ -0,0 +1,362 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please 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 8013357
    + * @summary javac should correctly enforce binary comparison rules.
    + */
    +import com.sun.tools.javac.code.Type;
    +import com.sun.tools.javac.code.Type.*;
    +import com.sun.tools.javac.code.Symbol.*;
    +import java.io.*;
    +import java.lang.reflect.Array;
    +import java.util.EnumSet;
    +
    +public class TestComparisons {
    +
    +    private int errors = 0;
    +    private int testnum = 0;
    +
    +    static final File testdir = new File("8013357");
    +
    +    private enum CompareType {
    +        BYTE_PRIM("byte"),
    +        SHORT_PRIM("short"),
    +        CHAR_PRIM("char"),
    +        INTEGER_PRIM("int"),
    +        LONG_PRIM("long"),
    +        FLOAT_PRIM("float"),
    +        DOUBLE_PRIM("double"),
    +        BOOLEAN_PRIM("boolean"),
    +
    +        BYTE("Byte"),
    +        SHORT("Short"),
    +        CHAR("Character"),
    +        INTEGER("Integer"),
    +        LONG("Long"),
    +        FLOAT("Float"),
    +        DOUBLE("Double"),
    +        BOOLEAN("Boolean"),
    +
    +        BYTE_SUPER("List", true),
    +        SHORT_SUPER("List", true),
    +        CHAR_SUPER("List", true),
    +        INTEGER_SUPER("List", true),
    +        LONG_SUPER("List", true),
    +        FLOAT_SUPER("List", true),
    +        DOUBLE_SUPER("List", true),
    +        BOOLEAN_SUPER("List", true),
    +
    +        OBJECT("Object"),
    +        NUMBER("Number"),
    +        STRING("String");
    +
    +        public final boolean isList;
    +        public final String name;
    +
    +        private CompareType(final String name, final boolean isList) {
    +            this.isList = isList;
    +            this.name = name;
    +        }
    +
    +        private CompareType(final String name) {
    +            this(name, false);
    +        }
    +    }
    +
    +    // The integers here refer to which subsection of JLS 15.21 is in
    +    // effect.  0 means no comparison is allowed.
    +    private static final int truthtab[][] = {
    +        // byte, comparable to itself, any numeric type, or any boxed
    +        // numeric type.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
    +          0, 0, 0, 0, 0, 0, 0, 0, // Captures
    +          0, 0, 0                 // Reference types
    +        },
    +        // short, comparable to itself, any numeric type, or any boxed
    +        // numeric type.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
    +          0, 0, 0, 0, 0, 0, 0, 0, // Captures
    +          0, 0, 0                 // Reference types
    +        },
    +        // char, comparable to itself, any numeric type, or any boxed
    +        // numeric type.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
    +          0, 0, 0, 0, 0, 0, 0, 0, // Captures
    +          0, 0, 0                 // Reference types
    +        },
    +        // int, comparable to itself, any numeric type, or any boxed
    +        // numeric type.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
    +          0, 0, 0, 0, 0, 0, 0, 0, // Captures
    +          0, 0, 0                 // Reference types
    +        },
    +        // long, comparable to itself, any numeric type, or any boxed
    +        // numeric type.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
    +          0, 0, 0, 0, 0, 0, 0, 0, // Captures
    +          0, 0, 0                 // Reference types
    +        },
    +        // float, comparable to itself, any numeric type, or any boxed
    +        // numeric type.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
    +          0, 0, 0, 0, 0, 0, 0, 0, // Captures
    +          0, 0, 0                 // Reference types
    +        },
    +        // double, comparable to itself, any numeric type, or any boxed
    +        // numeric type.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          1, 1, 1, 1, 1, 1, 1, 0, // Boxed primitives
    +          0, 0, 0, 0, 0, 0, 0, 0, // Captures
    +          0, 0, 0                 // Reference types
    +        },
    +        // boolean, comparable only to itself and Boolean.
    +        { 0, 0, 0, 0, 0, 0, 0, 2, // Primitives
    +          0, 0, 0, 0, 0, 0, 0, 2, // Boxed primitives
    +          0, 0, 0, 0, 0, 0, 0, 0, // Captures
    +          0, 0, 0                 // Reference types
    +        },
    +        // Byte, comparable to itself, Number, Object, any numeric primitive,
    +        // and any captures.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          3, 0, 0, 0, 0, 0, 0, 0, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 0                 // Reference types
    +        },
    +        // Short, comparable to itself, Number, Object, any numeric primitive,
    +        // and any captures.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          0, 3, 0, 0, 0, 0, 0, 0, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 0                 // Reference types
    +        },
    +        // Character, comparable to itself, Object, any numeric primitive,
    +        // and any captures.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          0, 0, 3, 0, 0, 0, 0, 0, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 0, 0                 // Reference types
    +        },
    +        // Int, comparable to itself, Number, Object, any numeric primitive,
    +        // and any captures.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          0, 0, 0, 3, 0, 0, 0, 0, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 0                 // Reference types
    +        },
    +        // Long, comparable to itself, Number, Object, any numeric primitive,
    +        // and any captures.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          0, 0, 0, 0, 3, 0, 0, 0, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 0                 // Reference types
    +        },
    +        // Float, comparable to itself, Number, Object, any numeric primitive,
    +        // and any captures.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          0, 0, 0, 0, 0, 3, 0, 0, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 0                 // Reference types
    +        },
    +        // Double, comparable to itself, Number, Object, any numeric primitive,
    +        // and any captures.
    +        { 1, 1, 1, 1, 1, 1, 1, 0, // Primitives
    +          0, 0, 0, 0, 0, 0, 3, 0, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 0                 // Reference types
    +        },
    +        // Boolean, to itself, any capture, Object, and boolean.
    +        { 0, 0, 0, 0, 0, 0, 0, 2, // Primitives
    +          0, 0, 0, 0, 0, 0, 0, 2, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 0, 0                 // Reference types
    +        },
    +        // Byte supertype wildcard, comparable to any reference type.
    +        // and any captures.
    +        { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 3                 // Reference types
    +        },
    +        // Short supertype wildcard, comparable to any reference type.
    +        // and any captures.
    +        { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 3                 // Reference types
    +        },
    +        // Character supertype wildcard, comparable to any reference type.
    +        // and any captures.
    +        { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 3                 // Reference types
    +        },
    +        // Integer supertype wildcard, comparable to any reference type.
    +        // and any captures.
    +        { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 3                 // Reference types
    +        },
    +        // Long supertype wildcard, comparable to any reference type.
    +        // and any captures.
    +        { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 3                 // Reference types
    +        },
    +        // Float supertype wildcard, comparable to any reference type.
    +        // and any captures.
    +        { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 3                 // Reference types
    +        },
    +        // Double supertype wildcard, comparable to any reference type.
    +        // and any captures.
    +        { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 3                 // Reference types
    +        },
    +        // Boolean supertype wildcard, comparable to any reference type.
    +        // and any captures.
    +        { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 3                 // Reference types
    +        },
    +        // Object, comparable to any reference type.
    +        // and any captures.
    +        { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 3                 // Reference types
    +        },
    +        // Number, comparable to Object, any of its subclasses.
    +        // and any captures.
    +        { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
    +          3, 3, 0, 3, 3, 3, 3, 0, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 3, 0                 // Reference types
    +        },
    +        // String supertype wildcard, comparable to any reference type.
    +        // and any captures.
    +        { 0, 0, 0, 0, 0, 0, 0, 0, // Primitives
    +          0, 0, 0, 0, 0, 0, 0, 0, // Boxed primitives
    +          3, 3, 3, 3, 3, 3, 3, 3, // Captures
    +          3, 0, 3                 // Reference types
    +        }
    +    };
    +
    +    private void assert_compile_fail(final File file, final String body) {
    +        final String filename = file.getPath();
    +        final String[] args = { filename };
    +        final StringWriter sw = new StringWriter();
    +        final PrintWriter pw = new PrintWriter(sw);
    +        final int rc = com.sun.tools.javac.Main.compile(args, pw);
    +        pw.close();
    +        if (rc == 0) {
    +            System.err.println("Compilation of " + file.getName() +
    +                               " didn't fail as expected.\nFile:\n" +
    +                               body + "\nOutput:\n" + sw.toString());
    +            errors++;
    +        }
    +    }
    +
    +    private void assert_compile_succeed(final File file, final String body) {
    +        final String filename = file.getPath();
    +        final String[] args = { filename };
    +        final StringWriter sw = new StringWriter();
    +        final PrintWriter pw = new PrintWriter(sw);
    +        final int rc = com.sun.tools.javac.Main.compile(args, pw);
    +        pw.close();
    +        if (rc != 0) {
    +            System.err.println("Compilation of " + file.getName() +
    +                               " didn't succeed as expected.\nFile:\n" +
    +                               body + "\nOutput:\n" +
    +                               sw.toString());
    +            errors++;
    +        }
    +    }
    +
    +    private String makeBody(final int num,
    +                            final CompareType left,
    +                            final CompareType right) {
    +        return "import java.util.List;\n" +
    +            "public class Test" + num + " {\n" +
    +            "    public boolean test(" + left.name +
    +            " left, " + right.name + " right) {\n" +
    +            "        return left" + (left.isList ? ".get(0)" : "") +
    +            " == right" + (right.isList ? ".get(0)" : "") + ";\n" +
    +            "    }\n" +
    +            "}\n";
    +    }
    +
    +    private File writeFile(final String filename,
    +                           final String body)
    +        throws IOException {
    +        final File f = new File(testdir, filename);
    +        f.getParentFile().mkdirs();
    +        final FileWriter out = new FileWriter(f);
    +        out.write(body);
    +        out.close();
    +        return f;
    +    }
    +
    +    private void test(final CompareType left, final CompareType right)
    +        throws IOException {
    +        final int num = testnum++;
    +        final String filename = "Test" + num + ".java";
    +        final String body = makeBody(num, left, right);
    +        final File file = writeFile(filename, body);
    +        if (truthtab[left.ordinal()][right.ordinal()] != 0)
    +            assert_compile_succeed(file, body);
    +        else
    +            assert_compile_fail(file, body);
    +    }
    +
    +    void run() throws Exception {
    +        testdir.mkdir();
    +
    +        for(CompareType left : CompareType.values())
    +            for(CompareType right : CompareType.values())
    +                test(left, right);
    +
    +        if (errors != 0)
    +            throw new Exception("ObjectZeroCompare test failed with " +
    +                                errors + " errors.");
    +    }
    +
    +    public static void main(String... args) throws Exception {
    +        new TestComparisons().run();
    +    }
    +}
    diff --git a/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAnotherAuxiliary.java b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAnotherAuxiliary.java
    index 07ed640a415..d5c3660fb72 100644
    --- a/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAnotherAuxiliary.java
    +++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAnotherAuxiliary.java
    @@ -23,6 +23,7 @@
     
     /**
      * @test
    + * @bug 7153951
      * @compile ClassUsingAnotherAuxiliary.java NotAClassName.java
      * @compile -Xlint:auxiliaryclass ClassUsingAnotherAuxiliary.java NotAClassName.java
      * @compile/fail/ref=ClassUsingAnotherAuxiliary.out -XDrawDiagnostics -Werror -Xlint:auxiliaryclass ClassUsingAnotherAuxiliary.java NotAClassName.java
    diff --git a/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAnotherAuxiliary.out b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAnotherAuxiliary.out
    index 57123508721..5df6bdb1b0d 100644
    --- a/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAnotherAuxiliary.out
    +++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAnotherAuxiliary.out
    @@ -1,4 +1,4 @@
    -ClassUsingAnotherAuxiliary.java:32:5: compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file: AnAuxiliaryClass, NotAClassName.java
    +ClassUsingAnotherAuxiliary.java:33:5: compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file: AnAuxiliaryClass, NotAClassName.java
     - compiler.err.warnings.and.werror
     1 error
     1 warning
    diff --git a/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary.java b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary.java
    index 9d22ba780e7..605eb8017cb 100644
    --- a/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary.java
    +++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary.java
    @@ -23,6 +23,7 @@
     
     /**
      * @test
    + * @bug 7153951
      * @clean ClassUsingAuxiliary ClassWithAuxiliary AuxiliaryClass ClassWithAuxiliary$NotAnAuxiliaryClass ClassWithAuxiliary$NotAnAuxiliaryClassEither
      * @run compile ClassUsingAuxiliary.java ClassWithAuxiliary.java
      * @run compile/fail/ref=ClassUsingAuxiliary1.out -XDrawDiagnostics -Werror -Xlint:auxiliaryclass ClassUsingAuxiliary.java ClassWithAuxiliary.java
    diff --git a/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary1.out b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary1.out
    index e0f30900377..d319c0b08e3 100644
    --- a/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary1.out
    +++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary1.out
    @@ -1,4 +1,4 @@
    -ClassUsingAuxiliary.java:33:5: compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file: AuxiliaryClass, ClassWithAuxiliary.java
    +ClassUsingAuxiliary.java:34:5: compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file: AuxiliaryClass, ClassWithAuxiliary.java
     - compiler.err.warnings.and.werror
     1 error
     1 warning
    diff --git a/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary2.out b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary2.out
    index e0f30900377..d319c0b08e3 100644
    --- a/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary2.out
    +++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary2.out
    @@ -1,4 +1,4 @@
    -ClassUsingAuxiliary.java:33:5: compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file: AuxiliaryClass, ClassWithAuxiliary.java
    +ClassUsingAuxiliary.java:34:5: compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file: AuxiliaryClass, ClassWithAuxiliary.java
     - compiler.err.warnings.and.werror
     1 error
     1 warning
    diff --git a/langtools/test/tools/javac/warnings/AuxiliaryClass/SelfClassWithAux.java b/langtools/test/tools/javac/warnings/AuxiliaryClass/SelfClassWithAux.java
    index fdc5a8fad71..398315dcb4b 100644
    --- a/langtools/test/tools/javac/warnings/AuxiliaryClass/SelfClassWithAux.java
    +++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/SelfClassWithAux.java
    @@ -29,16 +29,17 @@
     
     /*
      * @test
    + * @bug 7153951
      * @run compile -Werror -Xlint:auxiliaryclass SelfClassWithAux.java ClassWithAuxiliary.java
      * @run compile -Werror -Xlint:auxiliaryclass SelfClassWithAux.java
      */
     
     class SelfClassWithAux {
    -    Aux aux;
    +    AuxClass aux;
         ClassWithAuxiliary.NotAnAuxiliaryClass alfa;
         ClassWithAuxiliary.NotAnAuxiliaryClassEither beta;
     }
     
    -class Aux {
    -    Aux aux;
    +class AuxClass {
    +    AuxClass aux;
     }
    diff --git a/nashorn/.hgtags b/nashorn/.hgtags
    index d23a6e85666..cbbd166c330 100644
    --- a/nashorn/.hgtags
    +++ b/nashorn/.hgtags
    @@ -206,3 +206,4 @@ ddbf41575a2bdb12ccb9f91e169018bf04073038 jdk8-b93
     d92b756bc73966f1bfd111f44f3216cea3bba129 jdk8-b94
     cbc9926f5b40a24025c1e15d8870157d651a9ff7 jdk8-b95
     d6bd440ac5b97bb1205b6c3274569c1cfe626723 jdk8-b96
    +1bf1d6ce30427e1f9dc1ada18db409d1f14d99fe jdk8-b97
    diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java
    index 808f2658046..bc6bb4b2db2 100644
    --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java
    +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java
    @@ -166,11 +166,11 @@ public class ClassGenerator {
             mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC);
             mi.loadClass(className);
             mi.invokeStatic(MAP_TYPE, MAP_NEWMAP, MAP_NEWMAP_DESC);
    -        mi.storeLocal(0);
    +        // stack: PropertyMap
         }
     
         static void emitStaticInitSuffix(final MethodGenerator mi, final String className) {
    -        mi.loadLocal(0);
    +        // stack: PropertyMap
             mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC);
             mi.returnVoid();
             mi.computeMaxs();
    @@ -278,7 +278,7 @@ public class ClassGenerator {
     
         static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) {
             final String propertyName = memInfo.getName();
    -        mi.loadLocal(0);
    +        // stack: PropertyMap
             mi.loadLiteral(propertyName);
             // setup flags
             mi.push(memInfo.getAttributes());
    @@ -293,12 +293,12 @@ public class ClassGenerator {
                 mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, setterDesc(memInfo)));
             }
             mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC);
    -        mi.storeLocal(0);
    +        // stack: PropertyMap
         }
     
         static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo getter, final MemberInfo setter) {
             final String propertyName = getter.getName();
    -        mi.loadLocal(0);
    +        // stack: PropertyMap
             mi.loadLiteral(propertyName);
             // setup flags
             mi.push(getter.getAttributes());
    @@ -313,7 +313,7 @@ public class ClassGenerator {
                         setter.getJavaName(), setter.getJavaDesc()));
             }
             mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC);
    -        mi.storeLocal(0);
    +        // stack: PropertyMap
         }
     
         static ScriptClassInfo getScriptClassInfo(final String fileName) throws IOException {
    diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java
    index d140585f499..ffeb90bea3e 100644
    --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java
    +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java
    @@ -159,10 +159,14 @@ public class ScriptClassInstrumentor extends ClassVisitor {
                 public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
                     if (isConstructor && opcode == INVOKESPECIAL &&
                             INIT.equals(name) && SCRIPTOBJECT_TYPE.equals(owner)) {
    -                    super.visitFieldInsn(GETSTATIC, scriptClassInfo.getJavaName(),
    -                            MAP_FIELD_NAME, MAP_DESC);
    -                    super.visitMethodInsn(INVOKESPECIAL, SCRIPTOBJECT_TYPE, INIT,
    -                            SCRIPTOBJECT_INIT_DESC);
    +
    +                    // replace call to empty super-constructor with one passing PropertyMap argument
    +                    if (DEFAULT_INIT_DESC.equals(desc)) {
    +                        super.visitFieldInsn(GETSTATIC, scriptClassInfo.getJavaName(), MAP_FIELD_NAME, MAP_DESC);
    +                        super.visitMethodInsn(INVOKESPECIAL, SCRIPTOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC);
    +                    } else {
    +                        super.visitMethodInsn(opcode, owner, name, desc);
    +                    }
     
                         if (memberCount > 0) {
                             // initialize @Property fields if needed
    @@ -223,7 +227,7 @@ public class ScriptClassInstrumentor extends ClassVisitor {
                     ClassGenerator.addSetter(cv, className, memInfo);
                 }
             }
    -        ClassGenerator.addMapField(this);
    +        // omit addMapField() since instance classes already define a static PropertyMap field
         }
     
         void emitGettersSetters() {
    diff --git a/nashorn/docs/JavaScriptingProgrammersGuide.html b/nashorn/docs/JavaScriptingProgrammersGuide.html
    index a9803f7fd81..18ae823d82e 100644
    --- a/nashorn/docs/JavaScriptingProgrammersGuide.html
    +++ b/nashorn/docs/JavaScriptingProgrammersGuide.html
    @@ -227,6 +227,16 @@ access the variable - for example, it can call public methods on
     it. Note that the syntax to access Java objects, methods and fields
     is dependent on the scripting language. JavaScript supports the
     most "natural" Java-like syntax.

    +

    +Nashorn script engine pre-defines two global variables named "context" +and "engine". The "context" variable is of type javax.script.ScriptContext +and refers to the current ScriptContext instance passed to script engine's +eval method. The "engine" variable is of type javax.script.ScriptEngine and +refers to the current nashorn script engine instance evaluating the script. +Both of these variables are non-writable, non-enumerable and non-configurable +- which implies script code can not write overwrite the value, for..loop iteration +on global object will not iterate these variables and these variables can not be +deleted by script.

    
     // ScriptVars.java
     
    diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml
    index 7c05e789fe9..7e2d999d328 100644
    --- a/nashorn/make/build.xml
    +++ b/nashorn/make/build.xml
    @@ -124,7 +124,7 @@
         
       
     
    -  
    +  
         
           
           
    @@ -139,7 +139,13 @@
           
         
       
    -  
    +
    +  
    +    
    +    
    +    
    +  
    +
       
         Builds the javafx shell.
         
    @@ -238,7 +244,7 @@
         
         
         
    -    
    +
         
         
         
    @@ -462,24 +468,24 @@
       
       
         
    -     
    +    
     
         
    -        
    +    
         
         
     
         
    -        
    +    
         
     
         
    -     
    +    
         
         
     
         
    -     
    +    
         
         
     
    diff --git a/nashorn/src/jdk/nashorn/api/scripting/JSObject.java b/nashorn/src/jdk/nashorn/api/scripting/JSObject.java
    index 583e8f7a199..4f3a8e88f93 100644
    --- a/nashorn/src/jdk/nashorn/api/scripting/JSObject.java
    +++ b/nashorn/src/jdk/nashorn/api/scripting/JSObject.java
    @@ -30,13 +30,23 @@ package jdk.nashorn.api.scripting;
      */
     public abstract class JSObject {
         /**
    -     * Call a JavaScript method
    +     * Call a JavaScript function
          *
    -     * @param methodName name of method
    +     * @param functionName name of function
          * @param args arguments to method
          * @return result of call
          */
    -    public abstract Object call(String methodName, Object args[]);
    +    public abstract Object call(String functionName, Object... args);
    +
    +    /**
    +     * Call a JavaScript method as a constructor. This is equivalent to
    +     * calling new obj.Method(arg1, arg2...) in JavaScript.
    +     *
    +     * @param functionName name of function
    +     * @param args arguments to method
    +     * @return result of constructor call
    +     */
    +    public abstract Object newObject(String functionName, Object... args);
     
         /**
          * Evaluate a JavaScript expression
    diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornException.java b/nashorn/src/jdk/nashorn/api/scripting/NashornException.java
    index d1d47b1dc08..3cd687cce08 100644
    --- a/nashorn/src/jdk/nashorn/api/scripting/NashornException.java
    +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornException.java
    @@ -25,6 +25,9 @@
     
     package jdk.nashorn.api.scripting;
     
    +import java.util.ArrayList;
    +import java.util.List;
    +import jdk.nashorn.internal.codegen.CompilerConstants;
     import jdk.nashorn.internal.runtime.ECMAErrors;
     
     /**
    @@ -136,4 +139,53 @@ public abstract class NashornException extends RuntimeException {
             return column;
         }
     
    +    /**
    +     * Returns array javascript stack frames from the given exception object.
    +     *
    +     * @param exception exception from which stack frames are retrieved and filtered
    +     * @return array of javascript stack frames
    +     */
    +    public static StackTraceElement[] getScriptFrames(final Throwable exception) {
    +        final StackTraceElement[] frames = ((Throwable)exception).getStackTrace();
    +        final List filtered = new ArrayList<>();
    +        for (final StackTraceElement st : frames) {
    +            if (ECMAErrors.isScriptFrame(st)) {
    +                final String className = "<" + st.getFileName() + ">";
    +                String methodName = st.getMethodName();
    +                if (methodName.equals(CompilerConstants.RUN_SCRIPT.symbolName())) {
    +                    methodName = "";
    +                }
    +                filtered.add(new StackTraceElement(className, methodName,
    +                        st.getFileName(), st.getLineNumber()));
    +            }
    +        }
    +        return filtered.toArray(new StackTraceElement[filtered.size()]);
    +    }
    +
    +    /**
    +     * Return a formatted script stack trace string with frames information separated by '\n'
    +     *
    +     * @param exception exception for which script stack string is returned
    +     * @return formatted stack trace string
    +     */
    +    public static String getScriptStackString(final Throwable exception) {
    +        final StringBuilder buf = new StringBuilder();
    +        final StackTraceElement[] frames = getScriptFrames((Throwable)exception);
    +        for (final StackTraceElement st : frames) {
    +            buf.append("\tat ");
    +            buf.append(st.getMethodName());
    +            buf.append(" (");
    +            buf.append(st.getFileName());
    +            buf.append(':');
    +            buf.append(st.getLineNumber());
    +            buf.append(")\n");
    +        }
    +        final int len = buf.length();
    +        // remove trailing '\n'
    +        if (len > 0) {
    +            assert buf.charAt(len - 1) == '\n';
    +            buf.deleteCharAt(len - 1);
    +        }
    +        return buf.toString();
    +    }
     }
    diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
    index b05a4aee435..d38e63c88b8 100644
    --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
    +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
    @@ -71,6 +71,9 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
         private final ScriptEngineFactory factory;
         private final Context             nashornContext;
         private final ScriptObject        global;
    +    // initialized bit late to be made 'final'. Property object for "context"
    +    // property of global object
    +    private Property                  contextProperty;
     
         // default options passed to Nashorn Options object
         private static final String[] DEFAULT_OPTIONS = new String[] { "-scripting", "-doe" };
    @@ -281,13 +284,16 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
     
             nashornContext.initGlobal(newGlobal);
     
    +        final int NON_ENUMERABLE_CONSTANT = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE;
             // current ScriptContext exposed as "context"
    -        newGlobal.addOwnProperty("context", Property.NOT_ENUMERABLE, UNDEFINED);
    +        // "context" is non-writable from script - but script engine still
    +        // needs to set it and so save the context Property object
    +        contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, UNDEFINED);
             // current ScriptEngine instance exposed as "engine". We added @SuppressWarnings("LeakingThisInConstructor") as
             // NetBeans identifies this assignment as such a leak - this is a false positive as we're setting this property
             // in the Global of a Context we just created - both the Context and the Global were just created and can not be
             // seen from another thread outside of this constructor.
    -        newGlobal.addOwnProperty("engine", Property.NOT_ENUMERABLE, this);
    +        newGlobal.addOwnProperty("engine", NON_ENUMERABLE_CONSTANT, this);
             // global script arguments with undefined value
             newGlobal.addOwnProperty("arguments", Property.NOT_ENUMERABLE, UNDEFINED);
             // file name default is null
    @@ -322,9 +328,10 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
     
         // scripts should see "context" and "engine" as variables
         private void setContextVariables(final ScriptContext ctxt) {
    -        ctxt.setAttribute("context", ctxt, ScriptContext.ENGINE_SCOPE);
             final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
    -        ctxtGlobal.set("context", ctxt, false);
    +        // set "context" global variable via contextProperty - because this
    +        // property is non-writable
    +        contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false);
             Object args = ScriptObjectMirror.unwrap(ctxt.getAttribute("arguments"), ctxtGlobal);
             if (args == null || args == UNDEFINED) {
                 args = ScriptRuntime.EMPTY_ARRAY;
    diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
    index 79e908db5d2..c7dbab5a184 100644
    --- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
    +++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
    @@ -102,7 +102,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
     
         // JSObject methods
         @Override
    -    public Object call(final String methodName, final Object args[]) {
    +    public Object call(final String functionName, final Object... args) {
             final ScriptObject oldGlobal = NashornScriptEngine.getNashornGlobal();
             final boolean globalChanged = (oldGlobal != global);
     
    @@ -111,9 +111,9 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
                     NashornScriptEngine.setNashornGlobal(global);
                 }
     
    -            final Object val = sobj.get(methodName);
    +            final Object val = functionName == null? sobj : sobj.get(functionName);
                 if (! (val instanceof ScriptFunction)) {
    -                throw new RuntimeException("No such method: " + methodName);
    +                throw new RuntimeException("No such function " + ((functionName != null)? functionName : ""));
                 }
     
                 final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
    @@ -129,6 +129,34 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
             }
         }
     
    +    @Override
    +    public Object newObject(final String functionName, final Object... args) {
    +        final ScriptObject oldGlobal = NashornScriptEngine.getNashornGlobal();
    +        final boolean globalChanged = (oldGlobal != global);
    +
    +        try {
    +            if (globalChanged) {
    +                NashornScriptEngine.setNashornGlobal(global);
    +            }
    +
    +            final Object val = functionName == null? sobj : sobj.get(functionName);
    +            if (! (val instanceof ScriptFunction)) {
    +                throw new RuntimeException("not a constructor " + ((functionName != null)? functionName : ""));
    +            }
    +
    +            final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
    +            return wrap(ScriptRuntime.checkAndConstruct((ScriptFunction)val, unwrapArray(modArgs, global)), global);
    +        } catch (final RuntimeException | Error e) {
    +            throw e;
    +        } catch (final Throwable t) {
    +            throw new RuntimeException(t);
    +        } finally {
    +            if (globalChanged) {
    +                NashornScriptEngine.setNashornGlobal(oldGlobal);
    +            }
    +        }
    +    }
    +
         @Override
         public Object eval(final String s) {
             return inGlobal(new Callable() {
    diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java
    index 2d379183fd5..09c6a0651cb 100644
    --- a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java
    +++ b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java
    @@ -165,7 +165,8 @@ public class ClassEmitter implements Emitter {
         /**
          * Constructor from the compiler
          *
    -     * @param compiler      Compiler
    +     * @param env           Script environment
    +     * @param sourceName    Source name
          * @param unitClassName Compile unit class name.
          * @param strictMode    Should we generate this method in strict mode
          */
    diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
    index e66e288801d..414d1bb8bc3 100644
    --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
    +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
    @@ -244,7 +244,7 @@ final class CodeGenerator extends NodeOperatorVisitor, BytecodeOps {
     
             @Override
             public Type aload(final MethodVisitor method) {
    -            method.visitInsn(IALOAD);
    -            return INT;
    +            method.visitInsn(LALOAD);
    +            return LONG;
             }
     
             @Override
             public Type newarray(final MethodVisitor method) {
    -            method.visitIntInsn(NEWARRAY, T_INT);
    +            method.visitIntInsn(NEWARRAY, T_LONG);
                 return this;
             }
     
             @Override
             public Type getElementType() {
    -            return INT;
    +            return LONG;
             }
         };
     
    diff --git a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
    index c34f9d94c5b..a7cea66a256 100644
    --- a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
    +++ b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
    @@ -621,8 +621,10 @@ public abstract class LiteralNode extends Node implements PropertyKey {
                 elementType = Type.INT;
                 analyzeElements();
     
    -            if (elementType == Type.INT) {
    +            if (elementType.isInteger()) {
                     presetIntArray();
    +            } else if (elementType.isLong()) {
    +                presetLongArray();
                 } else if (elementType.isNumeric()) {
                     presetNumberArray();
                 } else {
    @@ -649,6 +651,25 @@ public abstract class LiteralNode extends Node implements PropertyKey {
                 postsets = Arrays.copyOf(computed, nComputed);
             }
     
    +        private void presetLongArray() {
    +            final long[] array = new long[value.length];
    +            final int[] computed = new int[value.length];
    +            int nComputed = 0;
    +
    +            for (int i = 0; i < value.length; i++) {
    +                final Object element = objectAsConstant(value[i]);
    +
    +                if (element instanceof Number) {
    +                    array[i] = ((Number)element).longValue();
    +                } else {
    +                    computed[nComputed++] = i;
    +                }
    +            }
    +
    +            presets = array;
    +            postsets = Arrays.copyOf(computed, nComputed);
    +        }
    +
             private void presetNumberArray() {
                 final double[] array = new double[value.length];
                 final int[] computed = new int[value.length];
    @@ -746,6 +767,8 @@ public abstract class LiteralNode extends Node implements PropertyKey {
             public Type getType() {
                 if (elementType.isInteger()) {
                     return Type.INT_ARRAY;
    +            } else if (elementType.isLong()) {
    +                return Type.LONG_ARRAY;
                 } else if (elementType.isNumeric()) {
                     return Type.NUMBER_ARRAY;
                 } else {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java b/nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java
    index 59660ae6b85..d2d80b2f5a8 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java
    @@ -34,6 +34,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.runtime.JSType;
     import jdk.nashorn.internal.runtime.PropertyDescriptor;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptFunction;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.ScriptRuntime;
    @@ -63,16 +64,19 @@ public final class AccessorPropertyDescriptor extends ScriptObject implements Pr
         @Property
         public Object set;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         AccessorPropertyDescriptor() {
             this(false, false, UNDEFINED, UNDEFINED);
         }
     
         AccessorPropertyDescriptor(final boolean configurable, final boolean enumerable, final Object get, final Object set) {
    +        super(Global.objectPrototype(), $nasgenmap$);
             this.configurable = configurable;
             this.enumerable   = enumerable;
             this.get          = get;
             this.set          = set;
    -        setProto(Global.objectPrototype());
         }
     
         @Override
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
    index 2011daebb33..312d521c65e 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
    @@ -29,6 +29,7 @@ import jdk.nashorn.internal.objects.annotations.Attribute;
     import jdk.nashorn.internal.objects.annotations.Getter;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.ScriptRuntime;
     import jdk.nashorn.internal.runtime.arrays.ArrayData;
    @@ -38,6 +39,9 @@ import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
     @ScriptClass("ArrayBufferView")
     abstract class ArrayBufferView extends ScriptObject {
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
             checkConstructorArgs(buffer, byteOffset, elementLength);
             this.setProto(getPrototype());
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java b/nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java
    index 7ce4d85e534..8ac4397712e 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java
    @@ -33,6 +33,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.runtime.JSType;
     import jdk.nashorn.internal.runtime.PropertyDescriptor;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptFunction;
     import jdk.nashorn.internal.runtime.ScriptObject;
     
    @@ -61,16 +62,19 @@ public final class DataPropertyDescriptor extends ScriptObject implements Proper
         @Property
         public Object value;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         DataPropertyDescriptor() {
             this(false, false, false, UNDEFINED);
         }
     
         DataPropertyDescriptor(final boolean configurable, final boolean enumerable, final boolean writable, final Object value) {
    +        super(Global.objectPrototype(), $nasgenmap$);
             this.configurable = configurable;
             this.enumerable   = enumerable;
             this.writable     = writable;
             this.value        = value;
    -        setProto(Global.objectPrototype());
         }
     
     
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java b/nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java
    index 8f2be7c8cee..d6e9cf6058f 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java
    @@ -30,6 +30,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.runtime.JSType;
     import jdk.nashorn.internal.runtime.PropertyDescriptor;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptFunction;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.ScriptRuntime;
    @@ -51,14 +52,17 @@ public final class GenericPropertyDescriptor extends ScriptObject implements Pro
         @Property
         public Object enumerable;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         GenericPropertyDescriptor() {
             this(false, false);
         }
     
         GenericPropertyDescriptor(final boolean configurable, final boolean enumerable) {
    +        super(Global.objectPrototype(), $nasgenmap$);
             this.configurable = configurable;
             this.enumerable   = enumerable;
    -        setProto(Global.objectPrototype());
         }
     
         @Override
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java
    index 59a9dd34a20..5644c510642 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/Global.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java
    @@ -25,9 +25,9 @@
     
     package jdk.nashorn.internal.objects;
     
    +import static jdk.nashorn.internal.lookup.Lookup.MH;
     import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
     import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
    -import static jdk.nashorn.internal.lookup.Lookup.MH;
     
     import java.io.IOException;
     import java.io.PrintWriter;
    @@ -43,6 +43,7 @@ import java.util.List;
     import java.util.Map;
     import jdk.internal.dynalink.linker.GuardedInvocation;
     import jdk.internal.dynalink.linker.LinkRequest;
    +import jdk.nashorn.internal.lookup.MethodHandleFactory;
     import jdk.nashorn.internal.objects.annotations.Attribute;
     import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
    @@ -52,8 +53,10 @@ import jdk.nashorn.internal.runtime.GlobalFunctions;
     import jdk.nashorn.internal.runtime.GlobalObject;
     import jdk.nashorn.internal.runtime.JSType;
     import jdk.nashorn.internal.runtime.NativeJavaPackage;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptEnvironment;
     import jdk.nashorn.internal.runtime.PropertyDescriptor;
    +import jdk.nashorn.internal.runtime.arrays.ArrayData;
     import jdk.nashorn.internal.runtime.regexp.RegExpResult;
     import jdk.nashorn.internal.runtime.Scope;
     import jdk.nashorn.internal.runtime.ScriptFunction;
    @@ -378,6 +381,9 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
     
         private final Context context;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         /**
          * Constructor
          *
    @@ -483,7 +489,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
     
         @Override
         public ScriptObject newObject() {
    -        return newEmptyInstance();
    +        return new JO(getObjectPrototype());
         }
     
         @Override
    @@ -1241,7 +1247,17 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
          * @return the new array
          */
         public static NativeArray allocate(final Object[] initial) {
    -        return new NativeArray(initial);
    +        ArrayData arrayData = ArrayData.allocate(initial);
    +
    +        for (int index = 0; index < initial.length; index++) {
    +            final Object value = initial[index];
    +
    +            if (value == ScriptRuntime.EMPTY) {
    +                arrayData = arrayData.delete(index);
    +            }
    +        }
    +
    +        return new NativeArray(arrayData);
         }
     
         /**
    @@ -1251,7 +1267,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
          * @return the new array
          */
         public static NativeArray allocate(final double[] initial) {
    -        return new NativeArray(initial);
    +        return new NativeArray(ArrayData.allocate(initial));
         }
     
         /**
    @@ -1261,7 +1277,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
          * @return the new array
          */
         public static NativeArray allocate(final long[] initial) {
    -        return new NativeArray(initial);
    +        return new NativeArray(ArrayData.allocate(initial));
         }
     
         /**
    @@ -1271,7 +1287,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
          * @return the new array
          */
         public static NativeArray allocate(final int[] initial) {
    -        return new NativeArray(initial);
    +        return new NativeArray(ArrayData.allocate(initial));
         }
     
         /**
    @@ -1328,9 +1344,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
          * @return New empty object.
          */
         public static ScriptObject newEmptyInstance() {
    -        final ScriptObject sobj = new JO();
    -        sobj.setProto(objectPrototype());
    -        return sobj;
    +        return Global.instance().newObject();
         }
     
         /**
    @@ -1544,7 +1558,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
             addOwnProperty("echo", Attribute.NOT_ENUMERABLE, value);
     
             // Nashorn extension: global.$OPTIONS (scripting-mode-only)
    -        final ScriptObject options = newEmptyInstance();
    +        final ScriptObject options = newObject();
             final ScriptEnvironment scriptEnv = context.getEnv();
             copyOptions(options, scriptEnv);
             addOwnProperty("$OPTIONS", Attribute.NOT_ENUMERABLE, options);
    @@ -1553,7 +1567,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
             if (System.getSecurityManager() == null) {
                 // do not fill $ENV if we have a security manager around
                 // Retrieve current state of ENV variables.
    -            final ScriptObject env = newEmptyInstance();
    +            final ScriptObject env = newObject();
                 env.putAll(System.getenv());
                 addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, env);
             } else {
    @@ -1780,7 +1794,11 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
     
     
         private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) {
    -        return MH.findStatic(MethodHandles.publicLookup(), Global.class, name, MH.type(rtype, types));
    +        try {
    +            return MethodHandles.lookup().findStatic(Global.class, name, MH.type(rtype, types));
    +        } catch (final NoSuchMethodException | IllegalAccessException e) {
    +            throw new MethodHandleFactory.LookupException(e);
    +        }
         }
     
         RegExpResult getLastRegExpResult() {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
    index d92d7fb3ee7..456284d8cfe 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
    @@ -25,9 +25,9 @@
     
     package jdk.nashorn.internal.objects;
     
    +import static jdk.nashorn.internal.lookup.Lookup.MH;
     import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
     import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
    -import static jdk.nashorn.internal.lookup.Lookup.MH;
     
     import java.lang.invoke.MethodHandle;
     import java.lang.invoke.MethodHandles;
    @@ -42,6 +42,7 @@ import jdk.nashorn.internal.runtime.ScriptRuntime;
     import jdk.nashorn.internal.runtime.arrays.ArrayData;
     import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
     import jdk.nashorn.internal.lookup.Lookup;
    +import jdk.nashorn.internal.lookup.MethodHandleFactory;
     
     /**
      * ECMA 10.6 Arguments Object.
    @@ -60,13 +61,13 @@ public final class NativeArguments extends ScriptObject {
         private static final MethodHandle G$CALLEE = findOwnMH("G$callee", Object.class, Object.class);
         private static final MethodHandle S$CALLEE = findOwnMH("S$callee", void.class, Object.class, Object.class);
     
    -    private static final PropertyMap nasgenmap$;
    +    private static final PropertyMap map$;
     
         static {
             PropertyMap map = PropertyMap.newMap(NativeArguments.class);
             map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH);
             map = Lookup.newProperty(map, "callee", Property.NOT_ENUMERABLE, G$CALLEE, S$CALLEE);
    -        nasgenmap$ = map;
    +        map$ = map;
         }
     
         private Object length;
    @@ -75,8 +76,8 @@ public final class NativeArguments extends ScriptObject {
         // This is lazily initialized - only when delete is invoked at all
         private BitSet deleted;
     
    -    NativeArguments(final Object[] arguments, final Object callee, final int numParams) {
    -        super(nasgenmap$);
    +    NativeArguments(final ScriptObject proto, final Object[] arguments, final Object callee, final int numParams) {
    +        super(proto, map$);
             setIsArguments();
     
             setArray(ArrayData.allocate(arguments));
    @@ -101,9 +102,6 @@ public final class NativeArguments extends ScriptObject {
             }
             System.arraycopy(arguments, 0, newValues, 0, Math.min(newValues.length, arguments.length));
             this.namedArgs = ArrayData.allocate(newValues);
    -
    -        // set Object.prototype as __proto__
    -        this.setProto(Global.objectPrototype());
         }
     
         @Override
    @@ -125,7 +123,7 @@ public final class NativeArguments extends ScriptObject {
         @Override
         public void setArgument(final int key, final Object value) {
             if (namedArgs.has(key)) {
    -            namedArgs.set(key, value, false);
    +            namedArgs = namedArgs.set(key, value, false);
             }
         }
     
    @@ -552,7 +550,8 @@ public final class NativeArguments extends ScriptObject {
         public static ScriptObject allocate(final Object[] arguments, final ScriptFunction callee, final int numParams) {
             // Strict functions won't always have a callee for arguments, and will pass null instead.
             final boolean isStrict = callee == null || callee.isStrict();
    -        return isStrict ? new NativeStrictArguments(arguments, numParams) : new NativeArguments(arguments, callee, numParams);
    +        final ScriptObject proto = Global.objectPrototype();
    +        return isStrict ? new NativeStrictArguments(proto, arguments, numParams) : new NativeArguments(proto, arguments, callee, numParams);
         }
     
         /**
    @@ -624,7 +623,11 @@ public final class NativeArguments extends ScriptObject {
         }
     
         private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) {
    -        return MH.findStatic(MethodHandles.publicLookup(), NativeArguments.class, name, MH.type(rtype, types));
    +        try {
    +            return MethodHandles.lookup().findStatic(NativeArguments.class, name, MH.type(rtype, types));
    +        } catch (final NoSuchMethodException | IllegalAccessException e) {
    +            throw new MethodHandleFactory.LookupException(e);
    +        }
         }
     
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
    index a480c590062..1af79785d9c 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
    @@ -50,6 +50,7 @@ import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
     import jdk.nashorn.internal.runtime.PropertyDescriptor;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptFunction;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.ScriptRuntime;
    @@ -82,6 +83,8 @@ public final class NativeArray extends ScriptObject {
     
         private static final InvokeByName TO_LOCALE_STRING = new InvokeByName("toLocaleString", ScriptObject.class, String.class);
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
     
         /*
          * Constructors.
    @@ -126,8 +129,8 @@ public final class NativeArray extends ScriptObject {
             this.setArray(arrayData);
         }
     
    -    private NativeArray(final ArrayData arrayData) {
    -        setProto(Global.instance().getArrayPrototype());
    +    NativeArray(final ArrayData arrayData) {
    +        super(Global.instance().getArrayPrototype(), $nasgenmap$);
             this.setArray(arrayData);
             this.setIsArray();
         }
    @@ -856,8 +859,12 @@ public final class NativeArray extends ScriptObject {
                     }
     
                     // delete missing elements - which are at the end of sorted array
    -                sobj.setArray(array.delete(sorted.length, len - 1));
    -            }
    +                if (sorted.length != len) {
    +                    array = array.delete(sorted.length, len - 1);
    +                }
    +
    +                sobj.setArray(array);
    +           }
     
                 return sobj;
             } catch (final ClassCastException | NullPointerException e) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java
    index 542b2aebb46..f122bfca8f5 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java
    @@ -32,6 +32,7 @@ import jdk.nashorn.internal.objects.annotations.Function;
     import jdk.nashorn.internal.objects.annotations.Getter;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.ScriptRuntime;
     
    @@ -39,6 +40,9 @@ import jdk.nashorn.internal.runtime.ScriptRuntime;
     final class NativeArrayBuffer extends ScriptObject {
         private final byte[] buffer;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         @Constructor(arity = 1)
         public static Object constructor(final boolean newObj, final Object self, final Object... args) {
             if (args.length == 0) {
    @@ -49,8 +53,8 @@ final class NativeArrayBuffer extends ScriptObject {
         }
     
         protected NativeArrayBuffer(final byte[] byteArray) {
    +        super(Global.instance().getArrayBufferPrototype(), $nasgenmap$);
             this.buffer = byteArray;
    -        this.setProto(Global.instance().getArrayBufferPrototype());
         }
     
         protected NativeArrayBuffer(final int byteLength) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java b/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java
    index a63f0d48287..bfbbb3d73d7 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java
    @@ -37,6 +37,7 @@ import jdk.nashorn.internal.objects.annotations.Constructor;
     import jdk.nashorn.internal.objects.annotations.Function;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.ScriptRuntime;
     import jdk.nashorn.internal.lookup.MethodHandleFactory;
    @@ -52,13 +53,16 @@ public final class NativeBoolean extends ScriptObject {
     
         final static MethodHandle WRAPFILTER = findWrapFilter();
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeBoolean(final boolean value) {
             this(value, Global.instance().getBooleanPrototype());
         }
     
         private NativeBoolean(final boolean value, final ScriptObject proto) {
    +        super(proto, $nasgenmap$);
             this.value = value;
    -        this.setProto(proto);
         }
     
         @Override
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
    index ef01d74b252..3a7d0ef3535 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
    @@ -42,6 +42,7 @@ import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.parser.DateParser;
     import jdk.nashorn.internal.runtime.ConsString;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptEnvironment;
     import jdk.nashorn.internal.runtime.ScriptFunction;
     import jdk.nashorn.internal.runtime.ScriptObject;
    @@ -100,16 +101,19 @@ public final class NativeDate extends ScriptObject {
         private double time;
         private final TimeZone timezone;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeDate() {
             this(System.currentTimeMillis());
         }
     
         NativeDate(final double time) {
    +        super(Global.instance().getDatePrototype(), $nasgenmap$);
             final ScriptEnvironment env = Global.getEnv();
     
             this.time = time;
             this.timezone = env._timezone;
    -        this.setProto(Global.instance().getDatePrototype());
         }
     
         @Override
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
    index 337f2e3d5b1..afcf7b2bfc2 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
    @@ -47,8 +47,12 @@ import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
      */
     @ScriptClass("Debug")
     public final class NativeDebug extends ScriptObject {
    +
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeDebug() {
    -        this.setProto(Global.objectPrototype());
    +        super(Global.objectPrototype(), $nasgenmap$);
         }
     
         @Override
    @@ -187,7 +191,7 @@ public final class NativeDebug extends ScriptObject {
             out.println("Scope count " + ScriptObject.getScopeCount());
             out.println("ScriptObject listeners added " + PropertyListenerManager.getListenersAdded());
             out.println("ScriptObject listeners removed " + PropertyListenerManager.getListenersRemoved());
    -        out.println("ScriptFunction count " + ScriptObject.getCount());
    +        out.println("ScriptFunction constructor calls " + ScriptFunction.getConstructorCount());
             out.println("ScriptFunction invokes " + ScriptFunction.getInvokes());
             out.println("ScriptFunction allocations " + ScriptFunction.getAllocations());
             out.println("PropertyMap count " + PropertyMap.getCount());
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java
    index b10a1c40990..07f5d65aa7b 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java
    @@ -30,18 +30,17 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
     
     import java.lang.invoke.MethodHandle;
     import java.lang.invoke.MethodHandles;
    -import java.util.ArrayList;
    -import java.util.List;
    -import jdk.nashorn.internal.codegen.CompilerConstants;
    +import jdk.nashorn.api.scripting.NashornException;
    +import jdk.nashorn.internal.lookup.MethodHandleFactory;
     import jdk.nashorn.internal.objects.annotations.Attribute;
     import jdk.nashorn.internal.objects.annotations.Constructor;
     import jdk.nashorn.internal.objects.annotations.Function;
     import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
    -import jdk.nashorn.internal.runtime.ECMAErrors;
     import jdk.nashorn.internal.runtime.ECMAException;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.ScriptRuntime;
     
    @@ -85,8 +84,11 @@ public final class NativeError extends ScriptObject {
         @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
         public Object message;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeError(final Object msg) {
    -        this.setProto(Global.instance().getErrorPrototype());
    +        super(Global.instance().getErrorPrototype(), $nasgenmap$);
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    @@ -113,6 +115,21 @@ public final class NativeError extends ScriptObject {
             return new NativeError(msg);
         }
     
    +    /**
    +     * Nashorn extension: Error.captureStackTrace. Capture stack trace at the point of call into the Error object provided.
    +     *
    +     * @param self self reference
    +     * @return undefined
    +     */
    +    @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
    +    public static Object captureStackTrace(final Object self, final Object errorObj) {
    +        Global.checkObject(errorObj);
    +        final ScriptObject sobj = (ScriptObject)errorObj;
    +        final ECMAException exp = new ECMAException(sobj, null);
    +        sobj.set("stack", getScriptStackString(sobj, exp), false);
    +        return UNDEFINED;
    +    }
    +
         /**
          * Nashorn extension: Error.dumpStack
          * dumps the stack of the current thread.
    @@ -142,6 +159,30 @@ public final class NativeError extends ScriptObject {
             return ECMAException.printStackTrace((ScriptObject)self);
         }
     
    +    /**
    +     * Nashorn extension: Error.prototype.getStackTrace()
    +     * "stack" property is an array typed value containing {@link StackTraceElement}
    +     * objects of JavaScript stack frames.
    +     *
    +     * @param self  self reference
    +     *
    +     * @return      stack trace as a script array.
    +     */
    +    @Function(attributes = Attribute.NOT_ENUMERABLE)
    +    public static Object getStackTrace(final Object self) {
    +        Global.checkObject(self);
    +        final ScriptObject sobj = (ScriptObject)self;
    +        final Object exception = ECMAException.getException(sobj);
    +        Object[] res;
    +        if (exception instanceof Throwable) {
    +            res = NashornException.getScriptFrames((Throwable)exception);
    +        } else {
    +            res = ScriptRuntime.EMPTY_ARRAY;
    +        }
    +
    +        return new NativeArray(res);
    +    }
    +
         /**
          * Nashorn extension: Error.prototype.lineNumber
          *
    @@ -228,8 +269,8 @@ public final class NativeError extends ScriptObject {
     
         /**
          * Nashorn extension: Error.prototype.stack
    -     * "stack" property is an array typed value containing {@link StackTraceElement}
    -     * objects of JavaScript stack frames.
    +     * "stack" property is a string typed value containing JavaScript stack frames.
    +     * Each frame information is separated bv "\n" character.
          *
          * @param self  self reference
          *
    @@ -243,27 +284,11 @@ public final class NativeError extends ScriptObject {
             }
     
             final Object exception = ECMAException.getException(sobj);
    -        Object[] res;
             if (exception instanceof Throwable) {
    -            final StackTraceElement[] frames = ((Throwable)exception).getStackTrace();
    -            final List filtered = new ArrayList<>();
    -            for (final StackTraceElement st : frames) {
    -                if (ECMAErrors.isScriptFrame(st)) {
    -                    final String className = "<" + st.getFileName() + ">";
    -                    String methodName = st.getMethodName();
    -                    if (methodName.equals(CompilerConstants.RUN_SCRIPT.symbolName())) {
    -                        methodName = "";
    -                    }
    -                    filtered.add(new StackTraceElement(className, methodName,
    -                            st.getFileName(), st.getLineNumber()));
    -                }
    -            }
    -            res = filtered.toArray();
    +            return getScriptStackString(sobj, (Throwable)exception);
             } else {
    -            res = ScriptRuntime.EMPTY_ARRAY;
    +            return "";
             }
    -
    -        return new NativeArray(res);
         }
     
         /**
    @@ -328,6 +353,14 @@ public final class NativeError extends ScriptObject {
         }
     
         private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) {
    -        return MH.findStatic(MethodHandles.publicLookup(), NativeError.class, name, MH.type(rtype, types));
    +        try {
    +            return MethodHandles.lookup().findStatic(NativeError.class, name, MH.type(rtype, types));
    +        } catch (final NoSuchMethodException | IllegalAccessException e) {
    +            throw new MethodHandleFactory.LookupException(e);
    +        }
    +    }
    +
    +    private static String getScriptStackString(final ScriptObject sobj, final Throwable exp) {
    +        return JSType.toString(sobj) + "\n" + NashornException.getScriptStackString(exp);
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java
    index c4fc838e911..2b88f7dc90a 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java
    @@ -33,6 +33,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     
     /**
    @@ -52,10 +53,13 @@ public final class NativeEvalError extends ScriptObject {
     
         /** ECMA 15.1.1.1 message property */
         @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
    -
         public Object message;
    +
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeEvalError(final Object msg) {
    -        this.setProto(Global.instance().getEvalErrorPrototype());
    +        super(Global.instance().getEvalErrorPrototype(), $nasgenmap$);
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
    index d59a4d6fdb9..beb7d50e542 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
    @@ -32,6 +32,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.arrays.ArrayData;
     
    @@ -46,6 +47,9 @@ public final class NativeFloat32Array extends ArrayBufferView {
         @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
         public static final int BYTES_PER_ELEMENT = 4;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
             @Override
             public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
    index 0f10a867d81..3451e31527c 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
    @@ -32,6 +32,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.arrays.ArrayData;
     
    @@ -46,6 +47,9 @@ public final class NativeFloat64Array extends ArrayBufferView {
         @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
         public static final int BYTES_PER_ELEMENT = 8;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
             @Override
             public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java
    index 38ead32523d..7df1b521027 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java
    @@ -38,6 +38,7 @@ import jdk.nashorn.internal.parser.Parser;
     import jdk.nashorn.internal.runtime.Context;
     import jdk.nashorn.internal.runtime.JSType;
     import jdk.nashorn.internal.runtime.ParserException;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptFunction;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.ScriptRuntime;
    @@ -52,6 +53,10 @@ import jdk.nashorn.internal.runtime.Source;
      */
     @ScriptClass("Function")
     public final class NativeFunction {
    +
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         // do *not* create me!
         private NativeFunction() {
         }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
    index d6c5349efd5..d05c69d70a5 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
    @@ -31,6 +31,7 @@ import jdk.nashorn.internal.objects.annotations.Function;
     import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.arrays.ArrayData;
     
    @@ -39,6 +40,10 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
      */
     @ScriptClass("Int16Array")
     public final class NativeInt16Array extends ArrayBufferView {
    +
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         /**
          * The size in bytes of each element in the array.
          */
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
    index a814eb61de1..596b935cb7d 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
    @@ -31,6 +31,7 @@ import jdk.nashorn.internal.objects.annotations.Function;
     import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.arrays.ArrayData;
     
    @@ -45,6 +46,9 @@ public final class NativeInt32Array extends ArrayBufferView {
         @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
         public static final int BYTES_PER_ELEMENT = 4;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
             @Override
             public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
    index ec43bfc8e18..f1a9b7f7100 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
    @@ -31,6 +31,7 @@ import jdk.nashorn.internal.objects.annotations.Function;
     import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.arrays.ArrayData;
     
    @@ -45,6 +46,9 @@ public final class NativeInt8Array extends ArrayBufferView {
         @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
         public static final int BYTES_PER_ELEMENT = 1;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
             @Override
             public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
    index 153db769f9b..5db4a1fddac 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
    @@ -42,6 +42,7 @@ import jdk.nashorn.internal.objects.annotations.Constructor;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.runtime.FindProperty;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptFunction;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.ScriptRuntime;
    @@ -142,9 +143,12 @@ public final class NativeJSAdapter extends ScriptObject {
     
         private static final MethodHandle IS_JSADAPTOR = findOwnMH("isJSAdaptor", boolean.class, Object.class, Object.class, MethodHandle.class, Object.class, ScriptFunction.class);
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeJSAdapter(final ScriptObject proto, final Object overrides, final ScriptObject adaptee) {
    +        super(proto, $nasgenmap$);
             this.adaptee = wrapAdaptee(adaptee);
    -        this.setProto(proto);
             if (overrides instanceof ScriptObject) {
                 this.overrides = true;
                 final ScriptObject sobj = (ScriptObject)overrides;
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java
    index ec35fc4eaef..3270bc84cd6 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java
    @@ -42,6 +42,7 @@ import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.ConsString;
     import jdk.nashorn.internal.runtime.JSONFunctions;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptFunction;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
    @@ -58,9 +59,11 @@ public final class NativeJSON extends ScriptObject {
         private static final MethodHandle REPLACER_INVOKER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
                 ScriptFunction.class, ScriptObject.class, Object.class, Object.class);
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
     
         NativeJSON() {
    -        this.setProto(Global.objectPrototype());
    +        super(Global.objectPrototype(), $nasgenmap$);
         }
     
         /**
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
    index 207be97938e..7a9ec38fe87 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
    @@ -40,6 +40,7 @@ import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
     import jdk.nashorn.internal.runtime.ListAdapter;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
     
    @@ -52,6 +53,9 @@ import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
     @ScriptClass("Java")
     public final class NativeJava {
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         private NativeJava() {
         }
     
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java
    index 82849172920..9d4c15ac4d1 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java
    @@ -34,6 +34,7 @@ import jdk.nashorn.internal.objects.annotations.Constructor;
     import jdk.nashorn.internal.objects.annotations.Function;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.runtime.NativeJavaPackage;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     
     /**
    @@ -55,9 +56,12 @@ import jdk.nashorn.internal.runtime.ScriptObject;
     public final class NativeJavaImporter extends ScriptObject {
         private final Object[] args;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeJavaImporter(final Object[] args) {
    +        super(Global.instance().getJavaImporterPrototype(), $nasgenmap$);
             this.args = args;
    -        this.setProto(Global.instance().getJavaImporterPrototype());
         }
     
         @Override
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java b/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java
    index 9b1f226ed2c..2b093548315 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java
    @@ -32,6 +32,7 @@ import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     
     /**
    @@ -41,8 +42,11 @@ import jdk.nashorn.internal.runtime.ScriptObject;
     @ScriptClass("Math")
     public final class NativeMath extends ScriptObject {
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeMath() {
    -        this.setProto(Global.objectPrototype());
    +        super(Global.objectPrototype(), $nasgenmap$);
         }
     
         /** ECMA 15.8.1.1 - E, always a double constant. Not writable or configurable */
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java b/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java
    index edb83f06d18..94a7cca1a4d 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java
    @@ -45,6 +45,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.ScriptRuntime;
     import jdk.nashorn.internal.lookup.MethodHandleFactory;
    @@ -83,15 +84,18 @@ public final class NativeNumber extends ScriptObject {
         private final boolean isInt;
         private final boolean isLong;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeNumber(final double value) {
             this(value, Global.instance().getNumberPrototype());
         }
     
         private NativeNumber(final double value, final ScriptObject proto) {
    +        super(proto, $nasgenmap$);
             this.value = value;
             this.isInt  = isRepresentableAsInt(value);
             this.isLong = isRepresentableAsLong(value);
    -        this.setProto(proto);
         }
     
         @Override
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
    index 20a6903905b..1034034506b 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
    @@ -36,6 +36,7 @@ import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.ECMAException;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptFunction;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.ScriptRuntime;
    @@ -53,6 +54,9 @@ import jdk.nashorn.internal.runtime.linker.InvokeByName;
     public final class NativeObject {
         private static final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         private NativeObject() {
         }
     
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java
    index 1dcb4f27eeb..faf68f871f7 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java
    @@ -33,6 +33,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     
     /**
    @@ -54,8 +55,11 @@ public final class NativeRangeError extends ScriptObject {
         @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
         public Object message;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeRangeError(final Object msg) {
    -        setProto(Global.instance().getRangeErrorPrototype());
    +        super(Global.instance().getRangeErrorPrototype(), $nasgenmap$);
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java
    index 7bff77966d1..954eed641f5 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java
    @@ -33,6 +33,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     
     /**
    @@ -54,8 +55,11 @@ public final class NativeReferenceError extends ScriptObject {
         @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
         public Object message;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeReferenceError(final Object msg) {
    -        this.setProto(Global.instance().getReferenceErrorPrototype());
    +        super(Global.instance().getReferenceErrorPrototype(), $nasgenmap$);
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
    index bbbd9791463..bec8b37db0a 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
    @@ -43,6 +43,7 @@ import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.BitVector;
     import jdk.nashorn.internal.runtime.JSType;
     import jdk.nashorn.internal.runtime.ParserException;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.regexp.RegExp;
     import jdk.nashorn.internal.runtime.regexp.RegExpFactory;
     import jdk.nashorn.internal.runtime.regexp.RegExpResult;
    @@ -66,6 +67,9 @@ public final class NativeRegExp extends ScriptObject {
         // Reference to global object needed to support static RegExp properties
         private Global globalObject;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeRegExp(final String input, final String flagString) {
             try {
                 this.regexp = RegExpFactory.create(input, flagString);
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java
    index a88f69c74e0..667205528ed 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java
    @@ -31,6 +31,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Setter;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.regexp.RegExpResult;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.arrays.ArrayData;
    @@ -49,14 +50,22 @@ public final class NativeRegExpExecResult extends ScriptObject {
         @Property
         public Object input;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeRegExpExecResult(final RegExpResult result) {
    -        setProto(Global.instance().getArrayPrototype());
    +        super(Global.instance().getArrayPrototype(), $nasgenmap$);
             setIsArray();
             this.setArray(ArrayData.allocate(result.getGroups().clone()));
             this.index = result.getIndex();
             this.input = result.getInput();
         }
     
    +    @Override
    +    public String getClassName() {
    +        return "Array";
    +    }
    +
         /**
          * Length getter
          * @param self self reference
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java
    index a643c190c5c..cf434f9fce4 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java
    @@ -37,6 +37,7 @@ import jdk.nashorn.internal.runtime.ScriptFunction;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.arrays.ArrayData;
     import jdk.nashorn.internal.lookup.Lookup;
    +import jdk.nashorn.internal.lookup.MethodHandleFactory;
     
     /**
      * ECMA 10.6 Arguments Object.
    @@ -50,22 +51,24 @@ public final class NativeStrictArguments extends ScriptObject {
         private static final MethodHandle S$LENGTH = findOwnMH("S$length", void.class, Object.class, Object.class);
     
         // property map for strict mode arguments object
    -    private static final PropertyMap nasgenmap$;
    +    private static final PropertyMap map$;
     
         static {
             PropertyMap map = PropertyMap.newMap(NativeStrictArguments.class);
             map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH);
             // In strict mode, the caller and callee properties should throw TypeError
    -        map = ScriptFunctionImpl.newThrowerProperty(map, "caller");
    -        map = ScriptFunctionImpl.newThrowerProperty(map, "callee");
    -        nasgenmap$ = map;
    +        // Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
    +        final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
    +        map = map.addProperty(map.newUserAccessors("caller", flags));
    +        map = map.addProperty(map.newUserAccessors("callee", flags));
    +        map$ = map;
         }
     
         private Object   length;
         private final Object[] namedArgs;
     
    -    NativeStrictArguments(final Object[] values, final int numParams) {
    -        super(nasgenmap$);
    +    NativeStrictArguments(final ScriptObject proto, final Object[] values, final int numParams) {
    +        super(proto, map$);
             setIsArguments();
     
             final ScriptFunction func = ScriptFunctionImpl.getTypeErrorThrower();
    @@ -83,8 +86,6 @@ public final class NativeStrictArguments extends ScriptObject {
                 Arrays.fill(namedArgs, UNDEFINED);
             }
             System.arraycopy(values, 0, namedArgs, 0, Math.min(namedArgs.length, values.length));
    -
    -        this.setProto(Global.objectPrototype());
         }
     
         @Override
    @@ -142,6 +143,10 @@ public final class NativeStrictArguments extends ScriptObject {
         }
     
         private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) {
    -        return MH.findStatic(MethodHandles.publicLookup(), NativeStrictArguments.class, name, MH.type(rtype, types));
    +        try {
    +            return MethodHandles.lookup().findStatic(NativeStrictArguments.class, name, MH.type(rtype, types));
    +        } catch (final NoSuchMethodException | IllegalAccessException e) {
    +            throw new MethodHandleFactory.LookupException(e);
    +        }
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
    index fda265e6065..a5b9ea83e54 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
    @@ -52,6 +52,7 @@ import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.ConsString;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptFunction;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.ScriptRuntime;
    @@ -70,14 +71,17 @@ public final class NativeString extends ScriptObject {
     
         static final MethodHandle WRAPFILTER = findWrapFilter();
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeString(final CharSequence value) {
             this(value, Global.instance().getStringPrototype());
         }
     
         private NativeString(final CharSequence value, final ScriptObject proto) {
    +        super(proto, $nasgenmap$);
             assert value instanceof String || value instanceof ConsString;
             this.value = value;
    -        this.setProto(proto);
         }
     
         @Override
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java
    index e9ec3050183..d7d04bbaa6e 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java
    @@ -33,6 +33,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     
     /**
    @@ -54,8 +55,11 @@ public final class NativeSyntaxError extends ScriptObject {
         @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
         public Object message;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeSyntaxError(final Object msg) {
    -        this.setProto(Global.instance().getSyntaxErrorPrototype());
    +        super(Global.instance().getSyntaxErrorPrototype(), $nasgenmap$);
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java
    index bbec5ad320e..c811a530569 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java
    @@ -33,6 +33,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     
     /**
    @@ -54,8 +55,11 @@ public final class NativeTypeError extends ScriptObject {
         @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
         public Object message;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeTypeError(final Object msg) {
    -        this.setProto(Global.instance().getTypeErrorPrototype());
    +        super(Global.instance().getTypeErrorPrototype(), $nasgenmap$);
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java
    index e6c9152534e..80df6c28529 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java
    @@ -33,6 +33,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     
     /**
    @@ -53,8 +54,11 @@ public final class NativeURIError extends ScriptObject {
         @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
         public Object message;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         NativeURIError(final Object msg) {
    -        this.setProto(Global.instance().getURIErrorPrototype());
    +        super(Global.instance().getURIErrorPrototype(), $nasgenmap$);
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
    index 13ce347461e..39c19131280 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
    @@ -31,6 +31,7 @@ import jdk.nashorn.internal.objects.annotations.Function;
     import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.arrays.ArrayData;
     
    @@ -45,6 +46,9 @@ public final class NativeUint16Array extends ArrayBufferView {
         @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
         public static final int BYTES_PER_ELEMENT = 2;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
             @Override
             public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
    index fb45c2821be..37102bae590 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
    @@ -32,6 +32,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.arrays.ArrayData;
     
    @@ -46,6 +47,9 @@ public final class NativeUint32Array extends ArrayBufferView {
         @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
         public static final int BYTES_PER_ELEMENT = 4;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
             @Override
             public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteBegin, final int length) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
    index 6cebcdb9c5f..aa6f89bec67 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
    @@ -31,6 +31,7 @@ import jdk.nashorn.internal.objects.annotations.Function;
     import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.arrays.ArrayData;
     
    @@ -45,6 +46,9 @@ public final class NativeUint8Array extends ArrayBufferView {
         @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
         public static final int BYTES_PER_ELEMENT = 1;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
             @Override
             public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
    index de171caa8a4..4467c856f06 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
    @@ -32,6 +32,7 @@ import jdk.nashorn.internal.objects.annotations.Property;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
     import jdk.nashorn.internal.runtime.JSType;
    +import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.runtime.arrays.ArrayData;
     
    @@ -46,6 +47,9 @@ public final class NativeUint8ClampedArray extends ArrayBufferView {
         @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
         public static final int BYTES_PER_ELEMENT = 1;
     
    +    // initialized by nasgen
    +    private static PropertyMap $nasgenmap$;
    +
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
             @Override
             public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java b/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java
    index edcc3274064..3a7205f9bba 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java
    @@ -35,6 +35,7 @@ import jdk.nashorn.internal.runtime.PropertyMap;
     import jdk.nashorn.internal.runtime.ScriptFunction;
     import jdk.nashorn.internal.runtime.ScriptObject;
     import jdk.nashorn.internal.lookup.Lookup;
    +import jdk.nashorn.internal.lookup.MethodHandleFactory;
     
     /**
      * Instances of this class serve as "prototype" object for script functions.
    @@ -43,7 +44,7 @@ import jdk.nashorn.internal.lookup.Lookup;
      *
      */
     public class PrototypeObject extends ScriptObject {
    -    private static final PropertyMap nasgenmap$;
    +    private static final PropertyMap map$;
     
         private Object constructor;
     
    @@ -53,11 +54,11 @@ public class PrototypeObject extends ScriptObject {
         static {
             PropertyMap map = PropertyMap.newMap(PrototypeObject.class);
             map = Lookup.newProperty(map, "constructor", Property.NOT_ENUMERABLE, GET_CONSTRUCTOR, SET_CONSTRUCTOR);
    -        nasgenmap$ = map;
    +        map$ = map;
         }
     
         PrototypeObject() {
    -        this(nasgenmap$);
    +        this(map$);
         }
     
         /**
    @@ -66,12 +67,12 @@ public class PrototypeObject extends ScriptObject {
          * @param map property map
          */
         public PrototypeObject(final PropertyMap map) {
    -        super(map != nasgenmap$ ? map.addAll(nasgenmap$) : nasgenmap$);
    +        super(map != map$ ? map.addAll(map$) : map$);
             setProto(Global.objectPrototype());
         }
     
         PrototypeObject(final ScriptFunction func) {
    -        this();
    +        this(map$);
             this.constructor = func;
         }
     
    @@ -106,6 +107,10 @@ public class PrototypeObject extends ScriptObject {
         }
     
         private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) {
    -        return MH.findStatic(MethodHandles.publicLookup(), PrototypeObject.class, name, MH.type(rtype, types));
    +        try {
    +            return MethodHandles.lookup().findStatic(PrototypeObject.class, name, MH.type(rtype, types));
    +        } catch (final NoSuchMethodException | IllegalAccessException e) {
    +            throw new MethodHandleFactory.LookupException(e);
    +        }
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
    index 23a13f25931..6834ef4b701 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
    @@ -51,7 +51,7 @@ public class ScriptFunctionImpl extends ScriptFunction {
         // property map for bound functions
         private static final PropertyMap boundfunctionmap$;
         // property map for non-strict, non-bound functions.
    -    private static final PropertyMap nasgenmap$;
    +    private static final PropertyMap map$;
     
         // Marker object for lazily initialized prototype object
         private static final Object LAZY_PROTOTYPE = new Object();
    @@ -65,7 +65,7 @@ public class ScriptFunctionImpl extends ScriptFunction {
          * @param specs specialized versions of this method, if available, null otherwise
          */
         ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs) {
    -        super(name, invokeHandle, nasgenmap$, null, specs, false, true, true);
    +        super(name, invokeHandle, map$, null, specs, false, true, true);
             init();
         }
     
    @@ -79,7 +79,7 @@ public class ScriptFunctionImpl extends ScriptFunction {
          * @param specs specialized versions of this method, if available, null otherwise
          */
         ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs) {
    -        super(name, invokeHandle, map.addAll(nasgenmap$), null, specs, false, true, true);
    +        super(name, invokeHandle, map.addAll(map$), null, specs, false, true, true);
             init();
         }
     
    @@ -124,8 +124,8 @@ public class ScriptFunctionImpl extends ScriptFunction {
             map = Lookup.newProperty(map, "prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE);
             map = Lookup.newProperty(map, "length",    Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null);
             map = Lookup.newProperty(map, "name",      Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null);
    -        nasgenmap$ = map;
    -        strictmodemap$ = createStrictModeMap(nasgenmap$);
    +        map$ = map;
    +        strictmodemap$ = createStrictModeMap(map$);
             boundfunctionmap$ = createBoundFunctionMap(strictmodemap$);
         }
     
    @@ -149,19 +149,17 @@ public class ScriptFunctionImpl extends ScriptFunction {
             return typeErrorThrower;
         }
     
    -    // add a new property that throws TypeError on get as well as set
    -    static synchronized PropertyMap newThrowerProperty(final PropertyMap map, final String name) {
    -        return map.newProperty(name, Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, -1,
    -                Lookup.TYPE_ERROR_THROWER_GETTER, Lookup.TYPE_ERROR_THROWER_SETTER);
    -    }
    -
    -    private static PropertyMap createStrictModeMap(final PropertyMap functionMap) {
    -        return newThrowerProperty(newThrowerProperty(functionMap, "arguments"), "caller");
    +    private static PropertyMap createStrictModeMap(PropertyMap map) {
    +        final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
    +        // Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
    +        map = map.addProperty(map.newUserAccessors("arguments", flags));
    +        map = map.addProperty(map.newUserAccessors("caller", flags));
    +        return map;
         }
     
         // Choose the map based on strict mode!
         private static PropertyMap getMap(final boolean strict) {
    -        return strict ? strictmodemap$ : nasgenmap$;
    +        return strict ? strictmodemap$ : map$;
         }
     
         private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
    @@ -260,12 +258,15 @@ public class ScriptFunctionImpl extends ScriptFunction {
             this.setProto(Global.instance().getFunctionPrototype());
             this.prototype = LAZY_PROTOTYPE;
     
    -        if (isStrict()) {
    -            final ScriptFunction func = getTypeErrorThrower();
    -            // We have to fill user accessor functions late as these are stored
    -            // in this object rather than in the PropertyMap of this object.
    -            setUserAccessors("arguments", func, func);
    -            setUserAccessors("caller", func, func);
    +        // We have to fill user accessor functions late as these are stored
    +        // in this object rather than in the PropertyMap of this object.
    +
    +        if (findProperty("arguments", true) != null) {
    +            setUserAccessors("arguments", getTypeErrorThrower(), getTypeErrorThrower());
    +        }
    +
    +        if (findProperty("caller", true) != null) {
    +            setUserAccessors("caller", getTypeErrorThrower(), getTypeErrorThrower());
             }
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java
    index 0c2c1633591..181dcf83dd4 100644
    --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java
    +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java
    @@ -535,15 +535,12 @@ loop:
                 if (!(lhs instanceof AccessNode ||
                       lhs instanceof IndexNode ||
                       lhs instanceof IdentNode)) {
    -                if (env._early_lvalue_error) {
    -                    throw error(JSErrorType.REFERENCE_ERROR, AbstractParser.message("invalid.lvalue"), lhs.getToken());
    -                }
    -                return referenceError(lhs, rhs);
    +                return referenceError(lhs, rhs, env._early_lvalue_error);
                 }
     
                 if (lhs instanceof IdentNode) {
                     if (!checkIdentLValue((IdentNode)lhs)) {
    -                    return referenceError(lhs, rhs);
    +                    return referenceError(lhs, rhs, false);
                     }
                     verifyStrictIdent((IdentNode)lhs, "assignment");
                 }
    @@ -767,8 +764,6 @@ loop:
             case LBRACE:
                 block();
                 break;
    -        case RBRACE:
    -            break;
             case VAR:
                 variableStatement(true);
                 break;
    @@ -1267,6 +1262,7 @@ loop:
             case RBRACE:
             case SEMICOLON:
             case EOL:
    +        case EOF:
                 break;
     
             default:
    @@ -1314,6 +1310,7 @@ loop:
             case RBRACE:
             case SEMICOLON:
             case EOL:
    +        case EOF:
                 break;
     
             default:
    @@ -1368,6 +1365,7 @@ loop:
             case RBRACE:
             case SEMICOLON:
             case EOL:
    +        case EOF:
                 break;
     
             default:
    @@ -1403,6 +1401,7 @@ loop:
             case RBRACE:
             case SEMICOLON:
             case EOL:
    +        case EOF:
                 break;
     
             default:
    @@ -1928,7 +1927,7 @@ loop:
     
             // Object context.
             // Prepare to accumulate elements.
    -       // final List elements = new ArrayList<>();
    +        // final List elements = new ArrayList<>();
             final Map map = new LinkedHashMap<>();
     
             // Create a block for the object literal.
    @@ -1941,6 +1940,9 @@ loop:
                         break loop;
     
                     case COMMARIGHT:
    +                    if (commaSeen) {
    +                        throw error(AbstractParser.message("expected.property.id", type.getNameOrType()));
    +                    }
                         next();
                         commaSeen = true;
                         break;
    @@ -2566,7 +2568,7 @@ loop:
                      */
     
                     // just expression as function body
    -                final Node expr = expression();
    +                final Node expr = assignmentExpression(true);
                     assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
                     // create a return statement - this creates code in itself and does not need to be
                     // wrapped into an ExecuteNode
    @@ -2612,7 +2614,10 @@ loop:
             }
         }
     
    -    private static RuntimeNode referenceError(final Node lhs, final Node rhs) {
    +    private RuntimeNode referenceError(final Node lhs, final Node rhs, final boolean earlyError) {
    +        if (earlyError) {
    +            throw error(JSErrorType.REFERENCE_ERROR, AbstractParser.message("invalid.lvalue"), lhs.getToken());
    +        }
             final ArrayList args = new ArrayList<>();
             args.add(lhs);
             if (rhs == null) {
    @@ -2690,18 +2695,18 @@ loop:
                 final Node lhs = leftHandSideExpression();
                 // ++, -- without operand..
                 if (lhs == null) {
    -                // error would have been issued when looking for 'lhs'
    -                return null;
    +                throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
                 }
    +
                 if (!(lhs instanceof AccessNode ||
                       lhs instanceof IndexNode ||
                       lhs instanceof IdentNode)) {
    -                return referenceError(lhs, null);
    +                return referenceError(lhs, null, env._early_lvalue_error);
                 }
     
                 if (lhs instanceof IdentNode) {
                     if (!checkIdentLValue((IdentNode)lhs)) {
    -                    return referenceError(lhs, null);
    +                    return referenceError(lhs, null, false);
                     }
                     verifyStrictIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
                 }
    @@ -2720,16 +2725,21 @@ loop:
                 case DECPREFIX:
                     final TokenType opType = type;
                     final Node lhs = expression;
    +                // ++, -- without operand..
    +                if (lhs == null) {
    +                    throw error(AbstractParser.message("expected.lvalue", type.getNameOrType()));
    +                }
    +
                     if (!(lhs instanceof AccessNode ||
                        lhs instanceof IndexNode ||
                        lhs instanceof IdentNode)) {
                         next();
    -                    return referenceError(lhs, null);
    +                    return referenceError(lhs, null, env._early_lvalue_error);
                     }
                     if (lhs instanceof IdentNode) {
                         if (!checkIdentLValue((IdentNode)lhs)) {
                             next();
    -                        return referenceError(lhs, null);
    +                        return referenceError(lhs, null, false);
                         }
                         verifyStrictIdent((IdentNode)lhs, "operand for " + opType.getName() + " operator");
                     }
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
    index 13e9e1ce3bd..bfdfa71995d 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
    @@ -288,7 +288,7 @@ public class AccessorProperty extends Property {
         }
     
         @Override
    -    protected void setObjectValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict)  {
    +    public void setObjectValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict)  {
             if (isSpill()) {
                 self.spill[getSlot()] = value;
             } else {
    @@ -303,7 +303,7 @@ public class AccessorProperty extends Property {
         }
     
         @Override
    -    protected Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
    +    public Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
             if (isSpill()) {
                 return self.spill[getSlot()];
             }
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
    index 5b89ec2c3a4..b39eb44a179 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
    @@ -101,13 +101,7 @@ public final class Context {
         /** Is Context global debug mode enabled ? */
         public static final boolean DEBUG = Options.getBooleanProperty("nashorn.debug");
     
    -    private static final ThreadLocal currentGlobal =
    -        new ThreadLocal() {
    -            @Override
    -            protected ScriptObject initialValue() {
    -                 return null;
    -            }
    -        };
    +    private static final ThreadLocal currentGlobal = new ThreadLocal<>();
     
         /**
          * Get the current global scope
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java
    index 16165fe9caa..c14accb7c4e 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java
    @@ -89,7 +89,7 @@ public final class FindProperty {
             MethodHandle setter = property.getSetter(type, getOwner().getMap());
             if (property instanceof UserAccessorProperty) {
                 final UserAccessorProperty uc = (UserAccessorProperty) property;
    -            setter = MH.insertArguments(setter, 0, (isInherited() ? getOwner() : null),
    +            setter = MH.insertArguments(setter, 0, isInherited() ? getOwner() : null,
                         uc.getSetterSlot(), strict? property.getKey() : null);
             }
     
    @@ -109,7 +109,7 @@ public final class FindProperty {
          * @return appropriate receiver
          */
         public ScriptObject getGetterReceiver() {
    -        return property != null && property.hasGetterFunction() ? self : prototype;
    +        return property != null && property.hasGetterFunction(prototype) ? self : prototype;
         }
     
        /**
    @@ -117,7 +117,7 @@ public final class FindProperty {
          * @return appropriate receiver
          */
         public ScriptObject getSetterReceiver() {
    -        return property != null && property.hasSetterFunction() ? self : prototype;
    +        return property != null && property.hasSetterFunction(prototype) ? self : prototype;
         }
     
         /**
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java b/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java
    index 713aa69d3ce..59a9d5ede03 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java
    @@ -54,9 +54,8 @@ public class FunctionScope extends ScriptObject implements Scope {
          * @param arguments   arguments
          */
         public FunctionScope(final PropertyMap map, final ScriptObject callerScope, final Object arguments) {
    -        super(map);
    +        super(callerScope, map);
             this.arguments = arguments;
    -        setProto(callerScope);
             setIsScope();
         }
     
    @@ -67,9 +66,8 @@ public class FunctionScope extends ScriptObject implements Scope {
          * @param callerScope caller scope
          */
         public FunctionScope(final PropertyMap map, final ScriptObject callerScope) {
    -        super(map);
    +        super(callerScope, map);
             this.arguments = null;
    -        setProto(callerScope);
             setIsScope();
         }
     
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java
    index 8f1f1e9e616..9507f0d3205 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java
    @@ -911,7 +911,7 @@ public enum JSType {
     
             for (int i = start; i < length ; i++) {
                 if (digit(chars[i], radix) == -1) {
    -                break;
    +                return Double.NaN;
                 }
                 pos++;
             }
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Property.java b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
    index a5e46016a00..e2cc6cdec21 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/Property.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
    @@ -180,17 +180,19 @@ public abstract class Property {
     
         /**
          * Check whether this property has a user defined getter function. See {@link UserAccessorProperty}
    +     * @param obj object containing getter
          * @return true if getter function exists, false is default
          */
    -    public boolean hasGetterFunction() {
    +    public boolean hasGetterFunction(final ScriptObject obj) {
             return false;
         }
     
         /**
          * Check whether this property has a user defined setter function. See {@link UserAccessorProperty}
    +     * @param obj object containing setter
          * @return true if getter function exists, false is default
          */
    -    public boolean hasSetterFunction() {
    +    public boolean hasSetterFunction(final ScriptObject obj) {
             return false;
         }
     
    @@ -363,7 +365,7 @@ public abstract class Property {
          * @param value the new property value
          * @param strict is this a strict setter?
          */
    -    protected abstract void setObjectValue(ScriptObject self, ScriptObject owner, Object value, boolean strict);
    +    public abstract void setObjectValue(ScriptObject self, ScriptObject owner, Object value, boolean strict);
     
         /**
          * Set the Object value of this property from {@code owner}. This allows to bypass creation of the
    @@ -373,7 +375,7 @@ public abstract class Property {
          * @param owner the owner object
          * @return  the property value
          */
    -    protected abstract Object getObjectValue(ScriptObject self, ScriptObject owner);
    +    public abstract Object getObjectValue(ScriptObject self, ScriptObject owner);
     
         /**
          * Abstract method for retrieving the setter for the property. We do not know
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
    index b7248166696..e03a3ef836e 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
    @@ -25,6 +25,8 @@
     
     package jdk.nashorn.internal.runtime;
     
    +import jdk.nashorn.internal.scripts.JO;
    +
     import static jdk.nashorn.internal.runtime.PropertyHashMap.EMPTY_HASHMAP;
     
     import java.lang.invoke.MethodHandle;
    @@ -166,7 +168,7 @@ public final class PropertyMap implements Iterable, PropertyListener {
          */
         public static PropertyMap newMap(final Class structure, final Collection properties, final int fieldCount, final int fieldMaximum) {
             // Reduce the number of empty maps in the context.
    -        if (structure == jdk.nashorn.internal.scripts.JO.class) {
    +        if (structure == JO.class) {
                 return EMPTY_MAP;
             }
     
    @@ -302,7 +304,7 @@ public final class PropertyMap implements Iterable, PropertyListener {
          *
          * @return New {@link PropertyMap} with {@link Property} added.
          */
    -    PropertyMap addProperty(final Property property) {
    +    public PropertyMap addProperty(final Property property) {
             PropertyMap newMap = checkHistory(property);
     
             if (newMap == null) {
    @@ -383,6 +385,21 @@ public final class PropertyMap implements Iterable, PropertyListener {
             return newMap;
         }
     
    +    /*
    +     * Make a new UserAccessorProperty property. getter and setter functions are stored in
    +     * this ScriptObject and slot values are used in property object. Note that slots
    +     * are assigned speculatively and should be added to map before adding other
    +     * properties.
    +     */
    +    public UserAccessorProperty newUserAccessors(final String key, final int propertyFlags) {
    +        int oldSpillLength = spillLength;
    +
    +        final int getterSlot = oldSpillLength++;
    +        final int setterSlot = oldSpillLength++;
    +
    +        return new UserAccessorProperty(key, propertyFlags, getterSlot, setterSlot);
    +    }
    +
         /**
          * Find a property in the map.
          *
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java
    index 26e6270a4f2..5dca0e26978 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java
    @@ -202,6 +202,16 @@ public abstract class ScriptFunction extends ScriptObject {
             return data.invoke(this, self, arguments);
         }
     
    +    /**
    +     * Execute this script function as a constructor.
    +     * @param arguments  Call arguments.
    +     * @return Newly constructed result.
    +     * @throws Throwable if there is an exception/error with the invocation or thrown from it
    +     */
    +    Object construct(final Object... arguments) throws Throwable {
    +        return data.construct(this, arguments);
    +    }
    +
         /**
          * Allocate function. Called from generated {@link ScriptObject} code
          * for allocation as a factory method
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
    index f98817c8ee6..673c0152ecf 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
    @@ -216,6 +216,12 @@ public abstract class ScriptFunctionData {
             return composeGenericMethod(code.mostGeneric().getInvoker());
         }
     
    +    final MethodHandle getGenericConstructor() {
    +        ensureCodeGenerated();
    +        ensureConstructor(code.mostGeneric());
    +        return composeGenericMethod(code.mostGeneric().getConstructor());
    +    }
    +
         private CompiledFunction getBest(final MethodType callSiteType) {
             ensureCodeGenerated();
             return code.best(callSiteType);
    @@ -535,10 +541,74 @@ public abstract class ScriptFunctionData {
             }
         }
     
    +    Object construct(final ScriptFunction fn, final Object... arguments) throws Throwable {
    +        final MethodHandle mh = getGenericConstructor();
    +
    +        final Object[]     args       = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments;
    +
    +        if (isVarArg(mh)) {
    +            if (needsCallee(mh)) {
    +                return mh.invokeExact(fn, args);
    +            }
    +            return mh.invokeExact(args);
    +        }
    +
    +        final int paramCount = mh.type().parameterCount();
    +        if (needsCallee(mh)) {
    +            switch (paramCount) {
    +            case 1:
    +                return mh.invokeExact(fn);
    +            case 2:
    +                return mh.invokeExact(fn, getArg(args, 0));
    +            case 3:
    +                return mh.invokeExact(fn, getArg(args, 0), getArg(args, 1));
    +            case 4:
    +                return mh.invokeExact(fn, getArg(args, 0), getArg(args, 1), getArg(args, 2));
    +            default:
    +                return mh.invokeWithArguments(withArguments(fn, paramCount, args));
    +            }
    +        }
    +
    +        switch (paramCount) {
    +        case 0:
    +            return mh.invokeExact();
    +        case 1:
    +            return mh.invokeExact(getArg(args, 0));
    +        case 2:
    +            return mh.invokeExact(getArg(args, 0), getArg(args, 1));
    +        case 3:
    +            return mh.invokeExact(getArg(args, 0), getArg(args, 1), getArg(args, 2));
    +        default:
    +            return mh.invokeWithArguments(withArguments(null, paramCount, args));
    +        }
    +    }
    +
         private static Object getArg(final Object[] args, final int i) {
             return i < args.length ? args[i] : UNDEFINED;
         }
     
    +    private static Object[] withArguments(final ScriptFunction fn, final int argCount, final Object[] args) {
    +        final Object[] finalArgs = new Object[argCount];
    +
    +        int nextArg = 0;
    +        if (fn != null) {
    +            //needs callee
    +            finalArgs[nextArg++] = fn;
    +        }
    +
    +        // Don't add more args that there is argCount in the handle (including self and callee).
    +        for (int i = 0; i < args.length && nextArg < argCount;) {
    +            finalArgs[nextArg++] = args[i++];
    +        }
    +
    +        // If we have fewer args than argCount, pad with undefined.
    +        while (nextArg < argCount) {
    +            finalArgs[nextArg++] = UNDEFINED;
    +        }
    +
    +        return finalArgs;
    +    }
    +
         private static Object[] withArguments(final ScriptFunction fn, final Object self, final int argCount, final Object[] args) {
             final Object[] finalArgs = new Object[argCount];
     
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
    index 0a2337f4d3c..1a081a1b2d5 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
    @@ -170,13 +170,30 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
             }
     
             this.arrayData = ArrayData.EMPTY_ARRAY;
    +        this.setMap(map == null ? PropertyMap.newMap(getClass()) : map);
    +    }
     
    -        if (map == null) {
    -            this.setMap(PropertyMap.newMap(getClass()));
    -            return;
    +    /**
    +     * Constructor that directly sets the prototype to {@code proto} and property map to
    +     * {@code map} without invalidating the map as calling {@link #setProto(ScriptObject)}
    +     * would do. This should only be used for objects that are always constructed with the
    +     * same combination of prototype and property map.
    +     *
    +     * @param proto the prototype object
    +     * @param map intial {@link PropertyMap}
    +     */
    +    protected ScriptObject(final ScriptObject proto, final PropertyMap map) {
    +        if (Context.DEBUG) {
    +            ScriptObject.count++;
             }
     
    -        this.setMap(map);
    +        this.arrayData = ArrayData.EMPTY_ARRAY;
    +        this.setMap(map == null ? PropertyMap.newMap(getClass()) : map);
    +        this.proto = proto;
    +
    +        if (proto != null) {
    +            proto.setIsPrototype();
    +        }
         }
     
         /**
    @@ -777,30 +794,18 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
         public final Property modifyOwnProperty(final Property oldProperty, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
             Property newProperty;
             if (oldProperty instanceof UserAccessorProperty) {
    -            // re-use the slots of the old user accessor property.
                 final UserAccessorProperty uc = (UserAccessorProperty) oldProperty;
    -
    -            int getterSlot = uc.getGetterSlot();
    -            // clear the old getter and set the new getter
    +            final int getterSlot = uc.getGetterSlot();
    +            final int setterSlot = uc.getSetterSlot();
                 setSpill(getterSlot, getter);
    -            // if getter function is null, flag the slot to be negative (less by 1)
    -            if (getter == null) {
    -                getterSlot = -getterSlot - 1;
    -            }
    -
    -            int setterSlot = uc.getSetterSlot();
    -            // clear the old setter and set the new setter
                 setSpill(setterSlot, setter);
    -            // if setter function is null, flag the slot to be negative (less by 1)
    -            if (setter == null) {
    -                setterSlot = -setterSlot - 1;
    +
    +            // if just flipping getter and setter with new functions, no need to change property or map
    +            if (uc.flags == propertyFlags) {
    +                return oldProperty;
                 }
     
                 newProperty = new UserAccessorProperty(oldProperty.getKey(), propertyFlags, getterSlot, setterSlot);
    -            // if just flipping getter and setter with new functions, no need to change property or map
    -            if (oldProperty.equals(newProperty)) {
    -                return oldProperty;
    -            }
             } else {
                 // erase old property value and create new user accessor property
                 erasePropertyValue(oldProperty);
    @@ -862,12 +867,10 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
          */
         public final void setUserAccessors(final String key, final ScriptFunction getter, final ScriptFunction setter) {
             final Property oldProperty = getMap().findProperty(key);
    -        if (oldProperty != null) {
    -            final UserAccessorProperty newProperty = newUserAccessors(oldProperty.getKey(), oldProperty.getFlags(), getter, setter);
    -            modifyOwnProperty(oldProperty, newProperty);
    +        if (oldProperty instanceof UserAccessorProperty) {
    +            modifyOwnProperty(oldProperty, oldProperty.getFlags(), getter, setter);
             } else {
    -            final UserAccessorProperty newProperty = newUserAccessors(key, 0, getter, setter);
    -            addOwnProperty(newProperty);
    +            addOwnProperty(newUserAccessors(key, oldProperty != null ? oldProperty.getFlags() : 0, getter, setter));
             }
         }
     
    @@ -1712,7 +1715,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
     
                 final ScriptObject prototype = find.getOwner();
     
    -            if (!property.hasGetterFunction()) {
    +            if (!property.hasGetterFunction(prototype)) {
                     methodHandle = bindTo(methodHandle, prototype);
                 }
                 return new GuardedInvocation(methodHandle, getMap().getProtoGetSwitchPoint(proto, name), guard);
    @@ -3144,49 +3147,30 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
          * Make a new UserAccessorProperty property. getter and setter functions are stored in
          * this ScriptObject and slot values are used in property object.
          */
    -    private UserAccessorProperty newUserAccessors(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
    -        int oldSpillLength = getMap().getSpillLength();
    +    protected final UserAccessorProperty newUserAccessors(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
    +        final UserAccessorProperty property = getMap().newUserAccessors(key, propertyFlags);
    +        setSpill(property.getGetterSlot(), getter);
    +        setSpill(property.getSetterSlot(), setter);
     
    -        int getterSlot = oldSpillLength++;
    -        setSpill(getterSlot, getter);
    -        // if getter function is null, flag the slot to be negative (less by 1)
    -        if (getter == null) {
    -            getterSlot = -getterSlot - 1;
    -        }
    -
    -        int setterSlot = oldSpillLength++;
    -
    -        setSpill(setterSlot, setter);
    -        // if setter function is null, flag the slot to be negative (less by 1)
    -        if (setter == null) {
    -            setterSlot = -setterSlot - 1;
    -        }
    -
    -        return new UserAccessorProperty(key, propertyFlags, getterSlot, setterSlot);
    +        return property;
         }
     
    -    private void setSpill(final int slot, final Object value) {
    -        if (slot >= 0) {
    -            final int index = slot;
    -            if (spill == null) {
    -                // create new spill.
    -                spill = new Object[Math.max(index + 1, SPILL_RATE)];
    -            } else if (index >= spill.length) {
    -                // grow spill as needed
    -                final Object[] newSpill = new Object[index + 1];
    -                System.arraycopy(spill, 0, newSpill, 0, spill.length);
    -                spill = newSpill;
    -            }
    -
    -            spill[index] = value;
    +    protected final void setSpill(final int slot, final Object value) {
    +        if (spill == null) {
    +            // create new spill.
    +            spill = new Object[Math.max(slot + 1, SPILL_RATE)];
    +        } else if (slot >= spill.length) {
    +            // grow spill as needed
    +            final Object[] newSpill = new Object[slot + 1];
    +            System.arraycopy(spill, 0, newSpill, 0, spill.length);
    +            spill = newSpill;
             }
    +
    +        spill[slot] = value;
         }
     
    -    // user accessors are either stored in spill array slots
    -    // get the accessor value using slot number. Note that slot is spill array index.
    -    Object getSpill(final int slot) {
    -        final int index = slot;
    -        return (index < 0 || (index >= spill.length)) ? null : spill[index];
    +    protected Object getSpill(final int slot) {
    +        return spill != null && slot < spill.length ? spill[slot] : null;
         }
     
         private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) {
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java
    index f1febc0ca17..15c915cf0e4 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java
    @@ -120,6 +120,17 @@ public final class ScriptRuntime {
             return deflt;
         }
     
    +    /**
    +     * Converts a switch tag value to a simple integer. deflt value if it can't.
    +     *
    +     * @param tag   Switch statement tag value.
    +     * @param deflt default to use if not convertible.
    +     * @return int tag value (or deflt.)
    +     */
    +    public static int switchTagAsInt(final boolean tag, final int deflt) {
    +        return deflt;
    +    }
    +
         /**
          * Converts a switch tag value to a simple integer. deflt value if it can't.
          *
    @@ -360,6 +371,47 @@ public final class ScriptRuntime {
             }
         }
     
    +    /**
    +     * Check that the target function is associated with current Context.
    +     * And also make sure that 'self', if ScriptObject, is from current context.
    +     *
    +     * Call a function as a constructor given args.
    +     *
    +     * @param target ScriptFunction object.
    +     * @param args   Call arguments.
    +     * @return Constructor call result.
    +     */
    +    public static Object checkAndConstruct(final ScriptFunction target, final Object... args) {
    +        final ScriptObject global = Context.getGlobalTrusted();
    +        if (! (global instanceof GlobalObject)) {
    +            throw new IllegalStateException("No current global set");
    +        }
    +
    +        if (target.getContext() != global.getContext()) {
    +            throw new IllegalArgumentException("'target' function is not from current Context");
    +        }
    +
    +        // all in order - call real 'construct'
    +        return construct(target, args);
    +    }
    +
    +    /*
    +     * Call a script function as a constructor with given args.
    +     *
    +     * @param target ScriptFunction object.
    +     * @param args   Call arguments.
    +     * @return Constructor call result.
    +     */
    +    public static Object construct(final ScriptFunction target, final Object... args) {
    +        try {
    +            return target.construct(args);
    +        } catch (final RuntimeException | Error e) {
    +            throw e;
    +        } catch (final Throwable t) {
    +            throw new RuntimeException(t);
    +        }
    +    }
    +
         /**
          * Generic implementation of ECMA 9.12 - SameValue algorithm
          *
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
    index a6dfce0f5fd..777254d831c 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
    @@ -151,9 +151,10 @@ final class SetMethodCreator {
             assert methodHandle != null;
             assert property     != null;
     
    +        final ScriptObject prototype = find.getOwner();
             final MethodHandle boundHandle;
    -        if (!property.hasSetterFunction() && find.isInherited()) {
    -            boundHandle = ScriptObject.bindTo(methodHandle, find.getOwner());
    +        if (!property.hasSetterFunction(prototype) && find.isInherited()) {
    +            boundHandle = ScriptObject.bindTo(methodHandle, prototype);
             } else {
                 boundHandle = methodHandle;
             }
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/URIUtils.java b/nashorn/src/jdk/nashorn/internal/runtime/URIUtils.java
    index 448d72c364f..2321353fbaa 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/URIUtils.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/URIUtils.java
    @@ -27,8 +27,6 @@ package jdk.nashorn.internal.runtime;
     
     import static jdk.nashorn.internal.runtime.ECMAErrors.uriError;
     
    -import java.io.UnsupportedEncodingException;
    -
     /**
      * URI handling global functions. ECMA 15.1.3 URI Handling Function Properties
      *
    @@ -127,6 +125,7 @@ public final class URIUtils {
     
                 k += 2;
                 char C;
    +            // Most significant bit is zero
                 if ((B & 0x80) == 0) {
                     C = (char) B;
                     if (!component && URI_RESERVED.indexOf(C) >= 0) {
    @@ -137,49 +136,68 @@ public final class URIUtils {
                         sb.append(C);
                     }
                 } else {
    -                int n;
    -                for (n = 1; n < 6; n++) {
    -                    if (((B << n) & 0x80) == 0) {
    -                        break;
    -                    }
    -                }
    +                // n is utf8 length, V is codepoint and minV is lower bound
    +                int n, V, minV;
     
    -                if (n == 1 || n > 4) {
    +                if ((B & 0xC0) == 0x80) {
    +                    // 10xxxxxx - illegal first byte
    +                    return error(string, k);
    +                } else if ((B & 0x20) == 0) {
    +                    // 110xxxxx 10xxxxxx
    +                    n = 2;
    +                    V = B & 0x1F;
    +                    minV = 0x80;
    +                } else if ((B & 0x10) == 0) {
    +                    // 1110xxxx 10xxxxxx 10xxxxxx
    +                    n = 3;
    +                    V = B & 0x0F;
    +                    minV = 0x800;
    +                } else if ((B & 0x08) == 0) {
    +                    // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    +                    n = 4;
    +                    V = B & 0x07;
    +                    minV = 0x10000;
    +                } else if ((B & 0x04) == 0) {
    +                    // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    +                    n = 5;
    +                    V =  B & 0x03;
    +                    minV = 0x200000;
    +                } else if ((B & 0x02) == 0) {
    +                    // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    +                    n = 6;
    +                    V = B & 0x01;
    +                    minV = 0x4000000;
    +                } else {
                         return error(string, k);
                     }
     
    -                if ((k + (3 * (n - 1))) >= len) {
    +                // check bound for sufficient chars
    +                if (k + (3*(n-1)) >= len) {
                         return error(string, k);
                     }
     
    -                final byte[] bbuf = new byte[n];
    -                bbuf[0] = (byte) B;
    -
                     for (int j = 1; j < n; j++) {
                         k++;
                         if (string.charAt(k) != '%') {
                             return error(string, k);
                         }
     
    -                    if (k + 2 == len) {
    -                        return error(string, k);
    -                    }
    -
                         B = toHexByte(string.charAt(k + 1), string.charAt(k + 2));
                         if (B < 0 || (B & 0xC0) != 0x80) {
                             return error(string, k + 1);
                         }
     
    +                    V = (V << 6) | (B & 0x3F);
                         k += 2;
    -                    bbuf[j] = (byte) B;
                     }
     
    -                int V;
    -                try {
    -                    V = ucs4Char(bbuf);
    -                } catch (final Exception e) {
    -                    throw uriError(e, "bad.uri", string, Integer.toString(k));
    +                // Check for overlongs and invalid codepoints.
    +                // The high and low surrogate halves used by UTF-16
    +                // (U+D800 through U+DFFF) are not legal Unicode values.
    +                if ((V < minV) || (V >= 0xD800 && V <= 0xDFFF)) {
    +                    V = Integer.MAX_VALUE;
                     }
    +
                     if (V < 0x10000) {
                         C = (char) V;
                         if (!component && URI_RESERVED.indexOf(C) >= 0) {
    @@ -224,10 +242,6 @@ public final class URIUtils {
             return -1;
         }
     
    -    private static int ucs4Char(final byte[] utf8) throws UnsupportedEncodingException {
    -        return new String(utf8, "UTF-8").codePointAt(0);
    -    }
    -
         private static String toHexEscape(final int u0) {
             int u = u0;
             int len;
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
    index 5159e6537b0..1dc64311545 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
    @@ -96,19 +96,19 @@ public final class UserAccessorProperty extends Property {
         }
     
         /**
    -     * Return getter slot for this UserAccessorProperty. Slots start with first embed field.
    +     * Return getter spill slot for this UserAccessorProperty.
          * @return getter slot
          */
         public int getGetterSlot() {
    -        return getterSlot < 0 ? -getterSlot - 1 : getterSlot;
    +        return getterSlot;
         }
     
         /**
    -     * Return setter slot for this UserAccessorProperty. Slots start with first embed field.
    +     * Return setter spill slot for this UserAccessorProperty.
          * @return setter slot
          */
         public int getSetterSlot() {
    -        return setterSlot < 0 ? -setterSlot - 1 : setterSlot;
    +        return setterSlot;
         }
     
         @Override
    @@ -124,7 +124,7 @@ public final class UserAccessorProperty extends Property {
     
             final UserAccessorProperty uc = (UserAccessorProperty) other;
             return getterSlot == uc.getterSlot && setterSlot == uc.setterSlot;
    -     }
    +    }
     
         @Override
         public int hashCode() {
    @@ -136,34 +136,26 @@ public final class UserAccessorProperty extends Property {
          */
         @Override
         public int getSpillCount() {
    -        // calculate how many spill array slots used by this propery.
    -        int count = 0;
    -        if (getGetterSlot() >= 0) {
    -            count++;
    -        }
    -        if (getSetterSlot() >= 0) {
    -            count++;
    -        }
    -        return count;
    +        return 2;
         }
     
         @Override
    -    public boolean hasGetterFunction() {
    -        return getterSlot > -1;
    +    public boolean hasGetterFunction(final ScriptObject obj) {
    +        return obj.getSpill(getterSlot) != null;
         }
     
         @Override
    -    public boolean hasSetterFunction() {
    -        return setterSlot > -1;
    +    public boolean hasSetterFunction(final ScriptObject obj) {
    +        return obj.getSpill(setterSlot) != null;
         }
     
         @Override
    -    protected Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
    +    public Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
             return userAccessorGetter(owner, getGetterSlot(), self);
         }
     
         @Override
    -    protected void setObjectValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict) {
    +    public void setObjectValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict) {
             userAccessorSetter(owner, getSetterSlot(), strict ? getKey() : null, self, value);
         }
     
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java
    index fca724a8bf3..d11059b275d 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java
    @@ -294,6 +294,29 @@ public abstract class ArrayData {
          */
         public abstract ArrayData set(int index, double value, boolean strict);
     
    +    /**
    +     * Set an empty value at a given index. Should only affect Object array.
    +     *
    +     * @param index the index
    +     * @return new array data (or same)
    +     */
    +    public ArrayData setEmpty(final int index) {
    +        // Do nothing.
    +        return this;
    +    }
    +
    +    /**
    +     * Set an empty value for a given range. Should only affect Object array.
    +     *
    +     * @param lo range low end
    +     * @param hi range high end
    +     * @return new array data (or same)
    +     */
    +    public ArrayData setEmpty(final long lo, final long hi) {
    +        // Do nothing.
    +        return this;
    +    }
    +
         /**
          * Get an int value from a given index
          *
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java
    index c347ed70e8b..7a20f788fda 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java
    @@ -128,6 +128,18 @@ abstract class ArrayFilter extends ArrayData {
             return this;
         }
     
    +    @Override
    +    public ArrayData setEmpty(final int index) {
    +        underlying.setEmpty(index);
    +        return this;
    +    }
    +
    +    @Override
    +    public ArrayData setEmpty(final long lo, final long hi) {
    +        underlying.setEmpty(lo, hi);
    +        return this;
    +    }
    +
         @Override
         public int getInt(final int index) {
             return underlying.getInt(index);
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java
    index 57bea4cf1e6..b5f1f16d024 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java
    @@ -142,6 +142,7 @@ final class DeletedArrayFilter extends ArrayFilter {
             final long longIndex = ArrayIndex.toLongIndex(index);
             assert longIndex >= 0 && longIndex < length();
             deleted.set(longIndex);
    +        underlying.setEmpty(index);
             return this;
         }
     
    @@ -149,6 +150,7 @@ final class DeletedArrayFilter extends ArrayFilter {
         public ArrayData delete(final long fromIndex, final long toIndex) {
             assert fromIndex >= 0 && fromIndex <= toIndex && toIndex < length();
             deleted.setRange(fromIndex, toIndex + 1);
    +        underlying.setEmpty(fromIndex, toIndex);
             return this;
         }
     
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java
    index 588252ac4f2..29c443bae10 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java
    @@ -202,6 +202,8 @@ final class DeletedRangeArrayFilter extends ArrayFilter {
         @Override
         public ArrayData delete(final int index) {
             final long longIndex = ArrayIndex.toLongIndex(index);
    +        underlying.setEmpty(index);
    +
             if (longIndex + 1 == lo) {
                 lo = longIndex;
             } else if (longIndex - 1 == hi) {
    @@ -220,6 +222,7 @@ final class DeletedRangeArrayFilter extends ArrayFilter {
             }
             lo = Math.min(fromIndex, lo);
             hi = Math.max(toIndex, hi);
    +        underlying.setEmpty(lo, hi);
             return this;
         }
     
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java
    index cb1e2fa03ba..4b1f58a430a 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java
    @@ -138,6 +138,18 @@ final class ObjectArrayData extends ArrayData {
             return this;
         }
     
    +    @Override
    +    public ArrayData setEmpty(final int index) {
    +        array[index] = ScriptRuntime.EMPTY;
    +        return this;
    +    }
    +
    +    @Override
    +    public ArrayData setEmpty(final long lo, final long hi) {
    +        Arrays.fill(array, (int)Math.max(lo, 0L), (int)Math.min(hi, (long)Integer.MAX_VALUE), ScriptRuntime.EMPTY);
    +        return this;
    +    }
    +
         @Override
         public int getInt(final int index) {
             return JSType.toInt32(array[index]);
    @@ -165,11 +177,13 @@ final class ObjectArrayData extends ArrayData {
     
         @Override
         public ArrayData delete(final int index) {
    +        setEmpty(index);
             return new DeletedRangeArrayFilter(this, index, index);
         }
     
         @Override
         public ArrayData delete(final long fromIndex, final long toIndex) {
    +        setEmpty(fromIndex, toIndex);
             return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
         }
     
    @@ -181,7 +195,7 @@ final class ObjectArrayData extends ArrayData {
     
             final int newLength = (int) (length() - 1);
             final Object elem = array[newLength];
    -        array[newLength] = 0;
    +        setEmpty(newLength);
             setLength(newLength);
             return elem;
         }
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java
    index fd52f22db83..0ccbb23c535 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java
    @@ -203,6 +203,18 @@ class SparseArrayData extends ArrayData {
             return this;
         }
     
    +    @Override
    +    public ArrayData setEmpty(final int index) {
    +        underlying.setEmpty(index);
    +        return this;
    +    }
    +
    +    @Override
    +    public ArrayData setEmpty(final long lo, final long hi) {
    +        underlying.setEmpty(lo, hi);
    +        return this;
    +    }
    +
         @Override
         public int getInt(final int index) {
             if (index >= 0 && index < maxDenseLength) {
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
    index edd75e4dafd..1b7eb66b4e9 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
    @@ -45,44 +45,14 @@ import jdk.nashorn.api.scripting.JSObject;
      * as ScriptObjects from other Nashorn contexts.
      */
     final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
    -   /**
    -     * Instances of this class are used to represent a method member of a JSObject
    -     */
    -    private static final class JSObjectMethod {
    -        // The name of the JSObject method property
    -        private final String name;
    -
    -        JSObjectMethod(final String name) {
    -            this.name = name;
    -        }
    -
    -        String getName() {
    -            return name;
    -        }
    -
    -        static GuardedInvocation lookup(final CallSiteDescriptor desc) {
    -            final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
    -            switch (operator) {
    -                case "call": {
    -                    // collect everything except the first two - JSObjectMethod instance and the actual 'self'
    -                    final int paramCount = desc.getMethodType().parameterCount();
    -                    final MethodHandle caller = MH.asCollector(JSOBJECTMETHOD_CALL, Object[].class, paramCount - 2);
    -                    return new GuardedInvocation(caller, null, IS_JSOBJECTMETHOD_GUARD);
    -                }
    -                default:
    -                    return null;
    -            }
    -        }
    -    }
    -
         @Override
         public boolean canLinkType(final Class type) {
             return canLinkTypeStatic(type);
         }
     
         static boolean canLinkTypeStatic(final Class type) {
    -        // can link JSObject and JSObjectMethod
    -        return JSObject.class.isAssignableFrom(type) || JSObjectMethod.class.isAssignableFrom(type);
    +        // can link JSObject
    +        return JSObject.class.isAssignableFrom(type);
         }
     
         @Override
    @@ -99,8 +69,6 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
             final GuardedInvocation inv;
             if (self instanceof JSObject) {
                 inv = lookup(desc);
    -        } else if (self instanceof JSObjectMethod) {
    -            inv = JSObjectMethod.lookup(desc);
             } else {
                 throw new AssertionError(); // Should never reach here.
             }
    @@ -115,7 +83,7 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
                 case "getProp":
                 case "getElem":
                 case "getMethod":
    -                return c > 2 ? findGetMethod(desc, operator) : findGetIndexMethod();
    +                return c > 2 ? findGetMethod(desc) : findGetIndexMethod();
                 case "setProp":
                 case "setElem":
                     return c > 2 ? findSetMethod(desc) : findSetIndexMethod();
    @@ -123,15 +91,14 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
                 case "callMethod":
                     return findCallMethod(desc, operator);
                 case "new":
    +                return findNewMethod(desc);
                 default:
                     return null;
             }
         }
     
    -    private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final String operator) {
    -        // if "getMethod" then return JSObjectMethod object - which just holds the name of the method
    -        // subsequently, link on dyn:call for JSObjectMethod will actually call that method
    -        final MethodHandle getter = MH.insertArguments("getMethod".equals(operator)? JSOBJECT_GETMETHOD : JSOBJECT_GET, 1, desc.getNameToken(2));
    +    private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc) {
    +        final MethodHandle getter = MH.insertArguments(JSOBJECT_GET, 1, desc.getNameToken(2));
             return new GuardedInvocation(getter, null, IS_JSOBJECT_GUARD);
         }
     
    @@ -156,9 +123,9 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
             return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD);
         }
     
    -    @SuppressWarnings("unused")
    -    private static boolean isJSObjectMethod(final Object self) {
    -        return self instanceof JSObjectMethod;
    +    private static GuardedInvocation findNewMethod(final CallSiteDescriptor desc) {
    +        MethodHandle func = MH.asCollector(JSOBJECT_NEW, Object[].class, desc.getMethodType().parameterCount() - 1);
    +        return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD);
         }
     
         @SuppressWarnings("unused")
    @@ -166,12 +133,6 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
             return self instanceof JSObject;
         }
     
    -
    -    @SuppressWarnings("unused")
    -    private static Object getMethod(final Object jsobj, final Object key) {
    -        return new JSObjectMethod(Objects.toString(key));
    -    }
    -
         @SuppressWarnings("unused")
         private static Object get(final Object jsobj, final Object key) {
             if (key instanceof String) {
    @@ -200,11 +161,8 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
         }
     
         @SuppressWarnings("unused")
    -    private static Object jsObjectMethodCall(final Object jsObjMethod, final Object jsobj, final Object... args) {
    -        // we have JSObjectMethod, JSObject and args. Get method name from JSObjectMethod instance
    -        final String methodName = ((JSObjectMethod)jsObjMethod).getName();
    -        // call the method on JSObject
    -        return ((JSObject)jsobj).call(methodName, args);
    +    private static Object newObject(final Object jsobj, final Object... args) {
    +        return ((JSObject)jsobj).newObject(null, args);
         }
     
         private static int getIndex(final Number n) {
    @@ -214,13 +172,11 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
     
         private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
     
    -    private static final MethodHandle IS_JSOBJECTMETHOD_GUARD = findOwnMH("isJSObjectMethod", boolean.class, Object.class);
         private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH("isJSObject", boolean.class, Object.class);
    -    private static final MethodHandle JSOBJECT_GETMETHOD = findOwnMH("getMethod", Object.class, Object.class, Object.class);
         private static final MethodHandle JSOBJECT_GET = findOwnMH("get", Object.class, Object.class, Object.class);
         private static final MethodHandle JSOBJECT_PUT = findOwnMH("put", Void.TYPE, Object.class, Object.class, Object.class);
         private static final MethodHandle JSOBJECT_CALL = findOwnMH("call", Object.class, Object.class, Object.class, Object[].class);
    -    private static final MethodHandle JSOBJECTMETHOD_CALL = findOwnMH("jsObjectMethodCall", Object.class, Object.class, Object.class, Object[].class);
    +    private static final MethodHandle JSOBJECT_NEW = findOwnMH("newObject", Object.class, Object.class, Object[].class);
     
         private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) {
             final Class   own = JSObjectLinker.class;
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
    index f058fa3354f..83c0a5abb00 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
    @@ -42,6 +42,8 @@ parser.error.expected.literal=Expected a literal but found {0}
     parser.error.expected.operand=Expected an operand but found {0}
     parser.error.expected.stmt=Expected statement but found {0}
     parser.error.expected.comma=Expected comma but found {0}
    +parser.error.expected.property.id=Expected property id but found {0}
    +parser.error.expected.lvalue=Expected l-value but found {0}
     parser.error.expected=Expected {0} but found {1}
     parser.error.invalid.return=Invalid return statement
     parser.error.no.func.decl.here=Function declarations can only occur at program or function body level. You should use a function expression here instead.
    diff --git a/nashorn/src/jdk/nashorn/internal/scripts/JO.java b/nashorn/src/jdk/nashorn/internal/scripts/JO.java
    index d698a2637ce..b31df1ae6f1 100644
    --- a/nashorn/src/jdk/nashorn/internal/scripts/JO.java
    +++ b/nashorn/src/jdk/nashorn/internal/scripts/JO.java
    @@ -32,11 +32,14 @@ import jdk.nashorn.internal.runtime.ScriptObject;
      * Empty object class.
      */
     public class JO extends ScriptObject {
    +
    +    private static final PropertyMap map$ = PropertyMap.newMap(JO.class);
    +
         /**
          * Constructor
          */
         public JO() {
    -        super(PropertyMap.newMap(JO.class));
    +        super(map$);
         }
     
         /**
    @@ -48,6 +51,15 @@ public class JO extends ScriptObject {
             super(map);
         }
     
    +    /**
    +     * Constructor given an initial prototype using the default property map
    +     *
    +     * @param proto the prototype object
    +     */
    +    public JO(final ScriptObject proto) {
    +        super(proto, map$);
    +    }
    +
         /**
          * Used by FunctionObjectCreator. A method handle of this method is passed to the ScriptFunction constructor.
          *
    diff --git a/nashorn/test/script/basic/JDK-8010697.js b/nashorn/test/script/basic/JDK-8010697.js
    new file mode 100644
    index 00000000000..c1b8e572937
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8010697.js
    @@ -0,0 +1,59 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8010697: DeletedArrayFilter seems to leak memory
    + *
    + * @test
    + * @run
    + */
    +
    +var N = 1000;
    +
    +var array = new Array(N);
    +var WeakReferenceArray = Java.type("java.lang.ref.WeakReference[]");
    +var refArray = new WeakReferenceArray(N);
    +
    +for (var i = 0; i < N; i ++) {
    +    var object = new java.lang.Object();
    +    array[i] = object;
    +    refArray[i] = new java.lang.ref.WeakReference(object);
    +}
    +
    +object = null;
    +
    +for (var i = 0; i < N; i ++) {
    +    delete array[i];
    +}
    +
    +java.lang.System.gc();
    +java.lang.System.gc();
    +
    +for (var i = 0; i < N; i ++) {
    +    if (refArray[i].get() != null) {
    +        print("Reference found at " + i);
    +        exit(0);
    +    }
    +}
    +
    +print("All references gone");
    diff --git a/nashorn/test/script/basic/JDK-8010697.js.EXPECTED b/nashorn/test/script/basic/JDK-8010697.js.EXPECTED
    new file mode 100644
    index 00000000000..fe74109082d
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8010697.js.EXPECTED
    @@ -0,0 +1 @@
    +All references gone
    diff --git a/nashorn/test/script/basic/JDK-8010732.js b/nashorn/test/script/basic/JDK-8010732.js
    new file mode 100644
    index 00000000000..166acb9e774
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8010732.js
    @@ -0,0 +1,48 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8010732: BigDecimal, BigInteger and Long handling in nashorn
    + *
    + * @test
    + * @run
    + */
    +
    +var x = new java.math.BigDecimal(1111.5);
    +var y = new java.math.BigDecimal(2222.5);
    +
    +print(x);
    +print(y);
    +
    +print(x + y);
    +print(x - y);
    +print(x * y);
    +print(x / y);
    +print(Math.sin(x));
    +
    +print(x.toString());
    +print(y.toString());
    +print(x.class);
    +print(y.class);
    +print(x.doubleValue() + y.doubleValue());
    +
    diff --git a/nashorn/test/script/basic/JDK-8010732.js.EXPECTED b/nashorn/test/script/basic/JDK-8010732.js.EXPECTED
    new file mode 100644
    index 00000000000..5df1cb1d956
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8010732.js.EXPECTED
    @@ -0,0 +1,12 @@
    +1111.5
    +2222.5
    +3334
    +-1111
    +2470308.75
    +0.5001124859392576
    +-0.5841231854504038
    +1111.5
    +2222.5
    +class java.math.BigDecimal
    +class java.math.BigDecimal
    +3334
    diff --git a/nashorn/test/script/basic/JDK-8012164.js b/nashorn/test/script/basic/JDK-8012164.js
    index 6416cfadfdb..62bb09c4b23 100644
    --- a/nashorn/test/script/basic/JDK-8012164.js
    +++ b/nashorn/test/script/basic/JDK-8012164.js
    @@ -37,8 +37,9 @@ function error() {
       try {
           throw new Error('foo');
       } catch (e) {
    -      for (i in e.stack) {
    -          printFrame(e.stack[i]);
    +      var frames = e.getStackTrace();
    +      for (i in frames) {
    +          printFrame(frames[i]);
           }
       }
     }
    diff --git a/nashorn/test/script/basic/JDK-8012164.js.EXPECTED b/nashorn/test/script/basic/JDK-8012164.js.EXPECTED
    index e70edea3c8e..9912edcd509 100644
    --- a/nashorn/test/script/basic/JDK-8012164.js.EXPECTED
    +++ b/nashorn/test/script/basic/JDK-8012164.js.EXPECTED
    @@ -1,3 +1,3 @@
     .error(test/script/basic/JDK-8012164.js:38)
     .func(test/script/basic/JDK-8012164.js:33)
    -.(test/script/basic/JDK-8012164.js:46)
    +.(test/script/basic/JDK-8012164.js:47)
    diff --git a/nashorn/test/script/basic/JDK-8014781.js b/nashorn/test/script/basic/JDK-8014781.js
    new file mode 100644
    index 00000000000..3c6d7d88a46
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8014781.js
    @@ -0,0 +1,40 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8014781: support Error.captureStackTrace
    + *
    + * @test
    + * @run
    + */
    +
    +function MyError() {
    +    Error.captureStackTrace(this);
    +}
    +
    +function func() {
    +    return new MyError();
    +}
    +
    +var e = func();
    +print(e.stack.replace(/\\/g, '/'));
    diff --git a/nashorn/test/script/basic/JDK-8014781.js.EXPECTED b/nashorn/test/script/basic/JDK-8014781.js.EXPECTED
    new file mode 100644
    index 00000000000..d3586c0ee67
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8014781.js.EXPECTED
    @@ -0,0 +1,4 @@
    +[object Object]
    +	at MyError (test/script/basic/JDK-8014781.js:32)
    +	at func (test/script/basic/JDK-8014781.js:36)
    +	at  (test/script/basic/JDK-8014781.js:39)
    diff --git a/nashorn/test/script/basic/JDK-8015347.js b/nashorn/test/script/basic/JDK-8015347.js
    new file mode 100644
    index 00000000000..d5a8ba318c0
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8015347.js
    @@ -0,0 +1,39 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8015347: Parsing issue with decodeURIComponent
    + *
    + * @test
    + * @run
    + */
    +
    +try {
    +    decodeURIComponent("%C0%80");
    +    fail("Should have thrown URIError");
    +} catch (e) {
    +    if (! (e instanceof URIError)) {
    +        fail("Expected URIError, but got " + e);
    +    }
    +}
    +
    diff --git a/nashorn/test/script/basic/JDK-8015959.js b/nashorn/test/script/basic/JDK-8015959.js
    new file mode 100644
    index 00000000000..c5322e3e149
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8015959.js
    @@ -0,0 +1,54 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8015959: Can't call foreign constructor
    + *
    + * @test
    + * @run
    + */
    +
    +function check(global) {
    +    var obj = new global.Point(344, 12);
    +    print("obj.x " + obj.x);
    +    print("obj.y " + obj.y);
    +    print("obj instanceof global.Point? " + (obj instanceof global.Point))
    +
    +    var P = global.Point;
    +    var p = new P(343, 54);
    +    print("p.x " + p.x);
    +    print("p.y " + p.y);
    +    print("p instanceof P? " + (p instanceof P))
    +}
    +
    +print("check with loadWithNewGlobal");
    +check(loadWithNewGlobal({
    +   name: "myscript",
    +   script: "function Point(x, y) { this.x = x; this.y = y }; this"
    +}));
    +
    +print("check with script engine");
    +var m = new javax.script.ScriptEngineManager();
    +var e = m.getEngineByName('nashorn');
    +check(e.eval("function Point(x, y) { this.x = x; this.y = y }; this"));
    +
    diff --git a/nashorn/test/script/basic/JDK-8015959.js.EXPECTED b/nashorn/test/script/basic/JDK-8015959.js.EXPECTED
    new file mode 100644
    index 00000000000..e5a00a9540d
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8015959.js.EXPECTED
    @@ -0,0 +1,14 @@
    +check with loadWithNewGlobal
    +obj.x 344
    +obj.y 12
    +obj instanceof global.Point? true
    +p.x 343
    +p.y 54
    +p instanceof P? true
    +check with script engine
    +obj.x 344
    +obj.y 12
    +obj instanceof global.Point? true
    +p.x 343
    +p.y 54
    +p instanceof P? true
    diff --git a/nashorn/test/script/basic/JDK-8015969.js b/nashorn/test/script/basic/JDK-8015969.js
    new file mode 100644
    index 00000000000..a9813773dfa
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8015969.js
    @@ -0,0 +1,75 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8015969: Needs to enforce and document that global "context" and "engine" can't be modified when running via jsr223
    + *
    + * @test
    + * @option -scripting
    + * @run
    + */
    +
    +var m = new javax.script.ScriptEngineManager();
    +var e = m.getEngineByName("nashorn");
    +
    +e.eval(<>e>>>0;
    +    var x = [z];
    +}
    diff --git a/nashorn/test/script/basic/JDK-8017950.js b/nashorn/test/script/basic/JDK-8017950.js
    new file mode 100644
    index 00000000000..c84eacc57f0
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8017950.js
    @@ -0,0 +1,47 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8017950: error.stack should be a string rather than an array
    + *
    + * @test
    + * @run
    + */
    +
    +function func() {
    +    try {
    +        throw new Error();
    +    } catch (e){
    +        print(e.stack.replace(/\\/g, '/'))
    +    }
    +}
    +
    +function f() { 
    +    func()
    +}
    +
    +function g() {
    +    f()
    +}
    +
    +g()
    diff --git a/nashorn/test/script/basic/JDK-8017950.js.EXPECTED b/nashorn/test/script/basic/JDK-8017950.js.EXPECTED
    new file mode 100644
    index 00000000000..8c34d21343f
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8017950.js.EXPECTED
    @@ -0,0 +1,5 @@
    +Error
    +	at func (test/script/basic/JDK-8017950.js:33)
    +	at f (test/script/basic/JDK-8017950.js:40)
    +	at g (test/script/basic/JDK-8017950.js:44)
    +	at  (test/script/basic/JDK-8017950.js:47)
    diff --git a/nashorn/test/script/basic/JDK-8019226.js b/nashorn/test/script/basic/JDK-8019226.js
    new file mode 100644
    index 00000000000..3a1cf2f901b
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019226.js
    @@ -0,0 +1,39 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8019226: line number not generated for first statement if it is on the same function declaration line 
    + *
    + * @test
    + * @run
    + */
    +
    +function func1() { func2() }
    +
    +function func2() { throw new Error("failed!") }
    +
    +try {
    +    func1()
    +} catch (e) {
    +    print(e.stack.replace(/\\/g, '/'))
    +}
    diff --git a/nashorn/test/script/basic/JDK-8019226.js.EXPECTED b/nashorn/test/script/basic/JDK-8019226.js.EXPECTED
    new file mode 100644
    index 00000000000..002a3ddbf0e
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019226.js.EXPECTED
    @@ -0,0 +1,4 @@
    +Error: failed!
    +	at func2 (test/script/basic/JDK-8019226.js:33)
    +	at func1 (test/script/basic/JDK-8019226.js:31)
    +	at  (test/script/basic/JDK-8019226.js:36)
    diff --git a/nashorn/test/script/basic/JDK-8019473.js b/nashorn/test/script/basic/JDK-8019473.js
    new file mode 100644
    index 00000000000..5001f3d7311
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019473.js
    @@ -0,0 +1,62 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8019473: Parser issues related to functions and blocks
    + *
    + * @test
    + * @run
    + */
    +
    +function checkNoError(code) {
    +    try {
    +        Function(code);
    +    } catch (e) {
    +        print("no error expected for: " + code + " , got " + e);
    +    }
    +}
    +
    +// implicit newlines at EOF should be accepted
    +checkNoError("for(;;) continue")
    +checkNoError("return")
    +checkNoError("yield")
    +checkNoError("for(;;) break")
    +
    +function checkError(code) {
    +    try {
    +        eval(code);
    +        print("SyntaxError expected for: " + code);
    +    } catch (e) {
    +        if (! (e instanceof SyntaxError)) {
    +            fail("SyntaxError expected, got " + e);
    +        }
    +    }
    +}
    +
    +checkError("function f() { case0: }");
    +checkError("function f() { if(0) }");
    +checkError("function f() { if(0); else }");
    +checkError("function f() { while(0) }");
    +
    +// comma expression as closure expression
    +checkError("function sq(x) x, x*x");
    diff --git a/nashorn/test/script/basic/JDK-8019478.js b/nashorn/test/script/basic/JDK-8019478.js
    new file mode 100644
    index 00000000000..f5e2a645214
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019478.js
    @@ -0,0 +1,33 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8019478: Object.prototype.toString.call(/a/.exec("a")) === "[object Array]" should be true
    + *
    + * @test
    + * @run
    + */
    +
    +if (Object.prototype.toString.call(/a/.exec("a")) !== "[object Array]") {
    +    fail("Object.prototype.toString.call(/a/.exec('a')) !== '[object Array]'");
    +}
    diff --git a/nashorn/test/script/basic/JDK-8019482.js b/nashorn/test/script/basic/JDK-8019482.js
    new file mode 100644
    index 00000000000..09f91e42ea9
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019482.js
    @@ -0,0 +1,41 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8019482: Number("0x0.0p0") should evaluate to NaN
    + *
    + * @test
    + * @run
    + */
    +
    +function checkHexLiteral(str) {
    +    if (! isNaN(Number(str))) {
    +        fail("Number(" + str + ") is not NaN");
    +    }
    +}
    +
    +checkHexLiteral("0x0.0");
    +checkHexLiteral("0x0.0p");
    +checkHexLiteral("0x12tu");
    +checkHexLiteral("0x12.2e22");
    +checkHexLiteral("0xtu");
    diff --git a/nashorn/test/script/basic/JDK-8019488.js b/nashorn/test/script/basic/JDK-8019488.js
    new file mode 100644
    index 00000000000..0cb58e9087f
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019488.js
    @@ -0,0 +1,68 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8019488: switch on literals result in NoSuchMethodError or VerifyError
    + *
    + * @test
    + * @run
    + */
    +
    +switch("") {
    +    case 0:
    +        break
    +}
    +
    +switch(true) {
    +    case 0:
    +        print("0"); break;
    +    case 1:
    +        print("1"); break;
    +}
    +
    +switch(false) {
    +    case 0:
    +        print("0"); break;
    +    case 1:
    +        print("1"); break;
    +}
    +
    +switch([]) {
    +    case 1:
    +        print("1");
    +}
    +
    +switch (undefined) {
    +    case 0:
    +        print("0");
    +}
    +
    +switch (null) {
    +    case 0:
    +        print("0");
    +}
    +
    +switch({}) {
    +    case 1:
    +        print("1");
    +}
    diff --git a/nashorn/test/script/basic/JDK-8019508.js b/nashorn/test/script/basic/JDK-8019508.js
    new file mode 100644
    index 00000000000..d23035c638a
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019508.js
    @@ -0,0 +1,56 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8019508: Comma handling in object literal parsing is wrong
    + *
    + * @test
    + * @run
    + */
    +
    +function checkObjLiteral(str) {
    +    try {
    +        eval(str);
    +        fail("SyntaxError expected for: " + str);
    +    } catch (e) {
    +        if (! (e instanceof SyntaxError)) {
    +            fail("expected SyntaxError, got " + e);
    +        }
    +        print(e.message.replace(/\\/g, '/'));
    +    }
    +}
    +
    +// only comma
    +checkObjLiteral("({,})");
    +
    +// starting with comma
    +checkObjLiteral("({, a:2 })");
    +
    +// consecutive commas
    +checkObjLiteral("({a:3,,})");
    +
    +// missing comma
    +checkObjLiteral("({a:3 b:2}");
    +
    +// single trailing comma is okay!
    +var obj = { a: 3, };
    diff --git a/nashorn/test/script/basic/JDK-8019508.js.EXPECTED b/nashorn/test/script/basic/JDK-8019508.js.EXPECTED
    new file mode 100644
    index 00000000000..d5f81409803
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019508.js.EXPECTED
    @@ -0,0 +1,12 @@
    +test/script/basic/JDK-8019508.js#33:1:2 Expected property id but found ,
    +({,})
    +  ^
    +test/script/basic/JDK-8019508.js#33:1:2 Expected property id but found ,
    +({, a:2 })
    +  ^
    +test/script/basic/JDK-8019508.js#33:1:6 Expected property id but found ,
    +({a:3,,})
    +      ^
    +test/script/basic/JDK-8019508.js#33:1:6 Expected comma but found ident
    +({a:3 b:2}
    +      ^
    diff --git a/nashorn/test/script/basic/JDK-8019553.js b/nashorn/test/script/basic/JDK-8019553.js
    new file mode 100644
    index 00000000000..d754618718a
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019553.js
    @@ -0,0 +1,43 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8019553:  NPE on illegal l-value for increment and decrement
    + *
    + * @test
    + * @run
    + */
    +
    +function check(str) {
    +    try {
    +        eval(str);
    +        fail("SyntaxError expected for: " + str);
    +    } catch (e) {
    +        print(e.toString().replace(/\\/g, '/'));
    +    }
    +}
    +
    +check("++ +3");
    +check("++ -7");
    +check("-- +2");
    +check("-- -8");
    diff --git a/nashorn/test/script/basic/JDK-8019553.js.EXPECTED b/nashorn/test/script/basic/JDK-8019553.js.EXPECTED
    new file mode 100644
    index 00000000000..78d22beac0f
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019553.js.EXPECTED
    @@ -0,0 +1,12 @@
    +SyntaxError: test/script/basic/JDK-8019553.js#33:1:3 Expected l-value but found +
    +++ +3
    +   ^
    +SyntaxError: test/script/basic/JDK-8019553.js#33:1:3 Expected l-value but found -
    +++ -7
    +   ^
    +SyntaxError: test/script/basic/JDK-8019553.js#33:1:3 Expected l-value but found +
    +-- +2
    +   ^
    +SyntaxError: test/script/basic/JDK-8019553.js#33:1:3 Expected l-value but found -
    +-- -8
    +   ^
    diff --git a/nashorn/test/script/basic/NASHORN-109.js b/nashorn/test/script/basic/NASHORN-109.js
    index b05e0f12e50..4667feb21de 100644
    --- a/nashorn/test/script/basic/NASHORN-109.js
    +++ b/nashorn/test/script/basic/NASHORN-109.js
    @@ -33,8 +33,9 @@ try {
             throw new Error("error");
         }
     } catch (e) {
    -    for (i in e.stack) { 
    -        print(e.stack[i].methodName + ' ' + e.stack[i].lineNumber);
    +    var frames = e.getStackTrace();
    +    for (i in frames) {
    +        print(frames[i].methodName + ' ' + frames[i].lineNumber);
         }
     }
     
    diff --git a/nashorn/test/script/basic/NASHORN-296.js b/nashorn/test/script/basic/NASHORN-296.js
    index cbb752fbcaa..26338e60f56 100644
    --- a/nashorn/test/script/basic/NASHORN-296.js
    +++ b/nashorn/test/script/basic/NASHORN-296.js
    @@ -33,7 +33,7 @@ function test(name) {
             load({ script: 'throw new Error()', name: name });
         } catch(e) {
             // normalize windows path separator to URL style
    -        var actual = e.stack[0].fileName;
    +        var actual = e.getStackTrace()[0].fileName;
             if (actual !== name) {
                 fail("expected file name to be " + name +
                      ", actually got file name " + actual);
    @@ -48,6 +48,6 @@ test("com/oracle/node/sample.js");
     try {
         throw new Error();
     } catch (e) {
    -    test(e.stack[0].fileName.substring(6));
    +    test(e.getStackTrace()[0].fileName.substring(6));
     }
     
    diff --git a/nashorn/test/script/basic/NASHORN-51.js b/nashorn/test/script/basic/NASHORN-51.js
    index 044bce94062..bc41d79bebf 100644
    --- a/nashorn/test/script/basic/NASHORN-51.js
    +++ b/nashorn/test/script/basic/NASHORN-51.js
    @@ -35,28 +35,28 @@ for (i in literals) {
             eval(literals[i] + "++");
             print("ERROR!! post increment : " + literals[i]);
         } catch (e) {
    -        print(e);
    +        print(e.toString().replace(/\\/g, '/'));
         }
     
         try {
             eval(literals[i] + "--");
             print("ERROR!! post decrement : " + literals[i]);
         } catch (e) {
    -        print(e);
    +        print(e.toString().replace(/\\/g, '/'));
         }
     
         try {
             eval("++" + literals[i]);
             print("ERROR!! pre increment : " + literals[i]);
         } catch (e) {
    -        print(e);
    +        print(e.toString().replace(/\\/g, '/'));
         }
     
         try {
             eval("--" + literals[i]);
             print("ERROR!! pre decrement : " + literals[i]);
         } catch (e) {
    -        print(e);
    +        print(e.toString().replace(/\\/g, '/'));
         }
     }
     
    diff --git a/nashorn/test/script/basic/NASHORN-51.js.EXPECTED b/nashorn/test/script/basic/NASHORN-51.js.EXPECTED
    index 9fc05c3f1b4..9479f7e1995 100644
    --- a/nashorn/test/script/basic/NASHORN-51.js.EXPECTED
    +++ b/nashorn/test/script/basic/NASHORN-51.js.EXPECTED
    @@ -1,24 +1,72 @@
    -ReferenceError: "1" can not be used as the left-hand side of assignment
    -ReferenceError: "1" can not be used as the left-hand side of assignment
    -ReferenceError: "1" can not be used as the left-hand side of assignment
    -ReferenceError: "1" can not be used as the left-hand side of assignment
    -ReferenceError: "0" can not be used as the left-hand side of assignment
    -ReferenceError: "0" can not be used as the left-hand side of assignment
    -ReferenceError: "0" can not be used as the left-hand side of assignment
    -ReferenceError: "0" can not be used as the left-hand side of assignment
    -ReferenceError: "3.14" can not be used as the left-hand side of assignment
    -ReferenceError: "3.14" can not be used as the left-hand side of assignment
    -ReferenceError: "3.14" can not be used as the left-hand side of assignment
    -ReferenceError: "3.14" can not be used as the left-hand side of assignment
    -ReferenceError: "true" can not be used as the left-hand side of assignment
    -ReferenceError: "true" can not be used as the left-hand side of assignment
    -ReferenceError: "true" can not be used as the left-hand side of assignment
    -ReferenceError: "true" can not be used as the left-hand side of assignment
    -ReferenceError: "false" can not be used as the left-hand side of assignment
    -ReferenceError: "false" can not be used as the left-hand side of assignment
    -ReferenceError: "false" can not be used as the left-hand side of assignment
    -ReferenceError: "false" can not be used as the left-hand side of assignment
    -ReferenceError: "null" can not be used as the left-hand side of assignment
    -ReferenceError: "null" can not be used as the left-hand side of assignment
    -ReferenceError: "null" can not be used as the left-hand side of assignment
    -ReferenceError: "null" can not be used as the left-hand side of assignment
    +ReferenceError: test/script/basic/NASHORN-51.js#35:1:0 Invalid left hand side for assignment
    +1++
    +^
    +ReferenceError: test/script/basic/NASHORN-51.js#42:1:0 Invalid left hand side for assignment
    +1--
    +^
    +ReferenceError: test/script/basic/NASHORN-51.js#49:1:2 Invalid left hand side for assignment
    +++1
    +  ^
    +ReferenceError: test/script/basic/NASHORN-51.js#56:1:2 Invalid left hand side for assignment
    +--1
    +  ^
    +ReferenceError: test/script/basic/NASHORN-51.js#35:1:0 Invalid left hand side for assignment
    +0++
    +^
    +ReferenceError: test/script/basic/NASHORN-51.js#42:1:0 Invalid left hand side for assignment
    +0--
    +^
    +ReferenceError: test/script/basic/NASHORN-51.js#49:1:2 Invalid left hand side for assignment
    +++0
    +  ^
    +ReferenceError: test/script/basic/NASHORN-51.js#56:1:2 Invalid left hand side for assignment
    +--0
    +  ^
    +ReferenceError: test/script/basic/NASHORN-51.js#35:1:0 Invalid left hand side for assignment
    +3.14++
    +^
    +ReferenceError: test/script/basic/NASHORN-51.js#42:1:0 Invalid left hand side for assignment
    +3.14--
    +^
    +ReferenceError: test/script/basic/NASHORN-51.js#49:1:2 Invalid left hand side for assignment
    +++3.14
    +  ^
    +ReferenceError: test/script/basic/NASHORN-51.js#56:1:2 Invalid left hand side for assignment
    +--3.14
    +  ^
    +ReferenceError: test/script/basic/NASHORN-51.js#35:1:0 Invalid left hand side for assignment
    +true++
    +^
    +ReferenceError: test/script/basic/NASHORN-51.js#42:1:0 Invalid left hand side for assignment
    +true--
    +^
    +ReferenceError: test/script/basic/NASHORN-51.js#49:1:2 Invalid left hand side for assignment
    +++true
    +  ^
    +ReferenceError: test/script/basic/NASHORN-51.js#56:1:2 Invalid left hand side for assignment
    +--true
    +  ^
    +ReferenceError: test/script/basic/NASHORN-51.js#35:1:0 Invalid left hand side for assignment
    +false++
    +^
    +ReferenceError: test/script/basic/NASHORN-51.js#42:1:0 Invalid left hand side for assignment
    +false--
    +^
    +ReferenceError: test/script/basic/NASHORN-51.js#49:1:2 Invalid left hand side for assignment
    +++false
    +  ^
    +ReferenceError: test/script/basic/NASHORN-51.js#56:1:2 Invalid left hand side for assignment
    +--false
    +  ^
    +ReferenceError: test/script/basic/NASHORN-51.js#35:1:0 Invalid left hand side for assignment
    +null++
    +^
    +ReferenceError: test/script/basic/NASHORN-51.js#42:1:0 Invalid left hand side for assignment
    +null--
    +^
    +ReferenceError: test/script/basic/NASHORN-51.js#49:1:2 Invalid left hand side for assignment
    +++null
    +  ^
    +ReferenceError: test/script/basic/NASHORN-51.js#56:1:2 Invalid left hand side for assignment
    +--null
    +  ^
    diff --git a/nashorn/test/script/basic/errorstack.js b/nashorn/test/script/basic/errorstack.js
    index 7db53142c10..8fcd25a2e1b 100644
    --- a/nashorn/test/script/basic/errorstack.js
    +++ b/nashorn/test/script/basic/errorstack.js
    @@ -22,7 +22,7 @@
      */
     
     /**
    - * "stack" property of Error objects. (nashorn extension).
    + * "getStackTrace()" method of Error objects. (nashorn extension).
      *
      * @test
      * @run
    @@ -43,9 +43,9 @@ function func3() {
     try {
         func1();
     } catch (e) {
    -    // "stack" is java.lang.StackTraceElement object
    -    for (i in e.stack) {
    -        print(e.stack[i].methodName + " : " + e.stack[i].lineNumber);
    +    var frames = e.getStackTrace();
    +    for (i in frames) {
    +        print(frames[i].methodName + " : " + frames[i].lineNumber);
         }
     }
     
    diff --git a/nashorn/test/script/error/NASHORN-57.js.EXPECTED b/nashorn/test/script/error/NASHORN-57.js.EXPECTED
    index 5a93b597c0e..c9c51de1292 100644
    --- a/nashorn/test/script/error/NASHORN-57.js.EXPECTED
    +++ b/nashorn/test/script/error/NASHORN-57.js.EXPECTED
    @@ -1,3 +1,3 @@
    -test/script/error/NASHORN-57.js:35:2 Expected statement but found ;
    +test/script/error/NASHORN-57.js:35:2 Expected l-value but found ;
     ++;
       ^
    diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java
    index 2cfdbf00046..b6e5bbcddc9 100644
    --- a/nashorn/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java
    +++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java
    @@ -39,7 +39,7 @@ import org.testng.annotations.Test;
     /**
      * @test
      * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.BooleanAccessTest
    - * @run testng jdk.nashorn.api.javaaccess.BooleanAccessTest
    + * @run testng/othervm jdk.nashorn.api.javaaccess.BooleanAccessTest
      */
     public class BooleanAccessTest {
     
    diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java
    index 69ca20c6c16..6de10a54783 100644
    --- a/nashorn/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java
    +++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java
    @@ -42,7 +42,7 @@ import org.testng.annotations.Test;
     /**
      * @test
      * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.MethodAccessTest
    - * @run testng jdk.nashorn.api.javaaccess.MethodAccessTest
    + * @run testng/othervm jdk.nashorn.api.javaaccess.MethodAccessTest
      */
     public class MethodAccessTest {
     
    diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java
    index 21994960176..0b7cb027b61 100644
    --- a/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java
    +++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java
    @@ -39,7 +39,7 @@ import org.testng.annotations.Test;
     /**
      * @test
      * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.NumberAccessTest
    - * @run testng jdk.nashorn.api.javaaccess.NumberAccessTest
    + * @run testng/othervm jdk.nashorn.api.javaaccess.NumberAccessTest
      */
     public class NumberAccessTest {
     
    diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java
    index ae719e7fb62..0302259e95b 100644
    --- a/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java
    +++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java
    @@ -38,7 +38,7 @@ import org.testng.annotations.Test;
     /**
      * @test
      * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.NumberBoxingTest
    - * @run testng jdk.nashorn.api.javaaccess.NumberBoxingTest
    + * @run testng/othervm jdk.nashorn.api.javaaccess.NumberBoxingTest
      */
     public class NumberBoxingTest {
     
    diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java
    index 7172051416c..2a51e7a9ce1 100644
    --- a/nashorn/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java
    +++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java
    @@ -38,7 +38,7 @@ import org.testng.annotations.Test;
     /**
      * @test
      * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.ObjectAccessTest
    - * @run testng jdk.nashorn.api.javaaccess.ObjectAccessTest
    + * @run testng/othervm jdk.nashorn.api.javaaccess.ObjectAccessTest
      */
     public class ObjectAccessTest {
     
    diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java
    index 6a7713bd6a4..dd4b5020787 100644
    --- a/nashorn/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java
    +++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java
    @@ -38,7 +38,7 @@ import org.testng.annotations.Test;
     /**
      * @test
      * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.StringAccessTest
    - * @run testng jdk.nashorn.api.javaaccess.StringAccessTest
    + * @run testng/othervm jdk.nashorn.api.javaaccess.StringAccessTest
      */
     public class StringAccessTest {
     
    

Attribute views

Description

Attribute viewsDescription
{@link java.nio.file.attribute.AttributeView}Can read or update non-opaque values associated with objects in a file system
  {@link java.nio.file.attribute.FileAttributeView}Can read or update POSIX defined file attributes
      {@link java.nio.file.attribute.DosFileAttributeView}  Can read or update FAT file attributes
    {@link java.nio.file.attribute.FileOwnerAttributeView}  
    {@link java.nio.file.attribute.FileOwnerAttributeView}  Can read or update the owner of a file
     {@link java.nio.file.attribute.AclFileAttributeView}  Can read or update Access Control Lists
Hijrah-umalquraislamic-umalquraca-islamic-cv-umalquraca-islamic-umalquraIslamic - Umm Al-Qura calendar of Saudi Arabia