提交 1a53dc2e 编写于 作者: L lana

Merge

#
# 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"
......
<?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>
......
/*
* 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);
}
}
}
/*
* 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"));
}
}
#
# 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
/*
* 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() {
......
/*
* 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;
}
};
}
/*
* 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:
......
......@@ -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;
......
/*
* 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) {
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++)
for (int i = 0; i < xs.bits.length; i++) {
bits[i] = bits[i] & xs.bits[i];
return this;
}
}
/** 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.
......
/*
* 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.
......
/*
* 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
......
/*
* 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
*/
......
/*
* 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);
}
......
/*
* 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() {}
}
}
/*
* 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();
}
}
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
\ No newline at end of file
/*
* 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;
}
}
/*
* 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");
}
}
/*
* 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 {}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册