Merge
This commit is contained in:
commit
23b301d6d8
@ -1,396 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. 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.
|
||||
#
|
||||
|
||||
#
|
||||
# Makefile for building the langtools workspace.
|
||||
#
|
||||
|
||||
#
|
||||
# On Solaris, the standard 'make' utility will not work with these makefiles.
|
||||
# This little rule is only understood by Solaris make, and is harmless
|
||||
# when seen by the GNU make tool. If using Solaris make, this causes the
|
||||
# make command to fail.
|
||||
#
|
||||
SUN_MAKE_TEST:sh = @echo "ERROR: PLEASE USE GNU VERSION OF MAKE"; exit 33
|
||||
|
||||
#----- cancel implicit rules
|
||||
|
||||
%: %.o
|
||||
%: %.obj
|
||||
%: %.dll
|
||||
%: %.c
|
||||
%: %.cc
|
||||
%: %.C
|
||||
%: %.p
|
||||
%: %.f
|
||||
%: %.s
|
||||
%: %.F
|
||||
%: %.r
|
||||
%: %.S
|
||||
%: %.mod
|
||||
%: %.sh
|
||||
%: %,v
|
||||
%: RCS/%,v
|
||||
|
||||
#----- imports
|
||||
|
||||
ifdef ALT_BOOT_JAVA_HOME
|
||||
BOOT_JAVA_HOME = $(ALT_BOOT_JAVA_HOME)
|
||||
else
|
||||
ifdef ALT_BOOTDIR
|
||||
BOOT_JAVA_HOME = $(ALT_BOOTDIR)
|
||||
else
|
||||
BOOT_JAVA_HOME=/java/re/jdk/1.5.0/archive/fcs/binaries/solaris-sparc
|
||||
endif
|
||||
endif
|
||||
|
||||
BOOT_JAVA=$(BOOT_JAVA_HOME)/bin/java
|
||||
BOOT_JAVAC=$(BOOT_JAVA_HOME)/bin/javac
|
||||
BOOTJAR=$(BOOT_JAVA_HOME)/bin/jar
|
||||
|
||||
ifdef ALT_TESTJAVA_HOME
|
||||
TESTJAVA_HOME = $(ALT_TESTJAVA_HOME)
|
||||
else
|
||||
TESTJAVA_HOME=/java/re/jdk/1.6.0/archive/fcs/binaries/solaris-sparc
|
||||
endif
|
||||
|
||||
TESTJAVA=$(TESTJAVA_HOME)/bin/java
|
||||
|
||||
ifdef ALT_FINDBUGS_HOME
|
||||
FINDBUGS_HOME = $(ALT_FINDBUGS_HOME)
|
||||
else
|
||||
FINDBUGS_HOME = /java/devtools/share/findbugs/1.1.2-rc4
|
||||
endif
|
||||
|
||||
FINDBUGS = $(FINDBUGS_HOME)/bin/findbugs
|
||||
|
||||
#----- commands
|
||||
|
||||
CHMOD = chmod
|
||||
CP = cp
|
||||
ECHO = echo # FIXME
|
||||
FIND = find
|
||||
MKDIR = mkdir
|
||||
SED = sed
|
||||
ZIP = zip
|
||||
|
||||
#----- locations and deliverables
|
||||
|
||||
TOPDIR = ..
|
||||
SRC_BIN_DIR = $(TOPDIR)/src/share/bin
|
||||
SRC_CLASSES_DIR = $(TOPDIR)/src/share/classes
|
||||
|
||||
BUILD_DIR = $(TOPDIR)/build
|
||||
|
||||
CLASSES_DIR = $(BUILD_DIR)/classes
|
||||
GENSRC_DIR = $(BUILD_DIR)/gensrc
|
||||
|
||||
DIST_DIR = $(TOPDIR)/dist
|
||||
BIN_DIR = $(DIST_DIR)/bin
|
||||
LIB_DIR = $(DIST_DIR)/lib
|
||||
|
||||
JAVAC_JAR = $(LIB_DIR)/javac.jar
|
||||
JAVADOC_JAR = $(LIB_DIR)/javadoc.jar
|
||||
JAVAH_JAR = $(LIB_DIR)/javah.jar
|
||||
JAVAP_JAR = $(LIB_DIR)/javap.jar
|
||||
|
||||
CLASSES_JAR = $(DIST_DIR)/classes.jar
|
||||
SRC_ZIP = $(DIST_DIR)/src.zip
|
||||
|
||||
BUILDTOOLSRC_DIR = tools
|
||||
BUILDTOOLCLASSES_DIR = $(BUILD_DIR)/toolclasses
|
||||
|
||||
#-----
|
||||
|
||||
ifndef JDK_MAJOR_VERSION
|
||||
JDK_MAJOR_VERSION = 1
|
||||
endif
|
||||
|
||||
ifndef JDK_MINOR_VERSION
|
||||
JDK_MINOR_VERSION = 7
|
||||
endif
|
||||
|
||||
ifndef JDK_MICRO_VERSION
|
||||
JDK_MICRO_VERSION = 0
|
||||
endif
|
||||
|
||||
ifndef JDK_VERSION
|
||||
JDK_VERSION = $(JDK_MAJOR_VERSION).$(JDK_MINOR_VERSION).$(JDK_MICRO_VERSION)
|
||||
endif
|
||||
|
||||
ifndef MILESTONE
|
||||
MILESTONE = internal
|
||||
endif
|
||||
|
||||
# RELEASE is JDK_VERSION and -MILESTONE if MILESTONE is set
|
||||
ifneq ($(MILESTONE),fcs)
|
||||
RELEASE = $(JDK_VERSION)-$(MILESTONE)$(BUILD_VARIANT_RELEASE)
|
||||
else
|
||||
RELEASE = $(JDK_VERSION)$(BUILD_VARIANT_RELEASE)
|
||||
endif
|
||||
|
||||
# FULL_VERSION is RELEASE and -BUILD_NUMBER if BUILD_NUMBER is set
|
||||
ifdef BUILD_NUMBER
|
||||
FULL_VERSION = $(RELEASE)-$(BUILD_NUMBER)
|
||||
else
|
||||
BUILD_NUMBER = b00
|
||||
USER_RELEASE_SUFFIX := $(shell echo $(USER)_`date '+%d_%b_%Y_%H_%M' | tr "A-Z" "a-z"`)
|
||||
FULL_VERSION = $(RELEASE)-$(USER_RELEASE_SUFFIX)-$(BUILD_NUMBER)
|
||||
endif
|
||||
|
||||
#----- useful macros
|
||||
|
||||
TOOLS = javac javadoc javah javap
|
||||
|
||||
SOURCE_LEVEL = 5
|
||||
BOOTSTRAP_TARGET_LEVEL = 5
|
||||
TARGET_LEVEL = 6
|
||||
|
||||
ifndef TARGET_JAVA
|
||||
TARGET_JAVA = java
|
||||
endif
|
||||
|
||||
NO_PROPRIETARY_API_WARNINGS = -XDignore.symbol.file=true
|
||||
|
||||
SELF = $(lastword $(MAKEFILE_LIST))
|
||||
|
||||
#-----
|
||||
|
||||
# the default is to generate the following:
|
||||
# dist/{bin,lib}:
|
||||
# lang tools compiled to run on the target JDK
|
||||
|
||||
default:
|
||||
$(MAKE) -f $(SELF) \
|
||||
MILESTONE=bootstrap \
|
||||
TARGET_LEVEL=$(BOOTSTRAP_TARGET_LEVEL) \
|
||||
TARGET_JAVA=$(BOOT_JAVA_HOME)/bin/java \
|
||||
GENSRC_DIR=$(BUILD_DIR)/bootstrap/gensrc \
|
||||
CLASSES_DIR=$(BUILD_DIR)/bootstrap/classes \
|
||||
BIN_DIR=$(BUILD_DIR)/bootstrap/bin \
|
||||
LIB_DIR=$(BUILD_DIR)/bootstrap/lib \
|
||||
$(BUILD_DIR)/bootstrap/lib/javac.jar \
|
||||
$(BUILD_DIR)/bootstrap/bin/javac
|
||||
$(MAKE) -f $(SELF) \
|
||||
BOOT_JAVAC=$(BUILD_DIR)/bootstrap/bin/javac \
|
||||
tools
|
||||
|
||||
# for jdk, we generate the following:
|
||||
# dist/bootstrap/{bin,lib}:
|
||||
# lang tools compiled to run on the boot JDK
|
||||
# dist/lib/classes.jar:
|
||||
# lang tools recompiled to run on the target JDK,
|
||||
# ready for inclusion in rt.jar and tools.jar
|
||||
# dist/lib/src.zip
|
||||
# .properties and .java files for classes in classes.jar,
|
||||
# ready for jdk src.zip
|
||||
|
||||
jdk:
|
||||
$(MAKE) -f $(SELF) \
|
||||
MILESTONE=bootstrap \
|
||||
TARGET_LEVEL=$(BOOTSTRAP_TARGET_LEVEL) \
|
||||
TARGET_JAVA=$(BOOT_JAVA_HOME)/bin/java \
|
||||
GENSRC_DIR=$(BUILD_DIR)/bootstrap/gensrc \
|
||||
CLASSES_DIR=$(BUILD_DIR)/bootstrap/classes \
|
||||
BIN_DIR=$(DIST_DIR)/bootstrap/bin \
|
||||
LIB_DIR=$(DIST_DIR)/bootstrap/lib \
|
||||
tools
|
||||
$(MAKE) -f $(SELF) \
|
||||
BOOT_JAVAC=$(DIST_DIR)/bootstrap/bin/javac \
|
||||
LIB_DIR=$(BUILD_DIR)/jdk/lib \
|
||||
$(DIST_DIR)/lib/classes.jar \
|
||||
$(DIST_DIR)/lib/src.zip
|
||||
|
||||
tools: $(TOOLS:%=$(LIB_DIR)/%.jar) $(TOOLS:%=$(BIN_DIR)/%)
|
||||
|
||||
clean:
|
||||
$(RM) -r $(BUILD_DIR)
|
||||
|
||||
really-clean: clean
|
||||
$(RM) -r $(DIST_DIR)
|
||||
|
||||
jprt_product_build \
|
||||
jprt_debug_build \
|
||||
jprt_fastdebug_build: lib
|
||||
|
||||
#----- javac
|
||||
|
||||
JAVAC_DIRS = \
|
||||
javax/annotation/processing \
|
||||
javax/lang/model \
|
||||
javax/tools \
|
||||
jdk/ \
|
||||
com/sun/source \
|
||||
com/sun/tools/javac
|
||||
|
||||
JAVAC_RESOURCE_FILES = \
|
||||
$(shell find $(patsubst %,$(SRC_CLASSES_DIR)/%,$(JAVAC_DIRS)) -name SCCS -prune -o -name \*.properties -print )
|
||||
|
||||
JAVAC_JAVA_FILES = \
|
||||
$(shell find $(patsubst %,$(SRC_CLASSES_DIR)/%,$(JAVAC_DIRS)) -name SCCS -prune -o -name \*.java -print ) \
|
||||
$(patsubst $(SRC_CLASSES_DIR)/%.properties,$(GENSRC_DIR)/%.java,$(JAVAC_RESOURCE_FILES)) \
|
||||
$(GENSRC_DIR)/com/sun/tools/javac/resources/version.java
|
||||
|
||||
$(JAVAC_JAR): $(JAVAC_JAVA_FILES)
|
||||
$(MKDIR) -p $(CLASSES_DIR) $(@D)
|
||||
$(BOOT_JAVAC) -d $(CLASSES_DIR) -target $(TARGET_LEVEL) $(NO_PROPRIETARY_API_WARNINGS) $(JAVAC_JAVA_FILES)
|
||||
( $(ECHO) Main-Class: com.sun.tools.javac.Main ) > $(BUILD_DIR)/javac.mf
|
||||
$(BOOTJAR) -cfm $@ $(BUILD_DIR)/javac.mf $(patsubst %,-C $(CLASSES_DIR) %, $(JAVAC_DIRS))
|
||||
|
||||
#----- javadoc
|
||||
|
||||
### FIXME -- javadoc has a couple of extra non-property resource files
|
||||
### that need to be included
|
||||
|
||||
JAVADOC_DIRS = \
|
||||
com/sun/javadoc \
|
||||
com/sun/tools/doclets \
|
||||
com/sun/tools/javadoc
|
||||
|
||||
JAVADOC_RESOURCE_FILES = \
|
||||
$(shell find $(patsubst %,$(SRC_CLASSES_DIR)/%,$(JAVADOC_DIRS)) -name SCCS -prune -o -name \*.properties -print )
|
||||
|
||||
JAVADOC_JAVA_FILES = \
|
||||
$(shell find $(patsubst %,$(SRC_CLASSES_DIR)/%,$(JAVADOC_DIRS)) -name SCCS -prune -o -name \*.java -print ) \
|
||||
$(patsubst $(SRC_CLASSES_DIR)/%.properties,$(GENSRC_DIR)/%.java,$(JAVADOC_RESOURCE_FILES))
|
||||
|
||||
$(JAVADOC_JAR): $(JAVADOC_JAVA_FILES) $(JAVAC_JAR)
|
||||
$(MKDIR) -p $(CLASSES_DIR) $(@D)
|
||||
$(BOOT_JAVAC) -sourcepath "" -classpath $(JAVAC_JAR) -d $(CLASSES_DIR) -target $(TARGET_LEVEL) $(JAVADOC_JAVA_FILES)
|
||||
( $(ECHO) Main-Class: com.sun.tools.javadoc.Main ; $(ECHO) Class-Path: javac.jar ) > $(BUILD_DIR)/javadoc.mf
|
||||
$(BOOTJAR) -cfm $@ $(BUILD_DIR)/javadoc.mf $(patsubst %,-C $(CLASSES_DIR) %, $(JAVADOC_DIRS))
|
||||
|
||||
#----- javah
|
||||
|
||||
JAVAH_DIRS = \
|
||||
com/sun/tools/javah
|
||||
|
||||
JAVAH_RESOURCE_FILES = \
|
||||
$(shell find $(patsubst %,$(SRC_CLASSES_DIR)/%,$(JAVAH_DIRS)) -name SCCS -prune -o -name \*.properties -print )
|
||||
|
||||
JAVAH_JAVA_FILES = \
|
||||
$(shell find $(patsubst %,$(SRC_CLASSES_DIR)/%,$(JAVAH_DIRS)) -name SCCS -prune -o -name \*.java -print ) \
|
||||
$(patsubst $(SRC_CLASSES_DIR)/%.properties,$(GENSRC_DIR)/%.java,$(JAVAH_RESOURCE_FILES))
|
||||
|
||||
$(JAVAH_JAR): $(JAVAH_JAVA_FILES) $(JAVADOC_JAR)
|
||||
$(MKDIR) -p $(CLASSES_DIR) $(@D)
|
||||
$(BOOT_JAVAC) -sourcepath "" -classpath $(CLASSES_DIR) -d $(CLASSES_DIR) -target $(TARGET_LEVEL) $(JAVAH_JAVA_FILES)
|
||||
( $(ECHO) Main-Class: com.sun.tools.javah.Main ; $(ECHO) Class-Path: javadoc.jar ) > $(BUILD_DIR)/javah.mf
|
||||
$(BOOTJAR) -cfm $@ $(BUILD_DIR)/javah.mf $(patsubst %,-C $(CLASSES_DIR) %, $(JAVAH_DIRS))
|
||||
|
||||
#----- javap
|
||||
|
||||
JAVAP_DIRS = \
|
||||
sun/tools/javap
|
||||
|
||||
JAVAP_RESOURCE_FILES = \
|
||||
$(shell find $(patsubst %,$(SRC_CLASSES_DIR)/%,$(JAVAP_DIRS)) -name SCCS -prune -o -name \*.properties -print )
|
||||
|
||||
JAVAP_JAVA_FILES = \
|
||||
$(shell find $(patsubst %,$(SRC_CLASSES_DIR)/%,$(JAVAP_DIRS)) -name SCCS -prune -o -name \*.java -print ) \
|
||||
$(patsubst $(SRC_CLASSES_DIR)/%.properties,$(GENSRC_DIR)/%.java,$(JAVAP_RESOURCE_FILES))
|
||||
|
||||
$(JAVAP_JAR): $(JAVAP_JAVA_FILES) \
|
||||
$(patsubst $(SRC_CLASSES_DIR)/%.properties,$(GENSRC_DIR)/%.java,$(JAVAP_RESOURCE_FILES))
|
||||
$(MKDIR) -p $(CLASSES_DIR)
|
||||
$(BOOT_JAVAC) -sourcepath "" -classpath $(CLASSES_DIR) -d $(CLASSES_DIR) -target $(TARGET_LEVEL) $(JAVAP_JAVA_FILES)
|
||||
( $(ECHO) Main-Class: sun.tools.javap.Main ) > $(BUILD_DIR)/javap.mf
|
||||
$(BOOTJAR) -cfm $@ $(BUILD_DIR)/javap.mf $(patsubst %,-C $(CLASSES_DIR) %, $(JAVAP_DIRS))
|
||||
|
||||
#-----
|
||||
|
||||
build-tools: $(BUILDTOOLCLASSES_DIR)/CompileProperties/CompileProperties.class
|
||||
|
||||
$(GENSRC_DIR)/%.java: $(SRC_CLASSES_DIR)/%.properties $(BUILDTOOLCLASSES_DIR)/CompileProperties/CompileProperties.class
|
||||
$(MKDIR) -p $(@D)
|
||||
$(BOOT_JAVA) -cp $(BUILDTOOLCLASSES_DIR)/CompileProperties CompileProperties $< $(patsubst $(CLASSES_DIR)/%.class,$(GENSRC_DIR)/%.java,$@)
|
||||
|
||||
$(GENSRC_DIR)/%.java: $(GENSRC_DIR)/%.properties $(BUILDTOOLCLASSES_DIR)/CompileProperties/CompileProperties.class
|
||||
$(MKDIR) -p $(@D)
|
||||
$(BOOT_JAVA) -cp $(BUILDTOOLCLASSES_DIR)/CompileProperties CompileProperties $< $(patsubst $(CLASSES_DIR)/%.class,$(GENSRC_DIR)/%.java,$@)
|
||||
|
||||
$(GENSRC_DIR)/%.properties: $(SRC_CLASSES_DIR)/%.properties-template
|
||||
$(MKDIR) -p $(@D)
|
||||
$(SED) -e 's/$$(JDK_VERSION)/$(JDK_VERSION)/' \
|
||||
-e 's/$$(FULL_VERSION)/$(FULL_VERSION)/' \
|
||||
-e 's/$$(RELEASE)/$(RELEASE)/' \
|
||||
< $< > $@
|
||||
|
||||
$(BUILDTOOLCLASSES_DIR)/%.class : $(BUILDTOOLSRC_DIR)/%.java
|
||||
$(MKDIR) -p $(@D)
|
||||
$(BOOT_JAVAC) -d $(@D) $<
|
||||
|
||||
#----- all classes
|
||||
|
||||
$(DIST_DIR)/%/classes.jar: $(JAVAC_JAR) $(JAVADOC_JAR) $(JAVAH_JAR) $(JAVAP_JAR)
|
||||
$(MKDIR) -p $(@D)
|
||||
$(BOOTJAR) -cf $@ -C $(CLASSES_DIR) .
|
||||
|
||||
#----- src.zip
|
||||
|
||||
SRC_ZIP_FILES = $(shell $(FIND) $(SRC_CLASSES_DIR) \( -name SCCS -o -name \*-template \) -prune -o -type f -print )
|
||||
|
||||
$(DIST_DIR)/%/src.zip: $(SRC_ZIP_FILES)
|
||||
abs_src_zip=`cd $(@D) ; pwd`/$(@F) ; \
|
||||
( cd $(SRC_CLASSES_DIR) ; $(FIND) . \( -name SCCS -o -name \*-template \) -prune -o -type f -print | $(ZIP) -q $$abs_src_zip -@ ) ; \
|
||||
( cd $(SRC_CLASSES_DIR) ; $(FIND) . -name SCCS -prune -o -name \*-template -print | $(SED) -e 's/-template//' ) | ( cd $(GENSRC_DIR) ; $(ZIP) -q $$abs_src_zip -@ )
|
||||
|
||||
#----- bin files
|
||||
|
||||
$(BIN_DIR)/%: $(SRC_BIN_DIR)/launcher.sh-template
|
||||
$(MKDIR) -p $(@D)
|
||||
$(SED) -e 's|#PROGRAM#|$(@F)|' -e 's|#TARGET_JAVA#|$(TARGET_JAVA)|' $< > $@
|
||||
$(CHMOD) +x $@
|
||||
|
||||
#-----
|
||||
|
||||
findbugs: $(BUILD_DIR)/findbugs.txt
|
||||
|
||||
$(BUILD_DIR)/findbugs.txt: $(CLASSES_JAR)
|
||||
$(MKDIR) -p $(@D)
|
||||
$(FINDBUGS) -textui -javahome $(BOOT_JAVA_HOME) -high -emacs -outputFile $@ $<
|
||||
|
||||
#-----
|
||||
|
||||
quick-check: $(patsubst %, $(DIST_LIB_DIR)/%.jar, $(TOOLS))
|
||||
$(TESTJAVA) -jar $(JAVAC_JAR) -version
|
||||
- $(TESTJAVA) -jar $(JAVADOC_JAR) -version
|
||||
$(TESTJAVA) -jar $(JAVAH_JAR) -version
|
||||
- $(TESTJAVA) -jar $(JAVAP_JAR) -version
|
||||
|
||||
#-----
|
||||
|
||||
.PHONY: \
|
||||
all \
|
||||
build \
|
||||
build-tools \
|
||||
clean \
|
||||
default \
|
||||
findbugs \
|
||||
jprt_product_build \
|
||||
jprt_debug_build \
|
||||
jprt_fastdebug_build \
|
||||
tools
|
||||
|
@ -716,6 +716,29 @@
|
||||
|
||||
<target name="sjavac" depends="build-sjavac,jtreg-sjavac,findbugs-sjavac"/>
|
||||
|
||||
<!--
|
||||
**** crules targets.
|
||||
-->
|
||||
|
||||
<target name="build-crules" depends="-def-compilecrules,-def-build-jar-with-services">
|
||||
<compilecrules/>
|
||||
<build-jar-with-services
|
||||
name="crules"
|
||||
includes="crules/* crules/resources/*"
|
||||
classes.dir="${build.toolclasses.dir}"
|
||||
lib.dir="${build.toolclasses.dir}"
|
||||
jarmainclass=""
|
||||
jarclasspath="crules.jar"
|
||||
service.type="com.sun.source.util.Plugin"
|
||||
service.provider="crules.MutableFieldsAnalyzer"/>
|
||||
<build-tool name="crules"/>
|
||||
</target>
|
||||
|
||||
<target name="check-coding-rules" depends="build-bootstrap-javac,-create-import-jdk-stubs,build-crules">
|
||||
<build-classes includes="${javac.includes}"
|
||||
plugin.options="-J-Xbootclasspath/a:${build.toolclasses.dir}/crules.jar -Xplugin:mutable_fields_analyzer" />
|
||||
</target>
|
||||
|
||||
<!--
|
||||
**** Create import JDK stubs.
|
||||
-->
|
||||
@ -811,6 +834,31 @@
|
||||
</macrodef>
|
||||
</target>
|
||||
|
||||
<target name="-def-build-jar-with-services">
|
||||
<macrodef name="build-jar-with-services">
|
||||
<attribute name="name"/>
|
||||
<attribute name="includes"/>
|
||||
<attribute name="classes.dir" default="${build.classes.dir}"/>
|
||||
<attribute name="lib.dir" default="${dist.lib.dir}"/>
|
||||
<attribute name="jarmainclass" default="com.sun.tools.@{name}.Main"/>
|
||||
<attribute name="jarclasspath" default=""/>
|
||||
<attribute name="service.type" default=""/>
|
||||
<attribute name="service.provider" default=""/>
|
||||
<sequential>
|
||||
<mkdir dir="${build.toolclasses.dir}"/>
|
||||
<jar destfile="@{lib.dir}/@{name}.jar"
|
||||
basedir="@{classes.dir}"
|
||||
includes="@{includes}">
|
||||
<service type="@{service.type}" provider="@{service.provider}"/>
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="@{jarmainclass}"/>
|
||||
<attribute name="Class-Path" value="@{jarclasspath}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
|
||||
<target name="-def-build-classes" depends="-def-pcompile">
|
||||
<macrodef name="build-classes">
|
||||
<attribute name="includes"/>
|
||||
@ -826,6 +874,7 @@
|
||||
<attribute name="target" default="${javac.target}"/>
|
||||
<attribute name="release" default="${release}"/>
|
||||
<attribute name="full.version" default="${full.version}"/>
|
||||
<attribute name="plugin.options" default=""/>
|
||||
<sequential>
|
||||
<echo level="verbose" message="build-classes: excludes=@{excludes}"/>
|
||||
<echo level="verbose" message="build-classes: bootclasspath.opt=@{bootclasspath.opt}"/>
|
||||
@ -868,6 +917,7 @@
|
||||
<compilerarg line="${javac.no.jdk.warnings}"/>
|
||||
<compilerarg line="${javac.version.opt}"/>
|
||||
<compilerarg line="${javac.lint.opts}"/>
|
||||
<compilerarg line="@{plugin.options}"/>
|
||||
</javac>
|
||||
<copy todir="@{classes.dir}" includeemptydirs="false">
|
||||
<fileset dir="${src.classes.dir}" includes="@{includes}" excludes="@{excludes}">
|
||||
@ -935,6 +985,32 @@
|
||||
classpath="${build.toolclasses.dir}/"/>
|
||||
</target>
|
||||
|
||||
<target name="-def-compilecrules">
|
||||
<macrodef name="compilecrules">
|
||||
<sequential>
|
||||
<mkdir dir="${build.toolclasses.dir}"/>
|
||||
<javac fork="true"
|
||||
source="${boot.javac.source}"
|
||||
target="${boot.javac.target}"
|
||||
executable="${boot.java.home}/bin/javac"
|
||||
srcdir="${make.tools.dir}"
|
||||
includes="crules/*"
|
||||
destdir="${build.toolclasses.dir}/"
|
||||
classpath="${ant.core.lib}"
|
||||
bootclasspath="${boot.java.home}/jre/lib/rt.jar"
|
||||
includeantruntime="false">
|
||||
<compilerarg value="-Xbootclasspath/p:${build.bootstrap.dir}/classes"/>
|
||||
<compilerarg line="${javac.lint.opts}"/>
|
||||
</javac>
|
||||
<copy todir="${build.toolclasses.dir}/" includeemptydirs="false">
|
||||
<fileset dir="${make.tools.dir}">
|
||||
<include name="**/*.properties"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
|
||||
<target name="-def-genstubs" depends="build-bootstrap-javac" if="require.import.jdk.stubs">
|
||||
<mkdir dir="${build.toolclasses.dir}"/>
|
||||
<javac fork="true"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -67,7 +67,7 @@
|
||||
</folders>
|
||||
<ide-actions>
|
||||
<!--
|
||||
Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -96,7 +96,7 @@
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
<!--
|
||||
<!--
|
||||
This file defines the standard actions accepted by langtools projects.
|
||||
It is normally included as an entity into a project's project.xml file.
|
||||
|
||||
@ -104,7 +104,7 @@
|
||||
- NetBeans: Setting Up Projects
|
||||
at http://www.netbeans.org/kb/55/using-netbeans/project_setup.html
|
||||
- NetBeans: Advanced Freeform Project Configuration
|
||||
at http://www.netbeans.org/kb/41/freeform-config.html
|
||||
at http://www.netbeans.org/kb/41/freeform-config.html
|
||||
-->
|
||||
<action name="build">
|
||||
<target>build</target>
|
||||
@ -144,7 +144,7 @@
|
||||
</arity>
|
||||
</context>
|
||||
</action>
|
||||
<!--
|
||||
<!--
|
||||
Note: NetBeans does not appear to support context menu items
|
||||
on shell scripts :-(
|
||||
-->
|
||||
@ -178,7 +178,7 @@
|
||||
</arity>
|
||||
</context>
|
||||
</action>
|
||||
<!--
|
||||
<!--
|
||||
Note: NetBeans does not appear to support context menu items
|
||||
on shell scripts :-(
|
||||
-->
|
||||
@ -239,10 +239,6 @@
|
||||
<label>Build files</label>
|
||||
<location>${root}/make</location>
|
||||
</source-folder>
|
||||
<source-folder style="packages">
|
||||
<label>Source files</label>
|
||||
<location>${root}/src/share/classes</location>
|
||||
</source-folder>
|
||||
<source-file>
|
||||
<label>README</label>
|
||||
<location>README</location>
|
||||
@ -250,7 +246,7 @@
|
||||
</items>
|
||||
<context-menu>
|
||||
<!--
|
||||
Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -279,7 +275,7 @@
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
<!--
|
||||
<!--
|
||||
This file defines the actions that will appear on the project's context
|
||||
menu, in the Projects viewer.
|
||||
It is normally included as an entity into a project's project.xml file.
|
||||
@ -288,7 +284,7 @@
|
||||
- NetBeans: Setting Up Projects
|
||||
at http://www.netbeans.org/kb/55/using-netbeans/project_setup.html
|
||||
- NetBeans: Advanced Freeform Project Configuration
|
||||
at http://www.netbeans.org/kb/41/freeform-config.html
|
||||
at http://www.netbeans.org/kb/41/freeform-config.html
|
||||
-->
|
||||
<ide-action name="select-tool"/>
|
||||
<separator/>
|
||||
@ -305,11 +301,11 @@
|
||||
</view>
|
||||
<subprojects/>
|
||||
</general-data>
|
||||
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/2">
|
||||
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3">
|
||||
<compilation-unit>
|
||||
<package-root>${root}/src/share/classes</package-root>
|
||||
<built-to>${root}/build/classes</built-to>
|
||||
<source-level>1.5</source-level>
|
||||
<source-level>1.7</source-level>
|
||||
</compilation-unit>
|
||||
</java-data>
|
||||
</configuration>
|
||||
|
117
langtools/make/tools/crules/AbstractCodingRulesAnalyzer.java
Normal file
117
langtools/make/tools/crules/AbstractCodingRulesAnalyzer.java
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package crules;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.source.tree.Tree;
|
||||
import com.sun.source.util.JavacTask;
|
||||
import com.sun.source.util.Plugin;
|
||||
import com.sun.source.util.TaskEvent;
|
||||
import com.sun.source.util.TaskListener;
|
||||
import com.sun.source.util.Trees;
|
||||
import com.sun.tools.javac.api.BasicJavacTask;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.TreeScanner;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.Log;
|
||||
|
||||
import static com.sun.source.util.TaskEvent.Kind;
|
||||
|
||||
public abstract class AbstractCodingRulesAnalyzer implements Plugin {
|
||||
|
||||
protected Log log;
|
||||
protected Trees trees;
|
||||
protected TreeScanner treeVisitor;
|
||||
protected Kind eventKind;
|
||||
protected Messages messages;
|
||||
|
||||
public void init(JavacTask task, String... args) {
|
||||
BasicJavacTask impl = (BasicJavacTask)task;
|
||||
Context context = impl.getContext();
|
||||
log = Log.instance(context);
|
||||
trees = Trees.instance(task);
|
||||
messages = new Messages();
|
||||
task.addTaskListener(new PostAnalyzeTaskListener());
|
||||
}
|
||||
|
||||
public class PostAnalyzeTaskListener implements TaskListener {
|
||||
|
||||
@Override
|
||||
public void started(TaskEvent taskEvent) {}
|
||||
|
||||
@Override
|
||||
public void finished(TaskEvent taskEvent) {
|
||||
if (taskEvent.getKind().equals(eventKind)) {
|
||||
TypeElement typeElem = taskEvent.getTypeElement();
|
||||
Tree tree = trees.getTree(typeElem);
|
||||
if (tree != null) {
|
||||
JavaFileObject prevSource = log.currentSourceFile();
|
||||
try {
|
||||
log.useSource(taskEvent.getCompilationUnit().getSourceFile());
|
||||
treeVisitor.scan((JCTree)tree);
|
||||
} finally {
|
||||
log.useSource(prevSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Messages {
|
||||
ResourceBundle bundle;
|
||||
|
||||
Messages() {
|
||||
String name = getClass().getPackage().getName() + ".resources.crules";
|
||||
bundle = ResourceBundle.getBundle(name, Locale.ENGLISH);
|
||||
}
|
||||
|
||||
public void error(JCTree tree, String code, Object... args) {
|
||||
String msg = (code == null) ? (String) args[0] : localize(code, args);
|
||||
log.error(tree, "proc.messager", msg.toString());
|
||||
}
|
||||
|
||||
private String localize(String code, Object... args) {
|
||||
String msg = bundle.getString(code);
|
||||
if (msg == null) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("message file broken: code=").append(code);
|
||||
if (args.length > 0) {
|
||||
sb.append(" arguments={0}");
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
sb.append(", {").append(i).append("}");
|
||||
}
|
||||
}
|
||||
msg = sb.toString();
|
||||
}
|
||||
return MessageFormat.format(msg, args);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
118
langtools/make/tools/crules/MutableFieldsAnalyzer.java
Normal file
118
langtools/make/tools/crules/MutableFieldsAnalyzer.java
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package crules;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.tools.javac.code.Kinds;
|
||||
import com.sun.tools.javac.tree.TreeScanner;
|
||||
|
||||
import static com.sun.source.util.TaskEvent.Kind;
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
|
||||
public class MutableFieldsAnalyzer extends AbstractCodingRulesAnalyzer {
|
||||
|
||||
public MutableFieldsAnalyzer() {
|
||||
treeVisitor = new MutableFieldsVisitor();
|
||||
eventKind = Kind.ANALYZE;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "mutable_fields_analyzer";
|
||||
}
|
||||
|
||||
private boolean ignoreField(String className, String field) {
|
||||
List<String> currentFieldsToIgnore =
|
||||
classFieldsToIgnoreMap.get(className);
|
||||
if (currentFieldsToIgnore != null) {
|
||||
for (String fieldToIgnore : currentFieldsToIgnore) {
|
||||
if (field.equals(fieldToIgnore)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class MutableFieldsVisitor extends TreeScanner {
|
||||
|
||||
@Override
|
||||
public void visitVarDef(JCVariableDecl tree) {
|
||||
boolean isJavacPack = tree.sym.outermostClass().fullname.toString()
|
||||
.contains(packageToCheck);
|
||||
if (isJavacPack &&
|
||||
(tree.sym.flags() & SYNTHETIC) == 0 &&
|
||||
tree.sym.owner.kind == Kinds.TYP) {
|
||||
if (!ignoreField(tree.sym.owner.flatName().toString(),
|
||||
tree.getName().toString())) {
|
||||
boolean enumClass = (tree.sym.owner.flags() & ENUM) != 0;
|
||||
boolean nonFinalStaticEnumField =
|
||||
(tree.sym.flags() & (ENUM | FINAL)) == 0;
|
||||
boolean nonFinalStaticField =
|
||||
(tree.sym.flags() & STATIC) != 0 &&
|
||||
(tree.sym.flags() & FINAL) == 0;
|
||||
if (enumClass ? nonFinalStaticEnumField : nonFinalStaticField) {
|
||||
messages.error(tree, "crules.err.var.must.be.final", tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
super.visitVarDef(tree);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final String packageToCheck = "com.sun.tools.javac";
|
||||
|
||||
private static final Map<String, List<String>> classFieldsToIgnoreMap =
|
||||
new HashMap<String, List<String>>();
|
||||
|
||||
static {
|
||||
classFieldsToIgnoreMap.
|
||||
put("com.sun.tools.javac.util.JCDiagnostic",
|
||||
Arrays.asList("fragmentFormatter"));
|
||||
classFieldsToIgnoreMap.
|
||||
put("com.sun.tools.javac.util.JavacMessages",
|
||||
Arrays.asList("defaultBundle", "defaultMessages"));
|
||||
classFieldsToIgnoreMap.
|
||||
put("com.sun.tools.javac.file.ZipFileIndexCache",
|
||||
Arrays.asList("sharedInstance"));
|
||||
classFieldsToIgnoreMap.
|
||||
put("com.sun.tools.javac.main.JavaCompiler",
|
||||
Arrays.asList("versionRB"));
|
||||
classFieldsToIgnoreMap.
|
||||
put("com.sun.tools.javac.code.Type",
|
||||
Arrays.asList("moreInfo"));
|
||||
classFieldsToIgnoreMap.
|
||||
put("com.sun.tools.javac.util.SharedNameTable",
|
||||
Arrays.asList("freelist"));
|
||||
classFieldsToIgnoreMap.
|
||||
put("com.sun.tools.javac.util.Log",
|
||||
Arrays.asList("useRawMessages"));
|
||||
}
|
||||
|
||||
}
|
28
langtools/make/tools/crules/resources/crules.properties
Normal file
28
langtools/make/tools/crules/resources/crules.properties
Normal file
@ -0,0 +1,28 @@
|
||||
#
|
||||
# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
# 0: symbol
|
||||
crules.err.var.must.be.final=\
|
||||
Static variable {0} must be final
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.source.util;
|
||||
|
||||
import com.sun.source.doctree.DocCommentTree;
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import com.sun.source.tree.CompilationUnitTree;
|
||||
|
||||
/**
|
||||
* Provides methods to obtain the position of a DocTree within a javadoc comment.
|
||||
* A position is defined as a simple character offset from the start of a
|
||||
* CompilationUnit where the first character is at offset 0.
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
@jdk.Supported
|
||||
public interface DocSourcePositions extends SourcePositions {
|
||||
|
||||
/**
|
||||
* Gets the starting position of the tree within the comment within the file. If tree is not found within
|
||||
* file, or if the starting position is not available,
|
||||
* return {@link javax.tools.Diagnostic#NOPOS}.
|
||||
* The given tree should be under the given comment tree, and the given documentation
|
||||
* comment tree should be returned from a {@link DocTrees#getDocCommentTree(com.sun.source.util.TreePath) }
|
||||
* for a tree under the given file.
|
||||
* The returned position must be at the start of the yield of this tree, that
|
||||
* is for any sub-tree of this tree, the following must hold:
|
||||
*
|
||||
* <p>
|
||||
* {@code tree.getStartPosition() <= subtree.getStartPosition()} or <br>
|
||||
* {@code tree.getStartPosition() == NOPOS} or <br>
|
||||
* {@code subtree.getStartPosition() == NOPOS}
|
||||
* </p>
|
||||
*
|
||||
* @param file CompilationUnit in which to find tree.
|
||||
* @param comment the comment tree that encloses the tree for which the
|
||||
* position is being sought
|
||||
* @param tree tree for which a position is sought.
|
||||
* @return the start position of tree.
|
||||
*/
|
||||
long getStartPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree);
|
||||
|
||||
/**
|
||||
* Gets the ending position of the tree within the comment within the file. If tree is not found within
|
||||
* file, or if the ending position is not available,
|
||||
* return {@link javax.tools.Diagnostic#NOPOS}.
|
||||
* The given tree should be under the given comment tree, and the given documentation
|
||||
* comment tree should be returned from a {@link DocTrees#getDocCommentTree(com.sun.source.util.TreePath) }
|
||||
* for a tree under the given file.
|
||||
* The returned position must be at the end of the yield of this tree,
|
||||
* that is for any sub-tree of this tree, the following must hold:
|
||||
*
|
||||
* <p>
|
||||
* {@code tree.getEndPosition() >= subtree.getEndPosition()} or <br>
|
||||
* {@code tree.getEndPosition() == NOPOS} or <br>
|
||||
* {@code subtree.getEndPosition() == NOPOS}
|
||||
* </p>
|
||||
*
|
||||
* In addition, the following must hold:
|
||||
*
|
||||
* <p>
|
||||
* {@code tree.getStartPosition() <= tree.getEndPosition()} or <br>
|
||||
* {@code tree.getStartPosition() == NOPOS} or <br>
|
||||
* {@code tree.getEndPosition() == NOPOS}
|
||||
* </p>
|
||||
*
|
||||
* @param file CompilationUnit in which to find tree.
|
||||
* @param comment the comment tree that encloses the tree for which the
|
||||
* position is being sought
|
||||
* @param tree tree for which a position is sought.
|
||||
* @return the start position of tree.
|
||||
*/
|
||||
long getEndPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree);
|
||||
|
||||
}
|
@ -72,6 +72,8 @@ public abstract class DocTrees extends Trees {
|
||||
*/
|
||||
public abstract Element getElement(TreePath path, ReferenceTree reference);
|
||||
|
||||
public abstract DocSourcePositions getSourcePositions();
|
||||
|
||||
/**
|
||||
* Prints a message of the specified kind at the location of the
|
||||
* tree within the provided compilation unit
|
||||
|
@ -59,7 +59,7 @@ public interface SourcePositions {
|
||||
|
||||
/**
|
||||
* Gets the ending position of tree within file. If tree is not found within
|
||||
* file, or if the starting position is not available,
|
||||
* file, or if the ending position is not available,
|
||||
* return {@link javax.tools.Diagnostic#NOPOS}.
|
||||
* The returned position must be at the end of the yield of this tree,
|
||||
* that is for any sub-tree of this tree, the following must hold:
|
||||
|
@ -315,7 +315,7 @@ public class Dependencies {
|
||||
static class SimpleLocation implements Location {
|
||||
public SimpleLocation(String name) {
|
||||
this.name = name;
|
||||
this.className = name.replace('/', '.').replace('$', '.');
|
||||
this.className = name.replace('/', '.');
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.classfile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import com.sun.tools.classfile.Instruction.TypeKind;
|
||||
import static com.sun.tools.classfile.ConstantPool.*;
|
||||
|
||||
/**
|
||||
* A utility class to find where in a ClassFile references
|
||||
* a {@link CONSTANT_Methodref_info method},
|
||||
* a {@link CONSTANT_InterfaceMethodref_info interface method,
|
||||
* or a {@link CONSTANT_Fieldref_info field}.
|
||||
*/
|
||||
public final class ReferenceFinder {
|
||||
/**
|
||||
* Filter for ReferenceFinder of what constant pool entries for reference lookup.
|
||||
*/
|
||||
public interface Filter {
|
||||
/**
|
||||
* Decides if the given CPRefInfo entry should be accepted or filtered.
|
||||
*
|
||||
* @param cpool ConstantPool of the ClassFile being parsed
|
||||
* @param cpref constant pool entry representing a reference to
|
||||
* a fields method, and interface method.
|
||||
* @return {@code true} if accepted; otherwise {@code false}
|
||||
*/
|
||||
boolean accept(ConstantPool cpool, CPRefInfo cpref);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor of individual method of a ClassFile that references the
|
||||
* accepted field, method, or interface method references.
|
||||
*/
|
||||
public interface Visitor {
|
||||
/**
|
||||
* Invoked for a method containing one or more accepted CPRefInfo entries
|
||||
*
|
||||
* @param cf ClassFile
|
||||
* @param method Method that does the references the accepted references
|
||||
* @param refs Accepted constant pool method/field reference
|
||||
*/
|
||||
void visit(ClassFile cf, Method method, List<CPRefInfo> refConstantPool);
|
||||
}
|
||||
|
||||
private final Filter filter;
|
||||
private final Visitor visitor;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public ReferenceFinder(Filter filter, Visitor visitor) {
|
||||
this.filter = Objects.requireNonNull(filter);
|
||||
this.visitor = Objects.requireNonNull(visitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a given ClassFile and invoke the visitor if there is any reference
|
||||
* to the constant pool entries referencing field, method, or
|
||||
* interface method that are accepted. This method will return
|
||||
* {@code true} if there is one or more accepted constant pool entries
|
||||
* to lookup; otherwise, it will return {@code false}.
|
||||
*
|
||||
* @param cf ClassFile
|
||||
* @return {@code true} if the given class file is processed to lookup
|
||||
* references
|
||||
* @throws ConstantPoolException if an error of the constant pool
|
||||
*/
|
||||
public boolean parse(ClassFile cf) throws ConstantPoolException {
|
||||
List<Integer> cprefs = new ArrayList<Integer>();
|
||||
int index = 1;
|
||||
for (ConstantPool.CPInfo cpInfo : cf.constant_pool.entries()) {
|
||||
if (cpInfo.accept(cpVisitor, cf.constant_pool)) {
|
||||
cprefs.add(index);
|
||||
}
|
||||
index += cpInfo.size();
|
||||
}
|
||||
|
||||
if (cprefs.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Method m : cf.methods) {
|
||||
Set<Integer> ids = new HashSet<Integer>();
|
||||
Code_attribute c_attr = (Code_attribute) m.attributes.get(Attribute.Code);
|
||||
if (c_attr != null) {
|
||||
for (Instruction instr : c_attr.getInstructions()) {
|
||||
int idx = instr.accept(codeVisitor, cprefs);
|
||||
if (idx > 0) {
|
||||
ids.add(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ids.size() > 0) {
|
||||
List<CPRefInfo> refInfos = new ArrayList<CPRefInfo>(ids.size());
|
||||
for (int id : ids) {
|
||||
refInfos.add(CPRefInfo.class.cast(cf.constant_pool.get(id)));
|
||||
}
|
||||
visitor.visit(cf, m, refInfos);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ConstantPool.Visitor<Boolean,ConstantPool> cpVisitor =
|
||||
new ConstantPool.Visitor<Boolean,ConstantPool>()
|
||||
{
|
||||
public Boolean visitClass(CONSTANT_Class_info info, ConstantPool cpool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, ConstantPool cpool) {
|
||||
return filter.accept(cpool, info);
|
||||
}
|
||||
|
||||
public Boolean visitMethodref(CONSTANT_Methodref_info info, ConstantPool cpool) {
|
||||
return filter.accept(cpool, info);
|
||||
}
|
||||
|
||||
public Boolean visitFieldref(CONSTANT_Fieldref_info info, ConstantPool cpool) {
|
||||
return filter.accept(cpool, info);
|
||||
}
|
||||
|
||||
public Boolean visitDouble(CONSTANT_Double_info info, ConstantPool cpool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean visitFloat(CONSTANT_Float_info info, ConstantPool cpool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean visitInteger(CONSTANT_Integer_info info, ConstantPool cpool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, ConstantPool cpool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean visitLong(CONSTANT_Long_info info, ConstantPool cpool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean visitNameAndType(CONSTANT_NameAndType_info info, ConstantPool cpool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean visitMethodHandle(CONSTANT_MethodHandle_info info, ConstantPool cpool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean visitMethodType(CONSTANT_MethodType_info info, ConstantPool cpool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean visitString(CONSTANT_String_info info, ConstantPool cpool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Boolean visitUtf8(CONSTANT_Utf8_info info, ConstantPool cpool) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private Instruction.KindVisitor<Integer, List<Integer>> codeVisitor =
|
||||
new Instruction.KindVisitor<Integer, List<Integer>>()
|
||||
{
|
||||
public Integer visitNoOperands(Instruction instr, List<Integer> p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Integer visitArrayType(Instruction instr, TypeKind kind, List<Integer> p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Integer visitBranch(Instruction instr, int offset, List<Integer> p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Integer visitConstantPoolRef(Instruction instr, int index, List<Integer> p) {
|
||||
return p.contains(index) ? index : 0;
|
||||
}
|
||||
|
||||
public Integer visitConstantPoolRefAndValue(Instruction instr, int index, int value, List<Integer> p) {
|
||||
return p.contains(index) ? index : 0;
|
||||
}
|
||||
|
||||
public Integer visitLocal(Instruction instr, int index, List<Integer> p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Integer visitLocalAndValue(Instruction instr, int index, int value, List<Integer> p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Integer visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, List<Integer> p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Integer visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, List<Integer> p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Integer visitValue(Instruction instr, int value, List<Integer> p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Integer visitUnknown(Instruction instr, List<Integer> p) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -43,14 +43,16 @@ import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.source.doctree.DocCommentTree;
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import com.sun.source.doctree.ReferenceTree;
|
||||
import com.sun.source.tree.CatchTree;
|
||||
import com.sun.source.tree.CompilationUnitTree;
|
||||
import com.sun.source.tree.Scope;
|
||||
import com.sun.source.tree.Tree;
|
||||
import com.sun.source.util.DocSourcePositions;
|
||||
import com.sun.source.util.DocTreeScanner;
|
||||
import com.sun.source.util.DocTrees;
|
||||
import com.sun.source.util.JavacTask;
|
||||
import com.sun.source.util.SourcePositions;
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Kinds;
|
||||
@ -76,8 +78,14 @@ import com.sun.tools.javac.comp.Resolve;
|
||||
import com.sun.tools.javac.model.JavacElements;
|
||||
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
|
||||
import com.sun.tools.javac.tree.DCTree;
|
||||
import com.sun.tools.javac.tree.DCTree.DCBlockTag;
|
||||
import com.sun.tools.javac.tree.DCTree.DCDocComment;
|
||||
import com.sun.tools.javac.tree.DCTree.DCEndPosTree;
|
||||
import com.sun.tools.javac.tree.DCTree.DCErroneous;
|
||||
import com.sun.tools.javac.tree.DCTree.DCIdentifier;
|
||||
import com.sun.tools.javac.tree.DCTree.DCParam;
|
||||
import com.sun.tools.javac.tree.DCTree.DCReference;
|
||||
import com.sun.tools.javac.tree.DCTree.DCText;
|
||||
import com.sun.tools.javac.tree.EndPosTable;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
@ -94,6 +102,7 @@ import com.sun.tools.javac.util.Log;
|
||||
import com.sun.tools.javac.util.Name;
|
||||
import com.sun.tools.javac.util.Names;
|
||||
import com.sun.tools.javac.util.Pair;
|
||||
import com.sun.tools.javac.util.Position;
|
||||
import static com.sun.tools.javac.code.TypeTag.*;
|
||||
|
||||
/**
|
||||
@ -166,8 +175,8 @@ public class JavacTrees extends DocTrees {
|
||||
javacTaskImpl = (JavacTaskImpl) t;
|
||||
}
|
||||
|
||||
public SourcePositions getSourcePositions() {
|
||||
return new SourcePositions() {
|
||||
public DocSourcePositions getSourcePositions() {
|
||||
return new DocSourcePositions() {
|
||||
public long getStartPosition(CompilationUnitTree file, Tree tree) {
|
||||
return TreeInfo.getStartPos((JCTree) tree);
|
||||
}
|
||||
@ -176,9 +185,80 @@ public class JavacTrees extends DocTrees {
|
||||
EndPosTable endPosTable = ((JCCompilationUnit) file).endPositions;
|
||||
return TreeInfo.getEndPos((JCTree) tree, endPosTable);
|
||||
}
|
||||
|
||||
public long getStartPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree) {
|
||||
return ((DCTree) tree).getSourcePosition((DCDocComment) comment);
|
||||
}
|
||||
@SuppressWarnings("fallthrough")
|
||||
public long getEndPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree) {
|
||||
DCDocComment dcComment = (DCDocComment) comment;
|
||||
if (tree instanceof DCEndPosTree) {
|
||||
int endPos = ((DCEndPosTree) tree).getEndPos(dcComment);
|
||||
|
||||
if (endPos != Position.NOPOS) {
|
||||
return endPos;
|
||||
}
|
||||
}
|
||||
int correction = 0;
|
||||
switch (tree.getKind()) {
|
||||
case TEXT:
|
||||
DCText text = (DCText) tree;
|
||||
|
||||
return dcComment.comment.getSourcePos(text.pos + text.text.length());
|
||||
case ERRONEOUS:
|
||||
DCErroneous err = (DCErroneous) tree;
|
||||
|
||||
return dcComment.comment.getSourcePos(err.pos + err.body.length());
|
||||
case IDENTIFIER:
|
||||
DCIdentifier ident = (DCIdentifier) tree;
|
||||
|
||||
return dcComment.comment.getSourcePos(ident.pos + (ident.name != names.error ? ident.name.length() : 0));
|
||||
case PARAM:
|
||||
DCParam param = (DCParam) tree;
|
||||
|
||||
if (param.isTypeParameter && param.getDescription().isEmpty()) {
|
||||
correction = 1;
|
||||
}
|
||||
case AUTHOR: case DEPRECATED: case RETURN: case SEE:
|
||||
case SERIAL: case SERIAL_DATA: case SERIAL_FIELD: case SINCE:
|
||||
case THROWS: case UNKNOWN_BLOCK_TAG: case VERSION: {
|
||||
DocTree last = getLastChild(tree);
|
||||
|
||||
if (last != null) {
|
||||
return getEndPosition(file, comment, last) + correction;
|
||||
}
|
||||
|
||||
DCBlockTag block = (DCBlockTag) tree;
|
||||
|
||||
return dcComment.comment.getSourcePos(block.pos + block.getTagName().length() + 1);
|
||||
}
|
||||
default:
|
||||
DocTree last = getLastChild(tree);
|
||||
|
||||
if (last != null) {
|
||||
return getEndPosition(file, comment, last);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return Position.NOPOS;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private DocTree getLastChild(DocTree tree) {
|
||||
final DocTree[] last = new DocTree[] {null};
|
||||
|
||||
tree.accept(new DocTreeScanner<Void, Void>() {
|
||||
@Override public Void scan(DocTree node, Void p) {
|
||||
if (node != null) last[0] = node;
|
||||
return null;
|
||||
}
|
||||
}, null);
|
||||
|
||||
return last[0];
|
||||
}
|
||||
|
||||
public JCClassDecl getTree(TypeElement element) {
|
||||
return (JCClassDecl) getTree((Element) element);
|
||||
}
|
||||
|
@ -465,18 +465,11 @@ public abstract class Symbol implements Element {
|
||||
* This is the implementation for {@code
|
||||
* javax.lang.model.element.Element.getAnnotationMirrors()}.
|
||||
*/
|
||||
public final List<? extends AnnotationMirror> getAnnotationMirrors() {
|
||||
@Override
|
||||
public List<Attribute.Compound> getAnnotationMirrors() {
|
||||
return getRawAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Should there be a {@code
|
||||
* javax.lang.model.element.Element.getTypeAnnotationMirrors()}.
|
||||
*/
|
||||
public final List<Attribute.TypeCompound> getTypeAnnotationMirrors() {
|
||||
return getRawTypeAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated this method should never be used by javac internally.
|
||||
*/
|
||||
@ -656,6 +649,24 @@ public abstract class Symbol implements Element {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Attribute.Compound> getAnnotationMirrors() {
|
||||
return onlyTypeVariableAnnotations(owner.getRawTypeAttributes());
|
||||
}
|
||||
|
||||
private List<Attribute.Compound> onlyTypeVariableAnnotations(
|
||||
List<Attribute.TypeCompound> candidates) {
|
||||
// Declaration annotations on TypeParameters are stored in type attributes
|
||||
List<Attribute.Compound> res = List.nil();
|
||||
for (Attribute.TypeCompound a : candidates) {
|
||||
if (a.position.type == TargetType.CLASS_TYPE_PARAMETER ||
|
||||
a.position.type == TargetType.METHOD_TYPE_PARAMETER)
|
||||
res = res.prepend(a);
|
||||
}
|
||||
|
||||
return res = res.reverse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, P> R accept(ElementVisitor<R, P> v, P p) {
|
||||
return v.visitTypeParameter(this, p);
|
||||
|
@ -206,7 +206,7 @@ public class TypeAnnotations {
|
||||
sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
|
||||
// Make sure all type annotations from the symbol are also
|
||||
// on the owner.
|
||||
sym.owner.annotations.appendUniqueTypes(sym.getTypeAnnotationMirrors());
|
||||
sym.owner.annotations.appendUniqueTypes(sym.getRawTypeAttributes());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1078,7 +1078,8 @@ public class Check {
|
||||
mask = MethodFlags;
|
||||
}
|
||||
// Imply STRICTFP if owner has STRICTFP set.
|
||||
if (((flags|implicit) & Flags.ABSTRACT) == 0)
|
||||
if (((flags|implicit) & Flags.ABSTRACT) == 0 ||
|
||||
((flags) & Flags.DEFAULT) != 0)
|
||||
implicit |= sym.owner.flags_field & STRICTFP;
|
||||
break;
|
||||
case TYP:
|
||||
|
@ -35,7 +35,6 @@ import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.comp.Resolve;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
@ -276,6 +275,15 @@ public class Flow {
|
||||
allowEffectivelyFinalInInnerClasses = source.allowEffectivelyFinalInInnerClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to reset several Bits instances.
|
||||
*/
|
||||
private void resetBits(Bits... bits) {
|
||||
for (Bits b : bits) {
|
||||
b.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base visitor class for all visitors implementing dataflow analysis logic.
|
||||
* This class define the shared logic for handling jumps (break/continue statements).
|
||||
@ -1294,11 +1302,11 @@ public class Flow {
|
||||
|
||||
/** The set of definitely assigned variables.
|
||||
*/
|
||||
Bits inits;
|
||||
final Bits inits;
|
||||
|
||||
/** The set of definitely unassigned variables.
|
||||
*/
|
||||
Bits uninits;
|
||||
final Bits uninits;
|
||||
|
||||
/** The set of variables that are definitely unassigned everywhere
|
||||
* in current try block. This variable is maintained lazily; it is
|
||||
@ -1308,15 +1316,15 @@ public class Flow {
|
||||
* anywhere in current try block, intersect uninitsTry and
|
||||
* uninits.
|
||||
*/
|
||||
Bits uninitsTry;
|
||||
final Bits uninitsTry;
|
||||
|
||||
/** When analyzing a condition, inits and uninits are null.
|
||||
* Instead we have:
|
||||
*/
|
||||
Bits initsWhenTrue;
|
||||
Bits initsWhenFalse;
|
||||
Bits uninitsWhenTrue;
|
||||
Bits uninitsWhenFalse;
|
||||
final Bits initsWhenTrue;
|
||||
final Bits initsWhenFalse;
|
||||
final Bits uninitsWhenTrue;
|
||||
final Bits uninitsWhenFalse;
|
||||
|
||||
/** A mapping from addresses to variable symbols.
|
||||
*/
|
||||
@ -1348,15 +1356,25 @@ public class Flow {
|
||||
/** The starting position of the analysed tree */
|
||||
int startPos;
|
||||
|
||||
AssignAnalyzer() {
|
||||
inits = new Bits();
|
||||
uninits = new Bits();
|
||||
uninitsTry = new Bits();
|
||||
initsWhenTrue = new Bits(true);
|
||||
initsWhenFalse = new Bits(true);
|
||||
uninitsWhenTrue = new Bits(true);
|
||||
uninitsWhenFalse = new Bits(true);
|
||||
}
|
||||
|
||||
class AssignPendingExit extends BaseAnalyzer.PendingExit {
|
||||
|
||||
Bits exit_inits;
|
||||
Bits exit_uninits;
|
||||
final Bits exit_inits = new Bits(true);
|
||||
final Bits exit_uninits = new Bits(true);
|
||||
|
||||
AssignPendingExit(JCTree tree, Bits inits, Bits uninits) {
|
||||
AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
|
||||
super(tree);
|
||||
this.exit_inits = inits.dup();
|
||||
this.exit_uninits = uninits.dup();
|
||||
this.exit_inits.assign(inits);
|
||||
this.exit_uninits.assign(uninits);
|
||||
}
|
||||
|
||||
void resolveJump() {
|
||||
@ -1476,19 +1494,20 @@ public class Flow {
|
||||
/** Split (duplicate) inits/uninits into WhenTrue/WhenFalse sets
|
||||
*/
|
||||
void split(boolean setToNull) {
|
||||
initsWhenFalse = inits.dup();
|
||||
uninitsWhenFalse = uninits.dup();
|
||||
initsWhenTrue = inits;
|
||||
uninitsWhenTrue = uninits;
|
||||
if (setToNull)
|
||||
inits = uninits = null;
|
||||
initsWhenFalse.assign(inits);
|
||||
uninitsWhenFalse.assign(uninits);
|
||||
initsWhenTrue.assign(inits);
|
||||
uninitsWhenTrue.assign(uninits);
|
||||
if (setToNull) {
|
||||
resetBits(inits, uninits);
|
||||
}
|
||||
}
|
||||
|
||||
/** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets.
|
||||
*/
|
||||
void merge() {
|
||||
inits = initsWhenFalse.andSet(initsWhenTrue);
|
||||
uninits = uninitsWhenFalse.andSet(uninitsWhenTrue);
|
||||
inits.assign(initsWhenFalse.andSet(initsWhenTrue));
|
||||
uninits.assign(uninitsWhenFalse.andSet(uninitsWhenTrue));
|
||||
}
|
||||
|
||||
/* ************************************************************************
|
||||
@ -1501,7 +1520,7 @@ public class Flow {
|
||||
void scanExpr(JCTree tree) {
|
||||
if (tree != null) {
|
||||
scan(tree);
|
||||
if (inits == null) merge();
|
||||
if (inits.isReset()) merge();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1518,28 +1537,29 @@ public class Flow {
|
||||
*/
|
||||
void scanCond(JCTree tree) {
|
||||
if (tree.type.isFalse()) {
|
||||
if (inits == null) merge();
|
||||
initsWhenTrue = inits.dup();
|
||||
if (inits.isReset()) merge();
|
||||
initsWhenTrue.assign(inits);
|
||||
initsWhenTrue.inclRange(firstadr, nextadr);
|
||||
uninitsWhenTrue = uninits.dup();
|
||||
uninitsWhenTrue.assign(uninits);
|
||||
uninitsWhenTrue.inclRange(firstadr, nextadr);
|
||||
initsWhenFalse = inits;
|
||||
uninitsWhenFalse = uninits;
|
||||
initsWhenFalse.assign(inits);
|
||||
uninitsWhenFalse.assign(uninits);
|
||||
} else if (tree.type.isTrue()) {
|
||||
if (inits == null) merge();
|
||||
initsWhenFalse = inits.dup();
|
||||
if (inits.isReset()) merge();
|
||||
initsWhenFalse.assign(inits);
|
||||
initsWhenFalse.inclRange(firstadr, nextadr);
|
||||
uninitsWhenFalse = uninits.dup();
|
||||
uninitsWhenFalse.assign(uninits);
|
||||
uninitsWhenFalse.inclRange(firstadr, nextadr);
|
||||
initsWhenTrue = inits;
|
||||
uninitsWhenTrue = uninits;
|
||||
initsWhenTrue.assign(inits);
|
||||
uninitsWhenTrue.assign(uninits);
|
||||
} else {
|
||||
scan(tree);
|
||||
if (inits != null)
|
||||
if (!inits.isReset())
|
||||
split(tree.type != syms.unknownType);
|
||||
}
|
||||
if (tree.type != syms.unknownType)
|
||||
inits = uninits = null;
|
||||
if (tree.type != syms.unknownType) {
|
||||
resetBits(inits, uninits);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------ Visitor methods for various sorts of trees -------------*/
|
||||
@ -1619,8 +1639,8 @@ public class Flow {
|
||||
public void visitMethodDef(JCMethodDecl tree) {
|
||||
if (tree.body == null) return;
|
||||
|
||||
Bits initsPrev = inits.dup();
|
||||
Bits uninitsPrev = uninits.dup();
|
||||
final Bits initsPrev = new Bits(inits);
|
||||
final Bits uninitsPrev = new Bits(uninits);
|
||||
int nextadrPrev = nextadr;
|
||||
int firstadrPrev = firstadr;
|
||||
int returnadrPrev = returnadr;
|
||||
@ -1658,14 +1678,14 @@ public class Flow {
|
||||
exits = exits.tail;
|
||||
Assert.check(exit.tree.hasTag(RETURN), exit.tree);
|
||||
if (isInitialConstructor) {
|
||||
inits = exit.exit_inits;
|
||||
inits.assign(exit.exit_inits);
|
||||
for (int i = firstadr; i < nextadr; i++)
|
||||
checkInit(exit.tree.pos(), vars[i]);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
inits = initsPrev;
|
||||
uninits = uninitsPrev;
|
||||
inits.assign(initsPrev);
|
||||
uninits.assign(uninitsPrev);
|
||||
nextadr = nextadrPrev;
|
||||
firstadr = firstadrPrev;
|
||||
returnadr = returnadrPrev;
|
||||
@ -1698,31 +1718,31 @@ public class Flow {
|
||||
ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
|
||||
FlowKind prevFlowKind = flowKind;
|
||||
flowKind = FlowKind.NORMAL;
|
||||
Bits initsSkip = null;
|
||||
Bits uninitsSkip = null;
|
||||
final Bits initsSkip = new Bits(true);
|
||||
final Bits uninitsSkip = new Bits(true);
|
||||
pendingExits = new ListBuffer<AssignPendingExit>();
|
||||
int prevErrors = log.nerrors;
|
||||
do {
|
||||
Bits uninitsEntry = uninits.dup();
|
||||
final Bits uninitsEntry = new Bits(uninits);
|
||||
uninitsEntry.excludeFrom(nextadr);
|
||||
scan(tree.body);
|
||||
resolveContinues(tree);
|
||||
scanCond(tree.cond);
|
||||
if (!flowKind.isFinal()) {
|
||||
initsSkip = initsWhenFalse;
|
||||
uninitsSkip = uninitsWhenFalse;
|
||||
initsSkip.assign(initsWhenFalse);
|
||||
uninitsSkip.assign(uninitsWhenFalse);
|
||||
}
|
||||
if (log.nerrors != prevErrors ||
|
||||
flowKind.isFinal() ||
|
||||
uninitsEntry.dup().diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
|
||||
new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
|
||||
break;
|
||||
inits = initsWhenTrue;
|
||||
uninits = uninitsEntry.andSet(uninitsWhenTrue);
|
||||
inits.assign(initsWhenTrue);
|
||||
uninits.assign(uninitsEntry.andSet(uninitsWhenTrue));
|
||||
flowKind = FlowKind.SPECULATIVE_LOOP;
|
||||
} while (true);
|
||||
flowKind = prevFlowKind;
|
||||
inits = initsSkip;
|
||||
uninits = uninitsSkip;
|
||||
inits.assign(initsSkip);
|
||||
uninits.assign(uninitsSkip);
|
||||
resolveBreaks(tree, prevPendingExits);
|
||||
}
|
||||
|
||||
@ -1730,34 +1750,34 @@ public class Flow {
|
||||
ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
|
||||
FlowKind prevFlowKind = flowKind;
|
||||
flowKind = FlowKind.NORMAL;
|
||||
Bits initsSkip = null;
|
||||
Bits uninitsSkip = null;
|
||||
final Bits initsSkip = new Bits(true);
|
||||
final Bits uninitsSkip = new Bits(true);
|
||||
pendingExits = new ListBuffer<AssignPendingExit>();
|
||||
int prevErrors = log.nerrors;
|
||||
Bits uninitsEntry = uninits.dup();
|
||||
final Bits uninitsEntry = new Bits(uninits);
|
||||
uninitsEntry.excludeFrom(nextadr);
|
||||
do {
|
||||
scanCond(tree.cond);
|
||||
if (!flowKind.isFinal()) {
|
||||
initsSkip = initsWhenFalse;
|
||||
uninitsSkip = uninitsWhenFalse;
|
||||
initsSkip.assign(initsWhenFalse) ;
|
||||
uninitsSkip.assign(uninitsWhenFalse);
|
||||
}
|
||||
inits = initsWhenTrue;
|
||||
uninits = uninitsWhenTrue;
|
||||
inits.assign(initsWhenTrue);
|
||||
uninits.assign(uninitsWhenTrue);
|
||||
scan(tree.body);
|
||||
resolveContinues(tree);
|
||||
if (log.nerrors != prevErrors ||
|
||||
flowKind.isFinal() ||
|
||||
uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
|
||||
new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
|
||||
break;
|
||||
uninits = uninitsEntry.andSet(uninits);
|
||||
uninits.assign(uninitsEntry.andSet(uninits));
|
||||
flowKind = FlowKind.SPECULATIVE_LOOP;
|
||||
} while (true);
|
||||
flowKind = prevFlowKind;
|
||||
//a variable is DA/DU after the while statement, if it's DA/DU assuming the
|
||||
//branch is not taken AND if it's DA/DU before any break statement
|
||||
inits = initsSkip;
|
||||
uninits = uninitsSkip;
|
||||
inits.assign(initsSkip);
|
||||
uninits.assign(uninitsSkip);
|
||||
resolveBreaks(tree, prevPendingExits);
|
||||
}
|
||||
|
||||
@ -1767,25 +1787,25 @@ public class Flow {
|
||||
flowKind = FlowKind.NORMAL;
|
||||
int nextadrPrev = nextadr;
|
||||
scan(tree.init);
|
||||
Bits initsSkip = null;
|
||||
Bits uninitsSkip = null;
|
||||
final Bits initsSkip = new Bits(true);
|
||||
final Bits uninitsSkip = new Bits(true);
|
||||
pendingExits = new ListBuffer<AssignPendingExit>();
|
||||
int prevErrors = log.nerrors;
|
||||
do {
|
||||
Bits uninitsEntry = uninits.dup();
|
||||
final Bits uninitsEntry = new Bits(uninits);
|
||||
uninitsEntry.excludeFrom(nextadr);
|
||||
if (tree.cond != null) {
|
||||
scanCond(tree.cond);
|
||||
if (!flowKind.isFinal()) {
|
||||
initsSkip = initsWhenFalse;
|
||||
uninitsSkip = uninitsWhenFalse;
|
||||
initsSkip.assign(initsWhenFalse);
|
||||
uninitsSkip.assign(uninitsWhenFalse);
|
||||
}
|
||||
inits = initsWhenTrue;
|
||||
uninits = uninitsWhenTrue;
|
||||
inits.assign(initsWhenTrue);
|
||||
uninits.assign(uninitsWhenTrue);
|
||||
} else if (!flowKind.isFinal()) {
|
||||
initsSkip = inits.dup();
|
||||
initsSkip.assign(inits);
|
||||
initsSkip.inclRange(firstadr, nextadr);
|
||||
uninitsSkip = uninits.dup();
|
||||
uninitsSkip.assign(uninits);
|
||||
uninitsSkip.inclRange(firstadr, nextadr);
|
||||
}
|
||||
scan(tree.body);
|
||||
@ -1793,16 +1813,16 @@ public class Flow {
|
||||
scan(tree.step);
|
||||
if (log.nerrors != prevErrors ||
|
||||
flowKind.isFinal() ||
|
||||
uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
|
||||
new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
|
||||
break;
|
||||
uninits = uninitsEntry.andSet(uninits);
|
||||
uninits.assign(uninitsEntry.andSet(uninits));
|
||||
flowKind = FlowKind.SPECULATIVE_LOOP;
|
||||
} while (true);
|
||||
flowKind = prevFlowKind;
|
||||
//a variable is DA/DU after a for loop, if it's DA/DU assuming the
|
||||
//branch is not taken AND if it's DA/DU before any break statement
|
||||
inits = initsSkip;
|
||||
uninits = uninitsSkip;
|
||||
inits.assign(initsSkip);
|
||||
uninits.assign(uninitsSkip);
|
||||
resolveBreaks(tree, prevPendingExits);
|
||||
nextadr = nextadrPrev;
|
||||
}
|
||||
@ -1815,27 +1835,27 @@ public class Flow {
|
||||
flowKind = FlowKind.NORMAL;
|
||||
int nextadrPrev = nextadr;
|
||||
scan(tree.expr);
|
||||
Bits initsStart = inits.dup();
|
||||
Bits uninitsStart = uninits.dup();
|
||||
final Bits initsStart = new Bits(inits);
|
||||
final Bits uninitsStart = new Bits(uninits);
|
||||
|
||||
letInit(tree.pos(), tree.var.sym);
|
||||
pendingExits = new ListBuffer<AssignPendingExit>();
|
||||
int prevErrors = log.nerrors;
|
||||
do {
|
||||
Bits uninitsEntry = uninits.dup();
|
||||
final Bits uninitsEntry = new Bits(uninits);
|
||||
uninitsEntry.excludeFrom(nextadr);
|
||||
scan(tree.body);
|
||||
resolveContinues(tree);
|
||||
if (log.nerrors != prevErrors ||
|
||||
flowKind.isFinal() ||
|
||||
uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
|
||||
new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
|
||||
break;
|
||||
uninits = uninitsEntry.andSet(uninits);
|
||||
uninits.assign(uninitsEntry.andSet(uninits));
|
||||
flowKind = FlowKind.SPECULATIVE_LOOP;
|
||||
} while (true);
|
||||
flowKind = prevFlowKind;
|
||||
inits = initsStart;
|
||||
uninits = uninitsStart.andSet(uninits);
|
||||
inits.assign(initsStart);
|
||||
uninits.assign(uninitsStart.andSet(uninits));
|
||||
resolveBreaks(tree, prevPendingExits);
|
||||
nextadr = nextadrPrev;
|
||||
}
|
||||
@ -1852,12 +1872,12 @@ public class Flow {
|
||||
pendingExits = new ListBuffer<AssignPendingExit>();
|
||||
int nextadrPrev = nextadr;
|
||||
scanExpr(tree.selector);
|
||||
Bits initsSwitch = inits;
|
||||
Bits uninitsSwitch = uninits.dup();
|
||||
final Bits initsSwitch = new Bits(inits);
|
||||
final Bits uninitsSwitch = new Bits(uninits);
|
||||
boolean hasDefault = false;
|
||||
for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
|
||||
inits = initsSwitch.dup();
|
||||
uninits = uninits.andSet(uninitsSwitch);
|
||||
inits.assign(initsSwitch);
|
||||
uninits.assign(uninits.andSet(uninitsSwitch));
|
||||
JCCase c = l.head;
|
||||
if (c.pat == null)
|
||||
hasDefault = true;
|
||||
@ -1875,8 +1895,8 @@ public class Flow {
|
||||
}
|
||||
// where
|
||||
/** Add any variables defined in stats to inits and uninits. */
|
||||
private void addVars(List<JCStatement> stats, Bits inits,
|
||||
Bits uninits) {
|
||||
private void addVars(List<JCStatement> stats, final Bits inits,
|
||||
final Bits uninits) {
|
||||
for (;stats.nonEmpty(); stats = stats.tail) {
|
||||
JCTree stat = stats.head;
|
||||
if (stat.hasTag(VARDEF)) {
|
||||
@ -1889,11 +1909,11 @@ public class Flow {
|
||||
|
||||
public void visitTry(JCTry tree) {
|
||||
ListBuffer<JCVariableDecl> resourceVarDecls = ListBuffer.lb();
|
||||
Bits uninitsTryPrev = uninitsTry;
|
||||
final Bits uninitsTryPrev = new Bits(uninitsTry);
|
||||
ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
|
||||
pendingExits = new ListBuffer<AssignPendingExit>();
|
||||
Bits initsTry = inits.dup();
|
||||
uninitsTry = uninits.dup();
|
||||
final Bits initsTry = new Bits(inits);
|
||||
uninitsTry.assign(uninits);
|
||||
for (JCTree resource : tree.resources) {
|
||||
if (resource instanceof JCVariableDecl) {
|
||||
JCVariableDecl vdecl = (JCVariableDecl) resource;
|
||||
@ -1908,8 +1928,8 @@ public class Flow {
|
||||
}
|
||||
scan(tree.body);
|
||||
uninitsTry.andSet(uninits);
|
||||
Bits initsEnd = inits;
|
||||
Bits uninitsEnd = uninits;
|
||||
final Bits initsEnd = new Bits(inits);
|
||||
final Bits uninitsEnd = new Bits(uninits);
|
||||
int nextadrCatch = nextadr;
|
||||
|
||||
if (!resourceVarDecls.isEmpty() &&
|
||||
@ -1925,8 +1945,8 @@ public class Flow {
|
||||
|
||||
for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
|
||||
JCVariableDecl param = l.head.param;
|
||||
inits = initsTry.dup();
|
||||
uninits = uninitsTry.dup();
|
||||
inits.assign(initsTry);
|
||||
uninits.assign(uninitsTry);
|
||||
scan(param);
|
||||
inits.incl(param.sym.adr);
|
||||
uninits.excl(param.sym.adr);
|
||||
@ -1936,8 +1956,8 @@ public class Flow {
|
||||
nextadr = nextadrCatch;
|
||||
}
|
||||
if (tree.finalizer != null) {
|
||||
inits = initsTry.dup();
|
||||
uninits = uninitsTry.dup();
|
||||
inits.assign(initsTry);
|
||||
uninits.assign(uninitsTry);
|
||||
ListBuffer<AssignPendingExit> exits = pendingExits;
|
||||
pendingExits = prevPendingExits;
|
||||
scan(tree.finalizer);
|
||||
@ -1958,8 +1978,8 @@ public class Flow {
|
||||
inits.orSet(initsEnd);
|
||||
}
|
||||
} else {
|
||||
inits = initsEnd;
|
||||
uninits = uninitsEnd;
|
||||
inits.assign(initsEnd);
|
||||
uninits.assign(uninitsEnd);
|
||||
ListBuffer<AssignPendingExit> exits = pendingExits;
|
||||
pendingExits = prevPendingExits;
|
||||
while (exits.nonEmpty()) pendingExits.append(exits.next());
|
||||
@ -1969,10 +1989,10 @@ public class Flow {
|
||||
|
||||
public void visitConditional(JCConditional tree) {
|
||||
scanCond(tree.cond);
|
||||
Bits initsBeforeElse = initsWhenFalse;
|
||||
Bits uninitsBeforeElse = uninitsWhenFalse;
|
||||
inits = initsWhenTrue;
|
||||
uninits = uninitsWhenTrue;
|
||||
final Bits initsBeforeElse = new Bits(initsWhenFalse);
|
||||
final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
|
||||
inits.assign(initsWhenTrue);
|
||||
uninits.assign(uninitsWhenTrue);
|
||||
if (tree.truepart.type.hasTag(BOOLEAN) &&
|
||||
tree.falsepart.type.hasTag(BOOLEAN)) {
|
||||
// if b and c are boolean valued, then
|
||||
@ -1980,12 +2000,12 @@ public class Flow {
|
||||
// v is (un)assigned after b when true and
|
||||
// v is (un)assigned after c when true
|
||||
scanCond(tree.truepart);
|
||||
Bits initsAfterThenWhenTrue = initsWhenTrue.dup();
|
||||
Bits initsAfterThenWhenFalse = initsWhenFalse.dup();
|
||||
Bits uninitsAfterThenWhenTrue = uninitsWhenTrue.dup();
|
||||
Bits uninitsAfterThenWhenFalse = uninitsWhenFalse.dup();
|
||||
inits = initsBeforeElse;
|
||||
uninits = uninitsBeforeElse;
|
||||
final Bits initsAfterThenWhenTrue = new Bits(initsWhenTrue);
|
||||
final Bits initsAfterThenWhenFalse = new Bits(initsWhenFalse);
|
||||
final Bits uninitsAfterThenWhenTrue = new Bits(uninitsWhenTrue);
|
||||
final Bits uninitsAfterThenWhenFalse = new Bits(uninitsWhenFalse);
|
||||
inits.assign(initsBeforeElse);
|
||||
uninits.assign(uninitsBeforeElse);
|
||||
scanCond(tree.falsepart);
|
||||
initsWhenTrue.andSet(initsAfterThenWhenTrue);
|
||||
initsWhenFalse.andSet(initsAfterThenWhenFalse);
|
||||
@ -1993,10 +2013,10 @@ public class Flow {
|
||||
uninitsWhenFalse.andSet(uninitsAfterThenWhenFalse);
|
||||
} else {
|
||||
scanExpr(tree.truepart);
|
||||
Bits initsAfterThen = inits.dup();
|
||||
Bits uninitsAfterThen = uninits.dup();
|
||||
inits = initsBeforeElse;
|
||||
uninits = uninitsBeforeElse;
|
||||
final Bits initsAfterThen = new Bits(inits);
|
||||
final Bits uninitsAfterThen = new Bits(uninits);
|
||||
inits.assign(initsBeforeElse);
|
||||
uninits.assign(uninitsBeforeElse);
|
||||
scanExpr(tree.falsepart);
|
||||
inits.andSet(initsAfterThen);
|
||||
uninits.andSet(uninitsAfterThen);
|
||||
@ -2005,16 +2025,16 @@ public class Flow {
|
||||
|
||||
public void visitIf(JCIf tree) {
|
||||
scanCond(tree.cond);
|
||||
Bits initsBeforeElse = initsWhenFalse;
|
||||
Bits uninitsBeforeElse = uninitsWhenFalse;
|
||||
inits = initsWhenTrue;
|
||||
uninits = uninitsWhenTrue;
|
||||
final Bits initsBeforeElse = new Bits(initsWhenFalse);
|
||||
final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
|
||||
inits.assign(initsWhenTrue);
|
||||
uninits.assign(uninitsWhenTrue);
|
||||
scan(tree.thenpart);
|
||||
if (tree.elsepart != null) {
|
||||
Bits initsAfterThen = inits.dup();
|
||||
Bits uninitsAfterThen = uninits.dup();
|
||||
inits = initsBeforeElse;
|
||||
uninits = uninitsBeforeElse;
|
||||
final Bits initsAfterThen = new Bits(inits);
|
||||
final Bits uninitsAfterThen = new Bits(uninits);
|
||||
inits.assign(initsBeforeElse);
|
||||
uninits.assign(uninitsBeforeElse);
|
||||
scan(tree.elsepart);
|
||||
inits.andSet(initsAfterThen);
|
||||
uninits.andSet(uninitsAfterThen);
|
||||
@ -2055,8 +2075,8 @@ public class Flow {
|
||||
|
||||
@Override
|
||||
public void visitLambda(JCLambda tree) {
|
||||
Bits prevUninits = uninits;
|
||||
Bits prevInits = inits;
|
||||
final Bits prevUninits = new Bits(uninits);
|
||||
final Bits prevInits = new Bits(inits);
|
||||
int returnadrPrev = returnadr;
|
||||
ListBuffer<AssignPendingExit> prevPending = pendingExits;
|
||||
try {
|
||||
@ -2076,8 +2096,8 @@ public class Flow {
|
||||
}
|
||||
finally {
|
||||
returnadr = returnadrPrev;
|
||||
uninits = prevUninits;
|
||||
inits = prevInits;
|
||||
uninits.assign(prevUninits);
|
||||
inits.assign(prevInits);
|
||||
pendingExits = prevPending;
|
||||
}
|
||||
}
|
||||
@ -2088,17 +2108,17 @@ public class Flow {
|
||||
}
|
||||
|
||||
public void visitAssert(JCAssert tree) {
|
||||
Bits initsExit = inits.dup();
|
||||
Bits uninitsExit = uninits.dup();
|
||||
final Bits initsExit = new Bits(inits);
|
||||
final Bits uninitsExit = new Bits(uninits);
|
||||
scanCond(tree.cond);
|
||||
uninitsExit.andSet(uninitsWhenTrue);
|
||||
if (tree.detail != null) {
|
||||
inits = initsWhenFalse;
|
||||
uninits = uninitsWhenFalse;
|
||||
inits.assign(initsWhenFalse);
|
||||
uninits.assign(uninitsWhenFalse);
|
||||
scanExpr(tree.detail);
|
||||
}
|
||||
inits = initsExit;
|
||||
uninits = uninitsExit;
|
||||
inits.assign(initsExit);
|
||||
uninits.assign(uninitsExit);
|
||||
}
|
||||
|
||||
public void visitAssign(JCAssign tree) {
|
||||
@ -2120,12 +2140,12 @@ public class Flow {
|
||||
switch (tree.getTag()) {
|
||||
case NOT:
|
||||
scanCond(tree.arg);
|
||||
Bits t = initsWhenFalse;
|
||||
initsWhenFalse = initsWhenTrue;
|
||||
initsWhenTrue = t;
|
||||
t = uninitsWhenFalse;
|
||||
uninitsWhenFalse = uninitsWhenTrue;
|
||||
uninitsWhenTrue = t;
|
||||
final Bits t = new Bits(initsWhenFalse);
|
||||
initsWhenFalse.assign(initsWhenTrue);
|
||||
initsWhenTrue.assign(t);
|
||||
t.assign(uninitsWhenFalse);
|
||||
uninitsWhenFalse.assign(uninitsWhenTrue);
|
||||
uninitsWhenTrue.assign(t);
|
||||
break;
|
||||
case PREINC: case POSTINC:
|
||||
case PREDEC: case POSTDEC:
|
||||
@ -2141,20 +2161,20 @@ public class Flow {
|
||||
switch (tree.getTag()) {
|
||||
case AND:
|
||||
scanCond(tree.lhs);
|
||||
Bits initsWhenFalseLeft = initsWhenFalse;
|
||||
Bits uninitsWhenFalseLeft = uninitsWhenFalse;
|
||||
inits = initsWhenTrue;
|
||||
uninits = uninitsWhenTrue;
|
||||
final Bits initsWhenFalseLeft = new Bits(initsWhenFalse);
|
||||
final Bits uninitsWhenFalseLeft = new Bits(uninitsWhenFalse);
|
||||
inits.assign(initsWhenTrue);
|
||||
uninits.assign(uninitsWhenTrue);
|
||||
scanCond(tree.rhs);
|
||||
initsWhenFalse.andSet(initsWhenFalseLeft);
|
||||
uninitsWhenFalse.andSet(uninitsWhenFalseLeft);
|
||||
break;
|
||||
case OR:
|
||||
scanCond(tree.lhs);
|
||||
Bits initsWhenTrueLeft = initsWhenTrue;
|
||||
Bits uninitsWhenTrueLeft = uninitsWhenTrue;
|
||||
inits = initsWhenFalse;
|
||||
uninits = uninitsWhenFalse;
|
||||
final Bits initsWhenTrueLeft = new Bits(initsWhenTrue);
|
||||
final Bits uninitsWhenTrueLeft = new Bits(uninitsWhenTrue);
|
||||
inits.assign(initsWhenFalse);
|
||||
uninits.assign(uninitsWhenFalse);
|
||||
scanCond(tree.rhs);
|
||||
initsWhenTrue.andSet(initsWhenTrueLeft);
|
||||
uninitsWhenTrue.andSet(uninitsWhenTrueLeft);
|
||||
@ -2200,11 +2220,7 @@ public class Flow {
|
||||
attrEnv = env;
|
||||
Flow.this.make = make;
|
||||
startPos = tree.pos().getStartPosition();
|
||||
inits = new Bits();
|
||||
uninits = new Bits();
|
||||
uninitsTry = new Bits();
|
||||
initsWhenTrue = initsWhenFalse =
|
||||
uninitsWhenTrue = uninitsWhenFalse = null;
|
||||
|
||||
if (vars == null)
|
||||
vars = new VarSymbol[32];
|
||||
else
|
||||
@ -2219,9 +2235,8 @@ public class Flow {
|
||||
} finally {
|
||||
// note that recursive invocations of this method fail hard
|
||||
startPos = -1;
|
||||
inits = uninits = uninitsTry = null;
|
||||
initsWhenTrue = initsWhenFalse =
|
||||
uninitsWhenTrue = uninitsWhenFalse = null;
|
||||
resetBits(inits, uninits, uninitsTry, initsWhenTrue,
|
||||
initsWhenFalse, uninitsWhenTrue, uninitsWhenFalse);
|
||||
if (vars != null) for (int i=0; i<vars.length; i++)
|
||||
vars[i] = null;
|
||||
firstadr = 0;
|
||||
|
@ -40,10 +40,9 @@ import com.sun.tools.javac.code.Symbol.MethodSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.VarSymbol;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Type.ClassType;
|
||||
import com.sun.tools.javac.code.Type.MethodType;
|
||||
import com.sun.tools.javac.code.Types;
|
||||
import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzer.*;
|
||||
import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzerPreprocessor.*;
|
||||
import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector;
|
||||
import com.sun.tools.javac.jvm.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
@ -81,7 +80,7 @@ public class LambdaToMethod extends TreeTranslator {
|
||||
private Env<AttrContext> attrEnv;
|
||||
|
||||
/** the analyzer scanner */
|
||||
private LambdaAnalyzer analyzer;
|
||||
private LambdaAnalyzerPreprocessor analyzer;
|
||||
|
||||
/** map from lambda trees to translation contexts */
|
||||
private Map<JCTree, TranslationContext<?>> contextMap;
|
||||
@ -156,7 +155,7 @@ public class LambdaToMethod extends TreeTranslator {
|
||||
make = TreeMaker.instance(context);
|
||||
types = Types.instance(context);
|
||||
transTypes = TransTypes.instance(context);
|
||||
analyzer = new LambdaAnalyzer();
|
||||
analyzer = new LambdaAnalyzerPreprocessor();
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
@ -206,7 +205,7 @@ public class LambdaToMethod extends TreeTranslator {
|
||||
public void visitClassDef(JCClassDecl tree) {
|
||||
if (tree.sym.owner.kind == PCK) {
|
||||
//analyze class
|
||||
analyzer.analyzeClass(tree);
|
||||
tree = analyzer.analyzeAndPreprocessClass(tree);
|
||||
}
|
||||
KlassInfo prevKlassInfo = kInfo;
|
||||
try {
|
||||
@ -531,16 +530,25 @@ public class LambdaToMethod extends TreeTranslator {
|
||||
/** Make an attributed class instance creation expression.
|
||||
* @param ctype The class type.
|
||||
* @param args The constructor arguments.
|
||||
* @param cons The constructor symbol
|
||||
*/
|
||||
JCNewClass makeNewClass(Type ctype, List<JCExpression> args) {
|
||||
JCNewClass makeNewClass(Type ctype, List<JCExpression> args, Symbol cons) {
|
||||
JCNewClass tree = make.NewClass(null,
|
||||
null, make.QualIdent(ctype.tsym), args, null);
|
||||
tree.constructor = rs.resolveConstructor(
|
||||
null, attrEnv, ctype, TreeInfo.types(args), List.<Type>nil());
|
||||
tree.constructor = cons;
|
||||
tree.type = ctype;
|
||||
return tree;
|
||||
}
|
||||
|
||||
/** Make an attributed class instance creation expression.
|
||||
* @param ctype The class type.
|
||||
* @param args The constructor arguments.
|
||||
*/
|
||||
JCNewClass makeNewClass(Type ctype, List<JCExpression> args) {
|
||||
return makeNewClass(ctype, args,
|
||||
rs.resolveConstructor(null, attrEnv, ctype, TreeInfo.types(args), List.<Type>nil()));
|
||||
}
|
||||
|
||||
private void addDeserializationCase(int implMethodKind, Symbol refSym, Type targetType, MethodSymbol samSym,
|
||||
DiagnosticPosition pos, List<Object> staticArgs, MethodType indyType) {
|
||||
String functionalInterfaceClass = classSig(targetType);
|
||||
@ -1019,8 +1027,9 @@ public class LambdaToMethod extends TreeTranslator {
|
||||
* This visitor collects information about translation of a lambda expression.
|
||||
* More specifically, it keeps track of the enclosing contexts and captured locals
|
||||
* accessed by the lambda being translated (as well as other useful info).
|
||||
* It also translates away problems for LambdaToMethod.
|
||||
*/
|
||||
class LambdaAnalyzer extends TreeScanner {
|
||||
class LambdaAnalyzerPreprocessor extends TreeTranslator {
|
||||
|
||||
/** the frame stack - used to reconstruct translation info about enclosing scopes */
|
||||
private List<Frame> frameStack;
|
||||
@ -1047,10 +1056,10 @@ public class LambdaToMethod extends TreeTranslator {
|
||||
private Map<ClassSymbol, Symbol> clinits =
|
||||
new HashMap<ClassSymbol, Symbol>();
|
||||
|
||||
private void analyzeClass(JCClassDecl tree) {
|
||||
private JCClassDecl analyzeAndPreprocessClass(JCClassDecl tree) {
|
||||
frameStack = List.nil();
|
||||
localClassDefs = new HashMap<Symbol, JCClassDecl>();
|
||||
scan(tree);
|
||||
return translate(tree);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1154,7 +1163,7 @@ public class LambdaToMethod extends TreeTranslator {
|
||||
frameStack.head.addLocal(param.sym);
|
||||
}
|
||||
contextMap.put(tree, context);
|
||||
scan(tree.body);
|
||||
super.visitLambda(tree);
|
||||
context.complete();
|
||||
}
|
||||
finally {
|
||||
@ -1220,12 +1229,47 @@ public class LambdaToMethod extends TreeTranslator {
|
||||
};
|
||||
fvc.scan(localCDef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method references to local class constructors, may, if the local
|
||||
* class references local variables, have implicit constructor
|
||||
* parameters added in Lower; As a result, the invokedynamic bootstrap
|
||||
* information added in the LambdaToMethod pass will have the wrong
|
||||
* signature. Hooks between Lower and LambdaToMethod have been added to
|
||||
* handle normal "new" in this case. This visitor converts potentially
|
||||
* effected method references into a lambda containing a normal "new" of
|
||||
* the class.
|
||||
*
|
||||
* @param tree
|
||||
*/
|
||||
@Override
|
||||
public void visitReference(JCMemberReference tree) {
|
||||
scan(tree.getQualifierExpression());
|
||||
contextMap.put(tree, makeReferenceContext(tree));
|
||||
if (tree.getMode() == ReferenceMode.NEW
|
||||
&& tree.kind != ReferenceKind.ARRAY_CTOR
|
||||
&& tree.sym.owner.isLocal()) {
|
||||
MethodSymbol consSym = (MethodSymbol) tree.sym;
|
||||
List<Type> ptypes = ((MethodType) consSym.type).getParameterTypes();
|
||||
Type classType = consSym.owner.type;
|
||||
|
||||
// Make new-class call
|
||||
List<JCVariableDecl> params = make.Params(ptypes, owner());
|
||||
JCNewClass nc = makeNewClass(classType, make.Idents(params));
|
||||
nc.pos = tree.pos;
|
||||
|
||||
// Make lambda holding the new-class call
|
||||
JCLambda slam = make.Lambda(params, nc);
|
||||
slam.descriptorType = tree.descriptorType;
|
||||
slam.targets = tree.targets;
|
||||
slam.type = tree.type;
|
||||
slam.pos = tree.pos;
|
||||
|
||||
// Now it is a lambda, process as such
|
||||
visitLambda(slam);
|
||||
} else {
|
||||
super.visitReference(tree);
|
||||
contextMap.put(tree, makeReferenceContext(tree));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1240,10 +1284,8 @@ public class LambdaToMethod extends TreeTranslator {
|
||||
}
|
||||
localContext = localContext.prev;
|
||||
}
|
||||
scan(tree.selected);
|
||||
} else {
|
||||
super.visitSelect(tree);
|
||||
}
|
||||
super.visitSelect(tree);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1647,7 +1647,7 @@ public class Code {
|
||||
State dup() {
|
||||
try {
|
||||
State state = (State)super.clone();
|
||||
state.defined = defined.dup();
|
||||
state.defined = new Bits(defined);
|
||||
state.stack = stack.clone();
|
||||
if (locks != null) state.locks = locks.clone();
|
||||
if (debugCode) {
|
||||
@ -1775,7 +1775,7 @@ public class Code {
|
||||
}
|
||||
|
||||
State join(State other) {
|
||||
defined = defined.andSet(other.defined);
|
||||
defined.andSet(other.defined);
|
||||
Assert.check(stacksize == other.stacksize
|
||||
&& nlocks == other.nlocks);
|
||||
for (int i=0; i<stacksize; ) {
|
||||
@ -1887,7 +1887,7 @@ public class Code {
|
||||
/** Set the current variable defined state. */
|
||||
public void setDefined(Bits newDefined) {
|
||||
if (alive && newDefined != state.defined) {
|
||||
Bits diff = state.defined.dup().xorSet(newDefined);
|
||||
Bits diff = new Bits(state.defined).xorSet(newDefined);
|
||||
for (int adr = diff.nextBit(0);
|
||||
adr >= 0;
|
||||
adr = diff.nextBit(adr+1)) {
|
||||
|
@ -33,10 +33,13 @@ import com.sun.tools.javac.code.Attribute;
|
||||
import com.sun.tools.javac.code.Kinds;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.TypeVariableSymbol;
|
||||
import com.sun.tools.javac.code.TargetType;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.Type.AnnotatedType;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
import static com.sun.tools.javac.code.TypeTag.CLASS;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
/**
|
||||
* Utility methods for operating on annotated constructs.
|
||||
@ -61,8 +64,12 @@ public class JavacAnnoConstructs {
|
||||
throw new IllegalArgumentException("Not an annotation type: "
|
||||
+ annoType);
|
||||
Attribute.Compound c;
|
||||
if (annotated.kind == Kinds.TYP && annotated instanceof ClassSymbol) {
|
||||
if (annotated.kind == Kinds.TYP &&
|
||||
annotated instanceof ClassSymbol) {
|
||||
c = getAttributeOnClass((ClassSymbol)annotated, annoType);
|
||||
} else if (annotated.kind == Kinds.TYP &&
|
||||
annotated instanceof TypeVariableSymbol) {
|
||||
c = getAttributeOnTypeVariable((TypeVariableSymbol)annotated, annoType);
|
||||
} else {
|
||||
c = getAttribute(annotated, annoType);
|
||||
}
|
||||
@ -82,6 +89,24 @@ public class JavacAnnoConstructs {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Helper to getAnnotation[s]
|
||||
private static <A extends Annotation> Attribute.Compound
|
||||
getAttributeOnTypeVariable(TypeVariableSymbol annotated, Class<A> annoType) {
|
||||
String name = annoType.getName();
|
||||
|
||||
// Declaration annotations on type variables are stored in type attributes
|
||||
// on the owner of the TypeVariableSymbol
|
||||
List<Attribute.Compound> res = List.nil();
|
||||
List<Attribute.TypeCompound> candidates = annotated.owner.getRawTypeAttributes();
|
||||
for (Attribute.TypeCompound anno : candidates)
|
||||
if (anno.position.type == TargetType.CLASS_TYPE_PARAMETER ||
|
||||
anno.position.type == TargetType.METHOD_TYPE_PARAMETER)
|
||||
if (name.equals(anno.type.tsym.flatName().toString()))
|
||||
return anno;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Helper to getAnnotation[s]
|
||||
private static <A extends Annotation> Attribute.Compound getAttributeOnClass(ClassSymbol annotated,
|
||||
Class<A> annoType) {
|
||||
|
@ -402,9 +402,10 @@ public class JavacElements implements Elements {
|
||||
* @param e the element being examined
|
||||
* @return all annotations of the element
|
||||
*/
|
||||
@Override
|
||||
public List<Attribute.Compound> getAllAnnotationMirrors(Element e) {
|
||||
Symbol sym = cast(Symbol.class, e);
|
||||
List<Attribute.Compound> annos = sym.getRawAttributes();
|
||||
List<Attribute.Compound> annos = sym.getAnnotationMirrors();
|
||||
while (sym.getKind() == ElementKind.CLASS) {
|
||||
Type sup = ((ClassSymbol) sym).getSuperclass();
|
||||
if (!sup.hasTag(CLASS) || sup.isErroneous() ||
|
||||
@ -413,7 +414,7 @@ public class JavacElements implements Elements {
|
||||
}
|
||||
sym = sup.tsym;
|
||||
List<Attribute.Compound> oldAnnos = annos;
|
||||
List<Attribute.Compound> newAnnos = sym.getRawAttributes();
|
||||
List<Attribute.Compound> newAnnos = sym.getAnnotationMirrors();
|
||||
for (Attribute.Compound anno : newAnnos) {
|
||||
if (isInherited(anno.type) &&
|
||||
!containsAnnoOfType(oldAnnos, anno.type)) {
|
||||
|
@ -41,6 +41,7 @@ import com.sun.tools.javac.tree.DCTree;
|
||||
import com.sun.tools.javac.tree.DCTree.DCAttribute;
|
||||
import com.sun.tools.javac.tree.DCTree.DCDocComment;
|
||||
import com.sun.tools.javac.tree.DCTree.DCEndElement;
|
||||
import com.sun.tools.javac.tree.DCTree.DCEndPosTree;
|
||||
import com.sun.tools.javac.tree.DCTree.DCErroneous;
|
||||
import com.sun.tools.javac.tree.DCTree.DCIdentifier;
|
||||
import com.sun.tools.javac.tree.DCTree.DCReference;
|
||||
@ -336,12 +337,12 @@ public class DocCommentParser {
|
||||
DCTree text = inlineText();
|
||||
if (text != null) {
|
||||
nextChar();
|
||||
return m.at(p).UnknownInlineTag(name, List.of(text));
|
||||
return m.at(p).UnknownInlineTag(name, List.of(text)).setEndPos(bp);
|
||||
}
|
||||
} else if (tp.getKind() == TagParser.Kind.INLINE) {
|
||||
DCTree tree = tp.parse(p);
|
||||
DCEndPosTree<?> tree = (DCEndPosTree<?>) tp.parse(p);
|
||||
if (tree != null) {
|
||||
return tree;
|
||||
return tree.setEndPos(bp);
|
||||
}
|
||||
} else {
|
||||
inlineText(); // skip content
|
||||
@ -509,7 +510,7 @@ public class DocCommentParser {
|
||||
fac.log.popDiagnosticHandler(deferredDiagnosticHandler);
|
||||
}
|
||||
|
||||
return m.at(pos).Reference(sig, qualExpr, member, paramTypes);
|
||||
return m.at(pos).Reference(sig, qualExpr, member, paramTypes).setEndPos(bp);
|
||||
}
|
||||
|
||||
JCTree parseType(String s) throws ParseException {
|
||||
@ -741,7 +742,7 @@ public class DocCommentParser {
|
||||
}
|
||||
if (ch == '>') {
|
||||
nextChar();
|
||||
return m.at(p).StartElement(name, attrs, selfClosing);
|
||||
return m.at(p).StartElement(name, attrs, selfClosing).setEndPos(bp);
|
||||
}
|
||||
}
|
||||
} else if (ch == '/') {
|
||||
|
@ -36,6 +36,7 @@ import com.sun.tools.javac.util.JCDiagnostic;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.Name;
|
||||
import com.sun.tools.javac.util.Position;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import javax.tools.JavaFileObject;
|
||||
@ -82,8 +83,24 @@ public abstract class DCTree implements DocTree {
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public static abstract class DCEndPosTree<T extends DCEndPosTree<T>> extends DCTree {
|
||||
|
||||
private int endPos = Position.NOPOS;
|
||||
|
||||
public int getEndPos(DCDocComment dc) {
|
||||
return dc.comment.getSourcePos(endPos);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T setEndPos(int endPos) {
|
||||
this.endPos = endPos;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class DCDocComment extends DCTree implements DocCommentTree {
|
||||
final Comment comment; // required for the implicit source pos table
|
||||
public final Comment comment; // required for the implicit source pos table
|
||||
|
||||
public final List<DCTree> firstSentence;
|
||||
public final List<DCTree> body;
|
||||
@ -125,7 +142,7 @@ public abstract class DCTree implements DocTree {
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class DCInlineTag extends DCTree implements InlineTagTree {
|
||||
public static abstract class DCInlineTag extends DCEndPosTree<DCInlineTag> implements InlineTagTree {
|
||||
public String getTagName() {
|
||||
return getKind().tagName;
|
||||
}
|
||||
@ -345,6 +362,7 @@ public abstract class DCTree implements DocTree {
|
||||
public int getEndPosition(EndPosTable endPosTable) {
|
||||
return pos + body.length();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class DCIdentifier extends DCTree implements IdentifierTree {
|
||||
@ -478,7 +496,7 @@ public abstract class DCTree implements DocTree {
|
||||
}
|
||||
}
|
||||
|
||||
public static class DCReference extends DCTree implements ReferenceTree {
|
||||
public static class DCReference extends DCEndPosTree<DCReference> implements ReferenceTree {
|
||||
public final String signature;
|
||||
|
||||
// The following are not directly exposed through ReferenceTree
|
||||
@ -663,7 +681,7 @@ public abstract class DCTree implements DocTree {
|
||||
}
|
||||
}
|
||||
|
||||
public static class DCStartElement extends DCTree implements StartElementTree {
|
||||
public static class DCStartElement extends DCEndPosTree<DCStartElement> implements StartElementTree {
|
||||
public final Name name;
|
||||
public final List<DCTree> attrs;
|
||||
public final boolean selfClosing;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,6 +27,8 @@ package com.sun.tools.javac.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.sun.tools.javac.util.Bits.BitsOpKind.*;
|
||||
|
||||
/** A class for extensible, mutable bit sets.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
@ -36,31 +38,114 @@ import java.util.Arrays;
|
||||
*/
|
||||
public class Bits {
|
||||
|
||||
public enum BitsOpKind {
|
||||
INIT,
|
||||
CLEAR,
|
||||
INCL_BIT,
|
||||
EXCL_BIT,
|
||||
ASSIGN,
|
||||
AND_SET,
|
||||
OR_SET,
|
||||
DIFF_SET,
|
||||
XOR_SET,
|
||||
INCL_RANGE,
|
||||
EXCL_RANGE,
|
||||
}
|
||||
|
||||
// ____________ reset _________
|
||||
// / UNKNOWN \ <-------- / UNINIT \
|
||||
// \____________/ | \_________/
|
||||
// | | |
|
||||
// |assign | | any
|
||||
// | ___________ |
|
||||
// ------> / NORMAL \ <----
|
||||
// \___________/ |
|
||||
// | |
|
||||
// | |
|
||||
// -----------
|
||||
// any
|
||||
private enum BitsState {
|
||||
/* A Bits instance is in UNKNOWN state if it has been explicitly reset.
|
||||
* It is possible to get to this state from any other by calling the
|
||||
* reset method. An instance in the UNKNOWN state can pass to the
|
||||
* NORMAL state after being assigned another Bits instance.
|
||||
*/
|
||||
UNKNOWN,
|
||||
/* A Bits instance is in UNINIT when it is created with the default
|
||||
* constructor but it isn't explicitly reset. The main objective of this
|
||||
* internal state is to save some memory.
|
||||
*/
|
||||
UNINIT,
|
||||
/* The normal state is reached after creating a Bits instance from an
|
||||
* existing one or after applying any operation to an instance on UNINIT
|
||||
* or NORMAL state. From this state a bits instance can pass to the
|
||||
* UNKNOWN state by calling the reset method.
|
||||
*/
|
||||
NORMAL;
|
||||
|
||||
static BitsState getState(int[] someBits, boolean reset) {
|
||||
if (reset) {
|
||||
return UNKNOWN;
|
||||
} else {
|
||||
if (someBits != unassignedBits) {
|
||||
return NORMAL;
|
||||
} else {
|
||||
return UNINIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final static int wordlen = 32;
|
||||
private final static int wordshift = 5;
|
||||
private final static int wordmask = wordlen - 1;
|
||||
|
||||
private int[] bits;
|
||||
public int[] bits = null;
|
||||
// This field will store last version of bits after every change.
|
||||
public int[] oldBits = null;
|
||||
|
||||
public BitsOpKind lastOperation = null;
|
||||
|
||||
private static final int[] unassignedBits = new int[0];
|
||||
|
||||
private BitsState currentState;
|
||||
|
||||
/** Construct an initially empty set.
|
||||
*/
|
||||
public Bits() {
|
||||
this(new int[1]);
|
||||
this(false);
|
||||
}
|
||||
|
||||
public Bits(Bits someBits) {
|
||||
this(someBits.dup().bits, BitsState.getState(someBits.bits, false));
|
||||
}
|
||||
|
||||
public Bits(boolean reset) {
|
||||
this(unassignedBits, BitsState.getState(unassignedBits, reset));
|
||||
}
|
||||
|
||||
/** Construct a set consisting initially of given bit vector.
|
||||
*/
|
||||
public Bits(int[] bits) {
|
||||
private Bits(int[] bits, BitsState initState) {
|
||||
this.bits = bits;
|
||||
this.currentState = initState;
|
||||
switch (initState) {
|
||||
case UNKNOWN:
|
||||
reset(); //this will also set current state;
|
||||
break;
|
||||
case NORMAL:
|
||||
Assert.check(bits != unassignedBits);
|
||||
lastOperation = INIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Construct a set consisting initially of given range.
|
||||
/** This method will be called after any operation that causes a change to
|
||||
* the bits. Subclasses can thus override it in order to extract information
|
||||
* from the changes produced to the bits by the given operation.
|
||||
*/
|
||||
public Bits(int start, int limit) {
|
||||
this();
|
||||
inclRange(start, limit);
|
||||
}
|
||||
public void changed() {}
|
||||
|
||||
private void sizeTo(int len) {
|
||||
if (bits.length < len) {
|
||||
@ -71,57 +156,110 @@ public class Bits {
|
||||
/** This set = {}.
|
||||
*/
|
||||
public void clear() {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
oldBits = bits;
|
||||
lastOperation = CLEAR;
|
||||
for (int i = 0; i < bits.length; i++) bits[i] = 0;
|
||||
changed();
|
||||
currentState = BitsState.NORMAL;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
bits = null;
|
||||
oldBits = null;
|
||||
currentState = BitsState.UNKNOWN;
|
||||
}
|
||||
|
||||
public boolean isReset() {
|
||||
return currentState == BitsState.UNKNOWN;
|
||||
}
|
||||
|
||||
public Bits assign(Bits someBits) {
|
||||
lastOperation = ASSIGN;
|
||||
oldBits = bits;
|
||||
bits = someBits.dup().bits;
|
||||
changed();
|
||||
currentState = BitsState.NORMAL;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Return a copy of this set.
|
||||
*/
|
||||
public Bits dup() {
|
||||
int[] newbits = new int[bits.length];
|
||||
System.arraycopy(bits, 0, newbits, 0, bits.length);
|
||||
return new Bits(newbits);
|
||||
private Bits dup() {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
Bits tmp = new Bits();
|
||||
if (currentState != BitsState.NORMAL) {
|
||||
tmp.bits = bits;
|
||||
} else {
|
||||
tmp.bits = new int[bits.length];
|
||||
System.arraycopy(bits, 0, tmp.bits, 0, bits.length);
|
||||
}
|
||||
currentState = BitsState.NORMAL;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/** Include x in this set.
|
||||
*/
|
||||
public void incl(int x) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
Assert.check(x >= 0);
|
||||
oldBits = bits;
|
||||
lastOperation = INCL_BIT;
|
||||
sizeTo((x >>> wordshift) + 1);
|
||||
bits[x >>> wordshift] = bits[x >>> wordshift] |
|
||||
(1 << (x & wordmask));
|
||||
changed();
|
||||
currentState = BitsState.NORMAL;
|
||||
}
|
||||
|
||||
|
||||
/** Include [start..limit) in this set.
|
||||
*/
|
||||
public void inclRange(int start, int limit) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
oldBits = bits;
|
||||
lastOperation = INCL_RANGE;
|
||||
sizeTo((limit >>> wordshift) + 1);
|
||||
for (int x = start; x < limit; x++)
|
||||
for (int x = start; x < limit; x++) {
|
||||
bits[x >>> wordshift] = bits[x >>> wordshift] |
|
||||
(1 << (x & wordmask));
|
||||
}
|
||||
changed();
|
||||
currentState = BitsState.NORMAL;
|
||||
}
|
||||
|
||||
/** Exclude [start...end] from this set.
|
||||
*/
|
||||
public void excludeFrom(int start) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
oldBits = bits;
|
||||
lastOperation = EXCL_RANGE;
|
||||
Bits temp = new Bits();
|
||||
temp.sizeTo(bits.length);
|
||||
temp.inclRange(0, start);
|
||||
andSet(temp);
|
||||
internalAndSet(temp);
|
||||
changed();
|
||||
currentState = BitsState.NORMAL;
|
||||
}
|
||||
|
||||
/** Exclude x from this set.
|
||||
*/
|
||||
public void excl(int x) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
Assert.check(x >= 0);
|
||||
oldBits = bits;
|
||||
lastOperation = EXCL_BIT;
|
||||
sizeTo((x >>> wordshift) + 1);
|
||||
bits[x >>> wordshift] = bits[x >>> wordshift] &
|
||||
~(1 << (x & wordmask));
|
||||
changed();
|
||||
currentState = BitsState.NORMAL;
|
||||
}
|
||||
|
||||
/** Is x an element of this set?
|
||||
*/
|
||||
public boolean isMember(int x) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
return
|
||||
0 <= x && x < (bits.length << wordshift) &&
|
||||
(bits[x >>> wordshift] & (1 << (x & wordmask))) != 0;
|
||||
@ -130,38 +268,66 @@ public class Bits {
|
||||
/** {@literal this set = this set & xs}.
|
||||
*/
|
||||
public Bits andSet(Bits xs) {
|
||||
sizeTo(xs.bits.length);
|
||||
for (int i = 0; i < xs.bits.length; i++)
|
||||
bits[i] = bits[i] & xs.bits[i];
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
oldBits = bits;
|
||||
lastOperation = AND_SET;
|
||||
internalAndSet(xs);
|
||||
changed();
|
||||
currentState = BitsState.NORMAL;
|
||||
return this;
|
||||
}
|
||||
|
||||
private void internalAndSet(Bits xs) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
sizeTo(xs.bits.length);
|
||||
for (int i = 0; i < xs.bits.length; i++) {
|
||||
bits[i] = bits[i] & xs.bits[i];
|
||||
}
|
||||
}
|
||||
|
||||
/** this set = this set | xs.
|
||||
*/
|
||||
public Bits orSet(Bits xs) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
oldBits = bits;
|
||||
lastOperation = OR_SET;
|
||||
sizeTo(xs.bits.length);
|
||||
for (int i = 0; i < xs.bits.length; i++)
|
||||
for (int i = 0; i < xs.bits.length; i++) {
|
||||
bits[i] = bits[i] | xs.bits[i];
|
||||
}
|
||||
changed();
|
||||
currentState = BitsState.NORMAL;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** this set = this set \ xs.
|
||||
*/
|
||||
public Bits diffSet(Bits xs) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
oldBits = bits;
|
||||
lastOperation = DIFF_SET;
|
||||
for (int i = 0; i < bits.length; i++) {
|
||||
if (i < xs.bits.length) {
|
||||
bits[i] = bits[i] & ~xs.bits[i];
|
||||
}
|
||||
}
|
||||
changed();
|
||||
currentState = BitsState.NORMAL;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** this set = this set ^ xs.
|
||||
*/
|
||||
public Bits xorSet(Bits xs) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
oldBits = bits;
|
||||
lastOperation = XOR_SET;
|
||||
sizeTo(xs.bits.length);
|
||||
for (int i = 0; i < xs.bits.length; i++)
|
||||
for (int i = 0; i < xs.bits.length; i++) {
|
||||
bits[i] = bits[i] ^ xs.bits[i];
|
||||
}
|
||||
changed();
|
||||
currentState = BitsState.NORMAL;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -187,6 +353,7 @@ public class Bits {
|
||||
* }</pre>
|
||||
*/
|
||||
public int nextBit(int x) {
|
||||
Assert.check(currentState != BitsState.UNKNOWN);
|
||||
int windex = x >>> wordshift;
|
||||
if (windex >= bits.length) return -1;
|
||||
int word = bits[windex] & ~((1 << (x & wordmask))-1);
|
||||
@ -202,17 +369,20 @@ public class Bits {
|
||||
/** a string representation of this set.
|
||||
*/
|
||||
public String toString() {
|
||||
char[] digits = new char[bits.length * wordlen];
|
||||
for (int i = 0; i < bits.length * wordlen; i++)
|
||||
digits[i] = isMember(i) ? '1' : '0';
|
||||
return new String(digits);
|
||||
if (bits.length > 0) {
|
||||
char[] digits = new char[bits.length * wordlen];
|
||||
for (int i = 0; i < bits.length * wordlen; i++)
|
||||
digits[i] = isMember(i) ? '1' : '0';
|
||||
return new String(digits);
|
||||
} else {
|
||||
return "[]";
|
||||
}
|
||||
}
|
||||
|
||||
/** Test Bits.nextBit(int). */
|
||||
public static void main(String[] args) {
|
||||
java.util.Random r = new java.util.Random();
|
||||
Bits bits = new Bits();
|
||||
int dupCount = 0;
|
||||
for (int i=0; i<125; i++) {
|
||||
int k;
|
||||
do {
|
||||
|
@ -341,9 +341,14 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
* </pre>
|
||||
*/
|
||||
public String name() {
|
||||
return getClassName(tsym, false);
|
||||
if (name == null) {
|
||||
name = getClassName(tsym, false);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Return the qualified class name as a String.
|
||||
* <pre>
|
||||
@ -354,9 +359,14 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
* </pre>
|
||||
*/
|
||||
public String qualifiedName() {
|
||||
return getClassName(tsym, true);
|
||||
if (qualifiedName == null) {
|
||||
qualifiedName = getClassName(tsym, true);
|
||||
}
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
private String qualifiedName;
|
||||
|
||||
/**
|
||||
* Return unqualified name of type excluding any dimension information.
|
||||
* <p>
|
||||
@ -380,9 +390,14 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
* Return the simple name of this type.
|
||||
*/
|
||||
public String simpleTypeName() {
|
||||
return tsym.name.toString();
|
||||
if (simpleTypeName == null) {
|
||||
simpleTypeName = tsym.name.toString();
|
||||
}
|
||||
return simpleTypeName;
|
||||
}
|
||||
|
||||
private String simpleTypeName;
|
||||
|
||||
/**
|
||||
* Return the qualified name and any type parameters.
|
||||
* Each parameter is a type variable with optional bounds.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -252,13 +252,23 @@ public class FieldDocImpl extends MemberDocImpl implements FieldDoc {
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return sym.name.toString();
|
||||
if (name == null) {
|
||||
name = sym.name.toString();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
public String qualifiedName() {
|
||||
return sym.enclClass().getQualifiedName() + "." + name();
|
||||
if (qualifiedName == null) {
|
||||
qualifiedName = sym.enclClass().getQualifiedName() + "." + name();
|
||||
}
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
private String qualifiedName;
|
||||
|
||||
/**
|
||||
* Return the source position of the entity, or null if
|
||||
* no position is available.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -203,13 +203,23 @@ public class MethodDocImpl
|
||||
|
||||
|
||||
public String name() {
|
||||
return sym.name.toString();
|
||||
if (name == null) {
|
||||
name = sym.name.toString();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
public String qualifiedName() {
|
||||
return sym.enclClass().getQualifiedName() + "." + sym.name;
|
||||
if (qualifiedName == null) {
|
||||
qualifiedName = sym.enclClass().getQualifiedName() + "." + sym.name;
|
||||
}
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
private String qualifiedName;
|
||||
|
||||
/**
|
||||
* Returns a string representation of this method. Includes the
|
||||
* qualified signature, the qualified method name, and any type
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -334,12 +334,17 @@ public class PackageDocImpl extends DocImpl implements PackageDoc {
|
||||
* Get package name.
|
||||
*/
|
||||
public String qualifiedName() {
|
||||
Name fullname = sym.getQualifiedName();
|
||||
// Some bogus tests depend on the interned "" being returned.
|
||||
// See 6457276.
|
||||
return fullname.isEmpty() ? "" : fullname.toString();
|
||||
if (qualifiedName == null) {
|
||||
Name fullname = sym.getQualifiedName();
|
||||
// Some bogus tests depend on the interned "" being returned.
|
||||
// See 6457276.
|
||||
qualifiedName = fullname.isEmpty() ? "" : fullname.toString();
|
||||
}
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
private String qualifiedName;
|
||||
|
||||
/**
|
||||
* set doc path for an unzipped directory
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -93,7 +93,7 @@ public class TestJavacTaskScanner extends ToolTester {
|
||||
System.out.println("#allMembers: " + numAllMembers);
|
||||
|
||||
check(numTokens, "#Tokens", 1222);
|
||||
check(numParseTypeElements, "#parseTypeElements", 136);
|
||||
check(numParseTypeElements, "#parseTypeElements", 158);
|
||||
check(numAllMembers, "#allMembers", 52);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8012723
|
||||
* @summary strictfp interface misses strictfp modifer on default method
|
||||
* @run main CheckACC_STRICTFlagOnDefaultMethodTest
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.Descriptor;
|
||||
import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
|
||||
import com.sun.tools.classfile.Method;
|
||||
|
||||
import static com.sun.tools.classfile.AccessFlags.ACC_STRICT;
|
||||
|
||||
public class CheckACC_STRICTFlagOnDefaultMethodTest {
|
||||
private static final String AssertionErrorMessage =
|
||||
"All methods should have the ACC_STRICT access flag " +
|
||||
"please check output";
|
||||
private static final String offendingMethodErrorMessage =
|
||||
"Method %s of class %s doesn't have the ACC_STRICT access flag";
|
||||
|
||||
private List<String> errors = new ArrayList<>();
|
||||
|
||||
public static void main(String[] args)
|
||||
throws IOException, ConstantPoolException, InvalidDescriptor {
|
||||
new CheckACC_STRICTFlagOnDefaultMethodTest().run();
|
||||
}
|
||||
|
||||
private void run()
|
||||
throws IOException, ConstantPoolException, InvalidDescriptor {
|
||||
String testClasses = System.getProperty("test.classes");
|
||||
check(testClasses,
|
||||
"CheckACC_STRICTFlagOnDefaultMethodTest$StrictfpInterface.class");
|
||||
if (errors.size() > 0) {
|
||||
for (String error: errors) {
|
||||
System.err.println(error);
|
||||
}
|
||||
throw new AssertionError(AssertionErrorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
void check(String dir, String... fileNames)
|
||||
throws
|
||||
IOException,
|
||||
ConstantPoolException,
|
||||
Descriptor.InvalidDescriptor {
|
||||
for (String fileName : fileNames) {
|
||||
ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName));
|
||||
|
||||
for (Method method : classFileToCheck.methods) {
|
||||
if ((method.access_flags.flags & ACC_STRICT) == 0) {
|
||||
errors.add(String.format(offendingMethodErrorMessage,
|
||||
method.getName(classFileToCheck.constant_pool),
|
||||
classFileToCheck.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strictfp interface StrictfpInterface {
|
||||
default void default_interface_method() {}
|
||||
static void static_interface_method() {}
|
||||
}
|
||||
|
||||
}
|
105
langtools/test/tools/javac/doctree/positions/TestPosition.java
Normal file
105
langtools/test/tools/javac/doctree/positions/TestPosition.java
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8008174
|
||||
* @summary proper source positions for doc comments
|
||||
* @build TestPosition
|
||||
* @compile/ref=TestPosition.out -processor TestPosition -proc:only TestPositionSource.java
|
||||
*/
|
||||
|
||||
import com.sun.source.doctree.DocCommentTree;
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import com.sun.source.tree.MethodTree;
|
||||
import com.sun.source.util.DocSourcePositions;
|
||||
import com.sun.source.util.DocTreeScanner;
|
||||
import com.sun.source.util.DocTrees;
|
||||
import com.sun.source.util.TreePath;
|
||||
import com.sun.source.util.TreePathScanner;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import javax.annotation.processing.*;
|
||||
import javax.lang.model.*;
|
||||
import javax.lang.model.element.*;
|
||||
|
||||
@SupportedAnnotationTypes("*")
|
||||
public class TestPosition extends AbstractProcessor {
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
TypeElement source = processingEnv.getElementUtils().getTypeElement("TestPositionSource");
|
||||
|
||||
if (source == null) throw new IllegalStateException();
|
||||
|
||||
if (!roundEnv.getRootElements().contains(source)) return false;
|
||||
|
||||
final DocTrees trees = DocTrees.instance(processingEnv);
|
||||
final TreePath testElement = trees.getPath(source);
|
||||
|
||||
if (testElement == null) throw new IllegalStateException();
|
||||
|
||||
String code;
|
||||
|
||||
try {
|
||||
code = testElement.getCompilationUnit().getSourceFile().getCharContent(false).toString();
|
||||
} catch ( IOException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
|
||||
new TreePathScanner<Void, Void>() {
|
||||
@Override public Void visitMethod(MethodTree node, Void p) {
|
||||
final DocCommentTree docCommentTree = trees.getDocCommentTree(getCurrentPath());
|
||||
|
||||
if (docCommentTree != null) {
|
||||
System.out.println(node.getName() + ":");
|
||||
new DocTreeScanner<Void, Void>() {
|
||||
@Override public Void scan(DocTree node, Void p) {
|
||||
if (node != null) {
|
||||
DocSourcePositions sp = (DocSourcePositions) trees.getSourcePositions(); //XXX: the cast???
|
||||
int start = (int) sp.getStartPosition(testElement.getCompilationUnit(), docCommentTree, node);
|
||||
int end = (int) sp.getEndPosition(testElement.getCompilationUnit(), docCommentTree, node);
|
||||
String snippet = code.substring(start, end).replace(" \n", "!trailing-whitespace!\n");
|
||||
|
||||
if (snippet.endsWith(" ")) {
|
||||
snippet = snippet.substring(0, snippet.length() - 1) + "!trailing-whitespace!";
|
||||
}
|
||||
System.out.println(node.getKind().name() + ":" + snippet);
|
||||
}
|
||||
return super.scan(node, p);
|
||||
}
|
||||
}.scan(docCommentTree, null);
|
||||
}
|
||||
|
||||
return super.visitMethod(node, p);
|
||||
}
|
||||
}.scan(testElement, null);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceVersion getSupportedSourceVersion() {
|
||||
return SourceVersion.latest();
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
valid:
|
||||
DOC_COMMENT:First sentence.
|
||||
*
|
||||
* <p>Description with {@link java.io.InputStream link}
|
||||
*
|
||||
* @param first description
|
||||
* @param second description
|
||||
* @return whatever
|
||||
* @throws IllegalStateException why?
|
||||
* @since 1.15
|
||||
* @see java.util.List
|
||||
TEXT:First sentence.
|
||||
START_ELEMENT:<p>
|
||||
TEXT:Description with!trailing-whitespace!
|
||||
LINK:{@link java.io.InputStream link}
|
||||
REFERENCE:java.io.InputStream
|
||||
TEXT:link
|
||||
PARAM:@param first description
|
||||
IDENTIFIER:first
|
||||
TEXT:description
|
||||
PARAM:@param second description
|
||||
IDENTIFIER:second
|
||||
TEXT:description
|
||||
RETURN:@return whatever
|
||||
TEXT:whatever
|
||||
THROWS:@throws IllegalStateException why?
|
||||
REFERENCE:IllegalStateException
|
||||
TEXT:why?
|
||||
SINCE:@since 1.15
|
||||
TEXT:1.15
|
||||
SEE:@see java.util.List
|
||||
REFERENCE:java.util.List
|
||||
erroneous:
|
||||
DOC_COMMENT:First sentence.
|
||||
*
|
||||
* <p>Description with {@link}, {@link java.util.List}, {@link
|
||||
*
|
||||
* @param
|
||||
* @param second
|
||||
* @return
|
||||
* @throws
|
||||
* @throws IllegalStateException
|
||||
* @since
|
||||
* @see
|
||||
TEXT:First sentence.
|
||||
START_ELEMENT:<p>
|
||||
TEXT:Description with!trailing-whitespace!
|
||||
LINK:{@link}
|
||||
TEXT:,!trailing-whitespace!
|
||||
LINK:{@link java.util.List}
|
||||
REFERENCE:java.util.List
|
||||
TEXT:,!trailing-whitespace!
|
||||
ERRONEOUS:{@link
|
||||
ERRONEOUS:@param
|
||||
PARAM:@param second
|
||||
IDENTIFIER:second
|
||||
RETURN:@return
|
||||
ERRONEOUS:@throws
|
||||
THROWS:@throws IllegalStateException
|
||||
REFERENCE:IllegalStateException
|
||||
SINCE:@since
|
||||
ERRONEOUS:@see
|
||||
withWhiteSpaces:
|
||||
DOC_COMMENT:First sentence.
|
||||
*
|
||||
* <p>Description with {@link }, {@link java.util.List#add( int )},
|
||||
* {@link java.util.List#add( int ) some text with whitespaces}, {@link
|
||||
*
|
||||
* @param first
|
||||
* @param second some text with trailing whitespace
|
||||
* @return some return
|
||||
* @throws java.lang.IllegalStateException
|
||||
* @throws java.lang.IllegalStateException some text
|
||||
TEXT:First sentence.
|
||||
START_ELEMENT:<p>
|
||||
TEXT:Description with!trailing-whitespace!
|
||||
LINK:{@link }
|
||||
TEXT:,!trailing-whitespace!
|
||||
LINK:{@link java.util.List#add( int )}
|
||||
REFERENCE:java.util.List#add( int )
|
||||
TEXT:,
|
||||
*!trailing-whitespace!
|
||||
LINK:{@link java.util.List#add( int ) some text with whitespaces}
|
||||
REFERENCE:java.util.List#add( int )
|
||||
TEXT:some text with whitespaces
|
||||
TEXT:,!trailing-whitespace!
|
||||
ERRONEOUS:{@link
|
||||
PARAM:@param first
|
||||
IDENTIFIER:first
|
||||
PARAM:@param second some text with trailing whitespace
|
||||
IDENTIFIER:second
|
||||
TEXT:some text with trailing whitespace
|
||||
RETURN:@return some return
|
||||
TEXT:some return
|
||||
THROWS:@throws java.lang.IllegalStateException
|
||||
REFERENCE:java.lang.IllegalStateException
|
||||
THROWS:@throws java.lang.IllegalStateException some text
|
||||
REFERENCE:java.lang.IllegalStateException
|
||||
TEXT:some text
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
public class TestPositionSource {
|
||||
|
||||
/**First sentence.
|
||||
*
|
||||
* <p>Description with {@link java.io.InputStream link}
|
||||
*
|
||||
* @param first description
|
||||
* @param second description
|
||||
* @return whatever
|
||||
* @throws IllegalStateException why?
|
||||
* @since 1.15
|
||||
* @see java.util.List
|
||||
*/
|
||||
public boolean valid(int first, int second) throws IllegalStateException {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**First sentence.
|
||||
*
|
||||
* <p>Description with {@link}, {@link java.util.List}, {@link
|
||||
*
|
||||
* @param
|
||||
* @param second
|
||||
* @return
|
||||
* @throws
|
||||
* @throws IllegalStateException
|
||||
* @since
|
||||
* @see
|
||||
*/
|
||||
public boolean erroneous(int first, int second) throws IllegalStateException {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**First sentence.
|
||||
*
|
||||
* <p>Description with {@link }, {@link java.util.List#add( int )},
|
||||
* {@link java.util.List#add( int ) some text with whitespaces}, {@link
|
||||
*
|
||||
* @param first
|
||||
* @param second some text with trailing whitespace
|
||||
* @return some return
|
||||
* @throws java.lang.IllegalStateException
|
||||
* @throws java.lang.IllegalStateException some text
|
||||
*/
|
||||
public boolean withWhiteSpaces(int first, int second) throws IllegalStateException {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8011591
|
||||
* @summary BootstrapMethodError when capturing constructor ref to local classes
|
||||
* @run testng MethodReferenceTestNewInnerImplicitArgs
|
||||
*/
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Test the case that a constructor has implicit parameters added to
|
||||
* access local variables and that this constructor is used in a
|
||||
* method reference.
|
||||
* @author Robert Field
|
||||
*/
|
||||
|
||||
@Test
|
||||
public class MethodReferenceTestNewInnerImplicitArgs {
|
||||
|
||||
|
||||
static class S {
|
||||
String b;
|
||||
S(String s, String s2) { b = s + s2; }
|
||||
}
|
||||
|
||||
interface I {
|
||||
S m();
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
S m(int i, int j);
|
||||
}
|
||||
|
||||
public static void testConstructorReferenceImplicitParameters() {
|
||||
String title = "Hey";
|
||||
String a2 = "!!!";
|
||||
class MS extends S {
|
||||
MS() {
|
||||
super(title, a2);
|
||||
}
|
||||
}
|
||||
|
||||
I result = MS::new;
|
||||
assertEquals(result.m().b, "Hey!!!");
|
||||
|
||||
class MS2 extends S {
|
||||
MS2(int x, int y) {
|
||||
super(title+x, a2+y);
|
||||
}
|
||||
}
|
||||
|
||||
I2 result2 = MS2::new;
|
||||
assertEquals(result2.m(8, 4).b, "Hey8!!!4");
|
||||
}
|
||||
}
|
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8011027
|
||||
* @library /tools/javac/lib
|
||||
* @build JavacTestingAbstractProcessor TestTypeParameterAnnotations
|
||||
* @compile -processor TestTypeParameterAnnotations -proc:only TestTypeParameterAnnotations.java
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.lang.annotation.*;
|
||||
import javax.annotation.processing.*;
|
||||
import javax.lang.model.element.*;
|
||||
import javax.lang.model.util.*;
|
||||
import javax.tools.*;
|
||||
|
||||
public class TestTypeParameterAnnotations<@Foo @Bar @Baz T> extends JavacTestingAbstractProcessor {
|
||||
int round = 0;
|
||||
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
if (++round == 1) {
|
||||
int found = (new Scanner()).scan(roundEnv.getRootElements(), null);
|
||||
if (found == expect) {
|
||||
; //nop
|
||||
} else {
|
||||
error("unexpected number of results: expected " + expect
|
||||
+ ", found " + found);
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class Scanner extends JavacTestingAbstractProcessor.ElementScanner<Integer,Void> {
|
||||
@Override
|
||||
public Integer visitExecutable(ExecutableElement e, Void p) {
|
||||
super.visitExecutable(e, p);
|
||||
found += check(e, e.getTypeParameters());
|
||||
return found;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer visitType(TypeElement e, Void p) {
|
||||
super.visitType(e, p);
|
||||
found += check(e, e.getTypeParameters());
|
||||
return found;
|
||||
}
|
||||
|
||||
int found;
|
||||
}
|
||||
|
||||
int check(Element e, List<? extends TypeParameterElement> typarams) {
|
||||
if (typarams.isEmpty())
|
||||
return 0;
|
||||
if (typarams.size() != 1)
|
||||
return 0;
|
||||
|
||||
for (TypeParameterElement tpe: typarams) {
|
||||
boolean b1 = checkAnnotationMirrors(tpe, tpe.getAnnotationMirrors());
|
||||
boolean b2 = checkAnnotationMirrors(tpe, elements.getAllAnnotationMirrors(tpe));
|
||||
boolean b3 = checkGetAnnotation(tpe);
|
||||
boolean b4 = checkGetAnnotations(tpe);
|
||||
return b1 && b2 && b3 && b4 ? 1 : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean checkAnnotationMirrors(TypeParameterElement tpe, List<? extends AnnotationMirror> l) {
|
||||
if (l.size() != 3) {
|
||||
error("To few annotations, got " + l.size() +
|
||||
", should be 3", tpe);
|
||||
return false;
|
||||
}
|
||||
|
||||
AnnotationMirror m = l.get(0);
|
||||
if (!m.getAnnotationType().asElement().equals(elements.getTypeElement("Foo"))) {
|
||||
error("Wrong type of annotation, was expecting @Foo", m.getAnnotationType().asElement());
|
||||
return false;
|
||||
}
|
||||
m = l.get(1);
|
||||
if (!m.getAnnotationType().asElement().equals(elements.getTypeElement("Bar"))) {
|
||||
error("Wrong type of annotation, was expecting @Bar", m.getAnnotationType().asElement());
|
||||
return false;
|
||||
}
|
||||
m = l.get(2);
|
||||
if (!m.getAnnotationType().asElement().equals(elements.getTypeElement("Baz"))) {
|
||||
error("Wrong type of annotation, was expecting @Baz", m.getAnnotationType().asElement());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean checkGetAnnotation(TypeParameterElement tpe) {
|
||||
Foo f = tpe.getAnnotation(Foo.class);
|
||||
if (f == null)
|
||||
error("Expecting @Foo to be present in getAnnotation()", tpe);
|
||||
|
||||
Bar b = tpe.getAnnotation(Bar.class);
|
||||
if (b == null)
|
||||
error("Expecting @Bar to be present in getAnnotation()", tpe);
|
||||
|
||||
Baz z = tpe.getAnnotation(Baz.class);
|
||||
if (z == null)
|
||||
error("Expecting @Baz to be present in getAnnotation()", tpe);
|
||||
|
||||
return f != null &&
|
||||
b != null &&
|
||||
z != null;
|
||||
}
|
||||
|
||||
boolean checkGetAnnotations(TypeParameterElement tpe) {
|
||||
Foo[] f = tpe.getAnnotationsByType(Foo.class);
|
||||
if (f.length != 1) {
|
||||
error("Expecting 1 @Foo to be present in getAnnotationsByType()", tpe);
|
||||
return false;
|
||||
}
|
||||
|
||||
Bar[] b = tpe.getAnnotationsByType(Bar.class);
|
||||
if (b.length != 1) {
|
||||
error("Expecting 1 @Bar to be present in getAnnotationsByType()", tpe);
|
||||
return false;
|
||||
}
|
||||
|
||||
Baz[] z = tpe.getAnnotationsByType(Baz.class);
|
||||
if (z.length != 1) {
|
||||
error("Expecting 1 @Baz to be present in getAnnotationsByType()", tpe);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void note(String msg) {
|
||||
messager.printMessage(Diagnostic.Kind.NOTE, msg);
|
||||
}
|
||||
|
||||
void note(String msg, Element e) {
|
||||
messager.printMessage(Diagnostic.Kind.NOTE, msg, e);
|
||||
}
|
||||
|
||||
void error(String msg, Element e) {
|
||||
messager.printMessage(Diagnostic.Kind.ERROR, msg, e);
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
messager.printMessage(Diagnostic.Kind.ERROR, msg);
|
||||
}
|
||||
|
||||
// additional generic elements to test
|
||||
<@Foo @Bar @Baz X> X m(X x) { return x; }
|
||||
|
||||
interface Intf<@Foo @Bar @Baz X> { X m() ; }
|
||||
|
||||
class Class<@Foo @Bar @Baz X> {
|
||||
<@Foo @Bar @Baz Y> Class() { }
|
||||
}
|
||||
|
||||
final int expect = 5; // top level class, plus preceding examples
|
||||
}
|
||||
|
||||
@Target(ElementType.TYPE_PARAMETER)
|
||||
@interface Foo {}
|
||||
|
||||
@Target(ElementType.TYPE_PARAMETER)
|
||||
@interface Bar {}
|
||||
|
||||
@Target(ElementType.TYPE_PARAMETER)
|
||||
@interface Baz {}
|
Loading…
x
Reference in New Issue
Block a user