mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 22:34:27 +02:00
Merge
This commit is contained in:
commit
eed5d34c26
235 changed files with 7673 additions and 2642 deletions
1
.hgtags
1
.hgtags
|
@ -449,3 +449,4 @@ a85884d55ce32799f5c7382b7ea4839052b362a2 jdk-10+21
|
||||||
e5357aa85dadacc6562175ff74714fecfb4470cf jdk-10+22
|
e5357aa85dadacc6562175ff74714fecfb4470cf jdk-10+22
|
||||||
22850b3a55240253841b9a425ad60a7fcdb22d47 jdk-10+23
|
22850b3a55240253841b9a425ad60a7fcdb22d47 jdk-10+23
|
||||||
3b201865d5c1f244f555cad58da599c9261286d8 jdk-10+24
|
3b201865d5c1f244f555cad58da599c9261286d8 jdk-10+24
|
||||||
|
8eb5e3ccee560c28ac9b1df2670adac2b3d36fad jdk-10+25
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
mydir="$(dirname "${BASH_SOURCE[0]}")"
|
mydir="$(dirname "${BASH_SOURCE[0]}")"
|
||||||
myname="$(basename "${BASH_SOURCE[0]}")"
|
myname="$(basename "${BASH_SOURCE[0]}")"
|
||||||
|
|
||||||
installed_jib_script=${mydir}/../../.jib/jib
|
installed_jib_script=${mydir}/../.jib/jib
|
||||||
install_data=${mydir}/../../.jib/.data
|
install_data=${mydir}/../.jib/.data
|
||||||
|
|
||||||
setup_url() {
|
setup_url() {
|
||||||
if [ -f ~/.config/jib/jib.conf ]; then
|
if [ -f ~/.config/jib/jib.conf ]; then
|
||||||
|
@ -42,7 +42,7 @@ setup_url() {
|
||||||
jib_revision="2.0-SNAPSHOT"
|
jib_revision="2.0-SNAPSHOT"
|
||||||
jib_ext="jib.sh.gz"
|
jib_ext="jib.sh.gz"
|
||||||
|
|
||||||
closed_script="${mydir}/../../../closed/conf/jib-install.conf"
|
closed_script="${mydir}/../../closed/make/conf/jib-install.conf"
|
||||||
if [ -f "${closed_script}" ]; then
|
if [ -f "${closed_script}" ]; then
|
||||||
source "${closed_script}"
|
source "${closed_script}"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -127,7 +127,7 @@ scripting language.</span></p>
|
||||||
<hr>
|
<hr>
|
||||||
<span><a name="package" id="package"></a></span>
|
<span><a name="package" id="package"></a></span>
|
||||||
<h2><span>Scripting Package</span></h2>
|
<h2><span>Scripting Package</span></h2>
|
||||||
<p><span>The Java Scripting functionality is in the <code><a href="http://docs.oracle.com/javase/6/docs/api/javax/script/package-summary.html">javax.script</a></code>
|
<p><span>The Java Scripting functionality is in the <code><a href="http://docs.oracle.com/javase/9/docs/api/javax/script/package-summary.html">javax.script</a></code>
|
||||||
package. This is a relatively small, simple API. The starting point
|
package. This is a relatively small, simple API. The starting point
|
||||||
of the scripting API is the <code>ScriptEngineManager</code> class.
|
of the scripting API is the <code>ScriptEngineManager</code> class.
|
||||||
A ScriptEngineManager object can discover script engines through
|
A ScriptEngineManager object can discover script engines through
|
||||||
|
|
|
@ -41,7 +41,7 @@ JDK_CLASSES := $(call PathList, $(strip $(addprefix $(JDK_OUTPUTDIR)/modules/, \
|
||||||
$(eval $(call SetupJavaCompiler, GENERATE_NEWBYTECODE_DEBUG, \
|
$(eval $(call SetupJavaCompiler, GENERATE_NEWBYTECODE_DEBUG, \
|
||||||
JVM := $(JAVA_JAVAC), \
|
JVM := $(JAVA_JAVAC), \
|
||||||
JAVAC := $(NEW_JAVAC), \
|
JAVAC := $(NEW_JAVAC), \
|
||||||
FLAGS := -g -source 9 -target 9 --upgrade-module-path "$(JDK_OUTPUTDIR)/modules/" \
|
FLAGS := -g -source 10 -target 10 --upgrade-module-path "$(JDK_OUTPUTDIR)/modules/" \
|
||||||
--system none --module-source-path $(call GetModuleSrcPath), \
|
--system none --module-source-path $(call GetModuleSrcPath), \
|
||||||
SERVER_DIR := $(SJAVAC_SERVER_DIR), \
|
SERVER_DIR := $(SJAVAC_SERVER_DIR), \
|
||||||
SERVER_JVM := $(SJAVAC_SERVER_JAVA)))
|
SERVER_JVM := $(SJAVAC_SERVER_JAVA)))
|
||||||
|
|
|
@ -36,7 +36,7 @@ ifeq ($(HAS_SPEC),)
|
||||||
|
|
||||||
# Include the corresponding closed file, if present.
|
# Include the corresponding closed file, if present.
|
||||||
# Normal hook mechanism cannot be used since we have no SPEC.
|
# Normal hook mechanism cannot be used since we have no SPEC.
|
||||||
-include $(topdir)/closed/make/InitSupport.gmk
|
-include $(topdir)/../closed/make/InitSupport.gmk
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Helper functions for the initial part of Init.gmk, before the spec file is
|
# Helper functions for the initial part of Init.gmk, before the spec file is
|
||||||
|
|
|
@ -1311,6 +1311,7 @@ AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER],
|
||||||
$2LDFLAGS_JDKLIB="${$2LDFLAGS_JDK}"
|
$2LDFLAGS_JDKLIB="${$2LDFLAGS_JDK}"
|
||||||
|
|
||||||
$2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
|
$2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
|
||||||
|
$2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} ${LDFLAGS_NO_EXEC_STACK}"
|
||||||
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
||||||
$2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} \
|
$2JAVA_BASE_LDFLAGS="${$2JAVA_BASE_LDFLAGS} \
|
||||||
-libpath:${OUTPUTDIR}/support/modules_libs/java.base"
|
-libpath:${OUTPUTDIR}/support/modules_libs/java.base"
|
||||||
|
@ -1388,6 +1389,7 @@ $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} ${$2JAVA_BASE_LDFLAGS}"
|
||||||
AC_SUBST($2JDKEXE_LIBS)
|
AC_SUBST($2JDKEXE_LIBS)
|
||||||
AC_SUBST($2LDFLAGS_CXX_JDK)
|
AC_SUBST($2LDFLAGS_CXX_JDK)
|
||||||
AC_SUBST($2LDFLAGS_HASH_STYLE)
|
AC_SUBST($2LDFLAGS_HASH_STYLE)
|
||||||
|
AC_SUBST($2LDFLAGS_NO_EXEC_STACK)
|
||||||
|
|
||||||
AC_SUBST($2JVM_CFLAGS)
|
AC_SUBST($2JVM_CFLAGS)
|
||||||
AC_SUBST($2JVM_LDFLAGS)
|
AC_SUBST($2JVM_LDFLAGS)
|
||||||
|
|
|
@ -723,6 +723,7 @@ OPENJDK_BUILD_JVM_LIBS
|
||||||
OPENJDK_BUILD_JVM_ASFLAGS
|
OPENJDK_BUILD_JVM_ASFLAGS
|
||||||
OPENJDK_BUILD_JVM_LDFLAGS
|
OPENJDK_BUILD_JVM_LDFLAGS
|
||||||
OPENJDK_BUILD_JVM_CFLAGS
|
OPENJDK_BUILD_JVM_CFLAGS
|
||||||
|
OPENJDK_BUILD_LDFLAGS_NO_EXEC_STACK
|
||||||
OPENJDK_BUILD_LDFLAGS_HASH_STYLE
|
OPENJDK_BUILD_LDFLAGS_HASH_STYLE
|
||||||
OPENJDK_BUILD_LDFLAGS_CXX_JDK
|
OPENJDK_BUILD_LDFLAGS_CXX_JDK
|
||||||
OPENJDK_BUILD_JDKEXE_LIBS
|
OPENJDK_BUILD_JDKEXE_LIBS
|
||||||
|
@ -738,6 +739,7 @@ JVM_LIBS
|
||||||
JVM_ASFLAGS
|
JVM_ASFLAGS
|
||||||
JVM_LDFLAGS
|
JVM_LDFLAGS
|
||||||
JVM_CFLAGS
|
JVM_CFLAGS
|
||||||
|
LDFLAGS_NO_EXEC_STACK
|
||||||
LDFLAGS_HASH_STYLE
|
LDFLAGS_HASH_STYLE
|
||||||
LDFLAGS_CXX_JDK
|
LDFLAGS_CXX_JDK
|
||||||
JDKEXE_LIBS
|
JDKEXE_LIBS
|
||||||
|
@ -5115,7 +5117,7 @@ VS_SDK_PLATFORM_NAME_2013=
|
||||||
#CUSTOM_AUTOCONF_INCLUDE
|
#CUSTOM_AUTOCONF_INCLUDE
|
||||||
|
|
||||||
# Do not change or remove the following line, it is needed for consistency checks:
|
# Do not change or remove the following line, it is needed for consistency checks:
|
||||||
DATE_WHEN_GENERATED=1506333008
|
DATE_WHEN_GENERATED=1506397140
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
|
@ -52024,6 +52026,7 @@ fi
|
||||||
LDFLAGS_JDKLIB="${LDFLAGS_JDK}"
|
LDFLAGS_JDKLIB="${LDFLAGS_JDK}"
|
||||||
|
|
||||||
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
|
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
|
||||||
|
LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${LDFLAGS_NO_EXEC_STACK}"
|
||||||
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
||||||
JAVA_BASE_LDFLAGS="${JAVA_BASE_LDFLAGS} \
|
JAVA_BASE_LDFLAGS="${JAVA_BASE_LDFLAGS} \
|
||||||
-libpath:${OUTPUTDIR}/support/modules_libs/java.base"
|
-libpath:${OUTPUTDIR}/support/modules_libs/java.base"
|
||||||
|
@ -52109,6 +52112,7 @@ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${JAVA_BASE_LDFLAGS}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Special extras...
|
# Special extras...
|
||||||
if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
|
if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
|
||||||
if test "x$OPENJDK_BUILD_CPU_ARCH" = "xsparc"; then
|
if test "x$OPENJDK_BUILD_CPU_ARCH" = "xsparc"; then
|
||||||
|
@ -52903,6 +52907,7 @@ fi
|
||||||
OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDK}"
|
OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDK}"
|
||||||
|
|
||||||
OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
|
OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${SHARED_LIBRARY_FLAGS}"
|
||||||
|
OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${LDFLAGS_NO_EXEC_STACK}"
|
||||||
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
||||||
OPENJDK_BUILD_JAVA_BASE_LDFLAGS="${OPENJDK_BUILD_JAVA_BASE_LDFLAGS} \
|
OPENJDK_BUILD_JAVA_BASE_LDFLAGS="${OPENJDK_BUILD_JAVA_BASE_LDFLAGS} \
|
||||||
-libpath:${OUTPUTDIR}/support/modules_libs/java.base"
|
-libpath:${OUTPUTDIR}/support/modules_libs/java.base"
|
||||||
|
@ -52988,6 +52993,7 @@ OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${OPENJDK_BUILD_JA
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Tests are only ever compiled for TARGET
|
# Tests are only ever compiled for TARGET
|
||||||
# Flags for compiling test libraries
|
# Flags for compiling test libraries
|
||||||
CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
|
CFLAGS_TESTLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
|
||||||
|
|
|
@ -387,6 +387,7 @@ CFLAGS_JDKEXE:=@CFLAGS_JDKEXE@
|
||||||
CXXFLAGS_JDKEXE:=@CXXFLAGS_JDKEXE@
|
CXXFLAGS_JDKEXE:=@CXXFLAGS_JDKEXE@
|
||||||
|
|
||||||
LDFLAGS_HASH_STYLE := @LDFLAGS_HASH_STYLE@
|
LDFLAGS_HASH_STYLE := @LDFLAGS_HASH_STYLE@
|
||||||
|
LDFLAGS_NO_EXEC_STACK := @LDFLAGS_NO_EXEC_STACK@
|
||||||
|
|
||||||
JVM_CFLAGS := @JVM_CFLAGS@
|
JVM_CFLAGS := @JVM_CFLAGS@
|
||||||
JVM_CFLAGS_SYMBOLS := @JVM_CFLAGS_SYMBOLS@
|
JVM_CFLAGS_SYMBOLS := @JVM_CFLAGS_SYMBOLS@
|
||||||
|
|
|
@ -58,7 +58,6 @@ BOOT_MODULES += \
|
||||||
java.rmi \
|
java.rmi \
|
||||||
java.security.sasl \
|
java.security.sasl \
|
||||||
java.xml \
|
java.xml \
|
||||||
jdk.httpserver \
|
|
||||||
jdk.internal.vm.ci \
|
jdk.internal.vm.ci \
|
||||||
jdk.management \
|
jdk.management \
|
||||||
jdk.management.agent \
|
jdk.management.agent \
|
||||||
|
@ -112,6 +111,7 @@ PLATFORM_MODULES += \
|
||||||
jdk.crypto.cryptoki \
|
jdk.crypto.cryptoki \
|
||||||
jdk.crypto.ec \
|
jdk.crypto.ec \
|
||||||
jdk.dynalink \
|
jdk.dynalink \
|
||||||
|
jdk.httpserver \
|
||||||
jdk.incubator.httpclient \
|
jdk.incubator.httpclient \
|
||||||
jdk.internal.vm.compiler.management \
|
jdk.internal.vm.compiler.management \
|
||||||
jdk.jsobject \
|
jdk.jsobject \
|
||||||
|
|
|
@ -900,6 +900,45 @@ var getJibProfilesProfiles = function (input, common, data) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"windows-x64-open": {
|
||||||
|
artifacts: {
|
||||||
|
jdk: {
|
||||||
|
local: "bundles/\\(jdk.*bin.tar.gz\\)",
|
||||||
|
remote: [
|
||||||
|
"bundles/openjdk/GPL/windows-x64/jdk-" + data.version
|
||||||
|
+ "_windows-x64_bin.tar.gz",
|
||||||
|
"bundles/openjdk/GPL/windows-x64/\\1"
|
||||||
|
],
|
||||||
|
subdir: "jdk-" + data.version
|
||||||
|
},
|
||||||
|
jre: {
|
||||||
|
local: "bundles/\\(jre.*bin.tar.gz\\)",
|
||||||
|
remote: "bundles/openjdk/GPL/windows-x64/\\1"
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
local: "bundles/\\(jdk.*bin-tests.tar.gz\\)",
|
||||||
|
remote: [
|
||||||
|
"bundles/openjdk/GPL/windows-x64/jdk-" + data.version
|
||||||
|
+ "_windows-x64_bin-tests.tar.gz",
|
||||||
|
"bundles/openjdk/GPL/windows-x64/\\1"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
jdk_symbols: {
|
||||||
|
local: "bundles/\\(jdk.*bin-symbols.tar.gz\\)",
|
||||||
|
remote: [
|
||||||
|
"bundles/openjdk/GPL/windows-x64/jdk-" + data.version
|
||||||
|
+ "_windows-x64_bin-symbols.tar.gz",
|
||||||
|
"bundles/openjdk/GPL/windows-x64/\\1"
|
||||||
|
],
|
||||||
|
subdir: "jdk-" + data.version
|
||||||
|
},
|
||||||
|
jre_symbols: {
|
||||||
|
local: "bundles/\\(jre.*bin-symbols.tar.gz\\)",
|
||||||
|
remote: "bundles/openjdk/GPL/windows-x64/\\1",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"linux-x86-open-debug": {
|
"linux-x86-open-debug": {
|
||||||
artifacts: {
|
artifacts: {
|
||||||
jdk: {
|
jdk: {
|
||||||
|
@ -929,9 +968,10 @@ var getJibProfilesProfiles = function (input, common, data) {
|
||||||
profiles["linux-x86-ri-debug"] = clone(profiles["linux-x86-open-debug"]);
|
profiles["linux-x86-ri-debug"] = clone(profiles["linux-x86-open-debug"]);
|
||||||
profiles["macosx-x64-ri"] = clone(profiles["macosx-x64-open"]);
|
profiles["macosx-x64-ri"] = clone(profiles["macosx-x64-open"]);
|
||||||
profiles["windows-x86-ri"] = clone(profiles["windows-x86-open"]);
|
profiles["windows-x86-ri"] = clone(profiles["windows-x86-open"]);
|
||||||
|
profiles["windows-x64-ri"] = clone(profiles["windows-x64-open"]);
|
||||||
|
|
||||||
// Generate artifacts for ri profiles
|
// Generate artifacts for ri profiles
|
||||||
[ "linux-x64-ri", "linux-x86-ri", "linux-x86-ri-debug", "macosx-x64-ri", "windows-x86-ri" ]
|
[ "linux-x64-ri", "linux-x86-ri", "linux-x86-ri-debug", "macosx-x64-ri", "windows-x86-ri", "windows-x64-ri" ]
|
||||||
.forEach(function (name) {
|
.forEach(function (name) {
|
||||||
// Rewrite all remote dirs to "bundles/openjdk/BCL/..."
|
// Rewrite all remote dirs to "bundles/openjdk/BCL/..."
|
||||||
for (artifactName in profiles[name].artifacts) {
|
for (artifactName in profiles[name].artifacts) {
|
||||||
|
@ -947,6 +987,11 @@ var getJibProfilesProfiles = function (input, common, data) {
|
||||||
configure_args: "--with-freetype-license="
|
configure_args: "--with-freetype-license="
|
||||||
+ input.get("freetype", "install_path")
|
+ input.get("freetype", "install_path")
|
||||||
+ "/freetype-2.7.1-v120-x86/freetype.md"
|
+ "/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 = concatObjects(profiles, profilesRiFreetype);
|
||||||
|
|
|
@ -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.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -36,7 +36,7 @@ ifneq ($(OPENJDK_TARGET_OS), windows)
|
||||||
ifeq ($(STATIC_BUILD), false)
|
ifeq ($(STATIC_BUILD), false)
|
||||||
ifeq ($(OPENJDK_TARGET_OS), linux)
|
ifeq ($(OPENJDK_TARGET_OS), linux)
|
||||||
LIBJSIG_CFLAGS := -fPIC -D_GNU_SOURCE -D_REENTRANT $(EXTRA_CFLAGS)
|
LIBJSIG_CFLAGS := -fPIC -D_GNU_SOURCE -D_REENTRANT $(EXTRA_CFLAGS)
|
||||||
LIBJSIG_LDFLAGS := $(LDFLAGS_HASH_STYLE) $(EXTRA_CFLAGS)
|
LIBJSIG_LDFLAGS := $(LDFLAGS_HASH_STYLE) ${LDFLAGS_NO_EXEC_STACK} $(EXTRA_CFLAGS)
|
||||||
LIBJSIG_LIBS := $(LIBDL)
|
LIBJSIG_LIBS := $(LIBDL)
|
||||||
|
|
||||||
# NOTE: The old build compiled this library without -soname.
|
# NOTE: The old build compiled this library without -soname.
|
||||||
|
|
|
@ -57,8 +57,8 @@ public class TransitiveDependencies {
|
||||||
}
|
}
|
||||||
|
|
||||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||||
List<String> options = Arrays.asList("-source", "9",
|
List<String> options = Arrays.asList("-source", "10",
|
||||||
"-target", "9",
|
"-target", "10",
|
||||||
"-proc:only",
|
"-proc:only",
|
||||||
"--system", "none",
|
"--system", "none",
|
||||||
"--module-source-path", args[0],
|
"--module-source-path", args[0],
|
||||||
|
|
|
@ -174,8 +174,6 @@
|
||||||
<target name="compile" depends="prepare" description="Compiles nashorn">
|
<target name="compile" depends="prepare" description="Compiles nashorn">
|
||||||
<javac srcdir="${dynalink.module.src.dir}"
|
<javac srcdir="${dynalink.module.src.dir}"
|
||||||
destdir="${dynalink.module.classes.dir}"
|
destdir="${dynalink.module.classes.dir}"
|
||||||
source="${javac.source}"
|
|
||||||
target="${javac.target}"
|
|
||||||
debug="${javac.debug}"
|
debug="${javac.debug}"
|
||||||
encoding="${javac.encoding}"
|
encoding="${javac.encoding}"
|
||||||
includeantruntime="false" fork="true">
|
includeantruntime="false" fork="true">
|
||||||
|
@ -190,8 +188,6 @@
|
||||||
</delete>
|
</delete>
|
||||||
<javac srcdir="${nashorn.module.src.dir}"
|
<javac srcdir="${nashorn.module.src.dir}"
|
||||||
destdir="${nashorn.module.classes.dir}"
|
destdir="${nashorn.module.classes.dir}"
|
||||||
source="${javac.source}"
|
|
||||||
target="${javac.target}"
|
|
||||||
debug="${javac.debug}"
|
debug="${javac.debug}"
|
||||||
encoding="${javac.encoding}"
|
encoding="${javac.encoding}"
|
||||||
includeantruntime="false" fork="true">
|
includeantruntime="false" fork="true">
|
||||||
|
@ -207,8 +203,6 @@
|
||||||
</delete>
|
</delete>
|
||||||
<javac srcdir="${nashorn.shell.module.src.dir}"
|
<javac srcdir="${nashorn.shell.module.src.dir}"
|
||||||
destdir="${nashorn.shell.module.classes.dir}"
|
destdir="${nashorn.shell.module.classes.dir}"
|
||||||
source="${javac.source}"
|
|
||||||
target="${javac.target}"
|
|
||||||
debug="${javac.debug}"
|
debug="${javac.debug}"
|
||||||
encoding="${javac.encoding}"
|
encoding="${javac.encoding}"
|
||||||
includeantruntime="false" fork="true">
|
includeantruntime="false" fork="true">
|
||||||
|
@ -342,8 +336,6 @@
|
||||||
<javac srcdir="${test.src.dir}"
|
<javac srcdir="${test.src.dir}"
|
||||||
destdir="${build.test.classes.dir}"
|
destdir="${build.test.classes.dir}"
|
||||||
classpath="${javac.test.classpath}"
|
classpath="${javac.test.classpath}"
|
||||||
source="${javac.source}"
|
|
||||||
target="${javac.target}"
|
|
||||||
debug="${javac.debug}"
|
debug="${javac.debug}"
|
||||||
encoding="${javac.encoding}"
|
encoding="${javac.encoding}"
|
||||||
includeantruntime="false" fork="true">
|
includeantruntime="false" fork="true">
|
||||||
|
@ -351,7 +343,7 @@
|
||||||
<compilerarg value="-Xlint:unchecked"/>
|
<compilerarg value="-Xlint:unchecked"/>
|
||||||
<compilerarg value="-Xlint:deprecation"/>
|
<compilerarg value="-Xlint:deprecation"/>
|
||||||
<compilerarg value="-Xdiags:verbose"/>
|
<compilerarg value="-Xdiags:verbose"/>
|
||||||
<compilerarg line="${test.module.imports}"/>
|
<compilerarg line="${test.module.imports.compile.time}"/>
|
||||||
</javac>
|
</javac>
|
||||||
|
|
||||||
<copy todir="${build.test.classes.dir}/META-INF/services">
|
<copy todir="${build.test.classes.dir}/META-INF/services">
|
||||||
|
|
|
@ -24,8 +24,6 @@ application.title=nasgen
|
||||||
|
|
||||||
# source and target levels
|
# source and target levels
|
||||||
build.compiler=modern
|
build.compiler=modern
|
||||||
javac.source=1.7
|
|
||||||
javac.target=1.7
|
|
||||||
|
|
||||||
# This directory is removed when the project is cleaned:
|
# This directory is removed when the project is cleaned:
|
||||||
nasgen.build.dir=../../../../build/nashorn/nasgen
|
nasgen.build.dir=../../../../build/nashorn/nasgen
|
||||||
|
|
|
@ -24,8 +24,6 @@ application.title=nashorntask
|
||||||
|
|
||||||
# source and target levels
|
# source and target levels
|
||||||
build.compiler=modern
|
build.compiler=modern
|
||||||
javac.source=1.8
|
|
||||||
javac.target=1.8
|
|
||||||
|
|
||||||
# This directory is removed when the project is cleaned:
|
# This directory is removed when the project is cleaned:
|
||||||
nashorntask.build.dir=../../../../build/nashorn/nashorntask
|
nashorntask.build.dir=../../../../build/nashorn/nashorntask
|
||||||
|
|
|
@ -32,8 +32,6 @@ jdk.jline.src.dir=src/jdk.internal.le/share/classes
|
||||||
|
|
||||||
# source and target levels
|
# source and target levels
|
||||||
build.compiler=modern
|
build.compiler=modern
|
||||||
javac.source=1.9
|
|
||||||
javac.target=1.9
|
|
||||||
|
|
||||||
javadoc.option=\
|
javadoc.option=\
|
||||||
-tag "implSpec:a:Implementation Requirements:" \
|
-tag "implSpec:a:Implementation Requirements:" \
|
||||||
|
@ -146,7 +144,7 @@ javac.test.classpath=\
|
||||||
${file.reference.bsh.jar}${path.separator}\
|
${file.reference.bsh.jar}${path.separator}\
|
||||||
${file.reference.snakeyaml.jar}
|
${file.reference.snakeyaml.jar}
|
||||||
|
|
||||||
test.module.imports=\
|
test.module.imports.compile.time=\
|
||||||
--add-exports jdk.scripting.nashorn/jdk.nashorn.internal.ir=ALL-UNNAMED \
|
--add-exports jdk.scripting.nashorn/jdk.nashorn.internal.ir=ALL-UNNAMED \
|
||||||
--add-exports jdk.scripting.nashorn/jdk.nashorn.internal.codegen=ALL-UNNAMED \
|
--add-exports jdk.scripting.nashorn/jdk.nashorn.internal.codegen=ALL-UNNAMED \
|
||||||
--add-exports jdk.scripting.nashorn/jdk.nashorn.internal.parser=ALL-UNNAMED \
|
--add-exports jdk.scripting.nashorn/jdk.nashorn.internal.parser=ALL-UNNAMED \
|
||||||
|
@ -159,7 +157,10 @@ test.module.imports=\
|
||||||
--add-exports jdk.scripting.nashorn/jdk.nashorn.internal.runtime.regexp=ALL-UNNAMED \
|
--add-exports jdk.scripting.nashorn/jdk.nashorn.internal.runtime.regexp=ALL-UNNAMED \
|
||||||
--add-exports jdk.scripting.nashorn/jdk.nashorn.internal.runtime.regexp.joni=ALL-UNNAMED \
|
--add-exports jdk.scripting.nashorn/jdk.nashorn.internal.runtime.regexp.joni=ALL-UNNAMED \
|
||||||
--add-exports jdk.scripting.nashorn/jdk.nashorn.tools=ALL-UNNAMED \
|
--add-exports jdk.scripting.nashorn/jdk.nashorn.tools=ALL-UNNAMED \
|
||||||
--add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \
|
--add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED
|
||||||
|
|
||||||
|
test.module.imports.runtime=\
|
||||||
|
${test.module.imports.compile.time} \
|
||||||
--add-opens jdk.scripting.nashorn/jdk.nashorn.internal.runtime=ALL-UNNAMED \
|
--add-opens jdk.scripting.nashorn/jdk.nashorn.internal.runtime=ALL-UNNAMED \
|
||||||
--add-opens jdk.scripting.nashorn/jdk.nashorn.internal.runtime.doubleconv=ALL-UNNAMED
|
--add-opens jdk.scripting.nashorn/jdk.nashorn.internal.runtime.doubleconv=ALL-UNNAMED
|
||||||
|
|
||||||
|
@ -359,7 +360,7 @@ run.test.user.country=TR
|
||||||
|
|
||||||
run.test.jvmargs.common=\
|
run.test.jvmargs.common=\
|
||||||
-server \
|
-server \
|
||||||
${test.module.imports} \
|
${test.module.imports.runtime} \
|
||||||
${run.test.jvmargs.external} \
|
${run.test.jvmargs.external} \
|
||||||
--add-modules jdk.scripting.nashorn.shell \
|
--add-modules jdk.scripting.nashorn.shell \
|
||||||
${nashorn.override.option} \
|
${nashorn.override.option} \
|
||||||
|
|
|
@ -73,6 +73,9 @@
|
||||||
#include "utilities/nativeCallStack.hpp"
|
#include "utilities/nativeCallStack.hpp"
|
||||||
#endif // INCLUDE_NMT
|
#endif // INCLUDE_NMT
|
||||||
|
|
||||||
|
#ifdef LINUX
|
||||||
|
#include "utilities/elfFile.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SIZE_T_MAX_VALUE ((size_t) -1)
|
#define SIZE_T_MAX_VALUE ((size_t) -1)
|
||||||
|
|
||||||
|
@ -1823,6 +1826,20 @@ WB_ENTRY(void, WB_RemoveCompilerDirective(JNIEnv* env, jobject o, jint count))
|
||||||
DirectivesStack::pop(count);
|
DirectivesStack::pop(count);
|
||||||
WB_END
|
WB_END
|
||||||
|
|
||||||
|
// Checks that the library libfile has the noexecstack bit set.
|
||||||
|
WB_ENTRY(jboolean, WB_CheckLibSpecifiesNoexecstack(JNIEnv* env, jobject o, jstring libfile))
|
||||||
|
jboolean ret = false;
|
||||||
|
#ifdef LINUX
|
||||||
|
// Can't be in VM when we call JNI.
|
||||||
|
ThreadToNativeFromVM ttnfv(thread);
|
||||||
|
const char* lf = env->GetStringUTFChars(libfile, NULL);
|
||||||
|
CHECK_JNI_EXCEPTION_(env, 0);
|
||||||
|
ret = (jboolean) ElfFile::specifies_noexecstack(lf);
|
||||||
|
env->ReleaseStringUTFChars(libfile, lf);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
WB_END
|
||||||
|
|
||||||
#define CC (char*)
|
#define CC (char*)
|
||||||
|
|
||||||
static JNINativeMethod methods[] = {
|
static JNINativeMethod methods[] = {
|
||||||
|
@ -2027,6 +2044,8 @@ static JNINativeMethod methods[] = {
|
||||||
(void*)&WB_GetConcurrentGCPhases},
|
(void*)&WB_GetConcurrentGCPhases},
|
||||||
{CC"requestConcurrentGCPhase0", CC"(Ljava/lang/String;)Z",
|
{CC"requestConcurrentGCPhase0", CC"(Ljava/lang/String;)Z",
|
||||||
(void*)&WB_RequestConcurrentGCPhase},
|
(void*)&WB_RequestConcurrentGCPhase},
|
||||||
|
{CC"checkLibSpecifiesNoexecstack", CC"(Ljava/lang/String;)Z",
|
||||||
|
(void*)&WB_CheckLibSpecifiesNoexecstack},
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef CC
|
#undef CC
|
||||||
|
|
|
@ -2160,10 +2160,12 @@ public abstract class ClassLoader {
|
||||||
* if a package of the given {@code name} is already
|
* if a package of the given {@code name} is already
|
||||||
* defined by this class loader
|
* defined by this class loader
|
||||||
*
|
*
|
||||||
|
*
|
||||||
* @since 1.2
|
* @since 1.2
|
||||||
* @revised 9
|
* @revised 9
|
||||||
* @spec JPMS
|
* @spec JPMS
|
||||||
*
|
*
|
||||||
|
* @jvms 5.3 Run-time package
|
||||||
* @see <a href="{@docRoot}/../specs/jar/jar.html#sealing">
|
* @see <a href="{@docRoot}/../specs/jar/jar.html#sealing">
|
||||||
* The JAR File Specification: Package Sealing</a>
|
* The JAR File Specification: Package Sealing</a>
|
||||||
*/
|
*/
|
||||||
|
@ -2186,17 +2188,19 @@ public abstract class ClassLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@code Package} of the given <a href="#name">name</a> that has been
|
* Returns a {@code Package} of the given <a href="#name">name</a> that
|
||||||
* defined by this class loader.
|
* has been defined by this class loader.
|
||||||
*
|
*
|
||||||
* @param name The <a href="#name">package name</a>
|
* @param name The <a href="#name">package name</a>
|
||||||
*
|
*
|
||||||
* @return The {@code Package} of the given name defined by this class loader,
|
* @return The {@code Package} of the given name that has been defined
|
||||||
* or {@code null} if not found
|
* by this class loader, or {@code null} if not found
|
||||||
*
|
*
|
||||||
* @throws NullPointerException
|
* @throws NullPointerException
|
||||||
* if {@code name} is {@code null}.
|
* if {@code name} is {@code null}.
|
||||||
*
|
*
|
||||||
|
* @jvms 5.3 Run-time package
|
||||||
|
*
|
||||||
* @since 9
|
* @since 9
|
||||||
* @spec JPMS
|
* @spec JPMS
|
||||||
*/
|
*/
|
||||||
|
@ -2211,14 +2215,18 @@ public abstract class ClassLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all of the {@code Package}s defined by this class loader.
|
* Returns all of the {@code Package}s that have been defined by
|
||||||
* The returned array has no duplicated {@code Package}s of the same name.
|
* this class loader. The returned array has no duplicated {@code Package}s
|
||||||
|
* of the same name.
|
||||||
*
|
*
|
||||||
* @apiNote This method returns an array rather than a {@code Set} or {@code Stream}
|
* @apiNote This method returns an array rather than a {@code Set} or {@code Stream}
|
||||||
* for consistency with the existing {@link #getPackages} method.
|
* for consistency with the existing {@link #getPackages} method.
|
||||||
*
|
*
|
||||||
* @return The array of {@code Package} objects defined by this class loader;
|
* @return The array of {@code Package} objects that have been defined by
|
||||||
* or an zero length array if no package has been defined by this class loader.
|
* this class loader; or an zero length array if no package has been
|
||||||
|
* defined by this class loader.
|
||||||
|
*
|
||||||
|
* @jvms 5.3 Run-time package
|
||||||
*
|
*
|
||||||
* @since 9
|
* @since 9
|
||||||
* @spec JPMS
|
* @spec JPMS
|
||||||
|
@ -2244,7 +2252,7 @@ public abstract class ClassLoader {
|
||||||
* @param name
|
* @param name
|
||||||
* The <a href="#name">package name</a>
|
* The <a href="#name">package name</a>
|
||||||
*
|
*
|
||||||
* @return The {@code Package} corresponding to the given name defined by
|
* @return The {@code Package} of the given name that has been defined by
|
||||||
* this class loader or its ancestors, or {@code null} if not found.
|
* this class loader or its ancestors, or {@code null} if not found.
|
||||||
*
|
*
|
||||||
* @throws NullPointerException
|
* @throws NullPointerException
|
||||||
|
@ -2263,6 +2271,8 @@ public abstract class ClassLoader {
|
||||||
* {@link ClassLoader#getDefinedPackage} method which returns
|
* {@link ClassLoader#getDefinedPackage} method which returns
|
||||||
* a {@code Package} for the specified class loader.
|
* a {@code Package} for the specified class loader.
|
||||||
*
|
*
|
||||||
|
* @see ClassLoader#getDefinedPackage(String)
|
||||||
|
*
|
||||||
* @since 1.2
|
* @since 1.2
|
||||||
* @revised 9
|
* @revised 9
|
||||||
* @spec JPMS
|
* @spec JPMS
|
||||||
|
@ -2281,10 +2291,10 @@ public abstract class ClassLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all of the {@code Package}s defined by this class loader
|
* Returns all of the {@code Package}s that have been defined by
|
||||||
* and its ancestors. The returned array may contain more than one
|
* this class loader and its ancestors. The returned array may contain
|
||||||
* {@code Package} object of the same package name, each defined by
|
* more than one {@code Package} object of the same package name, each
|
||||||
* a different class loader in the class loader hierarchy.
|
* defined by a different class loader in the class loader hierarchy.
|
||||||
*
|
*
|
||||||
* @apiNote The {@link #getPlatformClassLoader() platform class loader}
|
* @apiNote The {@link #getPlatformClassLoader() platform class loader}
|
||||||
* may delegate to the application class loader. In other words,
|
* may delegate to the application class loader. In other words,
|
||||||
|
@ -2294,8 +2304,10 @@ public abstract class ClassLoader {
|
||||||
* when invoked on the platform class loader, this method will not
|
* when invoked on the platform class loader, this method will not
|
||||||
* return any packages defined to the application class loader.
|
* return any packages defined to the application class loader.
|
||||||
*
|
*
|
||||||
* @return The array of {@code Package} objects defined by this
|
* @return The array of {@code Package} objects that have been defined by
|
||||||
* class loader and its ancestors
|
* this class loader and its ancestors
|
||||||
|
*
|
||||||
|
* @see ClassLoader#getDefinedPackages()
|
||||||
*
|
*
|
||||||
* @since 1.2
|
* @since 1.2
|
||||||
* @revised 9
|
* @revised 9
|
||||||
|
|
|
@ -29,6 +29,7 @@ import jdk.internal.misc.SharedSecrets;
|
||||||
|
|
||||||
import static java.lang.StackWalker.Option.*;
|
import static java.lang.StackWalker.Option.*;
|
||||||
import java.lang.StackWalker.StackFrame;
|
import java.lang.StackWalker.StackFrame;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
|
|
||||||
class StackFrameInfo implements StackFrame {
|
class StackFrameInfo implements StackFrame {
|
||||||
private final static JavaLangInvokeAccess JLIA =
|
private final static JavaLangInvokeAccess JLIA =
|
||||||
|
@ -78,6 +79,17 @@ class StackFrameInfo implements StackFrame {
|
||||||
return JLIA.getName(memberName);
|
return JLIA.getName(memberName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodType getMethodType() {
|
||||||
|
walker.ensureAccessEnabled(RETAIN_CLASS_REFERENCE);
|
||||||
|
return JLIA.getMethodType(memberName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescriptor() {
|
||||||
|
return JLIA.getMethodDescriptor(memberName);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getByteCodeIndex() {
|
public int getByteCodeIndex() {
|
||||||
// bci not available for native methods
|
// bci not available for native methods
|
||||||
|
|
|
@ -26,10 +26,12 @@ package java.lang;
|
||||||
|
|
||||||
import jdk.internal.reflect.CallerSensitive;
|
import jdk.internal.reflect.CallerSensitive;
|
||||||
|
|
||||||
import java.util.*;
|
import java.lang.invoke.MethodType;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,7 +98,7 @@ public final class StackWalker {
|
||||||
* @since 9
|
* @since 9
|
||||||
* @jvms 2.6
|
* @jvms 2.6
|
||||||
*/
|
*/
|
||||||
public static interface StackFrame {
|
public interface StackFrame {
|
||||||
/**
|
/**
|
||||||
* Gets the <a href="ClassLoader.html#name">binary name</a>
|
* Gets the <a href="ClassLoader.html#name">binary name</a>
|
||||||
* of the declaring class of the method represented by this stack frame.
|
* of the declaring class of the method represented by this stack frame.
|
||||||
|
@ -127,6 +129,47 @@ public final class StackWalker {
|
||||||
*/
|
*/
|
||||||
public Class<?> getDeclaringClass();
|
public Class<?> getDeclaringClass();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link MethodType} representing the parameter types and
|
||||||
|
* the return type for the method represented by this stack frame.
|
||||||
|
*
|
||||||
|
* @implSpec
|
||||||
|
* The default implementation throws {@code UnsupportedOperationException}.
|
||||||
|
*
|
||||||
|
* @return the {@code MethodType} for this stack frame
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException if this {@code StackWalker}
|
||||||
|
* is not configured with {@link Option#RETAIN_CLASS_REFERENCE
|
||||||
|
* Option.RETAIN_CLASS_REFERENCE}.
|
||||||
|
*
|
||||||
|
* @since 10
|
||||||
|
*/
|
||||||
|
public default MethodType getMethodType() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the <i>descriptor</i> of the method represented by
|
||||||
|
* this stack frame as defined by
|
||||||
|
* <cite>The Java Virtual Machine Specification</cite>.
|
||||||
|
*
|
||||||
|
* @implSpec
|
||||||
|
* The default implementation throws {@code UnsupportedOperationException}.
|
||||||
|
*
|
||||||
|
* @return the descriptor of the method represented by
|
||||||
|
* this stack frame
|
||||||
|
*
|
||||||
|
* @see MethodType#fromMethodDescriptorString(String, ClassLoader)
|
||||||
|
* @see MethodType#toMethodDescriptorString()
|
||||||
|
* @jvms 4.3.3 Method Descriptor
|
||||||
|
*
|
||||||
|
* @since 10
|
||||||
|
*/
|
||||||
|
public default String getDescriptor() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the index to the code array of the {@code Code} attribute
|
* Returns the index to the code array of the {@code Code} attribute
|
||||||
* containing the execution point represented by this stack frame.
|
* containing the execution point represented by this stack frame.
|
||||||
|
|
|
@ -28,6 +28,7 @@ package java.lang.invoke;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import static java.lang.invoke.LambdaForm.*;
|
import static java.lang.invoke.LambdaForm.*;
|
||||||
import static java.lang.invoke.LambdaForm.Kind.*;
|
import static java.lang.invoke.LambdaForm.Kind.*;
|
||||||
|
import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeVirtual;
|
||||||
import static java.lang.invoke.MethodHandleStatics.*;
|
import static java.lang.invoke.MethodHandleStatics.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -158,8 +159,11 @@ abstract class DelegatingMethodHandle extends MethodHandle {
|
||||||
static final NamedFunction NF_getTarget;
|
static final NamedFunction NF_getTarget;
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
NF_getTarget = new NamedFunction(DelegatingMethodHandle.class
|
MemberName member = new MemberName(DelegatingMethodHandle.class, "getTarget",
|
||||||
.getDeclaredMethod("getTarget"));
|
MethodType.methodType(MethodHandle.class), REF_invokeVirtual);
|
||||||
|
NF_getTarget = new NamedFunction(
|
||||||
|
MemberName.getFactory()
|
||||||
|
.resolveOrFail(REF_invokeVirtual, member, DelegatingMethodHandle.class, NoSuchMethodException.class));
|
||||||
} catch (ReflectiveOperationException ex) {
|
} catch (ReflectiveOperationException ex) {
|
||||||
throw newInternalError(ex);
|
throw newInternalError(ex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -753,42 +753,38 @@ class DirectMethodHandle extends MethodHandle {
|
||||||
return nf;
|
return nf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final MethodType OBJ_OBJ_TYPE = MethodType.methodType(Object.class, Object.class);
|
||||||
|
|
||||||
|
private static final MethodType LONG_OBJ_TYPE = MethodType.methodType(long.class, Object.class);
|
||||||
|
|
||||||
private static NamedFunction createFunction(byte func) {
|
private static NamedFunction createFunction(byte func) {
|
||||||
try {
|
try {
|
||||||
switch (func) {
|
switch (func) {
|
||||||
case NF_internalMemberName:
|
case NF_internalMemberName:
|
||||||
return new NamedFunction(DirectMethodHandle.class
|
return getNamedFunction("internalMemberName", OBJ_OBJ_TYPE);
|
||||||
.getDeclaredMethod("internalMemberName", Object.class));
|
|
||||||
case NF_internalMemberNameEnsureInit:
|
case NF_internalMemberNameEnsureInit:
|
||||||
return new NamedFunction(DirectMethodHandle.class
|
return getNamedFunction("internalMemberNameEnsureInit", OBJ_OBJ_TYPE);
|
||||||
.getDeclaredMethod("internalMemberNameEnsureInit", Object.class));
|
|
||||||
case NF_ensureInitialized:
|
case NF_ensureInitialized:
|
||||||
return new NamedFunction(DirectMethodHandle.class
|
return getNamedFunction("ensureInitialized", MethodType.methodType(void.class, Object.class));
|
||||||
.getDeclaredMethod("ensureInitialized", Object.class));
|
|
||||||
case NF_fieldOffset:
|
case NF_fieldOffset:
|
||||||
return new NamedFunction(DirectMethodHandle.class
|
return getNamedFunction("fieldOffset", LONG_OBJ_TYPE);
|
||||||
.getDeclaredMethod("fieldOffset", Object.class));
|
|
||||||
case NF_checkBase:
|
case NF_checkBase:
|
||||||
return new NamedFunction(DirectMethodHandle.class
|
return getNamedFunction("checkBase", OBJ_OBJ_TYPE);
|
||||||
.getDeclaredMethod("checkBase", Object.class));
|
|
||||||
case NF_staticBase:
|
case NF_staticBase:
|
||||||
return new NamedFunction(DirectMethodHandle.class
|
return getNamedFunction("staticBase", OBJ_OBJ_TYPE);
|
||||||
.getDeclaredMethod("staticBase", Object.class));
|
|
||||||
case NF_staticOffset:
|
case NF_staticOffset:
|
||||||
return new NamedFunction(DirectMethodHandle.class
|
return getNamedFunction("staticOffset", LONG_OBJ_TYPE);
|
||||||
.getDeclaredMethod("staticOffset", Object.class));
|
|
||||||
case NF_checkCast:
|
case NF_checkCast:
|
||||||
return new NamedFunction(DirectMethodHandle.class
|
return getNamedFunction("checkCast", MethodType.methodType(Object.class, Object.class, Object.class));
|
||||||
.getDeclaredMethod("checkCast", Object.class, Object.class));
|
|
||||||
case NF_allocateInstance:
|
case NF_allocateInstance:
|
||||||
return new NamedFunction(DirectMethodHandle.class
|
return getNamedFunction("allocateInstance", OBJ_OBJ_TYPE);
|
||||||
.getDeclaredMethod("allocateInstance", Object.class));
|
|
||||||
case NF_constructorMethod:
|
case NF_constructorMethod:
|
||||||
return new NamedFunction(DirectMethodHandle.class
|
return getNamedFunction("constructorMethod", OBJ_OBJ_TYPE);
|
||||||
.getDeclaredMethod("constructorMethod", Object.class));
|
|
||||||
case NF_UNSAFE:
|
case NF_UNSAFE:
|
||||||
return new NamedFunction(new MemberName(MethodHandleStatics.class
|
MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getField);
|
||||||
.getDeclaredField("UNSAFE")));
|
return new NamedFunction(
|
||||||
|
MemberName.getFactory()
|
||||||
|
.resolveOrFail(REF_getField, member, DirectMethodHandle.class, NoSuchMethodException.class));
|
||||||
default:
|
default:
|
||||||
throw newInternalError("Unknown function: " + func);
|
throw newInternalError("Unknown function: " + func);
|
||||||
}
|
}
|
||||||
|
@ -797,6 +793,15 @@ class DirectMethodHandle extends MethodHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static NamedFunction getNamedFunction(String name, MethodType type)
|
||||||
|
throws ReflectiveOperationException
|
||||||
|
{
|
||||||
|
MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
|
||||||
|
return new NamedFunction(
|
||||||
|
MemberName.getFactory()
|
||||||
|
.resolveOrFail(REF_invokeStatic, member, DirectMethodHandle.class, NoSuchMethodException.class));
|
||||||
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// The Holder class will contain pre-generated DirectMethodHandles resolved
|
// The Holder class will contain pre-generated DirectMethodHandles resolved
|
||||||
// speculatively using MemberName.getFactory().resolveOrNull. However, that
|
// speculatively using MemberName.getFactory().resolveOrNull. However, that
|
||||||
|
|
|
@ -611,23 +611,17 @@ class Invokers {
|
||||||
try {
|
try {
|
||||||
switch (func) {
|
switch (func) {
|
||||||
case NF_checkExactType:
|
case NF_checkExactType:
|
||||||
return new NamedFunction(Invokers.class
|
return getNamedFunction("checkExactType", MethodType.methodType(void.class, MethodHandle.class, MethodType.class));
|
||||||
.getDeclaredMethod("checkExactType", MethodHandle.class, MethodType.class));
|
|
||||||
case NF_checkGenericType:
|
case NF_checkGenericType:
|
||||||
return new NamedFunction(Invokers.class
|
return getNamedFunction("checkGenericType", MethodType.methodType(MethodHandle.class, MethodHandle.class, MethodType.class));
|
||||||
.getDeclaredMethod("checkGenericType", MethodHandle.class, MethodType.class));
|
|
||||||
case NF_getCallSiteTarget:
|
case NF_getCallSiteTarget:
|
||||||
return new NamedFunction(Invokers.class
|
return getNamedFunction("getCallSiteTarget", MethodType.methodType(MethodHandle.class, CallSite.class));
|
||||||
.getDeclaredMethod("getCallSiteTarget", CallSite.class));
|
|
||||||
case NF_checkCustomized:
|
case NF_checkCustomized:
|
||||||
return new NamedFunction(Invokers.class
|
return getNamedFunction("checkCustomized", MethodType.methodType(void.class, MethodHandle.class));
|
||||||
.getDeclaredMethod("checkCustomized", MethodHandle.class));
|
|
||||||
case NF_checkVarHandleGenericType:
|
case NF_checkVarHandleGenericType:
|
||||||
return new NamedFunction(Invokers.class
|
return getNamedFunction("checkVarHandleGenericType", MethodType.methodType(MethodHandle.class, VarHandle.class, VarHandle.AccessDescriptor.class));
|
||||||
.getDeclaredMethod("checkVarHandleGenericType", VarHandle.class, VarHandle.AccessDescriptor.class));
|
|
||||||
case NF_checkVarHandleExactType:
|
case NF_checkVarHandleExactType:
|
||||||
return new NamedFunction(Invokers.class
|
return getNamedFunction("checkVarHandleExactType", MethodType.methodType(MethodHandle.class, VarHandle.class, VarHandle.AccessDescriptor.class));
|
||||||
.getDeclaredMethod("checkVarHandleExactType", VarHandle.class, VarHandle.AccessDescriptor.class));
|
|
||||||
default:
|
default:
|
||||||
throw newInternalError("Unknown function: " + func);
|
throw newInternalError("Unknown function: " + func);
|
||||||
}
|
}
|
||||||
|
@ -636,6 +630,15 @@ class Invokers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static NamedFunction getNamedFunction(String name, MethodType type)
|
||||||
|
throws ReflectiveOperationException
|
||||||
|
{
|
||||||
|
MemberName member = new MemberName(Invokers.class, name, type, REF_invokeStatic);
|
||||||
|
return new NamedFunction(
|
||||||
|
MemberName.getFactory()
|
||||||
|
.resolveOrFail(REF_invokeStatic, member, Invokers.class, NoSuchMethodException.class));
|
||||||
|
}
|
||||||
|
|
||||||
private static class Lazy {
|
private static class Lazy {
|
||||||
private static final MethodHandle MH_asSpreader;
|
private static final MethodHandle MH_asSpreader;
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,29 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
|
||||||
return (MethodType) type;
|
return (MethodType) type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the descriptor of this member, which
|
||||||
|
* must be a method or constructor.
|
||||||
|
*/
|
||||||
|
String getMethodDescriptor() {
|
||||||
|
if (type == null) {
|
||||||
|
expandFromVM();
|
||||||
|
if (type == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isInvocable()) {
|
||||||
|
throw newIllegalArgumentException("not invocable, no method type");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a snapshot of type which doesn't get changed by racing threads.
|
||||||
|
final Object type = this.type;
|
||||||
|
if (type instanceof String) {
|
||||||
|
return (String) type;
|
||||||
|
} else {
|
||||||
|
return getMethodType().toMethodDescriptorString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Return the actual type under which this method or constructor must be invoked.
|
/** Return the actual type under which this method or constructor must be invoked.
|
||||||
* For non-static methods or constructors, this is the type with a leading parameter,
|
* For non-static methods or constructors, this is the type with a leading parameter,
|
||||||
* a reference to declaring class. For static methods, it is the same as the declared type.
|
* a reference to declaring class. For static methods, it is the same as the declared type.
|
||||||
|
|
|
@ -1785,6 +1785,18 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
||||||
return memberName.getName();
|
return memberName.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodType getMethodType(Object mname) {
|
||||||
|
MemberName memberName = (MemberName)mname;
|
||||||
|
return memberName.getMethodType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMethodDescriptor(Object mname) {
|
||||||
|
MemberName memberName = (MemberName)mname;
|
||||||
|
return memberName.getMethodDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNative(Object mname) {
|
public boolean isNative(Object mname) {
|
||||||
MemberName memberName = (MemberName)mname;
|
MemberName memberName = (MemberName)mname;
|
||||||
|
|
|
@ -211,7 +211,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increments i, mod modulus.
|
* Circularly increments i, mod modulus.
|
||||||
* Precondition and postcondition: 0 <= i < modulus.
|
* Precondition and postcondition: 0 <= i < modulus.
|
||||||
*/
|
*/
|
||||||
static final int inc(int i, int modulus) {
|
static final int inc(int i, int modulus) {
|
||||||
|
@ -220,7 +220,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrements i, mod modulus.
|
* Circularly decrements i, mod modulus.
|
||||||
* Precondition and postcondition: 0 <= i < modulus.
|
* Precondition and postcondition: 0 <= i < modulus.
|
||||||
*/
|
*/
|
||||||
static final int dec(int i, int modulus) {
|
static final int dec(int i, int modulus) {
|
||||||
|
@ -233,7 +233,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
||||||
* Precondition: 0 <= i < modulus, 0 <= distance <= modulus.
|
* Precondition: 0 <= i < modulus, 0 <= distance <= modulus.
|
||||||
* @return index 0 <= i < modulus
|
* @return index 0 <= i < modulus
|
||||||
*/
|
*/
|
||||||
static final int add(int i, int distance, int modulus) {
|
static final int inc(int i, int distance, int modulus) {
|
||||||
if ((i += distance) - modulus >= 0) i -= modulus;
|
if ((i += distance) - modulus >= 0) i -= modulus;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -825,7 +825,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
||||||
final int i, n;
|
final int i, n;
|
||||||
return ((n = sub(getFence(), i = cursor, es.length) >> 1) <= 0)
|
return ((n = sub(getFence(), i = cursor, es.length) >> 1) <= 0)
|
||||||
? null
|
? null
|
||||||
: new DeqSpliterator(i, cursor = add(i, n, es.length));
|
: new DeqSpliterator(i, cursor = inc(i, n, es.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void forEachRemaining(Consumer<? super E> action) {
|
public void forEachRemaining(Consumer<? super E> action) {
|
||||||
|
|
|
@ -490,7 +490,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements Map.putAll and Map constructor
|
* Implements Map.putAll and Map constructor.
|
||||||
*
|
*
|
||||||
* @param m the map
|
* @param m the map
|
||||||
* @param evict false when initially constructing this map, else
|
* @param evict false when initially constructing this map, else
|
||||||
|
@ -557,7 +557,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements Map.get and related methods
|
* Implements Map.get and related methods.
|
||||||
*
|
*
|
||||||
* @param hash hash for key
|
* @param hash hash for key
|
||||||
* @param key the key
|
* @param key the key
|
||||||
|
@ -612,7 +612,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements Map.put and related methods
|
* Implements Map.put and related methods.
|
||||||
*
|
*
|
||||||
* @param hash hash for key
|
* @param hash hash for key
|
||||||
* @param key the key
|
* @param key the key
|
||||||
|
@ -700,7 +700,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
}
|
}
|
||||||
threshold = newThr;
|
threshold = newThr;
|
||||||
@SuppressWarnings({"rawtypes","unchecked"})
|
@SuppressWarnings({"rawtypes","unchecked"})
|
||||||
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
|
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
|
||||||
table = newTab;
|
table = newTab;
|
||||||
if (oldTab != null) {
|
if (oldTab != null) {
|
||||||
for (int j = 0; j < oldCap; ++j) {
|
for (int j = 0; j < oldCap; ++j) {
|
||||||
|
@ -800,7 +800,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements Map.remove and related methods
|
* Implements Map.remove and related methods.
|
||||||
*
|
*
|
||||||
* @param hash hash for key
|
* @param hash hash for key
|
||||||
* @param key the key
|
* @param key the key
|
||||||
|
@ -875,7 +875,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
public boolean containsValue(Object value) {
|
public boolean containsValue(Object value) {
|
||||||
Node<K,V>[] tab; V v;
|
Node<K,V>[] tab; V v;
|
||||||
if ((tab = table) != null && size > 0) {
|
if ((tab = table) != null && size > 0) {
|
||||||
for (Node<K, V> e : tab) {
|
for (Node<K,V> e : tab) {
|
||||||
for (; e != null; e = e.next) {
|
for (; e != null; e = e.next) {
|
||||||
if ((v = e.value) == value ||
|
if ((v = e.value) == value ||
|
||||||
(value != null && value.equals(v)))
|
(value != null && value.equals(v)))
|
||||||
|
@ -927,7 +927,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
if (size > 0 && (tab = table) != null) {
|
if (size > 0 && (tab = table) != null) {
|
||||||
int mc = modCount;
|
int mc = modCount;
|
||||||
for (Node<K, V> e : tab) {
|
for (Node<K,V> e : tab) {
|
||||||
for (; e != null; e = e.next)
|
for (; e != null; e = e.next)
|
||||||
action.accept(e.key);
|
action.accept(e.key);
|
||||||
}
|
}
|
||||||
|
@ -975,7 +975,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
if (size > 0 && (tab = table) != null) {
|
if (size > 0 && (tab = table) != null) {
|
||||||
int mc = modCount;
|
int mc = modCount;
|
||||||
for (Node<K, V> e : tab) {
|
for (Node<K,V> e : tab) {
|
||||||
for (; e != null; e = e.next)
|
for (; e != null; e = e.next)
|
||||||
action.accept(e.value);
|
action.accept(e.value);
|
||||||
}
|
}
|
||||||
|
@ -1038,7 +1038,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
if (size > 0 && (tab = table) != null) {
|
if (size > 0 && (tab = table) != null) {
|
||||||
int mc = modCount;
|
int mc = modCount;
|
||||||
for (Node<K, V> e : tab) {
|
for (Node<K,V> e : tab) {
|
||||||
for (; e != null; e = e.next)
|
for (; e != null; e = e.next)
|
||||||
action.accept(e);
|
action.accept(e);
|
||||||
}
|
}
|
||||||
|
@ -1335,7 +1335,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
if (size > 0 && (tab = table) != null) {
|
if (size > 0 && (tab = table) != null) {
|
||||||
int mc = modCount;
|
int mc = modCount;
|
||||||
for (Node<K, V> e : tab) {
|
for (Node<K,V> e : tab) {
|
||||||
for (; e != null; e = e.next)
|
for (; e != null; e = e.next)
|
||||||
action.accept(e.key, e.value);
|
action.accept(e.key, e.value);
|
||||||
}
|
}
|
||||||
|
@ -1351,7 +1351,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
if (size > 0 && (tab = table) != null) {
|
if (size > 0 && (tab = table) != null) {
|
||||||
int mc = modCount;
|
int mc = modCount;
|
||||||
for (Node<K, V> e : tab) {
|
for (Node<K,V> e : tab) {
|
||||||
for (; e != null; e = e.next) {
|
for (; e != null; e = e.next) {
|
||||||
e.value = function.apply(e.key, e.value);
|
e.value = function.apply(e.key, e.value);
|
||||||
}
|
}
|
||||||
|
@ -1394,9 +1394,10 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the state of the {@code HashMap} instance to a stream (i.e.,
|
* Saves this map to a stream (that is, serializes it).
|
||||||
* serialize it).
|
|
||||||
*
|
*
|
||||||
|
* @param s the stream
|
||||||
|
* @throws IOException if an I/O error occurs
|
||||||
* @serialData The <i>capacity</i> of the HashMap (the length of the
|
* @serialData The <i>capacity</i> of the HashMap (the length of the
|
||||||
* bucket array) is emitted (int), followed by the
|
* bucket array) is emitted (int), followed by the
|
||||||
* <i>size</i> (an int, the number of key-value
|
* <i>size</i> (an int, the number of key-value
|
||||||
|
@ -1415,8 +1416,11 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconstitute the {@code HashMap} instance from a stream (i.e.,
|
* Reconstitutes this map from a stream (that is, deserializes it).
|
||||||
* deserialize it).
|
* @param s the stream
|
||||||
|
* @throws ClassNotFoundException if the class of a serialized object
|
||||||
|
* could not be found
|
||||||
|
* @throws IOException if an I/O error occurs
|
||||||
*/
|
*/
|
||||||
private void readObject(java.io.ObjectInputStream s)
|
private void readObject(java.io.ObjectInputStream s)
|
||||||
throws IOException, ClassNotFoundException {
|
throws IOException, ClassNotFoundException {
|
||||||
|
@ -1445,7 +1449,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
|
threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
|
||||||
(int)ft : Integer.MAX_VALUE);
|
(int)ft : Integer.MAX_VALUE);
|
||||||
@SuppressWarnings({"rawtypes","unchecked"})
|
@SuppressWarnings({"rawtypes","unchecked"})
|
||||||
Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
|
Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
|
||||||
table = tab;
|
table = tab;
|
||||||
|
|
||||||
// Read the keys and values, and put the mappings in the HashMap
|
// Read the keys and values, and put the mappings in the HashMap
|
||||||
|
@ -1830,7 +1834,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException {
|
void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException {
|
||||||
Node<K,V>[] tab;
|
Node<K,V>[] tab;
|
||||||
if (size > 0 && (tab = table) != null) {
|
if (size > 0 && (tab = table) != null) {
|
||||||
for (Node<K, V> e : tab) {
|
for (Node<K,V> e : tab) {
|
||||||
for (; e != null; e = e.next) {
|
for (; e != null; e = e.next) {
|
||||||
s.writeObject(e.key);
|
s.writeObject(e.key);
|
||||||
s.writeObject(e.value);
|
s.writeObject(e.value);
|
||||||
|
@ -1951,7 +1955,6 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forms tree of the nodes linked from this node.
|
* Forms tree of the nodes linked from this node.
|
||||||
* @return root of tree
|
|
||||||
*/
|
*/
|
||||||
final void treeify(Node<K,V>[] tab) {
|
final void treeify(Node<K,V>[] tab) {
|
||||||
TreeNode<K,V> root = null;
|
TreeNode<K,V> root = null;
|
||||||
|
@ -2089,8 +2092,11 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
return;
|
return;
|
||||||
if (root.parent != null)
|
if (root.parent != null)
|
||||||
root = root.root();
|
root = root.root();
|
||||||
if (root == null || root.right == null ||
|
if (root == null
|
||||||
(rl = root.left) == null || rl.left == null) {
|
|| (movable
|
||||||
|
&& (root.right == null
|
||||||
|
|| (rl = root.left) == null
|
||||||
|
|| rl.left == null))) {
|
||||||
tab[index] = first.untreeify(map); // too small
|
tab[index] = first.untreeify(map); // too small
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2319,7 +2325,7 @@ public class HashMap<K,V> extends AbstractMap<K,V>
|
||||||
|
|
||||||
static <K,V> TreeNode<K,V> balanceDeletion(TreeNode<K,V> root,
|
static <K,V> TreeNode<K,V> balanceDeletion(TreeNode<K,V> root,
|
||||||
TreeNode<K,V> x) {
|
TreeNode<K,V> x) {
|
||||||
for (TreeNode<K,V> xp, xpl, xpr;;) {
|
for (TreeNode<K,V> xp, xpl, xpr;;) {
|
||||||
if (x == null || x == root)
|
if (x == null || x == root)
|
||||||
return root;
|
return root;
|
||||||
else if ((xp = x.parent) == null) {
|
else if ((xp = x.parent) == null) {
|
||||||
|
|
|
@ -2490,13 +2490,13 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
||||||
for (Completion p = stack; p != null; p = p.next)
|
for (Completion p = stack; p != null; p = p.next)
|
||||||
++count;
|
++count;
|
||||||
return super.toString() +
|
return super.toString() +
|
||||||
((r == null) ?
|
((r == null)
|
||||||
((count == 0) ?
|
? ((count == 0)
|
||||||
"[Not completed]" :
|
? "[Not completed]"
|
||||||
"[Not completed, " + count + " dependents]") :
|
: "[Not completed, " + count + " dependents]")
|
||||||
(((r instanceof AltResult) && ((AltResult)r).ex != null) ?
|
: (((r instanceof AltResult) && ((AltResult)r).ex != null)
|
||||||
"[Completed exceptionally]" :
|
? "[Completed exceptionally: " + ((AltResult)r).ex + "]"
|
||||||
"[Completed normally]"));
|
: "[Completed normally]"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// jdk9 additions
|
// jdk9 additions
|
||||||
|
|
|
@ -1394,8 +1394,8 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the state of the {@code ConcurrentHashMap} instance to a
|
* Saves this map to a stream (that is, serializes it).
|
||||||
* stream (i.e., serializes it).
|
*
|
||||||
* @param s the stream
|
* @param s the stream
|
||||||
* @throws java.io.IOException if an I/O error occurs
|
* @throws java.io.IOException if an I/O error occurs
|
||||||
* @serialData
|
* @serialData
|
||||||
|
@ -1439,7 +1439,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reconstitutes the instance from a stream (that is, deserializes it).
|
* Reconstitutes this map from a stream (that is, deserializes it).
|
||||||
* @param s the stream
|
* @param s the stream
|
||||||
* @throws ClassNotFoundException if the class of a serialized object
|
* @throws ClassNotFoundException if the class of a serialized object
|
||||||
* could not be found
|
* could not be found
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -174,6 +174,10 @@ public class ExecutorCompletionService<V> implements CompletionService<V> {
|
||||||
this.completionQueue = completionQueue;
|
this.completionQueue = completionQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws RejectedExecutionException {@inheritDoc}
|
||||||
|
* @throws NullPointerException {@inheritDoc}
|
||||||
|
*/
|
||||||
public Future<V> submit(Callable<V> task) {
|
public Future<V> submit(Callable<V> task) {
|
||||||
if (task == null) throw new NullPointerException();
|
if (task == null) throw new NullPointerException();
|
||||||
RunnableFuture<V> f = newTaskFor(task);
|
RunnableFuture<V> f = newTaskFor(task);
|
||||||
|
@ -181,6 +185,10 @@ public class ExecutorCompletionService<V> implements CompletionService<V> {
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws RejectedExecutionException {@inheritDoc}
|
||||||
|
* @throws NullPointerException {@inheritDoc}
|
||||||
|
*/
|
||||||
public Future<V> submit(Runnable task, V result) {
|
public Future<V> submit(Runnable task, V result) {
|
||||||
if (task == null) throw new NullPointerException();
|
if (task == null) throw new NullPointerException();
|
||||||
RunnableFuture<V> f = newTaskFor(task, result);
|
RunnableFuture<V> f = newTaskFor(task, result);
|
||||||
|
|
|
@ -514,6 +514,9 @@ public class Executors {
|
||||||
task.run();
|
task.run();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + "[Wrapped task = " + task + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -540,6 +543,10 @@ public class Executors {
|
||||||
throw e.getException();
|
throw e.getException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + "[Wrapped task = " + task + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -592,6 +599,10 @@ public class Executors {
|
||||||
throw e.getException();
|
throw e.getException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + "[Wrapped task = " + task + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1375,6 +1375,9 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
|
||||||
public final void setRawResult(T v) { result = v; }
|
public final void setRawResult(T v) { result = v; }
|
||||||
public final boolean exec() { runnable.run(); return true; }
|
public final boolean exec() { runnable.run(); return true; }
|
||||||
public final void run() { invoke(); }
|
public final void run() { invoke(); }
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + "[Wrapped task = " + runnable + "]";
|
||||||
|
}
|
||||||
private static final long serialVersionUID = 5232453952276885070L;
|
private static final long serialVersionUID = 5232453952276885070L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1392,6 +1395,9 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
|
||||||
public final void setRawResult(Void v) { }
|
public final void setRawResult(Void v) { }
|
||||||
public final boolean exec() { runnable.run(); return true; }
|
public final boolean exec() { runnable.run(); return true; }
|
||||||
public final void run() { invoke(); }
|
public final void run() { invoke(); }
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + "[Wrapped task = " + runnable + "]";
|
||||||
|
}
|
||||||
private static final long serialVersionUID = 5232453952276885070L;
|
private static final long serialVersionUID = 5232453952276885070L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1437,6 +1443,9 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public final void run() { invoke(); }
|
public final void run() { invoke(); }
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + "[Wrapped task = " + callable + "]";
|
||||||
|
}
|
||||||
private static final long serialVersionUID = 2838392045355241008L;
|
private static final long serialVersionUID = 2838392045355241008L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -480,6 +480,41 @@ public class FutureTask<V> implements RunnableFuture<V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of this FutureTask.
|
||||||
|
*
|
||||||
|
* @implSpec
|
||||||
|
* The default implementation returns a string identifying this
|
||||||
|
* FutureTask, as well as its completion state. The state, in
|
||||||
|
* brackets, contains one of the strings {@code "Completed Normally"},
|
||||||
|
* {@code "Completed Exceptionally"}, {@code "Cancelled"}, or {@code
|
||||||
|
* "Not completed"}.
|
||||||
|
*
|
||||||
|
* @return a string representation of this FutureTask
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
final String status;
|
||||||
|
switch (state) {
|
||||||
|
case NORMAL:
|
||||||
|
status = "[Completed normally]";
|
||||||
|
break;
|
||||||
|
case EXCEPTIONAL:
|
||||||
|
status = "[Completed exceptionally: " + outcome + "]";
|
||||||
|
break;
|
||||||
|
case CANCELLED:
|
||||||
|
case INTERRUPTING:
|
||||||
|
case INTERRUPTED:
|
||||||
|
status = "[Cancelled]";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
final Callable<?> callable = this.callable;
|
||||||
|
status = (callable == null)
|
||||||
|
? "[Not completed]"
|
||||||
|
: "[Not completed, task = " + callable + "]";
|
||||||
|
}
|
||||||
|
return super.toString() + status;
|
||||||
|
}
|
||||||
|
|
||||||
// VarHandle mechanics
|
// VarHandle mechanics
|
||||||
private static final VarHandle STATE;
|
private static final VarHandle STATE;
|
||||||
private static final VarHandle RUNNER;
|
private static final VarHandle RUNNER;
|
||||||
|
|
|
@ -383,7 +383,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
*/
|
*/
|
||||||
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
|
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
|
||||||
private static final int COUNT_BITS = Integer.SIZE - 3;
|
private static final int COUNT_BITS = Integer.SIZE - 3;
|
||||||
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
|
private static final int COUNT_MASK = (1 << COUNT_BITS) - 1;
|
||||||
|
|
||||||
// runState is stored in the high-order bits
|
// runState is stored in the high-order bits
|
||||||
private static final int RUNNING = -1 << COUNT_BITS;
|
private static final int RUNNING = -1 << COUNT_BITS;
|
||||||
|
@ -393,8 +393,8 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
private static final int TERMINATED = 3 << COUNT_BITS;
|
private static final int TERMINATED = 3 << COUNT_BITS;
|
||||||
|
|
||||||
// Packing and unpacking ctl
|
// Packing and unpacking ctl
|
||||||
private static int runStateOf(int c) { return c & ~CAPACITY; }
|
private static int runStateOf(int c) { return c & ~COUNT_MASK; }
|
||||||
private static int workerCountOf(int c) { return c & CAPACITY; }
|
private static int workerCountOf(int c) { return c & COUNT_MASK; }
|
||||||
private static int ctlOf(int rs, int wc) { return rs | wc; }
|
private static int ctlOf(int rs, int wc) { return rs | wc; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -434,7 +434,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
* decrements are performed within getTask.
|
* decrements are performed within getTask.
|
||||||
*/
|
*/
|
||||||
private void decrementWorkerCount() {
|
private void decrementWorkerCount() {
|
||||||
do {} while (! compareAndDecrementWorkerCount(ctl.get()));
|
ctl.addAndGet(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -538,12 +538,17 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
* Core pool size is the minimum number of workers to keep alive
|
* Core pool size is the minimum number of workers to keep alive
|
||||||
* (and not allow to time out etc) unless allowCoreThreadTimeOut
|
* (and not allow to time out etc) unless allowCoreThreadTimeOut
|
||||||
* is set, in which case the minimum is zero.
|
* is set, in which case the minimum is zero.
|
||||||
|
*
|
||||||
|
* Since the worker count is actually stored in COUNT_BITS bits,
|
||||||
|
* the effective limit is {@code corePoolSize & COUNT_MASK}.
|
||||||
*/
|
*/
|
||||||
private volatile int corePoolSize;
|
private volatile int corePoolSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum pool size. Note that the actual maximum is internally
|
* Maximum pool size.
|
||||||
* bounded by CAPACITY.
|
*
|
||||||
|
* Since the worker count is actually stored in COUNT_BITS bits,
|
||||||
|
* the effective limit is {@code maximumPoolSize & COUNT_MASK}.
|
||||||
*/
|
*/
|
||||||
private volatile int maximumPoolSize;
|
private volatile int maximumPoolSize;
|
||||||
|
|
||||||
|
@ -705,7 +710,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
int c = ctl.get();
|
int c = ctl.get();
|
||||||
if (isRunning(c) ||
|
if (isRunning(c) ||
|
||||||
runStateAtLeast(c, TIDYING) ||
|
runStateAtLeast(c, TIDYING) ||
|
||||||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
|
(runStateLessThan(c, STOP) && ! workQueue.isEmpty()))
|
||||||
return;
|
return;
|
||||||
if (workerCountOf(c) != 0) { // Eligible to terminate
|
if (workerCountOf(c) != 0) { // Eligible to terminate
|
||||||
interruptIdleWorkers(ONLY_ONE);
|
interruptIdleWorkers(ONLY_ONE);
|
||||||
|
@ -744,17 +749,12 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
* specially.
|
* specially.
|
||||||
*/
|
*/
|
||||||
private void checkShutdownAccess() {
|
private void checkShutdownAccess() {
|
||||||
|
// assert mainLock.isHeldByCurrentThread();
|
||||||
SecurityManager security = System.getSecurityManager();
|
SecurityManager security = System.getSecurityManager();
|
||||||
if (security != null) {
|
if (security != null) {
|
||||||
security.checkPermission(shutdownPerm);
|
security.checkPermission(shutdownPerm);
|
||||||
final ReentrantLock mainLock = this.mainLock;
|
for (Worker w : workers)
|
||||||
mainLock.lock();
|
security.checkAccess(w.thread);
|
||||||
try {
|
|
||||||
for (Worker w : workers)
|
|
||||||
security.checkAccess(w.thread);
|
|
||||||
} finally {
|
|
||||||
mainLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,14 +763,9 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
* (in which case some threads may remain uninterrupted).
|
* (in which case some threads may remain uninterrupted).
|
||||||
*/
|
*/
|
||||||
private void interruptWorkers() {
|
private void interruptWorkers() {
|
||||||
final ReentrantLock mainLock = this.mainLock;
|
// assert mainLock.isHeldByCurrentThread();
|
||||||
mainLock.lock();
|
for (Worker w : workers)
|
||||||
try {
|
w.interruptIfStarted();
|
||||||
for (Worker w : workers)
|
|
||||||
w.interruptIfStarted();
|
|
||||||
} finally {
|
|
||||||
mainLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -896,26 +891,22 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
*/
|
*/
|
||||||
private boolean addWorker(Runnable firstTask, boolean core) {
|
private boolean addWorker(Runnable firstTask, boolean core) {
|
||||||
retry:
|
retry:
|
||||||
for (;;) {
|
for (int c = ctl.get();;) {
|
||||||
int c = ctl.get();
|
|
||||||
int rs = runStateOf(c);
|
|
||||||
|
|
||||||
// Check if queue empty only if necessary.
|
// Check if queue empty only if necessary.
|
||||||
if (rs >= SHUTDOWN &&
|
if (runStateAtLeast(c, SHUTDOWN)
|
||||||
! (rs == SHUTDOWN &&
|
&& (runStateAtLeast(c, STOP)
|
||||||
firstTask == null &&
|
|| firstTask != null
|
||||||
! workQueue.isEmpty()))
|
|| workQueue.isEmpty()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int wc = workerCountOf(c);
|
if (workerCountOf(c)
|
||||||
if (wc >= CAPACITY ||
|
>= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK))
|
||||||
wc >= (core ? corePoolSize : maximumPoolSize))
|
|
||||||
return false;
|
return false;
|
||||||
if (compareAndIncrementWorkerCount(c))
|
if (compareAndIncrementWorkerCount(c))
|
||||||
break retry;
|
break retry;
|
||||||
c = ctl.get(); // Re-read ctl
|
c = ctl.get(); // Re-read ctl
|
||||||
if (runStateOf(c) != rs)
|
if (runStateAtLeast(c, SHUTDOWN))
|
||||||
continue retry;
|
continue retry;
|
||||||
// else CAS failed due to workerCount change; retry inner loop
|
// else CAS failed due to workerCount change; retry inner loop
|
||||||
}
|
}
|
||||||
|
@ -934,10 +925,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
// Recheck while holding lock.
|
// Recheck while holding lock.
|
||||||
// Back out on ThreadFactory failure or if
|
// Back out on ThreadFactory failure or if
|
||||||
// shut down before lock acquired.
|
// shut down before lock acquired.
|
||||||
int rs = runStateOf(ctl.get());
|
int c = ctl.get();
|
||||||
|
|
||||||
if (rs < SHUTDOWN ||
|
if (isRunning(c) ||
|
||||||
(rs == SHUTDOWN && firstTask == null)) {
|
(runStateLessThan(c, STOP) && firstTask == null)) {
|
||||||
if (t.isAlive()) // precheck that t is startable
|
if (t.isAlive()) // precheck that t is startable
|
||||||
throw new IllegalThreadStateException();
|
throw new IllegalThreadStateException();
|
||||||
workers.add(w);
|
workers.add(w);
|
||||||
|
@ -1044,10 +1035,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = ctl.get();
|
int c = ctl.get();
|
||||||
int rs = runStateOf(c);
|
|
||||||
|
|
||||||
// Check if queue empty only if necessary.
|
// Check if queue empty only if necessary.
|
||||||
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
|
if (runStateAtLeast(c, SHUTDOWN)
|
||||||
|
&& (runStateAtLeast(c, STOP) || workQueue.isEmpty())) {
|
||||||
decrementWorkerCount();
|
decrementWorkerCount();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1140,17 +1131,12 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
wt.interrupt();
|
wt.interrupt();
|
||||||
try {
|
try {
|
||||||
beforeExecute(wt, task);
|
beforeExecute(wt, task);
|
||||||
Throwable thrown = null;
|
|
||||||
try {
|
try {
|
||||||
task.run();
|
task.run();
|
||||||
} catch (RuntimeException x) {
|
afterExecute(task, null);
|
||||||
thrown = x; throw x;
|
} catch (Throwable ex) {
|
||||||
} catch (Error x) {
|
afterExecute(task, ex);
|
||||||
thrown = x; throw x;
|
throw ex;
|
||||||
} catch (Throwable x) {
|
|
||||||
thrown = x; throw new Error(x);
|
|
||||||
} finally {
|
|
||||||
afterExecute(task, thrown);
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
task = null;
|
task = null;
|
||||||
|
@ -1331,7 +1317,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
*
|
*
|
||||||
* If the task cannot be submitted for execution, either because this
|
* If the task cannot be submitted for execution, either because this
|
||||||
* executor has been shutdown or because its capacity has been reached,
|
* executor has been shutdown or because its capacity has been reached,
|
||||||
* the task is handled by the current {@code RejectedExecutionHandler}.
|
* the task is handled by the current {@link RejectedExecutionHandler}.
|
||||||
*
|
*
|
||||||
* @param command the task to execute
|
* @param command the task to execute
|
||||||
* @throws RejectedExecutionException at discretion of
|
* @throws RejectedExecutionException at discretion of
|
||||||
|
@ -1438,7 +1424,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isShutdown() {
|
public boolean isShutdown() {
|
||||||
return ! isRunning(ctl.get());
|
return runStateAtLeast(ctl.get(), SHUTDOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Used by ScheduledThreadPoolExecutor. */
|
/** Used by ScheduledThreadPoolExecutor. */
|
||||||
|
@ -1459,7 +1445,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
*/
|
*/
|
||||||
public boolean isTerminating() {
|
public boolean isTerminating() {
|
||||||
int c = ctl.get();
|
int c = ctl.get();
|
||||||
return ! isRunning(c) && runStateLessThan(c, TERMINATED);
|
return runStateAtLeast(c, SHUTDOWN) && runStateLessThan(c, TERMINATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTerminated() {
|
public boolean isTerminated() {
|
||||||
|
@ -1472,7 +1458,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
final ReentrantLock mainLock = this.mainLock;
|
final ReentrantLock mainLock = this.mainLock;
|
||||||
mainLock.lock();
|
mainLock.lock();
|
||||||
try {
|
try {
|
||||||
while (!runStateAtLeast(ctl.get(), TERMINATED)) {
|
while (runStateLessThan(ctl.get(), TERMINATED)) {
|
||||||
if (nanos <= 0L)
|
if (nanos <= 0L)
|
||||||
return false;
|
return false;
|
||||||
nanos = termination.awaitNanos(nanos);
|
nanos = termination.awaitNanos(nanos);
|
||||||
|
@ -1951,7 +1937,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||||
}
|
}
|
||||||
int c = ctl.get();
|
int c = ctl.get();
|
||||||
String runState =
|
String runState =
|
||||||
runStateLessThan(c, SHUTDOWN) ? "Running" :
|
isRunning(c) ? "Running" :
|
||||||
runStateAtLeast(c, TERMINATED) ? "Terminated" :
|
runStateAtLeast(c, TERMINATED) ? "Terminated" :
|
||||||
"Shutting down";
|
"Shutting down";
|
||||||
return super.toString() +
|
return super.toString() +
|
||||||
|
|
|
@ -342,11 +342,13 @@ public enum TimeUnit {
|
||||||
* using:
|
* using:
|
||||||
*
|
*
|
||||||
* <pre> {@code
|
* <pre> {@code
|
||||||
* public synchronized Object poll(long timeout, TimeUnit unit)
|
* public E poll(long timeout, TimeUnit unit)
|
||||||
* throws InterruptedException {
|
* throws InterruptedException {
|
||||||
* while (empty) {
|
* synchronized (lock) {
|
||||||
* unit.timedWait(this, timeout);
|
* while (isEmpty()) {
|
||||||
* ...
|
* unit.timedWait(lock, timeout);
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
* }
|
* }
|
||||||
* }}</pre>
|
* }}</pre>
|
||||||
*
|
*
|
||||||
|
|
|
@ -67,11 +67,11 @@ public abstract class AbstractQueuedLongSynchronizer
|
||||||
private static final long serialVersionUID = 7373984972572414692L;
|
private static final long serialVersionUID = 7373984972572414692L;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
To keep sources in sync, the remainder of this source file is
|
* To keep sources in sync, the remainder of this source file is
|
||||||
exactly cloned from AbstractQueuedSynchronizer, replacing class
|
* exactly cloned from AbstractQueuedSynchronizer, replacing class
|
||||||
name and changing ints related with sync state to longs. Please
|
* name and changing ints related with sync state to longs. Please
|
||||||
keep it that way.
|
* keep it that way.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@code AbstractQueuedLongSynchronizer} instance
|
* Creates a new {@code AbstractQueuedLongSynchronizer} instance
|
||||||
|
@ -725,8 +725,7 @@ public abstract class AbstractQueuedLongSynchronizer
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if synchronization is held exclusively with
|
* Returns {@code true} if synchronization is held exclusively with
|
||||||
* respect to the current (calling) thread. This method is invoked
|
* respect to the current (calling) thread. This method is invoked
|
||||||
* upon each call to a non-waiting {@link ConditionObject} method.
|
* upon each call to a {@link ConditionObject} method.
|
||||||
* (Waiting methods instead invoke {@link #release}.)
|
|
||||||
*
|
*
|
||||||
* <p>The default implementation throws {@link
|
* <p>The default implementation throws {@link
|
||||||
* UnsupportedOperationException}. This method is invoked
|
* UnsupportedOperationException}. This method is invoked
|
||||||
|
@ -1366,9 +1365,8 @@ public abstract class AbstractQueuedLongSynchronizer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Condition implementation for a {@link
|
* Condition implementation for a {@link AbstractQueuedLongSynchronizer}
|
||||||
* AbstractQueuedLongSynchronizer} serving as the basis of a {@link
|
* serving as the basis of a {@link Lock} implementation.
|
||||||
* Lock} implementation.
|
|
||||||
*
|
*
|
||||||
* <p>Method documentation for this class describes mechanics,
|
* <p>Method documentation for this class describes mechanics,
|
||||||
* not behavioral specifications from the point of view of Lock
|
* not behavioral specifications from the point of view of Lock
|
||||||
|
@ -1401,6 +1399,8 @@ public abstract class AbstractQueuedLongSynchronizer
|
||||||
* @return its new wait node
|
* @return its new wait node
|
||||||
*/
|
*/
|
||||||
private Node addConditionWaiter() {
|
private Node addConditionWaiter() {
|
||||||
|
if (!isHeldExclusively())
|
||||||
|
throw new IllegalMonitorStateException();
|
||||||
Node t = lastWaiter;
|
Node t = lastWaiter;
|
||||||
// If lastWaiter is cancelled, clean out.
|
// If lastWaiter is cancelled, clean out.
|
||||||
if (t != null && t.waitStatus != Node.CONDITION) {
|
if (t != null && t.waitStatus != Node.CONDITION) {
|
||||||
|
|
|
@ -194,19 +194,13 @@ import java.util.concurrent.TimeUnit;
|
||||||
* represent the locked state. While a non-reentrant lock
|
* represent the locked state. While a non-reentrant lock
|
||||||
* does not strictly require recording of the current owner
|
* does not strictly require recording of the current owner
|
||||||
* thread, this class does so anyway to make usage easier to monitor.
|
* thread, this class does so anyway to make usage easier to monitor.
|
||||||
* It also supports conditions and exposes
|
* It also supports conditions and exposes some instrumentation methods:
|
||||||
* one of the instrumentation methods:
|
|
||||||
*
|
*
|
||||||
* <pre> {@code
|
* <pre> {@code
|
||||||
* class Mutex implements Lock, java.io.Serializable {
|
* class Mutex implements Lock, java.io.Serializable {
|
||||||
*
|
*
|
||||||
* // Our internal helper class
|
* // Our internal helper class
|
||||||
* private static class Sync extends AbstractQueuedSynchronizer {
|
* private static class Sync extends AbstractQueuedSynchronizer {
|
||||||
* // Reports whether in locked state
|
|
||||||
* protected boolean isHeldExclusively() {
|
|
||||||
* return getState() == 1;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* // Acquires the lock if state is zero
|
* // Acquires the lock if state is zero
|
||||||
* public boolean tryAcquire(int acquires) {
|
* public boolean tryAcquire(int acquires) {
|
||||||
* assert acquires == 1; // Otherwise unused
|
* assert acquires == 1; // Otherwise unused
|
||||||
|
@ -220,14 +214,27 @@ import java.util.concurrent.TimeUnit;
|
||||||
* // Releases the lock by setting state to zero
|
* // Releases the lock by setting state to zero
|
||||||
* protected boolean tryRelease(int releases) {
|
* protected boolean tryRelease(int releases) {
|
||||||
* assert releases == 1; // Otherwise unused
|
* assert releases == 1; // Otherwise unused
|
||||||
* if (getState() == 0) throw new IllegalMonitorStateException();
|
* if (!isHeldExclusively())
|
||||||
|
* throw new IllegalMonitorStateException();
|
||||||
* setExclusiveOwnerThread(null);
|
* setExclusiveOwnerThread(null);
|
||||||
* setState(0);
|
* setState(0);
|
||||||
* return true;
|
* return true;
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
|
* // Reports whether in locked state
|
||||||
|
* public boolean isLocked() {
|
||||||
|
* return getState() != 0;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* public boolean isHeldExclusively() {
|
||||||
|
* // a data race, but safe due to out-of-thin-air guarantees
|
||||||
|
* return getExclusiveOwnerThread() == Thread.currentThread();
|
||||||
|
* }
|
||||||
|
*
|
||||||
* // Provides a Condition
|
* // Provides a Condition
|
||||||
* Condition newCondition() { return new ConditionObject(); }
|
* public Condition newCondition() {
|
||||||
|
* return new ConditionObject();
|
||||||
|
* }
|
||||||
*
|
*
|
||||||
* // Deserializes properly
|
* // Deserializes properly
|
||||||
* private void readObject(ObjectInputStream s)
|
* private void readObject(ObjectInputStream s)
|
||||||
|
@ -240,12 +247,17 @@ import java.util.concurrent.TimeUnit;
|
||||||
* // The sync object does all the hard work. We just forward to it.
|
* // The sync object does all the hard work. We just forward to it.
|
||||||
* private final Sync sync = new Sync();
|
* private final Sync sync = new Sync();
|
||||||
*
|
*
|
||||||
* public void lock() { sync.acquire(1); }
|
* public void lock() { sync.acquire(1); }
|
||||||
* public boolean tryLock() { return sync.tryAcquire(1); }
|
* public boolean tryLock() { return sync.tryAcquire(1); }
|
||||||
* public void unlock() { sync.release(1); }
|
* public void unlock() { sync.release(1); }
|
||||||
* public Condition newCondition() { return sync.newCondition(); }
|
* public Condition newCondition() { return sync.newCondition(); }
|
||||||
* public boolean isLocked() { return sync.isHeldExclusively(); }
|
* public boolean isLocked() { return sync.isLocked(); }
|
||||||
* public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
|
* public boolean isHeldByCurrentThread() {
|
||||||
|
* return sync.isHeldExclusively();
|
||||||
|
* }
|
||||||
|
* public boolean hasQueuedThreads() {
|
||||||
|
* return sync.hasQueuedThreads();
|
||||||
|
* }
|
||||||
* public void lockInterruptibly() throws InterruptedException {
|
* public void lockInterruptibly() throws InterruptedException {
|
||||||
* sync.acquireInterruptibly(1);
|
* sync.acquireInterruptibly(1);
|
||||||
* }
|
* }
|
||||||
|
@ -1193,8 +1205,7 @@ public abstract class AbstractQueuedSynchronizer
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if synchronization is held exclusively with
|
* Returns {@code true} if synchronization is held exclusively with
|
||||||
* respect to the current (calling) thread. This method is invoked
|
* respect to the current (calling) thread. This method is invoked
|
||||||
* upon each call to a non-waiting {@link ConditionObject} method.
|
* upon each call to a {@link ConditionObject} method.
|
||||||
* (Waiting methods instead invoke {@link #release}.)
|
|
||||||
*
|
*
|
||||||
* <p>The default implementation throws {@link
|
* <p>The default implementation throws {@link
|
||||||
* UnsupportedOperationException}. This method is invoked
|
* UnsupportedOperationException}. This method is invoked
|
||||||
|
@ -1834,9 +1845,8 @@ public abstract class AbstractQueuedSynchronizer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Condition implementation for a {@link
|
* Condition implementation for a {@link AbstractQueuedSynchronizer}
|
||||||
* AbstractQueuedSynchronizer} serving as the basis of a {@link
|
* serving as the basis of a {@link Lock} implementation.
|
||||||
* Lock} implementation.
|
|
||||||
*
|
*
|
||||||
* <p>Method documentation for this class describes mechanics,
|
* <p>Method documentation for this class describes mechanics,
|
||||||
* not behavioral specifications from the point of view of Lock
|
* not behavioral specifications from the point of view of Lock
|
||||||
|
@ -1867,6 +1877,8 @@ public abstract class AbstractQueuedSynchronizer
|
||||||
* @return its new wait node
|
* @return its new wait node
|
||||||
*/
|
*/
|
||||||
private Node addConditionWaiter() {
|
private Node addConditionWaiter() {
|
||||||
|
if (!isHeldExclusively())
|
||||||
|
throw new IllegalMonitorStateException();
|
||||||
Node t = lastWaiter;
|
Node t = lastWaiter;
|
||||||
// If lastWaiter is cancelled, clean out.
|
// If lastWaiter is cancelled, clean out.
|
||||||
if (t != null && t.waitStatus != Node.CONDITION) {
|
if (t != null && t.waitStatus != Node.CONDITION) {
|
||||||
|
|
|
@ -73,7 +73,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
* available in the buffer. This can be achieved using two
|
* available in the buffer. This can be achieved using two
|
||||||
* {@link Condition} instances.
|
* {@link Condition} instances.
|
||||||
* <pre>
|
* <pre>
|
||||||
* class BoundedBuffer {
|
* class BoundedBuffer<E> {
|
||||||
* <b>final Lock lock = new ReentrantLock();</b>
|
* <b>final Lock lock = new ReentrantLock();</b>
|
||||||
* final Condition notFull = <b>lock.newCondition(); </b>
|
* final Condition notFull = <b>lock.newCondition(); </b>
|
||||||
* final Condition notEmpty = <b>lock.newCondition(); </b>
|
* final Condition notEmpty = <b>lock.newCondition(); </b>
|
||||||
|
@ -81,7 +81,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
* final Object[] items = new Object[100];
|
* final Object[] items = new Object[100];
|
||||||
* int putptr, takeptr, count;
|
* int putptr, takeptr, count;
|
||||||
*
|
*
|
||||||
* public void put(Object x) throws InterruptedException {
|
* public void put(E x) throws InterruptedException {
|
||||||
* <b>lock.lock();
|
* <b>lock.lock();
|
||||||
* try {</b>
|
* try {</b>
|
||||||
* while (count == items.length)
|
* while (count == items.length)
|
||||||
|
@ -95,12 +95,12 @@ import java.util.concurrent.TimeUnit;
|
||||||
* }</b>
|
* }</b>
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* public Object take() throws InterruptedException {
|
* public E take() throws InterruptedException {
|
||||||
* <b>lock.lock();
|
* <b>lock.lock();
|
||||||
* try {</b>
|
* try {</b>
|
||||||
* while (count == 0)
|
* while (count == 0)
|
||||||
* <b>notEmpty.await();</b>
|
* <b>notEmpty.await();</b>
|
||||||
* Object x = items[takeptr];
|
* E x = (E) items[takeptr];
|
||||||
* if (++takeptr == items.length) takeptr = 0;
|
* if (++takeptr == items.length) takeptr = 0;
|
||||||
* --count;
|
* --count;
|
||||||
* <b>notFull.signal();</b>
|
* <b>notFull.signal();</b>
|
||||||
|
@ -310,7 +310,8 @@ public interface Condition {
|
||||||
* the following form:
|
* the following form:
|
||||||
*
|
*
|
||||||
* <pre> {@code
|
* <pre> {@code
|
||||||
* boolean aMethod(long timeout, TimeUnit unit) {
|
* boolean aMethod(long timeout, TimeUnit unit)
|
||||||
|
* throws InterruptedException {
|
||||||
* long nanos = unit.toNanos(timeout);
|
* long nanos = unit.toNanos(timeout);
|
||||||
* lock.lock();
|
* lock.lock();
|
||||||
* try {
|
* try {
|
||||||
|
@ -320,6 +321,7 @@ public interface Condition {
|
||||||
* nanos = theCondition.awaitNanos(nanos);
|
* nanos = theCondition.awaitNanos(nanos);
|
||||||
* }
|
* }
|
||||||
* // ...
|
* // ...
|
||||||
|
* return true;
|
||||||
* } finally {
|
* } finally {
|
||||||
* lock.unlock();
|
* lock.unlock();
|
||||||
* }
|
* }
|
||||||
|
@ -410,7 +412,8 @@ public interface Condition {
|
||||||
* <p>The return value indicates whether the deadline has elapsed,
|
* <p>The return value indicates whether the deadline has elapsed,
|
||||||
* which can be used as follows:
|
* which can be used as follows:
|
||||||
* <pre> {@code
|
* <pre> {@code
|
||||||
* boolean aMethod(Date deadline) {
|
* boolean aMethod(Date deadline)
|
||||||
|
* throws InterruptedException {
|
||||||
* boolean stillWaiting = true;
|
* boolean stillWaiting = true;
|
||||||
* lock.lock();
|
* lock.lock();
|
||||||
* try {
|
* try {
|
||||||
|
@ -420,6 +423,7 @@ public interface Condition {
|
||||||
* stillWaiting = theCondition.awaitUntil(deadline);
|
* stillWaiting = theCondition.awaitUntil(deadline);
|
||||||
* }
|
* }
|
||||||
* // ...
|
* // ...
|
||||||
|
* return true;
|
||||||
* } finally {
|
* } finally {
|
||||||
* lock.unlock();
|
* lock.unlock();
|
||||||
* }
|
* }
|
||||||
|
|
|
@ -151,18 +151,20 @@ import jdk.internal.vm.annotation.ReservedStackAccess;
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* double distanceFromOrigin() { // A read-only method
|
* double distanceFromOrigin() { // A read-only method
|
||||||
|
* double currentX, currentY;
|
||||||
* long stamp = sl.tryOptimisticRead();
|
* long stamp = sl.tryOptimisticRead();
|
||||||
* double currentX = x, currentY = y;
|
* do {
|
||||||
* if (!sl.validate(stamp)) {
|
* if (stamp == 0L)
|
||||||
* stamp = sl.readLock();
|
* stamp = sl.readLock();
|
||||||
* try {
|
* try {
|
||||||
|
* // possibly racy reads
|
||||||
* currentX = x;
|
* currentX = x;
|
||||||
* currentY = y;
|
* currentY = y;
|
||||||
* } finally {
|
* } finally {
|
||||||
* sl.unlockRead(stamp);
|
* stamp = sl.tryConvertToOptimisticRead(stamp);
|
||||||
* }
|
* }
|
||||||
* }
|
* } while (stamp == 0);
|
||||||
* return Math.sqrt(currentX * currentX + currentY * currentY);
|
* return Math.hypot(currentX, currentY);
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* void moveIfAtOrigin(double newX, double newY) { // upgrade
|
* void moveIfAtOrigin(double newX, double newY) { // upgrade
|
||||||
|
|
|
@ -39,6 +39,18 @@ public interface JavaLangInvokeAccess {
|
||||||
*/
|
*/
|
||||||
String getName(Object mname);
|
String getName(Object mname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@code MethodType} for the given MemberName.
|
||||||
|
* Used by {@see StackFrameInfo}.
|
||||||
|
*/
|
||||||
|
MethodType getMethodType(Object mname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the descriptor for the given MemberName.
|
||||||
|
* Used by {@see StackFrameInfo}.
|
||||||
|
*/
|
||||||
|
String getMethodDescriptor(Object mname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if the given MemberName is a native method. Used by
|
* Returns {@code true} if the given MemberName is a native method. Used by
|
||||||
* {@see StackFrameInfo}.
|
* {@see StackFrameInfo}.
|
||||||
|
|
|
@ -1802,7 +1802,12 @@ public final class SSLSocketImpl extends BaseSSLSocketImpl {
|
||||||
try {
|
try {
|
||||||
readRecord(true);
|
readRecord(true);
|
||||||
} catch (SocketTimeoutException e) {
|
} catch (SocketTimeoutException e) {
|
||||||
// if time out, ignore the exception and continue
|
if ((debug != null) && Debug.isOn("ssl")) {
|
||||||
|
System.out.println(
|
||||||
|
Thread.currentThread().getName() +
|
||||||
|
", received Exception: " + e);
|
||||||
|
}
|
||||||
|
fatal((byte)(-1), "Did not receive close_notify from peer", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2011, 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -28,6 +28,7 @@ package sun.security.util;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used to compute digests on sections of the Manifest.
|
* This class is used to compute digests on sections of the Manifest.
|
||||||
|
@ -112,8 +113,6 @@ public class ManifestDigester {
|
||||||
rawBytes = bytes;
|
rawBytes = bytes;
|
||||||
entries = new HashMap<>();
|
entries = new HashMap<>();
|
||||||
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
Position pos = new Position();
|
Position pos = new Position();
|
||||||
|
|
||||||
if (!findSection(0, pos))
|
if (!findSection(0, pos))
|
||||||
|
@ -131,50 +130,41 @@ public class ManifestDigester {
|
||||||
|
|
||||||
if (len > 6) {
|
if (len > 6) {
|
||||||
if (isNameAttr(bytes, start)) {
|
if (isNameAttr(bytes, start)) {
|
||||||
StringBuilder nameBuf = new StringBuilder(sectionLen);
|
ByteArrayOutputStream nameBuf = new ByteArrayOutputStream();
|
||||||
|
nameBuf.write(bytes, start+6, len-6);
|
||||||
|
|
||||||
try {
|
int i = start + len;
|
||||||
nameBuf.append(
|
if ((i-start) < sectionLen) {
|
||||||
new String(bytes, start+6, len-6, "UTF8"));
|
if (bytes[i] == '\r') {
|
||||||
|
i += 2;
|
||||||
int i = start + len;
|
} else {
|
||||||
if ((i-start) < sectionLen) {
|
i += 1;
|
||||||
if (bytes[i] == '\r') {
|
|
||||||
i += 2;
|
|
||||||
} else {
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((i-start) < sectionLen) {
|
|
||||||
if (bytes[i++] == ' ') {
|
|
||||||
// name is wrapped
|
|
||||||
int wrapStart = i;
|
|
||||||
while (((i-start) < sectionLen)
|
|
||||||
&& (bytes[i++] != '\n'));
|
|
||||||
if (bytes[i-1] != '\n')
|
|
||||||
return; // XXX: exception?
|
|
||||||
int wrapLen;
|
|
||||||
if (bytes[i-2] == '\r')
|
|
||||||
wrapLen = i-wrapStart-2;
|
|
||||||
else
|
|
||||||
wrapLen = i-wrapStart-1;
|
|
||||||
|
|
||||||
nameBuf.append(new String(bytes, wrapStart,
|
|
||||||
wrapLen, "UTF8"));
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
entries.put(nameBuf.toString(),
|
|
||||||
new Entry(start, sectionLen, sectionLenWithBlank,
|
|
||||||
rawBytes));
|
|
||||||
|
|
||||||
} catch (java.io.UnsupportedEncodingException uee) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"UTF8 not available on platform");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while ((i-start) < sectionLen) {
|
||||||
|
if (bytes[i++] == ' ') {
|
||||||
|
// name is wrapped
|
||||||
|
int wrapStart = i;
|
||||||
|
while (((i-start) < sectionLen)
|
||||||
|
&& (bytes[i++] != '\n'));
|
||||||
|
if (bytes[i-1] != '\n')
|
||||||
|
return; // XXX: exception?
|
||||||
|
int wrapLen;
|
||||||
|
if (bytes[i-2] == '\r')
|
||||||
|
wrapLen = i-wrapStart-2;
|
||||||
|
else
|
||||||
|
wrapLen = i-wrapStart-1;
|
||||||
|
|
||||||
|
nameBuf.write(bytes, wrapStart, wrapLen);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entries.put(new String(nameBuf.toByteArray(), UTF_8),
|
||||||
|
new Entry(start, sectionLen, sectionLenWithBlank,
|
||||||
|
rawBytes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
start = pos.startOfNext;
|
start = pos.startOfNext;
|
||||||
|
|
|
@ -142,6 +142,10 @@ grant codeBase "jrt:/jdk.dynalink" {
|
||||||
permission java.security.AllPermission;
|
permission java.security.AllPermission;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
grant codeBase "jrt:/jdk.httpserver" {
|
||||||
|
permission java.security.AllPermission;
|
||||||
|
};
|
||||||
|
|
||||||
grant codeBase "jrt:/jdk.internal.le" {
|
grant codeBase "jrt:/jdk.internal.le" {
|
||||||
permission java.security.AllPermission;
|
permission java.security.AllPermission;
|
||||||
};
|
};
|
||||||
|
|
|
@ -679,14 +679,16 @@ Java_java_net_PlainSocketImpl_socketAccept(JNIEnv *env, jobject this,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ECONNABORTED or EWOULDBLOCK error so adjust timeout if there is one. */
|
/* ECONNABORTED or EWOULDBLOCK error so adjust timeout if there is one. */
|
||||||
currNanoTime = JVM_NanoTime(env, 0);
|
if (nanoTimeout >= NET_NSEC_PER_MSEC) {
|
||||||
nanoTimeout -= (currNanoTime - prevNanoTime);
|
currNanoTime = JVM_NanoTime(env, 0);
|
||||||
if (nanoTimeout < NET_NSEC_PER_MSEC) {
|
nanoTimeout -= (currNanoTime - prevNanoTime);
|
||||||
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
|
if (nanoTimeout < NET_NSEC_PER_MSEC) {
|
||||||
"Accept timed out");
|
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
|
||||||
return;
|
"Accept timed out");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prevNanoTime = currNanoTime;
|
||||||
}
|
}
|
||||||
prevNanoTime = currNanoTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newfd < 0) {
|
if (newfd < 0) {
|
||||||
|
|
|
@ -550,10 +550,10 @@ void
|
||||||
fileDescriptorClose(JNIEnv *env, jobject this)
|
fileDescriptorClose(JNIEnv *env, jobject this)
|
||||||
{
|
{
|
||||||
FD fd = (*env)->GetLongField(env, this, IO_handle_fdID);
|
FD fd = (*env)->GetLongField(env, this, IO_handle_fdID);
|
||||||
|
HANDLE h = (HANDLE)fd;
|
||||||
if ((*env)->ExceptionOccurred(env)) {
|
if ((*env)->ExceptionOccurred(env)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HANDLE h = (HANDLE)fd;
|
|
||||||
|
|
||||||
if (h == INVALID_HANDLE_VALUE) {
|
if (h == INVALID_HANDLE_VALUE) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -216,8 +216,9 @@ public enum SourceVersion {
|
||||||
* Character#isJavaIdentifierStart(int)} returns {@code true},
|
* Character#isJavaIdentifierStart(int)} returns {@code true},
|
||||||
* followed only by characters for which {@link
|
* followed only by characters for which {@link
|
||||||
* Character#isJavaIdentifierPart(int)} returns {@code true}.
|
* Character#isJavaIdentifierPart(int)} returns {@code true}.
|
||||||
* This pattern matches regular identifiers, keywords, and the
|
* This pattern matches regular identifiers, keywords, restricted
|
||||||
* literals {@code "true"}, {@code "false"}, and {@code "null"}.
|
* keywords, and the literals {@code "true"}, {@code "false"}, and
|
||||||
|
* {@code "null"}.
|
||||||
* The method returns {@code false} for all other strings.
|
* The method returns {@code false} for all other strings.
|
||||||
*
|
*
|
||||||
* @param name the string to check
|
* @param name the string to check
|
||||||
|
@ -251,10 +252,13 @@ public enum SourceVersion {
|
||||||
* qualified name in the latest source version. Unlike {@link
|
* qualified name in the latest source version. Unlike {@link
|
||||||
* #isIdentifier isIdentifier}, this method returns {@code false}
|
* #isIdentifier isIdentifier}, this method returns {@code false}
|
||||||
* for keywords, boolean literals, and the null literal.
|
* for keywords, boolean literals, and the null literal.
|
||||||
|
* This method returns {@code true} for <i>restricted
|
||||||
|
* keywords</i>.
|
||||||
*
|
*
|
||||||
* @param name the string to check
|
* @param name the string to check
|
||||||
* @return {@code true} if this string is a
|
* @return {@code true} if this string is a
|
||||||
* syntactically valid name, {@code false} otherwise.
|
* syntactically valid name, {@code false} otherwise.
|
||||||
|
* @jls 3.9 Keywords
|
||||||
* @jls 6.2 Names and Identifiers
|
* @jls 6.2 Names and Identifiers
|
||||||
*/
|
*/
|
||||||
public static boolean isName(CharSequence name) {
|
public static boolean isName(CharSequence name) {
|
||||||
|
@ -266,11 +270,14 @@ public enum SourceVersion {
|
||||||
* qualified name in the given source version. Unlike {@link
|
* qualified name in the given source version. Unlike {@link
|
||||||
* #isIdentifier isIdentifier}, this method returns {@code false}
|
* #isIdentifier isIdentifier}, this method returns {@code false}
|
||||||
* for keywords, boolean literals, and the null literal.
|
* for keywords, boolean literals, and the null literal.
|
||||||
|
* This method returns {@code true} for <i>restricted
|
||||||
|
* keywords</i>.
|
||||||
*
|
*
|
||||||
* @param name the string to check
|
* @param name the string to check
|
||||||
* @param version the version to use
|
* @param version the version to use
|
||||||
* @return {@code true} if this string is a
|
* @return {@code true} if this string is a
|
||||||
* syntactically valid name, {@code false} otherwise.
|
* syntactically valid name, {@code false} otherwise.
|
||||||
|
* @jls 3.9 Keywords
|
||||||
* @jls 6.2 Names and Identifiers
|
* @jls 6.2 Names and Identifiers
|
||||||
* @since 9
|
* @since 9
|
||||||
*/
|
*/
|
||||||
|
@ -287,6 +294,8 @@ public enum SourceVersion {
|
||||||
/**
|
/**
|
||||||
* Returns whether or not {@code s} is a keyword, boolean literal,
|
* Returns whether or not {@code s} is a keyword, boolean literal,
|
||||||
* or null literal in the latest source version.
|
* or null literal in the latest source version.
|
||||||
|
* This method returns {@code false} for <i>restricted
|
||||||
|
* keywords</i>.
|
||||||
*
|
*
|
||||||
* @param s the string to check
|
* @param s the string to check
|
||||||
* @return {@code true} if {@code s} is a keyword, or boolean
|
* @return {@code true} if {@code s} is a keyword, or boolean
|
||||||
|
@ -302,6 +311,8 @@ public enum SourceVersion {
|
||||||
/**
|
/**
|
||||||
* Returns whether or not {@code s} is a keyword, boolean literal,
|
* Returns whether or not {@code s} is a keyword, boolean literal,
|
||||||
* or null literal in the given source version.
|
* or null literal in the given source version.
|
||||||
|
* This method returns {@code false} for <i>restricted
|
||||||
|
* keywords</i>.
|
||||||
*
|
*
|
||||||
* @param s the string to check
|
* @param s the string to check
|
||||||
* @param version the version to use
|
* @param version the version to use
|
||||||
|
|
|
@ -87,7 +87,7 @@ public interface ModuleElement extends Element, QualifiedNameable {
|
||||||
*
|
*
|
||||||
* @return {@code true} if this is an open module and {@code
|
* @return {@code true} if this is an open module and {@code
|
||||||
* false} otherwise
|
* false} otherwise
|
||||||
*/ // TODO: add @jls to unnamed module section
|
*/
|
||||||
boolean isOpen();
|
boolean isOpen();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,7 +96,9 @@ public interface ModuleElement extends Element, QualifiedNameable {
|
||||||
*
|
*
|
||||||
* @return {@code true} if this is an unnamed module and {@code
|
* @return {@code true} if this is an unnamed module and {@code
|
||||||
* false} otherwise
|
* false} otherwise
|
||||||
*/ // TODO: add @jls to unnamed module section
|
*
|
||||||
|
* @jls 7.7.5 Unnamed Modules
|
||||||
|
*/
|
||||||
boolean isUnnamed();
|
boolean isUnnamed();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -71,6 +71,7 @@ public class Kinds {
|
||||||
HIDDEN(Category.RESOLUTION_TARGET), // not overloaded non-target
|
HIDDEN(Category.RESOLUTION_TARGET), // not overloaded non-target
|
||||||
STATICERR(Category.RESOLUTION_TARGET), // overloaded? target
|
STATICERR(Category.RESOLUTION_TARGET), // overloaded? target
|
||||||
MISSING_ENCL(Category.RESOLUTION), // not overloaded non-target
|
MISSING_ENCL(Category.RESOLUTION), // not overloaded non-target
|
||||||
|
BAD_VAR(Category.RESOLUTION), // not overloaded non-target
|
||||||
ABSENT_VAR(Category.RESOLUTION_TARGET, KindName.VAR), // not overloaded non-target
|
ABSENT_VAR(Category.RESOLUTION_TARGET, KindName.VAR), // not overloaded non-target
|
||||||
WRONG_MTHS(Category.RESOLUTION_TARGET, KindName.METHOD), // overloaded target
|
WRONG_MTHS(Category.RESOLUTION_TARGET, KindName.METHOD), // overloaded target
|
||||||
WRONG_MTH(Category.RESOLUTION_TARGET, KindName.METHOD), // not overloaded target
|
WRONG_MTH(Category.RESOLUTION_TARGET, KindName.METHOD), // not overloaded target
|
||||||
|
|
|
@ -227,6 +227,7 @@ public enum Source {
|
||||||
return compareTo(JDK1_8) <= 0;
|
return compareTo(JDK1_8) <= 0;
|
||||||
}
|
}
|
||||||
public boolean allowPrivateInterfaceMethods() { return compareTo(JDK1_9) >= 0; }
|
public boolean allowPrivateInterfaceMethods() { return compareTo(JDK1_9) >= 0; }
|
||||||
|
public boolean allowLocalVariableTypeInference() { return compareTo(JDK1_10) >= 0; }
|
||||||
public static SourceVersion toSourceVersion(Source source) {
|
public static SourceVersion toSourceVersion(Source source) {
|
||||||
switch(source) {
|
switch(source) {
|
||||||
case JDK1_2:
|
case JDK1_2:
|
||||||
|
|
|
@ -1616,6 +1616,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
|
||||||
|
|
||||||
public TypeVar(Name name, Symbol owner, Type lower) {
|
public TypeVar(Name name, Symbol owner, Type lower) {
|
||||||
super(null, TypeMetadata.EMPTY);
|
super(null, TypeMetadata.EMPTY);
|
||||||
|
Assert.checkNonNull(lower);
|
||||||
tsym = new TypeVariableSymbol(0, name, this, owner);
|
tsym = new TypeVariableSymbol(0, name, this, owner);
|
||||||
this.bound = null;
|
this.bound = null;
|
||||||
this.lower = lower;
|
this.lower = lower;
|
||||||
|
@ -1628,6 +1629,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
|
||||||
public TypeVar(TypeSymbol tsym, Type bound, Type lower,
|
public TypeVar(TypeSymbol tsym, Type bound, Type lower,
|
||||||
TypeMetadata metadata) {
|
TypeMetadata metadata) {
|
||||||
super(tsym, metadata);
|
super(tsym, metadata);
|
||||||
|
Assert.checkNonNull(lower);
|
||||||
this.bound = bound;
|
this.bound = bound;
|
||||||
this.lower = lower;
|
this.lower = lower;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1247,7 +1247,9 @@ public class TypeAnnotations {
|
||||||
final TypeAnnotationPosition pos =
|
final TypeAnnotationPosition pos =
|
||||||
TypeAnnotationPosition.localVariable(currentLambda,
|
TypeAnnotationPosition.localVariable(currentLambda,
|
||||||
tree.pos);
|
tree.pos);
|
||||||
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
|
if (!tree.isImplicitlyTyped()) {
|
||||||
|
separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
|
||||||
|
}
|
||||||
} else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
|
} else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
|
||||||
final TypeAnnotationPosition pos =
|
final TypeAnnotationPosition pos =
|
||||||
TypeAnnotationPosition.exceptionParameter(currentLambda,
|
TypeAnnotationPosition.exceptionParameter(currentLambda,
|
||||||
|
|
|
@ -190,6 +190,245 @@ public class Types {
|
||||||
}
|
}
|
||||||
// </editor-fold>
|
// </editor-fold>
|
||||||
|
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="projections">
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A projection kind. See {@link TypeProjection}
|
||||||
|
*/
|
||||||
|
enum ProjectionKind {
|
||||||
|
UPWARDS() {
|
||||||
|
@Override
|
||||||
|
ProjectionKind complement() {
|
||||||
|
return DOWNWARDS;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
DOWNWARDS() {
|
||||||
|
@Override
|
||||||
|
ProjectionKind complement() {
|
||||||
|
return UPWARDS;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
abstract ProjectionKind complement();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This visitor performs upwards and downwards projections on types.
|
||||||
|
*
|
||||||
|
* A projection is defined as a function that takes a type T, a set of type variables V and that
|
||||||
|
* produces another type S.
|
||||||
|
*
|
||||||
|
* An upwards projection maps a type T into a type S such that (i) T has no variables in V,
|
||||||
|
* and (ii) S is an upper bound of T.
|
||||||
|
*
|
||||||
|
* A downwards projection maps a type T into a type S such that (i) T has no variables in V,
|
||||||
|
* and (ii) S is a lower bound of T.
|
||||||
|
*
|
||||||
|
* Note that projections are only allowed to touch variables in V. Theferore it is possible for
|
||||||
|
* a projection to leave its input type unchanged if it does not contain any variables in V.
|
||||||
|
*
|
||||||
|
* Moreover, note that while an upwards projection is always defined (every type as an upper bound),
|
||||||
|
* a downwards projection is not always defined.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* {@code upwards(List<#CAP1>, [#CAP1]) = List<? extends String>, where #CAP1 <: String }
|
||||||
|
* {@code downwards(List<#CAP2>, [#CAP2]) = List<? super String>, where #CAP2 :> String }
|
||||||
|
* {@code upwards(List<#CAP1>, [#CAP2]) = List<#CAP1> }
|
||||||
|
* {@code downwards(List<#CAP1>, [#CAP1]) = not defined }
|
||||||
|
*/
|
||||||
|
class TypeProjection extends StructuralTypeMapping<ProjectionKind> {
|
||||||
|
|
||||||
|
List<Type> vars;
|
||||||
|
Set<Type> seen = new HashSet<>();
|
||||||
|
|
||||||
|
public TypeProjection(List<Type> vars) {
|
||||||
|
this.vars = vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type visitClassType(ClassType t, ProjectionKind pkind) {
|
||||||
|
if (t.isCompound()) {
|
||||||
|
List<Type> components = directSupertypes(t);
|
||||||
|
List<Type> components1 = components.map(c -> c.map(this, pkind));
|
||||||
|
if (components == components1) return t;
|
||||||
|
else return makeIntersectionType(components1);
|
||||||
|
} else {
|
||||||
|
Type outer = t.getEnclosingType();
|
||||||
|
Type outer1 = visit(outer, pkind);
|
||||||
|
List<Type> typarams = t.getTypeArguments();
|
||||||
|
List<Type> typarams1 = typarams.map(ta -> mapTypeArgument(ta, pkind));
|
||||||
|
if (typarams1.stream().anyMatch(ta -> ta.hasTag(BOT))) {
|
||||||
|
//not defined
|
||||||
|
return syms.botType;
|
||||||
|
}
|
||||||
|
if (outer1 == outer && typarams1 == typarams) return t;
|
||||||
|
else return new ClassType(outer1, typarams1, t.tsym, t.getMetadata()) {
|
||||||
|
@Override
|
||||||
|
protected boolean needsStripping() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Type makeWildcard(Type upper, Type lower) {
|
||||||
|
BoundKind bk;
|
||||||
|
Type bound;
|
||||||
|
if (upper.hasTag(BOT)) {
|
||||||
|
upper = syms.objectType;
|
||||||
|
}
|
||||||
|
boolean isUpperObject = isSameType(upper, syms.objectType);
|
||||||
|
if (!lower.hasTag(BOT) && isUpperObject) {
|
||||||
|
bound = lower;
|
||||||
|
bk = SUPER;
|
||||||
|
} else {
|
||||||
|
bound = upper;
|
||||||
|
bk = isUpperObject ? UNBOUND : EXTENDS;
|
||||||
|
}
|
||||||
|
return new WildcardType(bound, bk, syms.boundClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type visitTypeVar(TypeVar t, ProjectionKind pkind) {
|
||||||
|
if (vars.contains(t)) {
|
||||||
|
try {
|
||||||
|
if (seen.add(t)) {
|
||||||
|
final Type bound;
|
||||||
|
switch (pkind) {
|
||||||
|
case UPWARDS:
|
||||||
|
bound = t.getUpperBound();
|
||||||
|
break;
|
||||||
|
case DOWNWARDS:
|
||||||
|
bound = (t.getLowerBound() == null) ?
|
||||||
|
syms.botType :
|
||||||
|
t.getLowerBound();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Assert.error();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return bound.map(this, pkind);
|
||||||
|
} else {
|
||||||
|
//cycle
|
||||||
|
return syms.objectType;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
seen.remove(t);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type visitWildcardType(WildcardType wt, ProjectionKind pkind) {
|
||||||
|
switch (pkind) {
|
||||||
|
case UPWARDS:
|
||||||
|
return wt.isExtendsBound() ?
|
||||||
|
wt.type.map(this, pkind) :
|
||||||
|
syms.objectType;
|
||||||
|
case DOWNWARDS:
|
||||||
|
return wt.isSuperBound() ?
|
||||||
|
wt.type.map(this, pkind) :
|
||||||
|
syms.botType;
|
||||||
|
default:
|
||||||
|
Assert.error();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Type mapTypeArgument(Type t, ProjectionKind pkind) {
|
||||||
|
if (!t.containsAny(vars)) {
|
||||||
|
return t;
|
||||||
|
} else if (!t.hasTag(WILDCARD) && pkind == ProjectionKind.DOWNWARDS) {
|
||||||
|
//not defined
|
||||||
|
return syms.botType;
|
||||||
|
} else {
|
||||||
|
Type upper = t.map(this, pkind);
|
||||||
|
Type lower = t.map(this, pkind.complement());
|
||||||
|
return makeWildcard(upper, lower);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes an upward projection of given type, and vars. See {@link TypeProjection}.
|
||||||
|
*
|
||||||
|
* @param t the type to be projected
|
||||||
|
* @param vars the set of type variables to be mapped
|
||||||
|
* @return the type obtained as result of the projection
|
||||||
|
*/
|
||||||
|
public Type upward(Type t, List<Type> vars) {
|
||||||
|
return t.map(new TypeProjection(vars), ProjectionKind.UPWARDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the set of captured variables mentioned in a given type. See {@link CaptureScanner}.
|
||||||
|
* This routine is typically used to computed the input set of variables to be used during
|
||||||
|
* an upwards projection (see {@link Types#upward(Type, List)}).
|
||||||
|
*
|
||||||
|
* @param t the type where occurrences of captured variables have to be found
|
||||||
|
* @return the set of captured variables found in t
|
||||||
|
*/
|
||||||
|
public List<Type> captures(Type t) {
|
||||||
|
CaptureScanner cs = new CaptureScanner();
|
||||||
|
Set<Type> captures = new HashSet<>();
|
||||||
|
cs.visit(t, captures);
|
||||||
|
return List.from(captures);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This visitor scans a type recursively looking for occurrences of captured type variables.
|
||||||
|
*/
|
||||||
|
class CaptureScanner extends SimpleVisitor<Void, Set<Type>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitType(Type t, Set<Type> types) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitClassType(ClassType t, Set<Type> seen) {
|
||||||
|
if (t.isCompound()) {
|
||||||
|
directSupertypes(t).forEach(s -> visit(s, seen));
|
||||||
|
} else {
|
||||||
|
t.allparams().forEach(ta -> visit(ta, seen));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitArrayType(ArrayType t, Set<Type> seen) {
|
||||||
|
return visit(t.elemtype, seen);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitWildcardType(WildcardType t, Set<Type> seen) {
|
||||||
|
visit(t.type, seen);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitTypeVar(TypeVar t, Set<Type> seen) {
|
||||||
|
if ((t.tsym.flags() & Flags.SYNTHETIC) != 0 && seen.add(t)) {
|
||||||
|
visit(t.getUpperBound(), seen);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visitCapturedType(CapturedType t, Set<Type> seen) {
|
||||||
|
if (seen.add(t)) {
|
||||||
|
visit(t.getUpperBound(), seen);
|
||||||
|
visit(t.getLowerBound(), seen);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
// <editor-fold defaultstate="collapsed" desc="isUnbounded">
|
// <editor-fold defaultstate="collapsed" desc="isUnbounded">
|
||||||
/**
|
/**
|
||||||
* Checks that all the arguments to a class are unbounded
|
* Checks that all the arguments to a class are unbounded
|
||||||
|
|
|
@ -83,6 +83,7 @@ import com.sun.tools.javac.util.DiagnosticSource;
|
||||||
import static com.sun.tools.javac.code.Flags.GENERATEDCONSTR;
|
import static com.sun.tools.javac.code.Flags.GENERATEDCONSTR;
|
||||||
import static com.sun.tools.javac.code.TypeTag.CLASS;
|
import static com.sun.tools.javac.code.TypeTag.CLASS;
|
||||||
import static com.sun.tools.javac.tree.JCTree.Tag.APPLY;
|
import static com.sun.tools.javac.tree.JCTree.Tag.APPLY;
|
||||||
|
import static com.sun.tools.javac.tree.JCTree.Tag.FOREACHLOOP;
|
||||||
import static com.sun.tools.javac.tree.JCTree.Tag.LABELLED;
|
import static com.sun.tools.javac.tree.JCTree.Tag.LABELLED;
|
||||||
import static com.sun.tools.javac.tree.JCTree.Tag.METHODDEF;
|
import static com.sun.tools.javac.tree.JCTree.Tag.METHODDEF;
|
||||||
import static com.sun.tools.javac.tree.JCTree.Tag.NEWCLASS;
|
import static com.sun.tools.javac.tree.JCTree.Tag.NEWCLASS;
|
||||||
|
@ -139,7 +140,8 @@ public class Analyzer {
|
||||||
enum AnalyzerMode {
|
enum AnalyzerMode {
|
||||||
DIAMOND("diamond", Source::allowDiamond),
|
DIAMOND("diamond", Source::allowDiamond),
|
||||||
LAMBDA("lambda", Source::allowLambda),
|
LAMBDA("lambda", Source::allowLambda),
|
||||||
METHOD("method", Source::allowGraphInference);
|
METHOD("method", Source::allowGraphInference),
|
||||||
|
LOCAL("local", Source::allowLocalVariableTypeInference);
|
||||||
|
|
||||||
final String opt;
|
final String opt;
|
||||||
final Predicate<Source> sourceFilter;
|
final Predicate<Source> sourceFilter;
|
||||||
|
@ -341,11 +343,91 @@ public class Analyzer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for local variable inference analyzers.
|
||||||
|
*/
|
||||||
|
abstract class RedundantLocalVarTypeAnalyzerBase<X extends JCStatement> extends StatementAnalyzer<X, X> {
|
||||||
|
|
||||||
|
RedundantLocalVarTypeAnalyzerBase(JCTree.Tag tag) {
|
||||||
|
super(AnalyzerMode.LOCAL, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map a variable tree into a new declaration using implicit type.
|
||||||
|
*/
|
||||||
|
JCVariableDecl mapVar(JCVariableDecl oldTree, JCVariableDecl newTree){
|
||||||
|
newTree.vartype = null;
|
||||||
|
return newTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Analyze results of local variable inference.
|
||||||
|
*/
|
||||||
|
void processVar(JCVariableDecl oldTree, JCVariableDecl newTree, boolean hasErrors){
|
||||||
|
if (!hasErrors) {
|
||||||
|
if (types.isSameType(oldTree.type, newTree.type)) {
|
||||||
|
log.warning(oldTree, Warnings.LocalRedundantType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This analyzer checks if a local variable declaration has redundant type.
|
||||||
|
*/
|
||||||
|
class RedundantLocalVarTypeAnalyzer extends RedundantLocalVarTypeAnalyzerBase<JCVariableDecl> {
|
||||||
|
|
||||||
|
RedundantLocalVarTypeAnalyzer() {
|
||||||
|
super(VARDEF);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean match(JCVariableDecl tree){
|
||||||
|
return tree.sym.owner.kind == Kind.MTH &&
|
||||||
|
tree.init != null && !tree.isImplicitlyTyped() &&
|
||||||
|
attr.canInferLocalVarType(tree) == null;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
JCVariableDecl map(JCVariableDecl oldTree, JCVariableDecl newTree){
|
||||||
|
return mapVar(oldTree, newTree);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
void process(JCVariableDecl oldTree, JCVariableDecl newTree, boolean hasErrors){
|
||||||
|
processVar(oldTree, newTree, hasErrors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This analyzer checks if a for each variable declaration has redundant type.
|
||||||
|
*/
|
||||||
|
class RedundantLocalVarTypeAnalyzerForEach extends RedundantLocalVarTypeAnalyzerBase<JCEnhancedForLoop> {
|
||||||
|
|
||||||
|
RedundantLocalVarTypeAnalyzerForEach() {
|
||||||
|
super(FOREACHLOOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean match(JCEnhancedForLoop tree){
|
||||||
|
return !tree.var.isImplicitlyTyped();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
JCEnhancedForLoop map(JCEnhancedForLoop oldTree, JCEnhancedForLoop newTree){
|
||||||
|
newTree.var = mapVar(oldTree.var, newTree.var);
|
||||||
|
newTree.body = make.Block(0, List.nil()); //ignore body for analysis purpose
|
||||||
|
return newTree;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
void process(JCEnhancedForLoop oldTree, JCEnhancedForLoop newTree, boolean hasErrors){
|
||||||
|
processVar(oldTree.var, newTree.var, hasErrors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
StatementAnalyzer<JCTree, JCTree>[] analyzers = new StatementAnalyzer[] {
|
StatementAnalyzer<JCTree, JCTree>[] analyzers = new StatementAnalyzer[] {
|
||||||
new DiamondInitializer(),
|
new DiamondInitializer(),
|
||||||
new LambdaAnalyzer(),
|
new LambdaAnalyzer(),
|
||||||
new RedundantTypeArgAnalyzer()
|
new RedundantTypeArgAnalyzer(),
|
||||||
|
new RedundantLocalVarTypeAnalyzer(),
|
||||||
|
new RedundantLocalVarTypeAnalyzerForEach()
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,9 +28,11 @@ package com.sun.tools.javac.comp;
|
||||||
import com.sun.tools.javac.code.*;
|
import com.sun.tools.javac.code.*;
|
||||||
import com.sun.tools.javac.code.Attribute.Compound;
|
import com.sun.tools.javac.code.Attribute.Compound;
|
||||||
import com.sun.tools.javac.code.Attribute.TypeCompound;
|
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.Scope.WriteableScope;
|
||||||
import com.sun.tools.javac.code.Symbol.*;
|
import com.sun.tools.javac.code.Symbol.*;
|
||||||
import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
|
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.Errors;
|
||||||
import com.sun.tools.javac.tree.JCTree;
|
import com.sun.tools.javac.tree.JCTree;
|
||||||
import com.sun.tools.javac.tree.JCTree.*;
|
import com.sun.tools.javac.tree.JCTree.*;
|
||||||
|
@ -602,7 +604,7 @@ public class Annotate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Attribute getAnnotationEnumValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
|
private Attribute getAnnotationEnumValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
|
||||||
Type result = attr.attribExpr(tree, env, expectedElementType);
|
Type result = attr.attribTree(tree, env, annotationValueInfo(expectedElementType));
|
||||||
Symbol sym = TreeInfo.symbol(tree);
|
Symbol sym = TreeInfo.symbol(tree);
|
||||||
if (sym == null ||
|
if (sym == null ||
|
||||||
TreeInfo.nonstaticSelect(tree) ||
|
TreeInfo.nonstaticSelect(tree) ||
|
||||||
|
@ -616,7 +618,7 @@ public class Annotate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Attribute getAnnotationClassValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
|
private Attribute getAnnotationClassValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
|
||||||
Type result = attr.attribExpr(tree, env, expectedElementType);
|
Type result = attr.attribTree(tree, env, annotationValueInfo(expectedElementType));
|
||||||
if (result.isErroneous()) {
|
if (result.isErroneous()) {
|
||||||
// Does it look like an unresolved class literal?
|
// Does it look like an unresolved class literal?
|
||||||
if (TreeInfo.name(tree) == names._class &&
|
if (TreeInfo.name(tree) == names._class &&
|
||||||
|
@ -642,7 +644,7 @@ public class Annotate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Attribute getAnnotationPrimitiveValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
|
private Attribute getAnnotationPrimitiveValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
|
||||||
Type result = attr.attribExpr(tree, env, expectedElementType);
|
Type result = attr.attribTree(tree, env, annotationValueInfo(expectedElementType));
|
||||||
if (result.isErroneous())
|
if (result.isErroneous())
|
||||||
return new Attribute.Error(result.getOriginalType());
|
return new Attribute.Error(result.getOriginalType());
|
||||||
if (result.constValue() == null) {
|
if (result.constValue() == null) {
|
||||||
|
@ -653,6 +655,22 @@ public class Annotate {
|
||||||
return new Attribute.Constant(expectedElementType, result.constValue());
|
return new Attribute.Constant(expectedElementType, result.constValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Attr.ResultInfo annotationValueInfo(Type pt) {
|
||||||
|
return attr.unknownExprInfo.dup(pt, new AnnotationValueContext(attr.unknownExprInfo.checkContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
class AnnotationValueContext extends Check.NestedCheckContext {
|
||||||
|
AnnotationValueContext(CheckContext enclosingContext) {
|
||||||
|
super(enclosingContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean compatible(Type found, Type req, Warner warn) {
|
||||||
|
//handle non-final implicitly-typed vars (will be rejected later on)
|
||||||
|
return found.hasTag(TypeTag.NONE) || super.compatible(found, req, warn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Attribute getAnnotationArrayValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
|
private Attribute getAnnotationArrayValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
|
||||||
// Special case, implicit array
|
// Special case, implicit array
|
||||||
if (!tree.hasTag(NEWARRAY)) {
|
if (!tree.hasTag(NEWARRAY)) {
|
||||||
|
|
|
@ -36,7 +36,6 @@ import com.sun.source.tree.MemberSelectTree;
|
||||||
import com.sun.source.tree.TreeVisitor;
|
import com.sun.source.tree.TreeVisitor;
|
||||||
import com.sun.source.util.SimpleTreeVisitor;
|
import com.sun.source.util.SimpleTreeVisitor;
|
||||||
import com.sun.tools.javac.code.*;
|
import com.sun.tools.javac.code.*;
|
||||||
import com.sun.tools.javac.code.Directive.RequiresFlag;
|
|
||||||
import com.sun.tools.javac.code.Lint.LintCategory;
|
import com.sun.tools.javac.code.Lint.LintCategory;
|
||||||
import com.sun.tools.javac.code.Scope.WriteableScope;
|
import com.sun.tools.javac.code.Scope.WriteableScope;
|
||||||
import com.sun.tools.javac.code.Symbol.*;
|
import com.sun.tools.javac.code.Symbol.*;
|
||||||
|
@ -46,7 +45,6 @@ import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError;
|
||||||
import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
|
import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
|
||||||
import com.sun.tools.javac.comp.Check.CheckContext;
|
import com.sun.tools.javac.comp.Check.CheckContext;
|
||||||
import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
|
import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
|
||||||
import com.sun.tools.javac.comp.Infer.FreeTypeListener;
|
|
||||||
import com.sun.tools.javac.jvm.*;
|
import com.sun.tools.javac.jvm.*;
|
||||||
import static com.sun.tools.javac.resources.CompilerProperties.Fragments.Diamond;
|
import static com.sun.tools.javac.resources.CompilerProperties.Fragments.Diamond;
|
||||||
import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArg;
|
import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArg;
|
||||||
|
@ -830,6 +828,10 @@ public class Attr extends JCTree.Visitor {
|
||||||
final JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
|
final JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
|
||||||
try {
|
try {
|
||||||
Type itype = attribExpr(variable.init, env, type);
|
Type itype = attribExpr(variable.init, env, type);
|
||||||
|
if (variable.isImplicitlyTyped()) {
|
||||||
|
//fixup local variable type
|
||||||
|
type = variable.type = variable.sym.type = chk.checkLocalVarType(variable, itype.baseType(), variable.name);
|
||||||
|
}
|
||||||
if (itype.constValue() != null) {
|
if (itype.constValue() != null) {
|
||||||
return coerce(itype, type).constValue();
|
return coerce(itype, type).constValue();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1108,6 +1110,21 @@ public class Attr extends JCTree.Visitor {
|
||||||
// parameters have already been entered
|
// parameters have already been entered
|
||||||
env.info.scope.enter(tree.sym);
|
env.info.scope.enter(tree.sym);
|
||||||
} else {
|
} else {
|
||||||
|
if (tree.isImplicitlyTyped() && (tree.getModifiers().flags & PARAMETER) == 0) {
|
||||||
|
if (tree.init == null) {
|
||||||
|
//cannot use 'var' without initializer
|
||||||
|
log.error(tree, Errors.CantInferLocalVarType(tree.name, Fragments.LocalMissingInit));
|
||||||
|
tree.vartype = make.Erroneous();
|
||||||
|
} else {
|
||||||
|
Fragment msg = canInferLocalVarType(tree);
|
||||||
|
if (msg != null) {
|
||||||
|
//cannot use 'var' with initializer which require an explicit target
|
||||||
|
//(e.g. lambda, method reference, array initializer).
|
||||||
|
log.error(tree, Errors.CantInferLocalVarType(tree.name, msg));
|
||||||
|
tree.vartype = make.Erroneous();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
annotate.blockAnnotations();
|
annotate.blockAnnotations();
|
||||||
memberEnter.memberEnter(tree, env);
|
memberEnter.memberEnter(tree, env);
|
||||||
|
@ -1131,7 +1148,7 @@ public class Attr extends JCTree.Visitor {
|
||||||
boolean isImplicitLambdaParameter = env.tree.hasTag(LAMBDA) &&
|
boolean isImplicitLambdaParameter = env.tree.hasTag(LAMBDA) &&
|
||||||
((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
|
((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
|
||||||
(tree.sym.flags() & PARAMETER) != 0;
|
(tree.sym.flags() & PARAMETER) != 0;
|
||||||
chk.validate(tree.vartype, env, !isImplicitLambdaParameter);
|
chk.validate(tree.vartype, env, !isImplicitLambdaParameter && !tree.isImplicitlyTyped());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
v.getConstValue(); // ensure compile-time constant initializer is evaluated
|
v.getConstValue(); // ensure compile-time constant initializer is evaluated
|
||||||
|
@ -1152,6 +1169,10 @@ public class Attr extends JCTree.Visitor {
|
||||||
// marking the variable as undefined.
|
// marking the variable as undefined.
|
||||||
initEnv.info.enclVar = v;
|
initEnv.info.enclVar = v;
|
||||||
attribExpr(tree.init, initEnv, v.type);
|
attribExpr(tree.init, initEnv, v.type);
|
||||||
|
if (tree.isImplicitlyTyped()) {
|
||||||
|
//fixup local variable type
|
||||||
|
v.type = chk.checkLocalVarType(tree, tree.init.type.baseType(), tree.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = tree.type = v.type;
|
result = tree.type = v.type;
|
||||||
|
@ -1161,6 +1182,71 @@ public class Attr extends JCTree.Visitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Fragment canInferLocalVarType(JCVariableDecl tree) {
|
||||||
|
LocalInitScanner lis = new LocalInitScanner();
|
||||||
|
lis.scan(tree.init);
|
||||||
|
return lis.badInferenceMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class LocalInitScanner extends TreeScanner {
|
||||||
|
Fragment badInferenceMsg = null;
|
||||||
|
boolean needsTarget = true;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitNewArray(JCNewArray tree) {
|
||||||
|
if (tree.elemtype == null && needsTarget) {
|
||||||
|
badInferenceMsg = Fragments.LocalArrayMissingTarget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitLambda(JCLambda tree) {
|
||||||
|
if (needsTarget) {
|
||||||
|
badInferenceMsg = Fragments.LocalLambdaMissingTarget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitTypeCast(JCTypeCast tree) {
|
||||||
|
boolean prevNeedsTarget = needsTarget;
|
||||||
|
try {
|
||||||
|
needsTarget = false;
|
||||||
|
super.visitTypeCast(tree);
|
||||||
|
} finally {
|
||||||
|
needsTarget = prevNeedsTarget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitReference(JCMemberReference tree) {
|
||||||
|
if (needsTarget) {
|
||||||
|
badInferenceMsg = Fragments.LocalMrefMissingTarget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitNewClass(JCNewClass tree) {
|
||||||
|
boolean prevNeedsTarget = needsTarget;
|
||||||
|
try {
|
||||||
|
needsTarget = false;
|
||||||
|
super.visitNewClass(tree);
|
||||||
|
} finally {
|
||||||
|
needsTarget = prevNeedsTarget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitApply(JCMethodInvocation tree) {
|
||||||
|
boolean prevNeedsTarget = needsTarget;
|
||||||
|
try {
|
||||||
|
needsTarget = false;
|
||||||
|
super.visitApply(tree);
|
||||||
|
} finally {
|
||||||
|
needsTarget = prevNeedsTarget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void visitSkip(JCSkip tree) {
|
public void visitSkip(JCSkip tree) {
|
||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
|
@ -1243,7 +1329,6 @@ public class Attr extends JCTree.Visitor {
|
||||||
//attributing the for-each expression; we mimick this by attributing
|
//attributing the for-each expression; we mimick this by attributing
|
||||||
//the for-each expression first (against original scope).
|
//the for-each expression first (against original scope).
|
||||||
Type exprType = types.cvarUpperBound(attribExpr(tree.expr, loopEnv));
|
Type exprType = types.cvarUpperBound(attribExpr(tree.expr, loopEnv));
|
||||||
attribStat(tree.var, loopEnv);
|
|
||||||
chk.checkNonVoid(tree.pos(), exprType);
|
chk.checkNonVoid(tree.pos(), exprType);
|
||||||
Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
|
Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
|
||||||
if (elemtype == null) {
|
if (elemtype == null) {
|
||||||
|
@ -1261,6 +1346,15 @@ public class Attr extends JCTree.Visitor {
|
||||||
: types.wildUpperBound(iterableParams.head);
|
: types.wildUpperBound(iterableParams.head);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (tree.var.isImplicitlyTyped()) {
|
||||||
|
Type inferredType = chk.checkLocalVarType(tree.var, elemtype, tree.var.name);
|
||||||
|
if (inferredType.isErroneous()) {
|
||||||
|
tree.var.vartype = make.at(tree.var.vartype).Erroneous();
|
||||||
|
} else {
|
||||||
|
tree.var.vartype = make.at(tree.var.vartype).Type(inferredType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attribStat(tree.var, loopEnv);
|
||||||
chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
|
chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
|
||||||
loopEnv.tree = tree; // before, we were not in loop!
|
loopEnv.tree = tree; // before, we were not in loop!
|
||||||
attribStat(tree.body, loopEnv);
|
attribStat(tree.body, loopEnv);
|
||||||
|
@ -2379,7 +2473,8 @@ public class Attr extends JCTree.Visitor {
|
||||||
if (pt().hasTag(ARRAY)) {
|
if (pt().hasTag(ARRAY)) {
|
||||||
elemtype = types.elemtype(pt());
|
elemtype = types.elemtype(pt());
|
||||||
} else {
|
} else {
|
||||||
if (!pt().hasTag(ERROR)) {
|
if (!pt().hasTag(ERROR) &&
|
||||||
|
(env.info.enclVar == null || !env.info.enclVar.type.isErroneous())) {
|
||||||
log.error(tree.pos(),
|
log.error(tree.pos(),
|
||||||
Errors.IllegalInitializerForType(pt()));
|
Errors.IllegalInitializerForType(pt()));
|
||||||
}
|
}
|
||||||
|
@ -2404,7 +2499,7 @@ public class Attr extends JCTree.Visitor {
|
||||||
@Override
|
@Override
|
||||||
public void visitLambda(final JCLambda that) {
|
public void visitLambda(final JCLambda that) {
|
||||||
if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
|
if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
|
||||||
if (pt().hasTag(NONE)) {
|
if (pt().hasTag(NONE) && (env.info.enclVar == null || !env.info.enclVar.type.isErroneous())) {
|
||||||
//lambda only allowed in assignment or method invocation/cast context
|
//lambda only allowed in assignment or method invocation/cast context
|
||||||
log.error(that.pos(), Errors.UnexpectedLambda);
|
log.error(that.pos(), Errors.UnexpectedLambda);
|
||||||
}
|
}
|
||||||
|
@ -2837,7 +2932,7 @@ public class Attr extends JCTree.Visitor {
|
||||||
@Override
|
@Override
|
||||||
public void visitReference(final JCMemberReference that) {
|
public void visitReference(final JCMemberReference that) {
|
||||||
if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
|
if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
|
||||||
if (pt().hasTag(NONE)) {
|
if (pt().hasTag(NONE) && (env.info.enclVar == null || !env.info.enclVar.type.isErroneous())) {
|
||||||
//method reference only allowed in assignment or method invocation/cast context
|
//method reference only allowed in assignment or method invocation/cast context
|
||||||
log.error(that.pos(), Errors.UnexpectedMref);
|
log.error(that.pos(), Errors.UnexpectedMref);
|
||||||
}
|
}
|
||||||
|
@ -3811,6 +3906,14 @@ public class Attr extends JCTree.Visitor {
|
||||||
break;
|
break;
|
||||||
case VAR:
|
case VAR:
|
||||||
VarSymbol v = (VarSymbol)sym;
|
VarSymbol v = (VarSymbol)sym;
|
||||||
|
|
||||||
|
if (env.info.enclVar != null
|
||||||
|
&& v.type.hasTag(NONE)) {
|
||||||
|
//self reference to implicitly typed variable declaration
|
||||||
|
log.error(TreeInfo.positionFor(v, env.enclClass), Errors.CantInferLocalVarType(v.name, Fragments.LocalSelfRef));
|
||||||
|
return v.type = types.createErrorType(v.type);
|
||||||
|
}
|
||||||
|
|
||||||
// Test (4): if symbol is an instance field of a raw type,
|
// Test (4): if symbol is an instance field of a raw type,
|
||||||
// which is being assigned to, issue an unchecked warning if
|
// which is being assigned to, issue an unchecked warning if
|
||||||
// its type changes under erasure.
|
// its type changes under erasure.
|
||||||
|
@ -4135,6 +4238,9 @@ public class Attr extends JCTree.Visitor {
|
||||||
public void visitTypeArray(JCArrayTypeTree tree) {
|
public void visitTypeArray(JCArrayTypeTree tree) {
|
||||||
Type etype = attribType(tree.elemtype, env);
|
Type etype = attribType(tree.elemtype, env);
|
||||||
Type type = new ArrayType(etype, syms.arrayClass);
|
Type type = new ArrayType(etype, syms.arrayClass);
|
||||||
|
if (etype.isErroneous()) {
|
||||||
|
type = types.createErrorType(type);
|
||||||
|
}
|
||||||
result = check(tree, type, KindSelector.TYP, resultInfo);
|
result = check(tree, type, KindSelector.TYP, resultInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4776,7 +4882,7 @@ public class Attr extends JCTree.Visitor {
|
||||||
}
|
}
|
||||||
public void visitVarDef(final JCVariableDecl tree) {
|
public void visitVarDef(final JCVariableDecl tree) {
|
||||||
//System.err.println("validateTypeAnnotations.visitVarDef " + tree);
|
//System.err.println("validateTypeAnnotations.visitVarDef " + tree);
|
||||||
if (tree.sym != null && tree.sym.type != null)
|
if (tree.sym != null && tree.sym.type != null && !tree.isImplicitlyTyped())
|
||||||
validateAnnotatedType(tree.vartype, tree.sym.type);
|
validateAnnotatedType(tree.vartype, tree.sym.type);
|
||||||
scan(tree.mods);
|
scan(tree.mods);
|
||||||
scan(tree.vartype);
|
scan(tree.vartype);
|
||||||
|
@ -4904,17 +5010,16 @@ public class Attr extends JCTree.Visitor {
|
||||||
repeat = false;
|
repeat = false;
|
||||||
} else if (enclTr.hasTag(JCTree.Tag.WILDCARD)) {
|
} else if (enclTr.hasTag(JCTree.Tag.WILDCARD)) {
|
||||||
JCWildcard wc = (JCWildcard) enclTr;
|
JCWildcard wc = (JCWildcard) enclTr;
|
||||||
if (wc.getKind() == JCTree.Kind.EXTENDS_WILDCARD) {
|
if (wc.getKind() == JCTree.Kind.EXTENDS_WILDCARD ||
|
||||||
validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy).getExtendsBound());
|
wc.getKind() == JCTree.Kind.SUPER_WILDCARD) {
|
||||||
} else if (wc.getKind() == JCTree.Kind.SUPER_WILDCARD) {
|
validateAnnotatedType(wc.getBound(), wc.getBound().type);
|
||||||
validateAnnotatedType(wc.getBound(), ((WildcardType)enclTy).getSuperBound());
|
|
||||||
} else {
|
} else {
|
||||||
// Nothing to do for UNBOUND
|
// Nothing to do for UNBOUND
|
||||||
}
|
}
|
||||||
repeat = false;
|
repeat = false;
|
||||||
} else if (enclTr.hasTag(TYPEARRAY)) {
|
} else if (enclTr.hasTag(TYPEARRAY)) {
|
||||||
JCArrayTypeTree art = (JCArrayTypeTree) enclTr;
|
JCArrayTypeTree art = (JCArrayTypeTree) enclTr;
|
||||||
validateAnnotatedType(art.getType(), ((ArrayType)enclTy).getComponentType());
|
validateAnnotatedType(art.getType(), art.elemtype.type);
|
||||||
repeat = false;
|
repeat = false;
|
||||||
} else if (enclTr.hasTag(TYPEUNION)) {
|
} else if (enclTr.hasTag(TYPEUNION)) {
|
||||||
JCTypeUnion ut = (JCTypeUnion) enclTr;
|
JCTypeUnion ut = (JCTypeUnion) enclTr;
|
||||||
|
|
|
@ -843,26 +843,30 @@ public class Check {
|
||||||
List<Type> checkDiamondDenotable(ClassType t) {
|
List<Type> checkDiamondDenotable(ClassType t) {
|
||||||
ListBuffer<Type> buf = new ListBuffer<>();
|
ListBuffer<Type> buf = new ListBuffer<>();
|
||||||
for (Type arg : t.allparams()) {
|
for (Type arg : t.allparams()) {
|
||||||
if (!diamondTypeChecker.visit(arg, null)) {
|
if (!checkDenotable(arg)) {
|
||||||
buf.append(arg);
|
buf.append(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return buf.toList();
|
return buf.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean checkDenotable(Type t) {
|
||||||
|
return denotableChecker.visit(t, null);
|
||||||
|
}
|
||||||
// where
|
// where
|
||||||
|
|
||||||
/** diamondTypeChecker: A type visitor that descends down the given type looking for non-denotable
|
/** diamondTypeChecker: A type visitor that descends down the given type looking for non-denotable
|
||||||
* types. The visit methods return false as soon as a non-denotable type is encountered and true
|
* types. The visit methods return false as soon as a non-denotable type is encountered and true
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
private static final Types.SimpleVisitor<Boolean, Void> diamondTypeChecker = new Types.SimpleVisitor<Boolean, Void>() {
|
private static final Types.SimpleVisitor<Boolean, Void> denotableChecker = new Types.SimpleVisitor<Boolean, Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean visitType(Type t, Void s) {
|
public Boolean visitType(Type t, Void s) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public Boolean visitClassType(ClassType t, Void s) {
|
public Boolean visitClassType(ClassType t, Void s) {
|
||||||
if (t.isCompound()) {
|
if (t.isUnion() || t.isIntersection()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (Type targ : t.allparams()) {
|
for (Type targ : t.allparams()) {
|
||||||
|
@ -878,7 +882,7 @@ public class Check {
|
||||||
/* Any type variable mentioned in the inferred type must have been declared as a type parameter
|
/* Any type variable mentioned in the inferred type must have been declared as a type parameter
|
||||||
(i.e cannot have been produced by inference (18.4))
|
(i.e cannot have been produced by inference (18.4))
|
||||||
*/
|
*/
|
||||||
return t.tsym.owner.type.getTypeArguments().contains(t);
|
return (t.tsym.flags() & SYNTHETIC) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -941,6 +945,17 @@ public class Check {
|
||||||
(allowPrivateSafeVarargs ? PRIVATE : 0) )) != 0);
|
(allowPrivateSafeVarargs ? PRIVATE : 0) )) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Type checkLocalVarType(DiagnosticPosition pos, Type t, Name name) {
|
||||||
|
//upward project the initializer type
|
||||||
|
t = types.upward(t, types.captures(t));
|
||||||
|
//check that resulting type is not the null type
|
||||||
|
if (t.hasTag(BOT)) {
|
||||||
|
log.error(pos, Errors.CantInferLocalVarType(name, Fragments.LocalCantInferNull));
|
||||||
|
return types.createErrorType(t);
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
Type checkMethod(final Type mtype,
|
Type checkMethod(final Type mtype,
|
||||||
final Symbol sym,
|
final Symbol sym,
|
||||||
final Env<AttrContext> env,
|
final Env<AttrContext> env,
|
||||||
|
@ -3159,7 +3174,10 @@ public class Check {
|
||||||
if (s.kind == PCK)
|
if (s.kind == PCK)
|
||||||
return true;
|
return true;
|
||||||
} else if (target == names.TYPE_USE) {
|
} else if (target == names.TYPE_USE) {
|
||||||
if (s.kind == TYP || s.kind == VAR ||
|
if (s.kind == VAR && s.owner.kind == MTH && s.type.hasTag(NONE)) {
|
||||||
|
//cannot type annotate implictly typed locals
|
||||||
|
return false;
|
||||||
|
} else if (s.kind == TYP || s.kind == VAR ||
|
||||||
(s.kind == MTH && !s.isConstructor() &&
|
(s.kind == MTH && !s.isConstructor() &&
|
||||||
!s.type.getReturnType().hasTag(VOID)) ||
|
!s.type.getReturnType().hasTag(VOID)) ||
|
||||||
(s.kind == MTH && s.isConstructor())) {
|
(s.kind == MTH && s.isConstructor())) {
|
||||||
|
|
|
@ -529,7 +529,7 @@ public class Infer {
|
||||||
List<Type> upperBounds = uv.getBounds(InferenceBound.UPPER);
|
List<Type> upperBounds = uv.getBounds(InferenceBound.UPPER);
|
||||||
if (Type.containsAny(upperBounds, vars)) {
|
if (Type.containsAny(upperBounds, vars)) {
|
||||||
TypeSymbol fresh_tvar = new TypeVariableSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner);
|
TypeSymbol fresh_tvar = new TypeVariableSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner);
|
||||||
fresh_tvar.type = new TypeVar(fresh_tvar, types.makeIntersectionType(uv.getBounds(InferenceBound.UPPER)), null);
|
fresh_tvar.type = new TypeVar(fresh_tvar, types.makeIntersectionType(uv.getBounds(InferenceBound.UPPER)), syms.botType);
|
||||||
todo.append(uv);
|
todo.append(uv);
|
||||||
uv.setInst(fresh_tvar.type);
|
uv.setInst(fresh_tvar.type);
|
||||||
} else if (upperBounds.nonEmpty()) {
|
} else if (upperBounds.nonEmpty()) {
|
||||||
|
|
|
@ -259,7 +259,7 @@ public class MemberEnter extends JCTree.Visitor {
|
||||||
try {
|
try {
|
||||||
if (TreeInfo.isEnumInit(tree)) {
|
if (TreeInfo.isEnumInit(tree)) {
|
||||||
attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
|
attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
|
||||||
} else {
|
} else if (!tree.isImplicitlyTyped()) {
|
||||||
attr.attribType(tree.vartype, localEnv);
|
attr.attribType(tree.vartype, localEnv);
|
||||||
if (TreeInfo.isReceiverParam(tree))
|
if (TreeInfo.isReceiverParam(tree))
|
||||||
checkReceiver(tree, localEnv);
|
checkReceiver(tree, localEnv);
|
||||||
|
@ -279,8 +279,8 @@ public class MemberEnter extends JCTree.Visitor {
|
||||||
tree.vartype.type = atype.makeVarargs();
|
tree.vartype.type = atype.makeVarargs();
|
||||||
}
|
}
|
||||||
WriteableScope enclScope = enter.enterScope(env);
|
WriteableScope enclScope = enter.enterScope(env);
|
||||||
VarSymbol v =
|
Type vartype = tree.isImplicitlyTyped() ? Type.noType : tree.vartype.type;
|
||||||
new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);
|
VarSymbol v = new VarSymbol(0, tree.name, vartype, enclScope.owner);
|
||||||
v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);
|
v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);
|
||||||
tree.sym = v;
|
tree.sym = v;
|
||||||
if (tree.init != null) {
|
if (tree.init != null) {
|
||||||
|
@ -298,7 +298,9 @@ public class MemberEnter extends JCTree.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
annotate.annotateLater(tree.mods.annotations, localEnv, v, tree.pos());
|
annotate.annotateLater(tree.mods.annotations, localEnv, v, tree.pos());
|
||||||
annotate.queueScanTreeAndTypeAnnotate(tree.vartype, localEnv, v, tree.pos());
|
if (!tree.isImplicitlyTyped()) {
|
||||||
|
annotate.queueScanTreeAndTypeAnnotate(tree.vartype, localEnv, v, tree.pos());
|
||||||
|
}
|
||||||
|
|
||||||
v.pos = tree.pos;
|
v.pos = tree.pos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@ import java.util.EnumSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
@ -105,6 +106,7 @@ public class Resolve {
|
||||||
public final boolean allowModules;
|
public final boolean allowModules;
|
||||||
public final boolean checkVarargsAccessAfterResolution;
|
public final boolean checkVarargsAccessAfterResolution;
|
||||||
private final boolean compactMethodDiags;
|
private final boolean compactMethodDiags;
|
||||||
|
private final boolean allowLocalVariableTypeInference;
|
||||||
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
|
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
|
||||||
|
|
||||||
WriteableScope polymorphicSignatureScope;
|
WriteableScope polymorphicSignatureScope;
|
||||||
|
@ -116,7 +118,7 @@ public class Resolve {
|
||||||
varNotFound = new SymbolNotFoundError(ABSENT_VAR);
|
varNotFound = new SymbolNotFoundError(ABSENT_VAR);
|
||||||
methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
|
methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
|
||||||
typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
|
typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
|
||||||
referenceNotFound = new ReferenceLookupResult(methodNotFound, null);
|
referenceNotFound = ReferenceLookupResult.error(methodNotFound);
|
||||||
|
|
||||||
names = Names.instance(context);
|
names = Names.instance(context);
|
||||||
log = Log.instance(context);
|
log = Log.instance(context);
|
||||||
|
@ -136,6 +138,7 @@ public class Resolve {
|
||||||
Target target = Target.instance(context);
|
Target target = Target.instance(context);
|
||||||
allowMethodHandles = target.hasMethodHandles();
|
allowMethodHandles = target.hasMethodHandles();
|
||||||
allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific();
|
allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific();
|
||||||
|
allowLocalVariableTypeInference = source.allowLocalVariableTypeInference();
|
||||||
checkVarargsAccessAfterResolution =
|
checkVarargsAccessAfterResolution =
|
||||||
source.allowPostApplicabilityVarargsAccessCheck();
|
source.allowPostApplicabilityVarargsAccessCheck();
|
||||||
polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
|
polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
|
||||||
|
@ -2325,6 +2328,10 @@ public class Resolve {
|
||||||
* (a subset of VAL, TYP, PCK).
|
* (a subset of VAL, TYP, PCK).
|
||||||
*/
|
*/
|
||||||
Symbol findIdent(Env<AttrContext> env, Name name, KindSelector kind) {
|
Symbol findIdent(Env<AttrContext> env, Name name, KindSelector kind) {
|
||||||
|
return checkVarType(findIdentInternal(env, name, kind), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol findIdentInternal(Env<AttrContext> env, Name name, KindSelector kind) {
|
||||||
Symbol bestSoFar = typeNotFound;
|
Symbol bestSoFar = typeNotFound;
|
||||||
Symbol sym;
|
Symbol sym;
|
||||||
|
|
||||||
|
@ -2354,6 +2361,11 @@ public class Resolve {
|
||||||
*/
|
*/
|
||||||
Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
|
Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
|
||||||
Name name, KindSelector kind) {
|
Name name, KindSelector kind) {
|
||||||
|
return checkVarType(findIdentInPackageInternal(env, pck, name, kind), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol findIdentInPackageInternal(Env<AttrContext> env, TypeSymbol pck,
|
||||||
|
Name name, KindSelector kind) {
|
||||||
Name fullname = TypeSymbol.formFullName(name, pck);
|
Name fullname = TypeSymbol.formFullName(name, pck);
|
||||||
Symbol bestSoFar = typeNotFound;
|
Symbol bestSoFar = typeNotFound;
|
||||||
if (kind.contains(KindSelector.TYP)) {
|
if (kind.contains(KindSelector.TYP)) {
|
||||||
|
@ -2383,6 +2395,11 @@ public class Resolve {
|
||||||
*/
|
*/
|
||||||
Symbol findIdentInType(Env<AttrContext> env, Type site,
|
Symbol findIdentInType(Env<AttrContext> env, Type site,
|
||||||
Name name, KindSelector kind) {
|
Name name, KindSelector kind) {
|
||||||
|
return checkVarType(findIdentInTypeInternal(env, site, name, kind), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Symbol findIdentInTypeInternal(Env<AttrContext> env, Type site,
|
||||||
|
Name name, KindSelector kind) {
|
||||||
Symbol bestSoFar = typeNotFound;
|
Symbol bestSoFar = typeNotFound;
|
||||||
Symbol sym;
|
Symbol sym;
|
||||||
if (kind.contains(KindSelector.VAL)) {
|
if (kind.contains(KindSelector.VAL)) {
|
||||||
|
@ -2399,6 +2416,14 @@ public class Resolve {
|
||||||
return bestSoFar;
|
return bestSoFar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Symbol checkVarType(Symbol bestSoFar, Name name) {
|
||||||
|
if (allowLocalVariableTypeInference && name.equals(names.var) &&
|
||||||
|
(bestSoFar.kind == TYP || bestSoFar.kind == ABSENT_TYP)) {
|
||||||
|
bestSoFar = new BadVarTypeError();
|
||||||
|
}
|
||||||
|
return bestSoFar;
|
||||||
|
}
|
||||||
|
|
||||||
/* ***************************************************************************
|
/* ***************************************************************************
|
||||||
* Access checking
|
* Access checking
|
||||||
* The following methods convert ResolveErrors to ErrorSymbols, issuing
|
* The following methods convert ResolveErrors to ErrorSymbols, issuing
|
||||||
|
@ -2944,10 +2969,10 @@ public class Resolve {
|
||||||
|
|
||||||
//merge results
|
//merge results
|
||||||
Pair<Symbol, ReferenceLookupHelper> res;
|
Pair<Symbol, ReferenceLookupHelper> res;
|
||||||
Symbol bestSym = referenceChooser.result(boundRes, unboundRes);
|
ReferenceLookupResult bestRes = referenceChooser.result(boundRes, unboundRes);
|
||||||
res = new Pair<>(bestSym,
|
res = new Pair<>(bestRes.sym,
|
||||||
bestSym == unboundSym ? unboundLookupHelper : boundLookupHelper);
|
bestRes == unboundRes ? unboundLookupHelper : boundLookupHelper);
|
||||||
env.info.pendingResolutionPhase = bestSym == unboundSym ?
|
env.info.pendingResolutionPhase = bestRes == unboundRes ?
|
||||||
unboundEnv.info.pendingResolutionPhase :
|
unboundEnv.info.pendingResolutionPhase :
|
||||||
boundEnv.info.pendingResolutionPhase;
|
boundEnv.info.pendingResolutionPhase;
|
||||||
|
|
||||||
|
@ -3003,11 +3028,15 @@ public class Resolve {
|
||||||
Symbol sym;
|
Symbol sym;
|
||||||
|
|
||||||
ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext) {
|
ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext) {
|
||||||
this.staticKind = staticKind(sym, resolutionContext);
|
this(sym, staticKind(sym, resolutionContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ReferenceLookupResult(Symbol sym, StaticKind staticKind) {
|
||||||
|
this.staticKind = staticKind;
|
||||||
this.sym = sym;
|
this.sym = sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
private StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext) {
|
private static StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext) {
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
case MTH:
|
case MTH:
|
||||||
case AMBIGUOUS:
|
case AMBIGUOUS:
|
||||||
|
@ -3056,6 +3085,10 @@ public class Resolve {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ReferenceLookupResult error(Symbol sym) {
|
||||||
|
return new ReferenceLookupResult(sym, StaticKind.UNDEFINED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3068,7 +3101,7 @@ public class Resolve {
|
||||||
* Generate a result from a pair of lookup result objects. This method delegates to the
|
* Generate a result from a pair of lookup result objects. This method delegates to the
|
||||||
* appropriate result generation routine.
|
* appropriate result generation routine.
|
||||||
*/
|
*/
|
||||||
Symbol result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
|
ReferenceLookupResult result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
|
||||||
return unboundRes != referenceNotFound ?
|
return unboundRes != referenceNotFound ?
|
||||||
unboundResult(boundRes, unboundRes) :
|
unboundResult(boundRes, unboundRes) :
|
||||||
boundResult(boundRes);
|
boundResult(boundRes);
|
||||||
|
@ -3077,12 +3110,12 @@ public class Resolve {
|
||||||
/**
|
/**
|
||||||
* Generate a symbol from a given bound lookup result.
|
* Generate a symbol from a given bound lookup result.
|
||||||
*/
|
*/
|
||||||
abstract Symbol boundResult(ReferenceLookupResult boundRes);
|
abstract ReferenceLookupResult boundResult(ReferenceLookupResult boundRes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a symbol from a pair of bound/unbound lookup results.
|
* Generate a symbol from a pair of bound/unbound lookup results.
|
||||||
*/
|
*/
|
||||||
abstract Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes);
|
abstract ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3092,37 +3125,38 @@ public class Resolve {
|
||||||
ReferenceChooser basicReferenceChooser = new ReferenceChooser() {
|
ReferenceChooser basicReferenceChooser = new ReferenceChooser() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Symbol boundResult(ReferenceLookupResult boundRes) {
|
ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) {
|
||||||
return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ?
|
return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ?
|
||||||
boundRes.sym : //the search produces a non-static method
|
boundRes : //the search produces a non-static method
|
||||||
new BadMethodReferenceError(boundRes.sym, false);
|
ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
|
ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
|
||||||
if (boundRes.hasKind(StaticKind.STATIC) &&
|
if (boundRes.hasKind(StaticKind.STATIC) &&
|
||||||
(!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) {
|
(!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) {
|
||||||
//the first search produces a static method and no non-static method is applicable
|
//the first search produces a static method and no non-static method is applicable
|
||||||
//during the second search
|
//during the second search
|
||||||
return boundRes.sym;
|
return boundRes;
|
||||||
} else if (unboundRes.hasKind(StaticKind.NON_STATIC) &&
|
} else if (unboundRes.hasKind(StaticKind.NON_STATIC) &&
|
||||||
(!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) {
|
(!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) {
|
||||||
//the second search produces a non-static method and no static method is applicable
|
//the second search produces a non-static method and no static method is applicable
|
||||||
//during the first search
|
//during the first search
|
||||||
return unboundRes.sym;
|
return unboundRes;
|
||||||
} else if (boundRes.isSuccess() && unboundRes.isSuccess()) {
|
} else if (boundRes.isSuccess() && unboundRes.isSuccess()) {
|
||||||
//both searches produce some result; ambiguity (error recovery)
|
//both searches produce some result; ambiguity (error recovery)
|
||||||
return ambiguityError(boundRes.sym, unboundRes.sym);
|
return ReferenceLookupResult.error(ambiguityError(boundRes.sym, unboundRes.sym));
|
||||||
} else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
|
} else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
|
||||||
//Both searches failed to produce a result with correct staticness (i.e. first search
|
//Both searches failed to produce a result with correct staticness (i.e. first search
|
||||||
//produces an non-static method). Alternatively, a given search produced a result
|
//produces an non-static method). Alternatively, a given search produced a result
|
||||||
//with the right staticness, but the other search has applicable methods with wrong
|
//with the right staticness, but the other search has applicable methods with wrong
|
||||||
//staticness (error recovery)
|
//staticness (error recovery)
|
||||||
return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true);
|
return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ?
|
||||||
|
boundRes.sym : unboundRes.sym, true));
|
||||||
} else {
|
} else {
|
||||||
//both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
|
//both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
|
||||||
return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
|
return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
|
||||||
unboundRes.sym : boundRes.sym;
|
unboundRes : boundRes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3134,28 +3168,29 @@ public class Resolve {
|
||||||
ReferenceChooser structuralReferenceChooser = new ReferenceChooser() {
|
ReferenceChooser structuralReferenceChooser = new ReferenceChooser() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Symbol boundResult(ReferenceLookupResult boundRes) {
|
ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) {
|
||||||
return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ?
|
return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ?
|
||||||
boundRes.sym : //the search has at least one applicable non-static method
|
boundRes : //the search has at least one applicable non-static method
|
||||||
new BadMethodReferenceError(boundRes.sym, false);
|
ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Symbol unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
|
ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
|
||||||
if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) {
|
if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) {
|
||||||
//the first serach has at least one applicable static method
|
//the first serach has at least one applicable static method
|
||||||
return boundRes.sym;
|
return boundRes;
|
||||||
} else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) {
|
} else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) {
|
||||||
//the second search has at least one applicable non-static method
|
//the second search has at least one applicable non-static method
|
||||||
return unboundRes.sym;
|
return unboundRes;
|
||||||
} else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
|
} else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
|
||||||
//either the first search produces a non-static method, or second search produces
|
//either the first search produces a non-static method, or second search produces
|
||||||
//a non-static method (error recovery)
|
//a non-static method (error recovery)
|
||||||
return new BadMethodReferenceError(boundRes.isSuccess() ? boundRes.sym : unboundRes.sym, true);
|
return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ?
|
||||||
|
boundRes.sym : unboundRes.sym, true));
|
||||||
} else {
|
} else {
|
||||||
//both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
|
//both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
|
||||||
return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
|
return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
|
||||||
unboundRes.sym : boundRes.sym;
|
unboundRes : boundRes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3774,6 +3809,17 @@ public class Resolve {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BadVarTypeError extends ResolveError {
|
||||||
|
BadVarTypeError() {
|
||||||
|
super(Kind.BAD_VAR, "bad var use");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
|
||||||
|
return diags.create(dkind, log.currentSource(), pos, "illegal.ref.to.var.type", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* InvalidSymbolError error class indicating that a symbol matching a
|
* InvalidSymbolError error class indicating that a symbol matching a
|
||||||
* given name does not exists in a given site.
|
* given name does not exists in a given site.
|
||||||
|
@ -3995,14 +4041,35 @@ public class Resolve {
|
||||||
}
|
}
|
||||||
//where
|
//where
|
||||||
private Map<Symbol, JCDiagnostic> mapCandidates() {
|
private Map<Symbol, JCDiagnostic> mapCandidates() {
|
||||||
Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>();
|
MostSpecificMap candidates = new MostSpecificMap();
|
||||||
for (Candidate c : resolveContext.candidates) {
|
for (Candidate c : resolveContext.candidates) {
|
||||||
if (c.isApplicable()) continue;
|
if (c.isApplicable()) continue;
|
||||||
candidates.put(c.sym, c.details);
|
candidates.put(c);
|
||||||
}
|
}
|
||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
private class MostSpecificMap extends LinkedHashMap<Symbol, JCDiagnostic> {
|
||||||
|
private void put(Candidate c) {
|
||||||
|
ListBuffer<Symbol> overridden = new ListBuffer<>();
|
||||||
|
for (Symbol s : keySet()) {
|
||||||
|
if (s == c.sym) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c.sym.overrides(s, (TypeSymbol)s.owner, types, false)) {
|
||||||
|
overridden.add(s);
|
||||||
|
} else if (s.overrides(c.sym, (TypeSymbol)c.sym.owner, types, false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Symbol s : overridden) {
|
||||||
|
remove(s);
|
||||||
|
}
|
||||||
|
put(c.sym, c.details);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Map<Symbol, JCDiagnostic> filterCandidates(Map<Symbol, JCDiagnostic> candidatesMap) {
|
Map<Symbol, JCDiagnostic> filterCandidates(Map<Symbol, JCDiagnostic> candidatesMap) {
|
||||||
Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>();
|
Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>();
|
||||||
for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
|
for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
|
||||||
|
|
|
@ -179,6 +179,7 @@ public class JavacParser implements Parser {
|
||||||
this.allowAnnotationsAfterTypeParams = source.allowAnnotationsAfterTypeParams();
|
this.allowAnnotationsAfterTypeParams = source.allowAnnotationsAfterTypeParams();
|
||||||
this.allowUnderscoreIdentifier = source.allowUnderscoreIdentifier();
|
this.allowUnderscoreIdentifier = source.allowUnderscoreIdentifier();
|
||||||
this.allowPrivateInterfaceMethods = source.allowPrivateInterfaceMethods();
|
this.allowPrivateInterfaceMethods = source.allowPrivateInterfaceMethods();
|
||||||
|
this.allowLocalVariableTypeInference = source.allowLocalVariableTypeInference();
|
||||||
this.keepDocComments = keepDocComments;
|
this.keepDocComments = keepDocComments;
|
||||||
this.parseModuleInfo = parseModuleInfo;
|
this.parseModuleInfo = parseModuleInfo;
|
||||||
docComments = newDocCommentTable(keepDocComments, fac);
|
docComments = newDocCommentTable(keepDocComments, fac);
|
||||||
|
@ -270,11 +271,14 @@ public class JavacParser implements Parser {
|
||||||
*/
|
*/
|
||||||
boolean allowThisIdent;
|
boolean allowThisIdent;
|
||||||
|
|
||||||
|
/** Switch: is local variable inference allowed?
|
||||||
|
*/
|
||||||
|
boolean allowLocalVariableTypeInference;
|
||||||
|
|
||||||
/** The type of the method receiver, as specified by a first "this" parameter.
|
/** The type of the method receiver, as specified by a first "this" parameter.
|
||||||
*/
|
*/
|
||||||
JCVariableDecl receiverParam;
|
JCVariableDecl receiverParam;
|
||||||
|
|
||||||
|
|
||||||
/** When terms are parsed, the mode determines which is expected:
|
/** When terms are parsed, the mode determines which is expected:
|
||||||
* mode = EXPR : an expression
|
* mode = EXPR : an expression
|
||||||
* mode = TYPE : a type
|
* mode = TYPE : a type
|
||||||
|
@ -808,12 +812,16 @@ public class JavacParser implements Parser {
|
||||||
* parsing annotations.
|
* parsing annotations.
|
||||||
*/
|
*/
|
||||||
public JCExpression parseType() {
|
public JCExpression parseType() {
|
||||||
List<JCAnnotation> annotations = typeAnnotationsOpt();
|
return parseType(false);
|
||||||
return parseType(annotations);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public JCExpression parseType(List<JCAnnotation> annotations) {
|
public JCExpression parseType(boolean allowVar) {
|
||||||
JCExpression result = unannotatedType();
|
List<JCAnnotation> annotations = typeAnnotationsOpt();
|
||||||
|
return parseType(allowVar, annotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JCExpression parseType(boolean allowVar, List<JCAnnotation> annotations) {
|
||||||
|
JCExpression result = unannotatedType(allowVar);
|
||||||
|
|
||||||
if (annotations.nonEmpty()) {
|
if (annotations.nonEmpty()) {
|
||||||
result = insertAnnotationsToMostInner(result, annotations, false);
|
result = insertAnnotationsToMostInner(result, annotations, false);
|
||||||
|
@ -822,10 +830,18 @@ public class JavacParser implements Parser {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JCExpression unannotatedType() {
|
public JCExpression unannotatedType(boolean allowVar) {
|
||||||
return term(TYPE);
|
JCExpression result = term(TYPE);
|
||||||
|
|
||||||
|
if (!allowVar && isRestrictedLocalVarTypeName(result)) {
|
||||||
|
syntaxError(result.pos, "var.not.allowed.here");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected JCExpression term(int newmode) {
|
protected JCExpression term(int newmode) {
|
||||||
int prevmode = mode;
|
int prevmode = mode;
|
||||||
mode = newmode;
|
mode = newmode;
|
||||||
|
@ -1152,11 +1168,11 @@ public class JavacParser implements Parser {
|
||||||
accept(LPAREN);
|
accept(LPAREN);
|
||||||
mode = TYPE;
|
mode = TYPE;
|
||||||
int pos1 = pos;
|
int pos1 = pos;
|
||||||
List<JCExpression> targets = List.of(t = term3());
|
List<JCExpression> targets = List.of(t = parseType());
|
||||||
while (token.kind == AMP) {
|
while (token.kind == AMP) {
|
||||||
checkIntersectionTypesInCast();
|
checkIntersectionTypesInCast();
|
||||||
accept(AMP);
|
accept(AMP);
|
||||||
targets = targets.prepend(term3());
|
targets = targets.prepend(parseType());
|
||||||
}
|
}
|
||||||
if (targets.length() > 1) {
|
if (targets.length() > 1) {
|
||||||
t = toP(F.at(pos1).TypeIntersection(targets.reverse()));
|
t = toP(F.at(pos1).TypeIntersection(targets.reverse()));
|
||||||
|
@ -1912,7 +1928,7 @@ public class JavacParser implements Parser {
|
||||||
*/
|
*/
|
||||||
JCExpression typeArgument() {
|
JCExpression typeArgument() {
|
||||||
List<JCAnnotation> annotations = typeAnnotationsOpt();
|
List<JCAnnotation> annotations = typeAnnotationsOpt();
|
||||||
if (token.kind != QUES) return parseType(annotations);
|
if (token.kind != QUES) return parseType(false, annotations);
|
||||||
int pos = token.pos;
|
int pos = token.pos;
|
||||||
nextToken();
|
nextToken();
|
||||||
JCExpression result;
|
JCExpression result;
|
||||||
|
@ -2425,13 +2441,8 @@ public class JavacParser implements Parser {
|
||||||
token.kind == ENUM) {
|
token.kind == ENUM) {
|
||||||
return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
|
return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
|
||||||
} else {
|
} else {
|
||||||
JCExpression t = parseType();
|
JCExpression t = parseType(true);
|
||||||
ListBuffer<JCStatement> stats =
|
return localVariableDeclarations(mods, t);
|
||||||
variableDeclarators(mods, t, new ListBuffer<JCStatement>());
|
|
||||||
// A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
|
|
||||||
accept(SEMI);
|
|
||||||
storeEnd(stats.last(), S.prevToken().endPos);
|
|
||||||
return stats.toList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ABSTRACT: case STRICTFP: {
|
case ABSTRACT: case STRICTFP: {
|
||||||
|
@ -2458,12 +2469,7 @@ public class JavacParser implements Parser {
|
||||||
pos = token.pos;
|
pos = token.pos;
|
||||||
JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
|
JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
|
||||||
F.at(pos);
|
F.at(pos);
|
||||||
ListBuffer<JCStatement> stats =
|
return localVariableDeclarations(mods, t);
|
||||||
variableDeclarators(mods, t, new ListBuffer<JCStatement>());
|
|
||||||
// A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
|
|
||||||
accept(SEMI);
|
|
||||||
storeEnd(stats.last(), S.prevToken().endPos);
|
|
||||||
return stats.toList();
|
|
||||||
} else {
|
} else {
|
||||||
// This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
|
// This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
|
||||||
t = checkExprStat(t);
|
t = checkExprStat(t);
|
||||||
|
@ -2473,6 +2479,15 @@ public class JavacParser implements Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//where
|
||||||
|
private List<JCStatement> localVariableDeclarations(JCModifiers mods, JCExpression type) {
|
||||||
|
ListBuffer<JCStatement> stats =
|
||||||
|
variableDeclarators(mods, type, new ListBuffer<>(), true);
|
||||||
|
// A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
|
||||||
|
accept(SEMI);
|
||||||
|
storeEnd(stats.last(), S.prevToken().endPos);
|
||||||
|
return stats.toList();
|
||||||
|
}
|
||||||
|
|
||||||
/** Statement =
|
/** Statement =
|
||||||
* Block
|
* Block
|
||||||
|
@ -2766,11 +2781,11 @@ public class JavacParser implements Parser {
|
||||||
ListBuffer<JCStatement> stats = new ListBuffer<>();
|
ListBuffer<JCStatement> stats = new ListBuffer<>();
|
||||||
int pos = token.pos;
|
int pos = token.pos;
|
||||||
if (token.kind == FINAL || token.kind == MONKEYS_AT) {
|
if (token.kind == FINAL || token.kind == MONKEYS_AT) {
|
||||||
return variableDeclarators(optFinal(0), parseType(), stats).toList();
|
return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
|
||||||
} else {
|
} else {
|
||||||
JCExpression t = term(EXPR | TYPE);
|
JCExpression t = term(EXPR | TYPE);
|
||||||
if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
|
if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
|
||||||
return variableDeclarators(modifiersOpt(), t, stats).toList();
|
return variableDeclarators(modifiersOpt(), t, stats, true).toList();
|
||||||
} else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
|
} else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
|
||||||
error(pos, "bad.initializer", "for-loop");
|
error(pos, "bad.initializer", "for-loop");
|
||||||
return List.of((JCStatement)F.at(pos).VarDef(null, null, t, null));
|
return List.of((JCStatement)F.at(pos).VarDef(null, null, t, null));
|
||||||
|
@ -2989,9 +3004,10 @@ public class JavacParser implements Parser {
|
||||||
*/
|
*/
|
||||||
public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
|
public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
|
||||||
JCExpression type,
|
JCExpression type,
|
||||||
T vdefs)
|
T vdefs,
|
||||||
|
boolean localDecl)
|
||||||
{
|
{
|
||||||
return variableDeclaratorsRest(token.pos, mods, type, ident(), false, null, vdefs);
|
return variableDeclaratorsRest(token.pos, mods, type, ident(), false, null, vdefs, localDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
|
/** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
|
||||||
|
@ -3006,14 +3022,20 @@ public class JavacParser implements Parser {
|
||||||
Name name,
|
Name name,
|
||||||
boolean reqInit,
|
boolean reqInit,
|
||||||
Comment dc,
|
Comment dc,
|
||||||
T vdefs)
|
T vdefs,
|
||||||
|
boolean localDecl)
|
||||||
{
|
{
|
||||||
vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
|
JCVariableDecl head = variableDeclaratorRest(pos, mods, type, name, reqInit, dc, localDecl);
|
||||||
|
boolean implicit = allowLocalVariableTypeInference && head.vartype == null;
|
||||||
|
vdefs.append(head);
|
||||||
while (token.kind == COMMA) {
|
while (token.kind == COMMA) {
|
||||||
|
if (implicit) {
|
||||||
|
reportSyntaxError(pos, "var.not.allowed.compound");
|
||||||
|
}
|
||||||
// All but last of multiple declarators subsume a comma
|
// All but last of multiple declarators subsume a comma
|
||||||
storeEnd((JCTree)vdefs.last(), token.endPos);
|
storeEnd((JCTree)vdefs.last(), token.endPos);
|
||||||
nextToken();
|
nextToken();
|
||||||
vdefs.append(variableDeclarator(mods, type, reqInit, dc));
|
vdefs.append(variableDeclarator(mods, type, reqInit, dc, localDecl));
|
||||||
}
|
}
|
||||||
return vdefs;
|
return vdefs;
|
||||||
}
|
}
|
||||||
|
@ -3021,8 +3043,8 @@ public class JavacParser implements Parser {
|
||||||
/** VariableDeclarator = Ident VariableDeclaratorRest
|
/** VariableDeclarator = Ident VariableDeclaratorRest
|
||||||
* ConstantDeclarator = Ident ConstantDeclaratorRest
|
* ConstantDeclarator = Ident ConstantDeclaratorRest
|
||||||
*/
|
*/
|
||||||
JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, Comment dc) {
|
JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, Comment dc, boolean localDecl) {
|
||||||
return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc);
|
return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc, localDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
|
/** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
|
||||||
|
@ -3032,7 +3054,7 @@ public class JavacParser implements Parser {
|
||||||
* @param dc The documentation comment for the variable declarations, or null.
|
* @param dc The documentation comment for the variable declarations, or null.
|
||||||
*/
|
*/
|
||||||
JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
|
JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
|
||||||
boolean reqInit, Comment dc) {
|
boolean reqInit, Comment dc, boolean localDecl) {
|
||||||
type = bracketsOpt(type);
|
type = bracketsOpt(type);
|
||||||
JCExpression init = null;
|
JCExpression init = null;
|
||||||
if (token.kind == EQ) {
|
if (token.kind == EQ) {
|
||||||
|
@ -3040,12 +3062,40 @@ public class JavacParser implements Parser {
|
||||||
init = variableInitializer();
|
init = variableInitializer();
|
||||||
}
|
}
|
||||||
else if (reqInit) syntaxError(token.pos, "expected", EQ);
|
else if (reqInit) syntaxError(token.pos, "expected", EQ);
|
||||||
|
JCTree elemType = TreeInfo.innermostType(type, true);
|
||||||
|
if (allowLocalVariableTypeInference && elemType.hasTag(IDENT)) {
|
||||||
|
Name typeName = ((JCIdent)elemType).name;
|
||||||
|
if (isRestrictedLocalVarTypeName(typeName)) {
|
||||||
|
if (type.hasTag(TYPEARRAY)) {
|
||||||
|
//error - 'var' and arrays
|
||||||
|
reportSyntaxError(pos, "var.not.allowed.array");
|
||||||
|
} else {
|
||||||
|
//implicit type
|
||||||
|
type = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
JCVariableDecl result =
|
JCVariableDecl result =
|
||||||
toP(F.at(pos).VarDef(mods, name, type, init));
|
toP(F.at(pos).VarDef(mods, name, type, init));
|
||||||
attach(result, dc);
|
attach(result, dc);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isRestrictedLocalVarTypeName(JCExpression e) {
|
||||||
|
switch (e.getTag()) {
|
||||||
|
case IDENT:
|
||||||
|
return isRestrictedLocalVarTypeName(((JCIdent)e).name);
|
||||||
|
case TYPEARRAY:
|
||||||
|
return isRestrictedLocalVarTypeName(((JCArrayTypeTree)e).elemtype);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isRestrictedLocalVarTypeName(Name name) {
|
||||||
|
return allowLocalVariableTypeInference && name == names.var;
|
||||||
|
}
|
||||||
|
|
||||||
/** VariableDeclaratorId = Ident BracketsOpt
|
/** VariableDeclaratorId = Ident BracketsOpt
|
||||||
*/
|
*/
|
||||||
JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
|
JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
|
||||||
|
@ -3111,13 +3161,13 @@ public class JavacParser implements Parser {
|
||||||
int startPos = token.pos;
|
int startPos = token.pos;
|
||||||
if (token.kind == FINAL || token.kind == MONKEYS_AT) {
|
if (token.kind == FINAL || token.kind == MONKEYS_AT) {
|
||||||
JCModifiers mods = optFinal(Flags.FINAL);
|
JCModifiers mods = optFinal(Flags.FINAL);
|
||||||
JCExpression t = parseType();
|
JCExpression t = parseType(true);
|
||||||
return variableDeclaratorRest(token.pos, mods, t, ident(), true, null);
|
return variableDeclaratorRest(token.pos, mods, t, ident(), true, null, true);
|
||||||
}
|
}
|
||||||
JCExpression t = term(EXPR | TYPE);
|
JCExpression t = term(EXPR | TYPE);
|
||||||
if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
|
if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
|
||||||
JCModifiers mods = toP(F.at(startPos).Modifiers(Flags.FINAL));
|
JCModifiers mods = toP(F.at(startPos).Modifiers(Flags.FINAL));
|
||||||
return variableDeclaratorRest(token.pos, mods, t, ident(), true, null);
|
return variableDeclaratorRest(token.pos, mods, t, ident(), true, null, true);
|
||||||
} else {
|
} else {
|
||||||
checkVariableInTryWithResources(startPos);
|
checkVariableInTryWithResources(startPos);
|
||||||
if (!t.hasTag(IDENT) && !t.hasTag(SELECT)) {
|
if (!t.hasTag(IDENT) && !t.hasTag(SELECT)) {
|
||||||
|
@ -3397,7 +3447,7 @@ public class JavacParser implements Parser {
|
||||||
protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
|
protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
|
||||||
int pos = token.pos;
|
int pos = token.pos;
|
||||||
accept(CLASS);
|
accept(CLASS);
|
||||||
Name name = ident();
|
Name name = typeName();
|
||||||
|
|
||||||
List<JCTypeParameter> typarams = typeParametersOpt();
|
List<JCTypeParameter> typarams = typeParametersOpt();
|
||||||
|
|
||||||
|
@ -3418,6 +3468,15 @@ public class JavacParser implements Parser {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Name typeName() {
|
||||||
|
int pos = token.pos;
|
||||||
|
Name name = ident();
|
||||||
|
if (isRestrictedLocalVarTypeName(name)) {
|
||||||
|
reportSyntaxError(pos, "var.not.allowed", name);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
/** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
|
/** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
|
||||||
* [EXTENDS TypeList] InterfaceBody
|
* [EXTENDS TypeList] InterfaceBody
|
||||||
* @param mods The modifiers starting the interface declaration
|
* @param mods The modifiers starting the interface declaration
|
||||||
|
@ -3426,7 +3485,8 @@ public class JavacParser implements Parser {
|
||||||
protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
|
protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
|
||||||
int pos = token.pos;
|
int pos = token.pos;
|
||||||
accept(INTERFACE);
|
accept(INTERFACE);
|
||||||
Name name = ident();
|
|
||||||
|
Name name = typeName();
|
||||||
|
|
||||||
List<JCTypeParameter> typarams = typeParametersOpt();
|
List<JCTypeParameter> typarams = typeParametersOpt();
|
||||||
|
|
||||||
|
@ -3449,7 +3509,8 @@ public class JavacParser implements Parser {
|
||||||
protected JCClassDecl enumDeclaration(JCModifiers mods, Comment dc) {
|
protected JCClassDecl enumDeclaration(JCModifiers mods, Comment dc) {
|
||||||
int pos = token.pos;
|
int pos = token.pos;
|
||||||
accept(ENUM);
|
accept(ENUM);
|
||||||
Name name = ident();
|
|
||||||
|
Name name = typeName();
|
||||||
|
|
||||||
List<JCExpression> implementing = List.nil();
|
List<JCExpression> implementing = List.nil();
|
||||||
if (token.kind == IMPLEMENTS) {
|
if (token.kind == IMPLEMENTS) {
|
||||||
|
@ -3647,7 +3708,7 @@ public class JavacParser implements Parser {
|
||||||
nextToken();
|
nextToken();
|
||||||
} else {
|
} else {
|
||||||
// method returns types are un-annotated types
|
// method returns types are un-annotated types
|
||||||
type = unannotatedType();
|
type = unannotatedType(false);
|
||||||
}
|
}
|
||||||
if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) {
|
if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) {
|
||||||
if (isInterface || tk.name() != className)
|
if (isInterface || tk.name() != className)
|
||||||
|
@ -3667,7 +3728,7 @@ public class JavacParser implements Parser {
|
||||||
} else if (!isVoid && typarams.isEmpty()) {
|
} else if (!isVoid && typarams.isEmpty()) {
|
||||||
List<JCTree> defs =
|
List<JCTree> defs =
|
||||||
variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
|
variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
|
||||||
new ListBuffer<JCTree>()).toList();
|
new ListBuffer<JCTree>(), false).toList();
|
||||||
accept(SEMI);
|
accept(SEMI);
|
||||||
storeEnd(defs.last(), S.prevToken().endPos);
|
storeEnd(defs.last(), S.prevToken().endPos);
|
||||||
return defs;
|
return defs;
|
||||||
|
@ -3809,7 +3870,7 @@ public class JavacParser implements Parser {
|
||||||
JCTypeParameter typeParameter() {
|
JCTypeParameter typeParameter() {
|
||||||
int pos = token.pos;
|
int pos = token.pos;
|
||||||
List<JCAnnotation> annos = typeAnnotationsOpt();
|
List<JCAnnotation> annos = typeAnnotationsOpt();
|
||||||
Name name = ident();
|
Name name = typeName();
|
||||||
ListBuffer<JCExpression> bounds = new ListBuffer<>();
|
ListBuffer<JCExpression> bounds = new ListBuffer<>();
|
||||||
if (token.kind == EXTENDS) {
|
if (token.kind == EXTENDS) {
|
||||||
nextToken();
|
nextToken();
|
||||||
|
|
|
@ -1190,6 +1190,47 @@ compiler.err.io.exception=\
|
||||||
compiler.err.undef.label=\
|
compiler.err.undef.label=\
|
||||||
undefined label: {0}
|
undefined label: {0}
|
||||||
|
|
||||||
|
# 0: name (type)
|
||||||
|
compiler.err.illegal.ref.to.var.type=\
|
||||||
|
illegal reference to restricted type ''{0}''
|
||||||
|
|
||||||
|
# 0: token
|
||||||
|
compiler.err.var.not.allowed=\
|
||||||
|
''{0}'' not allowed here\n\
|
||||||
|
as of release 10, ''{0}'' is a restricted local variable type and cannot be used for type declarations
|
||||||
|
|
||||||
|
# 0: name (variable), 1: message segment
|
||||||
|
compiler.err.cant.infer.local.var.type=\
|
||||||
|
cannot infer type for local variable {0}\n\
|
||||||
|
({1})
|
||||||
|
|
||||||
|
compiler.err.var.not.allowed.here=\
|
||||||
|
''var'' is not allowed here
|
||||||
|
|
||||||
|
compiler.err.var.not.allowed.array=\
|
||||||
|
''var'' is not allowed as an element type of an array
|
||||||
|
|
||||||
|
compiler.err.var.not.allowed.compound=\
|
||||||
|
''var'' is not allowed in a compound declaration
|
||||||
|
|
||||||
|
compiler.misc.local.cant.infer.null=\
|
||||||
|
variable initializer is ''null''
|
||||||
|
|
||||||
|
compiler.misc.local.missing.init=\
|
||||||
|
cannot use ''var'' on variable without initializer
|
||||||
|
|
||||||
|
compiler.misc.local.lambda.missing.target=\
|
||||||
|
lambda expression needs an explicit target-type
|
||||||
|
|
||||||
|
compiler.misc.local.mref.missing.target=\
|
||||||
|
method reference needs an explicit target-type
|
||||||
|
|
||||||
|
compiler.misc.local.array.missing.target=\
|
||||||
|
array initializer needs an explicit target-type
|
||||||
|
|
||||||
|
compiler.misc.local.self.ref=\
|
||||||
|
cannot use ''var'' on self-referencing variable
|
||||||
|
|
||||||
# 0: message segment, 1: unused
|
# 0: message segment, 1: unused
|
||||||
compiler.err.cant.apply.diamond=\
|
compiler.err.cant.apply.diamond=\
|
||||||
cannot infer type arguments for {0}
|
cannot infer type arguments for {0}
|
||||||
|
@ -1873,6 +1914,9 @@ compiler.warn.raw.class.use=\
|
||||||
compiler.warn.diamond.redundant.args=\
|
compiler.warn.diamond.redundant.args=\
|
||||||
Redundant type arguments in new expression (use diamond operator instead).
|
Redundant type arguments in new expression (use diamond operator instead).
|
||||||
|
|
||||||
|
compiler.warn.local.redundant.type=\
|
||||||
|
Redundant type for local variable (replace explicit type with ''var'').
|
||||||
|
|
||||||
compiler.warn.potential.lambda.found=\
|
compiler.warn.potential.lambda.found=\
|
||||||
This anonymous inner class creation can be turned into a lambda expression.
|
This anonymous inner class creation can be turned into a lambda expression.
|
||||||
|
|
||||||
|
|
|
@ -946,6 +946,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isImplicitlyTyped() {
|
||||||
|
return vartype == null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(Visitor v) { v.visitVarDef(this); }
|
public void accept(Visitor v) { v.visitVarDef(this); }
|
||||||
|
|
||||||
|
|
|
@ -1359,7 +1359,7 @@ public class Pretty extends JCTree.Visitor {
|
||||||
|
|
||||||
// Prints the inner element type of a nested array
|
// Prints the inner element type of a nested array
|
||||||
private void printBaseElementType(JCTree tree) throws IOException {
|
private void printBaseElementType(JCTree tree) throws IOException {
|
||||||
printExpr(TreeInfo.innermostType(tree));
|
printExpr(TreeInfo.innermostType(tree, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
// prints the brackets of a nested array in reverse order
|
// prints the brackets of a nested array in reverse order
|
||||||
|
|
|
@ -1136,7 +1136,7 @@ public class TreeInfo {
|
||||||
* For an array that contains an annotated type, return that annotated type.
|
* For an array that contains an annotated type, return that annotated type.
|
||||||
* TODO: currently only used by Pretty. Describe behavior better.
|
* TODO: currently only used by Pretty. Describe behavior better.
|
||||||
*/
|
*/
|
||||||
public static JCTree innermostType(JCTree type) {
|
public static JCTree innermostType(JCTree type, boolean skipAnnos) {
|
||||||
JCTree lastAnnotatedType = null;
|
JCTree lastAnnotatedType = null;
|
||||||
JCTree cur = type;
|
JCTree cur = type;
|
||||||
loop: while (true) {
|
loop: while (true) {
|
||||||
|
@ -1157,7 +1157,7 @@ public class TreeInfo {
|
||||||
break loop;
|
break loop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lastAnnotatedType!=null) {
|
if (!skipAnnos && lastAnnotatedType!=null) {
|
||||||
return lastAnnotatedType;
|
return lastAnnotatedType;
|
||||||
} else {
|
} else {
|
||||||
return cur;
|
return cur;
|
||||||
|
|
|
@ -63,6 +63,7 @@ public class Names {
|
||||||
public final Name _default;
|
public final Name _default;
|
||||||
public final Name _super;
|
public final Name _super;
|
||||||
public final Name _this;
|
public final Name _this;
|
||||||
|
public final Name var;
|
||||||
public final Name exports;
|
public final Name exports;
|
||||||
public final Name opens;
|
public final Name opens;
|
||||||
public final Name module;
|
public final Name module;
|
||||||
|
@ -224,6 +225,7 @@ public class Names {
|
||||||
_default = fromString("default");
|
_default = fromString("default");
|
||||||
_super = fromString("super");
|
_super = fromString("super");
|
||||||
_this = fromString("this");
|
_this = fromString("this");
|
||||||
|
var = fromString("var");
|
||||||
exports = fromString("exports");
|
exports = fromString("exports");
|
||||||
opens = fromString("opens");
|
opens = fromString("opens");
|
||||||
module = fromString("module");
|
module = fromString("module");
|
||||||
|
|
|
@ -106,7 +106,8 @@ module jdk.compiler {
|
||||||
exports com.sun.tools.javac.jvm to
|
exports com.sun.tools.javac.jvm to
|
||||||
jdk.javadoc;
|
jdk.javadoc;
|
||||||
exports com.sun.tools.javac.main to
|
exports com.sun.tools.javac.main to
|
||||||
jdk.javadoc;
|
jdk.javadoc,
|
||||||
|
jdk.jshell;
|
||||||
exports com.sun.tools.javac.model to
|
exports com.sun.tools.javac.model to
|
||||||
jdk.javadoc;
|
jdk.javadoc;
|
||||||
exports com.sun.tools.javac.parser to
|
exports com.sun.tools.javac.parser to
|
||||||
|
|
|
@ -39,6 +39,7 @@ import javax.lang.model.type.TypeMirror;
|
||||||
import javax.lang.model.type.TypeVariable;
|
import javax.lang.model.type.TypeVariable;
|
||||||
import javax.lang.model.util.SimpleTypeVisitor9;
|
import javax.lang.model.util.SimpleTypeVisitor9;
|
||||||
|
|
||||||
|
import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
|
||||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||||
|
@ -98,15 +99,19 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Content getDeprecatedLink(Element member) {
|
protected Content getDeprecatedLink(Element member) {
|
||||||
StringBuilder sb = new StringBuilder();
|
Content deprecatedLinkContent = new ContentBuilder();
|
||||||
sb.append(utils.getFullyQualifiedName(member));
|
deprecatedLinkContent.addContent(utils.getFullyQualifiedName(member));
|
||||||
if (!utils.isConstructor(member)) {
|
if (!utils.isConstructor(member)) {
|
||||||
sb.append(".");
|
deprecatedLinkContent.addContent(".");
|
||||||
sb.append(member.getSimpleName());
|
deprecatedLinkContent.addContent(member.getSimpleName());
|
||||||
}
|
}
|
||||||
sb.append(utils.flatSignature((ExecutableElement) member));
|
String signature = utils.flatSignature((ExecutableElement) member);
|
||||||
|
if (signature.length() > 2) {
|
||||||
|
deprecatedLinkContent.addContent(Contents.ZERO_WIDTH_SPACE);
|
||||||
|
}
|
||||||
|
deprecatedLinkContent.addContent(signature);
|
||||||
|
|
||||||
return writer.getDocLink(MEMBER, member, sb);
|
return writer.getDocLink(MEMBER, utils.getEnclosingTypeElement(member), member, deprecatedLinkContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -199,55 +204,61 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
|
||||||
*/
|
*/
|
||||||
protected void addParameters(ExecutableElement member,
|
protected void addParameters(ExecutableElement member,
|
||||||
boolean includeAnnotations, Content htmltree, int indentSize) {
|
boolean includeAnnotations, Content htmltree, int indentSize) {
|
||||||
htmltree.addContent(Contents.ZERO_WIDTH_SPACE);
|
Content paramTree = new ContentBuilder();
|
||||||
htmltree.addContent("(");
|
|
||||||
String sep = "";
|
String sep = "";
|
||||||
List<? extends VariableElement> parameters = member.getParameters();
|
List<? extends VariableElement> parameters = member.getParameters();
|
||||||
CharSequence indent = makeSpace(indentSize + 1);
|
CharSequence indent = makeSpace(indentSize + 1);
|
||||||
TypeMirror rcvrType = member.getReceiverType();
|
TypeMirror rcvrType = member.getReceiverType();
|
||||||
if (includeAnnotations && rcvrType != null && utils.isAnnotated(rcvrType)) {
|
if (includeAnnotations && rcvrType != null && utils.isAnnotated(rcvrType)) {
|
||||||
List<? extends AnnotationMirror> annotationMirrors = rcvrType.getAnnotationMirrors();
|
List<? extends AnnotationMirror> annotationMirrors = rcvrType.getAnnotationMirrors();
|
||||||
addReceiverAnnotations(member, rcvrType, annotationMirrors, htmltree);
|
addReceiverAnnotations(member, rcvrType, annotationMirrors, paramTree);
|
||||||
sep = "," + DocletConstants.NL + indent;
|
sep = "," + DocletConstants.NL + indent;
|
||||||
}
|
}
|
||||||
int paramstart;
|
int paramstart;
|
||||||
for (paramstart = 0; paramstart < parameters.size(); paramstart++) {
|
for (paramstart = 0; paramstart < parameters.size(); paramstart++) {
|
||||||
htmltree.addContent(sep);
|
paramTree.addContent(sep);
|
||||||
VariableElement param = parameters.get(paramstart);
|
VariableElement param = parameters.get(paramstart);
|
||||||
|
|
||||||
if (param.getKind() != ElementKind.INSTANCE_INIT) {
|
if (param.getKind() != ElementKind.INSTANCE_INIT) {
|
||||||
if (includeAnnotations) {
|
if (includeAnnotations) {
|
||||||
boolean foundAnnotations =
|
boolean foundAnnotations =
|
||||||
writer.addAnnotationInfo(indent.length(),
|
writer.addAnnotationInfo(indent.length(),
|
||||||
member, param, htmltree);
|
member, param, paramTree);
|
||||||
if (foundAnnotations) {
|
if (foundAnnotations) {
|
||||||
htmltree.addContent(DocletConstants.NL);
|
paramTree.addContent(DocletConstants.NL);
|
||||||
htmltree.addContent(indent);
|
paramTree.addContent(indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addParam(member, param,
|
addParam(member, param,
|
||||||
(paramstart == parameters.size() - 1) && member.isVarArgs(), htmltree);
|
(paramstart == parameters.size() - 1) && member.isVarArgs(), paramTree);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = paramstart + 1; i < parameters.size(); i++) {
|
for (int i = paramstart + 1; i < parameters.size(); i++) {
|
||||||
htmltree.addContent(",");
|
paramTree.addContent(",");
|
||||||
htmltree.addContent(DocletConstants.NL);
|
paramTree.addContent(DocletConstants.NL);
|
||||||
htmltree.addContent(indent);
|
paramTree.addContent(indent);
|
||||||
if (includeAnnotations) {
|
if (includeAnnotations) {
|
||||||
boolean foundAnnotations =
|
boolean foundAnnotations =
|
||||||
writer.addAnnotationInfo(indent.length(), member, parameters.get(i),
|
writer.addAnnotationInfo(indent.length(), member, parameters.get(i),
|
||||||
htmltree);
|
paramTree);
|
||||||
if (foundAnnotations) {
|
if (foundAnnotations) {
|
||||||
htmltree.addContent(DocletConstants.NL);
|
paramTree.addContent(DocletConstants.NL);
|
||||||
htmltree.addContent(indent);
|
paramTree.addContent(indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addParam(member, parameters.get(i), (i == parameters.size() - 1) && member.isVarArgs(),
|
addParam(member, parameters.get(i), (i == parameters.size() - 1) && member.isVarArgs(),
|
||||||
htmltree);
|
paramTree);
|
||||||
|
}
|
||||||
|
if (paramTree.isEmpty()) {
|
||||||
|
htmltree.addContent("()");
|
||||||
|
} else {
|
||||||
|
htmltree.addContent(Contents.ZERO_WIDTH_SPACE);
|
||||||
|
htmltree.addContent("(");
|
||||||
|
htmltree.addContent(paramTree);
|
||||||
|
paramTree.addContent(")");
|
||||||
}
|
}
|
||||||
htmltree.addContent(")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -364,7 +364,7 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
|
||||||
List<? extends DocTree> tags;
|
List<? extends DocTree> tags;
|
||||||
Content span = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(element));
|
Content span = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(element));
|
||||||
HtmlTree div = new HtmlTree(HtmlTag.DIV);
|
HtmlTree div = new HtmlTree(HtmlTag.DIV);
|
||||||
div.addStyle(HtmlStyle.block);
|
div.addStyle(HtmlStyle.deprecationBlock);
|
||||||
if (utils.isDeprecated(element)) {
|
if (utils.isDeprecated(element)) {
|
||||||
div.addContent(span);
|
div.addContent(span);
|
||||||
tags = utils.getBlockTags(element, DocTree.Kind.DEPRECATED);
|
tags = utils.getBlockTags(element, DocTree.Kind.DEPRECATED);
|
||||||
|
|
|
@ -355,7 +355,7 @@ public abstract class AbstractMemberWriter {
|
||||||
writer.getTagletWriterInstance(false));
|
writer.getTagletWriterInstance(false));
|
||||||
if (!output.isEmpty()) {
|
if (!output.isEmpty()) {
|
||||||
Content deprecatedContent = output;
|
Content deprecatedContent = output;
|
||||||
Content div = HtmlTree.DIV(HtmlStyle.block, deprecatedContent);
|
Content div = HtmlTree.DIV(HtmlStyle.deprecationBlock, deprecatedContent);
|
||||||
contentTree.addContent(div);
|
contentTree.addContent(div);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,7 +278,8 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addAnnotationTypeSignature(String modifiers, Content annotationInfoTree) {
|
public void addAnnotationTypeSignature(String modifiers, Content annotationInfoTree) {
|
||||||
annotationInfoTree.addContent(new HtmlTree(HtmlTag.BR));
|
Content hr = new HtmlTree(HtmlTag.HR);
|
||||||
|
annotationInfoTree.addContent(hr);
|
||||||
Content pre = new HtmlTree(HtmlTag.PRE);
|
Content pre = new HtmlTree(HtmlTag.PRE);
|
||||||
addAnnotationInfo(annotationType, pre);
|
addAnnotationInfo(annotationType, pre);
|
||||||
pre.addContent(modifiers);
|
pre.addContent(modifiers);
|
||||||
|
@ -324,18 +325,15 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addAnnotationTypeDeprecationInfo(Content annotationInfoTree) {
|
public void addAnnotationTypeDeprecationInfo(Content annotationInfoTree) {
|
||||||
Content hr = new HtmlTree(HtmlTag.HR);
|
|
||||||
annotationInfoTree.addContent(hr);
|
|
||||||
List<? extends DocTree> deprs = utils.getBlockTags(annotationType, DocTree.Kind.DEPRECATED);
|
List<? extends DocTree> deprs = utils.getBlockTags(annotationType, DocTree.Kind.DEPRECATED);
|
||||||
if (utils.isDeprecated(annotationType)) {
|
if (utils.isDeprecated(annotationType)) {
|
||||||
CommentHelper ch = utils.getCommentHelper(annotationType);
|
CommentHelper ch = utils.getCommentHelper(annotationType);
|
||||||
Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(annotationType));
|
Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(annotationType));
|
||||||
Content div = HtmlTree.DIV(HtmlStyle.block, deprLabel);
|
Content div = HtmlTree.DIV(HtmlStyle.deprecationBlock, deprLabel);
|
||||||
if (!deprs.isEmpty()) {
|
if (!deprs.isEmpty()) {
|
||||||
|
|
||||||
List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
|
List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
|
||||||
if (!commentTags.isEmpty()) {
|
if (!commentTags.isEmpty()) {
|
||||||
div.addContent(Contents.SPACE);
|
|
||||||
addInlineDeprecatedComment(annotationType, deprs.get(0), div);
|
addInlineDeprecatedComment(annotationType, deprs.get(0), div);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -293,7 +293,8 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addClassSignature(String modifiers, Content classInfoTree) {
|
public void addClassSignature(String modifiers, Content classInfoTree) {
|
||||||
classInfoTree.addContent(new HtmlTree(HtmlTag.BR));
|
Content hr = new HtmlTree(HtmlTag.HR);
|
||||||
|
classInfoTree.addContent(hr);
|
||||||
Content pre = new HtmlTree(HtmlTag.PRE);
|
Content pre = new HtmlTree(HtmlTag.PRE);
|
||||||
addAnnotationInfo(typeElement, pre);
|
addAnnotationInfo(typeElement, pre);
|
||||||
pre.addContent(modifiers);
|
pre.addContent(modifiers);
|
||||||
|
@ -606,18 +607,15 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addClassDeprecationInfo(Content classInfoTree) {
|
public void addClassDeprecationInfo(Content classInfoTree) {
|
||||||
Content hr = new HtmlTree(HtmlTag.HR);
|
|
||||||
classInfoTree.addContent(hr);
|
|
||||||
List<? extends DocTree> deprs = utils.getBlockTags(typeElement, DocTree.Kind.DEPRECATED);
|
List<? extends DocTree> deprs = utils.getBlockTags(typeElement, DocTree.Kind.DEPRECATED);
|
||||||
if (utils.isDeprecated(typeElement)) {
|
if (utils.isDeprecated(typeElement)) {
|
||||||
Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(typeElement));
|
Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(typeElement));
|
||||||
Content div = HtmlTree.DIV(HtmlStyle.block, deprLabel);
|
Content div = HtmlTree.DIV(HtmlStyle.deprecationBlock, deprLabel);
|
||||||
if (!deprs.isEmpty()) {
|
if (!deprs.isEmpty()) {
|
||||||
CommentHelper ch = utils.getCommentHelper(typeElement);
|
CommentHelper ch = utils.getCommentHelper(typeElement);
|
||||||
DocTree dt = deprs.get(0);
|
DocTree dt = deprs.get(0);
|
||||||
List<? extends DocTree> commentTags = ch.getBody(configuration, dt);
|
List<? extends DocTree> commentTags = ch.getBody(configuration, dt);
|
||||||
if (!commentTags.isEmpty()) {
|
if (!commentTags.isEmpty()) {
|
||||||
div.addContent(Contents.SPACE);
|
|
||||||
addInlineDeprecatedComment(typeElement, deprs.get(0), div);
|
addInlineDeprecatedComment(typeElement, deprs.get(0), div);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,33 +100,33 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
|
||||||
private String getHeadingKey(DeprElementKind kind) {
|
private String getHeadingKey(DeprElementKind kind) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case REMOVAL:
|
case REMOVAL:
|
||||||
return "doclet.Deprecated_For_Removal";
|
return "doclet.For_Removal";
|
||||||
case MODULE:
|
case MODULE:
|
||||||
return "doclet.Deprecated_Modules";
|
return "doclet.Modules";
|
||||||
case PACKAGE:
|
case PACKAGE:
|
||||||
return "doclet.Deprecated_Packages";
|
return "doclet.Packages";
|
||||||
case INTERFACE:
|
case INTERFACE:
|
||||||
return "doclet.Deprecated_Interfaces";
|
return "doclet.Interfaces";
|
||||||
case CLASS:
|
case CLASS:
|
||||||
return "doclet.Deprecated_Classes";
|
return "doclet.Classes";
|
||||||
case ENUM:
|
case ENUM:
|
||||||
return "doclet.Deprecated_Enums";
|
return "doclet.Enums";
|
||||||
case EXCEPTION:
|
case EXCEPTION:
|
||||||
return "doclet.Deprecated_Exceptions";
|
return "doclet.Exceptions";
|
||||||
case ERROR:
|
case ERROR:
|
||||||
return "doclet.Deprecated_Errors";
|
return "doclet.Errors";
|
||||||
case ANNOTATION_TYPE:
|
case ANNOTATION_TYPE:
|
||||||
return "doclet.Deprecated_Annotation_Types";
|
return "doclet.Annotation_Types";
|
||||||
case FIELD:
|
case FIELD:
|
||||||
return "doclet.Deprecated_Fields";
|
return "doclet.Fields";
|
||||||
case METHOD:
|
case METHOD:
|
||||||
return "doclet.Deprecated_Methods";
|
return "doclet.Methods";
|
||||||
case CONSTRUCTOR:
|
case CONSTRUCTOR:
|
||||||
return "doclet.Deprecated_Constructors";
|
return "doclet.Constructors";
|
||||||
case ENUM_CONSTANT:
|
case ENUM_CONSTANT:
|
||||||
return "doclet.Deprecated_Enum_Constants";
|
return "doclet.Enum_Constants";
|
||||||
case ANNOTATION_TYPE_MEMBER:
|
case ANNOTATION_TYPE_MEMBER:
|
||||||
return "doclet.Deprecated_Annotation_Type_Members";
|
return "doclet.Annotation_Type_Members";
|
||||||
default:
|
default:
|
||||||
throw new AssertionError("unknown kind: " + kind);
|
throw new AssertionError("unknown kind: " + kind);
|
||||||
}
|
}
|
||||||
|
@ -135,33 +135,33 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
|
||||||
private String getSummaryKey(DeprElementKind kind) {
|
private String getSummaryKey(DeprElementKind kind) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case REMOVAL:
|
case REMOVAL:
|
||||||
return "doclet.deprecated_for_removal";
|
return "doclet.for_removal";
|
||||||
case MODULE:
|
case MODULE:
|
||||||
return "doclet.deprecated_modules";
|
return "doclet.modules";
|
||||||
case PACKAGE:
|
case PACKAGE:
|
||||||
return "doclet.deprecated_packages";
|
return "doclet.packages";
|
||||||
case INTERFACE:
|
case INTERFACE:
|
||||||
return "doclet.deprecated_interfaces";
|
return "doclet.interfaces";
|
||||||
case CLASS:
|
case CLASS:
|
||||||
return "doclet.deprecated_classes";
|
return "doclet.classes";
|
||||||
case ENUM:
|
case ENUM:
|
||||||
return "doclet.deprecated_enums";
|
return "doclet.enums";
|
||||||
case EXCEPTION:
|
case EXCEPTION:
|
||||||
return "doclet.deprecated_exceptions";
|
return "doclet.exceptions";
|
||||||
case ERROR:
|
case ERROR:
|
||||||
return "doclet.deprecated_errors";
|
return "doclet.errors";
|
||||||
case ANNOTATION_TYPE:
|
case ANNOTATION_TYPE:
|
||||||
return "doclet.deprecated_annotation_types";
|
return "doclet.annotation_types";
|
||||||
case FIELD:
|
case FIELD:
|
||||||
return "doclet.deprecated_fields";
|
return "doclet.fields";
|
||||||
case METHOD:
|
case METHOD:
|
||||||
return "doclet.deprecated_methods";
|
return "doclet.methods";
|
||||||
case CONSTRUCTOR:
|
case CONSTRUCTOR:
|
||||||
return "doclet.deprecated_constructors";
|
return "doclet.constructors";
|
||||||
case ENUM_CONSTANT:
|
case ENUM_CONSTANT:
|
||||||
return "doclet.deprecated_enum_constants";
|
return "doclet.enum_constants";
|
||||||
case ANNOTATION_TYPE_MEMBER:
|
case ANNOTATION_TYPE_MEMBER:
|
||||||
return "doclet.deprecated_annotation_type_members";
|
return "doclet.annotation_type_members";
|
||||||
default:
|
default:
|
||||||
throw new AssertionError("unknown kind: " + kind);
|
throw new AssertionError("unknown kind: " + kind);
|
||||||
}
|
}
|
||||||
|
@ -473,6 +473,6 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
|
||||||
default:
|
default:
|
||||||
writer = new AnnotationTypeOptionalMemberWriterImpl(this, null);
|
writer = new AnnotationTypeOptionalMemberWriterImpl(this, null);
|
||||||
}
|
}
|
||||||
return HtmlTree.TH_ROW_SCOPE(HtmlStyle.colFirst, writer.getDeprecatedLink(e));
|
return HtmlTree.TH_ROW_SCOPE(HtmlStyle.colDeprecatedItemName, writer.getDeprecatedLink(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1715,8 +1715,7 @@ public class HtmlDocletWriter extends HtmlDocWriter {
|
||||||
Content div;
|
Content div;
|
||||||
Content result = commentTagsToContent(null, element, tags, first);
|
Content result = commentTagsToContent(null, element, tags, first);
|
||||||
if (depr) {
|
if (depr) {
|
||||||
Content italic = HtmlTree.SPAN(HtmlStyle.deprecationComment, result);
|
div = HtmlTree.DIV(HtmlStyle.deprecationComment, result);
|
||||||
div = HtmlTree.DIV(HtmlStyle.block, italic);
|
|
||||||
htmltree.addContent(div);
|
htmltree.addContent(div);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -929,7 +929,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||||
if (utils.isDeprecated(mdle)) {
|
if (utils.isDeprecated(mdle)) {
|
||||||
CommentHelper ch = utils.getCommentHelper(mdle);
|
CommentHelper ch = utils.getCommentHelper(mdle);
|
||||||
HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
|
HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
|
||||||
deprDiv.addStyle(HtmlStyle.deprecatedContent);
|
deprDiv.addStyle(HtmlStyle.deprecationBlock);
|
||||||
Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(mdle));
|
Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(mdle));
|
||||||
deprDiv.addContent(deprPhrase);
|
deprDiv.addContent(deprPhrase);
|
||||||
if (!deprs.isEmpty()) {
|
if (!deprs.isEmpty()) {
|
||||||
|
@ -1064,7 +1064,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||||
if (utils.isDeprecated(pkg)) {
|
if (utils.isDeprecated(pkg)) {
|
||||||
deprs = utils.getDeprecatedTrees(pkg);
|
deprs = utils.getDeprecatedTrees(pkg);
|
||||||
HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
|
HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
|
||||||
deprDiv.addStyle(HtmlStyle.deprecatedContent);
|
deprDiv.addStyle(HtmlStyle.deprecationBlock);
|
||||||
Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(pkg));
|
Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(pkg));
|
||||||
deprDiv.addContent(deprPhrase);
|
deprDiv.addContent(deprPhrase);
|
||||||
if (!deprs.isEmpty()) {
|
if (!deprs.isEmpty()) {
|
||||||
|
|
|
@ -171,7 +171,7 @@ public class PackageWriterImpl extends HtmlDocletWriter
|
||||||
if (utils.isDeprecated(packageElement)) {
|
if (utils.isDeprecated(packageElement)) {
|
||||||
CommentHelper ch = utils.getCommentHelper(packageElement);
|
CommentHelper ch = utils.getCommentHelper(packageElement);
|
||||||
HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
|
HtmlTree deprDiv = new HtmlTree(HtmlTag.DIV);
|
||||||
deprDiv.addStyle(HtmlStyle.deprecatedContent);
|
deprDiv.addStyle(HtmlStyle.deprecationBlock);
|
||||||
Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(packageElement));
|
Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(packageElement));
|
||||||
deprDiv.addContent(deprPhrase);
|
deprDiv.addContent(deprPhrase);
|
||||||
if (!deprs.isEmpty()) {
|
if (!deprs.isEmpty()) {
|
||||||
|
|
|
@ -189,9 +189,8 @@ public abstract class SubWriterHolderWriter extends HtmlDocletWriter {
|
||||||
if (utils.isDeprecated(member)) {
|
if (utils.isDeprecated(member)) {
|
||||||
Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(member));
|
Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(member));
|
||||||
div = HtmlTree.DIV(HtmlStyle.block, deprLabel);
|
div = HtmlTree.DIV(HtmlStyle.block, deprLabel);
|
||||||
div.addContent(Contents.SPACE);
|
|
||||||
if (!deprs.isEmpty()) {
|
if (!deprs.isEmpty()) {
|
||||||
addInlineDeprecatedComment(member, deprs.get(0), div);
|
addSummaryDeprecatedComment(member, deprs.get(0), div);
|
||||||
}
|
}
|
||||||
tdSummary.addContent(div);
|
tdSummary.addContent(div);
|
||||||
return;
|
return;
|
||||||
|
@ -200,7 +199,6 @@ public abstract class SubWriterHolderWriter extends HtmlDocletWriter {
|
||||||
if (te != null && utils.isTypeElement(te) && utils.isDeprecated(te)) {
|
if (te != null && utils.isTypeElement(te) && utils.isDeprecated(te)) {
|
||||||
Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(te));
|
Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(te));
|
||||||
div = HtmlTree.DIV(HtmlStyle.block, deprLabel);
|
div = HtmlTree.DIV(HtmlStyle.block, deprLabel);
|
||||||
div.addContent(Contents.SPACE);
|
|
||||||
tdSummary.addContent(div);
|
tdSummary.addContent(div);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,6 @@ public class TagletWriterImpl extends TagletWriter {
|
||||||
if (utils.isDeprecated(element)) {
|
if (utils.isDeprecated(element)) {
|
||||||
result.addContent(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
|
result.addContent(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
|
||||||
htmlWriter.getDeprecatedPhrase(element)));
|
htmlWriter.getDeprecatedPhrase(element)));
|
||||||
result.addContent(RawHtml.nbsp);
|
|
||||||
if (!deprs.isEmpty()) {
|
if (!deprs.isEmpty()) {
|
||||||
List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
|
List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
|
||||||
if (!commentTags.isEmpty()) {
|
if (!commentTags.isEmpty()) {
|
||||||
|
@ -191,19 +190,17 @@ public class TagletWriterImpl extends TagletWriter {
|
||||||
if (utils.isDeprecated(element)) {
|
if (utils.isDeprecated(element)) {
|
||||||
result.addContent(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
|
result.addContent(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
|
||||||
htmlWriter.getDeprecatedPhrase(element)));
|
htmlWriter.getDeprecatedPhrase(element)));
|
||||||
result.addContent(RawHtml.nbsp);
|
|
||||||
if (!deprs.isEmpty()) {
|
if (!deprs.isEmpty()) {
|
||||||
List<? extends DocTree> bodyTags = ch.getBody(configuration, deprs.get(0));
|
List<? extends DocTree> bodyTags = ch.getBody(configuration, deprs.get(0));
|
||||||
Content body = commentTagsToOutput(null, element, bodyTags, false);
|
Content body = commentTagsToOutput(null, element, bodyTags, false);
|
||||||
if (!body.isEmpty())
|
if (!body.isEmpty())
|
||||||
result.addContent(HtmlTree.SPAN(HtmlStyle.deprecationComment, body));
|
result.addContent(HtmlTree.DIV(HtmlStyle.deprecationComment, body));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Element ee = utils.getEnclosingTypeElement(element);
|
Element ee = utils.getEnclosingTypeElement(element);
|
||||||
if (utils.isDeprecated(ee)) {
|
if (utils.isDeprecated(ee)) {
|
||||||
result.addContent(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
|
result.addContent(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
|
||||||
htmlWriter.getDeprecatedPhrase(ee)));
|
htmlWriter.getDeprecatedPhrase(ee)));
|
||||||
result.addContent(RawHtml.nbsp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,15 +47,16 @@ public enum HtmlStyle {
|
||||||
circle,
|
circle,
|
||||||
classUseContainer,
|
classUseContainer,
|
||||||
colConstructorName,
|
colConstructorName,
|
||||||
|
colDeprecatedItemName,
|
||||||
colFirst,
|
colFirst,
|
||||||
colLast,
|
colLast,
|
||||||
colSecond,
|
colSecond,
|
||||||
constantsSummary,
|
constantsSummary,
|
||||||
constantValuesContainer,
|
constantValuesContainer,
|
||||||
contentContainer,
|
contentContainer,
|
||||||
deprecatedContent,
|
|
||||||
deprecatedLabel,
|
deprecatedLabel,
|
||||||
deprecatedSummary,
|
deprecatedSummary,
|
||||||
|
deprecationBlock,
|
||||||
deprecationComment,
|
deprecationComment,
|
||||||
description,
|
description,
|
||||||
descfrmTypeLabel,
|
descfrmTypeLabel,
|
||||||
|
|
|
@ -74,34 +74,12 @@ doclet.see.class_or_package_not_found=Tag {0}: reference not found: {1}
|
||||||
doclet.see.class_or_package_not_accessible=Tag {0}: reference not accessible: {1}
|
doclet.see.class_or_package_not_accessible=Tag {0}: reference not accessible: {1}
|
||||||
doclet.tag.invalid_usage=invalid usage of tag {0}
|
doclet.tag.invalid_usage=invalid usage of tag {0}
|
||||||
doclet.Deprecated_API=Deprecated API
|
doclet.Deprecated_API=Deprecated API
|
||||||
doclet.Deprecated_For_Removal=Deprecated For Removal
|
doclet.For_Removal=For Removal
|
||||||
doclet.Deprecated_Modules=Deprecated Modules
|
doclet.Annotation_Types=Annotation Types
|
||||||
doclet.Deprecated_Packages=Deprecated Packages
|
doclet.Annotation_Type_Members=Annotation Type Elements
|
||||||
doclet.Deprecated_Classes=Deprecated Classes
|
doclet.for_removal=for removal
|
||||||
doclet.Deprecated_Enums=Deprecated Enums
|
doclet.annotation_types=annotation types
|
||||||
doclet.Deprecated_Interfaces=Deprecated Interfaces
|
doclet.annotation_type_members=annotation type elements
|
||||||
doclet.Deprecated_Exceptions=Deprecated Exceptions
|
|
||||||
doclet.Deprecated_Annotation_Types=Deprecated Annotation Types
|
|
||||||
doclet.Deprecated_Errors=Deprecated Errors
|
|
||||||
doclet.Deprecated_Fields=Deprecated Fields
|
|
||||||
doclet.Deprecated_Constructors=Deprecated Constructors
|
|
||||||
doclet.Deprecated_Methods=Deprecated Methods
|
|
||||||
doclet.Deprecated_Enum_Constants=Deprecated Enum Constants
|
|
||||||
doclet.Deprecated_Annotation_Type_Members=Deprecated Annotation Type Elements
|
|
||||||
doclet.deprecated_for_removal=deprecated for removal
|
|
||||||
doclet.deprecated_modules=deprecated modules
|
|
||||||
doclet.deprecated_packages=deprecated packages
|
|
||||||
doclet.deprecated_classes=deprecated classes
|
|
||||||
doclet.deprecated_enums=deprecated enums
|
|
||||||
doclet.deprecated_interfaces=deprecated interfaces
|
|
||||||
doclet.deprecated_exceptions=deprecated exceptions
|
|
||||||
doclet.deprecated_annotation_types=deprecated annotation types
|
|
||||||
doclet.deprecated_errors=deprecated errors
|
|
||||||
doclet.deprecated_fields=deprecated fields
|
|
||||||
doclet.deprecated_constructors=deprecated constructors
|
|
||||||
doclet.deprecated_methods=deprecated methods
|
|
||||||
doclet.deprecated_enum_constants=deprecated enum constants
|
|
||||||
doclet.deprecated_annotation_type_members=deprecated annotation type elements
|
|
||||||
doclet.Generated_Docs_Untitled=Generated Documentation (Untitled)
|
doclet.Generated_Docs_Untitled=Generated Documentation (Untitled)
|
||||||
doclet.Other_Packages=Other Packages
|
doclet.Other_Packages=Other Packages
|
||||||
doclet.Description=Description
|
doclet.Description=Description
|
||||||
|
|
|
@ -147,8 +147,8 @@ public class AnnotationTypeBuilder extends AbstractBuilder {
|
||||||
throws DocletException {
|
throws DocletException {
|
||||||
Content annotationInfoTree = writer.getAnnotationInfoTreeHeader();
|
Content annotationInfoTree = writer.getAnnotationInfoTreeHeader();
|
||||||
|
|
||||||
buildDeprecationInfo(annotationInfoTree);
|
|
||||||
buildAnnotationTypeSignature(annotationInfoTree);
|
buildAnnotationTypeSignature(annotationInfoTree);
|
||||||
|
buildDeprecationInfo(annotationInfoTree);
|
||||||
buildAnnotationTypeDescription(annotationInfoTree);
|
buildAnnotationTypeDescription(annotationInfoTree);
|
||||||
buildAnnotationTypeTagInfo(annotationInfoTree);
|
buildAnnotationTypeTagInfo(annotationInfoTree);
|
||||||
|
|
||||||
|
|
|
@ -175,8 +175,8 @@ public class ClassBuilder extends AbstractBuilder {
|
||||||
buildInterfaceUsageInfo(classInfoTree);
|
buildInterfaceUsageInfo(classInfoTree);
|
||||||
buildNestedClassInfo(classInfoTree);
|
buildNestedClassInfo(classInfoTree);
|
||||||
buildFunctionalInterfaceInfo(classInfoTree);
|
buildFunctionalInterfaceInfo(classInfoTree);
|
||||||
buildDeprecationInfo(classInfoTree);
|
|
||||||
buildClassSignature(classInfoTree);
|
buildClassSignature(classInfoTree);
|
||||||
|
buildDeprecationInfo(classInfoTree);
|
||||||
buildClassDescription(classInfoTree);
|
buildClassDescription(classInfoTree);
|
||||||
buildClassTagInfo(classInfoTree);
|
buildClassTagInfo(classInfoTree);
|
||||||
|
|
||||||
|
|
|
@ -531,14 +531,16 @@ Table styles
|
||||||
text-align:left;
|
text-align:left;
|
||||||
padding:0px 0px 12px 10px;
|
padding:0px 0px 12px 10px;
|
||||||
}
|
}
|
||||||
th.colFirst, th.colSecond, th.colLast, th.colConstructorName, .useSummary th, .constantsSummary th, .packagesSummary th,
|
th.colFirst, th.colSecond, th.colLast, th.colConstructorName, th.colDeprecatedItemName, .useSummary th,
|
||||||
td.colFirst, td.colSecond, td.colLast, .useSummary td, .constantsSummary td {
|
.constantsSummary th, .packagesSummary th, td.colFirst, td.colSecond, td.colLast, .useSummary td,
|
||||||
|
.constantsSummary td {
|
||||||
vertical-align:top;
|
vertical-align:top;
|
||||||
padding-right:0px;
|
padding-right:0px;
|
||||||
padding-top:8px;
|
padding-top:8px;
|
||||||
padding-bottom:3px;
|
padding-bottom:3px;
|
||||||
}
|
}
|
||||||
th.colFirst, th.colSecond, th.colLast, th.colConstructorName, .constantsSummary th, .packagesSummary th {
|
th.colFirst, th.colSecond, th.colLast, th.colConstructorName, th.colDeprecatedItemName, .constantsSummary th,
|
||||||
|
.packagesSummary th {
|
||||||
background:#dee3e9;
|
background:#dee3e9;
|
||||||
text-align:left;
|
text-align:left;
|
||||||
padding:8px 3px 3px 7px;
|
padding:8px 3px 3px 7px;
|
||||||
|
@ -547,7 +549,7 @@ td.colFirst, th.colFirst {
|
||||||
white-space:nowrap;
|
white-space:nowrap;
|
||||||
font-size:13px;
|
font-size:13px;
|
||||||
}
|
}
|
||||||
td.colSecond, th.colSecond, td.colLast, th.colConstructorName, th.colLast {
|
td.colSecond, th.colSecond, td.colLast, th.colConstructorName, th.colDeprecatedItemName, th.colLast {
|
||||||
font-size:13px;
|
font-size:13px;
|
||||||
}
|
}
|
||||||
.constantsSummary th, .packagesSummary th {
|
.constantsSummary th, .packagesSummary th {
|
||||||
|
@ -576,6 +578,7 @@ td.colSecond a:link, td.colSecond a:visited,
|
||||||
th.colFirst a:link, th.colFirst a:visited,
|
th.colFirst a:link, th.colFirst a:visited,
|
||||||
th.colSecond a:link, th.colSecond a:visited,
|
th.colSecond a:link, th.colSecond a:visited,
|
||||||
th.colConstructorName a:link, th.colConstructorName a:visited,
|
th.colConstructorName a:link, th.colConstructorName a:visited,
|
||||||
|
th.colDeprecatedItemName a:link, th.colDeprecatedItemName a:visited,
|
||||||
.constantValuesContainer td a:link, .constantValuesContainer td a:visited {
|
.constantValuesContainer td a:link, .constantValuesContainer td a:visited {
|
||||||
font-weight:bold;
|
font-weight:bold;
|
||||||
}
|
}
|
||||||
|
@ -645,8 +648,19 @@ h1.hidden {
|
||||||
.deprecationComment, .emphasizedPhrase, .interfaceName {
|
.deprecationComment, .emphasizedPhrase, .interfaceName {
|
||||||
font-style:italic;
|
font-style:italic;
|
||||||
}
|
}
|
||||||
|
.deprecationBlock {
|
||||||
|
font-size:14px;
|
||||||
|
font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:thin;
|
||||||
|
border-radius:10px;
|
||||||
|
padding:10px;
|
||||||
|
margin-bottom:10px;
|
||||||
|
margin-right:10px;
|
||||||
|
display:inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase,
|
div.block div.deprecationComment, div.block div.block span.emphasizedPhrase,
|
||||||
div.block div.block span.interfaceName {
|
div.block div.block span.interfaceName {
|
||||||
font-style:normal;
|
font-style:normal;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ public class DeprecatedAPIListBuilder {
|
||||||
deprecatedMap = new EnumMap<>(DeprElementKind.class);
|
deprecatedMap = new EnumMap<>(DeprElementKind.class);
|
||||||
for (DeprElementKind kind : DeprElementKind.values()) {
|
for (DeprElementKind kind : DeprElementKind.values()) {
|
||||||
deprecatedMap.put(kind,
|
deprecatedMap.put(kind,
|
||||||
new TreeSet<>(utils.makeGeneralPurposeComparator()));
|
new TreeSet<>(utils.makeDeprecatedComparator()));
|
||||||
}
|
}
|
||||||
buildDeprecatedAPIInfo();
|
buildDeprecatedAPIInfo();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1733,6 +1733,25 @@ public class Utils {
|
||||||
return packageComparator;
|
return packageComparator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Comparator<Element> deprecatedComparator = null;
|
||||||
|
/**
|
||||||
|
* Returns a Comparator for deprecated items listed on deprecated list page, by comparing the
|
||||||
|
* fully qualified names.
|
||||||
|
*
|
||||||
|
* @return a Comparator
|
||||||
|
*/
|
||||||
|
public Comparator<Element> makeDeprecatedComparator() {
|
||||||
|
if (deprecatedComparator == null) {
|
||||||
|
deprecatedComparator = new Utils.ElementComparator() {
|
||||||
|
@Override
|
||||||
|
public int compare(Element e1, Element e2) {
|
||||||
|
return compareFullyQualifiedNames(e1, e2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return deprecatedComparator;
|
||||||
|
}
|
||||||
|
|
||||||
private Comparator<SerialFieldTree> serialFieldTreeComparator = null;
|
private Comparator<SerialFieldTree> serialFieldTreeComparator = null;
|
||||||
/**
|
/**
|
||||||
* Returns a Comparator for SerialFieldTree.
|
* Returns a Comparator for SerialFieldTree.
|
||||||
|
|
|
@ -234,49 +234,6 @@ class JdepsTask {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
new Option(true, CommandOption.CHECK_MODULES) {
|
|
||||||
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
|
||||||
if (task.command != null) {
|
|
||||||
throw new BadArgs("err.command.set", task.command, opt);
|
|
||||||
}
|
|
||||||
Set<String> mods = Set.of(arg.split(","));
|
|
||||||
task.options.addmods.addAll(mods);
|
|
||||||
task.command = task.checkModuleDeps(mods);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Option(true, CommandOption.GENERATE_MODULE_INFO) {
|
|
||||||
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
|
||||||
if (task.command != null) {
|
|
||||||
throw new BadArgs("err.command.set", task.command, opt);
|
|
||||||
}
|
|
||||||
task.command = task.genModuleInfo(Paths.get(arg), false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Option(true, CommandOption.GENERATE_OPEN_MODULE) {
|
|
||||||
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
|
||||||
if (task.command != null) {
|
|
||||||
throw new BadArgs("err.command.set", task.command, opt);
|
|
||||||
}
|
|
||||||
task.command = task.genModuleInfo(Paths.get(arg), true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Option(false, CommandOption.LIST_DEPS) {
|
|
||||||
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
|
||||||
if (task.command != null) {
|
|
||||||
throw new BadArgs("err.command.set", task.command, opt);
|
|
||||||
}
|
|
||||||
task.command = task.listModuleDeps(false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Option(false, CommandOption.LIST_REDUCED_DEPS) {
|
|
||||||
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
|
||||||
if (task.command != null) {
|
|
||||||
throw new BadArgs("err.command.set", task.command, opt);
|
|
||||||
}
|
|
||||||
task.command = task.listModuleDeps(true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// ---- paths option ----
|
// ---- paths option ----
|
||||||
new Option(true, "-cp", "-classpath", "--class-path") {
|
new Option(true, "-cp", "-classpath", "--class-path") {
|
||||||
void process(JdepsTask task, String opt, String arg) {
|
void process(JdepsTask task, String opt, String arg) {
|
||||||
|
@ -312,15 +269,6 @@ class JdepsTask {
|
||||||
task.options.addmods.addAll(mods);
|
task.options.addmods.addAll(mods);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Option(true, "-m", "--module") {
|
|
||||||
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
|
||||||
if (!task.options.rootModules.isEmpty()) {
|
|
||||||
throw new BadArgs("err.option.already.specified", opt);
|
|
||||||
}
|
|
||||||
task.options.rootModules.add(arg);
|
|
||||||
task.options.addmods.add(arg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new Option(true, "--multi-release") {
|
new Option(true, "--multi-release") {
|
||||||
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
||||||
if (arg.equalsIgnoreCase("base")) {
|
if (arg.equalsIgnoreCase("base")) {
|
||||||
|
@ -338,6 +286,70 @@ class JdepsTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
new Option(false, "-q", "-quiet") {
|
||||||
|
void process(JdepsTask task, String opt, String arg) {
|
||||||
|
task.options.nowarning = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Option(false, "-version", "--version") {
|
||||||
|
void process(JdepsTask task, String opt, String arg) {
|
||||||
|
task.options.version = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// ---- module-specific options ----
|
||||||
|
|
||||||
|
new Option(true, "-m", "--module") {
|
||||||
|
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
||||||
|
if (!task.options.rootModules.isEmpty()) {
|
||||||
|
throw new BadArgs("err.option.already.specified", opt);
|
||||||
|
}
|
||||||
|
task.options.rootModules.add(arg);
|
||||||
|
task.options.addmods.add(arg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Option(true, CommandOption.GENERATE_MODULE_INFO) {
|
||||||
|
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
||||||
|
if (task.command != null) {
|
||||||
|
throw new BadArgs("err.command.set", task.command, opt);
|
||||||
|
}
|
||||||
|
task.command = task.genModuleInfo(Paths.get(arg), false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Option(true, CommandOption.GENERATE_OPEN_MODULE) {
|
||||||
|
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
||||||
|
if (task.command != null) {
|
||||||
|
throw new BadArgs("err.command.set", task.command, opt);
|
||||||
|
}
|
||||||
|
task.command = task.genModuleInfo(Paths.get(arg), true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Option(true, CommandOption.CHECK_MODULES) {
|
||||||
|
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
||||||
|
if (task.command != null) {
|
||||||
|
throw new BadArgs("err.command.set", task.command, opt);
|
||||||
|
}
|
||||||
|
Set<String> mods = Set.of(arg.split(","));
|
||||||
|
task.options.addmods.addAll(mods);
|
||||||
|
task.command = task.checkModuleDeps(mods);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Option(false, CommandOption.LIST_DEPS) {
|
||||||
|
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
||||||
|
if (task.command != null) {
|
||||||
|
throw new BadArgs("err.command.set", task.command, opt);
|
||||||
|
}
|
||||||
|
task.command = task.listModuleDeps(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Option(false, CommandOption.LIST_REDUCED_DEPS) {
|
||||||
|
void process(JdepsTask task, String opt, String arg) throws BadArgs {
|
||||||
|
if (task.command != null) {
|
||||||
|
throw new BadArgs("err.command.set", task.command, opt);
|
||||||
|
}
|
||||||
|
task.command = task.listModuleDeps(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// ---- Target filtering options ----
|
// ---- Target filtering options ----
|
||||||
new Option(true, "-p", "-package", "--package") {
|
new Option(true, "-p", "-package", "--package") {
|
||||||
|
@ -424,17 +436,6 @@ class JdepsTask {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
new Option(false, "-q", "-quiet") {
|
|
||||||
void process(JdepsTask task, String opt, String arg) {
|
|
||||||
task.options.nowarning = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
new Option(false, "-version", "--version") {
|
|
||||||
void process(JdepsTask task, String opt, String arg) {
|
|
||||||
task.options.version = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new HiddenOption(false, "-fullversion") {
|
new HiddenOption(false, "-fullversion") {
|
||||||
void process(JdepsTask task, String opt, String arg) {
|
void process(JdepsTask task, String opt, String arg) {
|
||||||
task.options.fullVersion = true;
|
task.options.fullVersion = true;
|
||||||
|
|
|
@ -86,10 +86,6 @@ main.opt.add-modules=\
|
||||||
\ --add-modules <module-name>[,<module-name>...]\n\
|
\ --add-modules <module-name>[,<module-name>...]\n\
|
||||||
\ Adds modules to the root set for analysis
|
\ Adds modules to the root set for analysis
|
||||||
|
|
||||||
main.opt.m=\
|
|
||||||
\ -m <module-name>\n\
|
|
||||||
\ --module <module-name> Specify the root module for analysis
|
|
||||||
|
|
||||||
main.opt.R=\
|
main.opt.R=\
|
||||||
\ -R -recursive Recursively traverse all run-time dependences.\n\
|
\ -R -recursive Recursively traverse all run-time dependences.\n\
|
||||||
\ The -R option implies -filter:none. If -p,\n\
|
\ The -R option implies -filter:none. If -p,\n\
|
||||||
|
@ -121,6 +117,11 @@ main.opt.apionly=\
|
||||||
\ type, method parameter types, returned type,\n\
|
\ type, method parameter types, returned type,\n\
|
||||||
\ checked exception types etc.
|
\ checked exception types etc.
|
||||||
|
|
||||||
|
main.opt.m=\n\
|
||||||
|
\Module dependence analysis options:\n\
|
||||||
|
\ -m <module-name>\n\
|
||||||
|
\ --module <module-name> Specify the root module for analysis
|
||||||
|
|
||||||
main.opt.generate-module-info=\
|
main.opt.generate-module-info=\
|
||||||
\ --generate-module-info <dir> Generate module-info.java under the specified\n\
|
\ --generate-module-info <dir> Generate module-info.java under the specified\n\
|
||||||
\ directory. The specified JAR files will be\n\
|
\ directory. The specified JAR files will be\n\
|
||||||
|
@ -142,7 +143,6 @@ main.opt.check=\
|
||||||
\ graph after transition reduction. It also\n\
|
\ graph after transition reduction. It also\n\
|
||||||
\ identifies any unused qualified exports.
|
\ identifies any unused qualified exports.
|
||||||
|
|
||||||
|
|
||||||
main.opt.dotoutput=\
|
main.opt.dotoutput=\
|
||||||
\ -dotoutput <dir>\n\
|
\ -dotoutput <dir>\n\
|
||||||
\ --dot-output <dir> Destination directory for DOT file output
|
\ --dot-output <dir> Destination directory for DOT file output
|
||||||
|
@ -157,15 +157,15 @@ main.opt.jdkinternals=\
|
||||||
\ WARNING: JDK internal APIs are inaccessible.
|
\ WARNING: JDK internal APIs are inaccessible.
|
||||||
|
|
||||||
main.opt.list-deps=\
|
main.opt.list-deps=\
|
||||||
\ --list-deps Lists the dependences and use of JDK internal\n\
|
\ --list-deps Lists the module dependences and also the\n\
|
||||||
\ APIs.
|
\ package names of JDK internal APIs if referenced.
|
||||||
|
|
||||||
main.opt.list-reduced-deps=\
|
main.opt.list-reduced-deps=\
|
||||||
\ --list-reduced-deps Same as --list-deps with not listing\n\
|
\ --list-reduced-deps Same as --list-deps with not listing\n\
|
||||||
\ the implied reads edges from the module graph\n\
|
\ the implied reads edges from the module graph\n\
|
||||||
\ If module M1 depends on M2 and M3,\n\
|
\ If module M1 reads M2, and M2 requires\n\
|
||||||
\ M2 requires public on M3, then M1 reading M3 is\n\
|
\ transitive on M3, then M1 reading M3 is implied\n\
|
||||||
\ implied and removed from the module graph.
|
\ and is not shown in the graph.
|
||||||
|
|
||||||
main.opt.depth=\
|
main.opt.depth=\
|
||||||
\ -depth=<depth> Specify the depth of the transitive\n\
|
\ -depth=<depth> Specify the depth of the transitive\n\
|
||||||
|
|
|
@ -40,6 +40,7 @@ import com.sun.source.tree.ExpressionTree;
|
||||||
import com.sun.source.tree.IdentifierTree;
|
import com.sun.source.tree.IdentifierTree;
|
||||||
import com.sun.source.tree.MethodTree;
|
import com.sun.source.tree.MethodTree;
|
||||||
import com.sun.source.tree.ModifiersTree;
|
import com.sun.source.tree.ModifiersTree;
|
||||||
|
import com.sun.source.tree.NewClassTree;
|
||||||
import com.sun.source.tree.Tree;
|
import com.sun.source.tree.Tree;
|
||||||
import com.sun.source.tree.VariableTree;
|
import com.sun.source.tree.VariableTree;
|
||||||
import com.sun.tools.javac.tree.JCTree;
|
import com.sun.tools.javac.tree.JCTree;
|
||||||
|
@ -59,6 +60,7 @@ import jdk.jshell.TaskFactory.AnalyzeTask;
|
||||||
import jdk.jshell.TaskFactory.BaseTask;
|
import jdk.jshell.TaskFactory.BaseTask;
|
||||||
import jdk.jshell.TaskFactory.CompileTask;
|
import jdk.jshell.TaskFactory.CompileTask;
|
||||||
import jdk.jshell.TaskFactory.ParseTask;
|
import jdk.jshell.TaskFactory.ParseTask;
|
||||||
|
import jdk.jshell.Wrap.CompoundWrap;
|
||||||
import jdk.jshell.Wrap.Range;
|
import jdk.jshell.Wrap.Range;
|
||||||
import jdk.jshell.Snippet.Status;
|
import jdk.jshell.Snippet.Status;
|
||||||
import jdk.jshell.spi.ExecutionControl.ClassBytecodes;
|
import jdk.jshell.spi.ExecutionControl.ClassBytecodes;
|
||||||
|
@ -274,26 +276,119 @@ class Eval {
|
||||||
for (Tree unitTree : units) {
|
for (Tree unitTree : units) {
|
||||||
VariableTree vt = (VariableTree) unitTree;
|
VariableTree vt = (VariableTree) unitTree;
|
||||||
String name = vt.getName().toString();
|
String name = vt.getName().toString();
|
||||||
String typeName = EvalPretty.prettyExpr((JCTree) vt.getType(), false);
|
String typeName;
|
||||||
Tree baseType = vt.getType();
|
String fullTypeName;
|
||||||
TreeDependencyScanner tds = new TreeDependencyScanner();
|
TreeDependencyScanner tds = new TreeDependencyScanner();
|
||||||
tds.scan(baseType); // Not dependent on initializer
|
Wrap typeWrap;
|
||||||
|
Wrap anonDeclareWrap = null;
|
||||||
|
Wrap winit = null;
|
||||||
StringBuilder sbBrackets = new StringBuilder();
|
StringBuilder sbBrackets = new StringBuilder();
|
||||||
while (baseType instanceof ArrayTypeTree) {
|
Tree baseType = vt.getType();
|
||||||
//TODO handle annotations too
|
if (baseType != null) {
|
||||||
baseType = ((ArrayTypeTree) baseType).getType();
|
tds.scan(baseType); // Not dependent on initializer
|
||||||
sbBrackets.append("[]");
|
fullTypeName = typeName = EvalPretty.prettyExpr((JCTree) vt.getType(), false);
|
||||||
|
while (baseType instanceof ArrayTypeTree) {
|
||||||
|
//TODO handle annotations too
|
||||||
|
baseType = ((ArrayTypeTree) baseType).getType();
|
||||||
|
sbBrackets.append("[]");
|
||||||
|
}
|
||||||
|
Range rtype = dis.treeToRange(baseType);
|
||||||
|
typeWrap = Wrap.rangeWrap(compileSource, rtype);
|
||||||
|
} else {
|
||||||
|
Tree init = vt.getInitializer();
|
||||||
|
if (init != null) {
|
||||||
|
Range rinit = dis.treeToRange(init);
|
||||||
|
String initCode = rinit.part(compileSource);
|
||||||
|
ExpressionInfo ei =
|
||||||
|
ExpressionToTypeInfo.localVariableTypeForInitializer(initCode, state);
|
||||||
|
typeName = ei == null ? "java.lang.Object" : ei.typeName;
|
||||||
|
fullTypeName = ei == null ? "java.lang.Object" : ei.fullTypeName;
|
||||||
|
if (ei != null && init.getKind() == Tree.Kind.NEW_CLASS &&
|
||||||
|
((NewClassTree) init).getClassBody() != null) {
|
||||||
|
NewClassTree nct = (NewClassTree) init;
|
||||||
|
StringBuilder constructor = new StringBuilder();
|
||||||
|
constructor.append(fullTypeName).append("(");
|
||||||
|
String sep = "";
|
||||||
|
if (ei.enclosingInstanceType != null) {
|
||||||
|
constructor.append(ei.enclosingInstanceType);
|
||||||
|
constructor.append(" encl");
|
||||||
|
sep = ", ";
|
||||||
|
}
|
||||||
|
int idx = 0;
|
||||||
|
for (String type : ei.parameterTypes) {
|
||||||
|
constructor.append(sep);
|
||||||
|
constructor.append(type);
|
||||||
|
constructor.append(" ");
|
||||||
|
constructor.append("arg" + idx++);
|
||||||
|
sep = ", ";
|
||||||
|
}
|
||||||
|
if (ei.enclosingInstanceType != null) {
|
||||||
|
constructor.append(") { encl.super (");
|
||||||
|
} else {
|
||||||
|
constructor.append(") { super (");
|
||||||
|
}
|
||||||
|
sep = "";
|
||||||
|
for (int i = 0; i < idx; i++) {
|
||||||
|
constructor.append(sep);
|
||||||
|
constructor.append("arg" + i++);
|
||||||
|
sep = ", ";
|
||||||
|
}
|
||||||
|
constructor.append("); }");
|
||||||
|
List<? extends Tree> members = nct.getClassBody().getMembers();
|
||||||
|
Range bodyRange = dis.treeListToRange(members);
|
||||||
|
Wrap bodyWrap;
|
||||||
|
|
||||||
|
if (bodyRange != null) {
|
||||||
|
bodyWrap = Wrap.rangeWrap(compileSource, bodyRange);
|
||||||
|
} else {
|
||||||
|
bodyWrap = Wrap.simpleWrap(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
Range argRange = dis.treeListToRange(nct.getArguments());
|
||||||
|
Wrap argWrap;
|
||||||
|
|
||||||
|
if (argRange != null) {
|
||||||
|
argWrap = Wrap.rangeWrap(compileSource, argRange);
|
||||||
|
} else {
|
||||||
|
argWrap = Wrap.simpleWrap(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ei.enclosingInstanceType != null) {
|
||||||
|
Range enclosingRanges =
|
||||||
|
dis.treeToRange(nct.getEnclosingExpression());
|
||||||
|
Wrap enclosingWrap = Wrap.rangeWrap(compileSource, enclosingRanges);
|
||||||
|
argWrap = argRange != null ? new CompoundWrap(enclosingWrap,
|
||||||
|
Wrap.simpleWrap(","),
|
||||||
|
argWrap)
|
||||||
|
: enclosingWrap;
|
||||||
|
}
|
||||||
|
Wrap hwrap = Wrap.simpleWrap("public static class " + fullTypeName +
|
||||||
|
(ei.isClass ? " extends " : " implements ") +
|
||||||
|
typeName + " { " + constructor);
|
||||||
|
anonDeclareWrap = new CompoundWrap(hwrap, bodyWrap, Wrap.simpleWrap("}"));
|
||||||
|
winit = new CompoundWrap("new " + fullTypeName + "(", argWrap, ")");
|
||||||
|
|
||||||
|
String superType = typeName;
|
||||||
|
|
||||||
|
typeName = fullTypeName;
|
||||||
|
fullTypeName = ei.isClass ? "<anonymous class extending " + superType + ">"
|
||||||
|
: "<anonymous class implementing " + superType + ">";
|
||||||
|
}
|
||||||
|
tds.scan(init);
|
||||||
|
} else {
|
||||||
|
fullTypeName = typeName = "java.lang.Object";
|
||||||
|
}
|
||||||
|
typeWrap = Wrap.identityWrap(typeName);
|
||||||
}
|
}
|
||||||
Range rtype = dis.treeToRange(baseType);
|
|
||||||
Range runit = dis.treeToRange(vt);
|
Range runit = dis.treeToRange(vt);
|
||||||
runit = new Range(runit.begin, runit.end - 1);
|
runit = new Range(runit.begin, runit.end - 1);
|
||||||
ExpressionTree it = vt.getInitializer();
|
ExpressionTree it = vt.getInitializer();
|
||||||
Range rinit = null;
|
|
||||||
int nameMax = runit.end - 1;
|
int nameMax = runit.end - 1;
|
||||||
SubKind subkind;
|
SubKind subkind;
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
subkind = SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND;
|
subkind = SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND;
|
||||||
rinit = dis.treeToRange(it);
|
Range rinit = dis.treeToRange(it);
|
||||||
|
winit = winit == null ? Wrap.rangeWrap(compileSource, rinit) : winit;
|
||||||
nameMax = rinit.begin - 1;
|
nameMax = rinit.begin - 1;
|
||||||
} else {
|
} else {
|
||||||
subkind = SubKind.VAR_DECLARATION_SUBKIND;
|
subkind = SubKind.VAR_DECLARATION_SUBKIND;
|
||||||
|
@ -304,10 +399,11 @@ class Eval {
|
||||||
}
|
}
|
||||||
int nameEnd = nameStart + name.length();
|
int nameEnd = nameStart + name.length();
|
||||||
Range rname = new Range(nameStart, nameEnd);
|
Range rname = new Range(nameStart, nameEnd);
|
||||||
Wrap guts = Wrap.varWrap(compileSource, rtype, sbBrackets.toString(), rname, rinit);
|
Wrap guts = Wrap.varWrap(compileSource, typeWrap, sbBrackets.toString(), rname,
|
||||||
DiagList modDiag = modifierDiagnostics(vt.getModifiers(), dis, true);
|
winit, anonDeclareWrap);
|
||||||
|
DiagList modDiag = modifierDiagnostics(vt.getModifiers(), dis, true);
|
||||||
Snippet snip = new VarSnippet(state.keyMap.keyForVariable(name), userSource, guts,
|
Snippet snip = new VarSnippet(state.keyMap.keyForVariable(name), userSource, guts,
|
||||||
name, subkind, typeName,
|
name, subkind, fullTypeName,
|
||||||
tds.declareReferences(), modDiag);
|
tds.declareReferences(), modDiag);
|
||||||
snippets.add(snip);
|
snippets.add(snip);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,14 +29,20 @@ import com.sun.source.tree.ReturnTree;
|
||||||
import com.sun.source.tree.ClassTree;
|
import com.sun.source.tree.ClassTree;
|
||||||
import com.sun.source.tree.CompilationUnitTree;
|
import com.sun.source.tree.CompilationUnitTree;
|
||||||
import com.sun.source.tree.ConditionalExpressionTree;
|
import com.sun.source.tree.ConditionalExpressionTree;
|
||||||
|
import com.sun.source.tree.ExpressionStatementTree;
|
||||||
import com.sun.source.tree.ExpressionTree;
|
import com.sun.source.tree.ExpressionTree;
|
||||||
|
import com.sun.source.tree.MethodInvocationTree;
|
||||||
import com.sun.source.tree.MethodTree;
|
import com.sun.source.tree.MethodTree;
|
||||||
|
import com.sun.source.tree.NewClassTree;
|
||||||
import com.sun.source.tree.Tree;
|
import com.sun.source.tree.Tree;
|
||||||
|
import com.sun.source.tree.Tree.Kind;
|
||||||
|
import com.sun.source.tree.VariableTree;
|
||||||
import com.sun.source.util.TreePath;
|
import com.sun.source.util.TreePath;
|
||||||
import com.sun.source.util.TreePathScanner;
|
import com.sun.source.util.TreePathScanner;
|
||||||
import com.sun.tools.javac.code.Symtab;
|
import com.sun.tools.javac.code.Symtab;
|
||||||
import com.sun.tools.javac.code.Type;
|
import com.sun.tools.javac.code.Type;
|
||||||
import com.sun.tools.javac.code.Types;
|
import com.sun.tools.javac.code.Types;
|
||||||
|
import com.sun.tools.javac.util.List;
|
||||||
import jdk.jshell.TaskFactory.AnalyzeTask;
|
import jdk.jshell.TaskFactory.AnalyzeTask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,6 +69,10 @@ class ExpressionToTypeInfo {
|
||||||
public static class ExpressionInfo {
|
public static class ExpressionInfo {
|
||||||
ExpressionTree tree;
|
ExpressionTree tree;
|
||||||
String typeName;
|
String typeName;
|
||||||
|
String fullTypeName;
|
||||||
|
List<String> parameterTypes;
|
||||||
|
String enclosingInstanceType;
|
||||||
|
boolean isClass;
|
||||||
boolean isNonVoid;
|
boolean isNonVoid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +121,16 @@ class ExpressionToTypeInfo {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TreePath visitVariable(VariableTree node, Boolean isTargetContext) {
|
||||||
|
if (isTargetContext) {
|
||||||
|
throw new Result(getCurrentPath());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type pathToType(TreePath tp) {
|
private Type pathToType(TreePath tp) {
|
||||||
|
@ -156,6 +176,30 @@ class ExpressionToTypeInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry method: get expression info corresponding to a local variable declaration if its type
|
||||||
|
* has been inferred automatically from the given initializer.
|
||||||
|
* @param code the initializer as a string
|
||||||
|
* @param state a JShell instance
|
||||||
|
* @return type information
|
||||||
|
*/
|
||||||
|
public static ExpressionInfo localVariableTypeForInitializer(String code, JShell state) {
|
||||||
|
if (code == null || code.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
OuterWrap codeWrap = state.outerMap.wrapInTrialClass(Wrap.methodWrap("var $$$ = " + code));
|
||||||
|
AnalyzeTask at = state.taskFactory.new AnalyzeTask(codeWrap);
|
||||||
|
CompilationUnitTree cu = at.firstCuTree();
|
||||||
|
if (at.hasErrors() || cu == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new ExpressionToTypeInfo(at, cu, state).typeOfExpression();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ExpressionInfo typeOfExpression() {
|
private ExpressionInfo typeOfExpression() {
|
||||||
return treeToInfo(findExpressionPath());
|
return treeToInfo(findExpressionPath());
|
||||||
}
|
}
|
||||||
|
@ -172,9 +216,11 @@ class ExpressionToTypeInfo {
|
||||||
private ExpressionInfo treeToInfo(TreePath tp) {
|
private ExpressionInfo treeToInfo(TreePath tp) {
|
||||||
if (tp != null) {
|
if (tp != null) {
|
||||||
Tree tree = tp.getLeaf();
|
Tree tree = tp.getLeaf();
|
||||||
if (tree instanceof ExpressionTree) {
|
boolean isExpression = tree instanceof ExpressionTree;
|
||||||
|
if (isExpression || tree.getKind() == Kind.VARIABLE) {
|
||||||
ExpressionInfo ei = new ExpressionInfo();
|
ExpressionInfo ei = new ExpressionInfo();
|
||||||
ei.tree = (ExpressionTree) tree;
|
if (isExpression)
|
||||||
|
ei.tree = (ExpressionTree) tree;
|
||||||
Type type = pathToType(tp, tree);
|
Type type = pathToType(tp, tree);
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
switch (type.getKind()) {
|
switch (type.getKind()) {
|
||||||
|
@ -189,27 +235,56 @@ class ExpressionToTypeInfo {
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
ei.isNonVoid = true;
|
ei.isNonVoid = true;
|
||||||
ei.typeName = varTypeName(type);
|
ei.typeName = varTypeName(type, false);
|
||||||
if (ei.typeName == null) {
|
ei.fullTypeName = varTypeName(type, true);
|
||||||
ei.typeName = OBJECT_TYPE_NAME;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (tree.getKind() == Tree.Kind.VARIABLE) {
|
||||||
|
Tree init = ((VariableTree) tree).getInitializer();
|
||||||
|
if (init.getKind() == Tree.Kind.NEW_CLASS &&
|
||||||
|
((NewClassTree) init).getClassBody() != null) {
|
||||||
|
NewClassTree nct = (NewClassTree) init;
|
||||||
|
ClassTree clazz = nct.getClassBody();
|
||||||
|
MethodTree constructor = (MethodTree) clazz.getMembers().get(0);
|
||||||
|
ExpressionStatementTree superCallStatement =
|
||||||
|
(ExpressionStatementTree) constructor.getBody().getStatements().get(0);
|
||||||
|
MethodInvocationTree superCall =
|
||||||
|
(MethodInvocationTree) superCallStatement.getExpression();
|
||||||
|
TreePath superCallPath =
|
||||||
|
at.trees().getPath(tp.getCompilationUnit(), superCall.getMethodSelect());
|
||||||
|
Type constrType = pathToType(superCallPath);
|
||||||
|
ei.parameterTypes = constrType.getParameterTypes()
|
||||||
|
.stream()
|
||||||
|
.map(t -> varTypeName(t, false))
|
||||||
|
.collect(List.collector());
|
||||||
|
if (nct.getEnclosingExpression() != null) {
|
||||||
|
TreePath enclPath = new TreePath(tp, nct.getEnclosingExpression());
|
||||||
|
ei.enclosingInstanceType = varTypeName(pathToType(enclPath), false);
|
||||||
|
}
|
||||||
|
ei.isClass = at.task.getTypes().directSupertypes(type).size() == 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
return ei;
|
return ei;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String varTypeName(Type type) {
|
private String varTypeName(Type type, boolean printIntersectionTypes) {
|
||||||
try {
|
try {
|
||||||
TypePrinter tp = new VarTypePrinter(at.messages(),
|
TypePrinter tp = new TypePrinter(at.messages(),
|
||||||
state.maps::fullClassNameAndPackageToClass, syms, types);
|
state.maps::fullClassNameAndPackageToClass, printIntersectionTypes);
|
||||||
return tp.toString(type);
|
List<Type> captures = types.captures(type);
|
||||||
|
String res = tp.toString(types.upward(type, captures));
|
||||||
|
|
||||||
|
if (res == null)
|
||||||
|
res = OBJECT_TYPE_NAME;
|
||||||
|
|
||||||
|
return res;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
return null;
|
return OBJECT_TYPE_NAME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,7 @@ class ReplParser extends JavacParser {
|
||||||
//mods.flags |= Flags.STATIC;
|
//mods.flags |= Flags.STATIC;
|
||||||
List<JCTree> defs
|
List<JCTree> defs
|
||||||
= variableDeclaratorsRest(pos, mods, t, name, false, dc,
|
= variableDeclaratorsRest(pos, mods, t, name, false, dc,
|
||||||
new ListBuffer<JCTree>()).toList();
|
new ListBuffer<JCTree>(), true).toList();
|
||||||
accept(SEMI);
|
accept(SEMI);
|
||||||
storeEnd(defs.last(), S.prevToken().endPos);
|
storeEnd(defs.last(), S.prevToken().endPos);
|
||||||
return defs;
|
return defs;
|
||||||
|
|
|
@ -134,6 +134,8 @@ import static jdk.jshell.TreeDissector.printType;
|
||||||
|
|
||||||
import static java.util.stream.Collectors.joining;
|
import static java.util.stream.Collectors.joining;
|
||||||
|
|
||||||
|
import javax.lang.model.type.IntersectionType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The concrete implementation of SourceCodeAnalysis.
|
* The concrete implementation of SourceCodeAnalysis.
|
||||||
* @author Robert Field
|
* @author Robert Field
|
||||||
|
@ -715,6 +717,13 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
|
||||||
switch (site.getKind()) {
|
switch (site.getKind()) {
|
||||||
|
case INTERSECTION: {
|
||||||
|
List<Element> result = new ArrayList<>();
|
||||||
|
for (TypeMirror bound : ((IntersectionType) site).getBounds()) {
|
||||||
|
result.addAll(membersOf(at, bound, shouldGenerateDotClassItem));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
case DECLARED: {
|
case DECLARED: {
|
||||||
TypeElement element = (TypeElement) at.getTypes().asElement(site);
|
TypeElement element = (TypeElement) at.getTypes().asElement(site);
|
||||||
List<Element> result = new ArrayList<>();
|
List<Element> result = new ArrayList<>();
|
||||||
|
|
|
@ -61,7 +61,20 @@ import javax.lang.model.util.Elements;
|
||||||
import javax.tools.FileObject;
|
import javax.tools.FileObject;
|
||||||
import jdk.jshell.MemoryFileManager.SourceMemoryJavaFileObject;
|
import jdk.jshell.MemoryFileManager.SourceMemoryJavaFileObject;
|
||||||
import java.lang.Runtime.Version;
|
import java.lang.Runtime.Version;
|
||||||
|
import java.nio.CharBuffer;
|
||||||
import com.sun.source.tree.Tree.Kind;
|
import com.sun.source.tree.Tree.Kind;
|
||||||
|
import com.sun.tools.javac.code.Kinds;
|
||||||
|
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||||
|
import com.sun.tools.javac.code.Symbol.VarSymbol;
|
||||||
|
import com.sun.tools.javac.parser.Parser;
|
||||||
|
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
|
||||||
|
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
|
||||||
|
import com.sun.tools.javac.tree.JCTree.JCExpression;
|
||||||
|
import com.sun.tools.javac.tree.JCTree.JCTypeCast;
|
||||||
|
import com.sun.tools.javac.tree.JCTree.Tag;
|
||||||
|
import com.sun.tools.javac.util.Context.Factory;
|
||||||
|
import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
|
||||||
|
import jdk.jshell.Snippet.Status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The primary interface to the compiler API. Parsing, analysis, and
|
* The primary interface to the compiler API. Parsing, analysis, and
|
||||||
|
@ -355,6 +368,7 @@ class TaskFactory {
|
||||||
Iterable<? extends JavaFileObject> compilationUnits = inputs
|
Iterable<? extends JavaFileObject> compilationUnits = inputs
|
||||||
.map(in -> sh.sourceToFileObject(fileManager, in))
|
.map(in -> sh.sourceToFileObject(fileManager, in))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
JShellJavaCompiler.preRegister(context, state);
|
||||||
this.task = (JavacTaskImpl) ((JavacTool) compiler).getTask(null,
|
this.task = (JavacTaskImpl) ((JavacTool) compiler).getTask(null,
|
||||||
fileManager, diagnostics, options, null,
|
fileManager, diagnostics, options, null,
|
||||||
compilationUnits, context);
|
compilationUnits, context);
|
||||||
|
@ -464,4 +478,57 @@ class TaskFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class JShellJavaCompiler extends com.sun.tools.javac.main.JavaCompiler {
|
||||||
|
|
||||||
|
public static void preRegister(Context c, JShell state) {
|
||||||
|
c.put(compilerKey, (Factory<com.sun.tools.javac.main.JavaCompiler>) i -> new JShellJavaCompiler(i, state));
|
||||||
|
}
|
||||||
|
|
||||||
|
private final JShell state;
|
||||||
|
|
||||||
|
public JShellJavaCompiler(Context context, JShell state) {
|
||||||
|
super(context);
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processAnnotations(com.sun.tools.javac.util.List<JCCompilationUnit> roots, Collection<String> classnames) {
|
||||||
|
super.processAnnotations(roots, classnames);
|
||||||
|
state.maps
|
||||||
|
.snippetList()
|
||||||
|
.stream()
|
||||||
|
.filter(s -> s.status() == Status.VALID)
|
||||||
|
.filter(s -> s.kind() == Snippet.Kind.VAR)
|
||||||
|
.filter(s -> s.subKind() == Snippet.SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND)
|
||||||
|
.forEach(s -> setVariableType(roots, (VarSnippet) s));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setVariableType(com.sun.tools.javac.util.List<JCCompilationUnit> roots, VarSnippet s) {
|
||||||
|
ClassSymbol clazz = syms.getClass(syms.unnamedModule, names.fromString(s.classFullName()));
|
||||||
|
if (clazz == null || !clazz.isCompleted())
|
||||||
|
return;
|
||||||
|
VarSymbol field = (VarSymbol) clazz.members().findFirst(names.fromString(s.name()), sym -> sym.kind == Kinds.Kind.VAR);
|
||||||
|
if (field != null) {
|
||||||
|
JavaFileObject prev = log.useSource(null);
|
||||||
|
DiscardDiagnosticHandler h = new DiscardDiagnosticHandler(log);
|
||||||
|
try {
|
||||||
|
String typeName = s.typeName();
|
||||||
|
CharBuffer buf = CharBuffer.wrap(("(" + typeName +")x\u0000").toCharArray(), 0, typeName.length() + 3);
|
||||||
|
Parser parser = parserFactory.newParser(buf, false, false, false);
|
||||||
|
JCExpression expr = parser.parseExpression();
|
||||||
|
if (expr.hasTag(Tag.TYPECAST)) {
|
||||||
|
JCTypeCast tree = (JCTypeCast) expr;
|
||||||
|
if (tree.clazz.hasTag(Tag.TYPEINTERSECTION)) {
|
||||||
|
field.type = attr.attribType(tree.clazz,
|
||||||
|
((JCClassDecl) roots.head.getTypeDecls().head).sym);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
log.popDiagnosticHandler(h);
|
||||||
|
log.useSource(prev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,7 +227,7 @@ class TreeDissector {
|
||||||
Type typeImpl = (Type) type;
|
Type typeImpl = (Type) type;
|
||||||
try {
|
try {
|
||||||
TypePrinter tp = new TypePrinter(at.messages(),
|
TypePrinter tp = new TypePrinter(at.messages(),
|
||||||
state.maps::fullClassNameAndPackageToClass);
|
state.maps::fullClassNameAndPackageToClass, true);
|
||||||
return tp.toString(typeImpl);
|
return tp.toString(typeImpl);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -32,9 +32,11 @@ import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||||
import com.sun.tools.javac.code.Symbol.PackageSymbol;
|
import com.sun.tools.javac.code.Symbol.PackageSymbol;
|
||||||
import com.sun.tools.javac.code.Type;
|
import com.sun.tools.javac.code.Type;
|
||||||
import com.sun.tools.javac.code.Type.ClassType;
|
import com.sun.tools.javac.code.Type.ClassType;
|
||||||
|
import com.sun.tools.javac.code.Type.IntersectionClassType;
|
||||||
import com.sun.tools.javac.util.JavacMessages;
|
import com.sun.tools.javac.util.JavacMessages;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.function.BinaryOperator;
|
import java.util.function.BinaryOperator;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print types in source form.
|
* Print types in source form.
|
||||||
|
@ -45,10 +47,14 @@ class TypePrinter extends Printer {
|
||||||
|
|
||||||
private final JavacMessages messages;
|
private final JavacMessages messages;
|
||||||
private final BinaryOperator<String> fullClassNameAndPackageToClass;
|
private final BinaryOperator<String> fullClassNameAndPackageToClass;
|
||||||
|
private final boolean printEnhancedTypes;
|
||||||
|
|
||||||
TypePrinter(JavacMessages messages, BinaryOperator<String> fullClassNameAndPackageToClass) {
|
TypePrinter(JavacMessages messages,
|
||||||
|
BinaryOperator<String> fullClassNameAndPackageToClass,
|
||||||
|
boolean printEnhancedTypes) {
|
||||||
this.messages = messages;
|
this.messages = messages;
|
||||||
this.fullClassNameAndPackageToClass = fullClassNameAndPackageToClass;
|
this.fullClassNameAndPackageToClass = fullClassNameAndPackageToClass;
|
||||||
|
this.printEnhancedTypes = printEnhancedTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
String toString(Type t) {
|
String toString(Type t) {
|
||||||
|
@ -92,8 +98,18 @@ class TypePrinter extends Printer {
|
||||||
protected String className(ClassType t, boolean longform, Locale locale) {
|
protected String className(ClassType t, boolean longform, Locale locale) {
|
||||||
Symbol sym = t.tsym;
|
Symbol sym = t.tsym;
|
||||||
if (sym.name.length() == 0 && (sym.flags() & COMPOUND) != 0) {
|
if (sym.name.length() == 0 && (sym.flags() & COMPOUND) != 0) {
|
||||||
return OBJECT;
|
if (printEnhancedTypes) {
|
||||||
|
return ((IntersectionClassType) t).getExplicitComponents()
|
||||||
|
.stream()
|
||||||
|
.map(i -> visit(i, locale))
|
||||||
|
.collect(Collectors.joining("&"));
|
||||||
|
} else {
|
||||||
|
return OBJECT;
|
||||||
|
}
|
||||||
} else if (sym.name.length() == 0) {
|
} else if (sym.name.length() == 0) {
|
||||||
|
if (printEnhancedTypes) {
|
||||||
|
return t.tsym.flatName().toString().substring(t.tsym.outermostClass().flatName().length());
|
||||||
|
}
|
||||||
// Anonymous
|
// Anonymous
|
||||||
String s;
|
String s;
|
||||||
ClassType norm = (ClassType) t.tsym.type;
|
ClassType norm = (ClassType) t.tsym.type;
|
||||||
|
|
|
@ -1,265 +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.jshell;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import com.sun.tools.javac.code.Type;
|
|
||||||
import com.sun.tools.javac.code.Type.ClassType;
|
|
||||||
import com.sun.tools.javac.util.JavacMessages;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.BinaryOperator;
|
|
||||||
import com.sun.tools.javac.code.BoundKind;
|
|
||||||
import com.sun.tools.javac.code.Flags;
|
|
||||||
import com.sun.tools.javac.code.Symtab;
|
|
||||||
import com.sun.tools.javac.code.Type.CapturedType;
|
|
||||||
import com.sun.tools.javac.code.Type.StructuralTypeMapping;
|
|
||||||
import com.sun.tools.javac.code.Type.TypeVar;
|
|
||||||
import com.sun.tools.javac.code.Type.WildcardType;
|
|
||||||
import com.sun.tools.javac.code.Types;
|
|
||||||
import com.sun.tools.javac.code.Types.SimpleVisitor;
|
|
||||||
import com.sun.tools.javac.util.List;
|
|
||||||
import static com.sun.tools.javac.code.BoundKind.EXTENDS;
|
|
||||||
import static com.sun.tools.javac.code.BoundKind.SUPER;
|
|
||||||
import static com.sun.tools.javac.code.BoundKind.UNBOUND;
|
|
||||||
import static com.sun.tools.javac.code.Type.ArrayType;
|
|
||||||
import static com.sun.tools.javac.code.TypeTag.BOT;
|
|
||||||
import static com.sun.tools.javac.code.TypeTag.WILDCARD;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print variable types in source form.
|
|
||||||
* TypeProjection and CaptureScanner are copied from Types in the JEP-286
|
|
||||||
* Sandbox by Maurizio. The checks for Non-Denotable in TypePrinter are
|
|
||||||
* cribbed from denotableChecker of the same source.
|
|
||||||
*
|
|
||||||
* @author Maurizio Cimadamore
|
|
||||||
* @author Robert Field
|
|
||||||
*/
|
|
||||||
class VarTypePrinter extends TypePrinter {
|
|
||||||
private static final String WILD = "?";
|
|
||||||
|
|
||||||
private final Symtab syms;
|
|
||||||
private final Types types;
|
|
||||||
|
|
||||||
VarTypePrinter(JavacMessages messages, BinaryOperator<String> fullClassNameAndPackageToClass,
|
|
||||||
Symtab syms, Types types) {
|
|
||||||
super(messages, fullClassNameAndPackageToClass);
|
|
||||||
this.syms = syms;
|
|
||||||
this.types = types;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
String toString(Type t) {
|
|
||||||
return super.toString(upward(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visitTypeVar(TypeVar t, Locale locale) {
|
|
||||||
/* Any type variable mentioned in the inferred type must have been declared as a type parameter
|
|
||||||
(i.e cannot have been produced by inference (18.4))
|
|
||||||
*/
|
|
||||||
// and beyond that, there are no global type vars, so if there are any
|
|
||||||
// type variables left, they need to be eliminated
|
|
||||||
return WILD; // Non-denotable
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visitCapturedType(CapturedType t, Locale locale) {
|
|
||||||
/* Any type variable mentioned in the inferred type must have been declared as a type parameter
|
|
||||||
(i.e cannot have been produced by capture conversion (5.1.10))
|
|
||||||
*/
|
|
||||||
return WILD; // Non-denotable
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type upward(Type t) {
|
|
||||||
List<Type> captures = captures(t);
|
|
||||||
return upward(t, captures);
|
|
||||||
}
|
|
||||||
|
|
||||||
/************* Following from JEP-286 Types.java ***********/
|
|
||||||
|
|
||||||
public Type upward(Type t, List<Type> vars) {
|
|
||||||
return t.map(new TypeProjection(vars), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Type> captures(Type t) {
|
|
||||||
CaptureScanner cs = new CaptureScanner();
|
|
||||||
Set<Type> captures = new HashSet<>();
|
|
||||||
cs.visit(t, captures);
|
|
||||||
return List.from(captures);
|
|
||||||
}
|
|
||||||
|
|
||||||
class CaptureScanner extends SimpleVisitor<Void, Set<Type>> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitType(Type t, Set<Type> types) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitClassType(ClassType t, Set<Type> seen) {
|
|
||||||
if (t.isCompound()) {
|
|
||||||
types.directSupertypes(t).forEach(s -> visit(s, seen));
|
|
||||||
} else {
|
|
||||||
t.allparams().forEach(ta -> visit(ta, seen));
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitArrayType(ArrayType t, Set<Type> seen) {
|
|
||||||
return visit(t.elemtype, seen);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitWildcardType(WildcardType t, Set<Type> seen) {
|
|
||||||
visit(t.type, seen);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitTypeVar(TypeVar t, Set<Type> seen) {
|
|
||||||
if ((t.tsym.flags() & Flags.SYNTHETIC) != 0 && seen.add(t)) {
|
|
||||||
visit(t.getUpperBound(), seen);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Void visitCapturedType(CapturedType t, Set<Type> seen) {
|
|
||||||
if (seen.add(t)) {
|
|
||||||
visit(t.getUpperBound(), seen);
|
|
||||||
visit(t.getLowerBound(), seen);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TypeProjection extends StructuralTypeMapping<Boolean> {
|
|
||||||
|
|
||||||
List<Type> vars;
|
|
||||||
Set<Type> seen = new HashSet<>();
|
|
||||||
|
|
||||||
public TypeProjection(List<Type> vars) {
|
|
||||||
this.vars = vars;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type visitClassType(ClassType t, Boolean upward) {
|
|
||||||
if (upward && !t.isCompound() && t.tsym.name.isEmpty()) {
|
|
||||||
//lift anonymous class type to first supertype (class or interface)
|
|
||||||
return types.directSupertypes(t).last();
|
|
||||||
} else if (t.isCompound()) {
|
|
||||||
List<Type> components = types.directSupertypes(t);
|
|
||||||
List<Type> components1 = components.map(c -> c.map(this, upward));
|
|
||||||
if (components == components1) return t;
|
|
||||||
else return types.makeIntersectionType(components1);
|
|
||||||
} else {
|
|
||||||
Type outer = t.getEnclosingType();
|
|
||||||
Type outer1 = visit(outer, upward);
|
|
||||||
List<Type> typarams = t.getTypeArguments();
|
|
||||||
List<Type> typarams1 = typarams.map(ta -> mapTypeArgument(ta, upward));
|
|
||||||
if (typarams1.stream().anyMatch(ta -> ta.hasTag(BOT))) {
|
|
||||||
//not defined
|
|
||||||
return syms.botType;
|
|
||||||
}
|
|
||||||
if (outer1 == outer && typarams1 == typarams) return t;
|
|
||||||
else return new ClassType(outer1, typarams1, t.tsym, t.getMetadata()) {
|
|
||||||
@Override
|
|
||||||
protected boolean needsStripping() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Type makeWildcard(Type upper, Type lower) {
|
|
||||||
BoundKind bk;
|
|
||||||
Type bound;
|
|
||||||
if (upper.hasTag(BOT)) {
|
|
||||||
upper = syms.objectType;
|
|
||||||
}
|
|
||||||
boolean isUpperObject = types.isSameType(upper, syms.objectType);
|
|
||||||
if (!lower.hasTag(BOT) && isUpperObject) {
|
|
||||||
bound = lower;
|
|
||||||
bk = SUPER;
|
|
||||||
} else {
|
|
||||||
bound = upper;
|
|
||||||
bk = isUpperObject ? UNBOUND : EXTENDS;
|
|
||||||
}
|
|
||||||
return new WildcardType(bound, bk, syms.boundClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type visitTypeVar(TypeVar t, Boolean upward) {
|
|
||||||
if (vars.contains(t)) {
|
|
||||||
try {
|
|
||||||
if (seen.add(t)) {
|
|
||||||
return (upward ?
|
|
||||||
t.getUpperBound() :
|
|
||||||
(t.getLowerBound() == null) ?
|
|
||||||
syms.botType :
|
|
||||||
t.getLowerBound())
|
|
||||||
.map(this, upward);
|
|
||||||
} else {
|
|
||||||
//cycle
|
|
||||||
return syms.objectType;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
seen.remove(t);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type visitWildcardType(WildcardType wt, Boolean upward) {
|
|
||||||
if (upward) {
|
|
||||||
return wt.isExtendsBound() ?
|
|
||||||
wt.type.map(this, upward) :
|
|
||||||
syms.objectType;
|
|
||||||
} else {
|
|
||||||
return wt.isSuperBound() ?
|
|
||||||
wt.type.map(this, upward) :
|
|
||||||
syms.botType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Type mapTypeArgument(Type t, boolean upward) {
|
|
||||||
if (!t.containsAny(vars)) {
|
|
||||||
return t;
|
|
||||||
} else if (!t.hasTag(WILDCARD) && !upward) {
|
|
||||||
//not defined
|
|
||||||
return syms.botType;
|
|
||||||
} else {
|
|
||||||
Type upper = t.map(this, upward);
|
|
||||||
Type lower = t.map(this, !upward);
|
|
||||||
return makeWildcard(upper, lower);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -74,16 +74,15 @@ abstract class Wrap implements GeneralWrap {
|
||||||
* @param rdecl Type name and name
|
* @param rdecl Type name and name
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static Wrap varWrap(String source, Range rtype, String brackets, Range rname, Range rinit) {
|
public static Wrap varWrap(String source, Wrap wtype, String brackets,
|
||||||
|
Range rname, Wrap winit, Wrap anonDeclareWrap) {
|
||||||
RangeWrap wname = new RangeWrap(source, rname);
|
RangeWrap wname = new RangeWrap(source, rname);
|
||||||
RangeWrap wtype = new RangeWrap(source, rtype);
|
|
||||||
Wrap wVarDecl = new VarDeclareWrap(wtype, brackets, wname);
|
Wrap wVarDecl = new VarDeclareWrap(wtype, brackets, wname);
|
||||||
Wrap wmeth;
|
Wrap wmeth;
|
||||||
|
|
||||||
if (rinit == null) {
|
if (winit == null) {
|
||||||
wmeth = new CompoundWrap(new NoWrap(" "), " return null;\n");
|
wmeth = new CompoundWrap(new NoWrap(" "), " return null;\n");
|
||||||
} else {
|
} else {
|
||||||
RangeWrap winit = new RangeWrap(source, rinit);
|
|
||||||
// int x = y
|
// int x = y
|
||||||
// int x_ = y; return x = x_;
|
// int x_ = y; return x = x_;
|
||||||
// decl + "_ = " + init ; + "return " + name + "=" + name + "_ ;"
|
// decl + "_ = " + init ; + "return " + name + "=" + name + "_ ;"
|
||||||
|
@ -93,7 +92,8 @@ abstract class Wrap implements GeneralWrap {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Wrap wInitMeth = new DoitMethodWrap(wmeth);
|
Wrap wInitMeth = new DoitMethodWrap(wmeth);
|
||||||
return new CompoundWrap(wVarDecl, wInitMeth);
|
return anonDeclareWrap != null ? new CompoundWrap(wVarDecl, wInitMeth, anonDeclareWrap)
|
||||||
|
: new CompoundWrap(wVarDecl, wInitMeth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Wrap tempVarWrap(String source, String typename, String name) {
|
public static Wrap tempVarWrap(String source, String typename, String name) {
|
||||||
|
@ -112,6 +112,14 @@ abstract class Wrap implements GeneralWrap {
|
||||||
return new NoWrap(source);
|
return new NoWrap(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Wrap identityWrap(String source) {
|
||||||
|
return new NoWrap(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Wrap rangeWrap(String source, Range range) {
|
||||||
|
return new RangeWrap(source, range);
|
||||||
|
}
|
||||||
|
|
||||||
public static Wrap classMemberWrap(String source) {
|
public static Wrap classMemberWrap(String source) {
|
||||||
Wrap w = new NoWrap(source);
|
Wrap w = new NoWrap(source);
|
||||||
return new CompoundWrap(" public static\n ", w);
|
return new CompoundWrap(" public static\n ", w);
|
||||||
|
|
|
@ -273,7 +273,8 @@ abstract class CompilationPhase {
|
||||||
private static final class LocalVariableTypeCalculationPhase extends CompilationPhase {
|
private static final class LocalVariableTypeCalculationPhase extends CompilationPhase {
|
||||||
@Override
|
@Override
|
||||||
FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
|
FunctionNode transform(final Compiler compiler, final CompilationPhases phases, final FunctionNode fn) {
|
||||||
final FunctionNode newFunctionNode = transformFunction(fn, new LocalVariableTypesCalculator(compiler));
|
final FunctionNode newFunctionNode = transformFunction(fn, new LocalVariableTypesCalculator(compiler,
|
||||||
|
compiler.getReturnType()));
|
||||||
final ScriptEnvironment senv = compiler.getScriptEnvironment();
|
final ScriptEnvironment senv = compiler.getScriptEnvironment();
|
||||||
final PrintWriter err = senv.getErr();
|
final PrintWriter err = senv.getErr();
|
||||||
|
|
||||||
|
|
|
@ -619,6 +619,10 @@ public final class Compiler implements Loggable {
|
||||||
return types == null ? null : types.get(fn, pos);
|
return types == null ? null : types.get(fn, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Type getReturnType() {
|
||||||
|
return types == null || !isOnDemandCompilation() ? Type.UNKNOWN : types.getReturnType();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do a compilation job
|
* Do a compilation job
|
||||||
*
|
*
|
||||||
|
|
|
@ -405,10 +405,15 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor {
|
||||||
// variables).
|
// variables).
|
||||||
private final Deque<Label> catchLabels = new ArrayDeque<>();
|
private final Deque<Label> catchLabels = new ArrayDeque<>();
|
||||||
|
|
||||||
LocalVariableTypesCalculator(final Compiler compiler) {
|
private LocalVariableTypesCalculator(final Compiler compiler) {
|
||||||
this.compiler = compiler;
|
this.compiler = compiler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalVariableTypesCalculator(final Compiler compiler, final Type returnType) {
|
||||||
|
this(compiler);
|
||||||
|
this.returnType = returnType;
|
||||||
|
}
|
||||||
|
|
||||||
private JumpTarget createJumpTarget(final Label label) {
|
private JumpTarget createJumpTarget(final Label label) {
|
||||||
assert !jumpTargets.containsKey(label);
|
assert !jumpTargets.containsKey(label);
|
||||||
final JumpTarget jumpTarget = new JumpTarget();
|
final JumpTarget jumpTarget = new JumpTarget();
|
||||||
|
|
|
@ -117,6 +117,15 @@ public final class TypeMap {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the return type required for the call site we're compiling for. This only determines
|
||||||
|
* whether object return type is required or not.
|
||||||
|
* @return Type.OBJECT for call sites with object return types, Type.UNKNOWN for everything else
|
||||||
|
*/
|
||||||
|
Type getReturnType() {
|
||||||
|
return returnType.isObject() ? Type.OBJECT : Type.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return toString("");
|
return toString("");
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue