--- a/.hgtags Tue Dec 05 10:21:41 2017 +0000
+++ b/.hgtags Tue Dec 05 10:28:45 2017 +0000
@@ -458,3 +458,4 @@
e6278add9ff28fab70fe1cc4c1d65f7363dc9445 jdk-10+31
a2008587c13fa05fa2dbfcb09fe987576fbedfd1 jdk-10+32
bbd692ad4fa300ecca7939ffbe3b1d5e52a28cc6 jdk-10+33
+89deac44e51517841491ba86ff44aa82a5ca96b3 jdk-10+34
--- a/doc/testing.html Tue Dec 05 10:21:41 2017 +0000
+++ b/doc/testing.html Tue Dec 05 10:28:45 2017 +0000
@@ -57,6 +57,7 @@
<h3 id="gtest">Gtest</h3>
<p>Since the Hotspot Gtest suite is so quick, the default is to run all tests. This is specified by just <code>gtest</code>, or as a fully qualified test descriptor <code>gtest:all</code>.</p>
<p>If you want, you can single out an individual test or a group of tests, for instance <code>gtest:LogDecorations</code> or <code>gtest:LogDecorations.level_test_vm</code>. This can be particularly useful if you want to run a shaky test repeatedly.</p>
+<p>For Gtest, there is a separate test suite for each JVM variant. The JVM variant is defined by adding <code>/<variant></code> to the test descriptor, e.g. <code>gtest:Log/client</code>. If you specify no variant, gtest will run once for each JVM variant present (e.g. server, client). So if you only have the server JVM present, then <code>gtest:all</code> will be equivalent to <code>gtest:all/server</code>.</p>
<h2 id="test-results-and-summary">Test results and summary</h2>
<p>At the end of the test run, a summary of all tests run will be presented. This will have a consistent look, regardless of what test suites were used. This is a sample summary:</p>
<pre><code>==============================
--- a/doc/testing.md Tue Dec 05 10:21:41 2017 +0000
+++ b/doc/testing.md Tue Dec 05 10:28:45 2017 +0000
@@ -81,6 +81,12 @@
instance `gtest:LogDecorations` or `gtest:LogDecorations.level_test_vm`. This
can be particularly useful if you want to run a shaky test repeatedly.
+For Gtest, there is a separate test suite for each JVM variant. The JVM variant
+is defined by adding `/<variant>` to the test descriptor, e.g.
+`gtest:Log/client`. If you specify no variant, gtest will run once for each JVM
+variant present (e.g. server, client). So if you only have the server JVM
+present, then `gtest:all` will be equivalent to `gtest:all/server`.
+
## Test results and summary
At the end of the test run, a summary of all tests run will be presented. This
--- a/make/CompileJavaModules.gmk Tue Dec 05 10:21:41 2017 +0000
+++ b/make/CompileJavaModules.gmk Tue Dec 05 10:28:45 2017 +0000
@@ -300,7 +300,9 @@
################################################################################
-java.xml_SETUP := GENERATE_JDKBYTECODE_NOWARNINGS
+java.xml_ADD_JAVAC_FLAGS += -Xdoclint:all/protected \
+ '-Xdoclint/package:$(call CommaList, javax.xml.catalog javax.xml.datatype \
+ javax.xml.transform javax.xml.validation javax.xml.xpath)'
java.xml_CLEAN += .properties
################################################################################
--- a/make/InitSupport.gmk Tue Dec 05 10:21:41 2017 +0000
+++ b/make/InitSupport.gmk Tue Dec 05 10:28:45 2017 +0000
@@ -279,7 +279,9 @@
# generated files.
ifeq ($$(MAKE_RESTARTS),)
ifeq ($$(words $$(matching_confs)), 1)
- $$(info Building configuration '$$(matching_confs)' (matching CONF=$$(CONF)))
+ ifneq ($$(findstring $$(LOG_LEVEL), info debug trace),)
+ $$(info Building configuration '$$(matching_confs)' (matching CONF=$$(CONF)))
+ endif
else
$$(info Building these configurations (matching CONF=$$(CONF)):)
$$(foreach var, $$(matching_confs), $$(info * $$(var)))
--- a/make/RunTests.gmk Tue Dec 05 10:21:41 2017 +0000
+++ b/make/RunTests.gmk Tue Dec 05 10:28:45 2017 +0000
@@ -68,6 +68,7 @@
TEST_RESULTS_DIR := $(OUTPUTDIR)/test-results
TEST_SUPPORT_DIR := $(OUTPUTDIR)/test-support
TEST_SUMMARY := $(TEST_RESULTS_DIR)/test-summary.txt
+TEST_LAST_IDS := $(TEST_SUPPORT_DIR)/test-last-ids.txt
ifeq ($(CUSTOM_ROOT), )
JTREG_TOPDIR := $(TOPDIR)
@@ -87,6 +88,9 @@
-timeoutHandlerTimeout:0
endif
+GTEST_LAUNCHER_DIRS := $(patsubst %/gtestLauncher, %, $(wildcard $(TEST_IMAGE_DIR)/hotspot/gtest/*/gtestLauncher))
+GTEST_VARIANTS := $(strip $(patsubst $(TEST_IMAGE_DIR)/hotspot/gtest/%, %, $(GTEST_LAUNCHER_DIRS)))
+
################################################################################
# Parse control variables
################################################################################
@@ -165,16 +169,23 @@
# Helper function to determine if a test specification is a Gtest test
#
# It is a Gtest test if it is either "gtest", or "gtest:" followed by an optional
-# test filter string.
+# test filter string, and an optional "/<variant>" to select a specific JVM
+# variant. If no variant is specified, all found variants are tested.
define ParseGtestTestSelection
$(if $(filter gtest%, $1), \
$(if $(filter gtest, $1), \
- gtest:all \
+ $(addprefix gtest:all/, $(GTEST_VARIANTS)) \
, \
- $(if $(filter gtest:, $1), \
- gtest:all \
+ $(if $(strip $(or $(filter gtest/%, $1) $(filter gtest:/%, $1))), \
+ $(patsubst gtest:/%, gtest:all/%, $(patsubst gtest/%, gtest:/%, $1)) \
, \
- $1 \
+ $(if $(filter gtest:%, $1), \
+ $(if $(findstring /, $1), \
+ $1 \
+ , \
+ $(addprefix $1/, $(GTEST_VARIANTS)) \
+ ) \
+ ) \
) \
) \
)
@@ -228,7 +239,8 @@
$(if $(findstring :, $(TEST_NAME)), \
$(if $(filter :%, $(TEST_NAME)), \
$(eval TEST_GROUP := $(patsubst :%, %, $(TEST_NAME))) \
- $(eval TEST_ROOTS := $(JTREG_TESTROOTS)) \
+ $(eval TEST_ROOTS := $(foreach test_root, $(JTREG_TESTROOTS), \
+ $(call CleanupJtregPath, $(test_root)))) \
, \
$(eval TEST_PATH := $(word 1, $(subst :, $(SPACE), $(TEST_NAME)))) \
$(eval TEST_GROUP := $(word 2, $(subst :, $(SPACE), $(TEST_NAME)))) \
@@ -251,6 +263,15 @@
)
endef
+# Helper function to determine if a test specification is a special test
+#
+# It is a special test if it is "special:" followed by a test name.
+define ParseSpecialTestSelection
+ $(if $(filter special:%, $1), \
+ $1 \
+ )
+endef
+
ifeq ($(TEST), )
$(info No test selection given in TEST!)
$(info Please use e.g. 'run-test TEST=tier1' or 'run-test-tier1')
@@ -270,6 +291,9 @@
$(eval PARSED_TESTS += $(call ParseJtregTestSelection, $(test))) \
) \
$(if $(strip $(PARSED_TESTS)), , \
+ $(eval PARSED_TESTS += $(call ParseSpecialTestSelection, $(test))) \
+ ) \
+ $(if $(strip $(PARSED_TESTS)), , \
$(eval UNKNOWN_TEST := $(test)) \
) \
$(eval TESTS_TO_RUN += $(PARSED_TESTS)) \
@@ -316,8 +340,14 @@
define SetupRunGtestTestBody
$1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1
$1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1
+ $1_EXITCODE := $$($1_TEST_RESULTS_DIR)/exitcode.txt
- $1_TEST_NAME := $$(strip $$(patsubst gtest:%, %, $$($1_TEST)))
+ $1_VARIANT := $$(lastword $$(subst /, , $$($1_TEST)))
+ ifeq ($$(filter $$($1_VARIANT), $$(GTEST_VARIANTS)), )
+ $$(error Invalid gtest variant '$$($1_VARIANT)'. Valid variants: $$(GTEST_VARIANTS))
+ endif
+ $1_TEST_NAME := $$(strip $$(patsubst %/$$($1_VARIANT), %, \
+ $$(patsubst gtest:%, %, $$($1_TEST))))
ifneq ($$($1_TEST_NAME), all)
$1_GTEST_FILTER := --gtest_filter=$$($1_TEST_NAME)*
endif
@@ -331,11 +361,14 @@
$$(call LogWarn, Running test '$$($1_TEST)')
$$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR))
$$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/gtest, \
- $$(FIXPATH) $$(TEST_IMAGE_DIR)/hotspot/gtest/server/gtestLauncher \
- -jdk $(JDK_IMAGE_DIR) $$($1_GTEST_FILTER) \
- --gtest_output=xml:$$($1_TEST_RESULTS_DIR)/gtest.xml \
- $$($1_GTEST_REPEAT) $$(GTEST_OPTIONS) $$(GTEST_VM_OPTIONS) \
- > >($(TEE) $$($1_TEST_RESULTS_DIR)/gtest.txt) || true )
+ $$(FIXPATH) $$(TEST_IMAGE_DIR)/hotspot/gtest/$$($1_VARIANT)/gtestLauncher \
+ -jdk $(JDK_IMAGE_DIR) $$($1_GTEST_FILTER) \
+ --gtest_output=xml:$$($1_TEST_RESULTS_DIR)/gtest.xml \
+ $$($1_GTEST_REPEAT) $$(GTEST_OPTIONS) $$(GTEST_VM_OPTIONS) \
+ > >($(TEE) $$($1_TEST_RESULTS_DIR)/gtest.txt) \
+ && $$(ECHO) $$$$? > $$($1_EXITCODE) \
+ || $$(ECHO) $$$$? > $$($1_EXITCODE) \
+ )
$1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/gtest.txt
@@ -343,7 +376,7 @@
$$(call LogWarn, Finished running test '$$($1_TEST)')
$$(call LogWarn, Test report is stored in $$(strip \
$$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR))))
- $$(if $$(wildcard $$($1_RESULT_FILE)), \
+ $$(if $$(wildcard $$($1_RESULT_FILE)), \
$$(eval $1_TOTAL := $$(shell $$(AWK) '/==========.* tests? from .* \
test cases? ran/ { print $$$$2 }' $$($1_RESULT_FILE))) \
$$(if $$($1_TOTAL), , $$(eval $1_TOTAL := 0)) \
@@ -398,6 +431,7 @@
define SetupRunJtregTestBody
$1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1
$1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1
+ $1_EXITCODE := $$($1_TEST_RESULTS_DIR)/exitcode.txt
$1_TEST_NAME := $$(strip $$(patsubst jtreg:%, %, $$($1_TEST)))
@@ -505,7 +539,10 @@
-workDir:$$($1_TEST_SUPPORT_DIR) \
$$(JTREG_OPTIONS) \
$$(JTREG_FAILURE_HANDLER_OPTIONS) \
- $$($1_TEST_NAME) || true )
+ $$($1_TEST_NAME) \
+ && $$(ECHO) $$$$? > $$($1_EXITCODE) \
+ || $$(ECHO) $$$$? > $$($1_EXITCODE) \
+ )
$1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/text/stats.txt
@@ -513,7 +550,7 @@
$$(call LogWarn, Finished running test '$$($1_TEST)')
$$(call LogWarn, Test report is stored in $$(strip \
$$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR))))
- $$(if $$(wildcard $$($1_RESULT_FILE)), \
+ $$(if $$(wildcard $$($1_RESULT_FILE)), \
$$(eval $1_PASSED := $$(shell $$(AWK) '{ gsub(/[,;]/, ""); \
for (i=1; i<=NF; i++) { if ($$$$i == "passed:") \
print $$$$(i+1) } }' $$($1_RESULT_FILE))) \
@@ -540,6 +577,69 @@
TARGETS += $1
endef
+################################################################################
+
+### Rules for special tests
+
+SetupRunSpecialTest = $(NamedParamsMacroTemplate)
+define SetupRunSpecialTestBody
+ $1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1
+ $1_TEST_SUPPORT_DIR := $$(TEST_SUPPORT_DIR)/$1
+ $1_EXITCODE := $$($1_TEST_RESULTS_DIR)/exitcode.txt
+
+ $1_FULL_TEST_NAME := $$(strip $$(patsubst special:%, %, $$($1_TEST)))
+ ifneq ($$(findstring :, $$($1_FULL_TEST_NAME)), )
+ $1_TEST_NAME := $$(firstword $$(subst :, ,$$($1_FULL_TEST_NAME)))
+ $1_TEST_ARGS := $$(strip $$(patsubst special:$$($1_TEST_NAME):%, %, $$($1_TEST)))
+ else
+ $1_TEST_NAME := $$($1_FULL_TEST_NAME)
+ $1_TEST_ARGS :=
+ endif
+
+ ifeq ($$($1_TEST_NAME), hotspot-internal)
+ $1_TEST_COMMAND_LINE := \
+ $$(JDK_IMAGE_DIR)/bin/java -XX:+ExecuteInternalVMTests \
+ -XX:+ShowMessageBoxOnError -version
+ else ifeq ($$($1_TEST_NAME), failure-handler)
+ $1_TEST_COMMAND_LINE := \
+ ($(CD) $(TOPDIR)/make/test && $(MAKE) $(MAKE_ARGS) -f \
+ BuildFailureHandler.gmk test)
+ else ifeq ($$($1_TEST_NAME), make)
+ $1_TEST_COMMAND_LINE := \
+ ($(CD) $(TOPDIR)/test/make && $(MAKE) $(MAKE_ARGS) -f \
+ TestMake.gmk $$($1_TEST_ARGS))
+ else
+ $$(error Invalid special test specification: $$($1_TEST_NAME))
+ endif
+
+ run-test-$1:
+ $$(call LogWarn)
+ $$(call LogWarn, Running test '$$($1_TEST)')
+ $$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR))
+ $$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/test-execution, \
+ $$($1_TEST_COMMAND_LINE) \
+ > >($(TEE) $$($1_TEST_RESULTS_DIR)/test-output.txt) \
+ && $$(ECHO) $$$$? > $$($1_EXITCODE) \
+ || $$(ECHO) $$$$? > $$($1_EXITCODE) \
+ )
+
+ $1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/gtest.txt
+
+ # We can not parse the various "special" tests.
+ parse-test-$1: run-test-$1
+ $$(call LogWarn, Finished running test '$$($1_TEST)')
+ $$(call LogWarn, Test report is stored in $$(strip \
+ $$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR))))
+ $$(call LogWarn, Warning: Special test results are not properly parsed!)
+ $$(eval $1_PASSED := 0)
+ $$(eval $1_FAILED := 0)
+ $$(eval $1_ERROR := 0)
+ $$(eval $1_TOTAL := 0)
+
+ $1: run-test-$1 parse-test-$1
+
+ TARGETS += $1
+endef
################################################################################
# Setup and execute make rules for all selected tests
@@ -552,10 +652,13 @@
UseJtregTestHandler = \
$(if $(filter jtreg:%, $1), true)
+UseSpecialTestHandler = \
+ $(if $(filter special:%, $1), true)
+
# Now process each test to run and setup a proper make rule
$(foreach test, $(TESTS_TO_RUN), \
$(eval TEST_ID := $(shell $(ECHO) $(strip $(test)) | \
- $(TR) -cs '[a-z][A-Z][0-9]\n' '_')) \
+ $(TR) -cs '[a-z][A-Z][0-9]\n' '[_*1000]')) \
$(eval ALL_TEST_IDS += $(TEST_ID)) \
$(if $(call UseCustomTestHandler, $(test)), \
$(eval $(call SetupRunCustomTest, $(TEST_ID), \
@@ -572,6 +675,11 @@
TEST := $(test), \
)) \
) \
+ $(if $(call UseSpecialTestHandler, $(test)), \
+ $(eval $(call SetupRunSpecialTest, $(TEST_ID), \
+ TEST := $(test), \
+ )) \
+ ) \
)
# Sort also removes duplicates, so if there is any we'll get fewer words.
@@ -592,6 +700,8 @@
# Create and print a table of the result of all tests run
$(RM) $(TEST_SUMMARY).old 2> /dev/null
$(MV) $(TEST_SUMMARY) $(TEST_SUMMARY).old 2> /dev/null || true
+ $(RM) $(TEST_LAST_IDS).old 2> /dev/null
+ $(MV) $(TEST_LAST_IDS) $(TEST_LAST_IDS).old 2> /dev/null || true
$(ECHO) >> $(TEST_SUMMARY) ==============================
$(ECHO) >> $(TEST_SUMMARY) Test summary
$(ECHO) >> $(TEST_SUMMARY) ==============================
@@ -599,8 +709,9 @@
TEST TOTAL PASS FAIL ERROR " "
$(foreach test, $(TESTS_TO_RUN), \
$(eval TEST_ID := $(shell $(ECHO) $(strip $(test)) | \
- $(TR) -cs '[a-z][A-Z][0-9]\n' '_')) \
- $(eval NAME_PATTERN := $(shell $(ECHO) $(test) | $(TR) -c \\n _)) \
+ $(TR) -cs '[a-z][A-Z][0-9]\n' '[_*1000]')) \
+ $(ECHO) >> $(TEST_LAST_IDS) $(TEST_ID) $(NEWLINE) \
+ $(eval NAME_PATTERN := $(shell $(ECHO) $(test) | $(TR) -c '\n' '[_*1000]')) \
$(if $(filter __________________________________________________%, $(NAME_PATTERN)), \
$(eval TEST_NAME := ) \
$(PRINTF) >> $(TEST_SUMMARY) "%2s %-49s\n" " " "$(test)" $(NEWLINE) \
--- a/make/autoconf/basics.m4 Tue Dec 05 10:21:41 2017 +0000
+++ b/make/autoconf/basics.m4 Tue Dec 05 10:28:45 2017 +0000
@@ -1092,10 +1092,6 @@
# We can build without it.
LDD="true"
fi
- BASIC_PATH_PROGS(OTOOL, otool)
- if test "x$OTOOL" = "x"; then
- OTOOL="true"
- fi
BASIC_PATH_PROGS(READELF, [greadelf readelf])
BASIC_PATH_PROGS(DOT, dot)
BASIC_PATH_PROGS(HG, hg)
--- a/make/autoconf/generated-configure.sh Tue Dec 05 10:21:41 2017 +0000
+++ b/make/autoconf/generated-configure.sh Tue Dec 05 10:28:45 2017 +0000
@@ -818,6 +818,8 @@
DUMPBIN
RC
MT
+INSTALL_NAME_TOOL
+OTOOL
LIPO
ac_ct_AR
AR
@@ -932,7 +934,6 @@
HG
DOT
READELF
-OTOOL
LDD
ZIPEXE
UNZIP
@@ -1277,7 +1278,6 @@
UNZIP
ZIPEXE
LDD
-OTOOL
READELF
DOT
HG
@@ -1310,6 +1310,8 @@
AS
AR
LIPO
+OTOOL
+INSTALL_NAME_TOOL
STRIP
NM
GNM
@@ -2226,7 +2228,6 @@
UNZIP Override default value for UNZIP
ZIPEXE Override default value for ZIPEXE
LDD Override default value for LDD
- OTOOL Override default value for OTOOL
READELF Override default value for READELF
DOT Override default value for DOT
HG Override default value for HG
@@ -2260,6 +2261,9 @@
AS Override default value for AS
AR Override default value for AR
LIPO Override default value for LIPO
+ OTOOL Override default value for OTOOL
+ INSTALL_NAME_TOOL
+ Override default value for INSTALL_NAME_TOOL
STRIP Override default value for STRIP
NM Override default value for NM
GNM Override default value for GNM
@@ -5155,7 +5159,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1511359342
+DATE_WHEN_GENERATED=1512410983
###############################################################################
#
@@ -22126,206 +22130,6 @@
# Publish this variable in the help.
- if [ -z "${OTOOL+x}" ]; then
- # The variable is not set by user, try to locate tool using the code snippet
- for ac_prog in otool
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-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 ${ac_cv_path_OTOOL+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- case $OTOOL in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_OTOOL="$OTOOL" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_OTOOL="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-OTOOL=$ac_cv_path_OTOOL
-if test -n "$OTOOL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
-$as_echo "$OTOOL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$OTOOL" && break
-done
-
- else
- # The variable is set, but is it from the command line or the environment?
-
- # Try to remove the string !OTOOL! from our list.
- try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!OTOOL!/}
- if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then
- # If it failed, the variable was not from the command line. Ignore it,
- # but warn the user (except for BASH, which is always set by the calling BASH).
- if test "xOTOOL" != xBASH; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of OTOOL from the environment. Use command line variables instead." >&5
-$as_echo "$as_me: WARNING: Ignoring value of OTOOL from the environment. Use command line variables instead." >&2;}
- fi
- # Try to locate tool using the code snippet
- for ac_prog in otool
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-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 ${ac_cv_path_OTOOL+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- case $OTOOL in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_OTOOL="$OTOOL" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_OTOOL="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-OTOOL=$ac_cv_path_OTOOL
-if test -n "$OTOOL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
-$as_echo "$OTOOL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$OTOOL" && break
-done
-
- else
- # If it succeeded, then it was overridden by the user. We will use it
- # for the tool.
-
- # First remove it from the list of overridden variables, so we can test
- # for unknown variables in the end.
- CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var"
-
- # Check if we try to supply an empty value
- if test "x$OTOOL" = x; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool OTOOL= (no value)" >&5
-$as_echo "$as_me: Setting user supplied tool OTOOL= (no value)" >&6;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OTOOL" >&5
-$as_echo_n "checking for OTOOL... " >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
-$as_echo "disabled" >&6; }
- else
- # Check if the provided tool contains a complete path.
- tool_specified="$OTOOL"
- tool_basename="${tool_specified##*/}"
- if test "x$tool_basename" = "x$tool_specified"; then
- # A command without a complete path is provided, search $PATH.
- { $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool OTOOL=$tool_basename" >&5
-$as_echo "$as_me: Will search for user supplied tool OTOOL=$tool_basename" >&6;}
- # Extract the first word of "$tool_basename", so it can be a program name with args.
-set dummy $tool_basename; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_OTOOL+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- case $OTOOL in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_OTOOL="$OTOOL" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_OTOOL="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-OTOOL=$ac_cv_path_OTOOL
-if test -n "$OTOOL"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
-$as_echo "$OTOOL" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- if test "x$OTOOL" = x; then
- as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5
- fi
- else
- # Otherwise we believe it is a complete path. Use it as it is.
- { $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool OTOOL=$tool_specified" >&5
-$as_echo "$as_me: Will use user supplied tool OTOOL=$tool_specified" >&6;}
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OTOOL" >&5
-$as_echo_n "checking for OTOOL... " >&6; }
- if test ! -x "$tool_specified"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
- as_fn_error $? "User supplied tool OTOOL=$tool_specified does not exist or is not executable" "$LINENO" 5
- fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5
-$as_echo "$tool_specified" >&6; }
- fi
- fi
- fi
-
- fi
-
-
- if test "x$OTOOL" = "x"; then
- OTOOL="true"
- fi
-
-
- # Publish this variable in the help.
-
-
if [ -z "${READELF+x}" ]; then
# The variable is not set by user, try to locate tool using the code snippet
for ac_prog in greadelf readelf
@@ -39588,6 +39392,986 @@
fi
fi
+
+
+
+ # Publish this variable in the help.
+
+
+ if [ -z "${OTOOL+x}" ]; then
+ # The variable is not set by user, try to locate tool using the code snippet
+ for ac_prog in otool
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+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 ${ac_cv_path_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $OTOOL in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_OTOOL="$OTOOL" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_OTOOL="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+OTOOL=$ac_cv_path_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$OTOOL" && break
+done
+
+ else
+ # The variable is set, but is it from the command line or the environment?
+
+ # Try to remove the string !OTOOL! from our list.
+ try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!OTOOL!/}
+ if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then
+ # If it failed, the variable was not from the command line. Ignore it,
+ # but warn the user (except for BASH, which is always set by the calling BASH).
+ if test "xOTOOL" != xBASH; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of OTOOL from the environment. Use command line variables instead." >&5
+$as_echo "$as_me: WARNING: Ignoring value of OTOOL from the environment. Use command line variables instead." >&2;}
+ fi
+ # Try to locate tool using the code snippet
+ for ac_prog in otool
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+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 ${ac_cv_path_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $OTOOL in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_OTOOL="$OTOOL" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_OTOOL="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+OTOOL=$ac_cv_path_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$OTOOL" && break
+done
+
+ else
+ # If it succeeded, then it was overridden by the user. We will use it
+ # for the tool.
+
+ # First remove it from the list of overridden variables, so we can test
+ # for unknown variables in the end.
+ CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var"
+
+ # Check if we try to supply an empty value
+ if test "x$OTOOL" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool OTOOL= (no value)" >&5
+$as_echo "$as_me: Setting user supplied tool OTOOL= (no value)" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OTOOL" >&5
+$as_echo_n "checking for OTOOL... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
+$as_echo "disabled" >&6; }
+ else
+ # Check if the provided tool contains a complete path.
+ tool_specified="$OTOOL"
+ tool_basename="${tool_specified##*/}"
+ if test "x$tool_basename" = "x$tool_specified"; then
+ # A command without a complete path is provided, search $PATH.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool OTOOL=$tool_basename" >&5
+$as_echo "$as_me: Will search for user supplied tool OTOOL=$tool_basename" >&6;}
+ # Extract the first word of "$tool_basename", so it can be a program name with args.
+set dummy $tool_basename; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $OTOOL in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_OTOOL="$OTOOL" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_OTOOL="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+OTOOL=$ac_cv_path_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$OTOOL" = x; then
+ as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5
+ fi
+ else
+ # Otherwise we believe it is a complete path. Use it as it is.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool OTOOL=$tool_specified" >&5
+$as_echo "$as_me: Will use user supplied tool OTOOL=$tool_specified" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OTOOL" >&5
+$as_echo_n "checking for OTOOL... " >&6; }
+ if test ! -x "$tool_specified"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+ as_fn_error $? "User supplied tool OTOOL=$tool_specified does not exist or is not executable" "$LINENO" 5
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5
+$as_echo "$tool_specified" >&6; }
+ fi
+ fi
+ fi
+
+ fi
+
+
+
+ if test "x$OTOOL" = x; then
+ as_fn_error $? "Could not find required tool for OTOOL" "$LINENO" 5
+ fi
+
+
+
+ # Only process if variable expands to non-empty
+
+ if test "x$OTOOL" != x; then
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+
+ # First separate the path from the arguments. This will split at the first
+ # space.
+ complete="$OTOOL"
+ path="${complete%% *}"
+ tmp="$complete EOL"
+ arguments="${tmp#* }"
+
+ # Input might be given as Windows format, start by converting to
+ # unix format.
+ new_path=`$CYGPATH -u "$path"`
+
+ # Now try to locate executable using which
+ new_path=`$WHICH "$new_path" 2> /dev/null`
+ # bat and cmd files are not always considered executable in cygwin causing which
+ # to not find them
+ if test "x$new_path" = x \
+ && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
+ && test "x`$LS \"$path\" 2>/dev/null`" != x; then
+ new_path=`$CYGPATH -u "$path"`
+ fi
+ if test "x$new_path" = x; then
+ # Oops. Which didn't find the executable.
+ # The splitting of arguments from the executable at a space might have been incorrect,
+ # since paths with space are more likely in Windows. Give it another try with the whole
+ # argument.
+ path="$complete"
+ arguments="EOL"
+ new_path=`$CYGPATH -u "$path"`
+ new_path=`$WHICH "$new_path" 2> /dev/null`
+ # bat and cmd files are not always considered executable in cygwin causing which
+ # to not find them
+ if test "x$new_path" = x \
+ && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
+ && test "x`$LS \"$path\" 2>/dev/null`" != x; then
+ new_path=`$CYGPATH -u "$path"`
+ fi
+ if test "x$new_path" = x; then
+ # It's still not found. Now this is an unrecoverable error.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of OTOOL, which resolves as \"$complete\", is not found." >&5
+$as_echo "$as_me: The path of OTOOL, which resolves as \"$complete\", is not found." >&6;}
+ has_space=`$ECHO "$complete" | $GREP " "`
+ if test "x$has_space" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5
+$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;}
+ fi
+ as_fn_error $? "Cannot locate the the path of OTOOL" "$LINENO" 5
+ fi
+ fi
+
+ # Cygwin tries to hide some aspects of the Windows file system, such that binaries are
+ # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
+ # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
+ # "foo.exe" is OK but "foo" is an error.
+ #
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
+ # It is also a way to make sure we got the proper file name for the real test later on.
+ test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
+ if test "x$test_shortpath" = x; then
+ # Short path failed, file does not exist as specified.
+ # Try adding .exe or .cmd
+ if test -f "${new_path}.exe"; then
+ input_to_shortpath="${new_path}.exe"
+ elif test -f "${new_path}.cmd"; then
+ input_to_shortpath="${new_path}.cmd"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of OTOOL, which resolves as \"$new_path\", is invalid." >&5
+$as_echo "$as_me: The path of OTOOL, which resolves as \"$new_path\", is invalid." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&5
+$as_echo "$as_me: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&6;}
+ as_fn_error $? "Cannot locate the the path of OTOOL" "$LINENO" 5
+ fi
+ else
+ input_to_shortpath="$new_path"
+ fi
+
+ # Call helper function which possibly converts this using DOS-style short mode.
+ # If so, the updated path is stored in $new_path.
+ new_path="$input_to_shortpath"
+
+ input_path="$input_to_shortpath"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ shortmode_path=`$CYGPATH -s -m -a "$input_path"`
+ path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
+ if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
+ # Going to short mode and back again did indeed matter. Since short mode is
+ # case insensitive, let's make it lowercase to improve readability.
+ shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Now convert it back to Unix-style (cygpath)
+ input_path=`$CYGPATH -u "$shortmode_path"`
+ new_path="$input_path"
+ fi
+ fi
+
+ test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
+ if test "x$test_cygdrive_prefix" = x; then
+ # As a simple fix, exclude /usr/bin since it's not a real path.
+ if test "x`$ECHO $input_to_shortpath | $GREP ^/usr/bin/`" = x; then
+ # The path is in a Cygwin special directory (e.g. /home). We need this converted to
+ # a path prefixed by /cygdrive for fixpath to work.
+ new_path="$CYGWIN_ROOT_PATH$input_path"
+ fi
+ fi
+
+ # remove trailing .exe if any
+ new_path="${new_path/%.exe/}"
+
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+
+ # First separate the path from the arguments. This will split at the first
+ # space.
+ complete="$OTOOL"
+ path="${complete%% *}"
+ tmp="$complete EOL"
+ arguments="${tmp#* }"
+
+ # Input might be given as Windows format, start by converting to
+ # unix format.
+ new_path="$path"
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+
+ # Now try to locate executable using which
+ new_path=`$WHICH "$new_path" 2> /dev/null`
+
+ if test "x$new_path" = x; then
+ # Oops. Which didn't find the executable.
+ # The splitting of arguments from the executable at a space might have been incorrect,
+ # since paths with space are more likely in Windows. Give it another try with the whole
+ # argument.
+ path="$complete"
+ arguments="EOL"
+ new_path="$path"
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+
+ new_path=`$WHICH "$new_path" 2> /dev/null`
+ # bat and cmd files are not always considered executable in MSYS causing which
+ # to not find them
+ if test "x$new_path" = x \
+ && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
+ && test "x`$LS \"$path\" 2>/dev/null`" != x; then
+ new_path="$path"
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+ fi
+
+ if test "x$new_path" = x; then
+ # It's still not found. Now this is an unrecoverable error.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of OTOOL, which resolves as \"$complete\", is not found." >&5
+$as_echo "$as_me: The path of OTOOL, which resolves as \"$complete\", is not found." >&6;}
+ has_space=`$ECHO "$complete" | $GREP " "`
+ if test "x$has_space" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5
+$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;}
+ fi
+ as_fn_error $? "Cannot locate the the path of OTOOL" "$LINENO" 5
+ fi
+ fi
+
+ # Now new_path has a complete unix path to the binary
+ if test "x`$ECHO $new_path | $GREP ^/bin/`" != x; then
+ # Keep paths in /bin as-is, but remove trailing .exe if any
+ new_path="${new_path/%.exe/}"
+ # Do not save /bin paths to all_fixpath_prefixes!
+ else
+ # Not in mixed or Windows style, start by that.
+ new_path=`cmd //c echo $new_path`
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ fi
+
+ # Output is in $new_path
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+ # remove trailing .exe if any
+ new_path="${new_path/%.exe/}"
+
+ # Save the first 10 bytes of this path to the storage, so fixpath can work.
+ all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
+ fi
+
+ else
+ # We're on a unix platform. Hooray! :)
+ # First separate the path from the arguments. This will split at the first
+ # space.
+ complete="$OTOOL"
+ path="${complete%% *}"
+ tmp="$complete EOL"
+ arguments="${tmp#* }"
+
+ # Cannot rely on the command "which" here since it doesn't always work.
+ is_absolute_path=`$ECHO "$path" | $GREP ^/`
+ if test -z "$is_absolute_path"; then
+ # Path to executable is not absolute. Find it.
+ IFS_save="$IFS"
+ IFS=:
+ for p in $PATH; do
+ if test -f "$p/$path" && test -x "$p/$path"; then
+ new_path="$p/$path"
+ break
+ fi
+ done
+ IFS="$IFS_save"
+ else
+ # This is an absolute path, we can use it without further modifications.
+ new_path="$path"
+ fi
+
+ if test "x$new_path" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of OTOOL, which resolves as \"$complete\", is not found." >&5
+$as_echo "$as_me: The path of OTOOL, which resolves as \"$complete\", is not found." >&6;}
+ has_space=`$ECHO "$complete" | $GREP " "`
+ if test "x$has_space" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: This might be caused by spaces in the path, which is not allowed." >&5
+$as_echo "$as_me: This might be caused by spaces in the path, which is not allowed." >&6;}
+ fi
+ as_fn_error $? "Cannot locate the the path of OTOOL" "$LINENO" 5
+ fi
+ fi
+
+ # Now join together the path and the arguments once again
+ if test "x$arguments" != xEOL; then
+ new_complete="$new_path ${arguments% *}"
+ else
+ new_complete="$new_path"
+ fi
+
+ if test "x$complete" != "x$new_complete"; then
+ OTOOL="$new_complete"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting OTOOL to \"$new_complete\"" >&5
+$as_echo "$as_me: Rewriting OTOOL to \"$new_complete\"" >&6;}
+ fi
+ fi
+
+
+
+
+ # Publish this variable in the help.
+
+
+ if [ -z "${INSTALL_NAME_TOOL+x}" ]; then
+ # The variable is not set by user, try to locate tool using the code snippet
+ for ac_prog in install_name_tool
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+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 ${ac_cv_path_INSTALL_NAME_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $INSTALL_NAME_TOOL in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_INSTALL_NAME_TOOL="$INSTALL_NAME_TOOL" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_INSTALL_NAME_TOOL="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+INSTALL_NAME_TOOL=$ac_cv_path_INSTALL_NAME_TOOL
+if test -n "$INSTALL_NAME_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL_NAME_TOOL" >&5
+$as_echo "$INSTALL_NAME_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$INSTALL_NAME_TOOL" && break
+done
+
+ else
+ # The variable is set, but is it from the command line or the environment?
+
+ # Try to remove the string !INSTALL_NAME_TOOL! from our list.
+ try_remove_var=${CONFIGURE_OVERRIDDEN_VARIABLES//!INSTALL_NAME_TOOL!/}
+ if test "x$try_remove_var" = "x$CONFIGURE_OVERRIDDEN_VARIABLES"; then
+ # If it failed, the variable was not from the command line. Ignore it,
+ # but warn the user (except for BASH, which is always set by the calling BASH).
+ if test "xINSTALL_NAME_TOOL" != xBASH; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ignoring value of INSTALL_NAME_TOOL from the environment. Use command line variables instead." >&5
+$as_echo "$as_me: WARNING: Ignoring value of INSTALL_NAME_TOOL from the environment. Use command line variables instead." >&2;}
+ fi
+ # Try to locate tool using the code snippet
+ for ac_prog in install_name_tool
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+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 ${ac_cv_path_INSTALL_NAME_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $INSTALL_NAME_TOOL in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_INSTALL_NAME_TOOL="$INSTALL_NAME_TOOL" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_INSTALL_NAME_TOOL="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+INSTALL_NAME_TOOL=$ac_cv_path_INSTALL_NAME_TOOL
+if test -n "$INSTALL_NAME_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL_NAME_TOOL" >&5
+$as_echo "$INSTALL_NAME_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$INSTALL_NAME_TOOL" && break
+done
+
+ else
+ # If it succeeded, then it was overridden by the user. We will use it
+ # for the tool.
+
+ # First remove it from the list of overridden variables, so we can test
+ # for unknown variables in the end.
+ CONFIGURE_OVERRIDDEN_VARIABLES="$try_remove_var"
+
+ # Check if we try to supply an empty value
+ if test "x$INSTALL_NAME_TOOL" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Setting user supplied tool INSTALL_NAME_TOOL= (no value)" >&5
+$as_echo "$as_me: Setting user supplied tool INSTALL_NAME_TOOL= (no value)" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for INSTALL_NAME_TOOL" >&5
+$as_echo_n "checking for INSTALL_NAME_TOOL... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
+$as_echo "disabled" >&6; }
+ else
+ # Check if the provided tool contains a complete path.
+ tool_specified="$INSTALL_NAME_TOOL"
+ tool_basename="${tool_specified##*/}"
+ if test "x$tool_basename" = "x$tool_specified"; then
+ # A command without a complete path is provided, search $PATH.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Will search for user supplied tool INSTALL_NAME_TOOL=$tool_basename" >&5
+$as_echo "$as_me: Will search for user supplied tool INSTALL_NAME_TOOL=$tool_basename" >&6;}
+ # Extract the first word of "$tool_basename", so it can be a program name with args.
+set dummy $tool_basename; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_INSTALL_NAME_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $INSTALL_NAME_TOOL in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_INSTALL_NAME_TOOL="$INSTALL_NAME_TOOL" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_INSTALL_NAME_TOOL="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+INSTALL_NAME_TOOL=$ac_cv_path_INSTALL_NAME_TOOL
+if test -n "$INSTALL_NAME_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL_NAME_TOOL" >&5
+$as_echo "$INSTALL_NAME_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$INSTALL_NAME_TOOL" = x; then
+ as_fn_error $? "User supplied tool $tool_basename could not be found" "$LINENO" 5
+ fi
+ else
+ # Otherwise we believe it is a complete path. Use it as it is.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Will use user supplied tool INSTALL_NAME_TOOL=$tool_specified" >&5
+$as_echo "$as_me: Will use user supplied tool INSTALL_NAME_TOOL=$tool_specified" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for INSTALL_NAME_TOOL" >&5
+$as_echo_n "checking for INSTALL_NAME_TOOL... " >&6; }
+ if test ! -x "$tool_specified"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+ as_fn_error $? "User supplied tool INSTALL_NAME_TOOL=$tool_specified does not exist or is not executable" "$LINENO" 5
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tool_specified" >&5
+$as_echo "$tool_specified" >&6; }
+ fi
+ fi
+ fi
+
+ fi
+
+
+
+ if test "x$INSTALL_NAME_TOOL" = x; then
+ as_fn_error $? "Could not find required tool for INSTALL_NAME_TOOL" "$LINENO" 5
+ fi
+
+
+
+ # Only process if variable expands to non-empty
+
+ if test "x$INSTALL_NAME_TOOL" != x; then
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+
+ # First separate the path from the arguments. This will split at the first
+ # space.
+ complete="$INSTALL_NAME_TOOL"
+ path="${complete%% *}"
+ tmp="$complete EOL"
+ arguments="${tmp#* }"
+
+ # Input might be given as Windows format, start by converting to
+ # unix format.
+ new_path=`$CYGPATH -u "$path"`
+
+ # Now try to locate executable using which
+ new_path=`$WHICH "$new_path" 2> /dev/null`
+ # bat and cmd files are not always considered executable in cygwin causing which
+ # to not find them
+ if test "x$new_path" = x \
+ && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
+ && test "x`$LS \"$path\" 2>/dev/null`" != x; then
+ new_path=`$CYGPATH -u "$path"`
+ fi
+ if test "x$new_path" = x; then
+ # Oops. Which didn't find the executable.
+ # The splitting of arguments from the executable at a space might have been incorrect,
+ # since paths with space are more likely in Windows. Give it another try with the whole
+ # argument.
+ path="$complete"
+ arguments="EOL"
+ new_path=`$CYGPATH -u "$path"`
+ new_path=`$WHICH "$new_path" 2> /dev/null`
+ # bat and cmd files are not always considered executable in cygwin causing which
+ # to not find them
+ if test "x$new_path" = x \
+ && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
+ && test "x`$LS \"$path\" 2>/dev/null`" != x; then
+ new_path=`$CYGPATH -u "$path"`
+ fi
+ if test "x$new_path" = x; then
+ # It's still not found. Now this is an unrecoverable error.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of INSTALL_NAME_TOOL, which resolves as \"$complete\", is not found." >&5
+$as_echo "$as_me: The path of INSTALL_NAME_TOOL, which resolves as \"$complete\", is not found." >&6;}
+ has_space=`$ECHO "$complete" | $GREP " "`
+ if test "x$has_space" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5
+$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;}
+ fi
+ as_fn_error $? "Cannot locate the the path of INSTALL_NAME_TOOL" "$LINENO" 5
+ fi
+ fi
+
+ # Cygwin tries to hide some aspects of the Windows file system, such that binaries are
+ # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
+ # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
+ # "foo.exe" is OK but "foo" is an error.
+ #
+ # This test is therefore slightly more accurate than "test -f" to check for file presence.
+ # It is also a way to make sure we got the proper file name for the real test later on.
+ test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
+ if test "x$test_shortpath" = x; then
+ # Short path failed, file does not exist as specified.
+ # Try adding .exe or .cmd
+ if test -f "${new_path}.exe"; then
+ input_to_shortpath="${new_path}.exe"
+ elif test -f "${new_path}.cmd"; then
+ input_to_shortpath="${new_path}.cmd"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of INSTALL_NAME_TOOL, which resolves as \"$new_path\", is invalid." >&5
+$as_echo "$as_me: The path of INSTALL_NAME_TOOL, which resolves as \"$new_path\", is invalid." >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&5
+$as_echo "$as_me: Neither \"$new_path\" nor \"$new_path.exe/cmd\" can be found" >&6;}
+ as_fn_error $? "Cannot locate the the path of INSTALL_NAME_TOOL" "$LINENO" 5
+ fi
+ else
+ input_to_shortpath="$new_path"
+ fi
+
+ # Call helper function which possibly converts this using DOS-style short mode.
+ # If so, the updated path is stored in $new_path.
+ new_path="$input_to_shortpath"
+
+ input_path="$input_to_shortpath"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ shortmode_path=`$CYGPATH -s -m -a "$input_path"`
+ path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
+ if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
+ # Going to short mode and back again did indeed matter. Since short mode is
+ # case insensitive, let's make it lowercase to improve readability.
+ shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Now convert it back to Unix-style (cygpath)
+ input_path=`$CYGPATH -u "$shortmode_path"`
+ new_path="$input_path"
+ fi
+ fi
+
+ test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
+ if test "x$test_cygdrive_prefix" = x; then
+ # As a simple fix, exclude /usr/bin since it's not a real path.
+ if test "x`$ECHO $input_to_shortpath | $GREP ^/usr/bin/`" = x; then
+ # The path is in a Cygwin special directory (e.g. /home). We need this converted to
+ # a path prefixed by /cygdrive for fixpath to work.
+ new_path="$CYGWIN_ROOT_PATH$input_path"
+ fi
+ fi
+
+ # remove trailing .exe if any
+ new_path="${new_path/%.exe/}"
+
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+
+ # First separate the path from the arguments. This will split at the first
+ # space.
+ complete="$INSTALL_NAME_TOOL"
+ path="${complete%% *}"
+ tmp="$complete EOL"
+ arguments="${tmp#* }"
+
+ # Input might be given as Windows format, start by converting to
+ # unix format.
+ new_path="$path"
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+
+ # Now try to locate executable using which
+ new_path=`$WHICH "$new_path" 2> /dev/null`
+
+ if test "x$new_path" = x; then
+ # Oops. Which didn't find the executable.
+ # The splitting of arguments from the executable at a space might have been incorrect,
+ # since paths with space are more likely in Windows. Give it another try with the whole
+ # argument.
+ path="$complete"
+ arguments="EOL"
+ new_path="$path"
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+
+ new_path=`$WHICH "$new_path" 2> /dev/null`
+ # bat and cmd files are not always considered executable in MSYS causing which
+ # to not find them
+ if test "x$new_path" = x \
+ && test "x`$ECHO \"$path\" | $GREP -i -e \"\\.bat$\" -e \"\\.cmd$\"`" != x \
+ && test "x`$LS \"$path\" 2>/dev/null`" != x; then
+ new_path="$path"
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+ fi
+
+ if test "x$new_path" = x; then
+ # It's still not found. Now this is an unrecoverable error.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of INSTALL_NAME_TOOL, which resolves as \"$complete\", is not found." >&5
+$as_echo "$as_me: The path of INSTALL_NAME_TOOL, which resolves as \"$complete\", is not found." >&6;}
+ has_space=`$ECHO "$complete" | $GREP " "`
+ if test "x$has_space" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: You might be mixing spaces in the path and extra arguments, which is not allowed." >&5
+$as_echo "$as_me: You might be mixing spaces in the path and extra arguments, which is not allowed." >&6;}
+ fi
+ as_fn_error $? "Cannot locate the the path of INSTALL_NAME_TOOL" "$LINENO" 5
+ fi
+ fi
+
+ # Now new_path has a complete unix path to the binary
+ if test "x`$ECHO $new_path | $GREP ^/bin/`" != x; then
+ # Keep paths in /bin as-is, but remove trailing .exe if any
+ new_path="${new_path/%.exe/}"
+ # Do not save /bin paths to all_fixpath_prefixes!
+ else
+ # Not in mixed or Windows style, start by that.
+ new_path=`cmd //c echo $new_path`
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ fi
+
+ # Output is in $new_path
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+ # remove trailing .exe if any
+ new_path="${new_path/%.exe/}"
+
+ # Save the first 10 bytes of this path to the storage, so fixpath can work.
+ all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
+ fi
+
+ else
+ # We're on a unix platform. Hooray! :)
+ # First separate the path from the arguments. This will split at the first
+ # space.
+ complete="$INSTALL_NAME_TOOL"
+ path="${complete%% *}"
+ tmp="$complete EOL"
+ arguments="${tmp#* }"
+
+ # Cannot rely on the command "which" here since it doesn't always work.
+ is_absolute_path=`$ECHO "$path" | $GREP ^/`
+ if test -z "$is_absolute_path"; then
+ # Path to executable is not absolute. Find it.
+ IFS_save="$IFS"
+ IFS=:
+ for p in $PATH; do
+ if test -f "$p/$path" && test -x "$p/$path"; then
+ new_path="$p/$path"
+ break
+ fi
+ done
+ IFS="$IFS_save"
+ else
+ # This is an absolute path, we can use it without further modifications.
+ new_path="$path"
+ fi
+
+ if test "x$new_path" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of INSTALL_NAME_TOOL, which resolves as \"$complete\", is not found." >&5
+$as_echo "$as_me: The path of INSTALL_NAME_TOOL, which resolves as \"$complete\", is not found." >&6;}
+ has_space=`$ECHO "$complete" | $GREP " "`
+ if test "x$has_space" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: This might be caused by spaces in the path, which is not allowed." >&5
+$as_echo "$as_me: This might be caused by spaces in the path, which is not allowed." >&6;}
+ fi
+ as_fn_error $? "Cannot locate the the path of INSTALL_NAME_TOOL" "$LINENO" 5
+ fi
+ fi
+
+ # Now join together the path and the arguments once again
+ if test "x$arguments" != xEOL; then
+ new_complete="$new_path ${arguments% *}"
+ else
+ new_complete="$new_path"
+ fi
+
+ if test "x$complete" != "x$new_complete"; then
+ INSTALL_NAME_TOOL="$new_complete"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting INSTALL_NAME_TOOL to \"$new_complete\"" >&5
+$as_echo "$as_me: Rewriting INSTALL_NAME_TOOL to \"$new_complete\"" >&6;}
+ fi
+ fi
+
fi
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
@@ -64486,17 +65270,18 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUNDLE_FREETYPE" >&5
$as_echo "$BUNDLE_FREETYPE" >&6; }
- fi # end freetype needed
-
- FREETYPE_LICENSE=""
- if test "x$with_freetype_license" = "xyes"; then
- as_fn_error $? "--with-freetype-license must have a value" "$LINENO" 5
- elif test "x$with_freetype_license" != "x"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for freetype license" >&5
+ if test "x$BUNDLE_FREETYPE" = xyes; then
+ FREETYPE_LICENSE=""
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for freetype license" >&5
$as_echo_n "checking for freetype license... " >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_freetype_license" >&5
+ if test "x$with_freetype_license" = "xyes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "--with-freetype-license must have a value" "$LINENO" 5
+ elif test "x$with_freetype_license" != "x"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_freetype_license" >&5
$as_echo "$with_freetype_license" >&6; }
- FREETYPE_LICENSE="$with_freetype_license"
+ FREETYPE_LICENSE="$with_freetype_license"
# Only process if variable expands to non-empty
@@ -64629,10 +65414,154 @@
fi
fi
- if test ! -f "$FREETYPE_LICENSE"; then
- as_fn_error $? "$FREETYPE_LICENSE cannot be found" "$LINENO" 5
- fi
- fi
+ if test ! -f "$FREETYPE_LICENSE"; then
+ as_fn_error $? "$FREETYPE_LICENSE cannot be found" "$LINENO" 5
+ fi
+ else
+ if test "x$with_freetype" != "x" && test -f $with_freetype/freetype.md; then
+ FREETYPE_LICENSE="$with_freetype/freetype.md"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FREETYPE_LICENSE" >&5
+$as_echo "$FREETYPE_LICENSE" >&6; }
+
+ # Only process if variable expands to non-empty
+
+ if test "x$FREETYPE_LICENSE" != x; then
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+
+ # Input might be given as Windows format, start by converting to
+ # unix format.
+ path="$FREETYPE_LICENSE"
+ new_path=`$CYGPATH -u "$path"`
+
+ # Cygwin tries to hide some aspects of the Windows file system, such that binaries are
+ # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
+ # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
+ # "foo.exe" is OK but "foo" is an error.
+ #
+ # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # It is also a way to make sure we got the proper file name for the real test later on.
+ test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
+ if test "x$test_shortpath" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of FREETYPE_LICENSE, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of FREETYPE_LICENSE, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Cannot locate the the path of FREETYPE_LICENSE" "$LINENO" 5
+ fi
+
+ # Call helper function which possibly converts this using DOS-style short mode.
+ # If so, the updated path is stored in $new_path.
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ shortmode_path=`$CYGPATH -s -m -a "$input_path"`
+ path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
+ if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
+ # Going to short mode and back again did indeed matter. Since short mode is
+ # case insensitive, let's make it lowercase to improve readability.
+ shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Now convert it back to Unix-style (cygpath)
+ input_path=`$CYGPATH -u "$shortmode_path"`
+ new_path="$input_path"
+ fi
+ fi
+
+ test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
+ if test "x$test_cygdrive_prefix" = x; then
+ # As a simple fix, exclude /usr/bin since it's not a real path.
+ if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
+ # The path is in a Cygwin special directory (e.g. /home). We need this converted to
+ # a path prefixed by /cygdrive for fixpath to work.
+ new_path="$CYGWIN_ROOT_PATH$input_path"
+ fi
+ fi
+
+
+ if test "x$path" != "x$new_path"; then
+ FREETYPE_LICENSE="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting FREETYPE_LICENSE to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting FREETYPE_LICENSE to \"$new_path\"" >&6;}
+ fi
+
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+
+ path="$FREETYPE_LICENSE"
+ has_colon=`$ECHO $path | $GREP ^.:`
+ new_path="$path"
+ if test "x$has_colon" = x; then
+ # Not in mixed or Windows style, start by that.
+ new_path=`cmd //c echo $path`
+ fi
+
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ fi
+
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+ if test "x$path" != "x$new_path"; then
+ FREETYPE_LICENSE="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting FREETYPE_LICENSE to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting FREETYPE_LICENSE to \"$new_path\"" >&6;}
+ fi
+
+ # Save the first 10 bytes of this path to the storage, so fixpath can work.
+ all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
+
+ else
+ # We're on a unix platform. Hooray! :)
+ path="$FREETYPE_LICENSE"
+ has_space=`$ECHO "$path" | $GREP " "`
+ if test "x$has_space" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of FREETYPE_LICENSE, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of FREETYPE_LICENSE, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
+ fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of FREETYPE_LICENSE, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ if test -d "$path"; then
+ FREETYPE_LICENSE="`cd "$path"; $THEPWDCMD -L`"
+ else
+ dir="`$DIRNAME "$path"`"
+ base="`$BASENAME "$path"`"
+ FREETYPE_LICENSE="`cd "$dir"; $THEPWDCMD -L`/$base"
+ fi
+ fi
+ fi
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ fi
+ fi
+
+ fi # end freetype needed
@@ -65334,23 +66263,6 @@
fi
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for which libpng to use" >&5
-$as_echo_n "checking for which libpng to use... " >&6; }
-
- # default is bundled
- DEFAULT_LIBPNG=bundled
- # if user didn't specify, use DEFAULT_LIBPNG
- if test "x${with_libpng}" = "x"; then
- with_libpng=${DEFAULT_LIBPNG}
- fi
-
- if test "x${with_libpng}" = "xbundled"; then
- USE_EXTERNAL_LIBPNG=false
- PNG_CFLAGS=""
- PNG_LIBS=""
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: bundled" >&5
-$as_echo "bundled" >&6; }
- elif test "x${with_libpng}" = "xsystem"; then
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PNG" >&5
@@ -65418,6 +66330,23 @@
$as_echo "yes" >&6; }
LIBPNG_FOUND=yes
fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for which libpng to use" >&5
+$as_echo_n "checking for which libpng to use... " >&6; }
+
+ # default is bundled
+ DEFAULT_LIBPNG=bundled
+ # if user didn't specify, use DEFAULT_LIBPNG
+ if test "x${with_libpng}" = "x"; then
+ with_libpng=${DEFAULT_LIBPNG}
+ fi
+
+ if test "x${with_libpng}" = "xbundled"; then
+ USE_EXTERNAL_LIBPNG=false
+ PNG_CFLAGS=""
+ PNG_LIBS=""
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: bundled" >&5
+$as_echo "bundled" >&6; }
+ elif test "x${with_libpng}" = "xsystem"; then
if test "x${LIBPNG_FOUND}" = "xyes"; then
# PKG_CHECK_MODULES will set PNG_CFLAGS and PNG_LIBS
USE_EXTERNAL_LIBPNG=true
@@ -65515,6 +66444,40 @@
USE_EXTERNAL_LIBZ=true
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: system" >&5
$as_echo "system" >&6; }
+
+ if test "x$USE_EXTERNAL_LIBPNG" != "xtrue"; then
+ # If we use bundled libpng, we must verify that we have a proper zlib.
+ # For instance zlib-ng has had issues with inflateValidate().
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for system zlib functionality" >&5
+$as_echo_n "checking for system zlib functionality... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include "zlib.h"
+int
+main ()
+{
+
+ #if ZLIB_VERNUM >= 0x1281
+ inflateValidate(NULL, 0);
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not ok" >&5
+$as_echo "not ok" >&6; }
+ as_fn_error $? "System zlib not working correctly" "$LINENO" 5
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: system not found" >&5
$as_echo "system not found" >&6; }
--- a/make/autoconf/lib-bundled.m4 Tue Dec 05 10:21:41 2017 +0000
+++ b/make/autoconf/lib-bundled.m4 Tue Dec 05 10:28:45 2017 +0000
@@ -113,6 +113,7 @@
AC_ARG_WITH(libpng, [AS_HELP_STRING([--with-libpng],
[use libpng from build system or OpenJDK source (system, bundled) @<:@bundled@:>@])])
+ PKG_CHECK_MODULES(PNG, libpng, [LIBPNG_FOUND=yes], [LIBPNG_FOUND=no])
AC_MSG_CHECKING([for which libpng to use])
# default is bundled
@@ -128,7 +129,6 @@
PNG_LIBS=""
AC_MSG_RESULT([bundled])
elif test "x${with_libpng}" = "xsystem"; then
- PKG_CHECK_MODULES(PNG, libpng, [LIBPNG_FOUND=yes], [LIBPNG_FOUND=no])
if test "x${LIBPNG_FOUND}" = "xyes"; then
# PKG_CHECK_MODULES will set PNG_CFLAGS and PNG_LIBS
USE_EXTERNAL_LIBPNG=true
@@ -183,6 +183,24 @@
if test "x${ZLIB_FOUND}" = "xyes"; then
USE_EXTERNAL_LIBZ=true
AC_MSG_RESULT([system])
+
+ if test "x$USE_EXTERNAL_LIBPNG" != "xtrue"; then
+ # If we use bundled libpng, we must verify that we have a proper zlib.
+ # For instance zlib-ng has had issues with inflateValidate().
+ AC_MSG_CHECKING([for system zlib functionality])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([#include "zlib.h"], [
+ #if ZLIB_VERNUM >= 0x1281
+ inflateValidate(NULL, 0);
+ #endif
+ ])],
+ [AC_MSG_RESULT([ok])],
+ [
+ AC_MSG_RESULT([not ok])
+ AC_MSG_ERROR([System zlib not working correctly])
+ ]
+ )
+ fi
else
AC_MSG_RESULT([system not found])
AC_MSG_ERROR([--with-zlib=system specified, but no zlib found!])
--- a/make/autoconf/lib-freetype.m4 Tue Dec 05 10:21:41 2017 +0000
+++ b/make/autoconf/lib-freetype.m4 Tue Dec 05 10:28:45 2017 +0000
@@ -443,20 +443,31 @@
fi
AC_MSG_RESULT([$BUNDLE_FREETYPE])
- fi # end freetype needed
+ if test "x$BUNDLE_FREETYPE" = xyes; then
+ FREETYPE_LICENSE=""
+ AC_MSG_CHECKING([for freetype license])
+ if test "x$with_freetype_license" = "xyes"; then
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([--with-freetype-license must have a value])
+ elif test "x$with_freetype_license" != "x"; then
+ AC_MSG_RESULT([$with_freetype_license])
+ FREETYPE_LICENSE="$with_freetype_license"
+ BASIC_FIXUP_PATH(FREETYPE_LICENSE)
+ if test ! -f "$FREETYPE_LICENSE"; then
+ AC_MSG_ERROR([$FREETYPE_LICENSE cannot be found])
+ fi
+ else
+ if test "x$with_freetype" != "x" && test -f $with_freetype/freetype.md; then
+ FREETYPE_LICENSE="$with_freetype/freetype.md"
+ AC_MSG_RESULT([$FREETYPE_LICENSE])
+ BASIC_FIXUP_PATH(FREETYPE_LICENSE)
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+ fi
- FREETYPE_LICENSE=""
- if test "x$with_freetype_license" = "xyes"; then
- AC_MSG_ERROR([--with-freetype-license must have a value])
- elif test "x$with_freetype_license" != "x"; then
- AC_MSG_CHECKING([for freetype license])
- AC_MSG_RESULT([$with_freetype_license])
- FREETYPE_LICENSE="$with_freetype_license"
- BASIC_FIXUP_PATH(FREETYPE_LICENSE)
- if test ! -f "$FREETYPE_LICENSE"; then
- AC_MSG_ERROR([$FREETYPE_LICENSE cannot be found])
- fi
- fi
+ fi # end freetype needed
AC_SUBST(FREETYPE_BUNDLE_LIB_PATH)
AC_SUBST(FREETYPE_CFLAGS)
--- a/make/autoconf/spec.gmk.in Tue Dec 05 10:21:41 2017 +0000
+++ b/make/autoconf/spec.gmk.in Tue Dec 05 10:28:45 2017 +0000
@@ -293,6 +293,7 @@
FREETYPE_CFLAGS:=@FREETYPE_CFLAGS@
FREETYPE_BUNDLE_LIB_PATH=@FREETYPE_BUNDLE_LIB_PATH@
FREETYPE_LICENSE=@FREETYPE_LICENSE@
+FONTCONFIG_CFLAGS:=@FONTCONFIG_CFLAGS@
CUPS_CFLAGS:=@CUPS_CFLAGS@
ALSA_LIBS:=@ALSA_LIBS@
ALSA_CFLAGS:=@ALSA_CFLAGS@
@@ -471,6 +472,7 @@
STRIP:=@STRIP@
LIPO:=@LIPO@
+INSTALL_NAME_TOOL:=@INSTALL_NAME_TOOL@
# Options to linker to specify a mapfile.
# (Note absence of := assignment, because we do not want to evaluate the macro body here)
--- a/make/autoconf/toolchain.m4 Tue Dec 05 10:21:41 2017 +0000
+++ b/make/autoconf/toolchain.m4 Tue Dec 05 10:28:45 2017 +0000
@@ -628,6 +628,10 @@
if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
BASIC_PATH_PROGS(LIPO, lipo)
BASIC_FIXUP_EXECUTABLE(LIPO)
+ BASIC_REQUIRE_PROGS(OTOOL, otool)
+ BASIC_FIXUP_EXECUTABLE(OTOOL)
+ BASIC_REQUIRE_PROGS(INSTALL_NAME_TOOL, install_name_tool)
+ BASIC_FIXUP_EXECUTABLE(INSTALL_NAME_TOOL)
fi
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
--- a/make/conf/jib-profiles.js Tue Dec 05 10:21:41 2017 +0000
+++ b/make/conf/jib-profiles.js Tue Dec 05 10:28:45 2017 +0000
@@ -429,7 +429,7 @@
"macosx-x64": {
target_os: "macosx",
target_cpu: "x64",
- dependencies: ["devkit"],
+ dependencies: ["devkit", "freetype"],
configure_args: concat(common.configure_args_64bit, "--with-zlib=system",
"--with-macosx-version-max=10.7.0"),
},
@@ -662,21 +662,6 @@
}
});
- // The windows ri profile needs to add the freetype license file
- profilesRiFreetype = {
- "windows-x86-ri": {
- configure_args: "--with-freetype-license="
- + input.get("freetype", "install_path")
- + "/freetype-2.7.1-v120-x86/freetype.md"
- },
- "windows-x64-ri": {
- configure_args: "--with-freetype-license="
- + input.get("freetype", "install_path")
- + "/freetype-2.7.1-v120-x64/freetype.md"
- }
- };
- profiles = concatObjects(profiles, profilesRiFreetype);
-
// Profiles used to run tests. Used in JPRT and Mach 5.
var testOnlyProfiles = {
"run-test-jprt": {
@@ -788,6 +773,12 @@
var boot_jdk_platform = (input.build_os == "macosx" ? "osx" : input.build_os)
+ "-" + input.build_cpu;
+ var freetype_version = {
+ windows_x64: "2.7.1-v120+1.1",
+ windows_x86: "2.7.1-v120+1.1",
+ macosx_x64: "2.7.1-Xcode6.3-MacOSX10.9+1.0"
+ }[input.target_platform];
+
var dependencies = {
boot_jdk: {
@@ -852,7 +843,7 @@
freetype: {
organization: common.organization,
ext: "tar.gz",
- revision: "2.7.1-v120+1.0",
+ revision: freetype_version,
module: "freetype-" + input.target_platform
},
--- a/make/copy/Copy-java.desktop.gmk Tue Dec 05 10:21:41 2017 +0000
+++ b/make/copy/Copy-java.desktop.gmk Tue Dec 05 10:28:45 2017 +0000
@@ -44,7 +44,8 @@
################################################################################
ifneq ($(FREETYPE_BUNDLE_LIB_PATH), )
- # We need to bundle the freetype library, so it will be available at runtime as well as link time.
+ # We need to bundle the freetype library, so it will be available at runtime
+ # as well as link time.
#
# NB: Default freetype build system uses -h linker option and
# result .so contains hardcoded library name that is later
@@ -61,10 +62,10 @@
#
#TODO: rework this to avoid hardcoding library name in the makefile
#
- ifeq ($(OPENJDK_TARGET_OS), windows)
+ ifneq ($(filter $(OPENJDK_TARGET_OS), linux solaris), )
+ FREETYPE_TARGET_LIB := $(LIB_DST_DIR)/$(call SHARED_LIBRARY,freetype).6
+ else
FREETYPE_TARGET_LIB := $(LIB_DST_DIR)/$(call SHARED_LIBRARY,freetype)
- else
- FREETYPE_TARGET_LIB := $(LIB_DST_DIR)/$(call SHARED_LIBRARY,freetype).6
endif
# We can't use $(install-file) in this rule because it preserves symbolic links and
--- a/make/data/charsetmapping/charsets Tue Dec 05 10:21:41 2017 +0000
+++ b/make/data/charsetmapping/charsets Tue Dec 05 10:28:45 2017 +0000
@@ -492,7 +492,7 @@
charset x-MS950-HKSCS MS950_HKSCS
package sun.nio.cs.ext
- type source
+ type template
hisname MS950_HKSCS
ascii true
alias MS950_HKSCS # JDK historical;
--- a/make/data/charsetmapping/stdcs-windows Tue Dec 05 10:21:41 2017 +0000
+++ b/make/data/charsetmapping/stdcs-windows Tue Dec 05 10:28:45 2017 +0000
@@ -13,4 +13,5 @@
MS936
MS949
MS950
+MS950_HKSCS
MS950_HKSCS_XP
--- a/make/hotspot/symbols/symbols-unix Tue Dec 05 10:21:41 2017 +0000
+++ b/make/hotspot/symbols/symbols-unix Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,6 @@
JVM_ArrayCopy
JVM_AssertionStatusDirectives
JVM_CallStackWalk
-JVM_ClassDepth
-JVM_ClassLoaderDepth
JVM_Clone
JVM_ConstantPoolGetClassAt
JVM_ConstantPoolGetClassAtIfLoaded
@@ -47,8 +45,6 @@
JVM_ConstantPoolGetTagAt
JVM_ConstantPoolGetUTF8At
JVM_CountStackFrames
-JVM_CurrentClassLoader
-JVM_CurrentLoadedClass
JVM_CurrentThread
JVM_CurrentTimeMillis
JVM_DefineClass
--- a/make/jdk/src/classes/build/tools/charsetmapping/Main.java Tue Dec 05 10:21:41 2017 +0000
+++ b/make/jdk/src/classes/build/tools/charsetmapping/Main.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,6 +54,7 @@
new File(args[SRC_DIR], args[CHARSETS]));
String[] osStdcs = getOSStdCSList(new File(args[SRC_DIR], args[OS]));
boolean hasBig5_HKSCS = false;
+ boolean hasMS950_HKSCS = false;
boolean hasMS950_HKSCS_XP = false;
boolean hasEUC_TW = false;
for (String name : osStdcs) {
@@ -63,6 +64,8 @@
}
if (name.equals("Big5_HKSCS")) {
hasBig5_HKSCS = true;
+ } else if (name.equals("MS950_HKSCS")) {
+ hasMS950_HKSCS = true;
} else if (name.equals("MS950_HKSCS_XP")) {
hasMS950_HKSCS_XP = true;
} else if (name.equals("EUC_TW")) {
@@ -98,12 +101,15 @@
args[TEMPLATE],
args[OS].endsWith("windows") ? "windows" : "unix");
- // HKSCSMapping2008/XP.java goes together with Big5/MS950XP_HKSCS
- if (isStandard && hasBig5_HKSCS || isExtended && !hasBig5_HKSCS) {
+ // HKSCSMapping(2008).java goes std if one of Big5_HKSCS MS950_HKSCS
+ // is in std
+ if (isStandard && (hasBig5_HKSCS || hasMS950_HKSCS) ||
+ isExtended && !(hasBig5_HKSCS || hasMS950_HKSCS)) {
HKSCS.genClass2008(args[SRC_DIR], args[DST_DIR],
isStandard ? "sun.nio.cs" : "sun.nio.cs.ext",
new File(args[COPYRIGHT_SRC], "HKSCS.java"));
}
+ // HKSCS_XPMapping.java goes together with MS950XP_HKSCS
if (isStandard && hasMS950_HKSCS_XP || isExtended && !hasMS950_HKSCS_XP) {
HKSCS.genClassXP(args[SRC_DIR], args[DST_DIR],
isStandard ? "sun.nio.cs" : "sun.nio.cs.ext",
--- a/make/lib/Awt2dLibraries.gmk Tue Dec 05 10:21:41 2017 +0000
+++ b/make/lib/Awt2dLibraries.gmk Tue Dec 05 10:28:45 2017 +0000
@@ -658,7 +658,7 @@
$(eval $(call SetupNativeCompilation,BUILD_LIBFONTMANAGER, \
LIBRARY := fontmanager, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfontmanager, \
SRC := $(LIBFONTMANAGER_SRC), \
EXCLUDE_FILES := $(LIBFONTMANAGER_EXCLUDE_FILES) \
AccelGlyphCache.c, \
@@ -702,6 +702,21 @@
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfontmanager, \
))
+$(INSTALL_LIBRARIES_HERE)/$(call SHARED_LIBRARY,fontmanager): $(BUILD_LIBFONTMANAGER_TARGET)
+ $(install-file)
+ ifneq ($(FREETYPE_BUNDLE_LIB_PATH), )
+ ifeq ($(OPENJDK_TARGET_OS), macosx)
+ # If bundling freetype on macosx, we need to rewrite the rpath location
+ # in the libfontmanager library to point to the bundled location
+ $(INSTALL_NAME_TOOL) -change \
+ `$(OTOOL) -D $(FREETYPE_BUNDLE_LIB_PATH)/$(call SHARED_LIBRARY,freetype) | $(TAIL) -n1` \
+ '@rpath/$(call SHARED_LIBRARY,freetype)' \
+ $@
+ endif
+ endif
+
+BUILD_LIBFONTMANAGER += $(INSTALL_LIBRARIES_HERE)/$(call SHARED_LIBRARY,fontmanager)
+
$(BUILD_LIBFONTMANAGER): $(BUILD_LIBAWT)
ifneq (, $(findstring $(OPENJDK_TARGET_OS), solaris aix))
--- a/make/mapfiles/libjava/mapfile-vers Tue Dec 05 10:21:41 2017 +0000
+++ b/make/mapfiles/libjava/mapfile-vers Tue Dec 05 10:28:45 2017 +0000
@@ -205,10 +205,6 @@
Java_java_lang_Runtime_runFinalization0;
Java_java_lang_Runtime_totalMemory;
Java_java_lang_Runtime_availableProcessors;
- Java_java_lang_SecurityManager_classDepth;
- Java_java_lang_SecurityManager_classLoaderDepth0;
- Java_java_lang_SecurityManager_currentClassLoader0;
- Java_java_lang_SecurityManager_currentLoadedClass0;
Java_java_lang_SecurityManager_getClassContext;
Java_java_lang_Shutdown_halt0;
Java_java_lang_StackTraceElement_initStackTraceElement;
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp Tue Dec 05 10:21:41 2017 +0000
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp Tue Dec 05 10:28:45 2017 +0000
@@ -148,6 +148,16 @@
PrefetchCopyIntervalInBytes = 32760;
}
+ if (AllocatePrefetchDistance !=-1 && (AllocatePrefetchDistance & 7)) {
+ warning("AllocatePrefetchDistance must be multiple of 8");
+ AllocatePrefetchDistance &= ~7;
+ }
+
+ if (AllocatePrefetchStepSize & 7) {
+ warning("AllocatePrefetchStepSize must be multiple of 8");
+ AllocatePrefetchStepSize &= ~7;
+ }
+
if (SoftwarePrefetchHintDistance != -1 &&
(SoftwarePrefetchHintDistance & 7)) {
warning("SoftwarePrefetchHintDistance must be -1, or a multiple of 8");
--- a/src/hotspot/share/prims/jvm.cpp Tue Dec 05 10:21:41 2017 +0000
+++ b/src/hotspot/share/prims/jvm.cpp Tue Dec 05 10:28:45 2017 +0000
@@ -3137,64 +3137,6 @@
// java.lang.SecurityManager ///////////////////////////////////////////////////////////////////////
-static bool is_trusted_frame(JavaThread* jthread, vframeStream* vfst) {
- assert(jthread->is_Java_thread(), "must be a Java thread");
- if (jthread->privileged_stack_top() == NULL) return false;
- if (jthread->privileged_stack_top()->frame_id() == vfst->frame_id()) {
- oop loader = jthread->privileged_stack_top()->class_loader();
- if (loader == NULL) return true;
- bool trusted = java_lang_ClassLoader::is_trusted_loader(loader);
- if (trusted) return true;
- }
- return false;
-}
-
-JVM_ENTRY(jclass, JVM_CurrentLoadedClass(JNIEnv *env))
- JVMWrapper("JVM_CurrentLoadedClass");
- ResourceMark rm(THREAD);
-
- for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
- // if a method in a class in a trusted loader is in a doPrivileged, return NULL
- bool trusted = is_trusted_frame(thread, &vfst);
- if (trusted) return NULL;
-
- Method* m = vfst.method();
- if (!m->is_native()) {
- InstanceKlass* holder = m->method_holder();
- oop loader = holder->class_loader();
- if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) {
- return (jclass) JNIHandles::make_local(env, holder->java_mirror());
- }
- }
- }
- return NULL;
-JVM_END
-
-
-JVM_ENTRY(jobject, JVM_CurrentClassLoader(JNIEnv *env))
- JVMWrapper("JVM_CurrentClassLoader");
- ResourceMark rm(THREAD);
-
- for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
-
- // if a method in a class in a trusted loader is in a doPrivileged, return NULL
- bool trusted = is_trusted_frame(thread, &vfst);
- if (trusted) return NULL;
-
- Method* m = vfst.method();
- if (!m->is_native()) {
- InstanceKlass* holder = m->method_holder();
- assert(holder->is_klass(), "just checking");
- oop loader = holder->class_loader();
- if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) {
- return JNIHandles::make_local(env, loader);
- }
- }
- }
- return NULL;
-JVM_END
-
-
JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env))
JVMWrapper("JVM_GetClassContext");
ResourceMark rm(THREAD);
@@ -3234,58 +3176,6 @@
JVM_END
-JVM_ENTRY(jint, JVM_ClassDepth(JNIEnv *env, jstring name))
- JVMWrapper("JVM_ClassDepth");
- ResourceMark rm(THREAD);
- Handle h_name (THREAD, JNIHandles::resolve_non_null(name));
- Handle class_name_str = java_lang_String::internalize_classname(h_name, CHECK_0);
-
- const char* str = java_lang_String::as_utf8_string(class_name_str());
- TempNewSymbol class_name_sym = SymbolTable::probe(str, (int)strlen(str));
- if (class_name_sym == NULL) {
- return -1;
- }
-
- int depth = 0;
-
- for(vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
- if (!vfst.method()->is_native()) {
- InstanceKlass* holder = vfst.method()->method_holder();
- assert(holder->is_klass(), "just checking");
- if (holder->name() == class_name_sym) {
- return depth;
- }
- depth++;
- }
- }
- return -1;
-JVM_END
-
-
-JVM_ENTRY(jint, JVM_ClassLoaderDepth(JNIEnv *env))
- JVMWrapper("JVM_ClassLoaderDepth");
- ResourceMark rm(THREAD);
- int depth = 0;
- for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
- // if a method in a class in a trusted loader is in a doPrivileged, return -1
- bool trusted = is_trusted_frame(thread, &vfst);
- if (trusted) return -1;
-
- Method* m = vfst.method();
- if (!m->is_native()) {
- InstanceKlass* holder = m->method_holder();
- assert(holder->is_klass(), "just checking");
- oop loader = holder->class_loader();
- if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) {
- return depth;
- }
- depth++;
- }
- }
- return -1;
-JVM_END
-
-
// java.lang.Package ////////////////////////////////////////////////////////////////
--- a/src/java.base/share/classes/java/lang/Class.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/java/lang/Class.java Tue Dec 05 10:28:45 2017 +0000
@@ -53,12 +53,11 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.Set;
import java.util.StringJoiner;
import jdk.internal.HotSpotIntrinsicCandidate;
@@ -1771,7 +1770,7 @@
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
- return copyFields(privateGetPublicFields(null));
+ return copyFields(privateGetPublicFields());
}
@@ -3026,7 +3025,7 @@
// Returns an array of "root" fields. These Field objects must NOT
// be propagated to the outside world, but must instead be copied
// via ReflectionFactory.copyField.
- private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
+ private Field[] privateGetPublicFields() {
Field[] res;
ReflectionData<T> rd = reflectionData();
if (rd != null) {
@@ -3034,35 +3033,25 @@
if (res != null) return res;
}
- // No cached value available; compute value recursively.
- // Traverse in correct order for getField().
- List<Field> fields = new ArrayList<>();
- if (traversedInterfaces == null) {
- traversedInterfaces = new HashSet<>();
- }
+ // Use a linked hash set to ensure order is preserved and
+ // fields from common super interfaces are not duplicated
+ LinkedHashSet<Field> fields = new LinkedHashSet<>();
// Local fields
- Field[] tmp = privateGetDeclaredFields(true);
- addAll(fields, tmp);
+ addAll(fields, privateGetDeclaredFields(true));
// Direct superinterfaces, recursively
- for (Class<?> c : getInterfaces()) {
- if (!traversedInterfaces.contains(c)) {
- traversedInterfaces.add(c);
- addAll(fields, c.privateGetPublicFields(traversedInterfaces));
- }
+ for (Class<?> si : getInterfaces()) {
+ addAll(fields, si.privateGetPublicFields());
}
// Direct superclass, recursively
- if (!isInterface()) {
- Class<?> c = getSuperclass();
- if (c != null) {
- addAll(fields, c.privateGetPublicFields(traversedInterfaces));
- }
+ Class<?> sc = getSuperclass();
+ if (sc != null) {
+ addAll(fields, sc.privateGetPublicFields());
}
- res = new Field[fields.size()];
- fields.toArray(res);
+ res = fields.toArray(new Field[0]);
if (rd != null) {
rd.publicFields = res;
}
--- a/src/java.base/share/classes/java/lang/SecurityManager.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/java/lang/SecurityManager.java Tue Dec 05 10:28:45 2017 +0000
@@ -101,7 +101,7 @@
* <code>checkPermission</code> returns quietly. If denied, a
* <code>SecurityException</code> is thrown.
* <p>
- * As of Java 2 SDK v1.2, the default implementation of each of the other
+ * The default implementation of each of the other
* <code>check</code> methods in <code>SecurityManager</code> is to
* call the <code>SecurityManager checkPermission</code> method
* to determine if the calling thread has permission to perform the requested
@@ -197,10 +197,10 @@
* See {@extLink security_guide_permissions
* Permissions in the Java Development Kit (JDK)}
* for permission-related information.
- * This document includes, for example, a table listing the various SecurityManager
+ * This document includes a table listing the various SecurityManager
* <code>check</code> methods and the permission(s) the default
* implementation of each such method requires.
- * It also contains a table of all the version 1.2 methods
+ * It also contains a table of the methods
* that require permissions, and for each such method tells
* which permission it requires.
*
@@ -228,20 +228,7 @@
*
* @since 1.0
*/
-public
-class SecurityManager {
-
- /**
- * This field is <code>true</code> if there is a security check in
- * progress; <code>false</code> otherwise.
- *
- * @deprecated This type of security checking is not recommended.
- * It is recommended that the <code>checkPermission</code>
- * call be used instead. This field is subject to removal in a
- * future version of Java SE.
- */
- @Deprecated(since="1.2", forRemoval=true)
- protected boolean inCheck;
+public class SecurityManager {
/*
* Have we been initialized. Effective against finalizer attacks.
@@ -262,24 +249,6 @@
}
/**
- * Tests if there is a security check in progress.
- *
- * @return the value of the <code>inCheck</code> field. This field
- * should contain <code>true</code> if a security check is
- * in progress,
- * <code>false</code> otherwise.
- * @see java.lang.SecurityManager#inCheck
- * @deprecated This type of security checking is not recommended.
- * It is recommended that the <code>checkPermission</code>
- * call be used instead. This method is subject to removal in a
- * future version of Java SE.
- */
- @Deprecated(since="1.2", forRemoval=true)
- public boolean getInCheck() {
- return inCheck;
- }
-
- /**
* Constructs a new <code>SecurityManager</code>.
*
* <p> If there is a security manager already installed, this method first
@@ -322,198 +291,6 @@
protected native Class<?>[] getClassContext();
/**
- * Returns the class loader of the most recently executing method from
- * a class defined using a non-system class loader. A non-system
- * class loader is defined as being a class loader that is not equal to
- * the system class loader (as returned
- * by {@link ClassLoader#getSystemClassLoader}) or one of its ancestors.
- * <p>
- * This method will return
- * <code>null</code> in the following three cases:
- * <ol>
- * <li>All methods on the execution stack are from classes
- * defined using the system class loader or one of its ancestors.
- *
- * <li>All methods on the execution stack up to the first
- * "privileged" caller
- * (see {@link java.security.AccessController#doPrivileged})
- * are from classes
- * defined using the system class loader or one of its ancestors.
- *
- * <li> A call to <code>checkPermission</code> with
- * <code>java.security.AllPermission</code> does not
- * result in a SecurityException.
- *
- * </ol>
- *
- * @return the class loader of the most recent occurrence on the stack
- * of a method from a class defined using a non-system class
- * loader.
- *
- * @deprecated This type of security checking is not recommended.
- * It is recommended that the <code>checkPermission</code>
- * call be used instead. This method is subject to removal in a
- * future version of Java SE.
- *
- * @see java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader
- * @see #checkPermission(java.security.Permission) checkPermission
- */
- @Deprecated(since="1.2", forRemoval=true)
- protected ClassLoader currentClassLoader() {
- ClassLoader cl = currentClassLoader0();
- if ((cl != null) && hasAllPermission())
- cl = null;
- return cl;
- }
-
- private native ClassLoader currentClassLoader0();
-
- /**
- * Returns the class of the most recently executing method from
- * a class defined using a non-system class loader. A non-system
- * class loader is defined as being a class loader that is not equal to
- * the system class loader (as returned
- * by {@link ClassLoader#getSystemClassLoader}) or one of its ancestors.
- * <p>
- * This method will return
- * <code>null</code> in the following three cases:
- * <ol>
- * <li>All methods on the execution stack are from classes
- * defined using the system class loader or one of its ancestors.
- *
- * <li>All methods on the execution stack up to the first
- * "privileged" caller
- * (see {@link java.security.AccessController#doPrivileged})
- * are from classes
- * defined using the system class loader or one of its ancestors.
- *
- * <li> A call to <code>checkPermission</code> with
- * <code>java.security.AllPermission</code> does not
- * result in a SecurityException.
- *
- * </ol>
- *
- * @return the class of the most recent occurrence on the stack
- * of a method from a class defined using a non-system class
- * loader.
- *
- * @deprecated This type of security checking is not recommended.
- * It is recommended that the <code>checkPermission</code>
- * call be used instead. This method is subject to removal in a
- * future version of Java SE.
- *
- * @see java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader
- * @see #checkPermission(java.security.Permission) checkPermission
- */
- @Deprecated(since="1.2", forRemoval=true)
- protected Class<?> currentLoadedClass() {
- Class<?> c = currentLoadedClass0();
- if ((c != null) && hasAllPermission())
- c = null;
- return c;
- }
-
- /**
- * Returns the stack depth of the specified class.
- *
- * @param name the fully qualified name of the class to search for.
- * @return the depth on the stack frame of the first occurrence of a
- * method from a class with the specified name;
- * <code>-1</code> if such a frame cannot be found.
- * @deprecated This type of security checking is not recommended.
- * It is recommended that the <code>checkPermission</code>
- * call be used instead. This method is subject to removal in a
- * future version of Java SE.
- */
- @Deprecated(since="1.2", forRemoval=true)
- protected native int classDepth(String name);
-
- /**
- * Returns the stack depth of the most recently executing method
- * from a class defined using a non-system class loader. A non-system
- * class loader is defined as being a class loader that is not equal to
- * the system class loader (as returned
- * by {@link ClassLoader#getSystemClassLoader}) or one of its ancestors.
- * <p>
- * This method will return
- * -1 in the following three cases:
- * <ol>
- * <li>All methods on the execution stack are from classes
- * defined using the system class loader or one of its ancestors.
- *
- * <li>All methods on the execution stack up to the first
- * "privileged" caller
- * (see {@link java.security.AccessController#doPrivileged})
- * are from classes
- * defined using the system class loader or one of its ancestors.
- *
- * <li> A call to <code>checkPermission</code> with
- * <code>java.security.AllPermission</code> does not
- * result in a SecurityException.
- *
- * </ol>
- *
- * @return the depth on the stack frame of the most recent occurrence of
- * a method from a class defined using a non-system class loader.
- *
- * @deprecated This type of security checking is not recommended.
- * It is recommended that the <code>checkPermission</code>
- * call be used instead. This method is subject to removal in a
- * future version of Java SE.
- *
- * @see java.lang.ClassLoader#getSystemClassLoader() getSystemClassLoader
- * @see #checkPermission(java.security.Permission) checkPermission
- */
- @Deprecated(since="1.2", forRemoval=true)
- protected int classLoaderDepth() {
- int depth = classLoaderDepth0();
- if (depth != -1) {
- if (hasAllPermission())
- depth = -1;
- else
- depth--; // make sure we don't include ourself
- }
- return depth;
- }
-
- private native int classLoaderDepth0();
-
- /**
- * Tests if a method from a class with the specified
- * name is on the execution stack.
- *
- * @param name the fully qualified name of the class.
- * @return <code>true</code> if a method from a class with the specified
- * name is on the execution stack; <code>false</code> otherwise.
- * @deprecated This type of security checking is not recommended.
- * It is recommended that the <code>checkPermission</code>
- * call be used instead. This method is subject to removal in a
- * future version of Java SE.
- */
- @Deprecated(since="1.2", forRemoval=true)
- protected boolean inClass(String name) {
- return classDepth(name) >= 0;
- }
-
- /**
- * Basically, tests if a method from a class defined using a
- * class loader is on the execution stack.
- *
- * @return <code>true</code> if a call to <code>currentClassLoader</code>
- * has a non-null return value.
- *
- * @deprecated This type of security checking is not recommended.
- * It is recommended that the <code>checkPermission</code>
- * call be used instead. This method is subject to removal in a
- * future version of Java SE.
- * @see #currentClassLoader() currentClassLoader
- */
- @Deprecated(since="1.2", forRemoval=true)
- protected boolean inClassLoader() {
- return currentClassLoader() != null;
- }
-
- /**
* Creates an object that encapsulates the current execution
* environment. The result of this method is used, for example, by the
* three-argument <code>checkConnect</code> method and by the
@@ -1698,64 +1475,32 @@
}
/**
- * Throws a <code>SecurityException</code> if the
- * calling thread is not allowed to access members.
- * <p>
- * The default policy is to allow access to PUBLIC members, as well
- * as access to classes that have the same class loader as the caller.
- * In all other cases, this method calls <code>checkPermission</code>
- * with the <code>RuntimePermission("accessDeclaredMembers")
- * </code> permission.
- * <p>
- * If this method is overridden, then a call to
- * <code>super.checkMemberAccess</code> cannot be made,
- * as the default implementation of <code>checkMemberAccess</code>
- * relies on the code being checked being at a stack depth of
- * 4.
+ * Throws a {@code SecurityException} if the calling thread does
+ * not have {@code AllPermission}.
*
* @param clazz the class that reflection is to be performed on.
- *
* @param which type of access, PUBLIC or DECLARED.
- *
- * @exception SecurityException if the caller does not have
- * permission to access members.
- * @exception NullPointerException if the <code>clazz</code> argument is
- * <code>null</code>.
- *
- * @deprecated This method relies on the caller being at a stack depth
- * of 4 which is error-prone and cannot be enforced by the runtime.
- * Users of this method should instead invoke {@link #checkPermission}
- * directly.
- * This method is subject to removal in a future version of Java SE.
- *
- * @see java.lang.reflect.Member
+ * @throws SecurityException if the caller does not have
+ * {@code AllPermission}
+ * @throws NullPointerException if the {@code clazz} argument is
+ * {@code null}
+ * @deprecated This method was originally used to check if the calling
+ * thread was allowed to access members. It relied on the
+ * caller being at a stack depth of 4 which is error-prone and
+ * cannot be enforced by the runtime. The method has been
+ * obsoleted and code should instead use
+ * {@link #checkPermission} to check
+ * {@code RuntimePermission("accessDeclaredMembers")}. This
+ * method is subject to removal in a future version of Java SE.
* @since 1.1
* @see #checkPermission(java.security.Permission) checkPermission
*/
@Deprecated(since="1.8", forRemoval=true)
- @CallerSensitive
public void checkMemberAccess(Class<?> clazz, int which) {
if (clazz == null) {
throw new NullPointerException("class can't be null");
}
- if (which != Member.PUBLIC) {
- Class<?> stack[] = getClassContext();
- /*
- * stack depth of 4 should be the caller of one of the
- * methods in java.lang.Class that invoke checkMember
- * access. The stack should look like:
- *
- * someCaller [3]
- * java.lang.Class.someReflectionAPI [2]
- * java.lang.Class.checkMemberAccess [1]
- * SecurityManager.checkMemberAccess [0]
- *
- */
- if ((stack.length<4) ||
- (stack[3].getClassLoader() != clazz.getClassLoader())) {
- checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
- }
- }
+ checkPermission(SecurityConstants.ALL_PERMISSION);
}
/**
@@ -1792,8 +1537,6 @@
checkPermission(new SecurityPermission(target));
}
- private native Class<?> currentLoadedClass0();
-
/**
* Returns the thread group into which to instantiate any new
* thread being created at the time this is being called.
--- a/src/java.base/share/classes/java/lang/System.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/java/lang/System.java Tue Dec 05 10:28:45 2017 +0000
@@ -63,8 +63,8 @@
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import jdk.internal.HotSpotIntrinsicCandidate;
-import jdk.internal.misc.JavaLangAccess;;
-import jdk.internal.misc.SharedSecrets;;
+import jdk.internal.misc.JavaLangAccess;
+import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.VM;
import jdk.internal.logger.LoggerFinderLoader;
import jdk.internal.logger.LazyLoggers;
--- a/src/java.base/share/classes/java/util/Collection.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/java/util/Collection.java Tue Dec 05 10:28:45 2017 +0000
@@ -54,19 +54,15 @@
* constructors) but all of the general-purpose {@code Collection}
* implementations in the Java platform libraries comply.
*
- * <p>The "destructive" methods contained in this interface, that is, the
- * methods that modify the collection on which they operate, are specified to
- * throw {@code UnsupportedOperationException} if this collection does not
- * support the operation. If this is the case, these methods may, but are not
- * required to, throw an {@code UnsupportedOperationException} if the
- * invocation would have no effect on the collection. For example, invoking
- * the {@link #addAll(Collection)} method on an unmodifiable collection may,
- * but is not required to, throw the exception if the collection to be added
- * is empty.
+ * <p>Certain methods are specified to be
+ * <i>optional</i>. If a collection implementation doesn't implement a
+ * particular operation, it should define the corresponding method to throw
+ * {@code UnsupportedOperationException}. Such methods are marked "optional
+ * operation" in method specifications of the collections interfaces.
*
- * <p><a id="optional-restrictions">
- * Some collection implementations have restrictions on the elements that
- * they may contain.</a> For example, some implementations prohibit null elements,
+ * <p><a id="optional-restrictions"></a>Some collection implementations
+ * have restrictions on the elements that they may contain.
+ * For example, some implementations prohibit null elements,
* and some have restrictions on the types of their elements. Attempting to
* add an ineligible element throws an unchecked exception, typically
* {@code NullPointerException} or {@code ClassCastException}. Attempting
@@ -111,6 +107,86 @@
* methods. Implementations may optionally handle the self-referential scenario,
* however most current implementations do not do so.
*
+ * <h2><a id="view">View Collections</a></h2>
+ *
+ * <p>Most collections manage storage for elements they contain. By contrast, <i>view
+ * collections</i> themselves do not store elements, but instead they rely on a
+ * backing collection to store the actual elements. Operations that are not handled
+ * by the view collection itself are delegated to the backing collection. Examples of
+ * view collections include the wrapper collections returned by methods such as
+ * {@link Collections#checkedCollection Collections.checkedCollection},
+ * {@link Collections#synchronizedCollection Collections.synchronizedCollection}, and
+ * {@link Collections#unmodifiableCollection Collections.unmodifiableCollection}.
+ * Other examples of view collections include collections that provide a
+ * different representation of the same elements, for example, as
+ * provided by {@link List#subList List.subList},
+ * {@link NavigableSet#subSet NavigableSet.subSet}, or
+ * {@link Map#entrySet Map.entrySet}.
+ * Any changes made to the backing collection are visible in the view collection.
+ * Correspondingly, any changes made to the view collection — if changes
+ * are permitted — are written through to the backing collection.
+ * Although they technically aren't collections, instances of
+ * {@link Iterator} and {@link ListIterator} can also allow modifications
+ * to be written through to the backing collection, and in some cases,
+ * modifications to the backing collection will be visible to the Iterator
+ * during iteration.
+ *
+ * <h2><a id="unmodifiable">Unmodifiable Collections</a></h2>
+ *
+ * <p>Certain methods of this interface are considered "destructive" and are called
+ * "mutator" methods in that they modify the group of objects contained within
+ * the collection on which they operate. They can be specified to throw
+ * {@code UnsupportedOperationException} if this collection implementation
+ * does not support the operation. Such methods should (but are not required
+ * to) throw an {@code UnsupportedOperationException} if the invocation would
+ * have no effect on the collection. For example, consider a collection that
+ * does not support the {@link #add add} operation. What will happen if the
+ * {@link #addAll addAll} method is invoked on this collection, with an empty
+ * collection as the argument? The addition of zero elements has no effect,
+ * so it is permissible for this collection simply to do nothing and not to throw
+ * an exception. However, it is recommended that such cases throw an exception
+ * unconditionally, as throwing only in certain cases can lead to
+ * programming errors.
+ *
+ * <p>An <i>unmodifiable collection</i> is a collection, all of whose
+ * mutator methods (as defined above) are specified to throw
+ * {@code UnsupportedOperationException}. Such a collection thus cannot be
+ * modified by calling any methods on it. For a collection to be properly
+ * unmodifiable, any view collections derived from it must also be unmodifiable.
+ * For example, if a List is unmodifiable, the List returned by
+ * {@link List#subList List.subList} is also unmodifiable.
+ *
+ * <p>An unmodifiable collection is not necessarily immutable. If the
+ * contained elements are mutable, the entire collection is clearly
+ * mutable, even though it might be unmodifiable. For example, consider
+ * two unmodifiable lists containing mutable elements. The result of calling
+ * {@code list1.equals(list2)} might differ from one call to the next if
+ * the elements had been mutated, even though both lists are unmodifiable.
+ * However, if an unmodifiable collection contains all immutable elements,
+ * it can be considered effectively immutable.
+ *
+ * <h2><a id="unmodview">Unmodifiable View Collections</a></h2>
+ *
+ * <p>An <i>unmodifiable view collection</i> is a collection that is unmodifiable
+ * and that is also a view onto a backing collection. Its mutator methods throw
+ * {@code UnsupportedOperationException}, as described above, while
+ * reading and querying methods are delegated to the backing collection.
+ * The effect is to provide read-only access to the backing collection.
+ * This is useful for a component to provide users with read access to
+ * an internal collection, while preventing them from modifying such
+ * collections unexpectedly. Examples of unmodifiable view collections
+ * are those returned by the
+ * {@link Collections#unmodifiableCollection Collections.unmodifiableCollection},
+ * {@link Collections#unmodifiableList Collections.unmodifiableList}, and
+ * related methods.
+ *
+ * <p>Note that changes to the backing collection might still be possible,
+ * and if they occur, they are visible through the unmodifiable view. Thus,
+ * an unmodifiable view collection is not necessarily immutable. However,
+ * if the backing collection of an unmodifiable view is effectively immutable,
+ * or if the only reference to the backing collection is through an
+ * unmodifiable view, the view can be considered effectively immutable.
+ *
* <p>This interface is a member of the
* <a href="{@docRoot}/java/util/package-summary.html#CollectionsFramework">
* Java Collections Framework</a>.
@@ -192,7 +268,8 @@
* Returns an array containing all of the elements in this collection.
* If this collection makes any guarantees as to what order its elements
* are returned by its iterator, this method must return the elements in
- * the same order.
+ * the same order. The returned array's {@linkplain Class#getComponentType
+ * runtime component type} is {@code Object}.
*
* <p>The returned array will be "safe" in that no references to it are
* maintained by this collection. (In other words, this method must
@@ -202,7 +279,8 @@
* <p>This method acts as bridge between array-based and collection-based
* APIs.
*
- * @return an array containing all of the elements in this collection
+ * @return an array, whose {@linkplain Class#getComponentType runtime component
+ * type} is {@code Object}, containing all of the elements in this collection
*/
Object[] toArray();
@@ -239,14 +317,14 @@
* Note that {@code toArray(new Object[0])} is identical in function to
* {@code toArray()}.
*
- * @param <T> the runtime type of the array to contain the collection
+ * @param <T> the component type of the array to contain the collection
* @param a the array into which the elements of this collection are to be
* stored, if it is big enough; otherwise, a new array of the same
* runtime type is allocated for this purpose.
* @return an array containing all of the elements in this collection
- * @throws ArrayStoreException if the runtime type of the specified array
- * is not a supertype of the runtime type of every element in
- * this collection
+ * @throws ArrayStoreException if the runtime type of any element in this
+ * collection is not assignable to the {@linkplain Class#getComponentType
+ * runtime component type} of the specified array
* @throws NullPointerException if the specified array is null
*/
<T> T[] toArray(T[] a);
--- a/src/java.base/share/classes/java/util/Collections.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/java/util/Collections.java Tue Dec 05 10:28:45 2017 +0000
@@ -989,9 +989,8 @@
// Unmodifiable Wrappers
/**
- * Returns an unmodifiable view of the specified collection. This method
- * allows modules to provide users with "read-only" access to internal
- * collections. Query operations on the returned collection "read through"
+ * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
+ * specified collection. Query operations on the returned collection "read through"
* to the specified collection, and attempts to modify the returned
* collection, whether direct or via its iterator, result in an
* {@code UnsupportedOperationException}.<p>
@@ -1102,9 +1101,8 @@
}
/**
- * Returns an unmodifiable view of the specified set. This method allows
- * modules to provide users with "read-only" access to internal sets.
- * Query operations on the returned set "read through" to the specified
+ * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
+ * specified set. Query operations on the returned set "read through" to the specified
* set, and attempts to modify the returned set, whether direct or via its
* iterator, result in an {@code UnsupportedOperationException}.<p>
*
@@ -1132,9 +1130,8 @@
}
/**
- * Returns an unmodifiable view of the specified sorted set. This method
- * allows modules to provide users with "read-only" access to internal
- * sorted sets. Query operations on the returned sorted set "read
+ * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
+ * specified sorted set. Query operations on the returned sorted set "read
* through" to the specified sorted set. Attempts to modify the returned
* sorted set, whether direct, via its iterator, or via its
* {@code subSet}, {@code headSet}, or {@code tailSet} views, result in
@@ -1180,9 +1177,8 @@
}
/**
- * Returns an unmodifiable view of the specified navigable set. This method
- * allows modules to provide users with "read-only" access to internal
- * navigable sets. Query operations on the returned navigable set "read
+ * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
+ * specified navigable set. Query operations on the returned navigable set "read
* through" to the specified navigable set. Attempts to modify the returned
* navigable set, whether direct, via its iterator, or via its
* {@code subSet}, {@code headSet}, or {@code tailSet} views, result in
@@ -1269,9 +1265,8 @@
}
/**
- * Returns an unmodifiable view of the specified list. This method allows
- * modules to provide users with "read-only" access to internal
- * lists. Query operations on the returned list "read through" to the
+ * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
+ * specified list. Query operations on the returned list "read through" to the
* specified list, and attempts to modify the returned list, whether
* direct or via its iterator, result in an
* {@code UnsupportedOperationException}.<p>
@@ -1415,9 +1410,8 @@
}
/**
- * Returns an unmodifiable view of the specified map. This method
- * allows modules to provide users with "read-only" access to internal
- * maps. Query operations on the returned map "read through"
+ * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
+ * specified map. Query operations on the returned map "read through"
* to the specified map, and attempts to modify the returned
* map, whether direct or via its collection views, result in an
* {@code UnsupportedOperationException}.<p>
@@ -1765,9 +1759,8 @@
}
/**
- * Returns an unmodifiable view of the specified sorted map. This method
- * allows modules to provide users with "read-only" access to internal
- * sorted maps. Query operations on the returned sorted map "read through"
+ * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
+ * specified sorted map. Query operations on the returned sorted map "read through"
* to the specified sorted map. Attempts to modify the returned
* sorted map, whether direct, via its collection views, or via its
* {@code subMap}, {@code headMap}, or {@code tailMap} views, result in
@@ -1809,9 +1802,8 @@
}
/**
- * Returns an unmodifiable view of the specified navigable map. This method
- * allows modules to provide users with "read-only" access to internal
- * navigable maps. Query operations on the returned navigable map "read
+ * Returns an <a href="Collection.html#unmodview">unmodifiable view</a> of the
+ * specified navigable map. Query operations on the returned navigable map "read
* through" to the specified navigable map. Attempts to modify the returned
* navigable map, whether direct, via its collection views, or via its
* {@code subMap}, {@code headMap}, or {@code tailMap} views, result in
--- a/src/java.base/share/classes/java/util/List.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/java/util/List.java Tue Dec 05 10:28:45 2017 +0000
@@ -87,15 +87,16 @@
* Such exceptions are marked as "optional" in the specification for this
* interface.
*
- * <h2><a id="immutable">Immutable List Static Factory Methods</a></h2>
- * <p>The {@link List#of(Object...) List.of()} static factory methods
- * provide a convenient way to create immutable lists. The {@code List}
+ * <h2><a id="unmodifiable">Unmodifiable Lists</a></h2>
+ * <p>The {@link List#of(Object...) List.of} and
+ * {@link List#copyOf List.copyOf} static factory methods
+ * provide a convenient way to create unmodifiable lists. The {@code List}
* instances created by these methods have the following characteristics:
*
* <ul>
- * <li>They are <em>structurally immutable</em>. Elements cannot be added, removed,
- * or replaced. Calling any mutator method will always cause
- * {@code UnsupportedOperationException} to be thrown.
+ * <li>They are <a href="Collection.html#unmodifiable"><i>unmodifiable</i></a>. Elements cannot
+ * be added, removed, or replaced. Calling any mutator method on the List
+ * will always cause {@code UnsupportedOperationException} to be thrown.
* However, if the contained elements are themselves mutable,
* this may cause the List's contents to appear to change.
* <li>They disallow {@code null} elements. Attempts to create them with
@@ -777,9 +778,9 @@
}
/**
- * Returns an immutable list containing zero elements.
+ * Returns an unmodifiable list containing zero elements.
*
- * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+ * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
*
* @param <E> the {@code List}'s element type
* @return an empty {@code List}
@@ -791,9 +792,9 @@
}
/**
- * Returns an immutable list containing one element.
+ * Returns an unmodifiable list containing one element.
*
- * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+ * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
*
* @param <E> the {@code List}'s element type
* @param e1 the single element
@@ -807,9 +808,9 @@
}
/**
- * Returns an immutable list containing two elements.
+ * Returns an unmodifiable list containing two elements.
*
- * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+ * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
*
* @param <E> the {@code List}'s element type
* @param e1 the first element
@@ -824,9 +825,9 @@
}
/**
- * Returns an immutable list containing three elements.
+ * Returns an unmodifiable list containing three elements.
*
- * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+ * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
*
* @param <E> the {@code List}'s element type
* @param e1 the first element
@@ -842,9 +843,9 @@
}
/**
- * Returns an immutable list containing four elements.
+ * Returns an unmodifiable list containing four elements.
*
- * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+ * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
*
* @param <E> the {@code List}'s element type
* @param e1 the first element
@@ -861,9 +862,9 @@
}
/**
- * Returns an immutable list containing five elements.
+ * Returns an unmodifiable list containing five elements.
*
- * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+ * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
*
* @param <E> the {@code List}'s element type
* @param e1 the first element
@@ -881,9 +882,9 @@
}
/**
- * Returns an immutable list containing six elements.
+ * Returns an unmodifiable list containing six elements.
*
- * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+ * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
*
* @param <E> the {@code List}'s element type
* @param e1 the first element
@@ -903,9 +904,9 @@
}
/**
- * Returns an immutable list containing seven elements.
+ * Returns an unmodifiable list containing seven elements.
*
- * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+ * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
*
* @param <E> the {@code List}'s element type
* @param e1 the first element
@@ -926,9 +927,9 @@
}
/**
- * Returns an immutable list containing eight elements.
+ * Returns an unmodifiable list containing eight elements.
*
- * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+ * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
*
* @param <E> the {@code List}'s element type
* @param e1 the first element
@@ -950,9 +951,9 @@
}
/**
- * Returns an immutable list containing nine elements.
+ * Returns an unmodifiable list containing nine elements.
*
- * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+ * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
*
* @param <E> the {@code List}'s element type
* @param e1 the first element
@@ -975,9 +976,9 @@
}
/**
- * Returns an immutable list containing ten elements.
+ * Returns an unmodifiable list containing ten elements.
*
- * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+ * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
*
* @param <E> the {@code List}'s element type
* @param e1 the first element
@@ -1001,8 +1002,8 @@
}
/**
- * Returns an immutable list containing an arbitrary number of elements.
- * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+ * Returns an unmodifiable list containing an arbitrary number of elements.
+ * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
*
* @apiNote
* This method also accepts a single array as an argument. The element type of
@@ -1039,4 +1040,29 @@
return new ImmutableCollections.ListN<>(elements);
}
}
+
+ /**
+ * Returns an <a href="#unmodifiable">unmodifiable List</a> containing the elements of
+ * the given Collection, in its iteration order. The given Collection must not be null,
+ * and it must not contain any null elements. If the given Collection is subsequently
+ * modified, the returned List will not reflect such modifications.
+ *
+ * @implNote
+ * If the given Collection is an <a href="#unmodifiable">unmodifiable List</a>,
+ * calling copyOf will generally not create a copy.
+ *
+ * @param <E> the {@code List}'s element type
+ * @param coll a {@code Collection} from which elements are drawn, must be non-null
+ * @return a {@code List} containing the elements of the given {@code Collection}
+ * @throws NullPointerException if coll is null, or if it contains any nulls
+ * @since 10
+ */
+ @SuppressWarnings("unchecked")
+ static <E> List<E> copyOf(Collection<? extends E> coll) {
+ if (coll instanceof ImmutableCollections.AbstractImmutableList) {
+ return (List<E>)coll;
+ } else {
+ return (List<E>)List.of(coll.toArray());
+ }
+ }
}
--- a/src/java.base/share/classes/java/util/Map.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/java/util/Map.java Tue Dec 05 10:28:45 2017 +0000
@@ -110,17 +110,18 @@
* Implementations may optionally handle the self-referential scenario, however
* most current implementations do not do so.
*
- * <h2><a id="immutable">Immutable Map Static Factory Methods</a></h2>
- * <p>The {@link Map#of() Map.of()} and
- * {@link Map#ofEntries(Map.Entry...) Map.ofEntries()}
- * static factory methods provide a convenient way to create immutable maps.
+ * <h2><a id="unmodifiable">Unmodifiable Maps</a></h2>
+ * <p>The {@link Map#of() Map.of},
+ * {@link Map#ofEntries(Map.Entry...) Map.ofEntries}, and
+ * {@link Map#copyOf Map.copyOf}
+ * static factory methods provide a convenient way to create unmodifiable maps.
* The {@code Map}
* instances created by these methods have the following characteristics:
*
* <ul>
- * <li>They are <em>structurally immutable</em>. Keys and values cannot be added,
- * removed, or updated. Calling any mutator method will always cause
- * {@code UnsupportedOperationException} to be thrown.
+ * <li>They are <a href="Collection.html#unmodifiable"><i>unmodifiable</i></a>. Keys and values
+ * cannot be added, removed, or updated. Calling any mutator method on the Map
+ * will always cause {@code UnsupportedOperationException} to be thrown.
* However, if the contained keys or values are themselves mutable, this may cause the
* Map to behave inconsistently or its contents to appear to change.
* <li>They disallow {@code null} keys and values. Attempts to create them with
@@ -1276,8 +1277,8 @@
}
/**
- * Returns an immutable map containing zero mappings.
- * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+ * Returns an unmodifiable map containing zero mappings.
+ * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
*
* @param <K> the {@code Map}'s key type
* @param <V> the {@code Map}'s value type
@@ -1290,8 +1291,8 @@
}
/**
- * Returns an immutable map containing a single mapping.
- * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+ * Returns an unmodifiable map containing a single mapping.
+ * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
*
* @param <K> the {@code Map}'s key type
* @param <V> the {@code Map}'s value type
@@ -1307,8 +1308,8 @@
}
/**
- * Returns an immutable map containing two mappings.
- * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+ * Returns an unmodifiable map containing two mappings.
+ * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
*
* @param <K> the {@code Map}'s key type
* @param <V> the {@code Map}'s value type
@@ -1327,8 +1328,8 @@
}
/**
- * Returns an immutable map containing three mappings.
- * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+ * Returns an unmodifiable map containing three mappings.
+ * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
*
* @param <K> the {@code Map}'s key type
* @param <V> the {@code Map}'s value type
@@ -1349,8 +1350,8 @@
}
/**
- * Returns an immutable map containing four mappings.
- * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+ * Returns an unmodifiable map containing four mappings.
+ * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
*
* @param <K> the {@code Map}'s key type
* @param <V> the {@code Map}'s value type
@@ -1373,8 +1374,8 @@
}
/**
- * Returns an immutable map containing five mappings.
- * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+ * Returns an unmodifiable map containing five mappings.
+ * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
*
* @param <K> the {@code Map}'s key type
* @param <V> the {@code Map}'s value type
@@ -1399,8 +1400,8 @@
}
/**
- * Returns an immutable map containing six mappings.
- * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+ * Returns an unmodifiable map containing six mappings.
+ * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
*
* @param <K> the {@code Map}'s key type
* @param <V> the {@code Map}'s value type
@@ -1429,8 +1430,8 @@
}
/**
- * Returns an immutable map containing seven mappings.
- * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+ * Returns an unmodifiable map containing seven mappings.
+ * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
*
* @param <K> the {@code Map}'s key type
* @param <V> the {@code Map}'s value type
@@ -1461,8 +1462,8 @@
}
/**
- * Returns an immutable map containing eight mappings.
- * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+ * Returns an unmodifiable map containing eight mappings.
+ * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
*
* @param <K> the {@code Map}'s key type
* @param <V> the {@code Map}'s value type
@@ -1495,8 +1496,8 @@
}
/**
- * Returns an immutable map containing nine mappings.
- * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+ * Returns an unmodifiable map containing nine mappings.
+ * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
*
* @param <K> the {@code Map}'s key type
* @param <V> the {@code Map}'s value type
@@ -1531,8 +1532,8 @@
}
/**
- * Returns an immutable map containing ten mappings.
- * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+ * Returns an unmodifiable map containing ten mappings.
+ * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
*
* @param <K> the {@code Map}'s key type
* @param <V> the {@code Map}'s value type
@@ -1569,9 +1570,9 @@
}
/**
- * Returns an immutable map containing keys and values extracted from the given entries.
+ * Returns an unmodifiable map containing keys and values extracted from the given entries.
* The entries themselves are not stored in the map.
- * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+ * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
*
* @apiNote
* It is convenient to create the map entries using the {@link Map#entry Map.entry()} method.
@@ -1602,15 +1603,17 @@
@SafeVarargs
@SuppressWarnings("varargs")
static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) {
- if (entries.length == 0) { // implicit null check of entries
+ if (entries.length == 0) { // implicit null check of entries array
return ImmutableCollections.Map0.instance();
} else if (entries.length == 1) {
+ // implicit null check of the array slot
return new ImmutableCollections.Map1<>(entries[0].getKey(),
entries[0].getValue());
} else {
Object[] kva = new Object[entries.length << 1];
int a = 0;
for (Entry<? extends K, ? extends V> entry : entries) {
+ // implicit null checks of each array slot
kva[a++] = entry.getKey();
kva[a++] = entry.getValue();
}
@@ -1619,7 +1622,7 @@
}
/**
- * Returns an immutable {@link Entry} containing the given key and value.
+ * Returns an unmodifiable {@link Entry} containing the given key and value.
* These entries are suitable for populating {@code Map} instances using the
* {@link Map#ofEntries Map.ofEntries()} method.
* The {@code Entry} instances created by this method have the following characteristics:
@@ -1627,7 +1630,7 @@
* <ul>
* <li>They disallow {@code null} keys and values. Attempts to create them using a {@code null}
* key or value result in {@code NullPointerException}.
- * <li>They are immutable. Calls to {@link Entry#setValue Entry.setValue()}
+ * <li>They are unmodifiable. Calls to {@link Entry#setValue Entry.setValue()}
* on a returned {@code Entry} result in {@code UnsupportedOperationException}.
* <li>They are not serializable.
* <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
@@ -1655,4 +1658,30 @@
// KeyValueHolder checks for nulls
return new KeyValueHolder<>(k, v);
}
+
+ /**
+ * Returns an <a href="#unmodifiable">unmodifiable Map</a> containing the entries
+ * of the given Map. The given Map must not be null, and it must not contain any
+ * null keys or values. If the given Map is subsequently modified, the returned
+ * Map will not reflect such modifications.
+ *
+ * @implNote
+ * If the given Map is an <a href="#unmodifiable">unmodifiable Map</a>,
+ * calling copyOf will generally not create a copy.
+ *
+ * @param <K> the {@code Map}'s key type
+ * @param <V> the {@code Map}'s value type
+ * @param map a {@code Map} from which entries are drawn, must be non-null
+ * @return a {@code Map} containing the entries of the given {@code Map}
+ * @throws NullPointerException if map is null, or if it contains any null keys or values
+ * @since 10
+ */
+ @SuppressWarnings({"rawtypes","unchecked"})
+ static <K, V> Map<K, V> copyOf(Map<? extends K, ? extends V> map) {
+ if (map instanceof ImmutableCollections.AbstractImmutableMap) {
+ return (Map<K,V>)map;
+ } else {
+ return (Map<K,V>)Map.ofEntries(map.entrySet().toArray(new Entry[0]));
+ }
+ }
}
--- a/src/java.base/share/classes/java/util/Set.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/java/util/Set.java Tue Dec 05 10:28:45 2017 +0000
@@ -63,15 +63,16 @@
* Such exceptions are marked as "optional" in the specification for this
* interface.
*
- * <h2><a id="immutable">Immutable Set Static Factory Methods</a></h2>
- * <p>The {@link Set#of(Object...) Set.of()} static factory methods
- * provide a convenient way to create immutable sets. The {@code Set}
+ * <h2><a id="unmodifiable">Unmodifiable Sets</a></h2>
+ * <p>The {@link Set#of(Object...) Set.of} and
+ * {@link Set#copyOf Set.copyOf} static factory methods
+ * provide a convenient way to create unmodifiable sets. The {@code Set}
* instances created by these methods have the following characteristics:
*
* <ul>
- * <li>They are <em>structurally immutable</em>. Elements cannot be added or
- * removed. Calling any mutator method will always cause
- * {@code UnsupportedOperationException} to be thrown.
+ * <li>They are <a href="Collection.html#unmodifiable"><i>unmodifiable</i></a>. Elements cannot
+ * be added or removed. Calling any mutator method on the Set
+ * will always cause {@code UnsupportedOperationException} to be thrown.
* However, if the contained elements are themselves mutable, this may cause the
* Set to behave inconsistently or its contents to appear to change.
* <li>They disallow {@code null} elements. Attempts to create them with
@@ -439,8 +440,8 @@
}
/**
- * Returns an immutable set containing zero elements.
- * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+ * Returns an unmodifiable set containing zero elements.
+ * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @return an empty {@code Set}
@@ -452,8 +453,8 @@
}
/**
- * Returns an immutable set containing one element.
- * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+ * Returns an unmodifiable set containing one element.
+ * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the single element
@@ -467,8 +468,8 @@
}
/**
- * Returns an immutable set containing two elements.
- * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+ * Returns an unmodifiable set containing two elements.
+ * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@@ -484,8 +485,8 @@
}
/**
- * Returns an immutable set containing three elements.
- * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+ * Returns an unmodifiable set containing three elements.
+ * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@@ -502,8 +503,8 @@
}
/**
- * Returns an immutable set containing four elements.
- * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+ * Returns an unmodifiable set containing four elements.
+ * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@@ -521,8 +522,8 @@
}
/**
- * Returns an immutable set containing five elements.
- * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+ * Returns an unmodifiable set containing five elements.
+ * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@@ -541,8 +542,8 @@
}
/**
- * Returns an immutable set containing six elements.
- * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+ * Returns an unmodifiable set containing six elements.
+ * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@@ -563,8 +564,8 @@
}
/**
- * Returns an immutable set containing seven elements.
- * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+ * Returns an unmodifiable set containing seven elements.
+ * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@@ -586,8 +587,8 @@
}
/**
- * Returns an immutable set containing eight elements.
- * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+ * Returns an unmodifiable set containing eight elements.
+ * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@@ -610,8 +611,8 @@
}
/**
- * Returns an immutable set containing nine elements.
- * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+ * Returns an unmodifiable set containing nine elements.
+ * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@@ -635,8 +636,8 @@
}
/**
- * Returns an immutable set containing ten elements.
- * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+ * Returns an unmodifiable set containing ten elements.
+ * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@@ -661,8 +662,8 @@
}
/**
- * Returns an immutable set containing an arbitrary number of elements.
- * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+ * Returns an unmodifiable set containing an arbitrary number of elements.
+ * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @apiNote
* This method also accepts a single array as an argument. The element type of
@@ -700,4 +701,30 @@
return new ImmutableCollections.SetN<>(elements);
}
}
+
+ /**
+ * Returns an <a href="#unmodifiable">unmodifiable Set</a> containing the elements
+ * of the given Collection. The given Collection must not be null, and it must not
+ * contain any null elements. If the given Collection contains duplicate elements,
+ * an arbitrary element of the duplicates is preserved. If the given Collection is
+ * subsequently modified, the returned Set will not reflect such modifications.
+ *
+ * @implNote
+ * If the given Collection is an <a href="#unmodifiable">unmodifiable Set</a>,
+ * calling copyOf will generally not create a copy.
+ *
+ * @param <E> the {@code Set}'s element type
+ * @param coll a {@code Collection} from which elements are drawn, must be non-null
+ * @return a {@code Set} containing the elements of the given {@code Collection}
+ * @throws NullPointerException if coll is null, or if it contains any nulls
+ * @since 10
+ */
+ @SuppressWarnings("unchecked")
+ static <E> Set<E> copyOf(Collection<? extends E> coll) {
+ if (coll instanceof ImmutableCollections.AbstractImmutableSet) {
+ return (Set<E>)coll;
+ } else {
+ return (Set<E>)Set.of(new HashSet<>(coll).toArray());
+ }
+ }
}
--- a/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java Tue Dec 05 10:28:45 2017 +0000
@@ -38,11 +38,15 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.concurrent.locks.LockSupport;
import java.util.function.BiConsumer;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
+import static java.util.concurrent.Flow.Publisher;
+import static java.util.concurrent.Flow.Subscriber;
+import static java.util.concurrent.Flow.Subscription;
/**
* A {@link Flow.Publisher} that asynchronously issues submitted
@@ -74,6 +78,14 @@
* Flow#defaultBufferSize()} may provide a useful starting point for
* choosing a capacity based on expected rates, resources, and usages.
*
+ * <p>A single SubmissionPublisher may be shared among multiple
+ * sources. Actions in a source thread prior to publishing an item or
+ * issuing a signal <a href="package-summary.html#MemoryVisibility">
+ * <i>happen-before</i></a> actions subsequent to the corresponding
+ * access by each subscriber. But reported estimates of lag and demand
+ * are designed for use in monitoring, not for synchronization
+ * control, and may reflect stale or inaccurate views of progress.
+ *
* <p>Publication methods support different policies about what to do
* when buffers are saturated. Method {@link #submit(Object) submit}
* blocks until resources are available. This is simplest, but least
@@ -158,19 +170,27 @@
* @author Doug Lea
* @since 9
*/
-public class SubmissionPublisher<T> implements Flow.Publisher<T>,
+public class SubmissionPublisher<T> implements Publisher<T>,
AutoCloseable {
/*
* Most mechanics are handled by BufferedSubscription. This class
* mainly tracks subscribers and ensures sequentiality, by using
- * built-in synchronization locks across public methods. (Using
+ * built-in synchronization locks across public methods. Using
* built-in locks works well in the most typical case in which
- * only one thread submits items).
+ * only one thread submits items. We extend this idea in
+ * submission methods by detecting single-ownership to reduce
+ * producer-consumer synchronization strength.
*/
/** The largest possible power of two array size. */
static final int BUFFER_CAPACITY_LIMIT = 1 << 30;
+ /**
+ * Initial buffer capacity used when maxBufferCapacity is
+ * greater. Must be a power of two.
+ */
+ static final int INITIAL_CAPACITY = 32;
+
/** Round capacity to power of 2, at most limit. */
static final int roundCapacity(int cap) {
int n = cap - 1;
@@ -206,7 +226,7 @@
* but we expect that subscribing is much less common than
* publishing. Unsubscribing occurs only during traversal loops,
* when BufferedSubscription methods return negative values
- * signifying that they have been disabled. To reduce
+ * signifying that they have been closed. To reduce
* head-of-line blocking, submit and offer methods first call
* BufferedSubscription.offer on each subscriber, and place
* saturated ones in retries list (using nextRetry field), and
@@ -216,12 +236,16 @@
/** Run status, updated only within locks */
volatile boolean closed;
+ /** Set true on first call to subscribe, to initialize possible owner */
+ boolean subscribed;
+ /** The first caller thread to subscribe, or null if thread ever changed */
+ Thread owner;
/** If non-null, the exception in closeExceptionally */
volatile Throwable closedException;
// Parameters for constructing BufferedSubscriptions
final Executor executor;
- final BiConsumer<? super Flow.Subscriber<? super T>, ? super Throwable> onNextHandler;
+ final BiConsumer<? super Subscriber<? super T>, ? super Throwable> onNextHandler;
final int maxBufferCapacity;
/**
@@ -245,7 +269,7 @@
* positive
*/
public SubmissionPublisher(Executor executor, int maxBufferCapacity,
- BiConsumer<? super Flow.Subscriber<? super T>, ? super Throwable> handler) {
+ BiConsumer<? super Subscriber<? super T>, ? super Throwable> handler) {
if (executor == null)
throw new NullPointerException();
if (maxBufferCapacity <= 0)
@@ -311,12 +335,19 @@
* @param subscriber the subscriber
* @throws NullPointerException if subscriber is null
*/
- public void subscribe(Flow.Subscriber<? super T> subscriber) {
+ public void subscribe(Subscriber<? super T> subscriber) {
if (subscriber == null) throw new NullPointerException();
+ int max = maxBufferCapacity; // allocate initial array
+ Object[] array = new Object[max < INITIAL_CAPACITY ?
+ max : INITIAL_CAPACITY];
BufferedSubscription<T> subscription =
- new BufferedSubscription<T>(subscriber, executor,
- onNextHandler, maxBufferCapacity);
+ new BufferedSubscription<T>(subscriber, executor, onNextHandler,
+ array, max);
synchronized (this) {
+ if (!subscribed) {
+ subscribed = true;
+ owner = Thread.currentThread();
+ }
for (BufferedSubscription<T> b = clients, pred = null;;) {
if (b == null) {
Throwable ex;
@@ -332,7 +363,7 @@
break;
}
BufferedSubscription<T> next = b.next;
- if (b.isDisabled()) { // remove
+ if (b.isClosed()) { // remove
b.next = null; // detach
if (pred == null)
clients = next;
@@ -351,6 +382,107 @@
}
/**
+ * Common implementation for all three forms of submit and offer.
+ * Acts as submit if nanos == Long.MAX_VALUE, else offer.
+ */
+ private int doOffer(T item, long nanos,
+ BiPredicate<Subscriber<? super T>, ? super T> onDrop) {
+ if (item == null) throw new NullPointerException();
+ int lag = 0;
+ boolean complete, unowned;
+ synchronized (this) {
+ Thread t = Thread.currentThread(), o;
+ BufferedSubscription<T> b = clients;
+ if ((unowned = ((o = owner) != t)) && o != null)
+ owner = null; // disable bias
+ if (b == null)
+ complete = closed;
+ else {
+ complete = false;
+ boolean cleanMe = false;
+ BufferedSubscription<T> retries = null, rtail = null, next;
+ do {
+ next = b.next;
+ int stat = b.offer(item, unowned);
+ if (stat == 0) { // saturated; add to retry list
+ b.nextRetry = null; // avoid garbage on exceptions
+ if (rtail == null)
+ retries = b;
+ else
+ rtail.nextRetry = b;
+ rtail = b;
+ }
+ else if (stat < 0) // closed
+ cleanMe = true; // remove later
+ else if (stat > lag)
+ lag = stat;
+ } while ((b = next) != null);
+
+ if (retries != null || cleanMe)
+ lag = retryOffer(item, nanos, onDrop, retries, lag, cleanMe);
+ }
+ }
+ if (complete)
+ throw new IllegalStateException("Closed");
+ else
+ return lag;
+ }
+
+ /**
+ * Helps, (timed) waits for, and/or drops buffers on list; returns
+ * lag or negative drops (for use in offer).
+ */
+ private int retryOffer(T item, long nanos,
+ BiPredicate<Subscriber<? super T>, ? super T> onDrop,
+ BufferedSubscription<T> retries, int lag,
+ boolean cleanMe) {
+ for (BufferedSubscription<T> r = retries; r != null;) {
+ BufferedSubscription<T> nextRetry = r.nextRetry;
+ r.nextRetry = null;
+ if (nanos > 0L)
+ r.awaitSpace(nanos);
+ int stat = r.retryOffer(item);
+ if (stat == 0 && onDrop != null && onDrop.test(r.subscriber, item))
+ stat = r.retryOffer(item);
+ if (stat == 0)
+ lag = (lag >= 0) ? -1 : lag - 1;
+ else if (stat < 0)
+ cleanMe = true;
+ else if (lag >= 0 && stat > lag)
+ lag = stat;
+ r = nextRetry;
+ }
+ if (cleanMe)
+ cleanAndCount();
+ return lag;
+ }
+
+ /**
+ * Returns current list count after removing closed subscribers.
+ * Call only while holding lock. Used mainly by retryOffer for
+ * cleanup.
+ */
+ private int cleanAndCount() {
+ int count = 0;
+ BufferedSubscription<T> pred = null, next;
+ for (BufferedSubscription<T> b = clients; b != null; b = next) {
+ next = b.next;
+ if (b.isClosed()) {
+ b.next = null;
+ if (pred == null)
+ clients = next;
+ else
+ pred.next = next;
+ }
+ else {
+ pred = b;
+ ++count;
+ }
+ }
+ return count;
+ }
+
+ /**
* Publishes the given item to each current subscriber by
* asynchronously invoking its {@link Flow.Subscriber#onNext(Object)
* onNext} method, blocking uninterruptibly while resources for any
@@ -373,55 +505,7 @@
* @throws RejectedExecutionException if thrown by Executor
*/
public int submit(T item) {
- if (item == null) throw new NullPointerException();
- int lag = 0;
- boolean complete;
- synchronized (this) {
- complete = closed;
- BufferedSubscription<T> b = clients;
- if (!complete) {
- BufferedSubscription<T> pred = null, r = null, rtail = null;
- while (b != null) {
- BufferedSubscription<T> next = b.next;
- int stat = b.offer(item);
- if (stat < 0) { // disabled
- b.next = null;
- if (pred == null)
- clients = next;
- else
- pred.next = next;
- }
- else {
- if (stat > lag)
- lag = stat;
- else if (stat == 0) { // place on retry list
- b.nextRetry = null;
- if (rtail == null)
- r = b;
- else
- rtail.nextRetry = b;
- rtail = b;
- }
- pred = b;
- }
- b = next;
- }
- while (r != null) {
- BufferedSubscription<T> nextRetry = r.nextRetry;
- r.nextRetry = null;
- int stat = r.submit(item);
- if (stat > lag)
- lag = stat;
- else if (stat < 0 && clients == r)
- clients = r.next; // postpone internal unsubscribes
- r = nextRetry;
- }
- }
- }
- if (complete)
- throw new IllegalStateException("Closed");
- else
- return lag;
+ return doOffer(item, Long.MAX_VALUE, null);
}
/**
@@ -462,8 +546,8 @@
* @throws RejectedExecutionException if thrown by Executor
*/
public int offer(T item,
- BiPredicate<Flow.Subscriber<? super T>, ? super T> onDrop) {
- return doOffer(0L, item, onDrop);
+ BiPredicate<Subscriber<? super T>, ? super T> onDrop) {
+ return doOffer(item, 0L, onDrop);
}
/**
@@ -510,71 +594,11 @@
* @throws RejectedExecutionException if thrown by Executor
*/
public int offer(T item, long timeout, TimeUnit unit,
- BiPredicate<Flow.Subscriber<? super T>, ? super T> onDrop) {
- return doOffer(unit.toNanos(timeout), item, onDrop);
- }
-
- /** Common implementation for both forms of offer */
- final int doOffer(long nanos, T item,
- BiPredicate<Flow.Subscriber<? super T>, ? super T> onDrop) {
- if (item == null) throw new NullPointerException();
- int lag = 0, drops = 0;
- boolean complete;
- synchronized (this) {
- complete = closed;
- BufferedSubscription<T> b = clients;
- if (!complete) {
- BufferedSubscription<T> pred = null, r = null, rtail = null;
- while (b != null) {
- BufferedSubscription<T> next = b.next;
- int stat = b.offer(item);
- if (stat < 0) {
- b.next = null;
- if (pred == null)
- clients = next;
- else
- pred.next = next;
- }
- else {
- if (stat > lag)
- lag = stat;
- else if (stat == 0) {
- b.nextRetry = null;
- if (rtail == null)
- r = b;
- else
- rtail.nextRetry = b;
- rtail = b;
- }
- else if (stat > lag)
- lag = stat;
- pred = b;
- }
- b = next;
- }
- while (r != null) {
- BufferedSubscription<T> nextRetry = r.nextRetry;
- r.nextRetry = null;
- int stat = (nanos > 0L)
- ? r.timedOffer(item, nanos)
- : r.offer(item);
- if (stat == 0 && onDrop != null &&
- onDrop.test(r.subscriber, item))
- stat = r.offer(item);
- if (stat == 0)
- ++drops;
- else if (stat > lag)
- lag = stat;
- else if (stat < 0 && clients == r)
- clients = r.next;
- r = nextRetry;
- }
- }
- }
- if (complete)
- throw new IllegalStateException("Closed");
- else
- return (drops > 0) ? -drops : lag;
+ BiPredicate<Subscriber<? super T>, ? super T> onDrop) {
+ long nanos = unit.toNanos(timeout);
+ // distinguishes from untimed (only wrt interrupt policy)
+ if (nanos == Long.MAX_VALUE) --nanos;
+ return doOffer(item, nanos, onDrop);
}
/**
@@ -591,6 +615,7 @@
// no need to re-check closed here
b = clients;
clients = null;
+ owner = null;
closed = true;
}
while (b != null) {
@@ -621,8 +646,9 @@
synchronized (this) {
b = clients;
if (!closed) { // don't clobber racing close
+ closedException = error;
clients = null;
- closedException = error;
+ owner = null;
closed = true;
}
}
@@ -662,18 +688,16 @@
*/
public boolean hasSubscribers() {
boolean nonEmpty = false;
- if (!closed) {
- synchronized (this) {
- for (BufferedSubscription<T> b = clients; b != null;) {
- BufferedSubscription<T> next = b.next;
- if (b.isDisabled()) {
- b.next = null;
- b = clients = next;
- }
- else {
- nonEmpty = true;
- break;
- }
+ synchronized (this) {
+ for (BufferedSubscription<T> b = clients; b != null;) {
+ BufferedSubscription<T> next = b.next;
+ if (b.isClosed()) {
+ b.next = null;
+ b = clients = next;
+ }
+ else {
+ nonEmpty = true;
+ break;
}
}
}
@@ -686,27 +710,9 @@
* @return the number of current subscribers
*/
public int getNumberOfSubscribers() {
- int count = 0;
- if (!closed) {
- synchronized (this) {
- BufferedSubscription<T> pred = null, next;
- for (BufferedSubscription<T> b = clients; b != null; b = next) {
- next = b.next;
- if (b.isDisabled()) {
- b.next = null;
- if (pred == null)
- clients = next;
- else
- pred.next = next;
- }
- else {
- pred = b;
- ++count;
- }
- }
- }
+ synchronized (this) {
+ return cleanAndCount();
}
- return count;
}
/**
@@ -734,13 +740,13 @@
*
* @return list of current subscribers
*/
- public List<Flow.Subscriber<? super T>> getSubscribers() {
- ArrayList<Flow.Subscriber<? super T>> subs = new ArrayList<>();
+ public List<Subscriber<? super T>> getSubscribers() {
+ ArrayList<Subscriber<? super T>> subs = new ArrayList<>();
synchronized (this) {
BufferedSubscription<T> pred = null, next;
for (BufferedSubscription<T> b = clients; b != null; b = next) {
next = b.next;
- if (b.isDisabled()) {
+ if (b.isClosed()) {
b.next = null;
if (pred == null)
clients = next;
@@ -761,14 +767,14 @@
* @return true if currently subscribed
* @throws NullPointerException if subscriber is null
*/
- public boolean isSubscribed(Flow.Subscriber<? super T> subscriber) {
+ public boolean isSubscribed(Subscriber<? super T> subscriber) {
if (subscriber == null) throw new NullPointerException();
if (!closed) {
synchronized (this) {
BufferedSubscription<T> pred = null, next;
for (BufferedSubscription<T> b = clients; b != null; b = next) {
next = b.next;
- if (b.isDisabled()) {
+ if (b.isClosed()) {
b.next = null;
if (pred == null)
clients = next;
@@ -872,16 +878,15 @@
}
/** Subscriber for method consume */
- private static final class ConsumerSubscriber<T>
- implements Flow.Subscriber<T> {
+ static final class ConsumerSubscriber<T> implements Subscriber<T> {
final CompletableFuture<Void> status;
final Consumer<? super T> consumer;
- Flow.Subscription subscription;
+ Subscription subscription;
ConsumerSubscriber(CompletableFuture<Void> status,
Consumer<? super T> consumer) {
this.status = status; this.consumer = consumer;
}
- public final void onSubscribe(Flow.Subscription subscription) {
+ public final void onSubscribe(Subscription subscription) {
this.subscription = subscription;
status.whenComplete((v, e) -> subscription.cancel());
if (!status.isDone())
@@ -925,634 +930,534 @@
}
/**
- * A bounded (ring) buffer with integrated control to start a
- * consumer task whenever items are available. The buffer
- * algorithm is similar to one used inside ForkJoinPool (see its
- * internal documentation for details) specialized for the case of
- * at most one concurrent producer and consumer, and power of two
- * buffer sizes. This allows methods to operate without locks even
- * while supporting resizing, blocking, task-triggering, and
- * garbage-free buffers (nulling out elements when consumed),
- * although supporting these does impose a bit of overhead
- * compared to plain fixed-size ring buffers.
- *
- * The publisher guarantees a single producer via its lock. We
- * ensure in this class that there is at most one consumer. The
- * request and cancel methods must be fully thread-safe but are
- * coded to exploit the most common case in which they are only
- * called by consumers (usually within onNext).
+ * A resizable array-based ring buffer with integrated control to
+ * start a consumer task whenever items are available. The buffer
+ * algorithm is specialized for the case of at most one concurrent
+ * producer and consumer, and power of two buffer sizes. It relies
+ * primarily on atomic operations (CAS or getAndSet) at the next
+ * array slot to put or take an element, at the "tail" and "head"
+ * indices written only by the producer and consumer respectively.
*
- * Execution control is managed using the ACTIVE ctl bit. We
- * ensure that a task is active when consumable items (and
- * usually, SUBSCRIBE, ERROR or COMPLETE signals) are present and
- * there is demand (unfilled requests). This is complicated on
- * the creation side by the possibility of exceptions when trying
- * to execute tasks. These eventually force DISABLED state, but
- * sometimes not directly. On the task side, termination (clearing
- * ACTIVE) that would otherwise race with producers or request()
- * calls uses the CONSUME keep-alive bit to force a recheck.
+ * We ensure internally that there is at most one active consumer
+ * task at any given time. The publisher guarantees a single
+ * producer via its lock. Sync among producers and consumers
+ * relies on volatile fields "ctl", "demand", and "waiting" (along
+ * with element access). Other variables are accessed in plain
+ * mode, relying on outer ordering and exclusion, and/or enclosing
+ * them within other volatile accesses. Some atomic operations are
+ * avoided by tracking single threaded ownership by producers (in
+ * the style of biased locking).
*
- * The ctl field also manages run state. When DISABLED, no further
- * updates are possible. Disabling may be preceded by setting
- * ERROR or COMPLETE (or both -- ERROR has precedence), in which
- * case the associated Subscriber methods are invoked, possibly
- * synchronously if there is no active consumer task (including
- * cases where execute() failed). The cancel() method is supported
- * by treating as ERROR but suppressing onError signal.
+ * Execution control and protocol state are managed using field
+ * "ctl". Methods to subscribe, close, request, and cancel set
+ * ctl bits (mostly using atomic boolean method getAndBitwiseOr),
+ * and ensure that a task is running. (The corresponding consumer
+ * side actions are in method consume.) To avoid starting a new
+ * task on each action, ctl also includes a keep-alive bit
+ * (ACTIVE) that is refreshed if needed on producer actions.
+ * (Maintaining agreement about keep-alives requires most atomic
+ * updates to be full SC/Volatile strength, which is still much
+ * cheaper than using one task per item.) Error signals
+ * additionally null out items and/or fields to reduce termination
+ * latency. The cancel() method is supported by treating as ERROR
+ * but suppressing onError signal.
*
* Support for blocking also exploits the fact that there is only
* one possible waiter. ManagedBlocker-compatible control fields
* are placed in this class itself rather than in wait-nodes.
- * Blocking control relies on the "waiter" field. Producers set
- * the field before trying to block, but must then recheck (via
- * offer) before parking. Signalling then just unparks and clears
- * waiter field. If the producer and/or consumer are using a
- * ForkJoinPool, the producer attempts to help run consumer tasks
- * via ForkJoinPool.helpAsyncBlocker before blocking.
+ * Blocking control relies on the "waiting" and "waiter"
+ * fields. Producers set them before trying to block. Signalling
+ * unparks and clears fields. If the producer and/or consumer are
+ * using a ForkJoinPool, the producer attempts to help run
+ * consumer tasks via ForkJoinPool.helpAsyncBlocker before
+ * blocking.
*
- * This class uses @Contended and heuristic field declaration
- * ordering to reduce false-sharing-based memory contention among
- * instances of BufferedSubscription, but it does not currently
- * attempt to avoid memory contention among buffers. This field
- * and element packing can hurt performance especially when each
- * publisher has only one client operating at a high rate.
- * Addressing this may require allocating substantially more space
- * than users expect.
+ * Usages of this class may encounter any of several forms of
+ * memory contention. We try to ameliorate across them without
+ * unduly impacting footprints in low-contention usages where it
+ * isn't needed. Buffer arrays start out small and grow only as
+ * needed. The class uses @Contended and heuristic field
+ * declaration ordering to reduce false-sharing memory contention
+ * across instances of BufferedSubscription (as in, multiple
+ * subscribers per publisher). We additionally segregate some
+ * fields that would otherwise nearly always encounter cache line
+ * contention among producers and consumers. To reduce contention
+ * across time (vs space), consumers only periodically update
+ * other fields (see method takeItems), at the expense of possibly
+ * staler reporting of lags and demand (bounded at 12.5% == 1/8
+ * capacity) and possibly more atomic operations.
+ *
+ * Other forms of imbalance and slowdowns can occur during startup
+ * when producer and consumer methods are compiled and/or memory
+ * is allocated at different rates. This is ameliorated by
+ * artificially subdividing some consumer methods, including
+ * isolation of all subscriber callbacks. This code also includes
+ * typical power-of-two array screening idioms to avoid compilers
+ * generating traps, along with the usual SSA-based inline
+ * assignment coding style. Also, all methods and fields have
+ * default visibility to simplify usage by callers.
*/
@SuppressWarnings("serial")
@jdk.internal.vm.annotation.Contended
- private static final class BufferedSubscription<T>
- implements Flow.Subscription, ForkJoinPool.ManagedBlocker {
- // Order-sensitive field declarations
- long timeout; // > 0 if timed wait
- volatile long demand; // # unfilled requests
- int maxCapacity; // reduced on OOME
- int putStat; // offer result for ManagedBlocker
+ static final class BufferedSubscription<T>
+ implements Subscription, ForkJoinPool.ManagedBlocker {
+ long timeout; // Long.MAX_VALUE if untimed wait
+ int head; // next position to take
+ int tail; // next position to put
+ final int maxCapacity; // max buffer size
volatile int ctl; // atomic run state flags
- volatile int head; // next position to take
- int tail; // next position to put
- Object[] array; // buffer: null if disabled
- Flow.Subscriber<? super T> subscriber; // null if disabled
- Executor executor; // null if disabled
- BiConsumer<? super Flow.Subscriber<? super T>, ? super Throwable> onNextHandler;
- volatile Throwable pendingError; // holds until onError issued
- volatile Thread waiter; // blocked producer thread
- T putItem; // for offer within ManagedBlocker
+ Object[] array; // buffer
+ final Subscriber<? super T> subscriber;
+ final BiConsumer<? super Subscriber<? super T>, ? super Throwable> onNextHandler;
+ Executor executor; // null on error
+ Thread waiter; // blocked producer thread
+ Throwable pendingError; // holds until onError issued
BufferedSubscription<T> next; // used only by publisher
BufferedSubscription<T> nextRetry; // used only by publisher
- // ctl values
- static final int ACTIVE = 0x01; // consumer task active
- static final int CONSUME = 0x02; // keep-alive for consumer task
- static final int DISABLED = 0x04; // final state
- static final int ERROR = 0x08; // signal onError then disable
- static final int SUBSCRIBE = 0x10; // signal onSubscribe
- static final int COMPLETE = 0x20; // signal onComplete when done
+ @jdk.internal.vm.annotation.Contended("c") // segregate
+ volatile long demand; // # unfilled requests
+ @jdk.internal.vm.annotation.Contended("c")
+ volatile int waiting; // nonzero if producer blocked
+
+ // ctl bit values
+ static final int CLOSED = 0x01; // if set, other bits ignored
+ static final int ACTIVE = 0x02; // keep-alive for consumer task
+ static final int REQS = 0x04; // (possibly) nonzero demand
+ static final int ERROR = 0x08; // issues onError when noticed
+ static final int COMPLETE = 0x10; // issues onComplete when done
+ static final int RUN = 0x20; // task is or will be running
+ static final int OPEN = 0x40; // true after subscribe
static final long INTERRUPTED = -1L; // timeout vs interrupt sentinel
- /**
- * Initial buffer capacity used when maxBufferCapacity is
- * greater. Must be a power of two.
- */
- static final int DEFAULT_INITIAL_CAP = 32;
-
- BufferedSubscription(Flow.Subscriber<? super T> subscriber,
+ BufferedSubscription(Subscriber<? super T> subscriber,
Executor executor,
- BiConsumer<? super Flow.Subscriber<? super T>,
+ BiConsumer<? super Subscriber<? super T>,
? super Throwable> onNextHandler,
+ Object[] array,
int maxBufferCapacity) {
this.subscriber = subscriber;
this.executor = executor;
this.onNextHandler = onNextHandler;
+ this.array = array;
this.maxCapacity = maxBufferCapacity;
- this.array = new Object[maxBufferCapacity < DEFAULT_INITIAL_CAP ?
- (maxBufferCapacity < 2 ? // at least 2 slots
- 2 : maxBufferCapacity) :
- DEFAULT_INITIAL_CAP];
+ }
+
+ // Wrappers for some VarHandle methods
+
+ final boolean weakCasCtl(int cmp, int val) {
+ return CTL.weakCompareAndSet(this, cmp, val);
}
- final boolean isDisabled() {
- return ctl == DISABLED;
+ final int getAndBitwiseOrCtl(int bits) {
+ return (int)CTL.getAndBitwiseOr(this, bits);
}
+ final long subtractDemand(int k) {
+ long n = (long)(-k);
+ return n + (long)DEMAND.getAndAdd(this, n);
+ }
+
+ final boolean casDemand(long cmp, long val) {
+ return DEMAND.compareAndSet(this, cmp, val);
+ }
+
+ // Utilities used by SubmissionPublisher
+
/**
- * Returns estimated number of buffered items, or -1 if
- * disabled.
- */
- final int estimateLag() {
- int n;
- return (ctl == DISABLED) ? -1 : ((n = tail - head) > 0) ? n : 0;
- }
-
- /**
- * Tries to add item and start consumer task if necessary.
- * @return -1 if disabled, 0 if dropped, else estimated lag
+ * Returns true if closed (consumer task may still be running).
*/
- final int offer(T item) {
- int h = head, t = tail, cap, size, stat;
- Object[] a = array;
- if (a != null && (cap = a.length) > 0 && cap >= (size = t + 1 - h)) {
- a[(cap - 1) & t] = item; // relaxed writes OK
- tail = t + 1;
- stat = size;
- }
- else
- stat = growAndAdd(a, item);
- return (stat > 0 &&
- (ctl & (ACTIVE | CONSUME)) != (ACTIVE | CONSUME)) ?
- startOnOffer(stat) : stat;
+ final boolean isClosed() {
+ return (ctl & CLOSED) != 0;
}
/**
- * Tries to create or expand buffer, then adds item if possible.
+ * Returns estimated number of buffered items, or negative if
+ * closed.
+ */
+ final int estimateLag() {
+ int c = ctl, n = tail - head;
+ return ((c & CLOSED) != 0) ? -1 : (n < 0) ? 0 : n;
+ }
+
+ // Methods for submitting items
+
+ /**
+ * Tries to add item and start consumer task if necessary.
+ * @return negative if closed, 0 if saturated, else estimated lag
*/
- private int growAndAdd(Object[] a, T item) {
- boolean alloc;
- int cap, stat;
- if ((ctl & (ERROR | DISABLED)) != 0) {
- cap = 0;
- stat = -1;
- alloc = false;
- }
- else if (a == null || (cap = a.length) <= 0) {
- cap = 0;
- stat = 1;
- alloc = true;
- }
- else {
- VarHandle.fullFence(); // recheck
- int h = head, t = tail, size = t + 1 - h;
- if (cap >= size) {
- a[(cap - 1) & t] = item;
+ final int offer(T item, boolean unowned) {
+ Object[] a;
+ int stat = 0, cap = ((a = array) == null) ? 0 : a.length;
+ int t = tail, i = t & (cap - 1), n = t + 1 - head;
+ if (cap > 0) {
+ boolean added;
+ if (n >= cap && cap < maxCapacity) // resize
+ added = growAndoffer(item, a, t);
+ else if (n >= cap || unowned) // need volatile CAS
+ added = QA.compareAndSet(a, i, null, item);
+ else { // can use release mode
+ QA.setRelease(a, i, item);
+ added = true;
+ }
+ if (added) {
tail = t + 1;
- stat = size;
- alloc = false;
- }
- else if (cap >= maxCapacity) {
- stat = 0; // cannot grow
- alloc = false;
- }
- else {
- stat = cap + 1;
- alloc = true;
+ stat = n;
}
}
- if (alloc) {
- int newCap = (cap > 0) ? cap << 1 : 1;
- if (newCap <= cap)
- stat = 0;
- else {
- Object[] newArray = null;
- try {
- newArray = new Object[newCap];
- } catch (Throwable ex) { // try to cope with OOME
- }
- if (newArray == null) {
- if (cap > 0)
- maxCapacity = cap; // avoid continuous failure
- stat = 0;
- }
- else {
- array = newArray;
- int t = tail;
- int newMask = newCap - 1;
- if (a != null && cap > 0) {
- int mask = cap - 1;
- for (int j = head; j != t; ++j) {
- int k = j & mask;
- Object x = QA.getAcquire(a, k);
- if (x != null && // races with consumer
- QA.compareAndSet(a, k, x, null))
- newArray[j & newMask] = x;
- }
- }
- newArray[t & newMask] = item;
- tail = t + 1;
- }
+ return startOnOffer(stat);
+ }
+
+ /**
+ * Tries to expand buffer and add item, returning true on
+ * success. Currently fails only if out of memory.
+ */
+ final boolean growAndoffer(T item, Object[] a, int t) {
+ int cap = 0, newCap = 0;
+ Object[] newArray = null;
+ if (a != null && (cap = a.length) > 0 && (newCap = cap << 1) > 0) {
+ try {
+ newArray = new Object[newCap];
+ } catch (OutOfMemoryError ex) {
}
}
+ if (newArray == null)
+ return false;
+ else { // take and move items
+ int newMask = newCap - 1;
+ newArray[t-- & newMask] = item;
+ for (int mask = cap - 1, k = mask; k >= 0; --k) {
+ Object x = QA.getAndSet(a, t & mask, null);
+ if (x == null)
+ break; // already consumed
+ else
+ newArray[t-- & newMask] = x;
+ }
+ array = newArray;
+ VarHandle.releaseFence(); // release array and slots
+ return true;
+ }
+ }
+
+ /**
+ * Version of offer for retries (no resize or bias)
+ */
+ final int retryOffer(T item) {
+ Object[] a;
+ int stat = 0, t = tail, h = head, cap;
+ if ((a = array) != null && (cap = a.length) > 0 &&
+ QA.compareAndSet(a, (cap - 1) & t, null, item))
+ stat = (tail = t + 1) - h;
+ return startOnOffer(stat);
+ }
+
+ /**
+ * Tries to start consumer task after offer.
+ * @return negative if now closed, else argument
+ */
+ final int startOnOffer(int stat) {
+ int c; // start or keep alive if requests exist and not active
+ if (((c = ctl) & (REQS | ACTIVE)) == REQS &&
+ ((c = getAndBitwiseOrCtl(RUN | ACTIVE)) & (RUN | CLOSED)) == 0)
+ tryStart();
+ else if ((c & CLOSED) != 0)
+ stat = -1;
return stat;
}
/**
- * Spins/helps/blocks while offer returns 0. Called only if
- * initial offer return 0.
- */
- final int submit(T item) {
- int stat;
- if ((stat = offer(item)) == 0) {
- putItem = item;
- timeout = 0L;
- putStat = 0;
- ForkJoinPool.helpAsyncBlocker(executor, this);
- if ((stat = putStat) == 0) {
- try {
- ForkJoinPool.managedBlock(this);
- } catch (InterruptedException ie) {
- timeout = INTERRUPTED;
- }
- stat = putStat;
- }
- if (timeout < 0L)
- Thread.currentThread().interrupt();
- }
- return stat;
- }
-
- /**
- * Timeout version; similar to submit.
- */
- final int timedOffer(T item, long nanos) {
- int stat;
- if ((stat = offer(item)) == 0 && (timeout = nanos) > 0L) {
- putItem = item;
- putStat = 0;
- ForkJoinPool.helpAsyncBlocker(executor, this);
- if ((stat = putStat) == 0) {
- try {
- ForkJoinPool.managedBlock(this);
- } catch (InterruptedException ie) {
- timeout = INTERRUPTED;
- }
- stat = putStat;
- }
- if (timeout < 0L)
- Thread.currentThread().interrupt();
- }
- return stat;
- }
-
- /**
- * Tries to start consumer task after offer.
- * @return -1 if now disabled, else argument
+ * Tries to start consumer task. Sets error state on failure.
*/
- private int startOnOffer(int stat) {
- for (;;) {
- Executor e; int c;
- if ((c = ctl) == DISABLED || (e = executor) == null) {
- stat = -1;
- break;
- }
- else if ((c & ACTIVE) != 0) { // ensure keep-alive
- if ((c & CONSUME) != 0 ||
- CTL.compareAndSet(this, c, c | CONSUME))
- break;
- }
- else if (demand == 0L || tail == head)
- break;
- else if (CTL.compareAndSet(this, c, c | (ACTIVE | CONSUME))) {
- try {
- e.execute(new ConsumerTask<T>(this));
- break;
- } catch (RuntimeException | Error ex) { // back out
- do {} while (((c = ctl) & DISABLED) == 0 &&
- (c & ACTIVE) != 0 &&
- !CTL.weakCompareAndSet
- (this, c, c & ~ACTIVE));
- throw ex;
- }
- }
- }
- return stat;
- }
-
- private void signalWaiter(Thread w) {
- waiter = null;
- LockSupport.unpark(w); // release producer
- }
-
- /**
- * Nulls out most fields, mainly to avoid garbage retention
- * until publisher unsubscribes, but also to help cleanly stop
- * upon error by nulling required components.
- */
- private void detach() {
- Thread w = waiter;
- executor = null;
- subscriber = null;
- pendingError = null;
- signalWaiter(w);
- }
-
- /**
- * Issues error signal, asynchronously if a task is running,
- * else synchronously.
- */
- final void onError(Throwable ex) {
- for (int c;;) {
- if (((c = ctl) & (ERROR | DISABLED)) != 0)
- break;
- else if ((c & ACTIVE) != 0) {
- pendingError = ex;
- if (CTL.compareAndSet(this, c, c | ERROR))
- break; // cause consumer task to exit
- }
- else if (CTL.compareAndSet(this, c, DISABLED)) {
- Flow.Subscriber<? super T> s = subscriber;
- if (s != null && ex != null) {
- try {
- s.onError(ex);
- } catch (Throwable ignore) {
- }
- }
- detach();
- break;
- }
+ final void tryStart() {
+ try {
+ Executor e;
+ ConsumerTask<T> task = new ConsumerTask<T>(this);
+ if ((e = executor) != null) // skip if disabled on error
+ e.execute(task);
+ } catch (RuntimeException | Error ex) {
+ getAndBitwiseOrCtl(ERROR | CLOSED);
+ throw ex;
}
}
+ // Signals to consumer tasks
+
/**
- * Tries to start consumer task upon a signal or request;
- * disables on failure.
+ * Sets the given control bits, starting task if not running or closed.
+ * @param bits state bits, assumed to include RUN but not CLOSED
*/
- private void startOrDisable() {
- Executor e;
- if ((e = executor) != null) { // skip if already disabled
- try {
- e.execute(new ConsumerTask<T>(this));
- } catch (Throwable ex) { // back out and force signal
- for (int c;;) {
- if ((c = ctl) == DISABLED || (c & ACTIVE) == 0)
- break;
- if (CTL.compareAndSet(this, c, c & ~ACTIVE)) {
- onError(ex);
- break;
- }
- }
- }
- }
+ final void startOnSignal(int bits) {
+ if ((ctl & bits) != bits &&
+ (getAndBitwiseOrCtl(bits) & (RUN | CLOSED)) == 0)
+ tryStart();
+ }
+
+ final void onSubscribe() {
+ startOnSignal(RUN | ACTIVE);
}
final void onComplete() {
- for (int c;;) {
- if ((c = ctl) == DISABLED)
- break;
- if (CTL.compareAndSet(this, c,
- c | (ACTIVE | CONSUME | COMPLETE))) {
- if ((c & ACTIVE) == 0)
- startOrDisable();
- break;
- }
- }
+ startOnSignal(RUN | ACTIVE | COMPLETE);
}
- final void onSubscribe() {
- for (int c;;) {
- if ((c = ctl) == DISABLED)
- break;
- if (CTL.compareAndSet(this, c,
- c | (ACTIVE | CONSUME | SUBSCRIBE))) {
- if ((c & ACTIVE) == 0)
- startOrDisable();
- break;
- }
+ final void onError(Throwable ex) {
+ int c; Object[] a; // to null out buffer on async error
+ if (ex != null)
+ pendingError = ex; // races are OK
+ if (((c = getAndBitwiseOrCtl(ERROR | RUN | ACTIVE)) & CLOSED) == 0) {
+ if ((c & RUN) == 0)
+ tryStart();
+ else if ((a = array) != null)
+ Arrays.fill(a, null);
}
}
- /**
- * Causes consumer task to exit if active (without reporting
- * onError unless there is already a pending error), and
- * disables.
- */
- public void cancel() {
- for (int c;;) {
- if ((c = ctl) == DISABLED)
- break;
- else if ((c & ACTIVE) != 0) {
- if (CTL.compareAndSet(this, c,
- c | (CONSUME | ERROR)))
- break;
- }
- else if (CTL.compareAndSet(this, c, DISABLED)) {
- detach();
- break;
- }
- }
+ public final void cancel() {
+ onError(null);
}
- /**
- * Adds to demand and possibly starts task.
- */
- public void request(long n) {
+ public final void request(long n) {
if (n > 0L) {
for (;;) {
- long prev = demand, d;
- if ((d = prev + n) < prev) // saturate
- d = Long.MAX_VALUE;
- if (DEMAND.compareAndSet(this, prev, d)) {
- for (int c, h;;) {
- if ((c = ctl) == DISABLED)
- break;
- else if ((c & ACTIVE) != 0) {
- if ((c & CONSUME) != 0 ||
- CTL.compareAndSet(this, c, c | CONSUME))
- break;
- }
- else if ((h = head) != tail) {
- if (CTL.compareAndSet(this, c,
- c | (ACTIVE|CONSUME))) {
- startOrDisable();
- break;
- }
- }
- else if (head == h && tail == h)
- break; // else stale
- if (demand == 0L)
- break;
- }
+ long p = demand, d = p + n; // saturate
+ if (casDemand(p, d < p ? Long.MAX_VALUE : d))
break;
- }
}
+ startOnSignal(RUN | ACTIVE | REQS);
}
else
onError(new IllegalArgumentException(
"non-positive subscription request"));
}
- public final boolean isReleasable() { // for ManagedBlocker
- T item = putItem;
- if (item != null) {
- if ((putStat = offer(item)) == 0)
- return false;
- putItem = null;
- }
- return true;
- }
-
- public final boolean block() { // for ManagedBlocker
- T item = putItem;
- if (item != null) {
- putItem = null;
- long nanos = timeout;
- long deadline = (nanos > 0L) ? System.nanoTime() + nanos : 0L;
- while ((putStat = offer(item)) == 0) {
- if (Thread.interrupted()) {
- timeout = INTERRUPTED;
- if (nanos > 0L)
- break;
- }
- else if (nanos > 0L &&
- (nanos = deadline - System.nanoTime()) <= 0L)
- break;
- else if (waiter == null)
- waiter = Thread.currentThread();
- else {
- if (nanos > 0L)
- LockSupport.parkNanos(this, nanos);
- else
- LockSupport.park(this);
- waiter = null;
- }
- }
- }
- waiter = null;
- return true;
- }
+ // Consumer task actions
/**
- * Consumer loop, called from ConsumerTask, or indirectly
- * when helping during submit.
+ * Consumer loop, called from ConsumerTask, or indirectly when
+ * helping during submit.
*/
final void consume() {
- Flow.Subscriber<? super T> s;
- int h = head;
- if ((s = subscriber) != null) { // else disabled
- for (;;) {
- long d = demand;
- int c; Object[] a; int n, i; Object x; Thread w;
- if (((c = ctl) & (ERROR | SUBSCRIBE | DISABLED)) != 0) {
- if (!checkControl(s, c))
- break;
- }
- else if ((a = array) == null || h == tail ||
- (n = a.length) == 0 ||
- (x = QA.getAcquire(a, i = (n - 1) & h)) == null) {
- if (!checkEmpty(s, c))
- break;
+ Subscriber<? super T> s;
+ if ((s = subscriber) != null) { // hoist checks
+ subscribeOnOpen(s);
+ long d = demand;
+ for (int h = head, t = tail;;) {
+ int c, taken; boolean empty;
+ if (((c = ctl) & ERROR) != 0) {
+ closeOnError(s, null);
+ break;
}
- else if (d == 0L) {
- if (!checkDemand(c))
- break;
+ else if ((taken = takeItems(s, d, h)) > 0) {
+ head = h += taken;
+ d = subtractDemand(taken);
+ }
+ else if ((empty = (t == h)) && (c & COMPLETE) != 0) {
+ closeOnComplete(s); // end of stream
+ break;
}
- else if (((c & CONSUME) != 0 ||
- CTL.compareAndSet(this, c, c | CONSUME)) &&
- QA.compareAndSet(a, i, x, null)) {
- HEAD.setRelease(this, ++h);
- DEMAND.getAndAdd(this, -1L);
- if ((w = waiter) != null)
- signalWaiter(w);
- try {
- @SuppressWarnings("unchecked") T y = (T) x;
- s.onNext(y);
- } catch (Throwable ex) {
- handleOnNext(s, ex);
- }
+ else if ((d = demand) == 0L && (c & REQS) != 0)
+ weakCasCtl(c, c & ~REQS); // exhausted demand
+ else if (d != 0L && (c & REQS) == 0)
+ weakCasCtl(c, c | REQS); // new demand
+ else if (t == (t = tail) && (empty || d == 0L)) {
+ int bit = ((c & ACTIVE) != 0) ? ACTIVE : RUN;
+ if (weakCasCtl(c, c & ~bit) && bit == RUN)
+ break; // un-keep-alive or exit
}
}
}
}
/**
- * Responds to control events in consume().
+ * Consumes some items until unavailable or bound or error.
+ *
+ * @param s subscriber
+ * @param d current demand
+ * @param h current head
+ * @return number taken
*/
- private boolean checkControl(Flow.Subscriber<? super T> s, int c) {
- boolean stat = true;
- if ((c & SUBSCRIBE) != 0) {
- if (CTL.compareAndSet(this, c, c & ~SUBSCRIBE)) {
- try {
- if (s != null)
- s.onSubscribe(this);
- } catch (Throwable ex) {
- onError(ex);
- }
+ final int takeItems(Subscriber<? super T> s, long d, int h) {
+ Object[] a;
+ int k = 0, cap;
+ if ((a = array) != null && (cap = a.length) > 0) {
+ int m = cap - 1, b = (m >>> 3) + 1; // min(1, cap/8)
+ int n = (d < (long)b) ? (int)d : b;
+ for (; k < n; ++h, ++k) {
+ Object x = QA.getAndSet(a, h & m, null);
+ if (waiting != 0)
+ signalWaiter();
+ if (x == null)
+ break;
+ else if (!consumeNext(s, x))
+ break;
}
}
- else if ((c & ERROR) != 0) {
- Throwable ex = pendingError;
- ctl = DISABLED; // no need for CAS
- if (ex != null) { // null if errorless cancel
- try {
- if (s != null)
- s.onError(ex);
- } catch (Throwable ignore) {
- }
- }
- }
- else {
- detach();
- stat = false;
- }
- return stat;
+ return k;
}
- /**
- * Responds to apparent emptiness in consume().
- */
- private boolean checkEmpty(Flow.Subscriber<? super T> s, int c) {
- boolean stat = true;
- if (head == tail) {
- if ((c & CONSUME) != 0)
- CTL.compareAndSet(this, c, c & ~CONSUME);
- else if ((c & COMPLETE) != 0) {
- if (CTL.compareAndSet(this, c, DISABLED)) {
- try {
- if (s != null)
- s.onComplete();
- } catch (Throwable ignore) {
- }
- }
- }
- else if (CTL.compareAndSet(this, c, c & ~ACTIVE))
- stat = false;
+ final boolean consumeNext(Subscriber<? super T> s, Object x) {
+ try {
+ @SuppressWarnings("unchecked") T y = (T) x;
+ if (s != null)
+ s.onNext(y);
+ return true;
+ } catch (Throwable ex) {
+ handleOnNext(s, ex);
+ return false;
}
- return stat;
- }
-
- /**
- * Responds to apparent zero demand in consume().
- */
- private boolean checkDemand(int c) {
- boolean stat = true;
- if (demand == 0L) {
- if ((c & CONSUME) != 0)
- CTL.compareAndSet(this, c, c & ~CONSUME);
- else if (CTL.compareAndSet(this, c, c & ~ACTIVE))
- stat = false;
- }
- return stat;
}
/**
* Processes exception in Subscriber.onNext.
*/
- private void handleOnNext(Flow.Subscriber<? super T> s, Throwable ex) {
- BiConsumer<? super Flow.Subscriber<? super T>, ? super Throwable> h;
- if ((h = onNextHandler) != null) {
- try {
+ final void handleOnNext(Subscriber<? super T> s, Throwable ex) {
+ BiConsumer<? super Subscriber<? super T>, ? super Throwable> h;
+ try {
+ if ((h = onNextHandler) != null)
h.accept(s, ex);
- } catch (Throwable ignore) {
+ } catch (Throwable ignore) {
+ }
+ closeOnError(s, ex);
+ }
+
+ /**
+ * Issues subscriber.onSubscribe if this is first signal.
+ */
+ final void subscribeOnOpen(Subscriber<? super T> s) {
+ if ((ctl & OPEN) == 0 && (getAndBitwiseOrCtl(OPEN) & OPEN) == 0)
+ consumeSubscribe(s);
+ }
+
+ final void consumeSubscribe(Subscriber<? super T> s) {
+ try {
+ if (s != null) // ignore if disabled
+ s.onSubscribe(this);
+ } catch (Throwable ex) {
+ closeOnError(s, ex);
+ }
+ }
+
+ /**
+ * Issues subscriber.onComplete unless already closed.
+ */
+ final void closeOnComplete(Subscriber<? super T> s) {
+ if ((getAndBitwiseOrCtl(CLOSED) & CLOSED) == 0)
+ consumeComplete(s);
+ }
+
+ final void consumeComplete(Subscriber<? super T> s) {
+ try {
+ if (s != null)
+ s.onComplete();
+ } catch (Throwable ignore) {
+ }
+ }
+
+ /**
+ * Issues subscriber.onError, and unblocks producer if needed.
+ */
+ final void closeOnError(Subscriber<? super T> s, Throwable ex) {
+ if ((getAndBitwiseOrCtl(ERROR | CLOSED) & CLOSED) == 0) {
+ if (ex == null)
+ ex = pendingError;
+ pendingError = null; // detach
+ executor = null; // suppress racing start calls
+ signalWaiter();
+ consumeError(s, ex);
+ }
+ }
+
+ final void consumeError(Subscriber<? super T> s, Throwable ex) {
+ try {
+ if (ex != null && s != null)
+ s.onError(ex);
+ } catch (Throwable ignore) {
+ }
+ }
+
+ // Blocking support
+
+ /**
+ * Unblocks waiting producer.
+ */
+ final void signalWaiter() {
+ Thread w;
+ waiting = 0;
+ if ((w = waiter) != null)
+ LockSupport.unpark(w);
+ }
+
+ /**
+ * Returns true if closed or space available.
+ * For ManagedBlocker.
+ */
+ public final boolean isReleasable() {
+ Object[] a; int cap;
+ return ((ctl & CLOSED) != 0 ||
+ ((a = array) != null && (cap = a.length) > 0 &&
+ QA.getAcquire(a, (cap - 1) & tail) == null));
+ }
+
+ /**
+ * Helps or blocks until timeout, closed, or space available.
+ */
+ final void awaitSpace(long nanos) {
+ if (!isReleasable()) {
+ ForkJoinPool.helpAsyncBlocker(executor, this);
+ if (!isReleasable()) {
+ timeout = nanos;
+ try {
+ ForkJoinPool.managedBlock(this);
+ } catch (InterruptedException ie) {
+ timeout = INTERRUPTED;
+ }
+ if (timeout == INTERRUPTED)
+ Thread.currentThread().interrupt();
}
}
- onError(ex);
+ }
+
+ /**
+ * Blocks until closed, space available or timeout.
+ * For ManagedBlocker.
+ */
+ public final boolean block() {
+ long nanos = timeout;
+ boolean timed = (nanos < Long.MAX_VALUE);
+ long deadline = timed ? System.nanoTime() + nanos : 0L;
+ while (!isReleasable()) {
+ if (Thread.interrupted()) {
+ timeout = INTERRUPTED;
+ if (timed)
+ break;
+ }
+ else if (timed && (nanos = deadline - System.nanoTime()) <= 0L)
+ break;
+ else if (waiter == null)
+ waiter = Thread.currentThread();
+ else if (waiting == 0)
+ waiting = 1;
+ else if (timed)
+ LockSupport.parkNanos(this, nanos);
+ else
+ LockSupport.park(this);
+ }
+ waiter = null;
+ waiting = 0;
+ return true;
}
// VarHandle mechanics
- private static final VarHandle CTL;
- private static final VarHandle TAIL;
- private static final VarHandle HEAD;
- private static final VarHandle DEMAND;
- private static final VarHandle QA;
+ static final VarHandle CTL;
+ static final VarHandle DEMAND;
+ static final VarHandle QA;
static {
try {
MethodHandles.Lookup l = MethodHandles.lookup();
CTL = l.findVarHandle(BufferedSubscription.class, "ctl",
int.class);
- TAIL = l.findVarHandle(BufferedSubscription.class, "tail",
- int.class);
- HEAD = l.findVarHandle(BufferedSubscription.class, "head",
- int.class);
DEMAND = l.findVarHandle(BufferedSubscription.class, "demand",
long.class);
QA = MethodHandles.arrayElementVarHandle(Object[].class);
--- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Tue Dec 05 10:28:45 2017 +0000
@@ -422,8 +422,8 @@
* @return {@code true} if interrupted while waiting
*/
final boolean acquireQueued(final Node node, long arg) {
+ boolean interrupted = false;
try {
- boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
@@ -431,12 +431,13 @@
p.next = null; // help GC
return interrupted;
}
- if (shouldParkAfterFailedAcquire(p, node) &&
- parkAndCheckInterrupt())
- interrupted = true;
+ if (shouldParkAfterFailedAcquire(p, node))
+ interrupted |= parkAndCheckInterrupt();
}
} catch (Throwable t) {
cancelAcquire(node);
+ if (interrupted)
+ selfInterrupt();
throw t;
}
}
@@ -510,8 +511,8 @@
*/
private void doAcquireShared(long arg) {
final Node node = addWaiter(Node.SHARED);
+ boolean interrupted = false;
try {
- boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head) {
@@ -519,18 +520,18 @@
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // help GC
- if (interrupted)
- selfInterrupt();
return;
}
}
- if (shouldParkAfterFailedAcquire(p, node) &&
- parkAndCheckInterrupt())
- interrupted = true;
+ if (shouldParkAfterFailedAcquire(p, node))
+ interrupted |= parkAndCheckInterrupt();
}
} catch (Throwable t) {
cancelAcquire(node);
throw t;
+ } finally {
+ if (interrupted)
+ selfInterrupt();
}
}
--- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Tue Dec 05 10:28:45 2017 +0000
@@ -505,7 +505,7 @@
*
* @return the predecessor of this node
*/
- final Node predecessor() throws NullPointerException {
+ final Node predecessor() {
Node p = prev;
if (p == null)
throw new NullPointerException();
@@ -902,8 +902,8 @@
* @return {@code true} if interrupted while waiting
*/
final boolean acquireQueued(final Node node, int arg) {
+ boolean interrupted = false;
try {
- boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
@@ -911,12 +911,13 @@
p.next = null; // help GC
return interrupted;
}
- if (shouldParkAfterFailedAcquire(p, node) &&
- parkAndCheckInterrupt())
- interrupted = true;
+ if (shouldParkAfterFailedAcquire(p, node))
+ interrupted |= parkAndCheckInterrupt();
}
} catch (Throwable t) {
cancelAcquire(node);
+ if (interrupted)
+ selfInterrupt();
throw t;
}
}
@@ -990,8 +991,8 @@
*/
private void doAcquireShared(int arg) {
final Node node = addWaiter(Node.SHARED);
+ boolean interrupted = false;
try {
- boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head) {
@@ -999,18 +1000,18 @@
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // help GC
- if (interrupted)
- selfInterrupt();
return;
}
}
- if (shouldParkAfterFailedAcquire(p, node) &&
- parkAndCheckInterrupt())
- interrupted = true;
+ if (shouldParkAfterFailedAcquire(p, node))
+ interrupted |= parkAndCheckInterrupt();
}
} catch (Throwable t) {
cancelAcquire(node);
throw t;
+ } finally {
+ if (interrupted)
+ selfInterrupt();
}
}
--- a/src/java.base/share/classes/java/util/stream/Collectors.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/java/util/stream/Collectors.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -116,6 +116,8 @@
= Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED,
Collector.Characteristics.IDENTITY_FINISH));
static final Set<Collector.Characteristics> CH_NOID = Collections.emptySet();
+ static final Set<Collector.Characteristics> CH_UNORDERED_NOID
+ = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED));
private Collectors() { }
@@ -279,6 +281,26 @@
}
/**
+ * Returns a {@code Collector} that accumulates the input elements into an
+ * <a href="../List.html#unmodifiable">unmodifiable List</a> in encounter
+ * order. The returned Collector disallows null values and will throw
+ * {@code NullPointerException} if it is presented with a null value.
+ *
+ * @param <T> the type of the input elements
+ * @return a {@code Collector} that accumulates the input elements into an
+ * <a href="../List.html#unmodifiable">unmodifiable List</a> in encounter order
+ * @since 10
+ */
+ @SuppressWarnings("unchecked")
+ public static <T>
+ Collector<T, ?, List<T>> toUnmodifiableList() {
+ return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
+ (left, right) -> { left.addAll(right); return left; },
+ list -> (List<T>)List.of(list.toArray()),
+ CH_NOID);
+ }
+
+ /**
* Returns a {@code Collector} that accumulates the input elements into a
* new {@code Set}. There are no guarantees on the type, mutability,
* serializability, or thread-safety of the {@code Set} returned; if more
@@ -306,6 +328,36 @@
}
/**
+ * Returns a {@code Collector} that accumulates the input elements into an
+ * <a href="../Set.html#unmodifiable">unmodifiable Set</a>. The returned
+ * Collector disallows null values and will throw {@code NullPointerException}
+ * if it is presented with a null value. If the input contains duplicate elements,
+ * an arbitrary element of the duplicates is preserved.
+ *
+ * <p>This is an {@link Collector.Characteristics#UNORDERED unordered}
+ * Collector.
+ *
+ * @param <T> the type of the input elements
+ * @return a {@code Collector} that accumulates the input elements into an
+ * <a href="../Set.html#unmodifiable">unmodifiable Set</a>
+ * @since 10
+ */
+ @SuppressWarnings("unchecked")
+ public static <T>
+ Collector<T, ?, Set<T>> toUnmodifiableSet() {
+ return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
+ (left, right) -> {
+ if (left.size() < right.size()) {
+ right.addAll(left); return right;
+ } else {
+ left.addAll(right); return left;
+ }
+ },
+ set -> (Set<T>)Set.of(set.toArray()),
+ CH_UNORDERED_NOID);
+ }
+
+ /**
* Returns a {@code Collector} that concatenates the input elements into a
* {@code String}, in encounter order.
*
@@ -1353,7 +1405,7 @@
* <p>If the mapped keys contain duplicates (according to
* {@link Object#equals(Object)}), an {@code IllegalStateException} is
* thrown when the collection operation is performed. If the mapped keys
- * may have duplicates, use {@link #toMap(Function, Function, BinaryOperator)}
+ * might have duplicates, use {@link #toMap(Function, Function, BinaryOperator)}
* instead.
*
* <p>There are no guarantees on the type, mutability, serializability,
@@ -1411,6 +1463,45 @@
}
/**
+ * Returns a {@code Collector} that accumulates the input elements into an
+ * <a href="../Map.html#unmodifiable">unmodifiable Map</a>,
+ * whose keys and values are the result of applying the provided
+ * mapping functions to the input elements.
+ *
+ * <p>If the mapped keys contain duplicates (according to
+ * {@link Object#equals(Object)}), an {@code IllegalStateException} is
+ * thrown when the collection operation is performed. If the mapped keys
+ * might have duplicates, use {@link #toUnmodifiableMap(Function, Function, BinaryOperator)}
+ * to handle merging of the values.
+ *
+ * <p>The returned Collector disallows null keys and values. If either mapping function
+ * returns null, {@code NullPointerException} will be thrown.
+ *
+ * @param <T> the type of the input elements
+ * @param <K> the output type of the key mapping function
+ * @param <U> the output type of the value mapping function
+ * @param keyMapper a mapping function to produce keys, must be non-null
+ * @param valueMapper a mapping function to produce values, must be non-null
+ * @return a {@code Collector} that accumulates the input elements into an
+ * <a href="../Map.html#unmodifiable">unmodifiable Map</a>, whose keys and values
+ * are the result of applying the provided mapping functions to the input elements
+ * @throws NullPointerException if either keyMapper or valueMapper is null
+ *
+ * @see #toUnmodifiableMap(Function, Function, BinaryOperator)
+ * @since 10
+ */
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public static <T, K, U>
+ Collector<T, ?, Map<K,U>> toUnmodifiableMap(Function<? super T, ? extends K> keyMapper,
+ Function<? super T, ? extends U> valueMapper) {
+ Objects.requireNonNull(keyMapper, "keyMapper");
+ Objects.requireNonNull(valueMapper, "valueMapper");
+ return collectingAndThen(
+ toMap(keyMapper, valueMapper),
+ map -> (Map<K,U>)Map.ofEntries(map.entrySet().toArray(new Map.Entry[0])));
+ }
+
+ /**
* Returns a {@code Collector} that accumulates elements into a
* {@code Map} whose keys and values are the result of applying the provided
* mapping functions to the input elements.
@@ -1473,6 +1564,51 @@
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}
+
+ /**
+ * Returns a {@code Collector} that accumulates the input elements into an
+ * <a href="../Map.html#unmodifiable">unmodifiable Map</a>,
+ * whose keys and values are the result of applying the provided
+ * mapping functions to the input elements.
+ *
+ * <p>If the mapped
+ * keys contain duplicates (according to {@link Object#equals(Object)}),
+ * the value mapping function is applied to each equal element, and the
+ * results are merged using the provided merging function.
+ *
+ * <p>The returned Collector disallows null keys and values. If either mapping function
+ * returns null, {@code NullPointerException} will be thrown.
+ *
+ * @param <T> the type of the input elements
+ * @param <K> the output type of the key mapping function
+ * @param <U> the output type of the value mapping function
+ * @param keyMapper a mapping function to produce keys, must be non-null
+ * @param valueMapper a mapping function to produce values, must be non-null
+ * @param mergeFunction a merge function, used to resolve collisions between
+ * values associated with the same key, as supplied
+ * to {@link Map#merge(Object, Object, BiFunction)},
+ * must be non-null
+ * @return a {@code Collector} that accumulates the input elements into an
+ * <a href="../Map.html#unmodifiable">unmodifiable Map</a>, whose keys and values
+ * are the result of applying the provided mapping functions to the input elements
+ * @throws NullPointerException if the keyMapper, valueMapper, or mergeFunction is null
+ *
+ * @see #toUnmodifiableMap(Function, Function)
+ * @since 10
+ */
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public static <T, K, U>
+ Collector<T, ?, Map<K,U>> toUnmodifiableMap(Function<? super T, ? extends K> keyMapper,
+ Function<? super T, ? extends U> valueMapper,
+ BinaryOperator<U> mergeFunction) {
+ Objects.requireNonNull(keyMapper, "keyMapper");
+ Objects.requireNonNull(valueMapper, "valueMapper");
+ Objects.requireNonNull(mergeFunction, "mergeFunction");
+ return collectingAndThen(
+ toMap(keyMapper, valueMapper, mergeFunction, HashMap::new),
+ map -> (Map<K,U>)Map.ofEntries(map.entrySet().toArray(new Map.Entry[0])));
+ }
+
/**
* Returns a {@code Collector} that accumulates elements into a
* {@code Map} whose keys and values are the result of applying the provided
--- a/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,7 +33,7 @@
import java.nio.channels.FileChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.*;
-import java.nio.file.DirectoryStream.Filter;;
+import java.nio.file.DirectoryStream.Filter;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.FileAttribute;
@@ -274,7 +274,7 @@
if (o.path.length() == 0) {
return this;
}
- StringBuilder sb = new StringBuilder(path.length() + o.path.length());
+ StringBuilder sb = new StringBuilder(path.length() + o.path.length() + 1);
sb.append(path);
if (path.charAt(path.length() - 1) != '/')
sb.append('/');
@@ -478,12 +478,15 @@
// Remove DotSlash(./) and resolve DotDot (..) components
private String getResolved() {
- if (path.length() == 0) {
+ int length = path.length();
+ if (length == 0 || (path.indexOf("./") == -1 && path.charAt(length - 1) != '.')) {
return path;
+ } else {
+ return resolvePath();
}
- if (path.indexOf('.') == -1) {
- return path;
- }
+ }
+
+ private String resolvePath() {
int length = path.length();
char[] to = new char[length];
int nc = getNameCount();
--- a/src/java.base/share/classes/jdk/internal/util/jar/VersionedStream.java Tue Dec 05 10:21:41 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.internal.util.jar;
-
-import java.util.Objects;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.stream.Stream;
-
-public class VersionedStream {
- private static final String META_INF_VERSIONS = "META-INF/versions/";
-
- /**
- * Returns a stream of versioned entries, derived from the base names of
- * all entries in a multi-release {@code JarFile} that are present either in
- * the base directory or in any versioned directory with a version number
- * less than or equal to the {@code Runtime.Version::major} that the
- * {@code JarFile} was opened with. These versioned entries are aliases
- * for the real entries -- i.e. the names are base names and the content
- * may come from a versioned directory entry. If the {@code jarFile} is not
- * a multi-release jar, a stream of all entries is returned.
- *
- * @param jf the input JarFile
- * @return stream of entries
- * @since 9
- */
- public static Stream<JarEntry> stream(JarFile jf) {
- if (jf.isMultiRelease()) {
- int version = jf.getVersion().major();
- return jf.stream()
- .map(je -> getBaseSuffix(je, version))
- .filter(Objects::nonNull)
- .distinct()
- .map(jf::getJarEntry);
- }
- return jf.stream();
- }
-
- private static String getBaseSuffix(JarEntry je, int version) {
- String name = je.getName();
- if (name.startsWith(META_INF_VERSIONS)) {
- int len = META_INF_VERSIONS.length();
- int index = name.indexOf('/', len);
- if (index == -1 || index == (name.length() - 1)) {
- // filter out META-INF/versions/* and META-INF/versions/*/
- return null;
- }
- try {
- if (Integer.parseInt(name, len, index, 10) > version) {
- // not an integer
- return null;
- }
- } catch (NumberFormatException x) {
- // silently remove malformed entries
- return null;
- }
- // We know name looks like META-INF/versions/*/*
- return name.substring(index + 1);
- }
- return name;
- }
-}
--- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java Tue Dec 05 10:28:45 2017 +0000
@@ -2746,12 +2746,12 @@
if (rfc) {
dumpCert(cert, out);
} else {
- out.println("Certificate #" + i++);
+ out.println("Certificate #" + i);
out.println("====================================");
printX509Cert((X509Certificate)cert, out);
out.println();
}
- checkWeak(oneInMany(rb.getString("the.certificate"), i, chain.size()), cert);
+ checkWeak(oneInMany(rb.getString("the.certificate"), i++, chain.size()), cert);
} catch (Exception e) {
if (debug) {
e.printStackTrace();
--- a/src/java.base/share/native/include/jvm.h Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/native/include/jvm.h Tue Dec 05 10:28:45 2017 +0000
@@ -262,21 +262,9 @@
/*
* java.lang.SecurityManager
*/
-JNIEXPORT jclass JNICALL
-JVM_CurrentLoadedClass(JNIEnv *env);
-
-JNIEXPORT jobject JNICALL
-JVM_CurrentClassLoader(JNIEnv *env);
-
JNIEXPORT jobjectArray JNICALL
JVM_GetClassContext(JNIEnv *env);
-JNIEXPORT jint JNICALL
-JVM_ClassDepth(JNIEnv *env, jstring name);
-
-JNIEXPORT jint JNICALL
-JVM_ClassLoaderDepth(JNIEnv *env);
-
/*
* java.lang.Package
*/
--- a/src/java.base/share/native/libjava/SecurityManager.c Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/native/libjava/SecurityManager.c Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,53 +76,3 @@
return JVM_GetClassContext(env);
}
-
-JNIEXPORT jclass JNICALL
-Java_java_lang_SecurityManager_currentLoadedClass0(JNIEnv *env, jobject this)
-{
- /* Make sure the security manager instance is initialized */
- if (!check(env, this)) {
- return NULL; /* exception */
- }
-
- return JVM_CurrentLoadedClass(env);
-}
-
-JNIEXPORT jobject JNICALL
-Java_java_lang_SecurityManager_currentClassLoader0(JNIEnv *env, jobject this)
-{
- /* Make sure the security manager instance is initialized */
- if (!check(env, this)) {
- return NULL; /* exception */
- }
-
- return JVM_CurrentClassLoader(env);
-}
-
-JNIEXPORT jint JNICALL
-Java_java_lang_SecurityManager_classDepth(JNIEnv *env, jobject this,
- jstring name)
-{
- /* Make sure the security manager instance is initialized */
- if (!check(env, this)) {
- return -1; /* exception */
- }
-
- if (name == NULL) {
- JNU_ThrowNullPointerException(env, 0);
- return -1;
- }
-
- return JVM_ClassDepth(env, name);
-}
-
-JNIEXPORT jint JNICALL
-Java_java_lang_SecurityManager_classLoaderDepth0(JNIEnv *env, jobject this)
-{
- /* Make sure the security manager instance is initialized */
- if (!check(env, this)) {
- return -1; /* exception */
- }
-
- return JVM_ClassLoaderDepth(env);
-}
--- a/src/java.base/share/native/libzip/Deflater.c Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/native/libzip/Deflater.c Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -164,17 +164,14 @@
res = deflateParams(strm, level, strategy);
(*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
(*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
-
switch (res) {
case Z_OK:
(*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE);
+ case Z_BUF_ERROR:
this_off += this_len - strm->avail_in;
(*env)->SetIntField(env, this, offID, this_off);
(*env)->SetIntField(env, this, lenID, strm->avail_in);
return (jint) (len - strm->avail_out);
- case Z_BUF_ERROR:
- (*env)->SetBooleanField(env, this, setParamsID, JNI_FALSE);
- return 0;
default:
JNU_ThrowInternalError(env, strm->msg);
return 0;
@@ -203,19 +200,17 @@
res = deflate(strm, finish ? Z_FINISH : flush);
(*env)->ReleasePrimitiveArrayCritical(env, b, out_buf, 0);
(*env)->ReleasePrimitiveArrayCritical(env, this_buf, in_buf, 0);
-
switch (res) {
case Z_STREAM_END:
(*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
/* fall through */
case Z_OK:
+ case Z_BUF_ERROR:
this_off += this_len - strm->avail_in;
(*env)->SetIntField(env, this, offID, this_off);
(*env)->SetIntField(env, this, lenID, strm->avail_in);
return len - strm->avail_out;
- case Z_BUF_ERROR:
- return 0;
- default:
+ default:
JNU_ThrowInternalError(env, strm->msg);
return 0;
}
--- a/src/java.base/share/native/libzip/zlib/deflate.c Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/native/libzip/zlib/deflate.c Tue Dec 05 10:28:45 2017 +0000
@@ -505,8 +505,6 @@
s->pending = 0;
s->pending_out = s->pending_buf;
- s->high_water = 0; /* reset to its inital value 0 */
-
if (s->wrap < 0) {
s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
}
@@ -520,7 +518,7 @@
s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
#endif
adler32(0L, Z_NULL, 0);
- s->last_flush = Z_NO_FLUSH;
+ s->last_flush = -2;
_tr_init(s);
@@ -613,7 +611,7 @@
func = configuration_table[s->level].func;
if ((strategy != s->strategy || func != configuration_table[level].func) &&
- s->high_water) {
+ s->last_flush != -2) {
/* Flush the last buffer: */
int err = deflate(strm, Z_BLOCK);
if (err == Z_STREAM_ERROR)
--- a/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java Tue Dec 05 10:28:45 2017 +0000
@@ -93,4 +93,6 @@
s->status =
#ifdef GZIP
+(7) deflate.c undo (6), replaced withe the official zlib repo fix see#305/#f969409
+
--- a/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/unix/classes/java/net/PlainDatagramSocketImpl.java Tue Dec 05 10:28:45 2017 +0000
@@ -45,41 +45,33 @@
ExtendedSocketOptions.getInstance();
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
- if (!extendedOptions.isOptionSupported(name)) {
- if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
- super.setOption(name, value);
+ if (isClosed()) {
+ throw new SocketException("Socket closed");
+ }
+ if (supportedOptions().contains(name)) {
+ if (extendedOptions.isOptionSupported(name)) {
+ extendedOptions.setOption(fd, name, value);
} else {
- if (supportedOptions().contains(name)) {
- super.setOption(name, value);
- } else {
- throw new UnsupportedOperationException("unsupported option");
- }
+ super.setOption(name, value);
}
} else {
- if (isClosed()) {
- throw new SocketException("Socket closed");
- }
- extendedOptions.setOption(fd, name, value);
+ throw new UnsupportedOperationException("unsupported option");
}
}
@SuppressWarnings("unchecked")
protected <T> T getOption(SocketOption<T> name) throws IOException {
- if (!extendedOptions.isOptionSupported(name)) {
- if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
- return super.getOption(name);
+ if (isClosed()) {
+ throw new SocketException("Socket closed");
+ }
+ if (supportedOptions().contains(name)) {
+ if (extendedOptions.isOptionSupported(name)) {
+ return (T) extendedOptions.getOption(fd, name);
} else {
- if (supportedOptions().contains(name)) {
- return super.getOption(name);
- } else {
- throw new UnsupportedOperationException("unsupported option");
- }
+ return super.getOption(name);
}
} else {
- if (isClosed()) {
- throw new SocketException("Socket closed");
- }
- return (T) extendedOptions.getOption(fd, name);
+ throw new UnsupportedOperationException("unsupported option");
}
}
--- a/src/java.base/unix/classes/java/net/PlainSocketImpl.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.base/unix/classes/java/net/PlainSocketImpl.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,58 +58,57 @@
ExtendedSocketOptions.getInstance();
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
- if (!extendedOptions.isOptionSupported(name)) {
- if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
- super.setOption(name, value);
+ if (isClosedOrPending()) {
+ throw new SocketException("Socket closed");
+ }
+ if (supportedOptions().contains(name)) {
+ if (extendedOptions.isOptionSupported(name)) {
+ extendedOptions.setOption(fd, name, value);
} else {
- if (supportedOptions().contains(name)) {
- super.setOption(name, value);
- } else {
- throw new UnsupportedOperationException("unsupported option");
- }
+ super.setOption(name, value);
}
} else {
- if (getSocket() == null) {
- throw new UnsupportedOperationException("unsupported option");
- }
- if (isClosedOrPending()) {
- throw new SocketException("Socket closed");
- }
- extendedOptions.setOption(fd, name, value);
+ throw new UnsupportedOperationException("unsupported option");
}
}
@SuppressWarnings("unchecked")
protected <T> T getOption(SocketOption<T> name) throws IOException {
- if (!extendedOptions.isOptionSupported(name)) {
- if (!name.equals(StandardSocketOptions.SO_REUSEPORT)) {
- return super.getOption(name);
+ if (isClosedOrPending()) {
+ throw new SocketException("Socket closed");
+ }
+ if (supportedOptions().contains(name)) {
+ if (extendedOptions.isOptionSupported(name)) {
+ return (T) extendedOptions.getOption(fd, name);
} else {
- if (supportedOptions().contains(name)) {
- return super.getOption(name);
- } else {
- throw new UnsupportedOperationException("unsupported option");
- }
+ return super.getOption(name);
}
} else {
- if (getSocket() == null) {
- throw new UnsupportedOperationException("unsupported option");
- }
- if (isClosedOrPending()) {
- throw new SocketException("Socket closed");
- }
- return (T) extendedOptions.getOption(fd, name);
+ throw new UnsupportedOperationException("unsupported option");
}
}
protected Set<SocketOption<?>> supportedOptions() {
HashSet<SocketOption<?>> options = new HashSet<>(super.supportedOptions());
- if (getSocket() != null) {
- options.addAll(extendedOptions.options());
- }
+ addExtSocketOptions(extendedOptions.options(), options);
return options;
}
+ private void addExtSocketOptions(Set<SocketOption<?>> extOptions,
+ Set<SocketOption<?>> options) {
+ extOptions.forEach((option) -> {
+ if (option.name().equals("SO_FLOW_SLA")) {
+ // SO_FLOW_SLA is Solaris specific option which is not applicable
+ // for ServerSockets.
+ // getSocket() will always return null for server socket
+ if (getSocket() != null) {
+ options.add(option);
+ }
+ } else {
+ options.add(option);
+ }
+ });
+ }
protected void socketSetOption(int opt, boolean b, Object val) throws SocketException {
if (opt == SocketOptions.SO_REUSEPORT &&
!supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT)) {
--- a/src/java.desktop/share/classes/sun/applet/AppletSecurity.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.desktop/share/classes/sun/applet/AppletSecurity.java Tue Dec 05 10:28:45 2017 +0000
@@ -48,6 +48,8 @@
import sun.awt.AWTPermissions;
import sun.security.util.SecurityConstants;
+import static java.lang.StackWalker.*;
+import static java.lang.StackWalker.Option.*;
/**
@@ -106,11 +108,90 @@
});
}
+ private static final StackWalker walker =
+ AccessController.doPrivileged(
+ (PrivilegedAction<StackWalker>) () ->
+ StackWalker.getInstance(RETAIN_CLASS_REFERENCE));
+ /**
+ * Returns the class loader of the most recently executing method from
+ * a class defined using a non-system class loader. A non-system
+ * class loader is defined as being a class loader that is not equal to
+ * the system class loader (as returned
+ * by {@link ClassLoader#getSystemClassLoader}) or one of its ancestors.
+ * <p>
+ * This method will return
+ * <code>null</code> in the following three cases:
+ * <ol>
+ * <li>All methods on the execution stack are from classes
+ * defined using the system class loader or one of its ancestors.
+ *
+ * <li>All methods on the execution stack up to the first
+ * "privileged" caller
+ * (see {@link java.security.AccessController#doPrivileged})
+ * are from classes
+ * defined using the system class loader or one of its ancestors.
+ *
+ * <li> A call to <code>checkPermission</code> with
+ * <code>java.security.AllPermission</code> does not
+ * result in a SecurityException.
+ * </ol>
+ *
+ * NOTE: This is an implementation of the SecurityManager.currentClassLoader
+ * method that uses StackWalker. SecurityManager.currentClassLoader
+ * has been removed from SE. This is a temporary workaround which is
+ * only needed while applets are still supported.
+ *
+ * @return the class loader of the most recent occurrence on the stack
+ * of a method from a class defined using a non-system class
+ * loader.
+ */
+ private static ClassLoader currentClassLoader() {
+ StackFrame f =
+ walker.walk(s -> s.takeWhile(AppletSecurity::isNonPrivileged)
+ .filter(AppletSecurity::isNonSystemFrame)
+ .findFirst())
+ .orElse(null);
+
+ SecurityManager sm = System.getSecurityManager();
+ if (f != null && sm != null) {
+ try {
+ sm.checkPermission(new AllPermission());
+ } catch (SecurityException se) {
+ return f.getDeclaringClass().getClassLoader();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns true if the StackFrame is not AccessController.doPrivileged.
+ */
+ private static boolean isNonPrivileged(StackFrame f) {
+ // possibly other doPrivileged variants
+ Class<?> c = f.getDeclaringClass();
+ return c == AccessController.class &&
+ f.getMethodName().equals("doPrivileged");
+ }
+
+ /**
+ * Returns true if the StackFrame is not from a class defined by the
+ * system class loader or one of its ancestors.
+ */
+ private static boolean isNonSystemFrame(StackFrame f) {
+ ClassLoader loader = ClassLoader.getSystemClassLoader();
+ ClassLoader ld = f.getDeclaringClass().getClassLoader();
+ if (ld == null || ld == loader) return false;
+
+ while ((loader = loader.getParent()) != null) {
+ if (ld == loader)
+ return false;
+ }
+ return true;
+ }
+
/**
* get the current (first) instance of an AppletClassLoader on the stack.
*/
- @SuppressWarnings({"deprecation",
- "removal"}) // SecurityManager.currentClassLoader()
private AppletClassLoader currentAppletClassLoader()
{
// try currentClassLoader first
--- a/src/java.desktop/share/classes/sun/awt/FontDescriptor.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.desktop/share/classes/sun/awt/FontDescriptor.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* 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 @@
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
-import java.io.IOException;;
+import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.StandardCharsets;
--- a/src/java.security.jgss/share/native/libj2gss/GSSLibStub.c Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.security.jgss/share/native/libj2gss/GSSLibStub.c Tue Dec 05 10:28:45 2017 +0000
@@ -1410,7 +1410,6 @@
checkStatus(env, jobj, GSS_S_CONTEXT_EXPIRED, 0, "[GSSLibStub_getMic]");
return NULL;
}
- contextHdl = (gss_ctx_id_t) jlong_to_ptr(pContext);
qop = (gss_qop_t) jqop;
initGSSBuffer(env, jmsg, &msg);
if ((*env)->ExceptionCheck(env)) {
--- a/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriter.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.xml.ws/share/classes/com/sun/xml/internal/messaging/saaj/util/stax/SaajStaxWriter.java Tue Dec 05 10:28:45 2017 +0000
@@ -505,7 +505,7 @@
}
// add namespace declarations
for (NamespaceDeclaration namespace : this.namespaceDeclarations) {
- target.addNamespaceDeclaration(namespace.prefix, namespace.namespaceUri);
+ newElement.addNamespaceDeclaration(namespace.prefix, namespace.namespaceUri);
}
// add attribute declarations
for (AttributeDeclaration attribute : this.attributeDeclarations) {
--- a/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/message/saaj/SaajStaxWriter.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/api/message/saaj/SaajStaxWriter.java Tue Dec 05 10:28:45 2017 +0000
@@ -499,7 +499,7 @@
}
// add namespace declarations
for (NamespaceDeclaration namespace : this.namespaceDeclarations) {
- target.addNamespaceDeclaration(namespace.prefix, namespace.namespaceUri);
+ newElement.addNamespaceDeclaration(namespace.prefix, namespace.namespaceUri);
}
// add attribute declarations
for (AttributeDeclaration attribute : this.attributeDeclarations) {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java Tue Dec 05 10:28:45 2017 +0000
@@ -32,6 +32,7 @@
*
* @version $Id: ConstantDouble.java 1747278 2016-06-07 17:28:43Z britter $
* @see Constant
+ * @LastModified: Nov 2017
*/
public final class ConstantDouble extends Constant implements ConstantObject {
@@ -121,6 +122,6 @@
*/
@Override
public Object getConstantValue( final ConstantPool cp ) {
- return new Double(bytes);
+ return bytes;
}
}
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java Tue Dec 05 10:28:45 2017 +0000
@@ -32,6 +32,7 @@
*
* @version $Id: ConstantFloat.java 1747278 2016-06-07 17:28:43Z britter $
* @see Constant
+ * @LastModified: Nov 2017
*/
public final class ConstantFloat extends Constant implements ConstantObject {
@@ -122,6 +123,6 @@
*/
@Override
public Object getConstantValue( final ConstantPool cp ) {
- return new Float(bytes);
+ return bytes;
}
}
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java Tue Dec 05 10:28:45 2017 +0000
@@ -26,6 +26,7 @@
* <PRE>Stack: ... -> ..., </PRE>
*
* @version $Id: DCONST.java 1747278 2016-06-07 17:28:43Z britter $
+ * @LastModified: Nov 2017
*/
public class DCONST extends Instruction implements ConstantPushInstruction {
@@ -55,7 +56,7 @@
@Override
public Number getValue() {
- return new Double(value);
+ return value;
}
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java Tue Dec 05 10:28:45 2017 +0000
@@ -26,6 +26,7 @@
* <PRE>Stack: ... -> ..., </PRE>
*
* @version $Id: FCONST.java 1747278 2016-06-07 17:28:43Z britter $
+ * @LastModified: Nov 2017
*/
public class FCONST extends Instruction implements ConstantPushInstruction {
@@ -57,7 +58,7 @@
@Override
public Number getValue() {
- return new Float(value);
+ return value;
}
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,6 +1,5 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -41,6 +40,7 @@
* <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic">
* The invokedynamic instruction in The Java Virtual Machine Specification</a>
* @since 6.0
+ * @LastModified: Nov 2017
*/
public class INVOKEDYNAMIC extends InvokeInstruction {
@@ -124,8 +124,14 @@
/**
* Override the parent method because our classname is held elsewhere.
+ *
+ * @param cpg the ConstantPool generator
+ * @deprecated in FieldOrMethod
+ *
+ * @return name of the referenced class/interface
*/
@Override
+ @Deprecated
public String getClassName( final ConstantPoolGen cpg ) {
final ConstantPool cp = cpg.getConstantPool();
final ConstantInvokeDynamic cid = (ConstantInvokeDynamic) cp.getConstant(super.getIndex(), Const.CONSTANT_InvokeDynamic);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java Tue Dec 05 10:28:45 2017 +0000
@@ -32,6 +32,7 @@
* @version $Id: InstructionFactory.java 1749603 2016-06-21 20:50:19Z ggregory $
* @see Const
* @see InstructionConst
+ * @LastModified: Nov 2017
*/
public class InstructionFactory {
@@ -573,7 +574,7 @@
+ short_names[dest - Const.T_CHAR];
Instruction i = null;
try {
- i = (Instruction) java.lang.Class.forName(name).newInstance();
+ i = (Instruction) java.lang.Class.forName(name).getDeclaredConstructor().newInstance();
} catch (final Exception e) {
throw new RuntimeException("Could not find instruction: " + name, e);
}
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java Tue Dec 05 10:28:45 2017 +0000
@@ -32,6 +32,7 @@
* <PRE>Stack: ... -> ..., item</PRE>
*
* @version $Id: LDC.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @LastModified: Nov 2017
*/
public class LDC extends CPInstruction implements PushInstruction, ExceptionThrower {
@@ -104,9 +105,9 @@
c = cpg.getConstantPool().getConstant(i);
return ((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8) c).getBytes();
case com.sun.org.apache.bcel.internal.Const.CONSTANT_Float:
- return new Float(((com.sun.org.apache.bcel.internal.classfile.ConstantFloat) c).getBytes());
+ return ((com.sun.org.apache.bcel.internal.classfile.ConstantFloat) c).getBytes();
case com.sun.org.apache.bcel.internal.Const.CONSTANT_Integer:
- return Integer.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantInteger) c).getBytes());
+ return ((com.sun.org.apache.bcel.internal.classfile.ConstantInteger) c).getBytes();
case com.sun.org.apache.bcel.internal.Const.CONSTANT_Class:
final int nameIndex = ((com.sun.org.apache.bcel.internal.classfile.ConstantClass) c).getNameIndex();
c = cpg.getConstantPool().getConstant(nameIndex);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java Tue Dec 05 10:28:45 2017 +0000
@@ -26,6 +26,7 @@
* <PRE>Stack: ... -> ..., item.word1, item.word2</PRE>
*
* @version $Id: LDC2_W.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @LastModified: Nov 2017
*/
public class LDC2_W extends CPInstruction implements PushInstruction {
@@ -59,9 +60,9 @@
final com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(super.getIndex());
switch (c.getTag()) {
case com.sun.org.apache.bcel.internal.Const.CONSTANT_Long:
- return Long.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantLong) c).getBytes());
+ return ((com.sun.org.apache.bcel.internal.classfile.ConstantLong) c).getBytes();
case com.sun.org.apache.bcel.internal.Const.CONSTANT_Double:
- return new Double(((com.sun.org.apache.bcel.internal.classfile.ConstantDouble) c).getBytes());
+ return ((com.sun.org.apache.bcel.internal.classfile.ConstantDouble) c).getBytes();
default: // Never reached
throw new RuntimeException("Unknown or invalid constant type at " + super.getIndex());
}
--- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/Big5_HKSCS.java.template Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/Big5_HKSCS.java.template Tue Dec 05 10:28:45 2017 +0000
@@ -31,6 +31,7 @@
import sun.nio.cs.DoubleByte;
import sun.nio.cs.HKSCS;
import sun.nio.cs.HistoricallyNamedCharset;
+import sun.nio.cs.*;
import static sun.nio.cs.CharsetMapping.*;
public class Big5_HKSCS extends Charset implements HistoricallyNamedCharset
--- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/MS950_HKSCS.java Tue Dec 05 10:21:41 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.nio.cs.ext;
-
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CharsetEncoder;
-import sun.nio.cs.HistoricallyNamedCharset;
-import sun.nio.cs.*;
-import static sun.nio.cs.CharsetMapping.*;
-
-public class MS950_HKSCS extends Charset implements HistoricallyNamedCharset
-{
- public MS950_HKSCS() {
- super("x-MS950-HKSCS", ExtendedCharsets.aliasesFor("x-MS950-HKSCS"));
- }
-
- public String historicalName() {
- return "MS950_HKSCS";
- }
-
- public boolean contains(Charset cs) {
- return ((cs.name().equals("US-ASCII"))
- || (cs instanceof MS950)
- || (cs instanceof MS950_HKSCS));
- }
-
- public CharsetDecoder newDecoder() {
- return new Decoder(this);
- }
-
- public CharsetEncoder newEncoder() {
- return new Encoder(this);
- }
-
- static class Decoder extends HKSCS.Decoder {
- private static DoubleByte.Decoder ms950 =
- (DoubleByte.Decoder)new MS950().newDecoder();
-
- private static char[][] b2cBmp = new char[0x100][];
- private static char[][] b2cSupp = new char[0x100][];
- static {
- initb2c(b2cBmp, HKSCSMapping.b2cBmpStr);
- initb2c(b2cSupp, HKSCSMapping.b2cSuppStr);
- }
-
- private Decoder(Charset cs) {
- super(cs, ms950, b2cBmp, b2cSupp);
- }
- }
-
- private static class Encoder extends HKSCS.Encoder {
- private static DoubleByte.Encoder ms950 =
- (DoubleByte.Encoder)new MS950().newEncoder();
-
- static char[][] c2bBmp = new char[0x100][];
- static char[][] c2bSupp = new char[0x100][];
- static {
- initc2b(c2bBmp, HKSCSMapping.b2cBmpStr, HKSCSMapping.pua);
- initc2b(c2bSupp, HKSCSMapping.b2cSuppStr, null);
- }
-
- private Encoder(Charset cs) {
- super(cs, ms950, c2bBmp, c2bSupp);
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/MS950_HKSCS.java.template Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package $PACKAGE$;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import sun.nio.cs.HistoricallyNamedCharset;
+import sun.nio.cs.*;
+import static sun.nio.cs.CharsetMapping.*;
+
+public class MS950_HKSCS extends Charset implements HistoricallyNamedCharset
+{
+ public MS950_HKSCS() {
+ super("x-MS950-HKSCS", $ALIASES$);
+ }
+
+ public String historicalName() {
+ return "MS950_HKSCS";
+ }
+
+ public boolean contains(Charset cs) {
+ return ((cs.name().equals("US-ASCII"))
+ || (cs instanceof MS950)
+ || (cs instanceof MS950_HKSCS));
+ }
+
+ public CharsetDecoder newDecoder() {
+ return new Decoder(this);
+ }
+
+ public CharsetEncoder newEncoder() {
+ return new Encoder(this);
+ }
+
+ static class Decoder extends HKSCS.Decoder {
+ private static DoubleByte.Decoder ms950 =
+ (DoubleByte.Decoder)new MS950().newDecoder();
+
+ private static char[][] b2cBmp = new char[0x100][];
+ private static char[][] b2cSupp = new char[0x100][];
+ static {
+ initb2c(b2cBmp, HKSCSMapping.b2cBmpStr);
+ initb2c(b2cSupp, HKSCSMapping.b2cSuppStr);
+ }
+
+ private Decoder(Charset cs) {
+ super(cs, ms950, b2cBmp, b2cSupp);
+ }
+ }
+
+ private static class Encoder extends HKSCS.Encoder {
+ private static DoubleByte.Encoder ms950 =
+ (DoubleByte.Encoder)new MS950().newEncoder();
+
+ static char[][] c2bBmp = new char[0x100][];
+ static char[][] c2bSupp = new char[0x100][];
+ static {
+ initc2b(c2bBmp, HKSCSMapping.b2cBmpStr, HKSCSMapping.pua);
+ initc2b(c2bSupp, HKSCSMapping.b2cSuppStr, null);
+ }
+
+ private Encoder(Charset cs) {
+ super(cs, ms950, c2bBmp, c2bSupp);
+ }
+ }
+}
--- a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocCommentTree.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocCommentTree.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
package com.sun.source.doctree;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
/**
@@ -69,4 +70,39 @@
* @return the block tags of a documentation comment
*/
List<? extends DocTree> getBlockTags();
+
+ /**
+ * Returns a list of trees containing the content (if any) preceding
+ * the content of the documentation comment.
+ * When the {@code DocCommentTree} has been read from a documentation
+ * comment in a Java source file, the list will be empty.
+ * When the {@code DocCommentTree} has been read from an HTML file, this
+ * represents the content from the beginning of the file up to and
+ * including the {@code <body>} tag.
+ *
+ * @implSpec This implementation returns an empty list.
+ *
+ * @return the list of trees
+ * @since 10
+ */
+ default List<? extends DocTree> getPreamble() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Returns a list of trees containing the content (if any) following the
+ * content of the documentation comment.
+ * When the {@code DocCommentTree} has been read from a documentation
+ * comment in a Java source file, the list will be empty.
+ * When {@code DocCommentTree} has been read from an HTML file, this
+ * represents the content from the {@code </body>} tag to the end of file.
+ *
+ * @implSpec This implementation returns an empty list.
+ *
+ * @return the list of trees
+ * @since 10
+ */
+ default List<? extends DocTree> getPostamble() {
+ return Collections.emptyList();
+ }
}
--- a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTree.java Tue Dec 05 10:28:45 2017 +0000
@@ -78,6 +78,12 @@
DOC_ROOT("docRoot"),
/**
+ * Used for instances of {@link DocTypeTree}
+ * representing an HTML DocType declaration.
+ */
+ DOC_TYPE,
+
+ /**
* Used for instances of {@link EndElementTree}
* representing the end of an HTML element.
*/
--- a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTreeVisitor.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTreeVisitor.java Tue Dec 05 10:28:45 2017 +0000
@@ -105,6 +105,21 @@
R visitDocRoot(DocRootTree node, P p);
/**
+ * Visits a DocTypeTree node.
+ *
+ * @implSpec Visits a {@code DocTypeTree} node
+ * by calling {@code visitOther(node, p)}.
+ *
+ * @param node the node being visited
+ * @param p a parameter value
+ * @return a result value
+ * @since 10
+ */
+ default R visitDocType(DocTypeTree node, P p) {
+ return visitOther(node, p);
+ }
+
+ /**
* Visits an EndElementTree node.
* @param node the node being visited
* @param p a parameter value
@@ -130,11 +145,19 @@
/**
* Visits a HiddenTree node.
+ *
+ * @implSpec Visits a {@code HiddenTree} node
+ * by calling {@code visitOther(node, p)}.
+ *
* @param node the node being visited
* @param p a parameter value
* @return a result value
+ *
+ * @since 9
*/
- R visitHidden(HiddenTree node, P p);
+ default R visitHidden(HiddenTree node, P p) {
+ return visitOther(node, p);
+ }
/**
* Visits an IdentifierTree node.
@@ -146,11 +169,19 @@
/**
* Visits an IndexTree node.
+ *
+ * @implSpec Visits an {@code IndexTree} node
+ * by calling {@code visitOther(node, p)}.
+ *
* @param node the node being visited
* @param p a parameter value
* @return a result value
+ *
+ * @since 9
*/
- R visitIndex(IndexTree node, P p);
+ default R visitIndex(IndexTree node, P p) {
+ return visitOther(node, p);
+ }
/**
* Visits an InheritDocTree node.
@@ -186,11 +217,19 @@
/**
* Visits a ProvidesTree node.
+ *
+ * @implSpec Visits a {@code ProvidesTree} node
+ * by calling {@code visitOther(node, p)}.
+ *
* @param node the node being visited
* @param p a parameter value
* @return a result value
+ *
+ * @since 9
*/
- R visitProvides(ProvidesTree node, P p);
+ default R visitProvides(ProvidesTree node, P p) {
+ return visitOther(node, p);
+ }
/**
* Visits a ReferenceTree node.
@@ -267,7 +306,9 @@
* @return a result value
* @since 10
*/
- default R visitSummary(SummaryTree node, P p) { return visitOther(node, p);}
+ default R visitSummary(SummaryTree node, P p) {
+ return visitOther(node, p);
+ }
/**
* Visits a TextTree node.
@@ -303,11 +344,19 @@
/**
* Visits a UsesTree node.
+ *
+ * @implSpec Visits a {@code UsesTree} node
+ * by calling {@code visitOther(node, p)}.
+ *
* @param node the node being visited
* @param p a parameter value
* @return a result value
+ *
+ * @since 9
*/
- R visitUses(UsesTree node, P p);
+ default R visitUses(UsesTree node, P p) {
+ return visitOther(node, p);
+ }
/**
* Visits a ValueTree node.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocTypeTree.java Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.doctree;
+
+/**
+ * A tree node for a {@code doctype} declaration.
+ *
+ * <p>
+ * <!doctype text>
+ *
+ * @since 10
+ */
+public interface DocTypeTree extends DocTree {
+ /**
+ * Returns the text of the doctype declaration.
+ * @return text
+ */
+ String getText();
+}
--- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java Tue Dec 05 10:28:45 2017 +0000
@@ -39,6 +39,7 @@
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocRootTree;
import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.DocTypeTree;
import com.sun.source.doctree.EndElementTree;
import com.sun.source.doctree.EntityTree;
import com.sun.source.doctree.ErroneousTree;
@@ -121,6 +122,20 @@
*/
DocCommentTree newDocCommentTree(List<? extends DocTree> fullBody, List<? extends DocTree> tags);
+
+ /**
+ * Create a new {@code DocCommentTree} object, to represent the enitire doc comment.
+ * @param fullBody the entire body of the doc comment
+ * @param tags the block tags in the doc comment
+ * @param preamble the meta content of an html file including the body tag
+ * @param postamble the meta content of an html including the closing body tag
+ * @return a {@code DocCommentTree} object
+ * @since 10
+ */
+ DocCommentTree newDocCommentTree(List<? extends DocTree> fullBody,
+ List<? extends DocTree> tags,
+ List<? extends DocTree> preamble,
+ List<? extends DocTree> postamble);
/**
* Create a new {@code DocRootTree} object, to represent an {@code {@docroot} } tag.
* @return a {@code DocRootTree} object
@@ -128,6 +143,14 @@
DocRootTree newDocRootTree();
/**
+ * Create a new {@code DocTypeTree}, to represent a {@code DOCTYPE} HTML declaration.
+ * @param text the content of the declaration
+ * @return a {@code CommentTree} object
+ * @since 10
+ */
+ DocTypeTree newDocTypeTree(String text);
+
+ /**
* Create a new {@code EndElement} object, to represent the end of an HTML element.
* @param name the name of the HTML element
* @return an {@code EndElementTree} object
--- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java Tue Dec 05 10:28:45 2017 +0000
@@ -206,6 +206,18 @@
* @return the result of scanning
*/
@Override
+ public R visitDocType(DocTypeTree node, P p) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc} This implementation returns {@code null}.
+ *
+ * @param node {@inheritDoc}
+ * @param p {@inheritDoc}
+ * @return the result of scanning
+ */
+ @Override
public R visitEndElement(EndElementTree node, P p) {
return null;
}
--- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java Tue Dec 05 10:28:45 2017 +0000
@@ -98,13 +98,12 @@
/**
* Returns the doc comment tree of the given file. The file must be
* an HTML file, in which case the doc comment tree represents the
- * contents of the <body> tag, and any enclosing tags are ignored.
+ * entire contents of the file.
* Returns {@code null} if no doc comment was found.
* Future releases may support additional file types.
*
* @param fileObject the content container
* @return the doc comment tree
- *
* @since 9
*/
public abstract DocCommentTree getDocCommentTree(FileObject fileObject);
--- a/src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/source/util/SimpleDocTreeVisitor.java Tue Dec 05 10:28:45 2017 +0000
@@ -168,6 +168,19 @@
}
/**
+ * {@inheritDoc}
+ *
+ * @implSpec This implementation calls {@code defaultAction}.
+ *
+ * @param node {@inheritDoc}
+ * @param p {@inheritDoc}
+ * @return the result of {@code defaultAction}
+ * @since 10
+ */
+ @Override
+ public R visitDocType(DocTypeTree node, P p) { return defaultAction(node, p); }
+
+ /**
* {@inheritDoc} This implementation calls {@code defaultAction}.
*
* @param node {@inheritDoc}
@@ -175,9 +188,7 @@
* @return the result of {@code defaultAction}
*/
@Override
- public R visitEndElement(EndElementTree node, P p) {
- return defaultAction(node, p);
- }
+ public R visitEndElement(EndElementTree node, P p) { return defaultAction(node, p);}
/**
* {@inheritDoc} This implementation calls {@code defaultAction}.
@@ -209,6 +220,8 @@
* @param node {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of {@code defaultAction}
+ *
+ * @since 9
*/
@Override
public R visitHidden(HiddenTree node, P p) {
@@ -233,6 +246,8 @@
* @param node {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of {@code defaultAction}
+ *
+ * @since 9
*/
@Override
public R visitIndex(IndexTree node, P p) {
@@ -293,6 +308,8 @@
* @param node {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of {@code defaultAction}
+ *
+ * @since 9
*/
@Override
public R visitProvides(ProvidesTree node, P p) {
@@ -462,6 +479,8 @@
* @param node {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of {@code defaultAction}
+ *
+ * @since 9
*/
@Override
public R visitUses(UsesTree node, P p) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Tue Dec 05 10:28:45 2017 +0000
@@ -28,9 +28,8 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.BreakIterator;
-import java.util.HashMap;
+import java.util.Collections;
import java.util.HashSet;
-import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -59,6 +58,8 @@
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.EndElementTree;
+import com.sun.source.doctree.StartElementTree;
import com.sun.source.tree.CatchTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Scope;
@@ -68,6 +69,7 @@
import com.sun.source.util.DocTreeScanner;
import com.sun.source.util.DocTrees;
import com.sun.source.util.JavacTask;
+import com.sun.source.util.SimpleDocTreeVisitor;
import com.sun.source.util.TreePath;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Scope.NamedImportScope;
@@ -1006,16 +1008,7 @@
public String getText() {
try {
CharSequence rawDoc = fileObject.getCharContent(true);
- Pattern bodyPat =
- Pattern.compile("(?is).*?<body\\b[^>]*>(.*)</body\\b.*");
- Matcher m = bodyPat.matcher(rawDoc);
- if (m.matches()) {
- offset = m.end(1);
- return m.group(1);
- } else {
- // Assume doclint will do the right thing.
- return "";
- }
+ return rawDoc.toString();
} catch (IOException ignore) {
// do nothing
}
@@ -1038,13 +1031,15 @@
}
};
- return new DocCommentParser(parser, diagSource, comment).parse();
+ return new DocCommentParser(parser, diagSource, comment, true).parse();
}
@Override @DefinedBy(Api.COMPILER_TREE)
public DocTreePath getDocTreePath(FileObject fileObject, PackageElement packageElement) {
JavaFileObject jfo = asJavaFileObject(fileObject);
DocCommentTree docCommentTree = getDocCommentTree(jfo);
+ if (docCommentTree == null)
+ return null;
TreePath treePath = makeTreePath((PackageSymbol)packageElement, jfo, docCommentTree);
return new DocTreePath(treePath, docCommentTree);
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java Tue Dec 05 10:28:45 2017 +0000
@@ -115,7 +115,7 @@
values = EnumSet.noneOf(LintCategory.class);
Source source = Source.instance(context);
- if (source.compareTo(Source.JDK1_9) >= 0) {
+ if (source.compareTo(Source.JDK9) >= 0) {
values.add(LintCategory.DEP_ANN);
}
values.add(LintCategory.REQUIRES_TRANSITIVE_AUTOMATIC);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java Tue Dec 05 10:28:45 2017 +0000
@@ -31,7 +31,12 @@
import static javax.lang.model.SourceVersion.*;
import com.sun.tools.javac.jvm.Target;
+import com.sun.tools.javac.resources.CompilerProperties.Errors;
+import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.JCDiagnostic.Error;
+import com.sun.tools.javac.util.JCDiagnostic.Fragment;
+
import static com.sun.tools.javac.main.Option.*;
/** The source language version accepted.
@@ -59,22 +64,22 @@
/** 1.5 introduced generics, attributes, foreach, boxing, static import,
* covariant return, enums, varargs, et al. */
- JDK1_5("1.5"),
+ JDK5("5"),
/** 1.6 reports encoding problems as errors instead of warnings. */
- JDK1_6("1.6"),
+ JDK6("6"),
/** 1.7 introduced try-with-resources, multi-catch, string switch, etc. */
- JDK1_7("1.7"),
+ JDK7("7"),
/** 1.8 lambda expressions and default methods. */
- JDK1_8("1.8"),
+ JDK8("8"),
/** 1.9 modularity. */
- JDK1_9("1.9"),
+ JDK9("9"),
/** 1.10 covers the to be determined language features that will be added in JDK 10. */
- JDK1_10("1.10");
+ JDK10("10");
private static final Context.Key<Source> sourceKey = new Context.Key<>();
@@ -97,19 +102,19 @@
for (Source s : values()) {
tab.put(s.name, s);
}
- tab.put("5", JDK1_5); // Make 5 an alias for 1.5
- tab.put("6", JDK1_6); // Make 6 an alias for 1.6
- tab.put("7", JDK1_7); // Make 7 an alias for 1.7
- tab.put("8", JDK1_8); // Make 8 an alias for 1.8
- tab.put("9", JDK1_9); // Make 9 an alias for 1.9
- tab.put("10", JDK1_10); // Make 10 an alias for 1.10
+ tab.put("1.5", JDK5); // Make 5 an alias for 1.5
+ tab.put("1.6", JDK6); // Make 6 an alias for 1.6
+ tab.put("1.7", JDK7); // Make 7 an alias for 1.7
+ tab.put("1.8", JDK8); // Make 8 an alias for 1.8
+ tab.put("1.9", JDK9); // Make 9 an alias for 1.9
+ tab.put("1.10", JDK10); // Make 10 an alias for 1.10
}
private Source(String name) {
this.name = name;
}
- public static final Source MIN = Source.JDK1_6;
+ public static final Source MIN = Source.JDK6;
private static final Source MAX = values()[values().length - 1];
@@ -120,114 +125,108 @@
}
public Target requiredTarget() {
- if (this.compareTo(JDK1_10) >= 0) return Target.JDK1_10;
- if (this.compareTo(JDK1_9) >= 0) return Target.JDK1_9;
- if (this.compareTo(JDK1_8) >= 0) return Target.JDK1_8;
- if (this.compareTo(JDK1_7) >= 0) return Target.JDK1_7;
- if (this.compareTo(JDK1_6) >= 0) return Target.JDK1_6;
- if (this.compareTo(JDK1_5) >= 0) return Target.JDK1_5;
+ if (this.compareTo(JDK10) >= 0) return Target.JDK1_10;
+ if (this.compareTo(JDK9) >= 0) return Target.JDK1_9;
+ if (this.compareTo(JDK8) >= 0) return Target.JDK1_8;
+ if (this.compareTo(JDK7) >= 0) return Target.JDK1_7;
+ if (this.compareTo(JDK6) >= 0) return Target.JDK1_6;
+ if (this.compareTo(JDK5) >= 0) return Target.JDK1_5;
if (this.compareTo(JDK1_4) >= 0) return Target.JDK1_4;
return Target.JDK1_1;
}
- public boolean allowDiamond() {
- return compareTo(JDK1_7) >= 0;
- }
- public boolean allowMulticatch() {
- return compareTo(JDK1_7) >= 0;
- }
- public boolean allowImprovedRethrowAnalysis() {
- return compareTo(JDK1_7) >= 0;
- }
- public boolean allowImprovedCatchAnalysis() {
- return compareTo(JDK1_7) >= 0;
- }
- public boolean allowModules() {
- return compareTo(JDK1_9) >= 0;
- }
- public boolean allowTryWithResources() {
- return compareTo(JDK1_7) >= 0;
- }
- public boolean allowEffectivelyFinalVariablesInTryWithResources() {
- return compareTo(JDK1_9) >= 0;
- }
- public boolean allowBinaryLiterals() {
- return compareTo(JDK1_7) >= 0;
- }
- public boolean allowUnderscoresInLiterals() {
- return compareTo(JDK1_7) >= 0;
- }
- public boolean allowStringsInSwitch() {
- return compareTo(JDK1_7) >= 0;
- }
- public boolean allowDeprecationOnImport() {
- return compareTo(JDK1_9) < 0;
- }
- public boolean allowSimplifiedVarargs() {
- return compareTo(JDK1_7) >= 0;
- }
- public boolean allowObjectToPrimitiveCast() {
- return compareTo(JDK1_7) >= 0;
- }
- public boolean enforceThisDotInit() {
- return compareTo(JDK1_7) >= 0;
- }
- public boolean allowPoly() {
- return compareTo(JDK1_8) >= 0;
- }
- public boolean allowLambda() {
- return compareTo(JDK1_8) >= 0;
+ /**
+ * Models a feature of the Java programming language. Each feature can be associated with a
+ * minimum source level, a maximum source level and a diagnostic fragment describing the feature,
+ * which is used to generate error messages of the kind {@code feature XYZ not supported in source N}.
+ */
+ public enum Feature {
+
+ DIAMOND(JDK7, Fragments.FeatureDiamond, DiagKind.NORMAL),
+ MULTICATCH(JDK7, Fragments.FeatureMulticatch, DiagKind.PLURAL),
+ IMPROVED_RETHROW_ANALYSIS(JDK7),
+ IMPROVED_CATCH_ANALYSIS(JDK7),
+ MODULES(JDK9, Fragments.FeatureModules, DiagKind.PLURAL),
+ TRY_WITH_RESOURCES(JDK7, Fragments.FeatureTryWithResources, DiagKind.NORMAL),
+ EFFECTIVELY_FINAL_VARIABLES_IN_TRY_WITH_RESOURCES(JDK9, Fragments.FeatureVarInTryWithResources, DiagKind.PLURAL),
+ BINARY_LITERALS(JDK7, Fragments.FeatureBinaryLit, DiagKind.PLURAL),
+ UNDERSCORES_IN_LITERALS(JDK7, Fragments.FeatureUnderscoreLit, DiagKind.PLURAL),
+ STRINGS_IN_SWITCH(JDK7, Fragments.FeatureStringSwitch, DiagKind.PLURAL),
+ DEPRECATION_ON_IMPORT(MIN, JDK9),
+ SIMPLIFIED_VARARGS(JDK7),
+ OBJECT_TO_PRIMITIVE_CAST(JDK7),
+ ENFORCE_THIS_DOT_INIT(JDK7),
+ POLY(JDK8),
+ LAMBDA(JDK8, Fragments.FeatureLambda, DiagKind.PLURAL),
+ METHOD_REFERENCES(JDK8, Fragments.FeatureMethodReferences, DiagKind.PLURAL),
+ DEFAULT_METHODS(JDK8, Fragments.FeatureDefaultMethods, DiagKind.PLURAL),
+ STATIC_INTERFACE_METHODS(JDK8, Fragments.FeatureStaticIntfMethods, DiagKind.PLURAL),
+ STATIC_INTERFACE_METHODS_INVOKE(JDK8, Fragments.FeatureStaticIntfMethodInvoke, DiagKind.PLURAL),
+ STRICT_METHOD_CLASH_CHECK(JDK8),
+ EFFECTIVELY_FINAL_IN_INNER_CLASSES(JDK8),
+ TYPE_ANNOTATIONS(JDK8, Fragments.FeatureTypeAnnotations, DiagKind.PLURAL),
+ ANNOTATIONS_AFTER_TYPE_PARAMS(JDK8, Fragments.FeatureAnnotationsAfterTypeParams, DiagKind.PLURAL),
+ REPEATED_ANNOTATIONS(JDK8, Fragments.FeatureRepeatableAnnotations, DiagKind.PLURAL),
+ INTERSECTION_TYPES_IN_CAST(JDK8, Fragments.FeatureIntersectionTypesInCast, DiagKind.PLURAL),
+ GRAPH_INFERENCE(JDK8),
+ FUNCTIONAL_INTERFACE_MOST_SPECIFIC(JDK8),
+ POST_APPLICABILITY_VARARGS_ACCESS_CHECK(JDK8),
+ MAP_CAPTURES_TO_BOUNDS(MIN, JDK7),
+ PRIVATE_SAFE_VARARGS(JDK9),
+ DIAMOND_WITH_ANONYMOUS_CLASS_CREATION(JDK9, Fragments.FeatureDiamondAndAnonClass, DiagKind.NORMAL),
+ UNDERSCORE_IDENTIFIER(MIN, JDK8),
+ PRIVATE_INTERFACE_METHODS(JDK9, Fragments.FeaturePrivateIntfMethods, DiagKind.PLURAL),
+ LOCAL_VARIABLE_TYPE_INFERENCE(JDK10);
+
+ enum DiagKind {
+ NORMAL,
+ PLURAL;
+ }
+
+ private final Source minLevel;
+ private final Source maxLevel;
+ private final Fragment optFragment;
+ private final DiagKind optKind;
+
+ Feature(Source minLevel) {
+ this(minLevel, null, null);
+ }
+
+ Feature(Source minLevel, Fragment optFragment, DiagKind optKind) {
+ this(minLevel, MAX, optFragment, optKind);
+ }
+
+ Feature(Source minLevel, Source maxLevel) {
+ this(minLevel, maxLevel, null, null);
+ }
+
+ Feature(Source minLevel, Source maxLevel, Fragment optFragment, DiagKind optKind) {
+ this.minLevel = minLevel;
+ this.maxLevel = maxLevel;
+ this.optFragment = optFragment;
+ this.optKind = optKind;
+ }
+
+ public boolean allowedInSource(Source source) {
+ return source.compareTo(minLevel) >= 0 &&
+ source.compareTo(maxLevel) <= 0;
+ }
+
+ public Fragment fragment(String sourceName) {
+ Assert.checkNonNull(optFragment);
+ return optKind == DiagKind.NORMAL ?
+ Fragments.FeatureNotSupportedInSource(optFragment, sourceName, minLevel.name) :
+ Fragments.FeatureNotSupportedInSourcePlural(optFragment, sourceName, minLevel.name);
+ }
+
+ public Error error(String sourceName) {
+ Assert.checkNonNull(optFragment);
+ return optKind == DiagKind.NORMAL ?
+ Errors.FeatureNotSupportedInSource(optFragment, sourceName, minLevel.name) :
+ Errors.FeatureNotSupportedInSourcePlural(optFragment, sourceName, minLevel.name);
+ }
}
- public boolean allowMethodReferences() {
- return compareTo(JDK1_8) >= 0;
- }
- public boolean allowDefaultMethods() {
- return compareTo(JDK1_8) >= 0;
- }
- public boolean allowStaticInterfaceMethods() {
- return compareTo(JDK1_8) >= 0;
- }
- public boolean allowStrictMethodClashCheck() {
- return compareTo(JDK1_8) >= 0;
- }
- public boolean allowEffectivelyFinalInInnerClasses() {
- return compareTo(JDK1_8) >= 0;
- }
- public boolean allowTypeAnnotations() {
- return compareTo(JDK1_8) >= 0;
- }
- public boolean allowAnnotationsAfterTypeParams() {
- return compareTo(JDK1_8) >= 0;
- }
- public boolean allowRepeatedAnnotations() {
- return compareTo(JDK1_8) >= 0;
- }
- public boolean allowIntersectionTypesInCast() {
- return compareTo(JDK1_8) >= 0;
- }
- public boolean allowGraphInference() {
- return compareTo(JDK1_8) >= 0;
- }
- public boolean allowFunctionalInterfaceMostSpecific() {
- return compareTo(JDK1_8) >= 0;
- }
- public boolean allowPostApplicabilityVarargsAccessCheck() {
- return compareTo(JDK1_8) >= 0;
- }
- public boolean mapCapturesToBounds() {
- return compareTo(JDK1_8) < 0;
- }
- public boolean allowPrivateSafeVarargs() {
- return compareTo(JDK1_9) >= 0;
- }
- public boolean allowDiamondWithAnonymousClassCreation() {
- return compareTo(JDK1_9) >= 0;
- }
- public boolean allowUnderscoreIdentifier() {
- return compareTo(JDK1_8) <= 0;
- }
- public boolean allowPrivateInterfaceMethods() { return compareTo(JDK1_9) >= 0; }
- public boolean allowLocalVariableTypeInference() { return compareTo(JDK1_10) >= 0; }
+
public static SourceVersion toSourceVersion(Source source) {
switch(source) {
case JDK1_2:
@@ -236,17 +235,17 @@
return RELEASE_3;
case JDK1_4:
return RELEASE_4;
- case JDK1_5:
+ case JDK5:
return RELEASE_5;
- case JDK1_6:
+ case JDK6:
return RELEASE_6;
- case JDK1_7:
+ case JDK7:
return RELEASE_7;
- case JDK1_8:
+ case JDK8:
return RELEASE_8;
- case JDK1_9:
+ case JDK9:
return RELEASE_9;
- case JDK1_10:
+ case JDK10:
return RELEASE_10;
default:
return null;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Tue Dec 05 10:28:45 2017 +0000
@@ -35,6 +35,7 @@
import javax.lang.model.element.ElementVisitor;
import com.sun.tools.javac.code.Scope.WriteableScope;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.Completer;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
@@ -468,7 +469,7 @@
scope.enter(errSymbol);
Source source = Source.instance(context);
- if (source.allowModules()) {
+ if (Feature.MODULES.allowedInSource(source)) {
java_base = enterModule(names.java_base);
//avoid completing java.base during the Symtab initialization
java_base.completer = Completer.NULL_COMPLETER;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Tue Dec 05 10:28:45 2017 +0000
@@ -41,6 +41,7 @@
import com.sun.tools.javac.code.Attribute.RetentionPolicy;
import com.sun.tools.javac.code.Lint.LintCategory;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
import com.sun.tools.javac.comp.AttrContext;
@@ -113,9 +114,9 @@
syms = Symtab.instance(context);
names = Names.instance(context);
Source source = Source.instance(context);
- allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast();
- allowDefaultMethods = source.allowDefaultMethods();
- mapCapturesToBounds = source.mapCapturesToBounds();
+ allowObjectToPrimitiveCast = Feature.OBJECT_TO_PRIMITIVE_CAST.allowedInSource(source);
+ allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source);
+ mapCapturesToBounds = Feature.MAP_CAPTURES_TO_BOUNDS.allowedInSource(source);
chk = Check.instance(context);
enter = Enter.instance(context);
capturedName = names.fromString("<captured wildcard>");
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java Tue Dec 05 10:28:45 2017 +0000
@@ -29,6 +29,7 @@
import com.sun.source.tree.LambdaExpressionTree;
import com.sun.tools.javac.code.Source;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
@@ -128,7 +129,7 @@
String findOpt = options.get("find");
//parse modes
Source source = Source.instance(context);
- allowDiamondWithAnonymousClassCreation = source.allowDiamondWithAnonymousClassCreation();
+ allowDiamondWithAnonymousClassCreation = Feature.DIAMOND_WITH_ANONYMOUS_CLASS_CREATION.allowedInSource(source);
analyzerModes = AnalyzerMode.getAnalyzerModes(findOpt, source);
}
@@ -137,17 +138,17 @@
* the {@code -XDfind} option.
*/
enum AnalyzerMode {
- DIAMOND("diamond", Source::allowDiamond),
- LAMBDA("lambda", Source::allowLambda),
- METHOD("method", Source::allowGraphInference),
- LOCAL("local", Source::allowLocalVariableTypeInference);
+ DIAMOND("diamond", Feature.DIAMOND),
+ LAMBDA("lambda", Feature.LAMBDA),
+ METHOD("method", Feature.GRAPH_INFERENCE),
+ LOCAL("local", Feature.LOCAL_VARIABLE_TYPE_INFERENCE);
final String opt;
- final Predicate<Source> sourceFilter;
+ final Feature feature;
- AnalyzerMode(String opt, Predicate<Source> sourceFilter) {
+ AnalyzerMode(String opt, Feature feature) {
this.opt = opt;
- this.sourceFilter = sourceFilter;
+ this.feature = feature;
}
/**
@@ -168,7 +169,7 @@
for (AnalyzerMode mode : values()) {
if (modes.contains(mode.opt)) {
res.add(mode);
- } else if (modes.contains("-" + mode.opt) || !mode.sourceFilter.test(source)) {
+ } else if (modes.contains("-" + mode.opt) || !mode.feature.allowedInSource(source)) {
res.remove(mode);
}
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Tue Dec 05 10:28:45 2017 +0000
@@ -30,10 +30,12 @@
import com.sun.tools.javac.code.Attribute.TypeCompound;
import com.sun.tools.javac.code.Kinds.KindSelector;
import com.sun.tools.javac.code.Scope.WriteableScope;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
import com.sun.tools.javac.comp.Check.CheckContext;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
+import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.TreeInfo;
@@ -121,7 +123,7 @@
theUnfinishedDefaultValue = new Attribute.Error(syms.errType);
Source source = Source.instance(context);
- allowRepeatedAnnos = source.allowRepeatedAnnotations();
+ allowRepeatedAnnos = Feature.REPEATED_ANNOTATIONS.allowedInSource(source);
sourceName = source.name;
blockCount = 1;
@@ -344,7 +346,7 @@
if (annotated.containsKey(a.type.tsym)) {
if (!allowRepeatedAnnos) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, a.pos(), Errors.RepeatableAnnotationsNotSupportedInSource(sourceName));
+ log.error(DiagnosticFlag.SOURCE_LEVEL, a.pos(), Feature.REPEATED_ANNOTATIONS.error(sourceName));
}
ListBuffer<T> l = annotated.get(a.type.tsym);
l = l.append(c);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Tue Dec 05 10:28:45 2017 +0000
@@ -38,6 +38,7 @@
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Scope.WriteableScope;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.TypeMetadata.Annotations;
@@ -150,12 +151,12 @@
Options options = Options.instance(context);
Source source = Source.instance(context);
- allowStringsInSwitch = source.allowStringsInSwitch();
- allowPoly = source.allowPoly();
- allowTypeAnnos = source.allowTypeAnnotations();
- allowLambda = source.allowLambda();
- allowDefaultMethods = source.allowDefaultMethods();
- allowStaticInterfaceMethods = source.allowStaticInterfaceMethods();
+ allowStringsInSwitch = Feature.STRINGS_IN_SWITCH.allowedInSource(source);
+ allowPoly = Feature.POLY.allowedInSource(source);
+ allowTypeAnnos = Feature.TYPE_ANNOTATIONS.allowedInSource(source);
+ allowLambda = Feature.LAMBDA.allowedInSource(source);
+ allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source);
+ allowStaticInterfaceMethods = Feature.STATIC_INTERFACE_METHODS.allowedInSource(source);
sourceName = source.name;
useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
@@ -1392,7 +1393,7 @@
boolean enumSwitch = (seltype.tsym.flags() & Flags.ENUM) != 0;
boolean stringSwitch = types.isSameType(seltype, syms.stringType);
if (stringSwitch && !allowStringsInSwitch) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, tree.selector.pos(), Errors.StringSwitchNotSupportedInSource(sourceName));
+ log.error(DiagnosticFlag.SOURCE_LEVEL, tree.selector.pos(), Feature.STRINGS_IN_SWITCH.error(sourceName));
}
if (!enumSwitch && !stringSwitch)
seltype = chk.checkType(tree.selector.pos(), seltype, syms.intType);
@@ -3667,7 +3668,7 @@
}
if (!allowStaticInterfaceMethods && sitesym.isInterface() &&
sym.isStatic() && sym.kind == MTH) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, tree.pos(), Errors.StaticIntfMethodInvokeNotSupportedInSource(sourceName));
+ log.error(DiagnosticFlag.SOURCE_LEVEL, tree.pos(), Feature.STATIC_INTERFACE_METHODS_INVOKE.error(sourceName));
}
} else if (sym.kind != ERR &&
(sym.flags() & STATIC) != 0 &&
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Tue Dec 05 10:28:45 2017 +0000
@@ -33,6 +33,7 @@
import com.sun.tools.javac.code.Attribute.Compound;
import com.sun.tools.javac.code.Directive.ExportsDirective;
import com.sun.tools.javac.code.Directive.RequiresDirective;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
@@ -127,11 +128,6 @@
fileManager = context.get(JavaFileManager.class);
source = Source.instance(context);
- allowSimplifiedVarargs = source.allowSimplifiedVarargs();
- allowDefaultMethods = source.allowDefaultMethods();
- allowStrictMethodClashCheck = source.allowStrictMethodClashCheck();
- allowPrivateSafeVarargs = source.allowPrivateSafeVarargs();
- allowDiamondWithAnonymousClassCreation = source.allowDiamondWithAnonymousClassCreation();
warnOnAnyAccessToMembers = options.isSet("warnOnAccessToMembers");
Target target = Target.instance(context);
@@ -156,26 +152,6 @@
deferredLintHandler = DeferredLintHandler.instance(context);
}
- /** Switch: simplified varargs enabled?
- */
- boolean allowSimplifiedVarargs;
-
- /** Switch: default methods enabled?
- */
- boolean allowDefaultMethods;
-
- /** Switch: should unrelated return types trigger a method clash?
- */
- boolean allowStrictMethodClashCheck;
-
- /** Switch: can the @SafeVarargs annotation be applied to private methods?
- */
- boolean allowPrivateSafeVarargs;
-
- /** Switch: can diamond inference be used in anonymous instance creation ?
- */
- boolean allowDiamondWithAnonymousClassCreation;
-
/** Character for synthetic names
*/
char syntheticNameChar;
@@ -256,7 +232,7 @@
* @param pos Position to be used for error reporting.
*/
void warnUnsafeVararg(DiagnosticPosition pos, String key, Object... args) {
- if (lint.isEnabled(LintCategory.VARARGS) && allowSimplifiedVarargs)
+ if (lint.isEnabled(LintCategory.VARARGS) && Feature.SIMPLIFIED_VARARGS.allowedInSource(source))
log.warning(LintCategory.VARARGS, pos, key, args);
}
@@ -814,9 +790,9 @@
t.isErroneous()) {
return checkClassType(tree.clazz.pos(), t, true);
} else {
- if (tree.def != null && !allowDiamondWithAnonymousClassCreation) {
+ if (tree.def != null && !Feature.DIAMOND_WITH_ANONYMOUS_CLASS_CREATION.allowedInSource(source)) {
log.error(DiagnosticFlag.SOURCE_LEVEL, tree.clazz.pos(),
- Errors.CantApplyDiamond1(t, Fragments.DiamondAndAnonClassNotSupportedInSource(source.name)));
+ Errors.CantApplyDiamond1(t, Feature.DIAMOND_WITH_ANONYMOUS_CLASS_CREATION.fragment(source.name)));
}
if (t.tsym.type.getTypeArguments().isEmpty()) {
log.error(tree.clazz.pos(),
@@ -906,7 +882,7 @@
void checkVarargsMethodDecl(Env<AttrContext> env, JCMethodDecl tree) {
MethodSymbol m = tree.sym;
- if (!allowSimplifiedVarargs) return;
+ if (!Feature.SIMPLIFIED_VARARGS.allowedInSource(source)) return;
boolean hasTrustMeAnno = m.attribute(syms.trustMeType.tsym) != null;
Type varargElemType = null;
if (m.isVarArgs()) {
@@ -914,7 +890,7 @@
}
if (hasTrustMeAnno && !isTrustMeAllowedOnMethod(m)) {
if (varargElemType != null) {
- JCDiagnostic msg = allowPrivateSafeVarargs ?
+ JCDiagnostic msg = Feature.PRIVATE_SAFE_VARARGS.allowedInSource(source) ?
diags.fragment(Fragments.VarargsTrustmeOnVirtualVarargs(m)) :
diags.fragment(Fragments.VarargsTrustmeOnVirtualVarargsFinalOnly(m));
log.error(tree,
@@ -942,7 +918,7 @@
return (s.flags() & VARARGS) != 0 &&
(s.isConstructor() ||
(s.flags() & (STATIC | FINAL |
- (allowPrivateSafeVarargs ? PRIVATE : 0) )) != 0);
+ (Feature.PRIVATE_SAFE_VARARGS.allowedInSource(source) ? PRIVATE : 0) )) != 0);
}
Type checkLocalVarType(DiagnosticPosition pos, Type t, Name name) {
@@ -1019,7 +995,7 @@
if (useVarargs) {
Type argtype = owntype.getParameterTypes().last();
if (!types.isReifiable(argtype) &&
- (!allowSimplifiedVarargs ||
+ (!Feature.SIMPLIFIED_VARARGS.allowedInSource(source) ||
sym.baseSymbol().attribute(syms.trustMeType.tsym) == null ||
!isTrustMeAllowedOnMethod(sym))) {
warnUnchecked(env.tree.pos(),
@@ -2489,7 +2465,7 @@
if (m2 == m1) continue;
//if (i) the signature of 'sym' is not a subsignature of m1 (seen as
//a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
- if (!types.isSubSignature(sym.type, types.memberType(site, m2), allowStrictMethodClashCheck) &&
+ if (!types.isSubSignature(sym.type, types.memberType(site, m2), Feature.STRICT_METHOD_CLASH_CHECK.allowedInSource(source)) &&
types.hasSameArgs(m2.erasure(types), m1.erasure(types))) {
sym.flags_field |= CLASH;
if (m1 == sym) {
@@ -2534,7 +2510,7 @@
for (Symbol s : types.membersClosure(site, true).getSymbolsByName(sym.name, cf)) {
//if (i) the signature of 'sym' is not a subsignature of m1 (seen as
//a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
- if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) {
+ if (!types.isSubSignature(sym.type, types.memberType(site, s), Feature.STRICT_METHOD_CLASH_CHECK.allowedInSource(source))) {
if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
log.error(pos,
Errors.NameClashSameErasureNoHide(sym, sym.location(), s, s.location()));
@@ -2634,7 +2610,7 @@
void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site,
MethodSymbol msym1, MethodSymbol msym2) {
if (msym1 != msym2 &&
- allowDefaultMethods &&
+ Feature.DEFAULT_METHODS.allowedInSource(source) &&
lint.isEnabled(LintCategory.OVERLOADS) &&
(msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 &&
(msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Tue Dec 05 10:28:45 2017 +0000
@@ -32,6 +32,7 @@
import com.sun.source.tree.LambdaExpressionTree.BodyKind;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
import com.sun.tools.javac.tree.*;
@@ -291,10 +292,10 @@
rs = Resolve.instance(context);
diags = JCDiagnostic.Factory.instance(context);
Source source = Source.instance(context);
- allowImprovedRethrowAnalysis = source.allowImprovedRethrowAnalysis();
- allowImprovedCatchAnalysis = source.allowImprovedCatchAnalysis();
- allowEffectivelyFinalInInnerClasses = source.allowEffectivelyFinalInInnerClasses();
- enforceThisDotInit = source.enforceThisDotInit();
+ allowImprovedRethrowAnalysis = Feature.IMPROVED_RETHROW_ANALYSIS.allowedInSource(source);
+ allowImprovedCatchAnalysis = Feature.IMPROVED_CATCH_ANALYSIS.allowedInSource(source);
+ allowEffectivelyFinalInInnerClasses = Feature.EFFECTIVELY_FINAL_IN_INNER_CLASSES.allowedInSource(source);
+ enforceThisDotInit = Feature.ENFORCE_THIS_DOT_INIT.allowedInSource(source);
}
/**
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Tue Dec 05 10:28:45 2017 +0000
@@ -25,6 +25,7 @@
package com.sun.tools.javac.comp;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Type.UndetVar.UndetVarListener;
import com.sun.tools.javac.code.Types.TypeMapping;
import com.sun.tools.javac.comp.Attr.CheckMode;
@@ -116,7 +117,8 @@
log = Log.instance(context);
inferenceException = new InferenceException(diags);
Options options = Options.instance(context);
- allowGraphInference = Source.instance(context).allowGraphInference()
+ Source source = Source.instance(context);
+ allowGraphInference = Feature.GRAPH_INFERENCE.allowedInSource(source)
&& options.isUnset("useLegacyInference");
dependenciesFolder = options.get("debug.dumpInferenceGraphsTo");
pendingGraphs = List.nil();
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Tue Dec 05 10:28:45 2017 +0000
@@ -66,6 +66,7 @@
import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.ModuleFinder;
import com.sun.tools.javac.code.Source;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.Completer;
@@ -185,7 +186,7 @@
types = Types.instance(context);
fileManager = context.get(JavaFileManager.class);
source = Source.instance(context);
- allowModules = source.allowModules();
+ allowModules = Feature.MODULES.allowedInSource(source);
Options options = Options.instance(context);
allowAccessIntoSystem = options.isUnset(Option.RELEASE);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Dec 05 10:28:45 2017 +0000
@@ -28,6 +28,7 @@
import com.sun.tools.javac.api.Formattable.LocalizedString;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.comp.Attr.ResultInfo;
@@ -137,15 +138,15 @@
verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
Target target = Target.instance(context);
allowMethodHandles = target.hasMethodHandles();
- allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific();
- allowLocalVariableTypeInference = source.allowLocalVariableTypeInference();
+ allowFunctionalInterfaceMostSpecific = Feature.FUNCTIONAL_INTERFACE_MOST_SPECIFIC.allowedInSource(source);
+ allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source);
checkVarargsAccessAfterResolution =
- source.allowPostApplicabilityVarargsAccessCheck();
+ Feature.POST_APPLICABILITY_VARARGS_ACCESS_CHECK.allowedInSource(source);
polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
inapplicableMethodException = new InapplicableMethodException(diags);
- allowModules = source.allowModules();
+ allowModules = Feature.MODULES.allowedInSource(source);
}
/** error symbols, which are returned when resolution fails
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java Tue Dec 05 10:28:45 2017 +0000
@@ -29,6 +29,7 @@
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Attribute.TypeCompound;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.tree.*;
@@ -94,8 +95,8 @@
make = TreeMaker.instance(context);
resolve = Resolve.instance(context);
Source source = Source.instance(context);
- allowInterfaceBridges = source.allowDefaultMethods();
- allowGraphInference = source.allowGraphInference();
+ allowInterfaceBridges = Feature.DEFAULT_METHODS.allowedInSource(source);
+ allowGraphInference = Feature.GRAPH_INFERENCE.allowedInSource(source);
annotate = Annotate.instance(context);
attr = Attr.instance(context);
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java Tue Dec 05 10:28:45 2017 +0000
@@ -37,6 +37,7 @@
import com.sun.tools.javac.code.Scope.NamedImportScope;
import com.sun.tools.javac.code.Scope.StarImportScope;
import com.sun.tools.javac.code.Scope.WriteableScope;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.util.*;
@@ -137,8 +138,8 @@
typeEnvs = TypeEnvs.instance(context);
dependencies = Dependencies.instance(context);
Source source = Source.instance(context);
- allowTypeAnnos = source.allowTypeAnnotations();
- allowDeprecationOnImport = source.allowDeprecationOnImport();
+ allowTypeAnnos = Feature.TYPE_ANNOTATIONS.allowedInSource(source);
+ allowDeprecationOnImport = Feature.DEPRECATION_ON_IMPORT.allowedInSource(source);
}
/** Switch: support type annotations.
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue Dec 05 10:28:45 2017 +0000
@@ -42,6 +42,7 @@
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
import com.sun.tools.javac.code.*;
@@ -246,8 +247,8 @@
verbose = options.isSet(Option.VERBOSE);
Source source = Source.instance(context);
- allowSimplifiedVarargs = source.allowSimplifiedVarargs();
- allowModules = source.allowModules();
+ allowSimplifiedVarargs = Feature.SIMPLIFIED_VARARGS.allowedInSource(source);
+ allowModules = Feature.MODULES.allowedInSource(source);
saveParameterNames = options.isSet(PARAMETERS);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Tue Dec 05 10:28:45 2017 +0000
@@ -54,6 +54,7 @@
import com.sun.tools.doclint.DocLint;
import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Source;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.file.BaseFileManager;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.jvm.Profile;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Dec 05 10:28:45 2017 +0000
@@ -52,6 +52,7 @@
import com.sun.tools.javac.api.MultiTaskListener;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Lint.LintCategory;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
@@ -684,7 +685,7 @@
if (sep == -1) {
msym = modules.getDefaultModule();
typeName = name;
- } else if (source.allowModules()) {
+ } else if (Feature.MODULES.allowedInSource(source)) {
Name modName = names.fromString(name.substring(0, sep));
msym = moduleFinder.findModule(modName);
@@ -1544,7 +1545,7 @@
env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
compileStates.put(env, CompileState.TRANSTYPES);
- if (source.allowLambda() && scanner.hasLambdas) {
+ if (Feature.LAMBDA.allowedInSource(source) && scanner.hasLambdas) {
if (shouldStop(CompileState.UNLAMBDA))
return;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java Tue Dec 05 10:28:45 2017 +0000
@@ -51,6 +51,7 @@
import com.sun.tools.javac.code.Directive.RequiresDirective;
import com.sun.tools.javac.code.Directive.RequiresFlag;
import com.sun.tools.javac.code.Scope.WriteableScope;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Enter;
@@ -114,7 +115,7 @@
javacTaskImpl = t instanceof JavacTaskImpl ? (JavacTaskImpl) t : null;
log = Log.instance(context);
Source source = Source.instance(context);
- allowModules = source.allowModules();
+ allowModules = Feature.MODULES.allowedInSource(source);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java Tue Dec 05 10:28:45 2017 +0000
@@ -36,10 +36,12 @@
import com.sun.tools.javac.tree.DCTree;
import com.sun.tools.javac.tree.DCTree.DCAttribute;
import com.sun.tools.javac.tree.DCTree.DCDocComment;
+import com.sun.tools.javac.tree.DCTree.DCEndElement;
import com.sun.tools.javac.tree.DCTree.DCEndPosTree;
import com.sun.tools.javac.tree.DCTree.DCErroneous;
import com.sun.tools.javac.tree.DCTree.DCIdentifier;
import com.sun.tools.javac.tree.DCTree.DCReference;
+import com.sun.tools.javac.tree.DCTree.DCStartElement;
import com.sun.tools.javac.tree.DCTree.DCText;
import com.sun.tools.javac.tree.DocTreeMaker;
import com.sun.tools.javac.tree.JCTree;
@@ -50,6 +52,7 @@
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;
import com.sun.tools.javac.util.Position;
+import com.sun.tools.javac.util.StringUtils;
import static com.sun.tools.javac.util.LayoutCharacters.*;
@@ -68,11 +71,14 @@
}
}
+ private enum Phase {PREAMBLE, BODY, POSTAMBLE};
+
final ParserFactory fac;
final DiagnosticSource diagSource;
final Comment comment;
final DocTreeMaker m;
final Names names;
+ final boolean isFileContent;
BreakIterator sentenceBreaker;
@@ -93,17 +99,23 @@
Map<Name, TagParser> tagParsers;
- public DocCommentParser(ParserFactory fac, DiagnosticSource diagSource, Comment comment) {
+ public DocCommentParser(ParserFactory fac, DiagnosticSource diagSource,
+ Comment comment, boolean isFileContent) {
this.fac = fac;
this.diagSource = diagSource;
this.comment = comment;
names = fac.names;
+ this.isFileContent = isFileContent;
m = fac.docTreeMaker;
initTagParsers();
}
+ public DocCommentParser(ParserFactory fac, DiagnosticSource diagSource, Comment comment) {
+ this(fac, diagSource, comment, false);
+ }
+
public DocCommentParser(ParserFactory fac) {
- this(fac, null, null);
+ this(fac, null, null, false);
}
public DCDocComment parse() {
@@ -115,13 +127,22 @@
bp = -1;
nextChar();
- List<DCTree> body = blockContent();
+ List<DCTree> preamble = isFileContent ? blockContent(Phase.PREAMBLE) : List.nil();
+ List<DCTree> body = blockContent(Phase.BODY);
List<DCTree> tags = blockTags();
- int pos = !body.isEmpty()
- ? body.head.pos
- : !tags.isEmpty() ? tags.head.pos : Position.NOPOS;
+ List<DCTree> postamble = isFileContent ? blockContent(Phase.POSTAMBLE) : List.nil();
- DCDocComment dc = m.at(pos).newDocCommentTree(comment, body, tags);
+ int pos = Position.NOPOS;
+ if (!preamble.isEmpty())
+ pos = preamble.head.pos;
+ else if (!body.isEmpty())
+ pos = body.head.pos;
+ else if (!tags.isEmpty())
+ pos = tags.head.pos;
+ else if (!postamble.isEmpty())
+ pos = postamble.head.pos;
+
+ DCDocComment dc = m.at(pos).newDocCommentTree(comment, body, tags, preamble, postamble);
return dc;
}
@@ -133,13 +154,17 @@
}
}
+ protected List<DCTree> blockContent() {
+ return blockContent(Phase.BODY);
+ }
+
/**
* Read block content, consisting of text, html and inline tags.
* Terminated by the end of input, or the beginning of the next block tag:
* i.e. @ as the first non-whitespace character on a line.
*/
@SuppressWarnings("fallthrough")
- protected List<DCTree> blockContent() {
+ protected List<DCTree> blockContent(Phase phase) {
ListBuffer<DCTree> trees = new ListBuffer<>();
textStart = -1;
@@ -160,8 +185,36 @@
case '<':
newline = false;
+ if (isFileContent) {
+ switch (phase) {
+ case PREAMBLE:
+ if (peek("body")) {
+ trees.add(html());
+ if (textStart == -1) {
+ textStart = bp;
+ lastNonWhite = -1;
+ }
+ // mark this as the start, for processing purposes
+ newline = true;
+ break loop;
+ }
+ break;
+ case BODY:
+ if (peek("/body")) {
+ addPendingText(trees, lastNonWhite);
+ break loop;
+ }
+ break;
+ default:
+ // fallthrough
+ }
+ }
addPendingText(trees, bp - 1);
trees.add(html());
+
+ if (phase == Phase.PREAMBLE || phase == Phase.POSTAMBLE) {
+ break; // Ignore newlines after html tags, in the meta content
+ }
if (textStart == -1) {
textStart = bp;
lastNonWhite = -1;
@@ -734,11 +787,37 @@
}
}
+ boolean peek(String s) {
+ final int savedpos = bp;
+ try {
+ if (ch == '<')
+ nextChar();
+
+ if (ch == '/') {
+ if (s.charAt(0) != ch) {
+ return false;
+ } else {
+ s = s.substring(1, s.length());
+ nextChar();
+ }
+ }
+
+ if (isIdentifierStart(ch)) {
+ Name name = readIdentifier();
+ return StringUtils.toLowerCase(name.toString()).equals(s);
+ }
+ return false;
+ } finally {
+ bp = savedpos;
+ ch = buf[bp];
+ }
+ }
+
/**
* Read the start or end of an HTML tag, or an HTML comment
* {@literal <identifier attrs> } or {@literal </identifier> }
*/
- protected DCTree html() {
+ private DCTree html() {
int p = bp;
nextChar();
if (isIdentifierStart(ch)) {
@@ -790,6 +869,19 @@
nextChar();
}
}
+ } else if (isIdentifierStart(ch) && peek("doctype")) {
+ readIdentifier();
+ nextChar();
+ skipWhitespace();
+ int d = bp;
+ while (bp < buflen) {
+ if (ch == '>') {
+ int mark = bp;
+ nextChar();
+ return m.at(d).newDocTypeTree(newString(d, mark));
+ }
+ nextChar();
+ }
}
}
@@ -1316,4 +1408,5 @@
tagParsers.put(names.fromString(p.getTreeKind().tagName), p);
}
+
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Tue Dec 05 10:28:45 2017 +0000
@@ -26,8 +26,11 @@
package com.sun.tools.javac.parser;
import com.sun.tools.javac.code.Source;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
+import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
import java.nio.CharBuffer;
@@ -46,14 +49,6 @@
private static final boolean scannerDebug = false;
- /** Allow binary literals.
- */
- private boolean allowBinaryLiterals;
-
- /** Allow underscores in literals.
- */
- private boolean allowUnderscoresInLiterals;
-
/** The source language setting.
*/
private Source source;
@@ -121,14 +116,24 @@
this.tokens = fac.tokens;
this.source = fac.source;
this.reader = reader;
- this.allowBinaryLiterals = source.allowBinaryLiterals();
- this.allowUnderscoresInLiterals = source.allowUnderscoresInLiterals();
+ }
+
+ private void checkSourceLevel(int pos, Feature feature) {
+ if (!feature.allowedInSource(source)) {
+ lexError(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
+ }
}
/** Report an error at the given position using the provided arguments.
*/
- protected void lexError(int pos, String key, Object... args) {
- log.error(pos, key, args);
+ protected void lexError(int pos, JCDiagnostic.Error key) {
+ log.error(pos, key);
+ tk = TokenKind.ERROR;
+ errPos = pos;
+ }
+
+ protected void lexError(DiagnosticFlag flags, int pos, JCDiagnostic.Error key) {
+ log.error(flags, pos, key);
tk = TokenKind.ERROR;
errPos = pos;
}
@@ -175,7 +180,7 @@
case '\\':
reader.putChar('\\', true); break;
default:
- lexError(reader.bp, "illegal.esc.char");
+ lexError(reader.bp, Errors.IllegalEscChar);
}
}
} else if (reader.bp != reader.buflen) {
@@ -190,17 +195,14 @@
if (reader.ch != '_') {
reader.putChar(false);
} else {
- if (!allowUnderscoresInLiterals) {
- lexError(pos, "unsupported.underscore.lit", source.name);
- allowUnderscoresInLiterals = true;
- }
+ checkSourceLevel(pos, Feature.UNDERSCORES_IN_LITERALS);
}
saveCh = reader.ch;
savePos = reader.bp;
reader.scanChar();
} while (reader.digit(pos, digitRadix) >= 0 || reader.ch == '_');
if (saveCh == '_')
- lexError(savePos, "illegal.underscore");
+ lexError(savePos, Errors.IllegalUnderscore);
}
/** Read fractional part of hexadecimal floating point number.
@@ -216,11 +218,11 @@
if (reader.digit(pos, 10) >= 0) {
scanDigits(pos, 10);
if (!hexFloatsWork)
- lexError(pos, "unsupported.cross.fp.lit");
+ lexError(pos, Errors.UnsupportedCrossFpLit);
} else
- lexError(pos, "malformed.fp.lit");
+ lexError(pos, Errors.MalformedFpLit);
} else {
- lexError(pos, "malformed.fp.lit");
+ lexError(pos, Errors.MalformedFpLit);
}
if (reader.ch == 'f' || reader.ch == 'F') {
reader.putChar(true);
@@ -254,7 +256,7 @@
scanDigits(pos, 10);
return;
}
- lexError(pos, "malformed.fp.lit");
+ lexError(pos, Errors.MalformedFpLit);
reader.sp = sp1;
}
}
@@ -287,14 +289,14 @@
scanDigits(pos, 16);
}
if (!seendigit)
- lexError(pos, "invalid.hex.number");
+ lexError(pos, Errors.InvalidHexNumber);
else
scanHexExponentAndSuffix(pos);
}
private void skipIllegalUnderscores() {
if (reader.ch == '_') {
- lexError(reader.bp, "illegal.underscore");
+ lexError(reader.bp, Errors.IllegalUnderscore);
while (reader.ch == '_')
reader.scanChar();
}
@@ -329,10 +331,10 @@
if (!seenValidDigit) {
switch (radix) {
case 2:
- lexError(pos, "invalid.binary.number");
+ lexError(pos, Errors.InvalidBinaryNumber);
break;
case 16:
- lexError(pos, "invalid.hex.number");
+ lexError(pos, Errors.InvalidHexNumber);
break;
}
}
@@ -504,10 +506,7 @@
skipIllegalUnderscores();
scanNumber(pos, 16);
} else if (reader.ch == 'b' || reader.ch == 'B') {
- if (!allowBinaryLiterals) {
- lexError(pos, "unsupported.binary.lit", source.name);
- allowBinaryLiterals = true;
- }
+ checkSourceLevel(pos, Feature.BINARY_LITERALS);
reader.scanChar();
skipIllegalUnderscores();
scanNumber(pos, 2);
@@ -519,7 +518,7 @@
reader.scanChar();
} while (reader.ch == '_');
if (reader.digit(pos, 10) < 0) {
- lexError(savePos, "illegal.underscore");
+ lexError(savePos, Errors.IllegalUnderscore);
}
}
scanNumber(pos, 8);
@@ -542,7 +541,7 @@
reader.putChar('.');
tk = TokenKind.ELLIPSIS;
} else {
- lexError(savePos, "illegal.dot");
+ lexError(savePos, Errors.IllegalDot);
}
} else {
tk = TokenKind.DOT;
@@ -600,7 +599,7 @@
comments = addComment(comments, processComment(pos, reader.bp, style));
break;
} else {
- lexError(pos, "unclosed.comment");
+ lexError(pos, Errors.UnclosedComment);
break loop;
}
} else if (reader.ch == '=') {
@@ -613,17 +612,17 @@
case '\'':
reader.scanChar();
if (reader.ch == '\'') {
- lexError(pos, "empty.char.lit");
+ lexError(pos, Errors.EmptyCharLit);
reader.scanChar();
} else {
if (reader.ch == CR || reader.ch == LF)
- lexError(pos, "illegal.line.end.in.char.lit");
+ lexError(pos, Errors.IllegalLineEndInCharLit);
scanLitChar(pos);
if (reader.ch == '\'') {
reader.scanChar();
tk = TokenKind.CHARLITERAL;
} else {
- lexError(pos, "unclosed.char.lit");
+ lexError(pos, Errors.UnclosedCharLit);
}
}
break loop;
@@ -635,7 +634,7 @@
tk = TokenKind.STRINGLITERAL;
reader.scanChar();
} else {
- lexError(pos, "unclosed.str.lit");
+ lexError(pos, Errors.UnclosedStrLit);
}
break loop;
default:
@@ -676,7 +675,7 @@
String.format("%s", reader.ch) :
String.format("\\u%04x", (int)reader.ch);
}
- lexError(pos, "illegal.char", arg);
+ lexError(pos, Errors.IllegalChar(arg));
reader.scanChar();
}
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Dec 05 10:28:45 2017 +0000
@@ -26,12 +26,15 @@
package com.sun.tools.javac.parser;
import java.util.*;
+import java.util.function.Function;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
import com.sun.source.tree.ModuleTree.ModuleKind;
import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.parser.Tokens.*;
import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
import com.sun.tools.javac.resources.CompilerProperties;
@@ -41,6 +44,7 @@
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.tools.javac.util.JCDiagnostic.Error;
import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
@@ -163,23 +167,7 @@
this.log = fac.log;
this.names = fac.names;
this.source = fac.source;
- this.allowTWR = source.allowTryWithResources();
- this.allowEffectivelyFinalVariablesInTWR =
- source.allowEffectivelyFinalVariablesInTryWithResources();
- this.allowDiamond = source.allowDiamond();
- this.allowMulticatch = source.allowMulticatch();
this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
- this.allowLambda = source.allowLambda();
- this.allowMethodReferences = source.allowMethodReferences();
- this.allowDefaultMethods = source.allowDefaultMethods();
- this.allowStaticInterfaceMethods = source.allowStaticInterfaceMethods();
- this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast();
- this.allowTypeAnnotations = source.allowTypeAnnotations();
- this.allowModules = source.allowModules();
- this.allowAnnotationsAfterTypeParams = source.allowAnnotationsAfterTypeParams();
- this.allowUnderscoreIdentifier = source.allowUnderscoreIdentifier();
- this.allowPrivateInterfaceMethods = source.allowPrivateInterfaceMethods();
- this.allowLocalVariableTypeInference = source.allowLocalVariableTypeInference();
this.keepDocComments = keepDocComments;
this.parseModuleInfo = parseModuleInfo;
docComments = newDocCommentTable(keepDocComments, fac);
@@ -198,54 +186,10 @@
return keepDocComments ? new LazyDocCommentTable(fac) : null;
}
- /** Switch: Should diamond operator be recognized?
- */
- boolean allowDiamond;
-
- /** Switch: Should multicatch clause be accepted?
- */
- boolean allowMulticatch;
-
- /** Switch: should we recognize try-with-resources?
- */
- boolean allowTWR;
-
- /** Switch: should we allow (effectively) final variables as resources in try-with-resources?
- */
- boolean allowEffectivelyFinalVariablesInTWR;
-
/** Switch: should we fold strings?
*/
boolean allowStringFolding;
- /** Switch: should we recognize lambda expressions?
- */
- boolean allowLambda;
-
- /** Switch: should we allow method/constructor references?
- */
- boolean allowMethodReferences;
-
- /** Switch: should we recognize modules?
- */
- boolean allowModules;
-
- /** Switch: should we allow default methods in interfaces?
- */
- boolean allowDefaultMethods;
-
- /** Switch: should we allow static methods in interfaces?
- */
- boolean allowStaticInterfaceMethods;
-
- /** Switch: should we allow private (instance) methods in interfaces?
- */
- boolean allowPrivateInterfaceMethods;
-
- /** Switch: should we allow intersection types in cast?
- */
- boolean allowIntersectionTypesInCast;
-
/** Switch: should we keep docComments?
*/
boolean keepDocComments;
@@ -254,27 +198,11 @@
*/
boolean keepLineMap;
- /** Switch: should we recognize type annotations?
- */
- boolean allowTypeAnnotations;
-
- /** Switch: should we allow annotations after the method type parameters?
- */
- boolean allowAnnotationsAfterTypeParams;
-
- /** Switch: should we allow '_' as an identifier?
- */
- boolean allowUnderscoreIdentifier;
-
/** Switch: is "this" allowed as an identifier?
* This is needed to parse receiver types.
*/
boolean allowThisIdent;
- /** Switch: is local variable inference allowed?
- */
- boolean allowLocalVariableTypeInference;
-
/** The type of the method receiver, as specified by a first "this" parameter.
*/
JCVariableDecl receiverParam;
@@ -628,7 +556,7 @@
} else if (token.kind == THIS) {
if (allowThisIdent) {
// Make sure we're using a supported source version.
- checkTypeAnnotations();
+ checkSourceLevel(Feature.TYPE_ANNOTATIONS);
Name name = token.name();
nextToken();
return name;
@@ -638,7 +566,7 @@
return names.error;
}
} else if (token.kind == UNDERSCORE) {
- if (allowUnderscoreIdentifier) {
+ if (Feature.UNDERSCORE_IDENTIFIER.allowedInSource(source)) {
warning(token.pos, "underscore.as.identifier");
} else {
error(token.pos, "underscore.as.identifier");
@@ -1170,7 +1098,7 @@
int pos1 = pos;
List<JCExpression> targets = List.of(t = parseType());
while (token.kind == AMP) {
- checkIntersectionTypesInCast();
+ checkSourceLevel(Feature.INTERSECTION_TYPES_IN_CAST);
accept(AMP);
targets = targets.prepend(parseType());
}
@@ -1771,7 +1699,7 @@
}
JCExpression lambdaExpressionOrStatementRest(List<JCVariableDecl> args, int pos) {
- checkLambda();
+ checkSourceLevel(Feature.LAMBDA);
accept(ARROW);
return token.kind == LBRACE ?
@@ -1890,7 +1818,7 @@
if (token.kind == LT) {
nextToken();
if (token.kind == GT && diamondAllowed) {
- checkDiamond();
+ checkSourceLevel(Feature.DIAMOND);
mode |= DIAMOND;
nextToken();
return List.nil();
@@ -2065,7 +1993,7 @@
}
JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
- checkMethodReferences();
+ checkSourceLevel(Feature.METHOD_REFERENCES);
mode = EXPR;
List<JCExpression> typeArgs = null;
if (token.kind == LT) {
@@ -2568,7 +2496,7 @@
nextToken();
List<JCTree> resources = List.nil();
if (token.kind == LPAREN) {
- checkTryWithResources();
+ checkSourceLevel(Feature.TRY_WITH_RESOURCES);
nextToken();
resources = resources();
accept(RPAREN);
@@ -2584,7 +2512,7 @@
}
} else {
if (resources.isEmpty()) {
- if (allowTWR) {
+ if (Feature.TRY_WITH_RESOURCES.allowedInSource(source)) {
error(pos, "try.without.catch.finally.or.resource.decls");
} else {
error(pos, "try.without.catch.or.finally");
@@ -2701,7 +2629,7 @@
ListBuffer<JCExpression> catchTypes = new ListBuffer<>();
catchTypes.add(parseType());
while (token.kind == BAR) {
- checkMulticatch();
+ checkSourceLevel(Feature.MULTICATCH);
nextToken();
// Instead of qualident this is now parseType.
// But would that allow too much, e.g. arrays or generics?
@@ -2870,7 +2798,7 @@
case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
case STRICTFP : flag = Flags.STRICTFP; break;
case MONKEYS_AT : flag = Flags.ANNOTATION; break;
- case DEFAULT : checkDefaultMethods(); flag = Flags.DEFAULT; break;
+ case DEFAULT : checkSourceLevel(Feature.DEFAULT_METHODS); flag = Flags.DEFAULT; break;
case ERROR : flag = 0; nextToken(); break;
default: break loop;
}
@@ -2914,7 +2842,7 @@
JCAnnotation annotation(int pos, Tag kind) {
// accept(AT); // AT consumed by caller
if (kind == Tag.TYPE_ANNOTATION) {
- checkTypeAnnotations();
+ checkSourceLevel(Feature.TYPE_ANNOTATIONS);
}
JCTree ident = qualident(false);
List<JCExpression> fieldValues = annotationFieldValuesOpt();
@@ -3028,7 +2956,7 @@
boolean localDecl)
{
JCVariableDecl head = variableDeclaratorRest(pos, mods, type, name, reqInit, dc, localDecl);
- boolean implicit = allowLocalVariableTypeInference && head.vartype == null;
+ boolean implicit = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && head.vartype == null;
vdefs.append(head);
while (token.kind == COMMA) {
if (implicit) {
@@ -3066,7 +2994,7 @@
else if (reqInit) syntaxError(token.pos, "expected", EQ);
JCTree elemType = TreeInfo.innermostType(type, true);
int startPos = Position.NOPOS;
- if (allowLocalVariableTypeInference && elemType.hasTag(IDENT)) {
+ if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && elemType.hasTag(IDENT)) {
Name typeName = ((JCIdent)elemType).name;
if (isRestrictedLocalVarTypeName(typeName)) {
if (type.hasTag(TYPEARRAY)) {
@@ -3100,7 +3028,7 @@
}
boolean isRestrictedLocalVarTypeName(Name name) {
- return allowLocalVariableTypeInference && name == names.var;
+ return Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && name == names.var;
}
/** VariableDeclaratorId = Ident BracketsOpt
@@ -3176,7 +3104,7 @@
JCModifiers mods = toP(F.at(startPos).Modifiers(Flags.FINAL));
return variableDeclaratorRest(token.pos, mods, t, ident(), true, null, true);
} else {
- checkVariableInTryWithResources(startPos);
+ checkSourceLevel(Feature.EFFECTIVELY_FINAL_VARIABLES_IN_TRY_WITH_RESOURCES);
if (!t.hasTag(IDENT) && !t.hasTag(SELECT)) {
log.error(t.pos(), Errors.TryWithResourcesExprNeedsVar);
}
@@ -3278,10 +3206,7 @@
JCModuleDecl moduleDecl(JCModifiers mods, ModuleKind kind, Comment dc) {
int pos = token.pos;
- if (!allowModules) {
- log.error(pos, Errors.ModulesNotSupportedInSource(source.name));
- allowModules = true;
- }
+ checkSourceLevel(Feature.MODULES);
nextToken();
JCExpression name = qualident(false);
@@ -3700,7 +3625,7 @@
List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
if (annosAfterParams.nonEmpty()) {
- checkAnnotationsAfterTypeParams(annosAfterParams.head.pos);
+ checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS);
mods.annotations = mods.annotations.appendList(annosAfterParams);
if (mods.pos == Position.NOPOS)
mods.pos = mods.annotations.head.pos;
@@ -3768,10 +3693,10 @@
Comment dc) {
if (isInterface) {
if ((mods.flags & Flags.STATIC) != 0) {
- checkStaticInterfaceMethods();
+ checkSourceLevel(Feature.STATIC_INTERFACE_METHODS);
}
if ((mods.flags & Flags.PRIVATE) != 0) {
- checkPrivateInterfaceMethods();
+ checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS);
}
}
JCVariableDecl prevReceiverParam = this.receiverParam;
@@ -4226,64 +4151,13 @@
}
}
- void checkDiamond() {
- if (!allowDiamond) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.DiamondNotSupportedInSource(source.name));
- }
- }
- void checkMulticatch() {
- if (!allowMulticatch) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.MulticatchNotSupportedInSource(source.name));
- }
- }
- void checkTryWithResources() {
- if (!allowTWR) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.TryWithResourcesNotSupportedInSource(source.name));
- }
- }
- void checkVariableInTryWithResources(int startPos) {
- if (!allowEffectivelyFinalVariablesInTWR) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, startPos, Errors.VarInTryWithResourcesNotSupportedInSource(source.name));
- }
- }
- void checkLambda() {
- if (!allowLambda) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.LambdaNotSupportedInSource(source.name));
- }
+ void checkSourceLevel(Feature feature) {
+ checkSourceLevel(token.pos, feature);
}
- void checkMethodReferences() {
- if (!allowMethodReferences) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.MethodReferencesNotSupportedInSource(source.name));
- }
- }
- void checkDefaultMethods() {
- if (!allowDefaultMethods) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.DefaultMethodsNotSupportedInSource(source.name));
- }
- }
- void checkIntersectionTypesInCast() {
- if (!allowIntersectionTypesInCast) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.IntersectionTypesInCastNotSupportedInSource(source.name));
- }
- }
- void checkStaticInterfaceMethods() {
- if (!allowStaticInterfaceMethods) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.StaticIntfMethodsNotSupportedInSource(source.name));
- }
- }
- void checkTypeAnnotations() {
- if (!allowTypeAnnotations) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.TypeAnnotationsNotSupportedInSource(source.name));
- }
- }
- void checkPrivateInterfaceMethods() {
- if (!allowPrivateInterfaceMethods) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, CompilerProperties.Errors.PrivateIntfMethodsNotSupportedInSource(source.name));
- }
- }
- protected void checkAnnotationsAfterTypeParams(int pos) {
- if (!allowAnnotationsAfterTypeParams) {
- log.error(DiagnosticFlag.SOURCE_LEVEL, pos, Errors.AnnotationsAfterTypeParamsNotSupportedInSource(source.name));
+
+ protected void checkSourceLevel(int pos, Feature feature) {
+ if (!feature.allowedInSource(source)) {
+ log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
}
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Tue Dec 05 10:28:45 2017 +0000
@@ -53,6 +53,7 @@
import com.sun.tools.javac.api.MultiTaskListener;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.ClassType;
import com.sun.tools.javac.code.Types;
@@ -116,7 +117,6 @@
private final boolean fatalErrors;
private final boolean werror;
private final boolean showResolveErrors;
- private final boolean allowModules;
private final JavacFiler filer;
private final JavacMessager messager;
@@ -233,8 +233,6 @@
initialCompleter = ClassFinder.instance(context).getCompleter();
chk = Check.instance(context);
initProcessorLoader();
-
- allowModules = source.allowModules();
}
public void setProcessors(Iterable<? extends Processor> processors) {
@@ -770,7 +768,7 @@
if (psi.processorIterator.hasNext()) {
ProcessorState ps = new ProcessorState(psi.processorIterator.next(),
- log, source, allowModules,
+ log, source, Feature.MODULES.allowedInSource(source),
JavacProcessingEnvironment.this);
psi.procStateList.add(ps);
return ps;
@@ -837,7 +835,7 @@
for(TypeElement a : annotationsPresent) {
ModuleElement mod = elementUtils.getModuleOf(a);
- String moduleSpec = allowModules && mod != null ? mod.getQualifiedName() + "/" : "";
+ String moduleSpec = Feature.MODULES.allowedInSource(source) && mod != null ? mod.getQualifiedName() + "/" : "";
unmatchedAnnotations.put(moduleSpec + a.getQualifiedName().toString(),
a);
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Dec 05 10:28:45 2017 +0000
@@ -2601,38 +2601,87 @@
({3})
########################################
-# Diagnostics for language feature changes
+# Diagnostics for language feature changes.
+# Such diagnostics have a common template which can be customized by using a feature
+# diagnostic fragment (one of those given below).
########################################
-# 0: string
-compiler.err.modules.not.supported.in.source=\
- modules are not supported in -source {0}\n\
- (use -source 9 or higher to enable modules)
-
-# 0: string
-compiler.misc.diamond.and.anon.class.not.supported.in.source=\
- cannot use ''<>'' with anonymous inner classes in -source {0}\n\
- (use -source 9 or higher to enable ''<>'' with anonymous inner classes)
-
-# 0: string
-compiler.err.unsupported.binary.lit=\
- binary literals are not supported in -source {0}\n\
- (use -source 7 or higher to enable binary literals)
-
-# 0: string
-compiler.err.unsupported.underscore.lit=\
- underscores in literals are not supported in -source {0}\n\
- (use -source 7 or higher to enable underscores in literals)
-
-# 0: string
-compiler.err.try.with.resources.not.supported.in.source=\
- try-with-resources is not supported in -source {0}\n\
- (use -source 7 or higher to enable try-with-resources)
-
-# 0: string
-compiler.err.var.in.try.with.resources.not.supported.in.source=\
- variables in try-with-resources not supported in -source {0}\n\
- (use -source 9 or higher to enable variables in try-with-resources)
+# 0: message segment (feature), 1: string (found version), 2: string (expected version)
+compiler.err.feature.not.supported.in.source=\
+ {0} is not supported in -source {1}\n\
+ (use -source {2} or higher to enable {0})
+
+# 0: message segment (feature), 1: string (found version), 2: string (expected version)
+compiler.err.feature.not.supported.in.source.plural=\
+ {0} are not supported in -source {1}\n\
+ (use -source {2} or higher to enable {0})
+
+# 0: message segment (feature), 1: string (found version), 2: string (expected version)
+compiler.misc.feature.not.supported.in.source=\
+ {0} is not supported in -source {1}\n\
+ (use -source {2} or higher to enable {0})
+
+# 0: message segment (feature), 1: string (found version), 2: string (expected version)
+compiler.misc.feature.not.supported.in.source.plural=\
+ {0} are not supported in -source {1}\n\
+ (use -source {2} or higher to enable {0})
+
+compiler.misc.feature.modules=\
+ modules
+
+compiler.misc.feature.diamond.and.anon.class=\
+ ''<>'' with anonymous inner classes
+
+compiler.misc.feature.binary.lit=\
+ binary literals
+
+compiler.misc.feature.underscore.lit=\
+ underscores in literals
+
+compiler.misc.feature.try.with.resources=\
+ try-with-resources
+
+compiler.misc.feature.var.in.try.with.resources=\
+ variables in try-with-resources
+
+compiler.misc.feature.type.annotations=\
+ type annotations
+
+compiler.misc.feature.annotations.after.type.params=\
+ annotations after method type parameters
+
+compiler.misc.feature.repeatable.annotations=\
+ repeated annotations
+
+compiler.misc.feature.diamond=\
+ diamond operator
+
+compiler.misc.feature.multicatch=\
+ multi-catch statements
+
+compiler.misc.feature.string.switch=\
+ strings in switch
+
+compiler.misc.feature.lambda=\
+ lambda expressions
+
+compiler.misc.feature.method.references=\
+ method references
+
+compiler.misc.feature.default.methods=\
+ default methods
+
+compiler.misc.feature.intersection.types.in.cast=\
+ intersection types
+
+compiler.misc.feature.static.intf.methods=\
+ static interface methods
+
+compiler.misc.feature.static.intf.method.invoke=\
+ static interface method invocations
+
+compiler.misc.feature.private.intf.methods=\
+ private interface methods
compiler.warn.underscore.as.identifier=\
as of release 9, ''_'' is a keyword, and may not be used as an identifier
@@ -2694,71 +2743,6 @@
compiler.err.no.annotations.on.dot.class=\
no annotations are allowed in the type of a class literal
-# 0: string
-compiler.err.type.annotations.not.supported.in.source=\
- type annotations are not supported in -source {0}\n\
-(use -source 8 or higher to enable type annotations)
-
-# 0: string
-compiler.err.annotations.after.type.params.not.supported.in.source=\
- annotations after method type parameters are not supported in -source {0}\n\
-(use -source 8 or higher to enable annotations after method type parameters)
-
-# 0: string
-compiler.err.repeatable.annotations.not.supported.in.source=\
- repeated annotations are not supported in -source {0}\n\
-(use -source 8 or higher to enable repeated annotations)
-
-# 0: string
-compiler.err.diamond.not.supported.in.source=\
- diamond operator is not supported in -source {0}\n\
- (use -source 7 or higher to enable diamond operator)
-
-# 0: string
-compiler.err.multicatch.not.supported.in.source=\
- multi-catch statement is not supported in -source {0}\n\
- (use -source 7 or higher to enable multi-catch statement)
-
-# 0: string
-compiler.err.string.switch.not.supported.in.source=\
- strings in switch are not supported in -source {0}\n\
- (use -source 7 or higher to enable strings in switch)
-
-# 0: string
-compiler.err.lambda.not.supported.in.source=\
- lambda expressions are not supported in -source {0}\n\
- (use -source 8 or higher to enable lambda expressions)
-
-# 0: string
-compiler.err.method.references.not.supported.in.source=\
- method references are not supported in -source {0}\n\
- (use -source 8 or higher to enable method references)
-
-# 0: string
-compiler.err.default.methods.not.supported.in.source=\
- default methods are not supported in -source {0}\n\
- (use -source 8 or higher to enable default methods)
-
-# 0: string
-compiler.err.intersection.types.in.cast.not.supported.in.source=\
- intersection types in cast are not supported in -source {0}\n\
- (use -source 8 or higher to enable intersection types in cast)
-
-# 0: string
-compiler.err.static.intf.methods.not.supported.in.source=\
- static interface methods are not supported in -source {0}\n\
- (use -source 8 or higher to enable static interface methods)
-
-# 0: string
-compiler.err.static.intf.method.invoke.not.supported.in.source=\
- static interface method invocations are not supported in -source {0}\n\
- (use -source 8 or higher to enable static interface method invocations)
-
-# 0: string
-compiler.err.private.intf.methods.not.supported.in.source=\
- private interface methods are not supported in -source {0}\n\
- (use -source 9 or higher to enable private interface methods)
-
########################################
# Diagnostics for verbose resolution
# used by Resolve (debug only)
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DCTree.java Tue Dec 05 10:28:45 2017 +0000
@@ -109,17 +109,23 @@
public final List<DCTree> firstSentence;
public final List<DCTree> body;
public final List<DCTree> tags;
+ public final List<DCTree> preamble;
+ public final List<DCTree> postamble;
public DCDocComment(Comment comment,
List<DCTree> fullBody,
List<DCTree> firstSentence,
List<DCTree> body,
- List<DCTree> tags) {
+ List<DCTree> tags,
+ List<DCTree> preamble,
+ List<DCTree> postamble) {
this.comment = comment;
this.firstSentence = firstSentence;
this.fullBody = fullBody;
this.body = body;
this.tags = tags;
+ this.preamble = preamble;
+ this.postamble = postamble;
}
@Override @DefinedBy(Api.COMPILER_TREE)
@@ -152,6 +158,15 @@
return tags;
}
+ @Override @DefinedBy(Api.COMPILER_TREE)
+ public List<? extends DocTree> getPreamble() {
+ return preamble;
+ }
+
+ @Override @DefinedBy(Api.COMPILER_TREE)
+ public List<? extends DocTree> getPostamble() {
+ return postamble;
+ }
}
public static abstract class DCBlockTag extends DCTree implements BlockTagTree {
@@ -288,6 +303,29 @@
}
}
+ public static class DCDocType extends DCTree implements DocTypeTree {
+ public final String text;
+
+ DCDocType(String text) {
+ this.text = text;
+ }
+
+ @Override @DefinedBy(Api.COMPILER_TREE)
+ public Kind getKind() {
+ return Kind.DOC_TYPE;
+ }
+
+ @Override @DefinedBy(Api.COMPILER_TREE)
+ public <R, D> R accept(DocTreeVisitor<R, D> v, D d) {
+ return v.visitDocType(this, d);
+ }
+
+ @Override @DefinedBy(Api.COMPILER_TREE)
+ public String getText() {
+ return text;
+ }
+ }
+
public static class DCEndElement extends DCTree implements EndElementTree {
public final Name name;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocPretty.java Tue Dec 05 10:28:45 2017 +0000
@@ -225,6 +225,16 @@
}
@Override @DefinedBy(Api.COMPILER_TREE)
+ public Void visitDocType(DocTypeTree node, Void p) {
+ try {
+ print(node.getText());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return null;
+ }
+
+ @Override @DefinedBy(Api.COMPILER_TREE)
public Void visitEndElement(EndElementTree node, Void p) {
try {
print("</");
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java Tue Dec 05 10:28:45 2017 +0000
@@ -28,6 +28,7 @@
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.ListIterator;
@@ -37,6 +38,7 @@
import javax.tools.JavaFileObject;
import com.sun.source.doctree.AttributeTree.ValueKind;
+import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.DocTree.Kind;
import com.sun.source.doctree.EndElementTree;
@@ -59,6 +61,7 @@
import com.sun.tools.javac.tree.DCTree.DCDeprecated;
import com.sun.tools.javac.tree.DCTree.DCDocComment;
import com.sun.tools.javac.tree.DCTree.DCDocRoot;
+import com.sun.tools.javac.tree.DCTree.DCDocType;
import com.sun.tools.javac.tree.DCTree.DCEndElement;
import com.sun.tools.javac.tree.DCTree.DCEntity;
import com.sun.tools.javac.tree.DCTree.DCErroneous;
@@ -195,9 +198,23 @@
return tree;
}
- public DCDocComment newDocCommentTree(Comment comment, List<? extends DocTree> fullBody, List<? extends DocTree> tags) {
+ @Override @DefinedBy(Api.COMPILER_TREE)
+ public DCDocComment newDocCommentTree(List<? extends DocTree> fullBody, List<? extends DocTree> tags) {
Pair<List<DCTree>, List<DCTree>> pair = splitBody(fullBody);
- DCDocComment tree = new DCDocComment(comment, cast(fullBody), pair.fst, pair.snd, cast(tags));
+ List<DCTree> preamble = Collections.emptyList();
+ List<DCTree> postamble = Collections.emptyList();
+
+ return newDocCommentTree(fullBody, tags, preamble, postamble);
+ }
+
+ public DCDocComment newDocCommentTree(Comment comment,
+ List<? extends DocTree> fullBody,
+ List<? extends DocTree> tags,
+ List<? extends DocTree> preamble,
+ List<? extends DocTree> postamble) {
+ Pair<List<DCTree>, List<DCTree>> pair = splitBody(fullBody);
+ DCDocComment tree = new DCDocComment(comment, cast(fullBody), pair.fst, pair.snd,
+ cast(tags), cast(preamble), cast(postamble));
tree.pos = pos;
return tree;
}
@@ -208,7 +225,10 @@
* where the trees are being synthesized by a tool.
*/
@Override @DefinedBy(Api.COMPILER_TREE)
- public DCDocComment newDocCommentTree(List<? extends DocTree> fullBody, List<? extends DocTree> tags) {
+ public DCDocComment newDocCommentTree(List<? extends DocTree> fullBody,
+ List<? extends DocTree> tags,
+ List<? extends DocTree> preamble,
+ List<? extends DocTree> postamble) {
ListBuffer<DCTree> lb = new ListBuffer<>();
lb.addAll(cast(fullBody));
List<DCTree> fBody = lb.toList();
@@ -236,7 +256,8 @@
}
};
Pair<List<DCTree>, List<DCTree>> pair = splitBody(fullBody);
- DCDocComment tree = new DCDocComment(c, fBody, pair.fst, pair.snd, cast(tags));
+ DCDocComment tree = new DCDocComment(c, fBody, pair.fst, pair.snd, cast(tags),
+ cast(preamble), cast(postamble));
return tree;
}
@@ -248,6 +269,13 @@
}
@Override @DefinedBy(Api.COMPILER_TREE)
+ public DCDocType newDocTypeTree(String text) {
+ DCDocType tree = new DCDocType(text);
+ tree.pos = pos;
+ return tree;
+ }
+
+ @Override @DefinedBy(Api.COMPILER_TREE)
public DCEndElement newEndElementTree(Name name) {
DCEndElement tree = new DCEndElement(name);
tree.pos = pos;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java Tue Dec 05 10:28:45 2017 +0000
@@ -426,7 +426,7 @@
/** A set of "not-supported-in-source-X" errors produced so far. This is used to only generate
* one such error per file.
*/
- protected Set<Pair<JavaFileObject, String>> recordedSourceLevelErrors = new HashSet<>();
+ protected Set<Pair<JavaFileObject, List<String>>> recordedSourceLevelErrors = new HashSet<>();
public boolean hasDiagnosticListener() {
return diagListener != null;
@@ -521,13 +521,29 @@
if (!d.isFlagSet(DiagnosticFlag.SOURCE_LEVEL))
return true;
- Pair<JavaFileObject, String> coords = new Pair<>(file, d.getCode());
+ Pair<JavaFileObject, List<String>> coords = new Pair<>(file, getCode(d));
boolean shouldReport = !recordedSourceLevelErrors.contains(coords);
if (shouldReport)
recordedSourceLevelErrors.add(coords);
return shouldReport;
}
+ //where
+ private List<String> getCode(JCDiagnostic d) {
+ ListBuffer<String> buf = new ListBuffer<>();
+ getCodeRecursive(buf, d);
+ return buf.toList();
+ }
+
+ private void getCodeRecursive(ListBuffer<String> buf, JCDiagnostic d) {
+ buf.add(d.getCode());
+ for (Object o : d.getArgs()) {
+ if (o instanceof JCDiagnostic) {
+ getCodeRecursive(buf, (JCDiagnostic)o);
+ }
+ }
+ }
+
/** Prompt user after an error.
*/
public void prompt() {
--- a/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocHelper.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocHelper.java Tue Dec 05 10:28:45 2017 +0000
@@ -61,6 +61,7 @@
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
@@ -214,7 +215,9 @@
}
}
- DocCommentTree docCommentTree = parseDocComment(task, docComment);
+ Pair<DocCommentTree, Integer> parsed = parseDocComment(task, docComment);
+ DocCommentTree docCommentTree = parsed.fst;
+ int offset = parsed.snd;
IOException[] exception = new IOException[1];
Map<int[], String> replace = new TreeMap<>((span1, span2) -> span2[0] - span1[0]);
@@ -349,7 +352,10 @@
if (inherited == null) {
return null;
}
- DocCommentTree inheritedDocTree = parseDocComment(inheritedJavacTask, inherited);
+ Pair<DocCommentTree, Integer> parsed =
+ parseDocComment(inheritedJavacTask, inherited);
+ DocCommentTree inheritedDocTree = parsed.fst;
+ int offset = parsed.snd;
List<List<? extends DocTree>> inheritedText = new ArrayList<>();
DocTree parent = interestingParent.peek();
switch (parent.getKind()) {
@@ -391,7 +397,6 @@
break;
}
if (!inheritedText.isEmpty()) {
- long offset = trees.getSourcePositions().getStartPosition(null, inheritedDocTree, inheritedDocTree);
long start = Long.MAX_VALUE;
long end = Long.MIN_VALUE;
@@ -475,7 +480,6 @@
return docComment;
StringBuilder replacedInheritDoc = new StringBuilder(docComment);
- int offset = (int) trees.getSourcePositions().getStartPosition(null, docCommentTree, docCommentTree);
for (Entry<int[], String> e : replace.entrySet()) {
replacedInheritDoc.delete(e.getKey()[0] - offset, e.getKey()[1] - offset + 1);
@@ -507,22 +511,28 @@
}
private DocTree parseBlockTag(JavacTask task, String blockTag) {
- DocCommentTree dc = parseDocComment(task, blockTag);
+ DocCommentTree dc = parseDocComment(task, blockTag).fst;
return dc.getBlockTags().get(0);
}
- private DocCommentTree parseDocComment(JavacTask task, String javadoc) {
+ private Pair<DocCommentTree, Integer> parseDocComment(JavacTask task, String javadoc) {
DocTrees trees = DocTrees.instance(task);
try {
- return trees.getDocCommentTree(new SimpleJavaFileObject(new URI("mem://doc.html"), javax.tools.JavaFileObject.Kind.HTML) {
+ SimpleJavaFileObject fo =
+ new SimpleJavaFileObject(new URI("mem://doc.html"), Kind.HTML) {
@Override @DefinedBy(Api.COMPILER)
- public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ public CharSequence getCharContent(boolean ignoreEncodingErrors)
+ throws IOException {
return "<body>" + javadoc + "</body>";
}
- });
+ };
+ DocCommentTree tree = trees.getDocCommentTree(fo);
+ int offset = (int) trees.getSourcePositions().getStartPosition(null, tree, tree);
+ offset += "<body>".length() + 1;
+ return Pair.of(tree, offset);
} catch (URISyntaxException ex) {
- return null;
+ throw new IllegalStateException(ex);
}
}
--- a/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/RootDocImpl.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/RootDocImpl.java Tue Dec 05 10:28:45 2017 +0000
@@ -34,6 +34,7 @@
import javax.tools.StandardJavaFileManager;
import com.sun.javadoc.*;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
@@ -388,7 +389,7 @@
}
public boolean isFunctionalInterface(AnnotationDesc annotationDesc) {
- return env.source.allowLambda()
+ return Feature.LAMBDA.allowedInSource(env.source)
&& annotationDesc.annotationType().qualifiedName().equals(
env.syms.functionalInterfaceType.toString());
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.javadoc.internal.doclets.formats.html;
+
+import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.EndElementTree;
+import com.sun.source.doctree.StartElementTree;
+import com.sun.source.doctree.TextTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.toolkit.Content;
+import jdk.javadoc.internal.doclets.toolkit.DocFileElement;
+import jdk.javadoc.internal.doclets.toolkit.DocFilesHandler;
+import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
+import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
+import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
+import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
+import jdk.javadoc.internal.doclets.toolkit.util.Utils;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.PackageElement;
+import javax.tools.FileObject;
+import javax.tools.JavaFileManager.Location;
+import java.util.Collections;
+import java.util.List;
+
+public class DocFilesHandlerImpl implements DocFilesHandler {
+
+ public final Element element;
+ public final Location location;
+ public final DocPath source;
+ public final HtmlConfiguration configuration;
+
+ /**
+ * Constructor to construct the DocFilesWriter object.
+ *
+ * @param configuration the configuration of this doclet.
+ * @param element the containing element of the doc-files.
+ *
+ */
+ public DocFilesHandlerImpl(HtmlConfiguration configuration, Element element) {
+ this.configuration = configuration;
+ this.element = element;
+
+ switch (element.getKind()) {
+ case MODULE:
+ location = configuration.utils.getLocationForModule((ModuleElement)element);
+ source = DocPaths.DOC_FILES;
+ break;
+ case PACKAGE:
+ location = configuration.utils.getLocationForPackage((PackageElement)element);
+ source = DocPath.forPackage((PackageElement)element).resolve(DocPaths.DOC_FILES);
+ break;
+ default:
+ throw new AssertionError("unsupported element " + element);
+ }
+ }
+
+ /**
+ * Copy doc-files directory and its contents from the source
+ * elements directory to the generated documentation directory.
+ *
+ * @throws DocFileIOException if there is a problem while copying
+ * the documentation files
+ */
+
+ public void copyDocFiles() throws DocFileIOException {
+ boolean first = true;
+ for (DocFile srcdir : DocFile.list(configuration, location, source)) {
+ if (!srcdir.isDirectory()) {
+ continue;
+ }
+ DocPath path = null;
+ switch (this.element.getKind()) {
+ case MODULE:
+ path = DocPath.forModule((ModuleElement)this.element);
+ break;
+ case PACKAGE:
+ path = DocPath.forPackage((PackageElement)this.element);
+ break;
+ default:
+ throw new AssertionError("unknown kind:" + this.element.getKind());
+ }
+ copyDirectory(srcdir, path.resolve(DocPaths.DOC_FILES), first);
+ first = false;
+ }
+ }
+
+
+ private void copyDirectory(DocFile srcdir, final DocPath dstDocPath,
+ boolean first) throws DocFileIOException {
+ DocFile dstdir = DocFile.createFileForOutput(configuration, dstDocPath);
+ if (srcdir.isSameFile(dstdir)) {
+ return;
+ }
+ for (DocFile srcfile: srcdir.list()) {
+ DocFile destfile = dstdir.resolve(srcfile.getName());
+ if (srcfile.isFile()) {
+ if (destfile.exists() && !first) {
+ configuration.messages.warning("doclet.Copy_Overwrite_warning",
+ srcfile.getPath(), dstdir.getPath());
+ } else {
+ configuration.messages.notice("doclet.Copying_File_0_To_Dir_1",
+ srcfile.getPath(), dstdir.getPath());
+ if (Utils.toLowerCase(srcfile.getPath()).endsWith(".html")) {
+ handleHtmlFile(srcfile, dstDocPath);
+ } else {
+ destfile.copyFile(srcfile);
+ }
+ }
+ } else if (srcfile.isDirectory()) {
+ if (configuration.copydocfilesubdirs
+ && !configuration.shouldExcludeDocFileDir(srcfile.getName())) {
+ DocPath dirDocPath = dstDocPath.resolve(srcfile.getName());
+ copyDirectory(srcfile, dirDocPath, first);
+ }
+ }
+ }
+ }
+
+ private void handleHtmlFile(DocFile srcfile, DocPath dstPath) throws DocFileIOException {
+ DocPath dfilePath = dstPath.resolve(srcfile.getName());
+ HtmlDocletWriter docletWriter = new DocFileWriter(configuration, dfilePath, element);
+
+ Utils utils = configuration.utils;
+
+ FileObject fileObject = srcfile.getFileObject();
+ DocFileElement dfElement = new DocFileElement(element, fileObject);
+ String title = getWindowTitle(docletWriter, dfElement).trim();
+ HtmlTree htmlContent = docletWriter.getBody(true, title);
+ docletWriter.addTop(htmlContent);
+ docletWriter.addNavLinks(true, htmlContent);
+
+ List<? extends DocTree> fullBody = utils.getFullBody(dfElement);
+ Content bodyContent = docletWriter.commentTagsToContent(null, dfElement, fullBody, false);
+
+ docletWriter.addTagsInfo(dfElement, bodyContent);
+ htmlContent.addContent(bodyContent);
+
+ docletWriter.addNavLinks(false, htmlContent);
+ docletWriter.addBottom(htmlContent);
+ docletWriter.printHtmlDocument(Collections.emptyList(), false, htmlContent);
+ }
+
+ private String getWindowTitle(HtmlDocletWriter docletWriter, Element element) {
+ List<? extends DocTree> preamble = configuration.utils.getPreamble(element);
+ StringBuilder sb = new StringBuilder();
+ boolean titleFound = false;
+ loop:
+ for (DocTree dt : preamble) {
+ switch (dt.getKind()) {
+ case START_ELEMENT:
+ StartElementTree nodeStart = (StartElementTree)dt;
+ if (Utils.toLowerCase(nodeStart.getName().toString()).equals("title")) {
+ titleFound = true;
+ }
+ break;
+
+ case END_ELEMENT:
+ EndElementTree nodeEnd = (EndElementTree)dt;
+ if (Utils.toLowerCase(nodeEnd.getName().toString()).equals("title")) {
+ break loop;
+ }
+ break;
+
+ case TEXT:
+ TextTree nodeText = (TextTree)dt;
+ if (titleFound)
+ sb.append(nodeText.getBody());
+ break;
+
+ default:
+ // do nothing
+ }
+ }
+ return docletWriter.getWindowTitle(sb.toString().trim());
+ }
+
+ private static class DocFileWriter extends HtmlDocletWriter {
+
+ final PackageElement pkg;
+
+ /**
+ * Constructor to construct the HtmlDocletWriter object.
+ *
+ * @param configuration the configuruation of this doclet.
+ * @param path the file to be generated.
+ * @param e the anchoring element.
+ */
+ public DocFileWriter(HtmlConfiguration configuration, DocPath path, Element e) {
+ super(configuration, path);
+ switch (e.getKind()) {
+ case PACKAGE:
+ pkg = (PackageElement)e;
+ break;
+ default:
+ throw new AssertionError("unsupported element: " + e.getKind());
+ }
+ }
+
+ /**
+ * Get the module link.
+ *
+ * @return a content tree for the module link
+ */
+ @Override
+ protected Content getNavLinkModule() {
+ Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(pkg),
+ contents.moduleLabel);
+ Content li = HtmlTree.LI(linkContent);
+ return li;
+ }
+
+ /**
+ * Get this package link.
+ *
+ * @return a content tree for the package link
+ */
+ @Override
+ protected Content getNavLinkPackage() {
+ Content linkContent = getPackageLink(pkg,
+ contents.packageLabel);
+ Content li = HtmlTree.LI(linkContent);
+ return li;
+ }
+ }
+}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Tue Dec 05 10:28:45 2017 +0000
@@ -2268,13 +2268,14 @@
* @param annotationDoc the annotation being documented
* @param linkInfo the information about the link
* @param annotation the annotation string to which the annotation will be added
- * @param pairs annotation type element and value pairs
+ * @param map annotation type element to annotation value pairs
* @param indent the number of extra spaces to indent the annotations.
* @param linkBreak if true, add new line between each member value
*/
private void addAnnotations(TypeElement annotationDoc, LinkInfoImpl linkInfo,
- ContentBuilder annotation, Map<? extends ExecutableElement,? extends AnnotationValue>map,
- int indent, boolean linkBreak) {
+ ContentBuilder annotation,
+ Map<? extends ExecutableElement, ? extends AnnotationValue> map,
+ int indent, boolean linkBreak) {
linkInfo.label = new StringContent("@");
linkInfo.label.addContent(annotationDoc.getSimpleName());
annotation.addContent(getLink(linkInfo));
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/WriterFactoryImpl.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/WriterFactoryImpl.java Tue Dec 05 10:28:45 2017 +0000
@@ -26,6 +26,7 @@
package jdk.javadoc.internal.doclets.formats.html;
+import javax.lang.model.element.Element;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
@@ -37,6 +38,7 @@
import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeWriter;
import jdk.javadoc.internal.doclets.toolkit.ClassWriter;
import jdk.javadoc.internal.doclets.toolkit.ConstantsSummaryWriter;
+import jdk.javadoc.internal.doclets.toolkit.DocFilesHandler;
import jdk.javadoc.internal.doclets.toolkit.MemberSummaryWriter;
import jdk.javadoc.internal.doclets.toolkit.ModuleSummaryWriter;
import jdk.javadoc.internal.doclets.toolkit.PackageSummaryWriter;
@@ -235,4 +237,12 @@
public SerializedFormWriter getSerializedFormWriter() {
return new SerializedFormWriterImpl(configuration);
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public DocFilesHandler getDocFilesHandler(Element element) {
+ return new DocFilesHandlerImpl(configuration, element);
+ }
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseConfiguration.java Tue Dec 05 10:28:45 2017 +0000
@@ -375,7 +375,6 @@
}
initialized = true;
this.docEnv = docEnv;
- overviewElement = new OverviewElement(docEnv);
Splitter specifiedSplitter = new Splitter(docEnv, false);
specifiedModuleElements = Collections.unmodifiableSet(specifiedSplitter.mset);
specifiedPackageElements = Collections.unmodifiableSet(specifiedSplitter.pset);
@@ -715,6 +714,7 @@
* initializes certain components before anything else is started.
*/
protected boolean finishOptionSettings0() throws DocletException {
+
initDestDirectory();
for (String link : linkList) {
extern.link(link, reporter);
@@ -731,6 +731,7 @@
group.checkPackageGroups(grp.first, grp.second);
}
});
+ overviewElement = new OverviewElement(workArounds.getUnnamedPackage(), getOverviewPath());
return true;
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/CommentUtils.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/CommentUtils.java Tue Dec 05 10:28:45 2017 +0000
@@ -177,8 +177,11 @@
PackageElement pe = null;
switch (e.getKind()) {
case OTHER:
- fo = configuration.getOverviewPath();
- pe = configuration.workArounds.getUnnamedPackage();
+ if (e instanceof DocletElement) {
+ DocletElement de = (DocletElement)e;
+ fo = de.getFileObject();
+ pe = de.getPackageElement();
+ }
break;
case PACKAGE:
fo = configuration.workArounds.getJavaFileObject((PackageElement)e);
@@ -209,13 +212,12 @@
});
}
- public void setDocCommentTree(Element element, List<DocTree> fullBody,
- List<DocTree> blockTags, Utils utils) {
+ public void setDocCommentTree(Element element, List<? extends DocTree> fullBody,
+ List<? extends DocTree> blockTags, Utils utils) {
DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, blockTags);
dcTreesMap.put(element, new DocCommentDuo(null, docTree));
- // There maybe an entry with the original comments usually null,
- // therefore remove that entry if it exists, and allow a new one
- // to be reestablished.
+ // A method having null comment (no comment) that might need to be replaced
+ // with a synthetic comment, remove such a comment from the cache.
utils.removeCommentHelper(element);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/DocFileElement.java Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.javadoc.internal.doclets.toolkit;
+
+import java.lang.annotation.Annotation;
+import java.util.Set;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ElementVisitor;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.type.TypeMirror;
+import javax.tools.FileObject;
+
+import jdk.javadoc.doclet.DocletEnvironment;
+
+/**
+ * This is a pseudo element wrapper for doc-files html contents, essentially to
+ * associate the doc-file's html documentation's DocCommentTree to an element.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class DocFileElement implements DocletElement {
+
+ private final Element element;
+ private final FileObject fo;
+
+ public DocFileElement(Element element, FileObject fo) {
+ this.element = element;
+ this.fo = fo;
+ }
+
+ @Override
+ public PackageElement getPackageElement() {
+ switch(element.getKind()) {
+ case MODULE:
+ // uncomment to support doc-files in modules
+ // return configuration.workArounds.getUnnamedPackage();
+ throw new UnsupportedOperationException("not implemented");
+ case PACKAGE:
+ return (PackageElement)element;
+ default:
+ throw new AssertionError("unknown kind: " + element.getKind());
+ }
+ }
+
+ @Override
+ public FileObject getFileObject() {
+ return fo;
+ }
+
+ @Override
+ public Kind getSubKind() {
+ return Kind.DOCFILE;
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/DocFilesHandler.java Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package jdk.javadoc.internal.doclets.toolkit;
+
+/**
+ * The interface for copying doc-files to the output.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+
+public interface DocFilesHandler {
+ void copyDocFiles() throws DocletException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/DocletElement.java Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.javadoc.internal.doclets.toolkit;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ElementVisitor;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.type.TypeMirror;
+import javax.tools.FileObject;
+import java.lang.annotation.Annotation;
+import java.util.Set;
+
+public interface DocletElement extends Element {
+
+ public default TypeMirror asType() {
+ throw new UnsupportedOperationException("Unsupported method");
+ }
+
+ default ElementKind getKind() {
+ return ElementKind.OTHER;
+ }
+
+ default Set<Modifier> getModifiers() {
+ throw new UnsupportedOperationException("Unsupported method");
+ }
+
+ default Name getSimpleName() {
+ throw new UnsupportedOperationException("Unsupported method");
+ }
+
+ default Element getEnclosingElement() {
+ throw new UnsupportedOperationException("Unsupported method");
+ }
+
+ default java.util.List<? extends Element> getEnclosedElements() {
+ throw new UnsupportedOperationException("Unsupported method");
+ }
+
+ default java.util.List<? extends AnnotationMirror> getAnnotationMirrors() {
+ throw new UnsupportedOperationException("Unsupported method");
+ }
+
+ default <A extends Annotation> A getAnnotation(Class<A> annotationType) {
+ throw new UnsupportedOperationException("Unsupported method");
+ }
+
+ default <R, P> R accept(ElementVisitor<R, P> v, P p) {
+ return v.visitUnknown(this, p);
+ }
+
+ default <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
+ throw new UnsupportedOperationException("Unsupported method");
+ }
+
+ /**
+ * Returns the anchoring package element, in the case of a
+ * module element, this is the module's unnamed package.
+ * @return the anchor element.
+ */
+ PackageElement getPackageElement();
+
+ /**
+ * Returns the file object associated with this special
+ * element such as overview.html, doc-file/foo.html.
+ * @return the file object
+ */
+ FileObject getFileObject();
+
+ /**
+ * Returns the subkind of this element.
+ * @return a subkind
+ */
+ Kind getSubKind();
+
+ /**
+ * Sub kind enums that this element supports.
+ */
+ public static enum Kind {
+ OVERVIEW, DOCFILE;
+ }
+}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/OverviewElement.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/OverviewElement.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,17 +25,9 @@
package jdk.javadoc.internal.doclets.toolkit;
-import java.lang.annotation.Annotation;
-import java.util.Set;
-
-import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ElementVisitor;
-import javax.lang.model.element.Name;
-import javax.lang.model.type.TypeMirror;
-
-import jdk.javadoc.doclet.DocletEnvironment;
+import javax.lang.model.element.PackageElement;
+import javax.tools.FileObject;
/**
* This is a pseudo element wrapper for the overview element, essentially to
@@ -46,62 +38,28 @@
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
-public class OverviewElement implements Element {
-
- public final DocletEnvironment docEnv;
-
- OverviewElement(DocletEnvironment docEnv) {
- this.docEnv = docEnv;
- }
-
- @Override
- public TypeMirror asType() {
- throw new UnsupportedOperationException("Unsupported method");
- }
+public class OverviewElement implements DocletElement {
- @Override
- public ElementKind getKind() {
- return ElementKind.OTHER;
- }
+ private final PackageElement pkg;
+ private final FileObject fo;
- @Override
- public Set<javax.lang.model.element.Modifier> getModifiers() {
- throw new UnsupportedOperationException("Unsupported method");
- }
-
- @Override
- public Name getSimpleName() {
- throw new UnsupportedOperationException("Unsupported method");
+ public OverviewElement(PackageElement pkg, FileObject fo) {
+ this.pkg = pkg;
+ this.fo = fo;
}
@Override
- public Element getEnclosingElement() {
- throw new UnsupportedOperationException("Unsupported method");
+ public PackageElement getPackageElement() {
+ return pkg;
}
- @Override
- public java.util.List<? extends Element> getEnclosedElements() {
- throw new UnsupportedOperationException("Unsupported method");
- }
-
- @Override
- public java.util.List<? extends AnnotationMirror> getAnnotationMirrors() {
- throw new UnsupportedOperationException("Unsupported method");
+ public FileObject getFileObject() {
+ return fo;
}
@Override
- public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
- throw new UnsupportedOperationException("Unsupported method");
- }
-
- @Override
- public <R, P> R accept(ElementVisitor<R, P> v, P p) {
- return v.visitUnknown(this, p);
- }
-
- @Override
- public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
- throw new UnsupportedOperationException("Unsupported method");
+ public Kind getSubKind() {
+ return Kind.OVERVIEW;
}
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Tue Dec 05 10:28:45 2017 +0000
@@ -55,6 +55,7 @@
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Scope;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
@@ -187,7 +188,7 @@
// TODO: we need ElementUtils.getPackage to cope with input strings
// to return the proper unnamedPackage for all supported releases.
PackageElement getUnnamedPackage() {
- return (toolEnv.source.allowModules())
+ return (Feature.MODULES.allowedInSource(toolEnv.source))
? toolEnv.syms.unnamedModule.unnamedPackage
: toolEnv.syms.noModule.unnamedPackage;
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WriterFactory.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WriterFactory.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
package jdk.javadoc.internal.doclets.toolkit;
+import javax.lang.model.element.Element;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
@@ -222,4 +223,11 @@
* @return the writer for the serialized form.
*/
public SerializedFormWriter getSerializedFormWriter();
+
+ /**
+ * Return the handler for doc files.
+ *
+ * @return the handler for the doc files.
+ */
+ DocFilesHandler getDocFilesHandler(Element pkg);
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/AnnotationTypeBuilder.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/AnnotationTypeBuilder.java Tue Dec 05 10:28:45 2017 +0000
@@ -30,6 +30,7 @@
import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeWriter;
import jdk.javadoc.internal.doclets.toolkit.Content;
+import jdk.javadoc.internal.doclets.toolkit.DocFilesHandler;
import jdk.javadoc.internal.doclets.toolkit.DocletException;
@@ -132,7 +133,10 @@
//Only copy doc files dir if the containing package is not
//documented AND if we have not documented a class from the same
//package already. Otherwise, we are making duplicate copies.
- utils.copyDocFiles(containingPackage);
+ DocFilesHandler docFilesHandler = configuration
+ .getWriterFactory()
+ .getDocFilesHandler(containingPackage);
+ docFilesHandler.copyDocFiles();
containingPackagesSeen.add(containingPackage);
}
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/BuilderFactory.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/BuilderFactory.java Tue Dec 05 10:28:45 2017 +0000
@@ -34,12 +34,15 @@
import javax.lang.model.type.TypeMirror;
import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeWriter;
+import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
import jdk.javadoc.internal.doclets.toolkit.ClassWriter;
-import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
import jdk.javadoc.internal.doclets.toolkit.PropertyWriter;
import jdk.javadoc.internal.doclets.toolkit.WriterFactory;
import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
+
+
+
/**
* The factory for constructing builders.
*
@@ -87,7 +90,7 @@
* @param pkg the package being documented.
* @param prevPkg the previous package being documented.
* @param nextPkg the next package being documented.
- * @return the builder that builds the constant summary.
+ * @return the builder that builds the package summary.
*/
public AbstractBuilder getPackageSummaryBuilder(PackageElement pkg, PackageElement prevPkg,
PackageElement nextPkg) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ClassBuilder.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ClassBuilder.java Tue Dec 05 10:28:45 2017 +0000
@@ -30,6 +30,7 @@
import jdk.javadoc.internal.doclets.toolkit.ClassWriter;
import jdk.javadoc.internal.doclets.toolkit.Content;
+import jdk.javadoc.internal.doclets.toolkit.DocFilesHandler;
import jdk.javadoc.internal.doclets.toolkit.DocletException;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
@@ -269,7 +270,7 @@
*
* @throws DocFileIOException if there is a problem while copying the files
*/
- private void copyDocFiles() throws DocFileIOException {
+ private void copyDocFiles() throws DocletException {
PackageElement containingPackage = utils.containingPackage(typeElement);
if ((configuration.packages == null ||
!configuration.packages.contains(containingPackage)) &&
@@ -277,7 +278,10 @@
//Only copy doc files dir if the containing package is not
//documented AND if we have not documented a class from the same
//package already. Otherwise, we are making duplicate copies.
- utils.copyDocFiles(containingPackage);
+ DocFilesHandler docFilesHandler = configuration
+ .getWriterFactory()
+ .getDocFilesHandler(containingPackage);
+ docFilesHandler.copyDocFiles();
containingPackagesSeen.add(containingPackage);
}
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ModuleSummaryBuilder.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ModuleSummaryBuilder.java Tue Dec 05 10:28:45 2017 +0000
@@ -30,7 +30,6 @@
import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.DocletException;
import jdk.javadoc.internal.doclets.toolkit.ModuleSummaryWriter;
-import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
/**
@@ -117,7 +116,9 @@
moduleWriter.addModuleFooter(contentTree);
moduleWriter.printDocument(contentTree);
- utils.copyDirectory(mdle, DocPaths.moduleSummary(mdle));
+ // uncomment to support doc-files in modules
+ // DocFilesHandler docFilesHandler = configuration.getWriterFactory().getDocFilesWriter(mdle);
+ // docFilesHandler.copyDocFiles();
}
/**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/PackageSummaryBuilder.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/PackageSummaryBuilder.java Tue Dec 05 10:28:45 2017 +0000
@@ -32,6 +32,7 @@
import javax.lang.model.element.TypeElement;
import jdk.javadoc.internal.doclets.toolkit.Content;
+import jdk.javadoc.internal.doclets.toolkit.DocFilesHandler;
import jdk.javadoc.internal.doclets.toolkit.DocletException;
import jdk.javadoc.internal.doclets.toolkit.PackageSummaryWriter;
@@ -122,7 +123,10 @@
packageWriter.addPackageFooter(contentTree);
packageWriter.printDocument(contentTree);
- utils.copyDocFiles(packageElement);
+ DocFilesHandler docFilesHandler = configuration
+ .getWriterFactory()
+ .getDocFilesHandler(packageElement);
+ docFilesHandler.copyDocFiles();
}
/**
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java Tue Dec 05 10:28:45 2017 +0000
@@ -43,6 +43,7 @@
import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
+import jdk.javadoc.internal.doclets.toolkit.DocletElement;
import jdk.javadoc.internal.doclets.toolkit.Messages;
import jdk.javadoc.internal.doclets.toolkit.Resources;
@@ -571,6 +572,7 @@
return serializedFormTags;
}
+ @SuppressWarnings("fallthrough")
/**
* Returns the custom tags for a given element.
*
@@ -597,7 +599,17 @@
case PACKAGE:
return getPackageCustomTaglets();
case OTHER:
- return getOverviewCustomTaglets();
+ if (e instanceof DocletElement) {
+ DocletElement de = (DocletElement)e;
+ switch (de.getSubKind()) {
+ case DOCFILE:
+ return getPackageCustomTaglets();
+ case OVERVIEW:
+ return getOverviewCustomTaglets();
+ default:
+ // fall through
+ }
+ }
default:
throw new AssertionError("unknown element: " + e + " ,kind: " + e.getKind());
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocFile.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocFile.java Tue Dec 05 10:28:45 2017 +0000
@@ -33,6 +33,7 @@
import java.io.UnsupportedEncodingException;
import java.io.Writer;
+import javax.tools.FileObject;
import javax.tools.JavaFileManager.Location;
import javax.tools.StandardLocation;
@@ -102,6 +103,12 @@
}
/**
+ * Returns a file object for the file.
+ * @return a file object
+ */
+ public abstract FileObject getFileObject();
+
+ /**
* Open an input stream for the file.
*
* @return an open input stream for the file
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocPath.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocPath.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
package jdk.javadoc.internal.doclets.toolkit.util;
+import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
@@ -73,6 +74,12 @@
return (typeElement == null) ? empty : new DocPath(utils.getSimpleName(typeElement) + ".html");
}
+ public static DocPath forModule(ModuleElement mdle) {
+ return mdle == null || mdle.isUnnamed()
+ ? empty
+ : DocPath.create(mdle.getQualifiedName().toString());
+ }
+
/**
* Return the path for the package of a class.
* For example, if the class is java.lang.Object,
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocPaths.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocPaths.java Tue Dec 05 10:28:45 2017 +0000
@@ -170,6 +170,11 @@
/** The name of the file for the package usage info. */
public static final DocPath PACKAGE_USE = DocPath.create("package-use.html");
+ /** The name of the output directory for module documentation files. */
+ public static DocPath moduleDocFiles(ModuleElement mdle) {
+ return DocPath.create(mdle.getQualifiedName() + "-doc-files");
+ }
+
/** The name of the file for the module frame. */
public static DocPath moduleFrame(ModuleElement mdle) {
return DocPath.create(mdle.getQualifiedName() + "-frame.html");
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/StandardDocFileFactory.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/StandardDocFileFactory.java Tue Dec 05 10:28:45 2017 +0000
@@ -151,6 +151,11 @@
this.file = newFile(getDestDir(), path.getPath());
}
+ @Override
+ public FileObject getFileObject() {
+ return getJavaFileObjectForInput(file);
+ }
+
/**
* Open an input stream for the file.
*
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Tue Dec 05 10:28:45 2017 +0000
@@ -74,10 +74,12 @@
import com.sun.source.doctree.DocTree.Kind;
import com.sun.source.doctree.ParamTree;
import com.sun.source.doctree.SerialFieldTree;
+import com.sun.source.doctree.StartElementTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.LineMap;
import com.sun.source.util.DocSourcePositions;
import com.sun.source.util.DocTrees;
+import com.sun.source.util.SimpleDocTreeVisitor;
import com.sun.source.util.TreePath;
import com.sun.tools.javac.model.JavacTypes;
import jdk.javadoc.internal.doclets.formats.html.HtmlConfiguration;
@@ -265,97 +267,7 @@
return getEnclosingTypeElement(e) == null || isStatic(e);
}
- /**
- * Copy doc-files directory and its contents from the source
- * package directory to the generated documentation directory.
- * For example, given a package java.lang, this method will copy
- * the doc-files directory, found in the package directory to the
- * generated documentation hierarchy.
- *
- * @param pe the package containing the doc files to be copied
- * @throws DocFileIOException if there is a problem while copying
- * the documentation files
- */
- public void copyDocFiles(PackageElement pe) throws DocFileIOException {
- Location sourceLoc = getLocationForPackage(pe);
- copyDirectory(sourceLoc, DocPath.forPackage(pe).resolve(DocPaths.DOC_FILES));
- }
-
- /**
- * Copy the given directory contents from the source package directory
- * to the generated documentation directory. For example, given a package
- * java.lang, this method will copy the entire directory, to the generated
- * documentation hierarchy.
- *
- * @param pe the package containing the directory to be copied
- * @param dir the directory to be copied
- * @throws DocFileIOException if there is a problem while copying
- * the documentation files
- */
- public void copyDirectory(PackageElement pe, DocPath dir) throws DocFileIOException {
- copyDirectory(getLocationForPackage(pe), dir);
- }
-
- /**
- * Copy the given directory and its contents from the source
- * module directory to the generated documentation directory.
- * For example, given a package java.lang, this method will
- * copy the entire directory, to the generated documentation
- * hierarchy.
- *
- * @param mdle the module containing the directory to be copied
- * @param dir the directory to be copied
- * @throws DocFileIOException if there is a problem while copying
- * the documentation files
- */
- public void copyDirectory(ModuleElement mdle, DocPath dir) throws DocFileIOException {
- copyDirectory(getLocationForModule(mdle), dir);
- }
-
- /**
- * Copy files from a doc path location to the output.
- *
- * @param locn the location from which to read files
- * @param dir the directory to be copied
- * @throws DocFileIOException if there is a problem
- * copying the files
- */
- public void copyDirectory(Location locn, DocPath dir) throws DocFileIOException {
- boolean first = true;
- for (DocFile f : DocFile.list(configuration, locn, dir)) {
- if (!f.isDirectory()) {
- continue;
- }
- DocFile srcdir = f;
- DocFile destdir = DocFile.createFileForOutput(configuration, dir);
- if (srcdir.isSameFile(destdir)) {
- continue;
- }
-
- for (DocFile srcfile: srcdir.list()) {
- DocFile destfile = destdir.resolve(srcfile.getName());
- if (srcfile.isFile()) {
- if (destfile.exists() && !first) {
- messages.warning("doclet.Copy_Overwrite_warning",
- srcfile.getPath(), destdir.getPath());
- } else {
- messages.notice("doclet.Copying_File_0_To_Dir_1",
- srcfile.getPath(), destdir.getPath());
- destfile.copyFile(srcfile);
- }
- } else if (srcfile.isDirectory()) {
- if (configuration.copydocfilesubdirs
- && !configuration.shouldExcludeDocFileDir(srcfile.getName())) {
- copyDirectory(locn, dir.resolve(srcfile.getName()));
- }
- }
- }
-
- first = false;
- }
- }
-
- protected Location getLocationForPackage(PackageElement pd) {
+ public Location getLocationForPackage(PackageElement pd) {
ModuleElement mdle = configuration.docEnv.getElementUtils().getModuleOf(pd);
if (mdle == null)
@@ -364,7 +276,7 @@
return getLocationForModule(mdle);
}
- protected Location getLocationForModule(ModuleElement mdle) {
+ public Location getLocationForModule(ModuleElement mdle) {
Location loc = configuration.workArounds.getLocationForModule(mdle);
if (loc != null)
return loc;
@@ -3096,6 +3008,10 @@
if (!configuration.isAllowScriptInComments()) {
DocCommentTree dct = configuration.cmtUtils.parse(
URI.create("option://" + name.replace("-", "")), "<body>" + value + "</body>");
+
+ if (dct == null)
+ return;
+
try {
javaScriptScanner.scan(dct, null, p -> {
throw new JavaScriptScanner.Fault();
@@ -3123,6 +3039,13 @@
return dcTree;
}
+ public List<? extends DocTree> getPreamble(Element element) {
+ DocCommentTree docCommentTree = getDocCommentTree(element);
+ return docCommentTree == null
+ ? Collections.emptyList()
+ : docCommentTree.getPreamble();
+ }
+
public List<? extends DocTree> getFullBody(Element element) {
DocCommentTree docCommentTree = getDocCommentTree(element);
return (docCommentTree == null)
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Tue Dec 05 10:28:45 2017 +0000
@@ -55,6 +55,7 @@
import com.sun.tools.javac.code.Kinds.Kind;
import com.sun.tools.javac.code.Source;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
@@ -222,7 +223,7 @@
else
locs.add(StandardLocation.CLASS_PATH);
}
- if (source.allowModules() && toolEnv.fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH))
+ if (Feature.MODULES.allowedInSource(source) && toolEnv.fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH))
locs.add(StandardLocation.PATCH_MODULE_PATH);
this.locations = Collections.unmodifiableList(locs);
--- a/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java Tue Dec 05 10:28:45 2017 +0000
@@ -34,6 +34,7 @@
import com.sun.tools.javac.util.JCDiagnostic;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.tools.javac.util.JCDiagnostic.Error;
import com.sun.tools.javac.util.Log;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -78,7 +79,7 @@
Context context = new Context();
Log log = CaLog.createLog(context);
context.put(Log.class, log);
- context.put(Source.class, Source.JDK1_9);
+ context.put(Source.class, Source.JDK9);
scannerFactory = ScannerFactory.instance(context);
}
@@ -138,6 +139,11 @@
}
@Override
+ public void error(int pos, Error errorKey) {
+ die();
+ }
+
+ @Override
public void error(int pos, String key, Object... args) {
die();
}
--- a/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java Tue Dec 05 10:21:41 2017 +0000
+++ b/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java Tue Dec 05 10:28:45 2017 +0000
@@ -25,6 +25,7 @@
package jdk.jshell;
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.parser.JavacParser;
import com.sun.tools.javac.parser.ParserFactory;
@@ -191,7 +192,7 @@
List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
if (annosAfterParams.nonEmpty()) {
- checkAnnotationsAfterTypeParams(annosAfterParams.head.pos);
+ checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS);
mods.annotations = mods.annotations.appendList(annosAfterParams);
if (mods.pos == Position.NOPOS) {
mods.pos = mods.annotations.head.pos;
--- a/test/jdk/java/io/Serializable/maskSyntheticModifier/MaskSyntheticModifierTest.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/jdk/java/io/Serializable/maskSyntheticModifier/MaskSyntheticModifierTest.java Tue Dec 05 10:28:45 2017 +0000
@@ -30,6 +30,7 @@
* serialVersionUID calculation.
*/
+import java.io.File;
import java.io.ObjectStreamClass;
import java.nio.file.Files;
import java.nio.file.Paths;
@@ -46,7 +47,10 @@
}
private static void setup() throws Exception {
+ // Copy the class file to the first component of the class path
+ String cp = System.getProperty("java.class.path");
+ String cp1 = cp.substring(0, cp.indexOf(File.pathSeparatorChar));
Files.copy(Paths.get(System.getProperty("test.src"), "Foo.class"),
- Paths.get("Foo.class"), StandardCopyOption.REPLACE_EXISTING);
+ Paths.get(cp1, "Foo.class"), StandardCopyOption.REPLACE_EXISTING);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/SecurityManager/DepMethodsRequireAllPerm.java Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8004502 8008793 8029886 8186535
+ * @summary Sanity check that the SecurityManager checkMemberAccess method and
+ * methods that used to check AWTPermission now check for AllPermission
+ */
+
+import java.security.AllPermission;
+import java.security.Permission;
+
+public class DepMethodsRequireAllPerm {
+
+ static class MySecurityManager extends SecurityManager {
+ final Class<?> expectedClass;
+
+ MySecurityManager(Class<?> c) {
+ expectedClass = c;
+ }
+
+ @Override
+ public void checkPermission(Permission perm) {
+ if (perm.getClass() != expectedClass)
+ throw new RuntimeException("Got: " + perm.getClass() + ", expected: " + expectedClass);
+ super.checkPermission(perm);
+ }
+ }
+
+ public static void main(String[] args) {
+ MySecurityManager sm = new MySecurityManager(AllPermission.class);
+
+ try {
+ sm.checkAwtEventQueueAccess();
+ throw new RuntimeException("SecurityException expected");
+ } catch (SecurityException expected) { }
+
+ try {
+ sm.checkSystemClipboardAccess();
+ throw new RuntimeException("SecurityException expected");
+ } catch (SecurityException expected) { }
+
+ try {
+ sm.checkTopLevelWindow(null);
+ throw new RuntimeException("NullPointException expected");
+ } catch (NullPointerException expected) { }
+
+ if (sm.checkTopLevelWindow(new Object())) {
+ throw new RuntimeException("checkTopLevelWindow expected to return false");
+ }
+
+ try {
+ sm.checkMemberAccess(Object.class, java.lang.reflect.Member.DECLARED);
+ throw new RuntimeException("SecurityException expected");
+ } catch (SecurityException expected) { }
+
+ try {
+ sm.checkMemberAccess(null, java.lang.reflect.Member.DECLARED);
+ throw new RuntimeException("NullPointerException expected");
+ } catch (NullPointerException expected) { }
+ }
+}
--- a/test/jdk/java/lang/SecurityManager/NoAWT.java Tue Dec 05 10:21:41 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * 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 8004502 8008793 8029886
- * @summary Sanity check that SecurityManager methods that used to check
- * AWTPermission now check for AllPermission
- */
-
-import java.security.AllPermission;
-import java.security.Permission;
-
-public class NoAWT {
-
- static class MySecurityManager extends SecurityManager {
- final Class<?> expectedClass;
-
- MySecurityManager(Class<?> c) {
- expectedClass = c;
- }
-
- @Override
- public void checkPermission(Permission perm) {
- if (perm.getClass() != expectedClass)
- throw new RuntimeException("Got: " + perm.getClass() + ", expected: " + expectedClass);
- super.checkPermission(perm);
- }
- }
-
- public static void main(String[] args) {
- MySecurityManager sm = new MySecurityManager(AllPermission.class);
-
- try {
- sm.checkAwtEventQueueAccess();
- throw new RuntimeException("SecurityException expected");
- } catch (SecurityException expected) { }
-
- try {
- sm.checkSystemClipboardAccess();
- throw new RuntimeException("SecurityException expected");
- } catch (SecurityException expected) { }
-
- try {
- sm.checkTopLevelWindow(null);
- throw new RuntimeException("NullPointException expected");
- } catch (NullPointerException expected) { }
-
- if (sm.checkTopLevelWindow(new Object())) {
- throw new RuntimeException("checkTopLevelWindow expected to return false");
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/reflect/StaticFieldsOnInterface.java Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8186961
+ * @run main/othervm StaticFieldsOnInterface C
+ * @run main/othervm StaticFieldsOnInterface D
+ * @run main/othervm StaticFieldsOnInterface Y
+ */
+
+public class StaticFieldsOnInterface {
+ /*
+ A
+ / \
+ B C
+ \ /
+ D
+
+ Interface A has a public field
+ Ensure B, C, D only report exactly one public field
+
+ A
+ /
+ X A
+ |/
+ Y
+
+ Ensure class Y, extending class X, reports exactly one public field
+ */
+
+ public interface A {
+ public static final int CONSTANT = 42;
+ }
+
+ public interface B extends A {
+ }
+
+ public interface C extends A {
+ }
+
+ public interface D extends B, C {
+ }
+
+ static class X implements A {}
+ static class Y extends X implements A {}
+
+ public static void main(String[] args) throws Exception {
+ char first = 'C';
+ if (args.length > 0) {
+ first = args[0].charAt(0);
+ }
+
+ assertOneField(A.class);
+ // D first
+ if (first == 'D') {
+ assertOneField(D.class);
+ assertOneField(C.class);
+ }
+ // C first
+ else if (first == 'C') {
+ assertOneField(C.class);
+ assertOneField(D.class);
+ }
+ else {
+ assertOneField(Y.class);
+ }
+ }
+
+ static void assertOneField(Class<?> c) {
+ int nfs = c.getFields().length;
+ if (nfs != 1) {
+ throw new AssertionError(String.format(
+ "Class %s does not have exactly one field: %d", c.getName(), nfs));
+ }
+ }
+}
--- a/test/jdk/java/net/SocketOption/UnsupportedOptionsTest.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/jdk/java/net/SocketOption/UnsupportedOptionsTest.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,6 +57,8 @@
Class<?> c = Class.forName("jdk.net.ExtendedSocketOptions");
Field field = c.getField("SO_FLOW_SLA");
socketOptions.add((SocketOption<?>)field.get(null));
+ field = c.getField("TCP_QUICKACK");
+ socketOptions.add((SocketOption<?>)field.get(null));
} catch (ClassNotFoundException e) {
// ignore, jdk.net module not present
} catch (ReflectiveOperationException e) {
--- a/test/jdk/java/util/Collection/MOAT.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/jdk/java/util/Collection/MOAT.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,6 +57,8 @@
import java.util.concurrent.*;
import static java.util.Collections.*;
import java.lang.reflect.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
public class MOAT {
// Collections under test must not be initialized to contain this value,
@@ -230,6 +232,17 @@
testListMutatorsAlwaysThrow(list);
}
+ List<Integer> listCopy = List.copyOf(Arrays.asList(1, 2, 3));
+ testCollection(listCopy);
+ testImmutableList(listCopy);
+ testListMutatorsAlwaysThrow(listCopy);
+
+ List<Integer> listCollected = Stream.of(1, 2, 3).collect(Collectors.toUnmodifiableList());
+ equal(listCollected, List.of(1, 2, 3));
+ testCollection(listCollected);
+ testImmutableList(listCollected);
+ testListMutatorsAlwaysThrow(listCollected);
+
// Immutable Set
testEmptySet(Set.of());
testCollMutatorsAlwaysThrow(Set.of());
@@ -252,6 +265,18 @@
testCollMutatorsAlwaysThrow(set);
}
+ Set<Integer> setCopy = Set.copyOf(Arrays.asList(1, 2, 3));
+ testCollection(setCopy);
+ testImmutableSet(setCopy);
+ testCollMutatorsAlwaysThrow(setCopy);
+
+ Set<Integer> setCollected = Stream.of(1, 1, 2, 3, 2, 3)
+ .collect(Collectors.toUnmodifiableSet());
+ equal(setCollected, Set.of(1, 2, 3));
+ testCollection(setCollected);
+ testImmutableSet(setCollected);
+ testCollMutatorsAlwaysThrow(setCollected);
+
// Immutable Map
@SuppressWarnings("unchecked")
@@ -280,6 +305,35 @@
testImmutableMap(map);
testMapMutatorsAlwaysThrow(map);
}
+
+ Map<Integer,Integer> mapCopy = Map.copyOf(new HashMap<>(Map.of(1, 101, 2, 202, 3, 303)));
+ testMap(mapCopy);
+ testImmutableMap(mapCopy);
+ testMapMutatorsAlwaysThrow(mapCopy);
+
+ Map<Integer,Integer> mapCollected1 =
+ Stream.of(1, 2, 3)
+ .collect(Collectors.toUnmodifiableMap(i -> i, i -> 101 * i));
+ equal(mapCollected1, Map.of(1, 101, 2, 202, 3, 303));
+ testMap(mapCollected1);
+ testImmutableMap(mapCollected1);
+ testMapMutatorsAlwaysThrow(mapCollected1);
+
+ try {
+ Stream.of(1, 1, 2, 3, 2, 3)
+ .collect(Collectors.toUnmodifiableMap(i -> i, i -> 101 * i));
+ fail("duplicates should have thrown an exception");
+ } catch (IllegalStateException ise) {
+ pass();
+ }
+
+ Map<Integer,Integer> mapCollected2 =
+ Stream.of(1, 1, 2, 3, 2, 3)
+ .collect(Collectors.toUnmodifiableMap(i -> i, i -> 101 * i, Integer::sum));
+ equal(mapCollected2, Map.of(1, 202, 2, 404, 3, 606));
+ testMap(mapCollected2);
+ testImmutableMap(mapCollected2);
+ testMapMutatorsAlwaysThrow(mapCollected2);
}
private static void checkContainsSelf(Collection<Integer> c) {
--- a/test/jdk/java/util/Collection/SetFactories.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/jdk/java/util/Collection/SetFactories.java Tue Dec 05 10:28:45 2017 +0000
@@ -40,6 +40,9 @@
import org.testng.annotations.Test;
import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@@ -275,9 +278,9 @@
static <T> T serialClone(T obj) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(obj);
- oos.close();
+ try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+ oos.writeObject(obj);
+ }
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return (T) ois.readObject();
@@ -285,4 +288,53 @@
throw new AssertionError(e);
}
}
+
+ Set<Integer> genSet() {
+ return new HashSet<>(Arrays.asList(1, 2, 3));
+ }
+
+ @Test
+ public void copyOfResultsEqual() {
+ Set<Integer> orig = genSet();
+ Set<Integer> copy = Set.copyOf(orig);
+
+ assertEquals(orig, copy);
+ assertEquals(copy, orig);
+ }
+
+ @Test
+ public void copyOfModifiedUnequal() {
+ Set<Integer> orig = genSet();
+ Set<Integer> copy = Set.copyOf(orig);
+ orig.add(4);
+
+ assertNotEquals(orig, copy);
+ assertNotEquals(copy, orig);
+ }
+
+ @Test
+ public void copyOfIdentity() {
+ Set<Integer> orig = genSet();
+ Set<Integer> copy1 = Set.copyOf(orig);
+ Set<Integer> copy2 = Set.copyOf(copy1);
+
+ assertNotSame(orig, copy1);
+ assertSame(copy1, copy2);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void copyOfRejectsNullCollection() {
+ Set<Integer> set = Set.copyOf(null);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void copyOfRejectsNullElements() {
+ Set<Integer> set = Set.copyOf(Arrays.asList(1, null, 3));
+ }
+
+ @Test
+ public void copyOfAcceptsDuplicates() {
+ Set<Integer> set = Set.copyOf(Arrays.asList(1, 1, 2, 3, 3, 3));
+ assertEquals(set, Set.of(1, 2, 3));
+ }
}
--- a/test/jdk/java/util/List/ListFactories.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/jdk/java/util/List/ListFactories.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,9 @@
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@@ -221,9 +224,9 @@
static <T> T serialClone(T obj) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(obj);
- oos.close();
+ try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+ oos.writeObject(obj);
+ }
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return (T) ois.readObject();
@@ -231,4 +234,47 @@
throw new AssertionError(e);
}
}
+
+ List<Integer> genList() {
+ return new ArrayList<>(Arrays.asList(1, 2, 3));
+ }
+
+ @Test
+ public void copyOfResultsEqual() {
+ List<Integer> orig = genList();
+ List<Integer> copy = List.copyOf(orig);
+
+ assertEquals(orig, copy);
+ assertEquals(copy, orig);
+ }
+
+ @Test
+ public void copyOfModifiedUnequal() {
+ List<Integer> orig = genList();
+ List<Integer> copy = List.copyOf(orig);
+ orig.add(4);
+
+ assertNotEquals(orig, copy);
+ assertNotEquals(copy, orig);
+ }
+
+ @Test
+ public void copyOfIdentity() {
+ List<Integer> orig = genList();
+ List<Integer> copy1 = List.copyOf(orig);
+ List<Integer> copy2 = List.copyOf(copy1);
+
+ assertNotSame(orig, copy1);
+ assertSame(copy1, copy2);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void copyOfRejectsNullCollection() {
+ List<Integer> list = List.copyOf(null);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void copyOfRejectsNullElements() {
+ List<Integer> list = List.copyOf(Arrays.asList(1, null, 3));
+ }
}
--- a/test/jdk/java/util/Map/MapFactories.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/jdk/java/util/Map/MapFactories.java Tue Dec 05 10:28:45 2017 +0000
@@ -42,6 +42,9 @@
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@@ -70,6 +73,12 @@
}
// for varargs Map.Entry methods
+
+ @SuppressWarnings("unchecked")
+ Map.Entry<Integer,String>[] genEmptyEntryArray1() {
+ return (Map.Entry<Integer,String>[])new Map.Entry<?,?>[1];
+ }
+
@SuppressWarnings("unchecked")
Map.Entry<Integer,String>[] genEntries(int n) {
return IntStream.range(0, n)
@@ -322,21 +331,41 @@
}
@Test(expectedExceptions=NullPointerException.class)
- public void nullKeyDisallowedN() {
- Map.Entry<Integer,String>[] entries = genEntries(MAX_ENTRIES);
- entries[0] = new AbstractMap.SimpleImmutableEntry(null, "a");
+ public void nullKeyDisallowedVar1() {
+ Map.Entry<Integer,String>[] entries = genEmptyEntryArray1();
+ entries[0] = new AbstractMap.SimpleImmutableEntry<>(null, "a");
+ Map<Integer, String> map = Map.ofEntries(entries);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void nullValueDisallowedVar1() {
+ Map.Entry<Integer,String>[] entries = genEmptyEntryArray1();
+ entries[0] = new AbstractMap.SimpleImmutableEntry<>(0, null);
Map<Integer, String> map = Map.ofEntries(entries);
}
@Test(expectedExceptions=NullPointerException.class)
- public void nullValueDisallowedN() {
- Map.Entry<Integer,String>[] entries = genEntries(MAX_ENTRIES);
- entries[0] = new AbstractMap.SimpleImmutableEntry(0, null);
+ public void nullEntryDisallowedVar1() {
+ Map.Entry<Integer,String>[] entries = genEmptyEntryArray1();
Map<Integer, String> map = Map.ofEntries(entries);
}
@Test(expectedExceptions=NullPointerException.class)
- public void nullEntryDisallowedN() {
+ public void nullKeyDisallowedVarN() {
+ Map.Entry<Integer,String>[] entries = genEntries(MAX_ENTRIES);
+ entries[0] = new AbstractMap.SimpleImmutableEntry<>(null, "a");
+ Map<Integer, String> map = Map.ofEntries(entries);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void nullValueDisallowedVarN() {
+ Map.Entry<Integer,String>[] entries = genEntries(MAX_ENTRIES);
+ entries[0] = new AbstractMap.SimpleImmutableEntry<>(0, null);
+ Map<Integer, String> map = Map.ofEntries(entries);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void nullEntryDisallowedVarN() {
Map.Entry<Integer,String>[] entries = genEntries(MAX_ENTRIES);
entries[5] = null;
Map<Integer, String> map = Map.ofEntries(entries);
@@ -344,7 +373,7 @@
@Test(expectedExceptions=NullPointerException.class)
public void nullArrayDisallowed() {
- Map.ofEntries(null);
+ Map.ofEntries((Map.Entry<?,?>[])null);
}
@Test(dataProvider="all")
@@ -359,9 +388,9 @@
static <T> T serialClone(T obj) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(obj);
- oos.close();
+ try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+ oos.writeObject(obj);
+ }
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return (T) ois.readObject();
@@ -370,6 +399,62 @@
}
}
+ Map<Integer, String> genMap() {
+ Map<Integer, String> map = new HashMap<>();
+ map.put(1, "a");
+ map.put(2, "b");
+ map.put(3, "c");
+ return map;
+ }
+
+ @Test
+ public void copyOfResultsEqual() {
+ Map<Integer, String> orig = genMap();
+ Map<Integer, String> copy = Map.copyOf(orig);
+
+ assertEquals(orig, copy);
+ assertEquals(copy, orig);
+ }
+
+ @Test
+ public void copyOfModifiedUnequal() {
+ Map<Integer, String> orig = genMap();
+ Map<Integer, String> copy = Map.copyOf(orig);
+ orig.put(4, "d");
+
+ assertNotEquals(orig, copy);
+ assertNotEquals(copy, orig);
+ }
+
+ @Test
+ public void copyOfIdentity() {
+ Map<Integer, String> orig = genMap();
+ Map<Integer, String> copy1 = Map.copyOf(orig);
+ Map<Integer, String> copy2 = Map.copyOf(copy1);
+
+ assertNotSame(orig, copy1);
+ assertSame(copy1, copy2);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void copyOfRejectsNullMap() {
+ Map<Integer, String> map = Map.copyOf(null);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void copyOfRejectsNullKey() {
+ Map<Integer, String> map = genMap();
+ map.put(null, "x");
+ Map<Integer, String> copy = Map.copyOf(map);
+ }
+
+ @Test(expectedExceptions=NullPointerException.class)
+ public void copyOfRejectsNullValue() {
+ Map<Integer, String> map = genMap();
+ map.put(-1, null);
+ Map<Integer, String> copy = Map.copyOf(map);
+ }
+
// Map.entry() tests
@Test(expectedExceptions=NullPointerException.class)
@@ -386,7 +471,7 @@
public void entryBasicTests() {
Map.Entry<String,String> kvh1 = Map.entry("xyzzy", "plugh");
Map.Entry<String,String> kvh2 = Map.entry("foobar", "blurfl");
- Map.Entry<String,String> sie = new AbstractMap.SimpleImmutableEntry("xyzzy", "plugh");
+ Map.Entry<String,String> sie = new AbstractMap.SimpleImmutableEntry<>("xyzzy", "plugh");
assertTrue(kvh1.equals(sie));
assertTrue(sie.equals(kvh1));
@@ -404,5 +489,4 @@
Map<Number,Number> map = Map.ofEntries(e1, e2);
assertEquals(map.size(), 2);
}
-
}
--- a/test/jdk/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/jdk/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java Tue Dec 05 10:28:45 2017 +0000
@@ -39,6 +39,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
import java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject;
@@ -1283,4 +1284,57 @@
sync.release();
}
+ /**
+ * Tests scenario for
+ * JDK-8191937: Lost interrupt in AbstractQueuedSynchronizer when tryAcquire methods throw
+ */
+ public void testInterruptedFailingAcquire() throws InterruptedException {
+ final RuntimeException ex = new RuntimeException();
+
+ // A synchronizer only offering a choice of failure modes
+ class Sync extends AbstractQueuedLongSynchronizer {
+ boolean pleaseThrow;
+ @Override protected boolean tryAcquire(long ignored) {
+ if (pleaseThrow) throw ex;
+ return false;
+ }
+ @Override protected long tryAcquireShared(long ignored) {
+ if (pleaseThrow) throw ex;
+ return -1;
+ }
+ @Override protected boolean tryRelease(long ignored) {
+ return true;
+ }
+ @Override protected boolean tryReleaseShared(long ignored) {
+ return true;
+ }
+ }
+
+ final Sync s = new Sync();
+
+ final Thread thread = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ try {
+ if (ThreadLocalRandom.current().nextBoolean())
+ s.acquire(1);
+ else
+ s.acquireShared(1);
+ shouldThrow();
+ } catch (Throwable t) {
+ assertSame(ex, t);
+ assertTrue(Thread.interrupted());
+ }
+ }});
+ waitForThreadToEnterWaitState(thread);
+ assertSame(thread, s.getFirstQueuedThread());
+ assertTrue(s.hasQueuedPredecessors());
+ assertTrue(s.hasQueuedThreads());
+ assertEquals(1, s.getQueueLength());
+
+ s.pleaseThrow = true;
+ thread.interrupt();
+ s.release(1);
+ awaitTermination(thread);
+ }
+
}
--- a/test/jdk/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/jdk/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java Tue Dec 05 10:28:45 2017 +0000
@@ -36,9 +36,11 @@
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject;
@@ -1286,4 +1288,105 @@
sync.release();
}
+ /**
+ * Disabled demo test for (unfixed as of 2017-11)
+ * JDK-8191483: AbstractQueuedSynchronizer cancel/cancel race
+ * ant -Djsr166.tckTestClass=AbstractQueuedSynchronizerTest -Djsr166.methodFilter=testCancelCancelRace -Djsr166.runsPerTest=100 tck
+ */
+ public void DISABLED_testCancelCancelRace() throws InterruptedException {
+ class Sync extends AbstractQueuedSynchronizer {
+ protected boolean tryAcquire(int acquires) {
+ return !hasQueuedPredecessors() && compareAndSetState(0, 1);
+ }
+ protected boolean tryRelease(int releases) {
+ return compareAndSetState(1, 0);
+ }
+ }
+
+ Sync s = new Sync();
+ s.acquire(1); // acquire to force other threads to enqueue
+
+ // try to trigger double cancel race with two background threads
+ ArrayList<Thread> threads = new ArrayList<>();
+ Runnable failedAcquire = () -> {
+ try {
+ s.acquireInterruptibly(1);
+ shouldThrow();
+ } catch (InterruptedException expected) {}
+ };
+ for (int i = 0; i < 2; i++) {
+ Thread thread = new Thread(failedAcquire);
+ thread.start();
+ threads.add(thread);
+ }
+ Thread.sleep(100);
+ for (Thread thread : threads) thread.interrupt();
+ for (Thread thread : threads) awaitTermination(thread);
+
+ s.release(1);
+
+ // no one holds lock now, we should be able to acquire
+ if (!s.tryAcquire(1))
+ throw new RuntimeException(
+ String.format(
+ "Broken: hasQueuedPredecessors=%s hasQueuedThreads=%s queueLength=%d firstQueuedThread=%s",
+ s.hasQueuedPredecessors(),
+ s.hasQueuedThreads(),
+ s.getQueueLength(),
+ s.getFirstQueuedThread()));
+ }
+
+ /**
+ * Tests scenario for
+ * JDK-8191937: Lost interrupt in AbstractQueuedSynchronizer when tryAcquire methods throw
+ */
+ public void testInterruptedFailingAcquire() throws InterruptedException {
+ final RuntimeException ex = new RuntimeException();
+
+ // A synchronizer only offering a choice of failure modes
+ class Sync extends AbstractQueuedSynchronizer {
+ boolean pleaseThrow;
+ @Override protected boolean tryAcquire(int ignored) {
+ if (pleaseThrow) throw ex;
+ return false;
+ }
+ @Override protected int tryAcquireShared(int ignored) {
+ if (pleaseThrow) throw ex;
+ return -1;
+ }
+ @Override protected boolean tryRelease(int ignored) {
+ return true;
+ }
+ @Override protected boolean tryReleaseShared(int ignored) {
+ return true;
+ }
+ }
+
+ final Sync s = new Sync();
+
+ final Thread thread = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ try {
+ if (ThreadLocalRandom.current().nextBoolean())
+ s.acquire(1);
+ else
+ s.acquireShared(1);
+ shouldThrow();
+ } catch (Throwable t) {
+ assertSame(ex, t);
+ assertTrue(Thread.interrupted());
+ }
+ }});
+ waitForThreadToEnterWaitState(thread);
+ assertSame(thread, s.getFirstQueuedThread());
+ assertTrue(s.hasQueuedPredecessors());
+ assertTrue(s.hasQueuedThreads());
+ assertEquals(1, s.getQueueLength());
+
+ s.pleaseThrow = true;
+ thread.interrupt();
+ s.release(1);
+ awaitTermination(thread);
+ }
+
}
--- a/test/jdk/java/util/concurrent/tck/StampedLockTest.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/jdk/java/util/concurrent/tck/StampedLockTest.java Tue Dec 05 10:28:45 2017 +0000
@@ -614,7 +614,7 @@
long s = lock.readLock();
Thread t = newStartedThread(new CheckedRunnable() {
public void realRun() {
- threadAssertEquals(0L, lock.tryWriteLock());
+ assertEquals(0L, lock.tryWriteLock());
}});
awaitTermination(t);
--- a/test/jdk/java/util/concurrent/tck/SubmissionPublisherTest.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/jdk/java/util/concurrent/tck/SubmissionPublisherTest.java Tue Dec 05 10:28:45 2017 +0000
@@ -33,6 +33,7 @@
*/
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.Flow;
@@ -429,7 +430,8 @@
* Cancelling a subscription eventually causes no more onNexts to be issued
*/
public void testCancel() {
- SubmissionPublisher<Integer> p = basicPublisher();
+ SubmissionPublisher<Integer> p =
+ new SubmissionPublisher<Integer>(basicExecutor, 4); // must be < 20
TestSubscriber s1 = new TestSubscriber();
TestSubscriber s2 = new TestSubscriber();
p.subscribe(s1);
@@ -666,7 +668,6 @@
p.subscribe(s1);
p.subscribe(s2);
for (int i = 1; i <= 20; ++i) {
- assertTrue(p.estimateMinimumDemand() <= 1);
assertTrue(p.submit(i) >= 0);
}
p.close();
@@ -1005,4 +1006,31 @@
assertTrue(count.get() < n);
}
+ /**
+ * Tests scenario for
+ * JDK-8187947: A race condition in SubmissionPublisher
+ * cvs update -D '2017-11-25' src/main/java/util/concurrent/SubmissionPublisher.java && ant -Djsr166.expensiveTests=true -Djsr166.tckTestClass=SubmissionPublisherTest -Djsr166.methodFilter=testMissedSignal tck; cvs update -A src/main/java/util/concurrent/SubmissionPublisher.java
+ */
+ public void testMissedSignal_8187947() throws Exception {
+ final int N = expensiveTests ? (1 << 20) : (1 << 10);
+ final CountDownLatch finished = new CountDownLatch(1);
+ final SubmissionPublisher<Boolean> pub = new SubmissionPublisher<>();
+ class Sub implements Subscriber<Boolean> {
+ int received;
+ public void onSubscribe(Subscription s) {
+ s.request(N);
+ }
+ public void onNext(Boolean item) {
+ if (++received == N)
+ finished.countDown();
+ else
+ CompletableFuture.runAsync(() -> pub.submit(Boolean.TRUE));
+ }
+ public void onError(Throwable t) { throw new AssertionError(t); }
+ public void onComplete() {}
+ }
+ pub.subscribe(new Sub());
+ CompletableFuture.runAsync(() -> pub.submit(Boolean.TRUE));
+ await(finished);
+ }
}
--- a/test/jdk/java/util/zip/InflateIn_DeflateOut.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/jdk/java/util/zip/InflateIn_DeflateOut.java Tue Dec 05 10:28:45 2017 +0000
@@ -23,8 +23,9 @@
/**
* @test
- * @bug 4206909 4813885
- * @summary Test basic functionality of DeflaterOutputStream/InflaterInputStream and GZIPOutputStream/GZIPInputStream, including flush
+ * @bug 4206909 4813885 8191918
+ * @summary Test basic functionality of DeflaterOutputStream/InflaterInputStream
+ * and GZIPOutputStream/GZIPInputStream, including flush
* @key randomness
*/
@@ -147,6 +148,36 @@
check(Arrays.equals(data, buf));
}
+ private static void TestFlushableGZIPOutputStream() throws Throwable {
+ var random = new Random(new Date().getTime());
+
+ var byteOutStream = new ByteArrayOutputStream();
+ var output = new FlushableGZIPOutputStream(byteOutStream);
+
+ var data = new byte[random.nextInt(1024 * 1024)];
+ var buf = new byte[data.length];
+ random.nextBytes(data);
+
+ output.write(data);
+ for (int i=0; i<data.length; i++) {
+ output.write(data[i]);
+ }
+ output.flush();
+ for (int i=0; i<data.length; i++) {
+ output.write(data[i]);
+ }
+ output.write(data);
+ output.close();
+
+ var baos = new ByteArrayOutputStream();
+ try (var gzis = new GZIPInputStream(new
+ ByteArrayInputStream(byteOutStream.toByteArray()))) {
+ gzis.transferTo(baos);
+ }
+ var decompressedBytes = baos.toByteArray();
+ check(decompressedBytes.length == data.length * 4);
+ }
+
private static void check(InputStream is, OutputStream os)
throws Throwable
{
@@ -268,6 +299,7 @@
LineOrientedProtocol();
GZWriteFlushRead();
GZLineOrientedProtocol();
+ TestFlushableGZIPOutputStream();
}
//--------------------- Infrastructure ---------------------------
@@ -285,3 +317,80 @@
System.out.println("\nPassed = " + passed + " failed = " + failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
}
+
+class FlushableGZIPOutputStream extends GZIPOutputStream {
+ public FlushableGZIPOutputStream(OutputStream os) throws IOException {
+ super(os);
+ }
+
+ private static final byte[] EMPTYBYTEARRAY = new byte[0];
+ private boolean hasData = false;
+
+ /**
+ * Here we make sure we have received data, so that the header has been for
+ * sure written to the output stream already.
+ */
+ @Override
+ public synchronized void write(byte[] bytes, int i, int i1)
+ throws IOException {
+ super.write(bytes, i, i1);
+ hasData = true;
+ }
+
+ @Override
+ public synchronized void write(int i) throws IOException {
+ super.write(i);
+ hasData = true;
+ }
+
+ @Override
+ public synchronized void write(byte[] bytes) throws IOException {
+ super.write(bytes);
+ hasData = true;
+ }
+
+ @Override
+ public synchronized void flush() throws IOException {
+ if (!hasData) {
+ return; // do not allow the gzip header to be flushed on its own
+ }
+
+ // trick the deflater to flush
+ /**
+ * Now this is tricky: We force the Deflater to flush its data by
+ * switching compression level. As yet, a perplexingly simple workaround
+ * for
+ * http://developer.java.sun.com/developer/bugParade/bugs/4255743.html
+ */
+ if (!def.finished()) {
+ def.setInput(EMPTYBYTEARRAY, 0, 0);
+
+ def.setLevel(Deflater.NO_COMPRESSION);
+ deflate();
+
+ def.setLevel(Deflater.DEFAULT_COMPRESSION);
+ deflate();
+
+ out.flush();
+ }
+
+ hasData = false; // no more data to flush
+ }
+
+ /*
+ * Keep on calling deflate until it runs dry. The default implementation
+ * only does it once and can therefore hold onto data when they need to be
+ * flushed out.
+ */
+ @Override
+ protected void deflate() throws IOException {
+ int len;
+ do {
+ len = def.deflate(buf, 0, buf.length);
+ if (len > 0) {
+ out.write(buf, 0, len);
+ }
+ } while (len != 0);
+ }
+
+}
--- a/test/jdk/javax/xml/ws/8159058/SaajEmptyNamespaceTest.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/jdk/javax/xml/ws/8159058/SaajEmptyNamespaceTest.java Tue Dec 05 10:28:45 2017 +0000
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8159058
+ * @bug 8159058 8186441
* @summary Test that empty default namespace declaration clears the
* default namespace value
* @modules java.xml.ws/com.sun.xml.internal.ws.api
@@ -61,6 +61,26 @@
public class SaajEmptyNamespaceTest {
/*
+ * Test that SOAP reader doesn't move namespaces declarations to SOAP body element
+ * as reported in JDK-8186441
+ */
+ @Test
+ public void testPreserveNamespacesPosition() throws Exception {
+ // Create SOAP message from XML string and process it with SAAJ reader
+ XMLStreamReader envelope = XMLInputFactory.newFactory().createXMLStreamReader(
+ new StringReader(INPUT_SOAP_MESSAGE_2));
+ StreamMessage streamMessage = new StreamMessage(SOAPVersion.SOAP_11,
+ envelope, null);
+ SAAJFactory saajFact = new SAAJFactory();
+ SOAPMessage soapMessage = saajFact.readAsSOAPMessage(SOAPVersion.SOAP_11, streamMessage);
+
+ //Get SOAP body and convert it to string representation
+ SOAPBody body = soapMessage.getSOAPBody();
+ String bodyAsString = nodeToText(body);
+ Assert.assertEquals(bodyAsString, PRESERVE_NAMESPACES_EXPECTED_RESULT);
+ }
+
+ /*
* Test that SOAP message with default namespace declaration that contains empty
* string is properly processed by SAAJ reader.
*/
@@ -275,10 +295,28 @@
// Expected body content after SAAJ processing
private static String EXPECTED_RESULT = "<SampleServiceRequest"
- +" xmlns=\"http://example.org/test\">"
+ + " xmlns=\"http://example.org/test\""
+ + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ "<RequestParams xmlns=\"\">"
+ "<Param1>hogehoge</Param1>"
+ "<Param2>fugafuga</Param2>"
+ "</RequestParams>"
+ "</SampleServiceRequest>";
+
+ private static String PRESERVE_NAMESPACES_EXPECTED_RESULT =
+ "<s:Body xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+ +"<Request xmlns=\"http://example.org/NS_1\">"
+ +"<Item><Contact xmlns=\"http://example.org/NS_2\">Test_Contact</Contact>"
+ +"</Item></Request></s:Body>";
+
+ private static String INPUT_SOAP_MESSAGE_2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+ + "<s:Body>"
+ + "<Request xmlns=\"http://example.org/NS_1\">"
+ + "<Item>"
+ + "<Contact xmlns=\"http://example.org/NS_2\">Test_Contact</Contact>"
+ + "</Item>"
+ + "</Request>"
+ + "</s:Body>"
+ + "</s:Envelope>";
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/net/Sockets/ExtOptionTest.java Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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 8190843
+ * @summary can not set/get extendedOptions to ServerSocket
+ * @modules jdk.net
+ * @run main ExtOptionTest
+ */
+import java.io.IOException;
+import java.net.ServerSocket;
+
+import static jdk.net.ExtendedSocketOptions.TCP_QUICKACK;
+import static jdk.net.ExtendedSocketOptions.SO_FLOW_SLA;
+
+public class ExtOptionTest {
+
+ private static final String OS = "Linux";
+
+ public static void main(String args[]) throws IOException {
+ var operSys = System.getProperty("os.name");
+ try (ServerSocket ss = new ServerSocket(0)) {
+ // currently TCP_QUICKACK is available only on Linux.
+ if (operSys.equals(OS)) {
+ ss.setOption(TCP_QUICKACK, true);
+ if (!ss.getOption(TCP_QUICKACK)) {
+ throw new RuntimeException("Test failed, TCP_QUICKACK should"
+ + " have been set");
+ }
+ } else if (operSys.equals("SunOS")) {
+ if (ss.supportedOptions().contains(SO_FLOW_SLA)) {
+ throw new RuntimeException("Test failed, SO_FLOW_SLA is not "
+ + "applicable for ServerSocket");
+ }
+ } else {
+ if (ss.supportedOptions().contains(TCP_QUICKACK)) {
+ ss.setOption(TCP_QUICKACK, true);
+ if (!ss.getOption(TCP_QUICKACK)) {
+ throw new RuntimeException("Test failed, TCP_QUICKACK should"
+ + " have been set");
+ }
+ }
+ }
+ }
+ }
+}
--- a/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/jdk/sun/security/tools/jarsigner/TimestampCheck.java Tue Dec 05 10:28:45 2017 +0000
@@ -694,11 +694,15 @@
gencert("ts", "-ext eku:critical=ts");
- // Issue another cert for "ts" with a different EKU.
- // Length should be the same. Try several times.
- keytool("-gencert -alias ca -infile ts.req -outfile ts2.cert " +
- "-ext eku:critical=1.3.6.1.5.5.7.3.9");
for (int i = 0; i < 5; i++) {
+ // Issue another cert for "ts" with a different EKU.
+ // Length might be different because serial number is
+ // random. Try several times until a cert with the same
+ // length is generated so we can substitute ts.cert
+ // embedded in the PKCS7 block with ts2.cert.
+ // If cannot create one, related test will be ignored.
+ keytool("-gencert -alias ca -infile ts.req -outfile ts2.cert " +
+ "-ext eku:critical=1.3.6.1.5.5.7.3.9");
if (Files.size(Paths.get("ts.cert")) != Files.size(Paths.get("ts2.cert"))) {
Files.delete(Paths.get("ts2.cert"));
System.out.println("Warning: cannot create same length");
--- a/test/langtools/jdk/internal/shellsupport/doc/JavadocHelperTest.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/jdk/internal/shellsupport/doc/JavadocHelperTest.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* 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 8131019
+ * @bug 8131019 8190552
* @summary Test JavadocHelper
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
--- a/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,8 +23,8 @@
/*
* @test
- * @bug 8157349
- * @summary test copy of doc-files
+ * @bug 8157349 8185985
+ * @summary test copy of doc-files, and its contents for HTML meta content.
* @library ../lib
* @modules jdk.javadoc/jdk.javadoc.internal.tool
* @build JavadocTester
@@ -39,13 +39,123 @@
}
@Test
- void testDocFilesInModules() {
+ void testDocFilesInModulePackages() {
javadoc("-d", "modules-out",
+ "-top", "phi-TOP-phi",
+ "-bottom", "phi-BOTTOM-phi",
+ "-header", "phi-HEADER-phi",
+ "-footer", "phi-FOOTER-phi",
+ "-windowtitle", "phi-WINDOW-TITLE-phi",
+ "--module-source-path", testSrc("modules"),
+ "--module", "acme.mdle");
+ checkExit(Exit.OK);
+ checkOrder("p/doc-files/inpackage.html",
+ "\"Hello World\" (phi-WINDOW-TITLE-phi)",
+ "phi-TOP-phi",
+ // check top navbar
+ "<a href=\"../../acme.mdle-summary.html\">Module</a>",
+ "<a href=\"../../p/package-summary.html\">Package</a>",
+ "<a href=\"../../overview-tree.html\">Tree</a>",
+ "<a href=\"../../deprecated-list.html\">Deprecated</a>",
+ "<a href=\"../../index-all.html\">Index</a>",
+ "phi-HEADER-phi",
+ "In a named module acme.module and named package "
+ + "<a href=\"../../p/package-summary.html\"><code>p</code></a>.",
+ "\"simpleTagLabel\">Since:</",
+ "1940",
+ // check bottom navbar
+ "<a href=\"../../acme.mdle-summary.html\">Module</a>",
+ "<a href=\"../../p/package-summary.html\">Package</a>",
+ "<a href=\"../../overview-tree.html\">Tree</a>",
+ "<a href=\"../../deprecated-list.html\">Deprecated</a>",
+ "<a href=\"../../index-all.html\">Index</a>",
+ "phi-FOOTER-phi",
+ "phi-BOTTOM-phi"
+ );
+ }
+
+ @Test
+ void testDocFilesInMultiModulePackagesWithRecursiveCopy() {
+ javadoc("-d", "multi-modules-out-recursive",
+ "-docfilessubdirs",
+ "-top", "phi-TOP-phi",
+ "-bottom", "phi-BOTTOM-phi",
+ "-header", "phi-HEADER-phi",
+ "-footer", "phi-FOOTER-phi",
+ "-windowtitle", "phi-WINDOW-TITLE-phi",
+ "--module-source-path", testSrc("modules"),
+ "--module", "acme.mdle,acme2.mdle");
+ checkExit(Exit.OK);
+ checkOrder("p/doc-files/inpackage.html",
+ "\"Hello World\" (phi-WINDOW-TITLE-phi)",
+ "phi-TOP-phi",
+ // check top navbar
+ "<a href=\"../../acme.mdle-summary.html\">Module</a>",
+ "<a href=\"../../p/package-summary.html\">Package</a>",
+ "<a href=\"../../overview-tree.html\">Tree</a>",
+ "<a href=\"../../deprecated-list.html\">Deprecated</a>",
+ "<a href=\"../../index-all.html\">Index</a>",
+ "phi-HEADER-phi",
+ "In a named module acme.module and named package "
+ + "<a href=\"../../p/package-summary.html\"><code>p</code></a>.",
+ "\"simpleTagLabel\">Since:</",
+ "1940",
+ // check bottom navbar
+ "<a href=\"../../acme.mdle-summary.html\">Module</a>",
+ "<a href=\"../../p/package-summary.html\">Package</a>",
+ "<a href=\"../../overview-tree.html\">Tree</a>",
+ "<a href=\"../../deprecated-list.html\">Deprecated</a>",
+ "<a href=\"../../index-all.html\">Index</a>",
+ "phi-FOOTER-phi",
+ "phi-BOTTOM-phi"
+ );
+
+ // check the bottom most doc file
+ checkOrder("p2/doc-files/sub-dir/sub-dir-1/SubSubReadme.html",
+ "SubSubReadme (phi-WINDOW-TITLE-phi)",
+ "phi-TOP-phi",
+ // check top navbar
+ "<a href=\"../../../../acme2.mdle-summary.html\">Module</a>",
+ "<a href=\"../../../../p2/package-summary.html\">Package</a>",
+ "<a href=\"../../../../overview-tree.html\">Tree</a>",
+ "<a href=\"../../../../deprecated-list.html\">Deprecated</a>",
+ "<a href=\"../../../../index-all.html\">Index</a>",
+ "phi-HEADER-phi",
+ "SubSubReadme.html at third level of doc-file directory.",
+ // check bottom navbar
+ "<a href=\"../../../../acme2.mdle-summary.html\">Module</a>",
+ "<a href=\"../../../../p2/package-summary.html\">Package</a>",
+ "<a href=\"../../../../overview-tree.html\">Tree</a>",
+ "<a href=\"../../../../deprecated-list.html\">Deprecated</a>",
+ "<a href=\"../../../../index-all.html\">Index</a>",
+ "phi-FOOTER-phi",
+ "phi-BOTTOM-phi"
+ );
+ }
+ @Test
+ void testDocFilesInModulePackagesWithRecursiveCopy() {
+ javadoc("-d", "modules-out-recursive",
+ "-docfilessubdirs",
"--module-source-path", testSrc("modules"),
"--module", "acme.mdle");
checkExit(Exit.OK);
checkOutput("p/doc-files/inpackage.html", true,
- "In a named module and named package"
+ "In a named module acme.module and named package "
+ + "<a href=\"../../p/package-summary.html\"><code>p</code></a>."
+ );
+ }
+
+ @Test
+ void testDocFilesInModulePackagesWithRecursiveCopyWithExclusion() {
+ javadoc("-d", "modules-out-recursive-with-exclusion",
+ "-docfilessubdirs",
+ "-excludedocfilessubdir", "sub-dir",
+ "--module-source-path", testSrc("modules"),
+ "--module", "acme.mdle");
+ checkExit(Exit.OK);
+ checkOutput("p/doc-files/inpackage.html", true,
+ "In a named module acme.module and named package "
+ + "<a href=\"../../p/package-summary.html\"><code>p</code></a>."
);
}
@@ -61,18 +171,71 @@
}
@Test
+ void testDocFilesInPackagesWithRecursiveCopy() {
+ javadoc("-d", "packages-out-recursive",
+ "-docfilessubdirs",
+ "-sourcepath", testSrc("packages"),
+ "p1");
+ checkExit(Exit.OK);
+
+ checkOutput("p1/doc-files/inpackage.html", true,
+ "A named package in an unnamed module"
+ );
+
+ checkOutput("p1/doc-files/sub-dir/SubReadme.html", true,
+ "<title>SubReadme</title>",
+ "SubReadme.html at second level of doc-file directory."
+ );
+ }
+
+ @Test
+ void testDocFilesInPackagesWithRecursiveCopyWithExclusion() {
+ javadoc("-d", "packages-out-recursive-with-exclusion",
+ "-docfilessubdirs",
+ "-excludedocfilessubdir", "sub-dir",
+ "-sourcepath", testSrc("packages"),
+ "p1");
+ checkExit(Exit.OK);
+
+ checkOutput("p1/doc-files/inpackage.html", true,
+ "A named package in an unnamed module"
+ );
+ }
+
+ @Test
void testDocFilesInUnnamedPackages() {
javadoc("-d", "unnamed-out",
+ "-windowtitle", "phi-WINDOW-TITLE-phi",
"-sourcepath", testSrc("unnamed"),
testSrc("unnamed/Foo.java")
);
checkExit(Exit.OK);
checkOutput("doc-files/inpackage.html", true,
+ "<title>(phi-WINDOW-TITLE-phi)</title>\n",
"In an unnamed package"
);
}
@Test
+ void testDocFilesInUnnamedPackagesWithRecursiveCopy() {
+ javadoc("-d", "unnamed-out-recursive",
+ "-docfilessubdirs",
+ "-windowtitle", "phi-WINDOW-TITLE-phi",
+ "-sourcepath", testSrc("unnamed"),
+ testSrc("unnamed/Foo.java")
+ );
+ checkExit(Exit.OK);
+ checkOutput("doc-files/inpackage.html", true,
+ "<title>(phi-WINDOW-TITLE-phi)</title>\n",
+ "In an unnamed package"
+ );
+ checkOutput("doc-files/doc-file/SubReadme.html", true,
+ "<title>Beep Beep (phi-WINDOW-TITLE-phi)</title>\n",
+ "SubReadme.html at second level of doc-file directory for unnamed package."
+ );
+ }
+
+ @Test
void testDocFilesInPackagesSource7() {
javadoc("-d", "packages-out-src7",
"-source", "7",
--- a/test/langtools/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/p/doc-files/inpackage.html Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/p/doc-files/inpackage.html Tue Dec 05 10:28:45 2017 +0000
@@ -28,6 +28,8 @@
<title>"Hello World"</title>
</head>
<body>
- In a named module and named package
+ In a named module acme.module and named package {@link p}.
+ @author Wile E. Coyote
+ @since 1940
</body>
</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/p/doc-files/sub-dir/SubReadme.html Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ ~ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ ~
+ ~ This code is free software; you can redistribute 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.
+ -->
+
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>SubReadme</title>
+</head>
+<body>
+ SubReadme.html at second level of doc-file directory for acme.module.
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/p/doc-files/sub-dir/sub-dir-1/SubSubReadme.html Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ ~ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ ~
+ ~ This code is free software; you can redistribute 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.
+ -->
+
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>SubSubReadme</title>
+</head>
+<body>
+ SubSubReadme.html at third level of doc-file directory.
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/p/package.html Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ ~ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ ~
+ ~ This code is free software; you can redistribute 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.
+ -->
+
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>package.html file for p</title>
+</head>
+<body>
+ A named package {@link p} in a name module acme.mdle.
+ @author WECoyote
+ @since 1940
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/modules/acme2.mdle/module-info.java Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute 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.
+ */
+
+ /**
+ * A test module.
+ */
+module acme2.mdle {
+ exports p2;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/modules/acme2.mdle/p2/Foo.java Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package p2;
+
+/**
+ * A test class.
+ */
+public class Foo {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/modules/acme2.mdle/p2/doc-files/inpackage.html Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,35 @@
+<!--
+Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+This code is free software; you can redistribute 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.
+-->
+
+<html>
+ <head>
+ <title>"Hello World"</title>
+ </head>
+ <body>
+ In a named module acme2.mdle and named package {@link p2}.
+ @author Wile E. Coyote
+ @since 1940
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/modules/acme2.mdle/p2/doc-files/sub-dir/SubReadme.html Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ ~ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ ~
+ ~ This code is free software; you can redistribute 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.
+ -->
+
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>SubReadme</title>
+</head>
+<body>
+ SubReadme.html at second level of doc-file directory for acme2.mdle.
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/modules/acme2.mdle/p2/doc-files/sub-dir/sub-dir-1/SubSubReadme.html Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ ~ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ ~
+ ~ This code is free software; you can redistribute 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.
+ -->
+
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>SubSubReadme</title>
+</head>
+<body>
+ SubSubReadme.html at third level of doc-file directory.
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/modules/acme2.mdle/p2/package.html Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ ~ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ ~
+ ~ This code is free software; you can redistribute 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.
+ -->
+
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>package.html file for p</title>
+</head>
+<body>
+ A named package {@link p2} in a name module acme2.mdle.
+ @author WECoyote
+ @since 1940
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/modules/overview.html Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ ~ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ ~
+ ~ This code is free software; you can redistribute 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.
+ -->
+
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>My overview html file</title>
+</head>
+<body>
+The overview html file
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/packages/p1/doc-files/sub-dir/SubReadme.html Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ ~ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ ~
+ ~ This code is free software; you can redistribute 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.
+ -->
+
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>SubReadme</title>
+</head>
+<body>
+ SubReadme.html at second level of doc-file directory.
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/unnamed/doc-files/doc-file/SubReadme.html Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!--
+ ~ Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ ~ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ ~
+ ~ This code is free software; you can redistribute 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.
+ -->
+
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <TITLE>Beep Beep</TITLE>
+</head>
+<body>
+ SubReadme.html at second level of doc-file directory for unnamed package.
+</body>
+</html>
\ No newline at end of file
--- a/test/langtools/jdk/javadoc/doclet/testCopyFiles/unnamed/doc-files/inpackage.html Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/unnamed/doc-files/inpackage.html Tue Dec 05 10:28:45 2017 +0000
@@ -24,9 +24,6 @@
-->
<html>
- <head>
- <title>"Hello World"</title>
- </head>
<body>
In an unnamed package
</body>
--- a/test/langtools/jdk/javadoc/doclet/testPackageHtml/TestPackageHtml.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testPackageHtml/TestPackageHtml.java Tue Dec 05 10:28:45 2017 +0000
@@ -44,7 +44,7 @@
"-sourcepath", testSrc,
"pkg1");
checkExit(Exit.ERROR);
- checkOutput(Output.OUT, true, "package.html:10: error: bad use of '>'");
+ checkOutput(Output.OUT, true, "package.html:5: error: bad use of '>'");
}
// Doclet must handle empty body in package.html, must
--- a/test/langtools/jdk/javadoc/doclet/testSummaryTag/TestSummaryTag.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testSummaryTag/TestSummaryTag.java Tue Dec 05 10:28:45 2017 +0000
@@ -102,7 +102,7 @@
"p2");
checkExit(Exit.OK);
- checkOutput(Output.OUT, true, "package.html:5: warning: invalid use of @summary");
+ checkOutput(Output.OUT, true, "package.html:3: warning: invalid use of @summary");
checkOutput("index-all.html", true, "<div class=\"block\">foo bar</div>\n");
--- a/test/langtools/jdk/jshell/CompilerOptionsTest.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/jdk/jshell/CompilerOptionsTest.java Tue Dec 05 10:28:45 2017 +0000
@@ -51,6 +51,6 @@
public void testSourceVersion() {
assertEval("import java.util.function.*;", added(VALID));
assertDeclareFail("Function<Integer,Integer> f = x -> x*2;",
- new ExpectedDiagnostic("compiler.err.lambda.not.supported.in.source", 32, 32, 32, -1, -1, Diagnostic.Kind.ERROR));
+ new ExpectedDiagnostic("compiler.err.feature.not.supported.in.source.plural", 32, 32, 32, -1, -1, Diagnostic.Kind.ERROR));
}
}
--- a/test/langtools/tools/javac/6302184/HiddenOptionsShouldUseGivenEncodingTest.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/6302184/HiddenOptionsShouldUseGivenEncodingTest.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,28 +29,62 @@
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
- * @build toolbox.ToolBox
- * @run compile -encoding iso-8859-1 -XD-printsource T6302184.java
+ * @build toolbox.ToolBox toolbox.JavacTask
* @run main HiddenOptionsShouldUseGivenEncodingTest
*/
+import java.nio.charset.Charset;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Arrays;
import java.util.List;
+import toolbox.JavacTask;
import toolbox.ToolBox;
// Original test: test/tools/javac/6302184/T6302184.sh
public class HiddenOptionsShouldUseGivenEncodingTest {
public static void main(String[] args) throws Exception {
+ String encoding = "iso-8859-1";
+ Path src = Paths.get("src");
+ Files.createDirectories(src);
+ Files.write(src.resolve("T6302184.java"), source, Charset.forName(encoding));
+ Files.write(src.resolve("T6302184.out"), expect, Charset.forName(encoding));
+
+ Path out = Paths.get("out");
+ Files.createDirectories(out);
+
ToolBox tb = new ToolBox();
- String encoding = "iso-8859-1";
- Path path1 = Paths.get(ToolBox.testClasses, "T6302184.java");
+ new JavacTask(tb)
+ .outdir("out")
+ .options("-encoding", encoding, "-XD-printsource")
+ .files(src.resolve("T6302184.java"))
+ .run();
+
+ Path path1 = Paths.get("out").resolve("T6302184.java");
List<String> file1 = tb.readAllLines(path1, encoding);
- Path path2 = Paths.get(ToolBox.testSrc, "T6302184.out");
+ Path path2 = src.resolve("T6302184.out");
List<String> file2 = tb.readAllLines(path2, encoding);
tb.checkEqual(file1, file2);
}
+ static List<String> source = Arrays.asList(
+ "class T6302184 {",
+ " int \u00c0\u00c1\u00c2\u00c3\u00c4\u00c5 = 1;",
+ "}"
+ );
+
+ static List<String> expect = Arrays.asList(
+ "",
+ "class T6302184 {",
+ " ",
+ " T6302184() {",
+ " super();",
+ " }",
+ " int \u00c0\u00c1\u00c2\u00c3\u00c4\u00c5 = 1;",
+ "}"
+ );
+
}
--- a/test/langtools/tools/javac/6302184/T6302184.java Tue Dec 05 10:21:41 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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 is a test that uses ISO 8859 encoding.
- */
-class T6302184 {
- int ÀÁÂÃÄÅ = 1;
-}
--- a/test/langtools/tools/javac/6302184/T6302184.out Tue Dec 05 10:21:41 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-
-/**
- * This is a test that uses ISO 8859 encoding.
- */
-class T6302184 {
-
- T6302184() {
- super();
- }
- int ÀÁÂÃÄÅ = 1;
-}
--- a/test/langtools/tools/javac/StringsInSwitch/BadlyTypedLabel1_6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/StringsInSwitch/BadlyTypedLabel1_6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,7 +1,7 @@
-- compiler.warn.source.no.bootclasspath: 1.6
-- compiler.warn.option.obsolete.source: 1.6
+- compiler.warn.source.no.bootclasspath: 6
+- compiler.warn.option.obsolete.source: 6
- compiler.warn.option.obsolete.suppression
-BadlyTypedLabel1.java:10:15: compiler.err.string.switch.not.supported.in.source: 1.6
+BadlyTypedLabel1.java:10:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.string.switch), 6, 7
BadlyTypedLabel1.java:13:14: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.String)
2 errors
3 warnings
--- a/test/langtools/tools/javac/StringsInSwitch/BadlyTypedLabel2_6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/StringsInSwitch/BadlyTypedLabel2_6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,7 +1,7 @@
-- compiler.warn.source.no.bootclasspath: 1.6
-- compiler.warn.option.obsolete.source: 1.6
+- compiler.warn.source.no.bootclasspath: 6
+- compiler.warn.option.obsolete.source: 6
- compiler.warn.option.obsolete.suppression
-BadlyTypedLabel2.java:12:15: compiler.err.string.switch.not.supported.in.source: 1.6
+BadlyTypedLabel2.java:12:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.string.switch), 6, 7
BadlyTypedLabel2.java:15:14: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.math.RoundingMode, java.lang.String)
2 errors
3 warnings
--- a/test/langtools/tools/javac/StringsInSwitch/NonConstantLabel6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/StringsInSwitch/NonConstantLabel6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,7 +1,7 @@
-- compiler.warn.source.no.bootclasspath: 1.6
-- compiler.warn.option.obsolete.source: 1.6
+- compiler.warn.source.no.bootclasspath: 6
+- compiler.warn.option.obsolete.source: 6
- compiler.warn.option.obsolete.suppression
-NonConstantLabel.java:11:15: compiler.err.string.switch.not.supported.in.source: 1.6
+NonConstantLabel.java:11:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.string.switch), 6, 7
NonConstantLabel.java:14:14: compiler.err.string.const.req
2 errors
3 warnings
--- a/test/langtools/tools/javac/StringsInSwitch/OneCaseSwitches.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/StringsInSwitch/OneCaseSwitches.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,6 +1,6 @@
-- compiler.warn.source.no.bootclasspath: 1.6
-- compiler.warn.option.obsolete.source: 1.6
+- compiler.warn.source.no.bootclasspath: 6
+- compiler.warn.option.obsolete.source: 6
- compiler.warn.option.obsolete.suppression
-OneCaseSwitches.java:23:15: compiler.err.string.switch.not.supported.in.source: 1.6
+OneCaseSwitches.java:23:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.string.switch), 6, 7
1 error
-3 warnings
\ No newline at end of file
+3 warnings
--- a/test/langtools/tools/javac/StringsInSwitch/RSCL1_6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/StringsInSwitch/RSCL1_6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,7 +1,7 @@
-- compiler.warn.source.no.bootclasspath: 1.6
-- compiler.warn.option.obsolete.source: 1.6
+- compiler.warn.source.no.bootclasspath: 6
+- compiler.warn.option.obsolete.source: 6
- compiler.warn.option.obsolete.suppression
-RepeatedStringCaseLabels1.java:10:15: compiler.err.string.switch.not.supported.in.source: 1.6
+RepeatedStringCaseLabels1.java:10:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.string.switch), 6, 7
RepeatedStringCaseLabels1.java:13:9: compiler.err.duplicate.case.label
2 errors
3 warnings
--- a/test/langtools/tools/javac/StringsInSwitch/RSCL2_6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/StringsInSwitch/RSCL2_6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,7 +1,7 @@
-- compiler.warn.source.no.bootclasspath: 1.6
-- compiler.warn.option.obsolete.source: 1.6
+- compiler.warn.source.no.bootclasspath: 6
+- compiler.warn.option.obsolete.source: 6
- compiler.warn.option.obsolete.suppression
-RepeatedStringCaseLabels2.java:11:15: compiler.err.string.switch.not.supported.in.source: 1.6
+RepeatedStringCaseLabels2.java:11:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.string.switch), 6, 7
RepeatedStringCaseLabels2.java:14:9: compiler.err.duplicate.case.label
2 errors
3 warnings
--- a/test/langtools/tools/javac/TryWithResources/BadTwr6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/TryWithResources/BadTwr6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,6 +1,6 @@
-- compiler.warn.source.no.bootclasspath: 1.6
-- compiler.warn.option.obsolete.source: 1.6
+- compiler.warn.source.no.bootclasspath: 6
+- compiler.warn.option.obsolete.source: 6
- compiler.warn.option.obsolete.suppression
-BadTwr.java:13:12: compiler.err.try.with.resources.not.supported.in.source: 1.6
+BadTwr.java:13:12: compiler.err.feature.not.supported.in.source: (compiler.misc.feature.try.with.resources), 6, 7
1 error
3 warnings
--- a/test/langtools/tools/javac/TryWithResources/BadTwrSyntax6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/TryWithResources/BadTwrSyntax6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,7 +1,7 @@
-- compiler.warn.source.no.bootclasspath: 1.6
-- compiler.warn.option.obsolete.source: 1.6
+- compiler.warn.source.no.bootclasspath: 6
+- compiler.warn.option.obsolete.source: 6
- compiler.warn.option.obsolete.suppression
-BadTwrSyntax.java:14:12: compiler.err.try.with.resources.not.supported.in.source: 1.6
+BadTwrSyntax.java:14:12: compiler.err.feature.not.supported.in.source: (compiler.misc.feature.try.with.resources), 6, 7
BadTwrSyntax.java:14:43: compiler.err.illegal.start.of.expr
2 errors
3 warnings
--- a/test/langtools/tools/javac/TryWithResources/TwrForVariable1.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/TryWithResources/TwrForVariable1.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,2 +1,2 @@
-TwrForVariable1.java:13:14: compiler.err.var.in.try.with.resources.not.supported.in.source: 1.8
+TwrForVariable1.java:13:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.var.in.try.with.resources), 8, 9
1 error
--- a/test/langtools/tools/javac/TryWithResources/TwrOnNonResource6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/TryWithResources/TwrOnNonResource6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,6 +1,6 @@
-- compiler.warn.source.no.bootclasspath: 1.6
-- compiler.warn.option.obsolete.source: 1.6
+- compiler.warn.source.no.bootclasspath: 6
+- compiler.warn.option.obsolete.source: 6
- compiler.warn.option.obsolete.suppression
-TwrOnNonResource.java:12:12: compiler.err.try.with.resources.not.supported.in.source: 1.6
+TwrOnNonResource.java:12:12: compiler.err.feature.not.supported.in.source: (compiler.misc.feature.try.with.resources), 6, 7
1 error
3 warnings
--- a/test/langtools/tools/javac/TryWithResources/WeirdTwr.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/TryWithResources/WeirdTwr.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,6 +1,6 @@
-- compiler.warn.source.no.bootclasspath: 1.6
-- compiler.warn.option.obsolete.source: 1.6
+- compiler.warn.source.no.bootclasspath: 6
+- compiler.warn.option.obsolete.source: 6
- compiler.warn.option.obsolete.suppression
-WeirdTwr.java:14:12: compiler.err.try.with.resources.not.supported.in.source: 1.6
+WeirdTwr.java:14:12: compiler.err.feature.not.supported.in.source: (compiler.misc.feature.try.with.resources), 6, 7
1 error
3 warnings
--- a/test/langtools/tools/javac/annotations/repeatingAnnotations/WrongVersion6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/annotations/repeatingAnnotations/WrongVersion6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,2 +1,2 @@
-WrongVersion.java:12:9: compiler.err.repeatable.annotations.not.supported.in.source: 1.6
+WrongVersion.java:12:9: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.repeatable.annotations), 6, 8
1 error
--- a/test/langtools/tools/javac/annotations/repeatingAnnotations/WrongVersion7.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/annotations/repeatingAnnotations/WrongVersion7.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,2 +1,2 @@
-WrongVersion.java:12:9: compiler.err.repeatable.annotations.not.supported.in.source: 1.7
+WrongVersion.java:12:9: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.repeatable.annotations), 7, 8
1 error
--- a/test/langtools/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,2 +1,2 @@
-AnnotationVersion.java:12:27: compiler.err.type.annotations.not.supported.in.source: 1.6
+AnnotationVersion.java:12:27: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.type.annotations), 6, 8
1 error
--- a/test/langtools/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/AnnotationVersion7.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,2 +1,2 @@
-AnnotationVersion.java:12:27: compiler.err.type.annotations.not.supported.in.source: 1.7
+AnnotationVersion.java:12:27: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.type.annotations), 7, 8
1 error
--- a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CheckErrorsForSource7.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CheckErrorsForSource7.java Tue Dec 05 10:28:45 2017 +0000
@@ -135,7 +135,7 @@
boolean found = false;
for (Diagnostic<? extends JavaFileObject> d : errors.getDiagnostics()) {
- if (d.getKind() == Diagnostic.Kind.ERROR && EXPECTED_ERRORS.contains(d.getCode())) {
+ if (d.getKind() == Diagnostic.Kind.ERROR && EXPECTED_ERROR.equals(d.getCode())) {
if (found) {
throw new IllegalStateException("More than one expected error found.");
}
@@ -149,10 +149,7 @@
}
}
- static final Set<String> EXPECTED_ERRORS = new HashSet<>(Arrays.asList(
- "compiler.err.type.annotations.not.supported.in.source",
- "compiler.err.annotations.after.type.params.not.supported.in.source"
- ));
+ static final String EXPECTED_ERROR = "compiler.err.feature.not.supported.in.source.plural";
class TestFO extends SimpleJavaFileObject {
private final String content;
--- a/test/langtools/tools/javac/conditional/Conditional.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/conditional/Conditional.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,4 +1,4 @@
-- compiler.warn.source.no.bootclasspath: 1.7
+- compiler.warn.source.no.bootclasspath: 7
Conditional.java:16:38: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.util.List<? extends java.lang.Object>, java.util.List<java.lang.String>)
1 error
1 warning
--- a/test/langtools/tools/javac/defaultMethods/static/StaticInvokeQualified6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/defaultMethods/static/StaticInvokeQualified6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,2 +1,2 @@
-StaticInvokeQualified.java:11:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6
+StaticInvokeQualified.java:11:32: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.static.intf.method.invoke), 6, 8
1 error
--- a/test/langtools/tools/javac/defaultMethods/static/StaticInvokeQualified7.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/defaultMethods/static/StaticInvokeQualified7.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,2 +1,2 @@
-StaticInvokeQualified.java:11:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7
+StaticInvokeQualified.java:11:32: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.static.intf.method.invoke), 7, 8
1 error
--- a/test/langtools/tools/javac/defaultMethods/static/StaticInvokeSimple6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/defaultMethods/static/StaticInvokeSimple6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,2 +1,2 @@
-StaticInvokeSimple.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6
+StaticInvokeSimple.java:12:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.static.intf.method.invoke), 6, 8
1 error
--- a/test/langtools/tools/javac/defaultMethods/static/StaticInvokeSimple7.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/defaultMethods/static/StaticInvokeSimple7.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,2 +1,2 @@
-StaticInvokeSimple.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7
-1 error
\ No newline at end of file
+StaticInvokeSimple.java:12:15: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.static.intf.method.invoke), 7, 8
+1 error
--- a/test/langtools/tools/javac/depDocComment/SuppressDeprecation8.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/depDocComment/SuppressDeprecation8.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,4 +1,4 @@
-- compiler.warn.source.no.bootclasspath: 1.8
+- compiler.warn.source.no.bootclasspath: 8
SuppressDeprecation.java:83:10: compiler.warn.has.been.deprecated: g(), T
SuppressDeprecation.java:84:14: compiler.warn.has.been.deprecated: g(), T
SuppressDeprecation.java:85:9: compiler.warn.has.been.deprecated: var, T
--- a/test/langtools/tools/javac/diags/examples.not-yet.txt Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples.not-yet.txt Tue Dec 05 10:28:45 2017 +0000
@@ -61,6 +61,7 @@
compiler.misc.fatal.err.cant.locate.field # Resolve, from Lower
compiler.misc.fatal.err.cant.locate.meth # Resolve, from Lower
compiler.misc.fatal.err.cant.close # JavaCompiler
+compiler.misc.feature.not.supported.in.source.plural # cannot happen (for now)
compiler.misc.file.does.not.contain.package
compiler.misc.illegal.start.of.class.file
compiler.misc.inferred.do.not.conform.to.lower.bounds # cannot happen?
--- a/test/langtools/tools/javac/diags/examples/AnnotationsAfterTypeParamsNotSupportedInSource.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/AnnotationsAfterTypeParamsNotSupportedInSource.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.annotations.after.type.params.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.annotations.after.type.params
// key: compiler.warn.source.no.bootclasspath
// options: -source 7
--- a/test/langtools/tools/javac/diags/examples/DefaultMethodNotSupported.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/DefaultMethodNotSupported.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.default.methods.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.default.methods
// options: -source 7 -Xlint:-options
interface DefaultMethodNotSupported {
--- a/test/langtools/tools/javac/diags/examples/DiamondAndAnonClass.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/DiamondAndAnonClass.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.misc.diamond.and.anon.class.not.supported.in.source
+// key: compiler.misc.feature.not.supported.in.source
+// key: compiler.misc.feature.diamond.and.anon.class
// key: compiler.err.cant.apply.diamond.1
// key: compiler.warn.source.no.bootclasspath
// options: -source 8
--- a/test/langtools/tools/javac/diags/examples/DiamondNotSupported.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/DiamondNotSupported.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.diamond.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source
+// key: compiler.misc.feature.diamond
// options: -source 6 -Xlint:-options
import java.util.*;
--- a/test/langtools/tools/javac/diags/examples/IntersectionTypesInCastNotSupported.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/IntersectionTypesInCastNotSupported.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.intersection.types.in.cast.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.intersection.types.in.cast
// options: -source 7 -Xlint:-options
interface IntersectionTypesInCastNotSupported {
--- a/test/langtools/tools/javac/diags/examples/LambdaNotSupported.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/LambdaNotSupported.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.lambda.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.lambda
// options: -source 7 -Xlint:-options
class LambdaNotSupported {
--- a/test/langtools/tools/javac/diags/examples/MethodReferencesNotSupported.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/MethodReferencesNotSupported.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.method.references.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.method.references
// options: -source 7 -Xlint:-options
class MethodReferencesNotSupported {
--- a/test/langtools/tools/javac/diags/examples/ModulesNotSupportedInSource/module-info.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/ModulesNotSupportedInSource/module-info.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.modules.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.modules
// key: compiler.warn.source.no.bootclasspath
// options: -source 8 -Xlint:-path
--- a/test/langtools/tools/javac/diags/examples/MulticatchNotSupported.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/MulticatchNotSupported.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.multicatch.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.multicatch
// options: -source 1.6 -Xlint:-options
class MulticatchNotSupported {
--- a/test/langtools/tools/javac/diags/examples/PrivateInterfaceMethodsNotSupported.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/PrivateInterfaceMethodsNotSupported.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.private.intf.methods.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.private.intf.methods
// key: compiler.warn.source.no.bootclasspath
// options: -source 8
--- a/test/langtools/tools/javac/diags/examples/RepeatableAnnotationsNotSupported.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/RepeatableAnnotationsNotSupported.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.repeatable.annotations.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.repeatable.annotations
// key: compiler.warn.source.no.bootclasspath
// options: -source 7
--- a/test/langtools/tools/javac/diags/examples/StaticIntfMethodInvokeNotSupported.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/StaticIntfMethodInvokeNotSupported.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.static.intf.method.invoke.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.static.intf.method.invoke
// options: -source 7 -Xlint:-options
import java.util.stream.Stream;
--- a/test/langtools/tools/javac/diags/examples/StaticIntfMethodNotSupported.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/StaticIntfMethodNotSupported.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.static.intf.methods.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.static.intf.methods
// options: -source 7 -Xlint:-options -XDallowStaticInterfaceMethods
interface StaticIntfMethodNotSupported {
--- a/test/langtools/tools/javac/diags/examples/StringSwitchNotSupported.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/StringSwitchNotSupported.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.string.switch.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.string.switch
// options: -source 6 -Xlint:-options
class StringSwitchNotSupported {
--- a/test/langtools/tools/javac/diags/examples/TryResourceNotSupported.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/TryResourceNotSupported.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.try.with.resources.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source
+// key: compiler.misc.feature.try.with.resources
// options: -source 1.6 -Xlint:-options
import java.io.*;
--- a/test/langtools/tools/javac/diags/examples/TypeAnnotationsNotSupported.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/TypeAnnotationsNotSupported.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.type.annotations.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.type.annotations
// key: compiler.warn.source.no.bootclasspath
// options: -source 7
--- a/test/langtools/tools/javac/diags/examples/UnsupportedBinaryLiteral.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/UnsupportedBinaryLiteral.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.unsupported.binary.lit
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.binary.lit
// options: -source 6 -Xlint:-options
class UnsupportedBinaryLiteral {
--- a/test/langtools/tools/javac/diags/examples/UnsupportedUnderscoreLiteral.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/UnsupportedUnderscoreLiteral.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.unsupported.underscore.lit
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.underscore.lit
// options: -source 6 -Xlint:-options
class UnsupportedUnderscoreLiteral {
--- a/test/langtools/tools/javac/diags/examples/VarInTryWithResourcesNotSupportedInSource.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/diags/examples/VarInTryWithResourcesNotSupportedInSource.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,7 +21,8 @@
* questions.
*/
-// key: compiler.err.var.in.try.with.resources.not.supported.in.source
+// key: compiler.err.feature.not.supported.in.source.plural
+// key: compiler.misc.feature.var.in.try.with.resources
// key: compiler.warn.source.no.bootclasspath
// options: -source 8
--- a/test/langtools/tools/javac/doctree/DocCommentTester.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/doctree/DocCommentTester.java Tue Dec 05 10:28:45 2017 +0000
@@ -404,9 +404,18 @@
public Void visitDocComment(DocCommentTree node, Void p) {
header(node);
indent(+1);
+ // Applicable only to html files, print iff non-empty
+ if (!node.getPreamble().isEmpty())
+ print("preamble", node.getPreamble());
+
print("firstSentence", node.getFirstSentence());
print("body", node.getBody());
print("block tags", node.getBlockTags());
+
+ // Applicable only to html files, print iff non-empty
+ if (!node.getPostamble().isEmpty())
+ print("postamble", node.getPostamble());
+
indent(-1);
indent();
out.println("]");
@@ -418,6 +427,11 @@
return null;
}
+ public Void visitDocType(DocTypeTree node, Void p) {
+ header(node, compress(node.getText()));
+ return null;
+ }
+
public Void visitEndElement(EndElementTree node, Void p) {
header(node, node.getName().toString());
return null;
--- a/test/langtools/tools/javac/doctree/SimpleDocTreeVisitorTest.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/doctree/SimpleDocTreeVisitorTest.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,7 @@
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.DocTree.Kind;
import com.sun.source.doctree.DocTreeVisitor;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
@@ -84,7 +85,7 @@
}
for (DocTree.Kind k: DocTree.Kind.values()) {
- if (!found.contains(k) && k != DocTree.Kind.OTHER)
+ if (!found.contains(k) && k != DocTree.Kind.OTHER && k != DocTree.Kind.DOC_TYPE)
error("not found: " + k);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/Anchor.java Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Anchor test.
+ */
+public class Anchor {}
--- a/test/langtools/tools/javac/doctree/dcapi/DocCommentTreeApiTester.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/DocCommentTreeApiTester.java Tue Dec 05 10:28:45 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* 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 8132096 8157611
+ * @bug 8132096 8157611 8190552
* @summary test the APIs in the DocTree interface
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.file
@@ -52,6 +52,7 @@
import javax.lang.model.util.Elements;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardJavaFileManager;
import com.sun.source.doctree.DocTree;
@@ -64,8 +65,8 @@
public class DocCommentTreeApiTester {
- private static final String MARKER_START = "<!-- EXPECT_START";
- private static final String MARKER_END = "EXPECT_END -->";
+ private static final String MARKER_START = "EXPECT_START";
+ private static final String MARKER_END = "EXPECT_END";
private static final String testSrc = System.getProperty("test.src", ".");
@@ -85,22 +86,26 @@
DocCommentTreeApiTester test = new DocCommentTreeApiTester();
try {
// test getting a DocTree from an element
- test.runElementAndBreakIteratorTests("OverviewTest.java", "OverviewTest test.");
+ test.runElementAndBreakIteratorTests("Anchor.java", "Anchor test.");
// test relative paths in a class within a package
- test.runRelativePathTest("pkg/Anchor.java", "package.html");
+ test.runRelativePathTest("pkg/Anchor.java", "package.html", true);
// tests files relative path in an unnamed package
- test.runRelativePathTest("OverviewTest.java", "overview0.html");
+ test.runRelativePathTest("Anchor.java", "overview0.html", true);
- // tests doctreepath using package element and package.html
- test.runDocTreePath("pkg/Anchor.java", "package.html");
+ // test doctree path and Doc
+ test.runDocTreePath("Anchor.java", "package.html");
// test for correct parsing using valid and some invalid html tags
- for (int i = 0; i < 7; i++) {
- String hname = "overview" + i + ".html";
- test.runFileObjectTest(hname);
- }
+ test.runFileObjectTest("overview0.html");
+ test.runFileObjectTest("overview1.html");
+ test.runFileObjectTest("overview2.html");
+ test.runFileObjectTest("overview3.html");
+ test.runFileObjectTest("overview4.html");
+ test.runFileObjectTest("overview5.html");
+ test.runFileObjectTest("overview6.html");
+ test.runFileObjectTest("overview7.html");
} finally {
test.status();
@@ -166,7 +171,8 @@
* @param fileName the relative html file
* @throws java.lang.Exception ouch
*/
- public void runRelativePathTest(String javaFileName, String fileName) throws Exception {
+ public void runRelativePathTest(String javaFileName, String fileName,
+ boolean bodyOnly) throws Exception {
List<File> javaFiles = new ArrayList<>();
javaFiles.add(new File(testSrc, javaFileName));
@@ -185,13 +191,17 @@
Element klass = elements.iterator().next();
DocCommentTree dcTree = trees.getDocCommentTree(klass, fileName);
+
+ if (dcTree == null)
+ throw new Error("invalid input: " + fileName);
+
StringWriter sw = new StringWriter();
printer.print(dcTree, sw);
String found = sw.toString();
FileObject htmlFo = fm.getFileForInput(javax.tools.StandardLocation.SOURCE_PATH,
t.getElements().getPackageOf(klass).getQualifiedName().toString(),
- fileName);
+ fileName + ".out");
String expected = getExpected(htmlFo.openReader(true));
astcheck(fileName, expected, found);
@@ -209,6 +219,7 @@
List<File> otherFiles = new ArrayList<>();
otherFiles.add(new File(testSrc, htmlfileName));
+ otherFiles.add(new File(testSrc, htmlfileName + ".out"));
try (StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null)) {
Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(javaFiles);
@@ -218,10 +229,22 @@
final DocTrees trees = DocTrees.instance(t);
StringWriter sw = new StringWriter();
+ DocCommentTree dct = null;
+ String expected = null;
+ for (JavaFileObject jfo : others) {
+ switch (jfo.getKind()) {
+ case HTML:
+ dct = trees.getDocCommentTree(jfo);
+ if (dct == null)
+ throw new Exception("invalid input: " + jfo);
+ break;
+ default:
+ expected = getExpected(jfo.openReader(true));
+ }
+ }
- printer.print(trees.getDocCommentTree(others.iterator().next()), sw);
+ printer.print(dct, sw);
String found = sw.toString();
- String expected = getExpected(otherFiles.iterator().next().toPath());
astcheck(otherFiles.toString(), expected, found);
}
}
@@ -237,6 +260,9 @@
List<File> javaFiles = new ArrayList<>();
javaFiles.add(new File(testSrc, javaFileName));
+ List<File> otherFiles = new ArrayList<>();
+ otherFiles.add(new File(testSrc, pkgFileName + ".out"));
+
List<File> dirs = new ArrayList<>();
dirs.add(new File(testSrc));
@@ -256,15 +282,23 @@
FileObject htmlFo = fm.getFileForInput(javax.tools.StandardLocation.SOURCE_PATH,
t.getElements().getPackageOf(klass).getQualifiedName().toString(),
"package.html");
- System.out.println();
DocTreePath treePath = trees.getDocTreePath(htmlFo, pkg);
+
+ if (treePath == null) {
+ throw new Exception("invalid input: " + htmlFo);
+ }
+
DocCommentTree dcTree = treePath.getDocComment();
+ if (dcTree == null)
+ throw new Exception("invalid input" + htmlFo);
StringWriter sw = new StringWriter();
printer.print(dcTree, sw);
String found = sw.toString();
+ Iterable<? extends JavaFileObject> oos = fm.getJavaFileObjectsFromFiles(otherFiles);
+ JavaFileObject otherFo = oos.iterator().next();
+ String expected = getExpected(otherFo.openReader(true));
- String expected = getExpected(htmlFo.openReader(true));
astcheck(pkgFileName, expected, found);
}
}
@@ -300,10 +334,6 @@
return getExpected(lines);
}
- String getExpected(Path p) throws IOException {
- return getExpected(Files.readAllLines(p));
- }
-
String getExpected(List<String> lines) {
boolean start = false;
StringWriter sw = new StringWriter();
--- a/test/langtools/tools/javac/doctree/dcapi/OverviewTest.java Tue Dec 05 10:21:41 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * OverviewTest test.
- */
-public class OverviewTest {}
--- a/test/langtools/tools/javac/doctree/dcapi/overview0.html Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview0.html Tue Dec 05 10:28:45 2017 +0000
@@ -1,48 +1,8 @@
-<!--
- Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
--->
-<!-- EXPECT_START
-DocComment[DOC_COMMENT, pos:1
- firstSentence: 1
- Text[TEXT, pos:1, A_simple_well_fo...rmed_html_document]
- body: 4
- StartElement[START_ELEMENT, pos:36
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:41, overview0.html]
- StartElement[START_ELEMENT, pos:55
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:60, .]
- block tags: empty
-]
-EXPECT_END -->
+<!-- /nodynamiccopyright/ -->
<HTML>
<HEAD>
</HEAD>
<BODY>
-A simple well formed html document <pre>overview0.html<pre>.
+A simple well formed html document <pre>overview0.html</pre>.
</BODY>
-</HTML>
-
+</HTML>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview0.html.out Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,33 @@
+EXPECT_START
+DocComment[DOC_COMMENT, pos:0
+ preamble: 5
+ Comment[COMMENT, pos:0, <!--_/nodynamiccopyright/_-->]
+ StartElement[START_ELEMENT, pos:30
+ name:HTML
+ attributes: empty
+ ]
+ StartElement[START_ELEMENT, pos:37
+ name:HEAD
+ attributes: empty
+ ]
+ EndElement[END_ELEMENT, pos:44, HEAD]
+ StartElement[START_ELEMENT, pos:52
+ name:BODY
+ attributes: empty
+ ]
+ firstSentence: 1
+ Text[TEXT, pos:59, A_simple_well_fo...rmed_html_document]
+ body: 4
+ StartElement[START_ELEMENT, pos:94
+ name:pre
+ attributes: empty
+ ]
+ Text[TEXT, pos:99, overview0.html]
+ EndElement[END_ELEMENT, pos:113, pre]
+ Text[TEXT, pos:119, .]
+ block tags: empty
+ postamble: 2
+ EndElement[END_ELEMENT, pos:121, BODY]
+ EndElement[END_ELEMENT, pos:129, HTML]
+]
+EXPECT_END
--- a/test/langtools/tools/javac/doctree/dcapi/overview1.html Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview1.html Tue Dec 05 10:28:45 2017 +0000
@@ -1,47 +1,8 @@
-<!--
- Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
--->
-<!-- EXPECT_START
-DocComment[DOC_COMMENT, pos:1
- firstSentence: 1
- Text[TEXT, pos:1, Html_document]
- body: 4
- StartElement[START_ELEMENT, pos:15
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:20, overview1.html]
- StartElement[START_ELEMENT, pos:34
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:39, .|Missing_HTML.]
- block tags: empty
-]
-EXPECT_END -->
+<!-- /nodynamiccopyright/ -->
<HEAD>
</HEAD>
<BODY>
-Html document <pre>overview1.html<pre>.
+Html document <pre>overview1.html</pre>.
Missing HTML.
</BODY>
-</HTML>
+</HTML>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview1.html.out Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,29 @@
+EXPECT_START
+DocComment[DOC_COMMENT, pos:0
+ preamble: 4
+ Comment[COMMENT, pos:0, <!--_/nodynamiccopyright/_-->]
+ StartElement[START_ELEMENT, pos:30
+ name:HEAD
+ attributes: empty
+ ]
+ EndElement[END_ELEMENT, pos:37, HEAD]
+ StartElement[START_ELEMENT, pos:45
+ name:BODY
+ attributes: empty
+ ]
+ firstSentence: 1
+ Text[TEXT, pos:52, Html_document]
+ body: 4
+ StartElement[START_ELEMENT, pos:66
+ name:pre
+ attributes: empty
+ ]
+ Text[TEXT, pos:71, overview1.html]
+ EndElement[END_ELEMENT, pos:85, pre]
+ Text[TEXT, pos:91, .|Missing_HTML.]
+ block tags: empty
+ postamble: 2
+ EndElement[END_ELEMENT, pos:107, BODY]
+ EndElement[END_ELEMENT, pos:115, HTML]
+]
+EXPECT_END
--- a/test/langtools/tools/javac/doctree/dcapi/overview2.html Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview2.html Tue Dec 05 10:28:45 2017 +0000
@@ -1,47 +1,8 @@
-<!--
- Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
--->
-<!-- EXPECT_START
-DocComment[DOC_COMMENT, pos:1
- firstSentence: 1
- Text[TEXT, pos:1, Html_document]
- body: 4
- StartElement[START_ELEMENT, pos:15
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:20, overview2.html]
- StartElement[START_ELEMENT, pos:34
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:39, .|Missing_HEAD.]
- block tags: empty
-]
-EXPECT_END -->
+<!-- /nodynamiccopyright/ -->
<HTML>
</HEAD>
<BODY>
-Html document <pre>overview2.html<pre>.
+Html document <pre>overview2.html</pre>.
Missing HEAD.
</BODY>
-</HTML>
+</HTML>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview2.html.out Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,29 @@
+EXPECT_START
+DocComment[DOC_COMMENT, pos:0
+ preamble: 4
+ Comment[COMMENT, pos:0, <!--_/nodynamiccopyright/_-->]
+ StartElement[START_ELEMENT, pos:30
+ name:HTML
+ attributes: empty
+ ]
+ EndElement[END_ELEMENT, pos:37, HEAD]
+ StartElement[START_ELEMENT, pos:45
+ name:BODY
+ attributes: empty
+ ]
+ firstSentence: 1
+ Text[TEXT, pos:52, Html_document]
+ body: 4
+ StartElement[START_ELEMENT, pos:66
+ name:pre
+ attributes: empty
+ ]
+ Text[TEXT, pos:71, overview2.html]
+ EndElement[END_ELEMENT, pos:85, pre]
+ Text[TEXT, pos:91, .|Missing_HEAD.]
+ block tags: empty
+ postamble: 2
+ EndElement[END_ELEMENT, pos:107, BODY]
+ EndElement[END_ELEMENT, pos:115, HTML]
+]
+EXPECT_END
--- a/test/langtools/tools/javac/doctree/dcapi/overview3.html Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview3.html Tue Dec 05 10:28:45 2017 +0000
@@ -1,47 +1,8 @@
-<!--
- Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
--->
-<!-- EXPECT_START
-DocComment[DOC_COMMENT, pos:1
- firstSentence: 1
- Text[TEXT, pos:1, Html_document]
- body: 4
- StartElement[START_ELEMENT, pos:15
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:20, overview3.html]
- StartElement[START_ELEMENT, pos:34
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:39, .|Missing_enclosing_HEAD.]
- block tags: empty
-]
-EXPECT_END -->
+<!-- /nodynamiccopyright/ -->
<HTML>
<HEAD>
<BODY>
-Html document <pre>overview3.html<pre>.
+Html document <pre>overview3.html</pre>.
Missing enclosing HEAD.
</BODY>
-</HTML>
+</HTML>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview3.html.out Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,32 @@
+EXPECT_START
+DocComment[DOC_COMMENT, pos:0
+ preamble: 4
+ Comment[COMMENT, pos:0, <!--_/nodynamiccopyright/_-->]
+ StartElement[START_ELEMENT, pos:30
+ name:HTML
+ attributes: empty
+ ]
+ StartElement[START_ELEMENT, pos:37
+ name:HEAD
+ attributes: empty
+ ]
+ StartElement[START_ELEMENT, pos:44
+ name:BODY
+ attributes: empty
+ ]
+ firstSentence: 1
+ Text[TEXT, pos:51, Html_document]
+ body: 4
+ StartElement[START_ELEMENT, pos:65
+ name:pre
+ attributes: empty
+ ]
+ Text[TEXT, pos:70, overview3.html]
+ EndElement[END_ELEMENT, pos:84, pre]
+ Text[TEXT, pos:90, .|Missing_enclosing_HEAD.]
+ block tags: empty
+ postamble: 2
+ EndElement[END_ELEMENT, pos:116, BODY]
+ EndElement[END_ELEMENT, pos:124, HTML]
+]
+EXPECT_END
--- a/test/langtools/tools/javac/doctree/dcapi/overview4.html Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview4.html Tue Dec 05 10:28:45 2017 +0000
@@ -1,44 +1,6 @@
-<!--
- Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+<!-- /nodynamiccopyright/ -->
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
--->
-<!-- EXPECT_START
-DocComment[DOC_COMMENT, pos:1
- firstSentence: 1
- Text[TEXT, pos:1, Html_document]
- body: 4
- StartElement[START_ELEMENT, pos:15
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:20, overview4.html]
- StartElement[START_ELEMENT, pos:34
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:39, .|Only_BODY]
- block tags: empty
-]
-EXPECT_END -->
<BODY>
-Html document <pre>overview4.html<pre>.
+Html document <pre>overview4.html</pre>.
Only BODY
-</BODY>
+</BODY>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview4.html.out Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,23 @@
+EXPECT_START
+DocComment[DOC_COMMENT, pos:0
+ preamble: 2
+ Comment[COMMENT, pos:0, <!--_/nodynamiccopyright/_-->]
+ StartElement[START_ELEMENT, pos:31
+ name:BODY
+ attributes: empty
+ ]
+ firstSentence: 1
+ Text[TEXT, pos:38, Html_document]
+ body: 4
+ StartElement[START_ELEMENT, pos:52
+ name:pre
+ attributes: empty
+ ]
+ Text[TEXT, pos:57, overview4.html]
+ EndElement[END_ELEMENT, pos:71, pre]
+ Text[TEXT, pos:77, .|Only_BODY]
+ block tags: empty
+ postamble: 1
+ EndElement[END_ELEMENT, pos:89, BODY]
+]
+EXPECT_END
--- a/test/langtools/tools/javac/doctree/dcapi/overview5.html Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview5.html Tue Dec 05 10:28:45 2017 +0000
@@ -1,47 +1,8 @@
-<!--
- Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
--->
-<!-- EXPECT_START
-DocComment[DOC_COMMENT, pos:1
- firstSentence: 1
- Text[TEXT, pos:1, Html_document]
- body: 4
- StartElement[START_ELEMENT, pos:15
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:20, overview5.html]
- StartElement[START_ELEMENT, pos:34
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:39, .|Missing_enclosing_HTML]
- block tags: empty
-]
-EXPECT_END -->
+<!-- /nodynamiccopyright/ -->
<HTML>
<HEAD>
</HEAD>
<BODY>
-Html document <pre>overview5.html<pre>.
+Html document <pre>overview5.html</pre>.
Missing enclosing HTML
-</BODY>
+</BODY>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview5.html.out Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,32 @@
+EXPECT_START
+DocComment[DOC_COMMENT, pos:0
+ preamble: 5
+ Comment[COMMENT, pos:0, <!--_/nodynamiccopyright/_-->]
+ StartElement[START_ELEMENT, pos:30
+ name:HTML
+ attributes: empty
+ ]
+ StartElement[START_ELEMENT, pos:37
+ name:HEAD
+ attributes: empty
+ ]
+ EndElement[END_ELEMENT, pos:44, HEAD]
+ StartElement[START_ELEMENT, pos:52
+ name:BODY
+ attributes: empty
+ ]
+ firstSentence: 1
+ Text[TEXT, pos:59, Html_document]
+ body: 4
+ StartElement[START_ELEMENT, pos:73
+ name:pre
+ attributes: empty
+ ]
+ Text[TEXT, pos:78, overview5.html]
+ EndElement[END_ELEMENT, pos:92, pre]
+ Text[TEXT, pos:98, .|Missing_enclosing_HTML]
+ block tags: empty
+ postamble: 1
+ EndElement[END_ELEMENT, pos:123, BODY]
+]
+EXPECT_END
--- a/test/langtools/tools/javac/doctree/dcapi/overview6.html Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview6.html Tue Dec 05 10:28:45 2017 +0000
@@ -1,40 +1,4 @@
-<!--
- Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
--->
-<!-- EXPECT_START
-DocComment[DOC_COMMENT, pos:1
- firstSentence: 1
- Text[TEXT, pos:1, The_first_correct_body_pair.]
- body: 4
- EndElement[END_ELEMENT, pos:30, BODY]
- Text[TEXT, pos:37, ||]
- StartElement[START_ELEMENT, pos:39
- name:BODY
- attributes: empty
- ]
- Text[TEXT, pos:45, |Illegal_second_...body_pair,_the_first_body_should_not_be_ignored.]
- block tags: empty
-]
-EXPECT_END -->
+<!-- /nodynamiccopyright/ -->
<HTML>
<HEAD>
</HEAD>
@@ -46,4 +10,3 @@
Illegal second body pair, the first body should not be ignored.
</BODY>
</HTML>
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview6.html.out Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,32 @@
+EXPECT_START
+DocComment[DOC_COMMENT, pos:0
+ preamble: 5
+ Comment[COMMENT, pos:0, <!--_/nodynamiccopyright/_-->]
+ StartElement[START_ELEMENT, pos:30
+ name:HTML
+ attributes: empty
+ ]
+ StartElement[START_ELEMENT, pos:37
+ name:HEAD
+ attributes: empty
+ ]
+ EndElement[END_ELEMENT, pos:44, HEAD]
+ StartElement[START_ELEMENT, pos:52
+ name:BODY
+ attributes: empty
+ ]
+ firstSentence: 1
+ Text[TEXT, pos:59, The_first_correct_body_pair.]
+ body: empty
+ block tags: empty
+ postamble: 5
+ EndElement[END_ELEMENT, pos:88, BODY]
+ StartElement[START_ELEMENT, pos:97
+ name:BODY
+ attributes: empty
+ ]
+ Text[TEXT, pos:104, Illegal_second_b...ody_pair,_the_first_body_should_not_be_ignored.|]
+ EndElement[END_ELEMENT, pos:168, BODY]
+ EndElement[END_ELEMENT, pos:176, HTML]
+]
+EXPECT_END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview7.html Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,6 @@
+<!-- /nodynamiccopyright/ -->
+<HTML>
+<HEAD>
+</HEAD>
+<BODY>@since 1.0</BODY>
+</HTML>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/overview7.html.out Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,29 @@
+EXPECT_START
+DocComment[DOC_COMMENT, pos:0
+ preamble: 5
+ Comment[COMMENT, pos:0, <!--_/nodynamiccopyright/_-->]
+ StartElement[START_ELEMENT, pos:30
+ name:HTML
+ attributes: empty
+ ]
+ StartElement[START_ELEMENT, pos:37
+ name:HEAD
+ attributes: empty
+ ]
+ EndElement[END_ELEMENT, pos:44, HEAD]
+ StartElement[START_ELEMENT, pos:52
+ name:BODY
+ attributes: empty
+ ]
+ firstSentence: empty
+ body: empty
+ block tags: 1
+ Since[SINCE, pos:58
+ body: 1
+ Text[TEXT, pos:65, 1.0]
+ ]
+ postamble: 2
+ EndElement[END_ELEMENT, pos:68, BODY]
+ EndElement[END_ELEMENT, pos:76, HTML]
+]
+EXPECT_END
--- a/test/langtools/tools/javac/doctree/dcapi/package.html Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/package.html Tue Dec 05 10:28:45 2017 +0000
@@ -1,47 +1,11 @@
-<!--
- Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
--->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<!-- /nodynamiccopyright/ -->
<HTML>
<HEAD>
+ <TITLE>The Crafty Fox</TITLE>
</HEAD>
<BODY>
A simple well formed html document <pre>package.html<pre>.
</BODY>
-</HTML>
-<!-- EXPECT_START
-DocComment[DOC_COMMENT, pos:1
- firstSentence: 1
- Text[TEXT, pos:1, This_is_a_very_simple]
- body: 4
- StartElement[START_ELEMENT, pos:23
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:28, _well_formed_html_document_]
- StartElement[START_ELEMENT, pos:55
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:60, _using_some_html_tags.]
- block tags: empty
-]
-EXPECT_END -->
+</HTML>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/package.html.out Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,43 @@
+EXPECT_START
+DocComment[DOC_COMMENT, pos:10
+ preamble: 9
+ DocType[DOC_TYPE, pos:10, HTML_PUBLIC_"-//...W3C//DTD_HTML_4.01//EN"|________"http://www.w3.org/TR/html4/strict.dtd"]
+ Comment[COMMENT, pos:99, <!--_/nodynamiccopyright/_-->]
+ StartElement[START_ELEMENT, pos:129
+ name:HTML
+ attributes: empty
+ ]
+ StartElement[START_ELEMENT, pos:136
+ name:HEAD
+ attributes: empty
+ ]
+ StartElement[START_ELEMENT, pos:147
+ name:TITLE
+ attributes: empty
+ ]
+ Text[TEXT, pos:154, The_Crafty_Fox]
+ EndElement[END_ELEMENT, pos:168, TITLE]
+ EndElement[END_ELEMENT, pos:177, HEAD]
+ StartElement[START_ELEMENT, pos:185
+ name:BODY
+ attributes: empty
+ ]
+ firstSentence: 1
+ Text[TEXT, pos:192, A_simple_well_fo...rmed_html_document]
+ body: 4
+ StartElement[START_ELEMENT, pos:227
+ name:pre
+ attributes: empty
+ ]
+ Text[TEXT, pos:232, package.html]
+ StartElement[START_ELEMENT, pos:244
+ name:pre
+ attributes: empty
+ ]
+ Text[TEXT, pos:249, .]
+ block tags: empty
+ postamble: 2
+ EndElement[END_ELEMENT, pos:251, BODY]
+ EndElement[END_ELEMENT, pos:259, HTML]
+]
+EXPECT_END
--- a/test/langtools/tools/javac/doctree/dcapi/pkg/package.html Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/pkg/package.html Tue Dec 05 10:28:45 2017 +0000
@@ -1,48 +1,9 @@
-<!--
- Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
--->
-<!-- EXPECT_START
-DocComment[DOC_COMMENT, pos:1
- firstSentence: 1
- Text[TEXT, pos:1, A_simple_well_fo...rmed_html_document]
- body: 4
- StartElement[START_ELEMENT, pos:36
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:41, package.html]
- StartElement[START_ELEMENT, pos:53
- name:pre
- attributes: empty
- ]
- Text[TEXT, pos:58, .|In_package_pkg.]
- block tags: empty
-]
-EXPECT_END -->
+<!-- /nodynamiccopyright/ -->
<HTML>
<HEAD>
</HEAD>
<BODY>
-A simple well formed html document <pre>package.html<pre>.
+A simple well formed html document <pre>package.html</pre>.
In package pkg.
</BODY>
-</HTML>
+</HTML>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/doctree/dcapi/pkg/package.html.out Tue Dec 05 10:28:45 2017 +0000
@@ -0,0 +1,33 @@
+EXPECT_START
+DocComment[DOC_COMMENT, pos:0
+ preamble: 5
+ Comment[COMMENT, pos:0, <!--__/nodynamiccopyright/_-->]
+ StartElement[START_ELEMENT, pos:31
+ name:HTML
+ attributes: empty
+ ]
+ StartElement[START_ELEMENT, pos:38
+ name:HEAD
+ attributes: empty
+ ]
+ EndElement[END_ELEMENT, pos:45, HEAD]
+ StartElement[START_ELEMENT, pos:53
+ name:BODY
+ attributes: empty
+ ]
+ firstSentence: 1
+ Text[TEXT, pos:60, A_simple_well_fo...rmed_html_document]
+ body: 4
+ StartElement[START_ELEMENT, pos:95
+ name:pre
+ attributes: empty
+ ]
+ Text[TEXT, pos:100, package.html]
+ EndElement[END_ELEMENT, pos:112, pre]
+ Text[TEXT, pos:118, .|In_package_pkg.]
+ block tags: empty
+ postamble: 2
+ EndElement[END_ELEMENT, pos:136, BODY]
+ EndElement[END_ELEMENT, pos:144, HTML]
+]
+EXPECT_END
\ No newline at end of file
--- a/test/langtools/tools/javac/generics/diamond/neg/Neg09a.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/generics/diamond/neg/Neg09a.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,4 +1,4 @@
-- compiler.warn.source.no.bootclasspath: 1.8
-Neg09a.java:15:34: compiler.err.cant.apply.diamond.1: Neg09a.Member<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
+- compiler.warn.source.no.bootclasspath: 8
+Neg09a.java:15:34: compiler.err.cant.apply.diamond.1: Neg09a.Member<X>, (compiler.misc.feature.not.supported.in.source: (compiler.misc.feature.diamond.and.anon.class), 8, 9)
1 error
1 warning
--- a/test/langtools/tools/javac/generics/diamond/neg/Neg09b.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/generics/diamond/neg/Neg09b.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,4 +1,4 @@
-- compiler.warn.source.no.bootclasspath: 1.8
-Neg09b.java:16:34: compiler.err.cant.apply.diamond.1: Neg09b.Nested<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
+- compiler.warn.source.no.bootclasspath: 8
+Neg09b.java:16:34: compiler.err.cant.apply.diamond.1: Neg09b.Nested<X>, (compiler.misc.feature.not.supported.in.source: (compiler.misc.feature.diamond.and.anon.class), 8, 9)
1 error
1 warning
--- a/test/langtools/tools/javac/generics/diamond/neg/Neg09c.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/generics/diamond/neg/Neg09c.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,4 +1,4 @@
-- compiler.warn.source.no.bootclasspath: 1.8
-Neg09c.java:15:39: compiler.err.cant.apply.diamond.1: Neg09c.Member<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
+- compiler.warn.source.no.bootclasspath: 8
+Neg09c.java:15:39: compiler.err.cant.apply.diamond.1: Neg09c.Member<X>, (compiler.misc.feature.not.supported.in.source: (compiler.misc.feature.diamond.and.anon.class), 8, 9)
1 error
1 warning
--- a/test/langtools/tools/javac/generics/diamond/neg/Neg09d.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/generics/diamond/neg/Neg09d.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,4 +1,4 @@
-- compiler.warn.source.no.bootclasspath: 1.8
+- compiler.warn.source.no.bootclasspath: 8
Neg09d.java:16:33: compiler.err.doesnt.exist: Neg09
1 error
1 warning
--- a/test/langtools/tools/javac/generics/inference/6278587/T6278587Neg.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/generics/inference/6278587/T6278587Neg.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,4 +1,4 @@
-- compiler.warn.source.no.bootclasspath: 1.7
+- compiler.warn.source.no.bootclasspath: 7
T6278587Neg.java:18:10: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.lower.bounds: T, T6278587Neg.C)
1 error
1 warning
--- a/test/langtools/tools/javac/generics/odersky/BadTest4.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/generics/odersky/BadTest4.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,4 +1,4 @@
-- compiler.warn.source.no.bootclasspath: 1.7
+- compiler.warn.source.no.bootclasspath: 7
BadTest4.java:38:17: compiler.err.cant.apply.symbol: kindname.method, f, A,B, java.lang.Integer,java.lang.Number, kindname.class, BadTest4.Main, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Number, java.lang.Integer)
1 error
1 warning
--- a/test/langtools/tools/javac/lambda/SourceLevelTest.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/lambda/SourceLevelTest.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,6 +1,6 @@
-- compiler.warn.source.no.bootclasspath: 1.7
-SourceLevelTest.java:11:9: compiler.err.default.methods.not.supported.in.source: 1.7
-SourceLevelTest.java:18:17: compiler.err.lambda.not.supported.in.source: 1.7
-SourceLevelTest.java:19:20: compiler.err.method.references.not.supported.in.source: 1.7
+- compiler.warn.source.no.bootclasspath: 7
+SourceLevelTest.java:11:9: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.default.methods), 7, 8
+SourceLevelTest.java:18:17: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.lambda), 7, 8
+SourceLevelTest.java:19:20: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.method.references), 7, 8
3 errors
1 warning
--- a/test/langtools/tools/javac/lib/DPrinter.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/lib/DPrinter.java Tue Dec 05 10:28:45 2017 +0000
@@ -1028,6 +1028,12 @@
return visitInlineTag(node, null);
}
+ @Override
+ public Void visitDocType(DocTypeTree node, Void aVoid) {
+ printLimitedEscapedString("body", node.getText());
+ return visitTree(node, null);
+ }
+
public Void visitEndElement(EndElementTree node, Void p) {
printName("name", node.getName());
return visitTree(node, null);
--- a/test/langtools/tools/javac/literals/BadBinaryLiterals.6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/literals/BadBinaryLiterals.6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,8 +1,6 @@
-BadBinaryLiterals.java:10:17: compiler.err.unsupported.binary.lit: 1.6
+BadBinaryLiterals.java:10:17: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.binary.lit), 6, 7
BadBinaryLiterals.java:11:24: compiler.err.expected: ';'
-BadBinaryLiterals.java:13:21: compiler.err.int.number.too.large: 111111111111111111111111111111111
-BadBinaryLiterals.java:15:21: compiler.err.int.number.too.large: 11111111111111111111111111111111111111111111111111111111111111111
BadBinaryLiterals.java:16:27: compiler.err.expected: ';'
BadBinaryLiterals.java:17:27: compiler.err.expected: ';'
BadBinaryLiterals.java:17:30: compiler.err.expected: token.identifier
-7 errors
+5 errors
--- a/test/langtools/tools/javac/literals/BadUnderscoreLiterals.6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/literals/BadUnderscoreLiterals.6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,7 +1,7 @@
-BadUnderscoreLiterals.java:11:17: compiler.err.unsupported.underscore.lit: 1.6
+BadUnderscoreLiterals.java:11:17: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.underscore.lit), 6, 7
BadUnderscoreLiterals.java:15:15: compiler.err.illegal.underscore
BadUnderscoreLiterals.java:19:19: compiler.err.illegal.underscore
-BadUnderscoreLiterals.java:22:14: compiler.err.unsupported.binary.lit: 1.6
+BadUnderscoreLiterals.java:22:14: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.binary.lit), 6, 7
BadUnderscoreLiterals.java:22:16: compiler.err.illegal.underscore
BadUnderscoreLiterals.java:23:17: compiler.err.illegal.underscore
BadUnderscoreLiterals.java:26:16: compiler.err.illegal.underscore
--- a/test/langtools/tools/javac/options/T6900037.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/options/T6900037.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,4 +1,4 @@
-- compiler.warn.source.no.bootclasspath: 1.8
+- compiler.warn.source.no.bootclasspath: 8
- compiler.err.warnings.and.werror
1 error
1 warning
--- a/test/langtools/tools/javac/parser/extend/TrialParser.java Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/parser/extend/TrialParser.java Tue Dec 05 10:28:45 2017 +0000
@@ -21,6 +21,7 @@
* questions.
*/
+import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.parser.JavacParser;
import com.sun.tools.javac.parser.ParserFactory;
@@ -186,7 +187,7 @@
List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
if (annosAfterParams.nonEmpty()) {
- checkAnnotationsAfterTypeParams(annosAfterParams.head.pos);
+ checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS);
mods.annotations = mods.annotations.appendList(annosAfterParams);
if (mods.pos == Position.NOPOS) {
mods.pos = mods.annotations.head.pos;
--- a/test/langtools/tools/javac/processing/warnings/gold_sv_warn_5_6.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/processing/warnings/gold_sv_warn_5_6.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,2 +1,2 @@
-- compiler.warn.proc.processor.incompatible.source.version: RELEASE_5, TestSourceVersionWarnings, 1.6
+- compiler.warn.proc.processor.incompatible.source.version: RELEASE_5, TestSourceVersionWarnings, 6
1 warning
--- a/test/langtools/tools/javac/varargs/6313164/T6313164Source7.out Tue Dec 05 10:21:41 2017 +0000
+++ b/test/langtools/tools/javac/varargs/6313164/T6313164Source7.out Tue Dec 05 10:28:45 2017 +0000
@@ -1,4 +1,4 @@
-- compiler.warn.source.no.bootclasspath: 1.7
+- compiler.warn.source.no.bootclasspath: 7
T6313164.java:14:10: compiler.err.cant.apply.symbol: kindname.method, foo1, p1.A[], p1.B,p1.B, kindname.class, p1.B, (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
T6313164.java:19:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)
T6313164.java:20:15: compiler.err.prob.found.req: (compiler.misc.inaccessible.varargs.type: p1.A, kindname.class, T6313164)