8142968: Module System implementation

Initial integration of JEP 200, JEP 260, JEP 261, and JEP 282

Co-authored-by: Alex Buckley <alex.buckley@oracle.com>
Co-authored-by: Jonathan Gibbons <jonathan.gibbons@oracle.com>
Co-authored-by: Karen Kinnear <karen.kinnear@oracle.com>
Co-authored-by: Mandy Chung <mandy.chung@oracle.com>
Co-authored-by: Mark Reinhold <mark.reinhold@oracle.com>
Co-authored-by: Jan Lahoda <jan.lahoda@oracle.com>
Co-authored-by: Vicente Romero <vicente.romero@oracle.com>
Co-authored-by: Andreas Lundblad <andreas.lundblad@oracle.com>
Co-authored-by: Andrey Nazarov <andrey.x.nazarov@oracle.com>
Co-authored-by: Chris Hegarty <chris.hegarty@oracle.com>
Co-authored-by: Erik Joelsson <erik.joelsson@oracle.com>
Co-authored-by: Kumar Srinivasan <kumar.x.srinivasan@oracle.com>
Co-authored-by: Sundararajan Athijegannathan <sundararajan.athijegannathan@oracle.com>
Reviewed-by: jjg, jlahoda, vromero, mcimadamore, bpatel, ksrini, darcy, anazarov, dfuchs
This commit is contained in:
Alan Bateman 2016-03-17 19:04:28 +00:00
parent 8cffe4fb02
commit 001ebb3a72
879 changed files with 26184 additions and 9697 deletions

View File

@ -32,23 +32,35 @@ include JavaCompilation.gmk
include SetupJavaCompilers.gmk include SetupJavaCompilers.gmk
################################################################################ ################################################################################
# Setup the rules to build the interim langtools jar, which is compiled by # Setup the rules to build interim langtools, which is compiled by the boot
# the boot javac and can be run on the boot jdk. This will be used to compile # javac and can be run on the boot jdk. This will be used to compile
# the rest of the product. Include the Genstubs build tool in this compilation # the rest of the product. Each module is compiled separately to allow a modular
# as it will be used together with the interim javac. # boot jdk to override system classes using -Xoverride:.
$(eval $(call SetupJavaCompilation,BUILD_INTERIM_LANGTOOLS, \
SETUP := BOOT_JAVAC, \
DISABLE_SJAVAC := true, \
SRC := $(LANGTOOLS_TOPDIR)/src/java.compiler/share/classes \
$(LANGTOOLS_TOPDIR)/src/jdk.compiler/share/classes \
$(LANGTOOLS_TOPDIR)/src/jdk.javadoc/share/classes \
$(LANGTOOLS_TOPDIR)/src/jdk.jdeps/share/classes \
$(SUPPORT_OUTPUTDIR)/gensrc/jdk.compiler \
$(SUPPORT_OUTPUTDIR)/gensrc/jdk.javadoc \
$(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdeps, \
EXCLUDES := sun, \
COPY := .gif .png .xml .css .js javax.tools.JavaCompilerTool, \
BIN := $(BUILDTOOLS_OUTPUTDIR)/langtools_interim_classes, \
JAR := $(INTERIM_LANGTOOLS_JAR)))
all: $(BUILD_INTERIM_LANGTOOLS) # Param 1 - Name of module to compile
# Param 2 - Name of modules to depend on
define SetupInterimModule
$$(eval $$(call SetupJavaCompilation,BUILD_INTERIM_$(strip $1), \
SETUP := BOOT_JAVAC, \
DISABLE_SJAVAC := true, \
SRC := $(LANGTOOLS_TOPDIR)/src/$(strip $1)/share/classes \
$$(wildcard $(SUPPORT_OUTPUTDIR)/gensrc/$(strip $1)), \
EXCLUDES := sun com/sun/tools/jdeps com/sun/tools/javap, \
EXCLUDE_FILES := module-info.java, \
COPY := .gif .png .xml .css .js javax.tools.JavaCompilerTool, \
BIN := $(BUILDTOOLS_OUTPUTDIR)/override_modules/$(strip $1), \
ADD_JAVAC_FLAGS := -Xbootclasspath/p:$$(call PathList, \
$$(foreach m, $2, $(BUILDTOOLS_OUTPUTDIR)/override_modules/$$m)), \
))
$$(BUILD_INTERIM_$(strip $1)): $$(foreach m, $2, $$(BUILD_INTERIM_$(strip $$m)))
TARGETS += $$(BUILD_INTERIM_$(strip $1))
endef
$(eval $(call SetupInterimModule, java.compiler))
$(eval $(call SetupInterimModule, jdk.compiler, java.compiler))
$(eval $(call SetupInterimModule, jdk.jdeps, jdk.compiler java.compiler))
$(eval $(call SetupInterimModule, jdk.javadoc, java.compiler jdk.compiler))
all: $(TARGETS)

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -24,58 +24,13 @@
# #
#javac configuration for "normal build" (these will be passed to the bootstrap compiler): #javac configuration for "normal build" (these will be passed to the bootstrap compiler):
javac.debug = true javac.opts = -XDignore.symbol.file=true -Xlint:all,-deprecation,-options -Werror -g:source,lines,vars
javac.debuglevel = source,lines,vars javac.source = 9
javac.extra.opts=-XDignore.symbol.file=true javac.target = 9
javac.includes=
javac.lint.opts = -Xlint:all,-deprecation -Werror
javac.source = 8
javac.target = 8
#javac configuration for bootstrap build (these will be passed to the compiler from the given boot JDK): langtools.resource.includes = \
boot.javac.extra.opts=-XDignore.symbol.file=true
boot.javac.includes = \
javax/annotation/processing/ \
javax/lang/model/ \
javax/tools/ \
jdk/ \
com/sun/source/ \
com/sun/tools/javac/ \
com/sun/tools/doclint/
boot.javac.lint.opts=
boot.javac.source = 8
boot.javac.target = 8
#configuration of submodules (share by both the bootstrap and normal compilation):
langtools.modules=java.compiler:jdk.compiler:jdk.jdeps:jdk.javadoc:jdk.jshell:jdk.internal.le:jdk.jdi
java.compiler.dependencies=
jdk.compiler.dependencies=java.compiler
jdk.javadoc.dependencies=java.compiler:jdk.compiler
jdk.jdeps.dependencies=java.compiler:jdk.compiler
jdk.internal.le.dependencies=
jdk.jdi.dependencies=
jdk.jshell.dependencies=java.compiler:jdk.internal.le:jdk.compiler:jdk.jdi
tool.javac.main.class=com.sun.tools.javac.Main
tool.javadoc.main.class=com.sun.tools.javadoc.Main
tool.javap.main.class=com.sun.tools.javap.Main
tool.javah.main.class=com.sun.tools.javah.Main
tool.sjavac.main.class=com.sun.tools.sjavac.Main
tool.jshell.main.class=jdk.internal.jshell.tool.JShellTool
javac.resource.includes = \
com/sun/tools/javac/resources/compiler.properties com/sun/tools/javac/resources/compiler.properties
#test configuration:
jtreg.tests=
boot.javac.tests = tools/javac
crules.tests = ../make/test/crules
#javadoc configuration
javadoc.jls.cite=The Java&trade; Language Specification
javadoc.jls.option=-tag "jls:a:See &lt;cite&gt;${javadoc.jls.cite}&lt;/cite&gt;:" \
-tag "implNote:a:Implementation Note:"
# Version info -- override as needed # Version info -- override as needed
jdk.version = 9 jdk.version = 9
build.number = b00 build.number = b00
@ -89,3 +44,14 @@ milestone = internal
# FIXME -- need to include openjdk as needed # FIXME -- need to include openjdk as needed
release = ${jdk.version}-${milestone} release = ${jdk.version}-${milestone}
full.version = ${release}+${build.number} full.version = ${release}+${build.number}
#tools configuration:
tool.javac.main.class=com.sun.tools.javac.Main
tool.javadoc.main.class=jdk.javadoc.internal.tool.Main
tool.javap.main.class=com.sun.tools.javap.Main
tool.javah.main.class=com.sun.tools.javah.Main
tool.sjavac.main.class=com.sun.tools.sjavac.Main
tool.jshell.main.class=jdk.internal.jshell.tool.JShellTool
#test configuration:
jtreg.tests=

File diff suppressed because it is too large Load Diff

View File

@ -39,6 +39,10 @@ $(eval $(call SetupJavaCompilation, COMPILE_CREATE_SYMBOLS, \
BIN := $(BUILDTOOLS_OUTPUTDIR)/create_symbols, \ BIN := $(BUILDTOOLS_OUTPUTDIR)/create_symbols, \
)) ))
ifeq ($(BOOT_JDK_MODULAR), true)
COMPILECREATESYMBOLS_ADD_EXPORTS := -XaddExports:jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED,jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED,jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED
endif
$(SUPPORT_OUTPUTDIR)/symbols/ct.sym-files/_the.symbols: \ $(SUPPORT_OUTPUTDIR)/symbols/ct.sym-files/_the.symbols: \
$(COMPILE_CREATE_SYMBOLS) \ $(COMPILE_CREATE_SYMBOLS) \
$(wildcard $(LANGTOOLS_TOPDIR)/make/data/symbols/*) $(wildcard $(LANGTOOLS_TOPDIR)/make/data/symbols/*)
@ -46,6 +50,7 @@ $(SUPPORT_OUTPUTDIR)/symbols/ct.sym-files/_the.symbols: \
$(MKDIR) -p $(@D) $(MKDIR) -p $(@D)
$(ECHO) Creating ct.sym classes $(ECHO) Creating ct.sym classes
$(JAVA) $(INTERIM_LANGTOOLS_ARGS) \ $(JAVA) $(INTERIM_LANGTOOLS_ARGS) \
$(COMPILECREATESYMBOLS_ADD_EXPORTS) \
-classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols \ -classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols \
build.tools.symbolgenerator.CreateSymbols \ build.tools.symbolgenerator.CreateSymbols \
build-ctsym \ build-ctsym \

View File

@ -3,16 +3,12 @@
<component name="AntConfiguration"> <component name="AntConfiguration">
<buildFile url="file://$PROJECT_DIR$/.idea/build.xml"> <buildFile url="file://$PROJECT_DIR$/.idea/build.xml">
<properties> <properties>
<property name="boot.java.home" value="$JDKPath$" />
<property name="jtreg.tests" value="$FilePath$" /> <property name="jtreg.tests" value="$FilePath$" />
<property name="target.java.home" value="@IDEA_TARGET_JDK@" /> <property name="langtools.jdk.home" value="@IDEA_TARGET_JDK@" />
<property name="jtreg.home" value="@IDEA_JTREG_HOME@" /> <property name="jtreg.home" value="@IDEA_JTREG_HOME@" />
<property name="javac.debuglevel" value="source,lines,vars" /> <property name="jtreg.jpda.jvmargs" value="-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=5900" />
<property name="jtreg.jpda.jvmargs" value="-agentlib:jdwp=transport=dt_socket,server=n,address=localhost:5900,suspend=y" />
</properties> </properties>
<executeOn event="afterCompilation" target="post-make" /> <executeOn event="afterCompilation" target="post-make" />
</buildFile> </buildFile>
</component> </component>
</project> </project>

View File

@ -15,8 +15,7 @@
<java classname="org.apache.tools.ant.Main" fork="true" spawn="true"> <java classname="org.apache.tools.ant.Main" fork="true" spawn="true">
<arg value="-f"/> <arg value="-f"/>
<arg value="@{antfile}"/> <arg value="@{antfile}"/>
<arg value="-Dboot.java.home=${boot.java.home}"/> <arg value="-Dlangtools.jdk.home=${langtools.jdk.home}"/>
<arg value="-Dtarget.java.home=${target.java.home}"/>
<arg value="-Djtreg.home=${jtreg.home}"/> <arg value="-Djtreg.home=${jtreg.home}"/>
<arg value="-Djtreg.tests=${jtreg.tests}"/> <arg value="-Djtreg.tests=${jtreg.tests}"/>
<arg value="-Djtreg.jpda.jvmargs=${jtreg.jpda.jvmargs}"/> <arg value="-Djtreg.jpda.jvmargs=${jtreg.jpda.jvmargs}"/>
@ -28,18 +27,13 @@
</sequential> </sequential>
</macrodef> </macrodef>
<target name="crules" depends="build-all-tools,-def-jtreg">
<jtreg-tool name="all" tests="tools/all/RunCodingRules.java"/>
</target>
<target name="post-make" depends="clean, build-all-tools"/> <target name="post-make" depends="clean, build-all-tools"/>
<target name="jtreg-debug" depends="build-all-tools,-def-jtreg"> <target name="jtreg-debug" depends="build-all-tools, -def-jtreg">
<exec-target target="jtreg-debug-internal"/> <exec-target target="jtreg-debug-internal"/>
</target> </target>
<target name="jtreg-debug-internal" depends="-def-jtreg"> <target name="jtreg-debug-internal" depends="-def-jtreg">
<jtreg-tool name="all" tests="${jtreg.tests}" jpda.jvmargs="${jtreg.jpda.jvmargs}"/> <jtreg-tool name="all" tests="${jtreg.tests}" options="-conc:1" jpda.jvmargs="${jtreg.jpda.jvmargs}"/>
</target> </target>
</project> </project>

View File

@ -8,12 +8,11 @@
<sourceFolder url="file://$MODULE_DIR$/src/jdk.compiler/share/classes" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/jdk.compiler/share/classes" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/jdk.javadoc/share/classes" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/jdk.javadoc/share/classes" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/jdk.jdeps/share/classes" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/jdk.jdeps/share/classes" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/bootstrap/java.compiler/gensrc" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/bootstrap/jdk.compiler/gensrc" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/bootstrap/jdk.javadoc/gensrc" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/bootstrap/jdk.jdeps/gensrc" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/jdk.jshell/share/classes" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/jdk.jshell/share/classes" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/gensrc/jdk.compiler" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/gensrc/jdk.javadoc" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/gensrc/jdk.jdeps" isTestSource="false" />
</content> </content>
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />

View File

@ -124,8 +124,8 @@ public final class LangtoolsIdeaAntLogger extends DefaultLogger {
* This enum is used to represent the list of tasks we need to keep track of during logging. * This enum is used to represent the list of tasks we need to keep track of during logging.
*/ */
enum Task { enum Task {
/** javac task - invoked during compilation */ /** exec task - invoked during compilation */
JAVAC("javac", MessageKind.JAVAC_ERROR, MessageKind.JAVAC_WARNING, MessageKind.JAVAC_NOTE, JAVAC("exec", MessageKind.JAVAC_ERROR, MessageKind.JAVAC_WARNING, MessageKind.JAVAC_NOTE,
MessageKind.JAVAC_NESTED_DIAG, MessageKind.JAVAC_CRASH), MessageKind.JAVAC_NESTED_DIAG, MessageKind.JAVAC_CRASH),
/** jtreg task - invoked during test execution */ /** jtreg task - invoked during test execution */
JTREG("jtreg", MessageKind.JTREG_TEST_PASSED, MessageKind.JTREG_TEST_FAILED, MessageKind.JTREG_TEST_ERROR, MessageKind.JTREG_TEST_REPORT), JTREG("jtreg", MessageKind.JTREG_TEST_PASSED, MessageKind.JTREG_TEST_FAILED, MessageKind.JTREG_TEST_ERROR, MessageKind.JTREG_TEST_REPORT),

View File

@ -7,14 +7,14 @@
<option name="MAKE_PROJECT_ON_SAVE" value="true" /> <option name="MAKE_PROJECT_ON_SAVE" value="true" />
</component> </component>
<component name="RunManager" selected="Application.javac"> <component name="RunManager" selected="Application.javac">
<!-- standard tools --> <!-- javac -->
<configuration default="false" name="javac" type="Application" factoryName="Application"> <configuration default="false" name="javac" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javac.Main" /> <option name="MAIN_CLASS_NAME" value="com.sun.tools.javac.Main" />
<option name="VM_PARAMETERS" value="-Xbootclasspath/p:build@FILE_SEP@java.compiler@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.compiler@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.javadoc@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.jdeps@FILE_SEP@classes" /> <option name="VM_PARAMETERS" value="-Xpatch:build@FILE_SEP@modules" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" /> <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="" /> <option name="ALTERNATIVE_JRE_PATH" value="@IDEA_TARGET_JDK@" />
<option name="ENABLE_SWING_INSPECTOR" value="false" /> <option name="ENABLE_SWING_INSPECTOR" value="false" />
<option name="ENV_VARIABLES" /> <option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" /> <option name="PASS_PARENT_ENVS" value="true" />
@ -27,13 +27,14 @@
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" /> <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
</method> </method>
</configuration> </configuration>
<!-- javadoc -->
<configuration default="false" name="javadoc" type="Application" factoryName="Application"> <configuration default="false" name="javadoc" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javadoc.Main" /> <option name="MAIN_CLASS_NAME" value="com.sun.tools.javadoc.Main" />
<option name="VM_PARAMETERS" value="-Xbootclasspath/p:build@FILE_SEP@java.compiler@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.compiler@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.javadoc@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.jdeps@FILE_SEP@classes" /> <option name="VM_PARAMETERS" value="-Xpatch:build@FILE_SEP@modules" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" /> <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="" /> <option name="ALTERNATIVE_JRE_PATH" value="@IDEA_TARGET_JDK@" />
<option name="ENABLE_SWING_INSPECTOR" value="false" /> <option name="ENABLE_SWING_INSPECTOR" value="false" />
<option name="ENV_VARIABLES" /> <option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" /> <option name="PASS_PARENT_ENVS" value="true" />
@ -46,13 +47,14 @@
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" /> <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
</method> </method>
</configuration> </configuration>
<!-- javap -->
<configuration default="false" name="javap" type="Application" factoryName="Application"> <configuration default="false" name="javap" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javap.Main" /> <option name="MAIN_CLASS_NAME" value="com.sun.tools.javap.Main" />
<option name="VM_PARAMETERS" value="-Xbootclasspath/p:build@FILE_SEP@java.compiler@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.compiler@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.javadoc@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.jdeps@FILE_SEP@classes" /> <option name="VM_PARAMETERS" value="-Xpatch:build@FILE_SEP@modules" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" /> <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="" /> <option name="ALTERNATIVE_JRE_PATH" value="@IDEA_TARGET_JDK@" />
<option name="ENABLE_SWING_INSPECTOR" value="false" /> <option name="ENABLE_SWING_INSPECTOR" value="false" />
<option name="ENV_VARIABLES" /> <option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" /> <option name="PASS_PARENT_ENVS" value="true" />
@ -65,13 +67,14 @@
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" /> <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
</method> </method>
</configuration> </configuration>
<!-- javah -->
<configuration default="false" name="javah" type="Application" factoryName="Application"> <configuration default="false" name="javah" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javah.Main" /> <option name="MAIN_CLASS_NAME" value="com.sun.tools.javah.Main" />
<option name="VM_PARAMETERS" value="-Xbootclasspath/p:build@FILE_SEP@java.compiler@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.compiler@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.javadoc@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.jdeps@FILE_SEP@classes" /> <option name="VM_PARAMETERS" value="-Xpatch:build@FILE_SEP@modules" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" /> <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="" /> <option name="ALTERNATIVE_JRE_PATH" value="@IDEA_TARGET_JDK@" />
<option name="ENABLE_SWING_INSPECTOR" value="false" /> <option name="ENABLE_SWING_INSPECTOR" value="false" />
<option name="ENV_VARIABLES" /> <option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" /> <option name="PASS_PARENT_ENVS" value="true" />
@ -84,13 +87,14 @@
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" /> <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
</method> </method>
</configuration> </configuration>
<!-- sjavac -->
<configuration default="false" name="sjavac" type="Application" factoryName="Application"> <configuration default="false" name="sjavac" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="com.sun.tools.sjavac.Main" /> <option name="MAIN_CLASS_NAME" value="com.sun.tools.sjavac.Main" />
<option name="VM_PARAMETERS" value="-Xbootclasspath/p:build@FILE_SEP@java.compiler@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.compiler@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.javadoc@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@jdk.jdeps@FILE_SEP@classes" /> <option name="VM_PARAMETERS" value="-Xpatch:build@FILE_SEP@modules" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" /> <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="" /> <option name="ALTERNATIVE_JRE_PATH" value="@IDEA_TARGET_JDK@" />
<option name="ENABLE_SWING_INSPECTOR" value="false" /> <option name="ENABLE_SWING_INSPECTOR" value="false" />
<option name="ENV_VARIABLES" /> <option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" /> <option name="PASS_PARENT_ENVS" value="true" />
@ -103,13 +107,15 @@
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" /> <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
</method> </method>
</configuration> </configuration>
<!-- jshell -->
<configuration default="false" name="jshell" type="Application" factoryName="Application"> <configuration default="false" name="jshell" type="Application" factoryName="Application">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" /> <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="jdk.internal.jshell.tool.JShellTool" /> <option name="MAIN_CLASS_NAME" value="jdk.internal.jshell.tool.JShellTool" />
<option name="VM_PARAMETERS" value="-Xbootclasspath/p:build/jdk.internal.le/classes:build/jdk.jdi/classes:build/jdk.jshell/classes:build/java.compiler/classes:build/jdk.compiler/classes:build/jdk.javadoc/classes:build/jdk.jdeps/classes" /> <option name="VM_PARAMETERS" value="-Xpatch:build@FILE_SEP@modules -XaddExports:jdk.jshell/jdk.internal.jshell.tool=ALL-UNNAMED" />
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" /> <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" /> <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="ALTERNATIVE_JRE_PATH" value="@IDEA_TARGET_JDK@" />
<option name="ENABLE_SWING_INSPECTOR" value="false" /> <option name="ENABLE_SWING_INSPECTOR" value="false" />
<option name="ENV_VARIABLES" /> <option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" /> <option name="PASS_PARENT_ENVS" value="true" />
@ -120,24 +126,11 @@
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" /> <option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-all-classes" />
</method> </method>
</configuration> </configuration>
<!-- bootstrap javac --> <!-- jtreg run -->
<configuration default="false" name="javac (bootstrap)" type="Application" factoryName="Application"> <configuration default="false" name="jtreg (run)" type="AntRunConfiguration" factoryName="Ant Target">
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javac.Main" /> <antsettings antfile="file://$PROJECT_DIR$/.idea/build.xml" target="jtreg" />
<option name="VM_PARAMETERS" value="-Xbootclasspath/p:build@FILE_SEP@bootstrap@FILE_SEP@java.compiler@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@bootstrap@FILE_SEP@jdk.compiler@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@bootstrap@FILE_SEP@jdk.javadoc@FILE_SEP@classes@PATH_SEP@build@FILE_SEP@bootstrap@FILE_SEP@jdk.jdeps@FILE_SEP@classes" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" value="" />
<option name="ENABLE_SWING_INSPECTOR" value="false" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<module name="langtools" />
<envs />
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Run" />
<method> <method>
<option name="Make" enabled="false" /> <option name="Make" enabled="false" />
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-bootstrap-javac" />
</method> </method>
</configuration> </configuration>
<!-- jtreg debug --> <!-- jtreg debug -->
@ -181,4 +174,3 @@
</buildFile> </buildFile>
</component> </component>
</project> </project>

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# #
# Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -31,22 +31,10 @@ case `uname -s` in
mydir=`cygpath -m $mydir` mydir=`cygpath -m $mydir`
;; ;;
esac esac
mylib="$mydir/../lib" mylib="$mydir/../modules"
# By default, put the jar file and its dependencies on the bootclasspath. # patch langtools modules
# This is always required on a Mac, because the system langtools classes bcp=-Xpatch:"$mylib"
# are always on the main class path; in addition, it may be required on
# standard versions of JDK (i.e. using rt.jar and tools.jar) because some
# langtools interfaces are in rt.jar.
# Assume that the jar file being invoked lists all the necessary langtools
# jar files in its Class-Path manifest entry, so there is no need to search
# dependent jar files for additional dependencies.
if [ "$LANGTOOLS_USE_BOOTCLASSPATH" != "no" ]; then
cp=`echo "$mylib"/*.jar |
sed -e 's|\([a-z.]*\.jar\) *|\1#PS#|g'`
bcp=$cp
fi
# tools currently assumes that assertions are enabled in the launcher # tools currently assumes that assertions are enabled in the launcher
ea=-ea:com.sun.tools... ea=-ea:com.sun.tools...
@ -71,4 +59,4 @@ done
unset DUALCASE unset DUALCASE
IFS=$nl IFS=$nl
"#TARGET_JAVA#" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} #PROGRAM# ${toolOpts} "#TARGET_JAVA#" $bcp ${ea} ${javaOpts} #PROGRAM# ${toolOpts}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -48,20 +48,12 @@
<!-- Build project. (action: build; F11) --> <!-- Build project. (action: build; F11) -->
<target name="build" depends="-get-tool-if-set,-build-bootstrap-javac,-build-all" />
<target name="-build-bootstrap-javac" if="langtools.tool.bootstrap">
<antcall target="build-bootstrap-javac"/>
</target>
<target name="-build-all" unless="langtools.tool.bootstrap">
<antcall target="build-all-tools"/>
</target>
<!-- Compile a single file. (action: compile.single; F9) --> <!-- Compile a single file. (action: compile.single; F9) -->
<target name="compile-single" depends="-get-tool-if-set,build-bootstrap-javac-classes" unless="langtools.tool.bootstrap"> <target name="compile-single" depends="-get-tool-if-set,-check-langtools.jdk.home">
<fail unless="includes">Must set property 'includes'</fail> <fail unless="includes">Must set property 'includes'</fail>
<mkdir dir="${build.dir}/${module.name}/classes" /> <mkdir dir="${build.dir}/${module.name}/classes" />
<javac fork="true" executable="${boot.java.home}/bin/javac" <javac fork="true" executable="${java.home}/bin/javac"
srcdir="${basedir}/src/${module.name}/share/classes" srcdir="${basedir}/src/${module.name}/share/classes"
destdir="${build.dir}/${module.name}/classes" destdir="${build.dir}/${module.name}/classes"
includes="${includes}" includes="${includes}"
@ -72,7 +64,6 @@
target="${javac.target}" target="${javac.target}"
debug="${javac.debug}" debug="${javac.debug}"
debuglevel="${javac.debuglevel}"> debuglevel="${javac.debuglevel}">
<compilerarg value="-J-Xbootclasspath/p:${build.bootstrap.dir}/classes"/>
</javac> </javac>
</target> </target>
@ -81,12 +72,11 @@
the user. the user.
--> -->
<target name="run" depends="-check-target.java.home,-build-classes,-def-run,-get-tool-and-args,-setup-bootclasspath,-def-resolve-main-class" <target name="run" depends="-check-langtools.jdk.home,-build-classes,-def-run,-get-tool-and-args,-def-resolve-main-class"
description="run tool"> description="run tool">
<echo level="info" message="${with_bootclasspath}"/> <echo level="info" message="Run ${langtools.tool.name} with args ${langtools.tool.args}"/>
<echo level="info" message="Run ${use_bootstrap}${langtools.tool.name} with args ${langtools.tool.args}"/>
<resolve-main-class tool.name="${langtools.tool.name}" /> <resolve-main-class tool.name="${langtools.tool.name}" />
<run bcp="${with_bootclasspath}" mainclass="${langtools.main.class}" args="${langtools.tool.args}"/> <run mainclass="${langtools.main.class}" args="${langtools.tool.args}"/>
</target> </target>
<target name="-def-resolve-main-class"> <target name="-def-resolve-main-class">
@ -102,17 +92,14 @@
</macrodef> </macrodef>
</target> </target>
<target name="-build-classes" depends="-get-tool-if-set,-build-classes-bootstrap-javac,-build-classes-all" /> <target name="-build-classes" depends="-get-tool-if-set,-build-classes-all" />
<target name="-build-classes-bootstrap-javac" if="langtools.tool.bootstrap"> <target name="-build-classes-all">
<antcall target="build-bootstrap-javac-classes"/>
</target>
<target name="-build-classes-all" unless="langtools.tool.bootstrap">
<antcall target="build-all-classes"/> <antcall target="build-all-classes"/>
</target> </target>
<!-- Run a selected class. (action: run.single; shift-F6) --> <!-- Run a selected class. (action: run.single; shift-F6) -->
<target name="run-single" depends="-check-target.java.home,-setup-bootclasspath,-def-run"> <target name="run-single" depends="-check-langtools.jdk.home,-def-run">
<fail unless="run.classname">Must set property 'run.classname' </fail> <fail unless="run.classname">Must set property 'run.classname' </fail>
<echo level="info" message="run ${run.classname}"/> <echo level="info" message="run ${run.classname}"/>
<run mainclass="${run.classname}" args=""/> <run mainclass="${run.classname}" args=""/>
@ -123,22 +110,12 @@
test all tools. test all tools.
--> -->
<target name="jtreg" depends="-get-tool-if-set,-jtreg-bootstrap-javac,-jtreg-all" <target name="jtreg" depends="-get-tool-if-set,-jtreg-all"
description="Test langtools tools or bootstrap javac" description="Test langtools tools"
/> />
<target name="-jtreg-bootstrap-javac" if="langtools.tool.bootstrap"> <target name="-jtreg-all">
<echo level="info" message="Testing bootstrap javac"/>
<echo level="verbose" message="(Unset langtools.tool.bootstrap to test all tools)"/>
<antcall>
<target name="jtreg-bootstrap-javac"/>
<target name="-show-jtreg"/>
</antcall>
</target>
<target name="-jtreg-all" unless="langtools.tool.bootstrap">
<echo level="info" message="Testing all tools"/> <echo level="info" message="Testing all tools"/>
<echo level="verbose" message="(Set langtools.tool.bootstrap to test bootstrap javac)"/>
<antcall> <antcall>
<target name="langtools.jtreg"/> <target name="langtools.jtreg"/>
<target name="-show-jtreg"/> <target name="-show-jtreg"/>
@ -173,29 +150,27 @@
<!-- Debug tool in NetBeans. --> <!-- Debug tool in NetBeans. -->
<target name="debug" depends="-check-target.java.home,-def-run,-def-start-debugger,-get-tool-and-args,-setup-bootclasspath,-build-classes,-def-resolve-main-class" if="netbeans.home"> <target name="debug" depends="-check-langtools.jdk.home,-def-run,-def-start-debugger,-get-tool-and-args,-build-classes,-def-resolve-main-class" if="netbeans.home">
<echo level="info" message="Debug ${use_bootstrap}${langtools.tool.name} with args ${langtools.tool.args}"/> <echo level="info" message="Debug ${langtools.tool.name} with args ${langtools.tool.args}"/>
<start-debugger/> <start-debugger/>
<resolve-main-class tool.name="${langtools.tool.name}" /> <resolve-main-class tool.name="${langtools.tool.name}" />
<run bcp="${with_bootclasspath}" mainclass="${langtools.main.class}" args="${langtools.tool.args}" jpda.jvmargs="${jpda.jvmargs}"/> <run mainclass="${langtools.main.class}" args="${langtools.tool.args}" jpda.jvmargs="${jpda.jvmargs}"/>
</target> </target>
<!-- Debug a selected class . --> <!-- Debug a selected class . -->
<target name="debug-single" depends="-check-target.java.home,-def-start-debugger,-def-run"> <target name="debug-single" depends="-check-langtools.jdk.home,-def-start-debugger,-def-run">
<fail unless="debug.classname">Must set property 'debug.classname'</fail> <fail unless="debug.classname">Must set property 'debug.classname'</fail>
<start-debugger/> <start-debugger/>
<run mainclass="${debug.classname}" args="" jpda.jvmargs="${jpda.jvmargs}"/> <run mainclass="${debug.classname}" args="" jpda.jvmargs="${jpda.jvmargs}"/>
</target> </target>
<!-- Debug a jtreg test. --> <!-- Debug a jtreg test. -->
<target name="debug-jtreg" depends="-check-target.java.home,-def-start-debugger,-def-jtreg,-get-tool-if-set,-setup-bootclasspath"> <target name="debug-jtreg" depends="-check-langtools.jdk.home,-def-start-debugger,-def-jtreg,-get-tool-if-set">
<fail unless="jtreg.tests">Must set property 'jtreg.tests'</fail> <fail unless="jtreg.tests">Must set property 'jtreg.tests'</fail>
<start-debugger/> <start-debugger/>
<jtreg-tool name="debug" <jtreg-tool name="debug"
samevm="false"
tests="${jtreg.tests}" tests="${jtreg.tests}"
jpda.jvmargs="${jpda.jvmargs}" jpda.jvmargs="${jpda.jvmargs}"/>
langtools.classes="${with_bootclasspath}"/>
</target> </target>
<!-- Update a class being debugged. --> <!-- Update a class being debugged. -->
@ -206,11 +181,7 @@
<antcall target="compile-single"> <antcall target="compile-single">
<param name="includes" value="${class}.java"/> <param name="includes" value="${class}.java"/>
</antcall> </antcall>
<condition property="build.classes.dir" <property name="build.classes.dir" value="${build.dir}/${module.name}/classes" />
value="${build.dir}/${module.name}/classes"
else="${boot.build.dir}/${module.name}/classes">
<isset property="use_bootstrap"/>
</condition>
<nbjpdareload> <nbjpdareload>
<fileset dir="${build.classes.dir}"> <fileset dir="${build.classes.dir}">
<include name="${class}.class"/> <include name="${class}.class"/>
@ -218,23 +189,11 @@
</nbjpdareload> </nbjpdareload>
</target> </target>
<!-- Generate javadoc for one or all tools. (action: javadoc; Alt-F6)
If langtools.tool.name is set, then just test that tool; otherwise
test all tools.
-->
<target name="javadoc" depends="langtools.javadoc,-show-javadoc" />
<target name="-show-javadoc" if="netbeans.home">
<nbbrowse file="${build.javadoc.dir}/index.html"/>
</target>
<!-- Prompt for values. --> <!-- Prompt for values. -->
<target name="-get-tool-if-set" depends="-def-select-tool"> <target name="-get-tool-if-set" depends="-def-select-tool">
<select-tool <select-tool
toolproperty="langtools.tool.name" toolproperty="langtools.tool.name"
bootstrapproperty="langtools.tool.bootstrap"
propertyfile="${langtools.properties}" propertyfile="${langtools.properties}"
askIfUnset="false" askIfUnset="false"
/> />
@ -244,32 +203,22 @@
<select-tool <select-tool
toolproperty="langtools.tool.name" toolproperty="langtools.tool.name"
argsproperty="langtools.tool.args" argsproperty="langtools.tool.args"
bootstrapproperty="langtools.tool.bootstrap"
propertyfile="${langtools.properties}" propertyfile="${langtools.properties}"
askIfUnset="true" askIfUnset="true"
/> />
</target> </target>
<target name="-setup-bootclasspath">
<condition property="use_bootstrap" value="bootstrap-" else="">
<isset property="langtools.tool.bootstrap"/>
</condition>
<condition property="with_bootclasspath" value="${langtools.boot.classes}" else="${langtools.classes}">
<isset property="langtools.tool.bootstrap"/>
</condition>
</target>
<!-- Macro to run a tool or selected class - used by run* and debug* tasks --> <!-- Macro to run a tool or selected class - used by run* and debug* tasks -->
<target name="-def-run"> <target name="-def-run">
<macrodef name="run"> <macrodef name="run">
<attribute name="mainclass"/> <attribute name="mainclass"/>
<attribute name="args" default=""/> <attribute name="args" default=""/>
<attribute name="bcp" default="${with_bootclasspath}"/> <attribute name="build.modules" default="${build.modules}"/>
<attribute name="jpda.jvmargs" default=""/> <attribute name="jpda.jvmargs" default=""/>
<sequential> <sequential>
<java fork="true" jvm="${target.java.home}/bin/java" classname="@{mainclass}"> <java fork="true" jvm="${langtools.jdk.home}/bin/java" classname="@{mainclass}">
<jvmarg line="-Xbootclasspath/p:@{bcp}"/> <jvmarg line="-Xpatch:@{build.modules}"/>
<jvmarg line="@{jpda.jvmargs}"/> <jvmarg line="@{jpda.jvmargs}"/>
<arg line="@{args}"/> <arg line="@{args}"/>
</java> </java>
@ -285,11 +234,7 @@
<nbjpdastart name="${ant.project.name}" addressproperty="jpda.address" transport="dt_socket"> <nbjpdastart name="${ant.project.name}" addressproperty="jpda.address" transport="dt_socket">
<bootclasspath> <bootclasspath>
<pathelement path="${langtools.classes}"/> <pathelement path="${langtools.classes}"/>
<pathelement location="${target.java.home}/jre/lib/rt.jar"/>
</bootclasspath> </bootclasspath>
<sourcepath>
<pathelement path="${langtools.sources}"/>
</sourcepath>
</nbjpdastart> </nbjpdastart>
<property <property
name="@{jpda.jvmargs.property}" name="@{jpda.jvmargs.property}"
@ -300,6 +245,7 @@
</target> </target>
<target name="-def-select-tool"> <target name="-def-select-tool">
<property name="build.toolclasses.dir" location="${build.dir}/toolclasses"/>
<mkdir dir="${build.toolclasses.dir}"/> <mkdir dir="${build.toolclasses.dir}"/>
<javac srcdir="${make.tools.dir}" <javac srcdir="${make.tools.dir}"
includes="anttasks/SelectTool*" includes="anttasks/SelectTool*"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions
@ -408,9 +408,6 @@
</arity> </arity>
</context> </context>
</action> </action>
<action name="javadoc">
<target>javadoc</target>
</action>
<action name="select-tool"> <action name="select-tool">
<target>select-tool</target> <target>select-tool</target>
</action> </action>
@ -477,7 +474,6 @@
<ide-action name="build"/> <ide-action name="build"/>
<ide-action name="rebuild"/> <ide-action name="rebuild"/>
<ide-action name="clean"/> <ide-action name="clean"/>
<ide-action name="javadoc"/>
<separator/> <separator/>
<ide-action name="run"/> <ide-action name="run"/>
<ide-action name="debug"/> <ide-action name="debug"/>
@ -490,37 +486,35 @@
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4"> <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4">
<compilation-unit> <compilation-unit>
<package-root>${root}/src/java.compiler/share/classes</package-root> <package-root>${root}/src/java.compiler/share/classes</package-root>
<package-root>${root}/build/bootstrap/java.compiler/gensrc</package-root> <package-root>${root}/build/gensrc/java.compiler</package-root>
<built-to>${root}/build/java.compiler/classes</built-to> <built-to>${root}/build/java.compiler/classes</built-to>
<source-level>1.8</source-level> <source-level>1.8</source-level>
</compilation-unit> </compilation-unit>
<compilation-unit> <compilation-unit>
<package-root>${root}/src/jdk.compiler/share/classes</package-root> <package-root>${root}/src/jdk.compiler/share/classes</package-root>
<package-root>${root}/build/bootstrap/jdk.compiler/gensrc</package-root> <package-root>${root}/build/gensrc/jdk.compiler</package-root>
<classpath mode="compile">${root}/build/java.compiler/classes</classpath> <classpath mode="compile">${root}/build/java.compiler/classes</classpath>
<built-to>${root}/build/jdk.compiler/classes</built-to> <built-to>${root}/build/jdk.compiler/classes</built-to>
<source-level>1.8</source-level> <source-level>1.8</source-level>
</compilation-unit> </compilation-unit>
<compilation-unit> <compilation-unit>
<package-root>${root}/src/jdk.jdeps/share/classes</package-root> <package-root>${root}/src/jdk.jdeps/share/classes</package-root>
<package-root>${root}/build/bootstrap/jdk.jdeps/gensrc</package-root> <package-root>${root}/build/gensrc/jdk.jdeps</package-root>
<classpath mode="compile">${root}/build/java.compiler/classes:${root}/build/jdk.compiler/classes</classpath> <classpath mode="compile">${root}/build/java.compiler/classes:${root}/build/jdk.compiler/classes</classpath>
<built-to>${root}/build/jdk.jdeps/classes</built-to> <built-to>${root}/build/jdk.jdeps/classes</built-to>
<source-level>1.8</source-level> <source-level>1.8</source-level>
</compilation-unit> </compilation-unit>
<compilation-unit> <compilation-unit>
<package-root>${root}/src/jdk.javadoc/share/classes</package-root> <package-root>${root}/src/jdk.javadoc/share/classes</package-root>
<package-root>${root}/build/bootstrap/jdk.javadoc/gensrc</package-root> <package-root>${root}/build/gensrc/jdk.javadoc</package-root>
<classpath mode="compile">${root}/build/java.compiler/classes:${root}/build/jdk.compiler/classes</classpath> <classpath mode="compile">${root}/build/java.compiler/classes:${root}/build/jdk.compiler/classes</classpath>
<built-to>${root}/build/jdk.javadoc/classes</built-to> <built-to>${root}/build/jdk.javadoc/classes</built-to>
<source-level>1.8</source-level> <source-level>1.8</source-level>
</compilation-unit> </compilation-unit>
<compilation-unit> <compilation-unit>
<package-root>${root}/src/jdk.jshell/share/classes</package-root> <package-root>${root}/src/jdk.jshell/share/classes</package-root>
<package-root>${root}/build/bootstrap/jdk.jshell/gensrc</package-root> <package-root>${root}/build/gensrc/jdk.jshell</package-root>
<package-root>${root}/../jdk/src/jdk.internal.le/share/classes</package-root> <classpath mode="compile">${root}/build/java.compiler/classes:${root}/build/jdk.compiler/classes</classpath>
<package-root>${root}/../jdk/src/jdk.jdi/share/classes</package-root>
<classpath mode="compile">${root}/build/java.compiler/classes:${root}/build/jdk.compiler/classes:${root}/build/jdk.internal.le/classes:${root}/build/jdk.jdi/classes</classpath>
<built-to>${root}/build/jdk.jshell/classes</built-to> <built-to>${root}/build/jdk.jshell/classes</built-to>
<source-level>1.8</source-level> <source-level>1.8</source-level>
</compilation-unit> </compilation-unit>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -74,18 +74,7 @@ public class SelectToolTask extends Task {
enum ToolChoices { enum ToolChoices {
NONE(""), NONE(""),
BOOSTRAP_JAVAC("bootstrap-javac", true) { JAVAC("javac"),
@Override
public ToolChoices baseTool() {
return JAVAC;
}
},
JAVAC("javac") {
@Override
public ToolChoices asBootstrap() {
return BOOSTRAP_JAVAC;
}
},
JAVADOC("javadoc"), JAVADOC("javadoc"),
JAVAH("javah"), JAVAH("javah"),
JAVAP("javap"), JAVAP("javap"),
@ -103,14 +92,6 @@ public class SelectToolTask extends Task {
this.bootstrap = bootstrap; this.bootstrap = bootstrap;
} }
public ToolChoices asBootstrap() {
return this;
}
public ToolChoices baseTool() {
return this;
}
@Override @Override
public String toString() { public String toString() {
return toolName; return toolName;
@ -145,15 +126,6 @@ public class SelectToolTask extends Task {
this.argsProperty = argsProperty; this.argsProperty = argsProperty;
} }
/**
* Set the name of the property which will be used to bootstrap the
* selected tool, if any. The property will remain unset.
* @param bootstrapProperty
*/
public void setBootstrapProperty(String bootstrapProperty) {
this.bootstrapProperty = bootstrapProperty;
}
/** /**
* Specify whether or not to pop up a dialog if the user has not specified * Specify whether or not to pop up a dialog if the user has not specified
* a default value for a property. * a default value for a property.
@ -169,7 +141,6 @@ public class SelectToolTask extends Task {
Properties props = readProperties(propertyFile); Properties props = readProperties(propertyFile);
toolName = props.getProperty("tool.name"); toolName = props.getProperty("tool.name");
toolBootstrap = props.getProperty("tool.bootstrap") != null;
if (toolName != null) { if (toolName != null) {
toolArgs = props.getProperty(toolName + ".args", ""); toolArgs = props.getProperty(toolName + ".args", "");
} }
@ -183,8 +154,6 @@ public class SelectToolTask extends Task {
// finally, return required values, if any // finally, return required values, if any
if (toolProperty != null && !(toolName == null || toolName.equals(""))) { if (toolProperty != null && !(toolName == null || toolName.equals(""))) {
p.setProperty(toolProperty, toolName); p.setProperty(toolProperty, toolName);
if (toolBootstrap)
p.setProperty(bootstrapProperty, "true");
if (argsProperty != null && toolArgs != null) if (argsProperty != null && toolArgs != null)
p.setProperty(argsProperty, toolArgs); p.setProperty(argsProperty, toolArgs);
@ -198,20 +167,15 @@ public class SelectToolTask extends Task {
ToolChoices tool = (ToolChoices)toolChoice.getSelectedItem(); ToolChoices tool = (ToolChoices)toolChoice.getSelectedItem();
toolName = tool.baseTool().toolName; toolName = tool.toolName;
toolBootstrap = tool.bootstrap;
toolArgs = argsField.getText(); toolArgs = argsField.getText();
if (defaultCheck.isSelected()) { if (defaultCheck.isSelected()) {
if (toolName.equals("")) { if (toolName.equals("")) {
fileProps.remove("tool.name"); fileProps.remove("tool.name");
fileProps.remove("tool.bootstrap"); fileProps.remove("tool.bootstrap");
} else { } else {
fileProps.remove("tool.bootstrap");
fileProps.put("tool.name", toolName); fileProps.put("tool.name", toolName);
if (toolBootstrap) {
fileProps.put("tool.bootstrap", "true");
} else {
fileProps.remove("tool.bootstrap");
}
fileProps.put(toolName + ".args", toolArgs); fileProps.put(toolName + ".args", toolArgs);
} }
writeProperties(propertyFile, fileProps); writeProperties(propertyFile, fileProps);
@ -237,8 +201,6 @@ public class SelectToolTask extends Task {
toolChoice = new JComboBox<>(toolChoices.toArray()); toolChoice = new JComboBox<>(toolChoices.toArray());
ToolChoices tool = toolName != null ? ToolChoices.valueOf(toolName.toUpperCase()) : null; ToolChoices tool = toolName != null ? ToolChoices.valueOf(toolName.toUpperCase()) : null;
if (toolName != null) { if (toolName != null) {
if (toolBootstrap)
tool = tool.asBootstrap();
toolChoice.setSelectedItem(tool); toolChoice.setSelectedItem(tool);
} }
toolChoice.addItemListener(new ItemListener() { toolChoice.addItemListener(new ItemListener() {
@ -348,14 +310,13 @@ public class SelectToolTask extends Task {
String getDefaultArgsForTool(Properties props, ToolChoices tool) { String getDefaultArgsForTool(Properties props, ToolChoices tool) {
if (tool == null) if (tool == null)
return ""; return "";
String toolName = tool.baseTool().toolName; String toolName = tool.toolName;
return toolName.equals("") ? "" : props.getProperty(toolName + ".args", ""); return toolName.equals("") ? "" : props.getProperty(toolName + ".args", "");
} }
// Ant task parameters // Ant task parameters
private boolean askIfUnset; private boolean askIfUnset;
private String toolProperty; private String toolProperty;
private String bootstrapProperty;
private String argsProperty; private String argsProperty;
private File propertyFile; private File propertyFile;
@ -367,6 +328,5 @@ public class SelectToolTask extends Task {
// Result values for the client // Result values for the client
private String toolName; private String toolName;
private boolean toolBootstrap;
private String toolArgs; private String toolArgs;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,10 +23,13 @@
package crules; package crules;
import java.lang.reflect.Layer;
import java.lang.reflect.Module;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
@ -52,6 +55,11 @@ public class CodingRulesAnalyzerPlugin implements Plugin {
@DefinedBy(Api.COMPILER_TREE) @DefinedBy(Api.COMPILER_TREE)
public void init(JavacTask task, String... args) { public void init(JavacTask task, String... args) {
addExports("jdk.compiler",
"com.sun.tools.javac.api",
"com.sun.tools.javac.code",
"com.sun.tools.javac.tree",
"com.sun.tools.javac.util");
BasicJavacTask impl = (BasicJavacTask)task; BasicJavacTask impl = (BasicJavacTask)task;
Context context = impl.getContext(); Context context = impl.getContext();
log = Log.instance(context); log = Log.instance(context);
@ -63,6 +71,20 @@ public class CodingRulesAnalyzerPlugin implements Plugin {
)); ));
} }
private void addExports(String moduleName, String... packageNames) {
for (String packageName : packageNames) {
try {
Layer layer = Layer.boot();
Optional<Module> m = layer.findModule(moduleName);
if (!m.isPresent())
throw new Error("module not found: " + moduleName);
m.get().addExports(packageName, getClass().getModule());
} catch (Exception e) {
throw new Error("failed to add exports for " + moduleName + "/" + packageName);
}
}
}
public class PostAnalyzeTaskListener implements TaskListener { public class PostAnalyzeTaskListener implements TaskListener {
private final Map<Kind, List<AbstractCodingRulesAnalyzer>> analyzers = new HashMap<>(); private final Map<Kind, List<AbstractCodingRulesAnalyzer>> analyzers = new HashMap<>();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -77,6 +77,7 @@ public interface MessageType {
MODIFIER("modifier", "Modifier", "javax.lang.model.element"), MODIFIER("modifier", "Modifier", "javax.lang.model.element"),
FILE("file", "File", "java.io"), FILE("file", "File", "java.io"),
FILE_OBJECT("file object", "JavaFileObject", "javax.tools"), FILE_OBJECT("file object", "JavaFileObject", "javax.tools"),
PATH("path", "Path", "java.nio.file"),
NAME("name", "Name", "com.sun.tools.javac.util"), NAME("name", "Name", "com.sun.tools.javac.util"),
NUMBER("number", "int", null), NUMBER("number", "int", null),
OPTION_NAME("option name", "Option", "com.sun.tools.javac.main"), OPTION_NAME("option name", "Option", "com.sun.tools.javac.main"),

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -105,8 +105,8 @@ public interface Element extends javax.lang.model.AnnotatedConstruct {
* java.util.Set<E>} is {@code "Set"}. * java.util.Set<E>} is {@code "Set"}.
* *
* If this element represents an unnamed {@linkplain * If this element represents an unnamed {@linkplain
* PackageElement#getSimpleName package}, an empty name is * PackageElement#getSimpleName package} or unnamed {@linkplain
* returned. * ModuleElement#getSimpleName module}, an empty name is returned.
* *
* If it represents a {@linkplain ExecutableElement#getSimpleName * If it represents a {@linkplain ExecutableElement#getSimpleName
* constructor}, the name "{@code <init>}" is returned. If it * constructor}, the name "{@code <init>}" is returned. If it
@ -122,6 +122,7 @@ public interface Element extends javax.lang.model.AnnotatedConstruct {
* @see ExecutableElement#getSimpleName * @see ExecutableElement#getSimpleName
* @see TypeElement#getSimpleName * @see TypeElement#getSimpleName
* @see VariableElement#getSimpleName * @see VariableElement#getSimpleName
* @see ModuleElement#getSimpleName
*/ */
Name getSimpleName(); Name getSimpleName();
@ -137,7 +138,7 @@ public interface Element extends javax.lang.model.AnnotatedConstruct {
* top-level type}, its package is returned. * top-level type}, its package is returned.
* *
* <li> If this is a {@linkplain * <li> If this is a {@linkplain
* PackageElement#getEnclosingElement package}, {@code null} is * PackageElement#getEnclosingElement package}, its module is
* returned. * returned.
* *
* <li> If this is a {@linkplain * <li> If this is a {@linkplain
@ -150,6 +151,9 @@ public interface Element extends javax.lang.model.AnnotatedConstruct {
* parameter}, {@linkplain ExecutableElement the executable * parameter}, {@linkplain ExecutableElement the executable
* element} which declares the parameter is returned. * element} which declares the parameter is returned.
* *
* <li> If this is a {@linkplain ModuleElement#getEnclosingElement
* module}, {@code null} is returned.
*
* </ul> * </ul>
* *
* @return the enclosing element, or {@code null} if there is none * @return the enclosing element, or {@code null} if there is none
@ -169,6 +173,9 @@ public interface Element extends javax.lang.model.AnnotatedConstruct {
* encloses the top-level classes and interfaces within it, but is * encloses the top-level classes and interfaces within it, but is
* not considered to enclose subpackages. * not considered to enclose subpackages.
* *
* A {@linkplain ModuleElement#getEnclosedElements module}
* encloses packages within it.
*
* Other kinds of elements are not currently considered to enclose * Other kinds of elements are not currently considered to enclose
* any elements; however, that may change as this API or the * any elements; however, that may change as this API or the
* programming language evolves. * programming language evolves.
@ -177,8 +184,9 @@ public interface Element extends javax.lang.model.AnnotatedConstruct {
* methods in {@link ElementFilter}. * methods in {@link ElementFilter}.
* *
* @return the enclosed elements, or an empty list if none * @return the enclosed elements, or an empty list if none
* @see PackageElement#getEnclosedElements
* @see TypeElement#getEnclosedElements * @see TypeElement#getEnclosedElements
* @see PackageElement#getEnclosedElements
* @see ModuleElement#getEnclosedElements
* @see Elements#getAllMembers * @see Elements#getAllMembers
* @jls 8.8.9 Default Constructor * @jls 8.8.9 Default Constructor
* @jls 8.9 Enums * @jls 8.9 Enums

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -94,7 +94,13 @@ public enum ElementKind {
* A resource variable. * A resource variable.
* @since 1.7 * @since 1.7
*/ */
RESOURCE_VARIABLE; RESOURCE_VARIABLE,
/**
* A module.
* @since 9
*/
MODULE;
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -143,4 +143,13 @@ public interface ElementVisitor<R, P> {
* a visitor implementation may optionally throw this exception * a visitor implementation may optionally throw this exception
*/ */
R visitUnknown(Element e, P p); R visitUnknown(Element e, P p);
/**
* Visits a module element.
* @param e the element to visit
* @param p a visitor-specified parameter
* @return a visitor-specified result
* @since 9
*/
R visitModule(ModuleElement e, P p);
} }

View File

@ -0,0 +1,191 @@
/*
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.lang.model.element;
import java.util.List;
/**
* Represents a module program element. Provides access to information
* about the module and its members.
*
* @see javax.lang.model.util.Elements#getModuleOf
* @since 9
*/ // TODO: add @jls to module section
public interface ModuleElement extends Element, QualifiedNameable {
/**
* Returns the fully qualified name of this module.
*
* @return the qualified name of this module, or an
* empty name if this is an unnamed module
*/
@Override
Name getQualifiedName();
/**
* Returns the simple name of this module. For an unnamed
* module, an empty name is returned.
*
* @return the simple name of this module or an empty name if
* this is an unnamed module
*/
@Override
Name getSimpleName();
/**
* Returns the packages within this module.
* @return the packages within this module
*/
@Override
List<? extends Element> getEnclosedElements();
/**
* Returns {@code true} if this is an unnamed module and {@code
* false} otherwise.
*
* @return {@code true} if this is an unnamed module and {@code
* false} otherwise
*/ // TODO: add @jls to unnamed module section
boolean isUnnamed();
/**
* Returns {@code null} since a module is not enclosed by another
* element.
*
* @return {@code null}
*/
@Override
Element getEnclosingElement();
/**
* Returns the directives contained in the declaration of this module.
* @return the directives in the declaration of this module
*/
List<? extends Directive> getDirectives();
/**
* The {@code kind} of a directive.
*
* <p>Note that it is possible additional directive kinds will be added
* to accommodate new, currently unknown, language structures added to
* future versions of the Java&trade; programming language.
*
* @since 9
*/
enum DirectiveKind {
/** A "requires [public] module-name" directive. */
REQUIRES,
/** An "exports package-name [to module-name-list]" directive. */
EXPORTS,
/** A "uses service-name" directive. */
USES,
/** A "provides service-name with implementation-name" directive. */
PROVIDES
};
/**
* Represents a "module statement" within the declaration of this module.
*
* @since 9
*
*/ // TODO: add jls to Module Statement
interface Directive {
/**
* Returns the {@code kind} of this directive.
*
* @return the kind of this directive
*/
DirectiveKind getKind();
}
/**
* A dependency of a module.
* @since 9
*/
interface RequiresDirective extends Directive {
/**
* Returns whether or not this is a public dependency.
* @return whether or not this is a public dependency
*/
boolean isPublic();
/**
* Returns the module that is required
* @return the module that is required
*/
ModuleElement getDependency();
}
/**
* An exported package of a module.
* @since 9
*/
interface ExportsDirective extends Directive {
/**
* Returns the package being exported.
* @return the package being exported
*/
PackageElement getPackage();
/**
* Returns the specific modules to which the package is being exported,
* or null, if the package is exported to all modules which
* have readability to this module.
* @return the specific modules to which the package is being exported
*/
List<? extends ModuleElement> getTargetModules();
}
/**
* An implementation of a service provided by a module.
* @since 9
*/
interface ProvidesDirective extends Directive {
/**
* Returns the service being provided.
* @return the service being provided
*/
TypeElement getService();
/**
* Returns the implementation of the service being provided.
* @return the implementation of the service being provided
*/
TypeElement getImplementation();
}
/**
* A reference to a service used by a module.
* @since 9
*/
interface UsesDirective extends Directive {
/**
* Returns the service that is used.
* @return the service that is used
*/
TypeElement getService();
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -72,20 +72,19 @@ public interface PackageElement extends Element, QualifiedNameable {
List<? extends Element> getEnclosedElements(); List<? extends Element> getEnclosedElements();
/** /**
* Returns {@code true} is this is an unnamed package and {@code * Returns {@code true} if this is an unnamed package and {@code
* false} otherwise. * false} otherwise.
* *
* @return {@code true} is this is an unnamed package and {@code * @return {@code true} if this is an unnamed package and {@code
* false} otherwise * false} otherwise
* @jls 7.4.2 Unnamed Packages * @jls 7.4.2 Unnamed Packages
*/ */
boolean isUnnamed(); boolean isUnnamed();
/** /**
* Returns {@code null} since a package is not enclosed by another * Returns the enclosing module.
* element.
* *
* @return {@code null} * @return the enclosing module
*/ */
@Override @Override
Element getEnclosingElement(); Element getEnclosingElement();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -151,7 +151,14 @@ public enum TypeKind {
* *
* @since 1.8 * @since 1.8
*/ */
INTERSECTION; INTERSECTION,
/**
* A pseudo-type corresponding to a module element.
* @see NoType
* @since 9
*/
MODULE;
/** /**
* Returns {@code true} if this kind corresponds to a primitive * Returns {@code true} if this kind corresponds to a primitive

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -132,4 +132,19 @@ public abstract class AbstractElementVisitor6<R, P> implements ElementVisitor<R,
public R visitUnknown(Element e, P p) { public R visitUnknown(Element e, P p) {
throw new UnknownElementException(e, p); throw new UnknownElementException(e, p);
} }
/**
* Visits a {@code ModuleElement} by calling {@code
* visitUnknown}.
* @param e {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of {@code visitUnknown}
*
* @since 9
*/
@Override
public R visitModule(ModuleElement e, P p) {
return visitUnknown(e, p);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,7 @@ package javax.lang.model.util;
import javax.annotation.processing.SupportedSourceVersion; import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.ModuleElement;
import static javax.lang.model.SourceVersion.*; import static javax.lang.model.SourceVersion.*;
@ -71,4 +72,15 @@ public abstract class AbstractElementVisitor9<R, P> extends AbstractElementVisit
protected AbstractElementVisitor9(){ protected AbstractElementVisitor9(){
super(); super();
} }
/**
* Visits a {@code ModuleElement} in a manner defined by a
* subclass.
*
* @param t {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of the visit as defined by a subclass
*/
@Override
public abstract R visitModule(ModuleElement t, P p);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,12 @@ import java.util.ArrayList;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.lang.model.element.ModuleElement.Directive;
import javax.lang.model.element.ModuleElement.DirectiveKind;
import javax.lang.model.element.ModuleElement.ExportsDirective;
import javax.lang.model.element.ModuleElement.ProvidesDirective;
import javax.lang.model.element.ModuleElement.RequiresDirective;
import javax.lang.model.element.ModuleElement.UsesDirective;
/** /**
@ -78,6 +84,9 @@ public class ElementFilter {
private static final Set<ElementKind> PACKAGE_KIND = private static final Set<ElementKind> PACKAGE_KIND =
Collections.unmodifiableSet(EnumSet.of(ElementKind.PACKAGE)); Collections.unmodifiableSet(EnumSet.of(ElementKind.PACKAGE));
private static final Set<ElementKind> MODULE_KIND =
Collections.unmodifiableSet(EnumSet.of(ElementKind.MODULE));
private static final Set<ElementKind> TYPE_KINDS = private static final Set<ElementKind> TYPE_KINDS =
Collections.unmodifiableSet(EnumSet.of(ElementKind.CLASS, Collections.unmodifiableSet(EnumSet.of(ElementKind.CLASS,
ElementKind.ENUM, ElementKind.ENUM,
@ -183,6 +192,28 @@ public class ElementFilter {
return setFilter(elements, PACKAGE_KIND, PackageElement.class); return setFilter(elements, PACKAGE_KIND, PackageElement.class);
} }
/**
* Returns a list of modules in {@code elements}.
* @return a list of modules in {@code elements}
* @param elements the elements to filter
* @since 9
*/
public static List<ModuleElement>
modulesIn(Iterable<? extends Element> elements) {
return listFilter(elements, MODULE_KIND, ModuleElement.class);
}
/**
* Returns a set of modules in {@code elements}.
* @return a set of modules in {@code elements}
* @param elements the elements to filter
* @since 9
*/
public static Set<ModuleElement>
modulesIn(Set<? extends Element> elements) {
return setFilter(elements, MODULE_KIND, ModuleElement.class);
}
// Assumes targetKinds and E are sensible. // Assumes targetKinds and E are sensible.
private static <E extends Element> List<E> listFilter(Iterable<? extends Element> elements, private static <E extends Element> List<E> listFilter(Iterable<? extends Element> elements,
Set<ElementKind> targetKinds, Set<ElementKind> targetKinds,
@ -207,4 +238,62 @@ public class ElementFilter {
} }
return set; return set;
} }
/**
* Returns a list of export directives in {@code directives}.
* @return a list of export directives in {@code directives}
* @param directives the directives to filter
* @since 9
*/
public static List<ExportsDirective>
exportsIn(Iterable<? extends Directive> directives) {
return listFilter(directives, DirectiveKind.EXPORTS, ExportsDirective.class);
}
/**
* Returns a list of provides directives in {@code directives}.
* @return a list of provides directives in {@code directives}
* @param directives the directives to filter
* @since 9
*/
public static List<ProvidesDirective>
providesIn(Iterable<? extends Directive> directives) {
return listFilter(directives, DirectiveKind.PROVIDES, ProvidesDirective.class);
}
/**
* Returns a list of requires directives in {@code directives}.
* @return a list of requires directives in {@code directives}
* @param directives the directives to filter
* @since 9
*/
public static List<RequiresDirective>
requiresIn(Iterable<? extends Directive> directives) {
return listFilter(directives, DirectiveKind.REQUIRES, RequiresDirective.class);
}
/**
* Returns a list of uses directives in {@code directives}.
* @return a list of uses directives in {@code directives}
* @param directives the directives to filter
* @since 9
*/
public static List<UsesDirective>
usesIn(Iterable<? extends Directive> directives) {
return listFilter(directives, DirectiveKind.USES, UsesDirective.class);
}
// Assumes directiveKind and D are sensible.
private static <D extends Directive> List<D> listFilter(Iterable<? extends Directive> directives,
DirectiveKind directiveKind,
Class<D> clazz) {
List<D> list = new ArrayList<>();
for (Directive d : directives) {
if (d.getKind() == directiveKind)
list.add(clazz.cast(d));
}
return list;
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -95,4 +95,17 @@ public class ElementKindVisitor9<R, P> extends ElementKindVisitor8<R, P> {
protected ElementKindVisitor9(R defaultValue) { protected ElementKindVisitor9(R defaultValue) {
super(defaultValue); super(defaultValue);
} }
/**
* Visits a {@code ModuleElement} by calling {@code
* defaultAction}.
*
* @param e the element to visit
* @param p a visitor-specified parameter
* @return the result of {@code defaultAction}
*/
@Override
public R visitModule(ModuleElement e, P p) {
return defaultAction(e, p);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -108,4 +108,17 @@ public class ElementScanner9<R, P> extends ElementScanner8<R, P> {
protected ElementScanner9(R defaultValue){ protected ElementScanner9(R defaultValue){
super(defaultValue); super(defaultValue);
} }
/**
* Visits a {@code ModuleElement} by scanning the enclosed
* elements.
*
* @param e the element to visit
* @param p a visitor-specified parameter
* @return the result of the scan
*/
@Override
public R visitModule(ModuleElement e, P p) {
return scan(e.getEnclosedElements(), p); // TODO: Hmmm, this might not be right
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -30,7 +30,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.lang.model.type.*;
/** /**
@ -63,6 +62,15 @@ public interface Elements {
*/ */
TypeElement getTypeElement(CharSequence name); TypeElement getTypeElement(CharSequence name);
/**
* Returns a module element given its fully qualified name.
*
* @param name the name
* @return the named module element, or {@code null} if it cannot be found
* @since 9
*/
ModuleElement getModuleElement(CharSequence name);
/** /**
* Returns the values of an annotation's elements, including defaults. * Returns the values of an annotation's elements, including defaults.
* *
@ -128,6 +136,16 @@ public interface Elements {
*/ */
PackageElement getPackageOf(Element type); PackageElement getPackageOf(Element type);
/**
* Returns the module of an element. The module of a module is
* itself.
*
* @param type the element being examined
* @return the module of an element
* @since 9
*/
ModuleElement getModuleOf(Element type);
/** /**
* Returns all members of a type element, whether inherited or * Returns all members of a type element, whether inherited or
* declared directly. For a class the result also includes its * declared directly. For a class the result also includes its

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,7 @@ package javax.lang.model.util;
import javax.annotation.processing.SupportedSourceVersion; import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.ModuleElement;
import static javax.lang.model.SourceVersion.*; import static javax.lang.model.SourceVersion.*;
/** /**
@ -90,4 +91,17 @@ public class SimpleElementVisitor9<R, P> extends SimpleElementVisitor8<R, P> {
protected SimpleElementVisitor9(R defaultValue){ protected SimpleElementVisitor9(R defaultValue){
super(defaultValue); super(defaultValue);
} }
/**
* Visits a {@code ModuleElement} by calling {@code
* defaultAction}.
*
* @param e the element to visit
* @param p a visitor-specified parameter
* @return the result of {@code defaultAction}
*/
@Override
public R visitModule(ModuleElement e, P p) {
return defaultAction(e, p);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,6 +28,7 @@ package javax.tools;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.Objects; import java.util.Objects;
import java.util.ServiceLoader;
import java.util.Set; import java.util.Set;
import javax.tools.JavaFileObject.Kind; import javax.tools.JavaFileObject.Kind;
@ -163,4 +164,24 @@ public class ForwardingJavaFileManager<M extends JavaFileManager> implements Jav
public void close() throws IOException { public void close() throws IOException {
fileManager.close(); fileManager.close();
} }
public Location getModuleLocation(Location location, String moduleName) throws IOException {
return fileManager.getModuleLocation(location, moduleName);
}
public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
return fileManager.getModuleLocation(location, fo, pkgName);
}
public <S> ServiceLoader<S> getServiceLoader(Location location, Class<S> service) throws IOException {
return fileManager.getServiceLoader(location, service);
}
public String inferModuleName(Location location) throws IOException {
return fileManager.inferModuleName(location);
}
public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
return fileManager.listModuleLocations(location);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,7 +29,9 @@ import java.io.Closeable;
import java.io.Flushable; import java.io.Flushable;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.util.ServiceLoader;
import java.util.Set; import java.util.Set;
import static javax.tools.JavaFileObject.Kind; import static javax.tools.JavaFileObject.Kind;
/** /**
@ -124,6 +126,17 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
* @return true if this is an output location, false otherwise * @return true if this is an output location, false otherwise
*/ */
boolean isOutputLocation(); boolean isOutputLocation();
/**
* Indicates if this location is expected to contain modules,
* as compared to a location which contains packages and classes.
*
* @return true if this location is expected to contain modules
* @since 9
*/
default boolean isModuleLocation() {
return false;
}
} }
/** /**
@ -385,6 +398,7 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
* @throws IOException if an I/O error occurred * @throws IOException if an I/O error occurred
* @see #close * @see #close
*/ */
@Override
void flush() throws IOException; void flush() throws IOException;
/** /**
@ -398,5 +412,84 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
* @throws IOException if an I/O error occurred * @throws IOException if an I/O error occurred
* @see #flush * @see #flush
*/ */
@Override
void close() throws IOException; void close() throws IOException;
/**
* Gets a location for a named module within a module-oriented location.
*
* @param location the module-oriented location
* @param moduleName the name of the module to be found
* @return the location for the named module
*
* @throws IOException if an I/O error occurred
* @throws UnsupportedOperationException if this operation if not supported by this file manager
* @since 9
*/ // TODO: describe failure modes
default Location getModuleLocation(Location location, String moduleName) throws IOException {
throw new UnsupportedOperationException();
}
/**
* Gets a location for the module containing a specific file representing a Java
* source or class.
*
* @param location a module-oriented location
* @param fo the file
* @param pkgName the package name for the class(es) defined in this file
* @return the module containing the file
*
* @throws IOException if an I/O error occurred
* @throws UnsupportedOperationException if this operation if not supported by this file manager
* @since 9
*/ // TODO: describe failure modes
default Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
throw new UnsupportedOperationException();
}
/**
* Get a service loader for a specific service class from a given location.
*
* @param location the location
* @param service the {@code Class} object of the service class
* @param <S> the service class
* @return a service loader for the given service class
*
* @throws IOException if an I/O error occurred
* @throws UnsupportedOperationException if this operation if not supported by this file manager
* @since 9
*/ // TODO: describe failure modes
default <S> ServiceLoader<S> getServiceLoader(Location location, Class<S> service) throws IOException {
throw new UnsupportedOperationException();
}
/**
* Infer the name of the module from its location, as returned by
* getModuleLocation or listModuleLocations.
*
* @param location a location representing a module
* @return the name of the module
*
* @throws IOException if an I/O error occurred
* @throws UnsupportedOperationException if this operation if not supported by this file manager
* @since 9
*/ // TODO: describe failure modes
default String inferModuleName(Location location) throws IOException {
throw new UnsupportedOperationException();
}
/**
* Lists the modules in a module-oriented location.
*
* @param location the location for which to list the modules
* @return a series of sets of locations containing modules
*
* @throws IOException if an I/O error occurred
* @throws UnsupportedOperationException if this operation if not supported by this file manager
* @since 9
*/ // TODO: describe failure modes
default Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
throw new UnsupportedOperationException();
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,12 @@ public enum StandardLocation implements Location {
*/ */
ANNOTATION_PROCESSOR_PATH, ANNOTATION_PROCESSOR_PATH,
/**
* Location to search for modules containing annotation processors.
* @since 9
*/
ANNOTATION_PROCESSOR_MODULE_PATH,
/** /**
* Location to search for platform classes. Sometimes called * Location to search for platform classes. Sometimes called
* the boot class path. * the boot class path.
@ -72,7 +78,31 @@ public enum StandardLocation implements Location {
* Location of new native header files. * Location of new native header files.
* @since 1.8 * @since 1.8
*/ */
NATIVE_HEADER_OUTPUT; NATIVE_HEADER_OUTPUT,
/**
* Location to search for the source code of modules.
* @since 9
*/
MODULE_SOURCE_PATH,
/**
* Location to search for upgradeable system modules.
* @since 9
*/
UPGRADE_MODULE_PATH,
/**
* Location to search for system modules.
* @since 9
*/
SYSTEM_MODULES,
/**
* Location to search for precompiled user modules.
* @since 9
*/
MODULE_PATH;
/** /**
* Returns a location object with the given name. The following * Returns a location object with the given name. The following
@ -90,8 +120,11 @@ public enum StandardLocation implements Location {
for (Location location : values()) for (Location location : values())
locations.putIfAbsent(location.getName(), location); locations.putIfAbsent(location.getName(), location);
} }
locations.putIfAbsent(name.toString(/* null-check */), new Location() { name.getClass(); /* null-check */
locations.putIfAbsent(name, new Location() {
@Override
public String getName() { return name; } public String getName() { return name; }
@Override
public boolean isOutputLocation() { return name.endsWith("_OUTPUT"); } public boolean isOutputLocation() { return name.endsWith("_OUTPUT"); }
}); });
return locations.get(name); return locations.get(name);
@ -100,8 +133,10 @@ public enum StandardLocation implements Location {
private static final ConcurrentMap<String,Location> locations private static final ConcurrentMap<String,Location> locations
= new ConcurrentHashMap<>(); = new ConcurrentHashMap<>();
@Override
public String getName() { return name(); } public String getName() { return name(); }
@Override
public boolean isOutputLocation() { public boolean isOutputLocation() {
switch (this) { switch (this) {
case CLASS_OUTPUT: case CLASS_OUTPUT:
@ -112,4 +147,18 @@ public enum StandardLocation implements Location {
return false; return false;
} }
} }
@Override
public boolean isModuleLocation() {
switch (this) {
case MODULE_SOURCE_PATH:
case ANNOTATION_PROCESSOR_MODULE_PATH:
case UPGRADE_MODULE_PATH:
case SYSTEM_MODULES:
case MODULE_PATH:
return true;
default:
return false;
}
}
} }

View File

@ -25,10 +25,11 @@
package javax.tools; package javax.tools;
import java.lang.ref.Reference; import java.lang.reflect.InvocationTargetException;
import java.lang.ref.WeakReference; import java.lang.reflect.Method;
import java.util.HashMap; import java.util.Iterator;
import java.util.Map; import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
/** /**
* Provides methods for locating tool providers, for example, * Provides methods for locating tool providers, for example,
@ -40,8 +41,8 @@ import java.util.Map;
*/ */
public class ToolProvider { public class ToolProvider {
private static final String systemJavaCompilerName private static final String systemJavaCompilerModule = "jdk.compiler";
= "com.sun.tools.javac.api.JavacTool"; private static final String systemJavaCompilerName = "com.sun.tools.javac.api.JavacTool";
/** /**
* Returns the Java&trade; programming language compiler provided * Returns the Java&trade; programming language compiler provided
@ -52,13 +53,17 @@ public class ToolProvider {
* {@linkplain java.nio.file.FileSystem filesystem}.</p> * {@linkplain java.nio.file.FileSystem filesystem}.</p>
* @return the compiler provided with this platform or * @return the compiler provided with this platform or
* {@code null} if no compiler is provided * {@code null} if no compiler is provided
* @implNote This implementation returns the compiler provided
* by the {@code jdk.compiler} module if that module is available,
* and null otherwise.
*/ */
public static JavaCompiler getSystemJavaCompiler() { public static JavaCompiler getSystemJavaCompiler() {
return instance().getSystemTool(JavaCompiler.class, systemJavaCompilerName); return getSystemTool(JavaCompiler.class,
systemJavaCompilerModule, systemJavaCompilerName);
} }
private static final String systemDocumentationToolName private static final String systemDocumentationToolModule = "jdk.javadoc";
= "jdk.javadoc.internal.api.JavadocTool"; private static final String systemDocumentationToolName = "jdk.javadoc.internal.api.JavadocTool";
/** /**
* Returns the Java&trade; programming language documentation tool provided * Returns the Java&trade; programming language documentation tool provided
@ -69,9 +74,13 @@ public class ToolProvider {
* {@linkplain java.nio.file.FileSystem filesystem}.</p> * {@linkplain java.nio.file.FileSystem filesystem}.</p>
* @return the documentation tool provided with this platform or * @return the documentation tool provided with this platform or
* {@code null} if no documentation tool is provided * {@code null} if no documentation tool is provided
* @implNote This implementation returns the tool provided
* by the {@code jdk.javadoc} module if that module is available,
* and null otherwise.
*/ */
public static DocumentationTool getSystemDocumentationTool() { public static DocumentationTool getSystemDocumentationTool() {
return instance().getSystemTool(DocumentationTool.class, systemDocumentationToolName); return getSystemTool(DocumentationTool.class,
systemDocumentationToolModule, systemDocumentationToolName);
} }
/** /**
@ -87,41 +96,70 @@ public class ToolProvider {
return ClassLoader.getSystemClassLoader(); return ClassLoader.getSystemClassLoader();
} }
private static final boolean useLegacy;
private static ToolProvider instance; static {
Class<?> c = null;
private static synchronized ToolProvider instance() {
if (instance == null)
instance = new ToolProvider();
return instance;
}
// Cache for tool classes.
// Use weak references to avoid keeping classes around unnecessarily
private final Map<String, Reference<Class<?>>> toolClasses = new HashMap<>();
private ToolProvider() { }
private <T> T getSystemTool(Class<T> clazz, String name) {
Class<? extends T> c = getSystemToolClass(clazz, name);
try { try {
return c.asSubclass(clazz).newInstance(); c = Class.forName("java.lang.reflect.Module");
} catch (InstantiationException | IllegalAccessException | RuntimeException | Error e) { } catch (Throwable t) {
throw new Error(e);
} }
useLegacy = (c == null);
} }
private <T> Class<? extends T> getSystemToolClass(Class<T> clazz, String name) { /**
Reference<Class<?>> refClass = toolClasses.get(name); * Get an instance of a system tool using the service loader.
Class<?> c = (refClass == null ? null : refClass.get()); * @implNote By default, this returns the implementation in the specified module.
if (c == null) { * For limited backward compatibility, if this code is run on an older version
* of the Java platform that does not support modules, this method will
* try and create an instance of the named class. Note that implies the
* class must be available on the system class path.
* @param <T> the interface of the tool
* @param clazz the interface of the tool
* @param moduleName the name of the module containing the desired implementation
* @param className the class name of the desired implementation
* @return the specified implementation of the tool
*/
private static <T> T getSystemTool(Class<T> clazz, String moduleName, String className) {
if (useLegacy) {
try { try {
c = Class.forName(name, false, ClassLoader.getSystemClassLoader()); return Class.forName(className, true, ClassLoader.getSystemClassLoader()).asSubclass(clazz).newInstance();
} catch (ClassNotFoundException | RuntimeException | Error e) { } catch (ReflectiveOperationException e) {
throw new Error(e); throw new Error(e);
} }
toolClasses.put(name, new WeakReference<>(c));
} }
return c.asSubclass(clazz);
try {
ServiceLoader<T> sl = ServiceLoader.load(clazz, ClassLoader.getSystemClassLoader());
for (Iterator<T> iter = sl.iterator(); iter.hasNext(); ) {
T tool = iter.next();
if (matches(tool, moduleName))
return tool;
}
} catch (ServiceConfigurationError e) {
throw new Error(e);
}
return null;
}
/**
* Determine if this is tho desired tool instance.
* @param <T> the interface of the tool
* @param tool the instance of the tool
* @param moduleName the name of the module containing the desired implementation
* @return true if and only if the tool matches the specified criteria
*/
private static <T> boolean matches(T tool, String moduleName) {
// for now, use reflection to implement
// return moduleName.equals(tool.getClass().getModule().getName());
try {
Method getModuleMethod = Class.class.getDeclaredMethod("getModule");
Object toolModule = getModuleMethod.invoke(tool.getClass());
Method getNameMethod = toolModule.getClass().getDeclaredMethod("getName");
String toolModuleName = (String) getNameMethod.invoke(toolModule);
return moduleName.equals(toolModuleName);
} catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
return false;
}
} }
} }

View File

@ -1,10 +1,12 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. * 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 * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -21,31 +23,15 @@
* questions. * questions.
*/ */
package pkg2; module java.compiler {
exports javax.annotation.processing;
exports javax.lang.model;
exports javax.lang.model.element;
exports javax.lang.model.type;
exports javax.lang.model.util;
exports javax.tools;
/** uses javax.tools.DocumentationTool;
* @deprecated Class1Pkg2. This class is deprecated uses javax.tools.JavaCompiler;
*
* @author Bhavesh Patel
*/
public class Class1Pkg2 {
/**
* A sample enum.
*/
public static enum ModalExclusionType {
/**
* Test comment.
*/
NO_EXCLUDE,
/**
* Another comment.
*/
APPLICATION_EXCLUDE
};
/**
* A string constant.
*/
public static final String CONSTANT1 = "C2";
} }

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2011, 2014, 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.tree;
/**
* A super-type for all the directives in a ModuleTree.
*/
public interface DirectiveTree extends Tree { }

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.source.tree;
import java.util.List;
/**
* A tree node for an 'exports' directive in a module declaration.
*
* For example:
* <pre>
* exports <em>package-name</em>;
* exports <em>package-name</em> to <em>module-name</em>;
* </pre>
*
* @since 9
*/
public interface ExportsTree extends DirectiveTree {
/**
* Returns the name of the package to be exported.
* @return the name of the package to be exported
*/
ExpressionTree getExportName();
/**
* Returns the names of the modules to which the package is exported,
* or null, if the package is exported to all modules.
*
* @return the names of the modules to which the package is exported, or null
*/
List<? extends ExpressionTree> getModuleNames();
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.source.tree;
import java.util.List;
/**
* A tree node for a module declaration.
*
* For example:
* <pre>
* module <em>module-name</em> {
* <em>directives</em>
* }
* </pre>
*
* @since 9
*/
public interface ModuleTree extends Tree {
/**
* Returns the name of the module.
* @return the name of the module
*/
ExpressionTree getName();
/**
* Returns the directives in the module declaration.
* @return the directives in the module declaration
*/
List<? extends DirectiveTree> getDirectives();
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.source.tree;
/**
* A tree node for a 'provides' directive in a module declaration.
*
* For example:
* <pre>
* provides <em>service-name</em> with <em>implementation-name</em>;
* </pre>
* @since 9
*/
public interface ProvidesTree extends DirectiveTree {
/**
* Returns the name of the service type being provided.
* @return the name of the service type being provided
*/
ExpressionTree getServiceName();
/**
* Returns the name of the implementation type being provided.
* @return the name of the implementation type being provided
*/
ExpressionTree getImplementationName();
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.source.tree;
/**
* A tree node for a 'requires' directive in a module declaration.
*
* For example:
* <pre>
* requires <em>module-name</em>;
* requires public <em>module-name</em>;
* </pre>
*
* @since 9
*/
public interface RequiresTree extends DirectiveTree {
/**
* Returns true if this is a "requires public" directive.
* @return true if this is a "requires public" directive
*/
boolean isPublic();
/**
* Returns the name of the module that is required.
* @return the name of the module that is required
*/
ExpressionTree getModuleName();
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -603,6 +603,35 @@ public interface Tree {
*/ */
ANNOTATION_TYPE(ClassTree.class), ANNOTATION_TYPE(ClassTree.class),
/**
* Used for instances of {@link ModuleTree} representing module declarations.
*/
MODULE(ModuleTree.class),
/**
* Used for instances of {@link ExportsTree} representing
* export directives in a module declaration.
*/
EXPORTS(ExportsTree.class),
/**
* Used for instances of {@link ProvidesTree} representing
* export directives in a module declaration.
*/
PROVIDES(ProvidesTree.class),
/**
* Used for instances of {@link RequiresTree} representing
* export directives in a module declaration.
*/
REQUIRES(RequiresTree.class),
/**
* Used for instances of {@link UsesTree} representing
* export directives in a module declaration.
*/
USES(UsesTree.class),
/** /**
* An implementation-reserved node. This is the not the node * An implementation-reserved node. This is the not the node
* you are looking for. * you are looking for.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -481,6 +481,46 @@ public interface TreeVisitor<R,P> {
*/ */
R visitWildcard(WildcardTree node, P p); R visitWildcard(WildcardTree node, P p);
/**
* Visits a ModuleTree node.
* @param node the node being visited
* @param p a parameter value
* @return a result value
*/
R visitModule(ModuleTree node, P p);
/**
* Visits an ExportsTree node.
* @param node the node being visited
* @param p a parameter value
* @return a result value
*/
R visitExports(ExportsTree node, P p);
/**
* Visits a ProvidesTree node.
* @param node the node being visited
* @param p a parameter value
* @return a result value
*/
R visitProvides(ProvidesTree node, P p);
/**
* Visits a RequiresTree node.
* @param node the node being visited
* @param p a parameter value
* @return a result value
*/
R visitRequires(RequiresTree node, P p);
/**
* Visits a UsesTree node.
* @param node the node being visited
* @param p a parameter value
* @return a result value
*/
R visitUses(UsesTree node, P p);
/** /**
* Visits an unknown type of Tree node. * Visits an unknown type of Tree node.
* This can occur if the language evolves and new kinds * This can occur if the language evolves and new kinds

View File

@ -1,10 +1,13 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. * 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 * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -21,28 +24,22 @@
* questions. * questions.
*/ */
package pkg1; package com.sun.source.tree;
/** /**
* A sample interface. * A tree node for a 'uses' directive in a module declaration.
* *
* @author Bhavesh Patel * For example:
* <pre>
* uses <em>service-name</em>;
* </pre>
*
* @since 9
*/ */
public interface Interface1Pkg1 { public interface UsesTree extends DirectiveTree {
/** /**
* A test method. * Returns the name of the service type.
* * @return the name of the service type
* @param a blah.
* @param b blah.
*/ */
void method1(int a, int b); ExpressionTree getServiceName();
/**
* Another test method.
*
* @param c blah.
*/
void method2(int c);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -719,14 +719,30 @@ public class SimpleTreeVisitor <R,P> implements TreeVisitor<R,P> {
return defaultAction(node, p); return defaultAction(node, p);
} }
/** public R visitModule(ModuleTree node, P p) {
* {@inheritDoc} This implementation calls {@code defaultAction}. return defaultAction(node, p);
* }
* @param node {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of {@code defaultAction}
*/
@Override @Override
public R visitExports(ExportsTree node, P p) {
return defaultAction(node, p);
}
@Override
public R visitProvides(ProvidesTree node, P p) {
return defaultAction(node, p);
}
@Override
public R visitRequires(RequiresTree node, P p) {
return defaultAction(node, p);
}
@Override
public R visitUses(UsesTree node, P p) {
return defaultAction(node, p);
}
public R visitErroneous(ErroneousTree node, P p) { public R visitErroneous(ErroneousTree node, P p) {
return defaultAction(node, p); return defaultAction(node, p);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -846,6 +846,32 @@ public class TreeScanner<R,P> implements TreeVisitor<R,P> {
return r; return r;
} }
public R visitModule(ModuleTree node, P p) {
R r = scan(node.getName(), p);
r = scanAndReduce(node.getDirectives(), p, r);
return r;
}
public R visitExports(ExportsTree node, P p) {
R r = scan(node.getExportName(), p);
r = scanAndReduce(node.getModuleNames(), p, r);
return r;
}
public R visitProvides(ProvidesTree node, P p) {
R r = scan(node.getServiceName(), p);
r = scanAndReduce(node.getImplementationName(), p, r);
return r;
}
public R visitRequires(RequiresTree node, P p) {
return scan(node.getModuleName(), p);
}
public R visitUses(UsesTree node, P p) {
return scan(node.getServiceName(), p);
}
/** /**
* {@inheritDoc} This implementation returns {@code null}. * {@inheritDoc} This implementation returns {@code null}.
* *

View File

@ -195,6 +195,9 @@ public class DocLint implements Plugin {
} else { } else {
throw new BadArgs("dc.bad.value.for.option", arg, args[i]); throw new BadArgs("dc.bad.value.for.option", arg, args[i]);
} }
} else if ((arg.equals("-target") || arg.equals("-source")) && i + 1 < args.length) {
javacOpts.add(arg);
javacOpts.add(args[++i]);
} else if (arg.equals(STATS)) { } else if (arg.equals(STATS)) {
env.messages.setStatsEnabled(true); env.messages.setStatsEnabled(true);
} else if (arg.equals("-bootclasspath") && i + 1 < args.length) { } else if (arg.equals("-bootclasspath") && i + 1 < args.length) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,6 +28,7 @@ package com.sun.tools.javac.api;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Locale; import java.util.Locale;
import java.util.ServiceLoader;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -57,7 +58,6 @@ import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.PropagatedException; import com.sun.tools.javac.util.PropagatedException;
import com.sun.tools.javac.util.ServiceLoader;
/** /**
* Provides basic functionality for implementations of JavacTask. * Provides basic functionality for implementations of JavacTask.
@ -195,8 +195,7 @@ public class BasicJavacTask extends JavacTask {
Set<List<String>> pluginsToCall = new LinkedHashSet<>(pluginOpts); Set<List<String>> pluginsToCall = new LinkedHashSet<>(pluginOpts);
JavacProcessingEnvironment pEnv = JavacProcessingEnvironment.instance(context); JavacProcessingEnvironment pEnv = JavacProcessingEnvironment.instance(context);
ClassLoader cl = pEnv.getProcessorClassLoader(); ServiceLoader<Plugin> sl = pEnv.getServiceLoader(Plugin.class);
ServiceLoader<Plugin> sl = ServiceLoader.load(Plugin.class, cl);
for (Plugin plugin : sl) { for (Plugin plugin : sl) {
for (List<String> p : pluginsToCall) { for (List<String> p : pluginsToCall) {
if (plugin.getName().equals(p.head)) { if (plugin.getName().equals(p.head)) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,6 +36,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.net.URI; import java.net.URI;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -346,6 +347,50 @@ public class ClientCodeWrapper {
} }
} }
@Override @DefinedBy(Api.COMPILER)
public Location getModuleLocation(Location location, String moduleName) throws IOException {
try {
return clientJavaFileManager.getModuleLocation(location, moduleName);
} catch (ClientCodeException e) {
throw e;
} catch (RuntimeException | Error e) {
throw new ClientCodeException(e);
}
}
@Override @DefinedBy(Api.COMPILER)
public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
try {
return clientJavaFileManager.getModuleLocation(location, fo, pkgName);
} catch (ClientCodeException e) {
throw e;
} catch (RuntimeException | Error e) {
throw new ClientCodeException(e);
}
}
@Override @DefinedBy(Api.COMPILER)
public String inferModuleName(Location location) throws IOException {
try {
return clientJavaFileManager.inferModuleName(location);
} catch (ClientCodeException e) {
throw e;
} catch (RuntimeException | Error e) {
throw new ClientCodeException(e);
}
}
@Override @DefinedBy(Api.COMPILER)
public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
try {
return clientJavaFileManager.listModuleLocations(location);
} catch (ClientCodeException e) {
throw e;
} catch (RuntimeException | Error e) {
throw new ClientCodeException(e);
}
}
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public int isSupportedOption(String option) { public int isSupportedOption(String option) {
try { try {
@ -380,6 +425,17 @@ public class ClientCodeWrapper {
} }
} }
@Override @DefinedBy(Api.COMPILER)
public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(Iterable<? extends Path> paths) {
try {
return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjectsFromPaths(paths);
} catch (ClientCodeException e) {
throw e;
} catch (RuntimeException | Error e) {
throw new ClientCodeException(e);
}
}
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) { public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
try { try {
@ -391,6 +447,17 @@ public class ClientCodeWrapper {
} }
} }
@Override @DefinedBy(Api.COMPILER)
public Iterable<? extends JavaFileObject> getJavaFileObjects(Path... paths) {
try {
return ((StandardJavaFileManager)clientJavaFileManager).getJavaFileObjects(paths);
} catch (ClientCodeException e) {
throw e;
} catch (RuntimeException | Error e) {
throw new ClientCodeException(e);
}
}
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) { public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
try { try {
@ -414,9 +481,20 @@ public class ClientCodeWrapper {
} }
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public void setLocation(Location location, Iterable<? extends File> path) throws IOException { public void setLocation(Location location, Iterable<? extends File> files) throws IOException {
try { try {
((StandardJavaFileManager)clientJavaFileManager).setLocation(location, path); ((StandardJavaFileManager)clientJavaFileManager).setLocation(location, files);
} catch (ClientCodeException e) {
throw e;
} catch (RuntimeException | Error e) {
throw new ClientCodeException(e);
}
}
@Override @DefinedBy(Api.COMPILER)
public void setLocationFromPaths(Location location, Iterable<? extends Path> paths) throws IOException {
try {
((StandardJavaFileManager)clientJavaFileManager).setLocationFromPaths(location, paths);
} catch (ClientCodeException e) { } catch (ClientCodeException e) {
throw e; throw e;
} catch (RuntimeException | Error e) { } catch (RuntimeException | Error e) {
@ -434,6 +512,28 @@ public class ClientCodeWrapper {
throw new ClientCodeException(e); throw new ClientCodeException(e);
} }
} }
@Override @DefinedBy(Api.COMPILER)
public Iterable<? extends Path> getLocationAsPaths(Location location) {
try {
return ((StandardJavaFileManager)clientJavaFileManager).getLocationAsPaths(location);
} catch (ClientCodeException e) {
throw e;
} catch (RuntimeException | Error e) {
throw new ClientCodeException(e);
}
}
@Override @DefinedBy(Api.COMPILER)
public Path asPath(FileObject file) {
try {
return ((StandardJavaFileManager)clientJavaFileManager).asPath(file);
} catch (ClientCodeException e) {
throw e;
} catch (RuntimeException | Error e) {
throw new ClientCodeException(e);
}
}
} }
protected class WrappedFileObject implements FileObject { protected class WrappedFileObject implements FileObject {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,12 +33,17 @@ import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.processing.Processor; import javax.annotation.processing.Processor;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;
import javax.tools.*; import javax.tools.*;
import javax.tools.JavaFileObject.Kind;
import com.sun.source.tree.*; import com.sun.source.tree.*;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.comp.*; import com.sun.tools.javac.comp.*;
import com.sun.tools.javac.file.BaseFileManager; import com.sun.tools.javac.file.BaseFileManager;
import com.sun.tools.javac.main.*; import com.sun.tools.javac.main.*;
@ -49,6 +54,8 @@ import com.sun.tools.javac.processing.AnnotationProcessingError;
import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
import com.sun.tools.javac.tree.JCTree.Tag;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
@ -253,7 +260,7 @@ public class JavacTaskImpl extends BasicJavacTask {
* @return a list of elements corresponding to the top level * @return a list of elements corresponding to the top level
* classes in the abstract syntax trees * classes in the abstract syntax trees
*/ */
public Iterable<? extends TypeElement> enter() { public Iterable<? extends Element> enter() {
return enter(null); return enter(null);
} }
@ -264,11 +271,13 @@ public class JavacTaskImpl extends BasicJavacTask {
* @return a list of elements corresponding to the top level * @return a list of elements corresponding to the top level
* classes in the abstract syntax trees * classes in the abstract syntax trees
*/ */
public Iterable<? extends TypeElement> enter(Iterable<? extends CompilationUnitTree> trees) public Iterable<? extends Element> enter(Iterable<? extends CompilationUnitTree> trees)
{ {
if (trees == null && notYetEntered != null && notYetEntered.isEmpty()) if (trees == null && notYetEntered != null && notYetEntered.isEmpty())
return List.nil(); return List.nil();
boolean wasInitialized = compiler != null;
prepareCompiler(true); prepareCompiler(true);
ListBuffer<JCCompilationUnit> roots = null; ListBuffer<JCCompilationUnit> roots = null;
@ -305,22 +314,38 @@ public class JavacTaskImpl extends BasicJavacTask {
} }
} }
if (roots == null) if (roots == null) {
if (trees == null && !wasInitialized) {
compiler.initModules(List.nil());
}
return List.nil(); return List.nil();
}
List<JCCompilationUnit> units = compiler.initModules(roots.toList());
try { try {
List<JCCompilationUnit> units = compiler.enterTrees(roots.toList()); units = compiler.enterTrees(units);
if (notYetEntered.isEmpty()) if (notYetEntered.isEmpty())
compiler.processAnnotations(units); compiler.processAnnotations(units);
ListBuffer<TypeElement> elements = new ListBuffer<>(); ListBuffer<Element> elements = new ListBuffer<>();
for (JCCompilationUnit unit : units) { for (JCCompilationUnit unit : units) {
for (JCTree node : unit.defs) { boolean isPkgInfo = unit.sourcefile.isNameCompatible("package-info",
if (node.hasTag(JCTree.Tag.CLASSDEF)) { JavaFileObject.Kind.SOURCE);
JCClassDecl cdef = (JCClassDecl) node; if (isPkgInfo) {
if (cdef.sym != null) // maybe null if errors in anno processing elements.append(unit.packge);
elements.append(cdef.sym); } else {
for (JCTree node : unit.defs) {
if (node.hasTag(JCTree.Tag.CLASSDEF)) {
JCClassDecl cdef = (JCClassDecl) node;
if (cdef.sym != null) // maybe null if errors in anno processing
elements.append(cdef.sym);
} else if (node.hasTag(JCTree.Tag.MODULEDEF)) {
JCModuleDecl mdef = (JCModuleDecl) node;
if (mdef.sym != null)
elements.append(mdef.sym);
}
} }
} }
} }
@ -353,7 +378,7 @@ public class JavacTaskImpl extends BasicJavacTask {
// This implementation requires that we open up privileges on JavaCompiler. // This implementation requires that we open up privileges on JavaCompiler.
// An alternative implementation would be to move this code to JavaCompiler and // An alternative implementation would be to move this code to JavaCompiler and
// wrap it here // wrap it here
public Iterable<? extends Element> analyze(Iterable<? extends TypeElement> classes) { public Iterable<? extends Element> analyze(Iterable<? extends Element> classes) {
enter(null); // ensure all classes have been entered enter(null); // ensure all classes have been entered
final ListBuffer<Element> results = new ListBuffer<>(); final ListBuffer<Element> results = new ListBuffer<>();
@ -383,8 +408,13 @@ public class JavacTaskImpl extends BasicJavacTask {
if (cdef.sym != null) if (cdef.sym != null)
elems.append(cdef.sym); elems.append(cdef.sym);
break; break;
case TOPLEVEL: case MODULEDEF:
JCCompilationUnit unit = (JCCompilationUnit) env.tree; JCModuleDecl mod = (JCModuleDecl) env.tree;
if (mod.sym != null)
elems.append(mod.sym);
break;
case PACKAGEDEF:
JCCompilationUnit unit = env.toplevel;
if (unit.packge != null) if (unit.packge != null)
elems.append(unit.packge); elems.append(unit.packge);
break; break;
@ -413,7 +443,7 @@ public class JavacTaskImpl extends BasicJavacTask {
* @param classes a list of class elements * @param classes a list of class elements
* @return the files that were generated * @return the files that were generated
*/ */
public Iterable<? extends JavaFileObject> generate(Iterable<? extends TypeElement> classes) { public Iterable<? extends JavaFileObject> generate(Iterable<? extends Element> classes) {
final ListBuffer<JavaFileObject> results = new ListBuffer<>(); final ListBuffer<JavaFileObject> results = new ListBuffer<>();
try { try {
analyze(null); // ensure all classes have been parsed, entered, and analyzed analyze(null); // ensure all classes have been parsed, entered, and analyzed
@ -447,17 +477,33 @@ public class JavacTaskImpl extends BasicJavacTask {
return TreeInfo.pathFor((JCTree) node, (JCTree.JCCompilationUnit) unit).reverse(); return TreeInfo.pathFor((JCTree) node, (JCTree.JCCompilationUnit) unit).reverse();
} }
public void ensureEntered() {
args.allowEmpty();
enter(null);
}
abstract class Filter { abstract class Filter {
void run(Queue<Env<AttrContext>> list, Iterable<? extends TypeElement> classes) { void run(Queue<Env<AttrContext>> list, Iterable<? extends Element> elements) {
Set<TypeElement> set = new HashSet<>(); Set<Element> set = new HashSet<>();
for (TypeElement item: classes) for (Element item: elements) {
set.add(item); set.add(item);
}
ListBuffer<Env<AttrContext>> defer = new ListBuffer<>(); ListBuffer<Env<AttrContext>> defer = new ListBuffer<>();
while (list.peek() != null) { while (list.peek() != null) {
Env<AttrContext> env = list.remove(); Env<AttrContext> env = list.remove();
ClassSymbol csym = env.enclClass.sym; Symbol test = null;
if (csym != null && set.contains(csym.outermostClass()))
if (env.tree.hasTag(Tag.MODULEDEF)) {
test = ((JCModuleDecl) env.tree).sym;
} else if (env.tree.hasTag(Tag.PACKAGEDEF)) {
test = env.toplevel.packge;
} else {
ClassSymbol csym = env.enclClass.sym;
if (csym != null)
test = csym.outermostClass();
}
if (test != null && set.contains(test))
process(env); process(env);
else else
defer = defer.append(env); defer = defer.append(env);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -129,9 +129,17 @@ public final class JavacTool implements JavaCompiler {
} }
if (classes != null) { if (classes != null) {
for (String cls : classes) for (String cls : classes) {
if (!SourceVersion.isName(cls)) // implicit null check int sep = cls.indexOf('/'); // implicit null check
if (sep > 0) {
String mod = cls.substring(0, sep);
if (!SourceVersion.isName(mod))
throw new IllegalArgumentException("Not a valid module name: " + mod);
cls = cls.substring(sep + 1);
}
if (!SourceVersion.isName(cls))
throw new IllegalArgumentException("Not a valid class name: " + cls); throw new IllegalArgumentException("Not a valid class name: " + cls);
}
} }
if (compilationUnits != null) { if (compilationUnits != null) {

View File

@ -76,6 +76,7 @@ import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol; import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symbol.TypeSymbol; import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol;
@ -92,6 +93,7 @@ import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.comp.MemberEnter; import com.sun.tools.javac.comp.MemberEnter;
import com.sun.tools.javac.comp.Modules;
import com.sun.tools.javac.comp.Resolve; import com.sun.tools.javac.comp.Resolve;
import com.sun.tools.javac.file.BaseFileManager; import com.sun.tools.javac.file.BaseFileManager;
import com.sun.tools.javac.model.JavacElements; import com.sun.tools.javac.model.JavacElements;
@ -156,6 +158,7 @@ import static com.sun.tools.javac.code.TypeTag.*;
public class JavacTrees extends DocTrees { public class JavacTrees extends DocTrees {
// in a world of a single context per compilation, these would all be final // in a world of a single context per compilation, these would all be final
private Modules modules;
private Resolve resolve; private Resolve resolve;
private Enter enter; private Enter enter;
private Log log; private Log log;
@ -206,6 +209,7 @@ public class JavacTrees extends DocTrees {
} }
private void init(Context context) { private void init(Context context) {
modules = Modules.instance(context);
attr = Attr.instance(context); attr = Attr.instance(context);
enter = Enter.instance(context); enter = Enter.instance(context);
elements = JavacElements.instance(context); elements = JavacElements.instance(context);
@ -434,21 +438,31 @@ public class JavacTrees extends DocTrees {
// and if not, then we check to see if it identifies a package. // and if not, then we check to see if it identifies a package.
Type t = attr.attribType(ref.qualifierExpression, env); Type t = attr.attribType(ref.qualifierExpression, env);
if (t.isErroneous()) { if (t.isErroneous()) {
if (ref.memberName == null) { JCCompilationUnit toplevel =
// Attr/Resolve assume packages exist and create symbols as needed treeMaker.TopLevel(List.<JCTree>nil());
// so use getPackageElement to restrict search to existing packages final ModuleSymbol msym = modules.getDefaultModule();
PackageSymbol pck = elements.getPackageElement(ref.qualifierExpression.toString()); toplevel.modle = msym;
if (pck != null) { toplevel.packge = msym.unnamedPackage;
return pck; Symbol sym = attr.attribIdent(ref.qualifierExpression, toplevel);
} else if (ref.qualifierExpression.hasTag(JCTree.Tag.IDENT)) {
sym.complete();
if ((sym.kind == PCK || sym.kind == TYP) && sym.exists()) {
tsym = (TypeSymbol) sym;
memberName = (Name) ref.memberName;
if (sym.kind == PCK && memberName != null) {
//cannot refer to a package "member"
return null;
}
} else {
if (ref.qualifierExpression.hasTag(JCTree.Tag.IDENT)) {
// fixup: allow "identifier" instead of "#identifier" // fixup: allow "identifier" instead of "#identifier"
// for compatibility with javadoc // for compatibility with javadoc
tsym = env.enclClass.sym; tsym = env.enclClass.sym;
memberName = ((JCIdent) ref.qualifierExpression).name; memberName = ((JCIdent) ref.qualifierExpression).name;
} else } else {
return null; return null;
} else { }
return null;
} }
} else { } else {
tsym = t.tsym; tsym = t.tsym;
@ -1179,7 +1193,8 @@ public class JavacTrees extends DocTrees {
} }
}; };
PackageSymbol psym = javaFileObjectToPackageMap.getOrDefault(jfo, syms.unnamedPackage); PackageSymbol psym = javaFileObjectToPackageMap.getOrDefault(jfo,
syms.unnamedModule.unnamedPackage);
jcCompilationUnit.docComments = new DocCommentTable() { jcCompilationUnit.docComments = new DocCommentTable() {
@Override @Override
@ -1209,13 +1224,12 @@ public class JavacTrees extends DocTrees {
}; };
jcCompilationUnit.lineMap = jcCompilationUnit.getLineMap(); jcCompilationUnit.lineMap = jcCompilationUnit.getLineMap();
jcCompilationUnit.modle = psym.modle;
jcCompilationUnit.sourcefile = jfo;
jcCompilationUnit.namedImportScope = new NamedImportScope(psym, jcCompilationUnit.toplevelScope); jcCompilationUnit.namedImportScope = new NamedImportScope(psym, jcCompilationUnit.toplevelScope);
jcCompilationUnit.packge = psym; jcCompilationUnit.packge = psym;
jcCompilationUnit.starImportScope = null;
jcCompilationUnit.sourcefile = jfo;
jcCompilationUnit.starImportScope = new StarImportScope(psym); jcCompilationUnit.starImportScope = new StarImportScope(psym);
jcCompilationUnit.toplevelScope = WriteableScope.create(psym); jcCompilationUnit.toplevelScope = WriteableScope.create(psym);
return new TreePath(jcCompilationUnit); return new TreePath(jcCompilationUnit);
} }
} }

View File

@ -37,11 +37,13 @@ import javax.tools.JavaFileManager;
import javax.tools.JavaFileManager.Location; import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager; import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import com.sun.tools.javac.code.Scope.WriteableScope; import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.Completer; import com.sun.tools.javac.code.Symbol.Completer;
import com.sun.tools.javac.code.Symbol.CompletionFailure; import com.sun.tools.javac.code.Symbol.CompletionFailure;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol; import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symbol.TypeSymbol; import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.comp.Annotate; import com.sun.tools.javac.comp.Annotate;
@ -118,6 +120,10 @@ public class ClassFinder {
*/ */
final Name completionFailureName; final Name completionFailureName;
/** Module specified with -Xmodule:
*/
final Name moduleOverride;
/** Access to files /** Access to files
*/ */
private final JavaFileManager fileManager; private final JavaFileManager fileManager;
@ -178,7 +184,7 @@ public class ClassFinder {
return instance; return instance;
} }
/** Construct a new class reader. */ /** Construct a new class finder. */
protected ClassFinder(Context context) { protected ClassFinder(Context context) {
context.put(classFinderKey, this); context.put(classFinderKey, this);
reader = ClassReader.instance(context); reader = ClassReader.instance(context);
@ -205,6 +211,9 @@ public class ClassFinder {
? names.fromString(options.get("failcomplete")) ? names.fromString(options.get("failcomplete"))
: null; : null;
moduleOverride = options.isSet(XMODULE) ? names.fromString(options.get(XMODULE))
: null;
// Temporary, until more info is available from the module system. // Temporary, until more info is available from the module system.
boolean useCtProps; boolean useCtProps;
JavaFileManager fm = context.get(JavaFileManager.class); JavaFileManager fm = context.get(JavaFileManager.class);
@ -237,7 +246,7 @@ public class ClassFinder {
* available from the module system. * available from the module system.
*/ */
long getSupplementaryFlags(ClassSymbol c) { long getSupplementaryFlags(ClassSymbol c) {
if (jrtIndex == null || !jrtIndex.isInJRT(c.classfile)) { if (jrtIndex == null || !jrtIndex.isInJRT(c.classfile) || c.name == names.module_info) {
return 0; return 0;
} }
@ -318,7 +327,7 @@ public class ClassFinder {
for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) { for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) {
Symbol encl = owner.members().findFirst(name); Symbol encl = owner.members().findFirst(name);
if (encl == null) if (encl == null)
encl = syms.classes.get(TypeSymbol.formFlatName(name, owner)); encl = syms.getClass(c.packge().modle, TypeSymbol.formFlatName(name, owner));
if (encl != null) if (encl != null)
encl.complete(); encl.complete();
} }
@ -328,7 +337,7 @@ public class ClassFinder {
/** Fill in definition of class `c' from corresponding class or /** Fill in definition of class `c' from corresponding class or
* source file. * source file.
*/ */
private void fillIn(ClassSymbol c) { void fillIn(ClassSymbol c) {
if (completionFailureName == c.fullname) { if (completionFailureName == c.fullname) {
throw new CompletionFailure(c, "user-selected completion failure by class name"); throw new CompletionFailure(c, "user-selected completion failure by class name");
} }
@ -397,14 +406,21 @@ public class ClassFinder {
/** Load a toplevel class with given fully qualified name /** Load a toplevel class with given fully qualified name
* The class is entered into `classes' only if load was successful. * The class is entered into `classes' only if load was successful.
*/ */
public ClassSymbol loadClass(Name flatname) throws CompletionFailure { public ClassSymbol loadClass(ModuleSymbol msym, Name flatname) throws CompletionFailure {
boolean absent = syms.classes.get(flatname) == null; Assert.checkNonNull(msym);
ClassSymbol c = syms.enterClass(flatname); Name packageName = Convert.packagePart(flatname);
PackageSymbol ps = syms.lookupPackage(msym, packageName);
Assert.checkNonNull(ps.modle, () -> "msym=" + msym + "; flatName=" + flatname);
boolean absent = syms.getClass(ps.modle, flatname) == null;
ClassSymbol c = syms.enterClass(ps.modle, flatname);
if (c.members_field == null) { if (c.members_field == null) {
try { try {
c.complete(); c.complete();
} catch (CompletionFailure ex) { } catch (CompletionFailure ex) {
if (absent) syms.classes.remove(flatname); if (absent) syms.removeClass(ps.modle, flatname);
throw ex; throw ex;
} }
} }
@ -438,7 +454,7 @@ public class ClassFinder {
? p.package_info ? p.package_info
: (ClassSymbol) p.members_field.findFirst(classname); : (ClassSymbol) p.members_field.findFirst(classname);
if (c == null) { if (c == null) {
c = syms.enterClass(classname, p); c = syms.enterClass(p.modle, classname, p);
if (c.classfile == null) // only update the file if's it's newly created if (c.classfile == null) // only update the file if's it's newly created
c.classfile = file; c.classfile = file;
if (isPkgInfo) { if (isPkgInfo) {
@ -479,6 +495,7 @@ public class ClassFinder {
/** /**
* specifies types of files to be read when filling in a package symbol * specifies types of files to be read when filling in a package symbol
*/ */
// Note: overridden by JavadocClassFinder
protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() { protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() {
return EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.SOURCE); return EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.SOURCE);
} }
@ -502,16 +519,83 @@ public class ClassFinder {
if (p.members_field == null) if (p.members_field == null)
p.members_field = WriteableScope.create(p); p.members_field = WriteableScope.create(p);
preferCurrent = false; ModuleSymbol msym = p.modle;
if (userPathsFirst) {
Assert.checkNonNull(msym, () -> p.toString());
msym.complete();
if (msym == syms.noModule) {
preferCurrent = false;
if (userPathsFirst) {
scanUserPaths(p);
preferCurrent = true;
scanPlatformPath(p);
} else {
scanPlatformPath(p);
scanUserPaths(p);
}
} else if (msym.classLocation == StandardLocation.CLASS_PATH) {
// assert p.modle.sourceLocation == StandardLocation.SOURCE_PATH);
scanUserPaths(p); scanUserPaths(p);
preferCurrent = true;
scanPlatformPath(p);
} else { } else {
scanPlatformPath(p); scanModulePaths(p, msym);
scanUserPaths(p); }
}
// TODO: for now, this is a much simplified form of scanUserPaths
// and (deliberately) does not default sourcepath to classpath.
// But, we need to think about retaining existing behavior for
// -classpath and -sourcepath for single module mode.
// One plausible solution is to detect if the module's sourceLocation
// is the same as the module's classLocation.
private void scanModulePaths(PackageSymbol p, ModuleSymbol msym) throws IOException {
Set<JavaFileObject.Kind> kinds = getPackageFileKinds();
Set<JavaFileObject.Kind> classKinds = EnumSet.copyOf(kinds);
classKinds.remove(JavaFileObject.Kind.SOURCE);
boolean wantClassFiles = !classKinds.isEmpty();
Set<JavaFileObject.Kind> sourceKinds = EnumSet.copyOf(kinds);
sourceKinds.remove(JavaFileObject.Kind.CLASS);
boolean wantSourceFiles = !sourceKinds.isEmpty();
String packageName = p.fullname.toString();
if (msym.name == moduleOverride) {
if (wantClassFiles) {
fillIn(p, CLASS_PATH,
fileManager.list(CLASS_PATH,
packageName,
classKinds,
false));
}
if (wantSourceFiles && fileManager.hasLocation(SOURCE_PATH)) {
fillIn(p, SOURCE_PATH,
fileManager.list(SOURCE_PATH,
packageName,
sourceKinds,
false));
}
}
Location classLocn = msym.classLocation;
Location sourceLocn = msym.sourceLocation;
if (wantClassFiles && (classLocn != null)) {
fillIn(p, classLocn,
fileManager.list(classLocn,
packageName,
classKinds,
false));
}
if (wantSourceFiles && (sourceLocn != null)) {
fillIn(p, sourceLocn,
fileManager.list(sourceLocn,
packageName,
sourceKinds,
false));
} }
verbosePath = false;
} }
/** /**

View File

@ -0,0 +1,239 @@
/*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. 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.javac.code;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.List;
/**
* Root class for the directives that may appear in module compilation units.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public abstract class Directive implements ModuleElement.Directive {
/** Flags for RequiresDirective. */
public enum RequiresFlag {
PUBLIC(0x0020),
SYNTHETIC(0x1000),
MANDATED(0x8000),
EXTRA(0x10000);
// overkill? move to ClassWriter?
public static int value(Set<RequiresFlag> s) {
int v = 0;
for (RequiresFlag f: s)
v |= f.value;
return v;
}
RequiresFlag(int value) {
this.value = value;
}
public final int value;
}
/**
* 'exports' Package ';'
*/
public static class ExportsDirective extends Directive
implements ModuleElement.ExportsDirective {
public final PackageSymbol packge;
public final List<ModuleSymbol> modules;
public ExportsDirective(PackageSymbol packge, List<ModuleSymbol> modules) {
this.packge = packge;
this.modules = modules;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public ModuleElement.DirectiveKind getKind() {
return ModuleElement.DirectiveKind.EXPORTS;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public PackageElement getPackage() {
return packge;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public java.util.List<? extends ModuleElement> getTargetModules() {
return Collections.unmodifiableList(modules);
}
@Override
public String toString() {
if (modules == null)
return "Exports[" + packge + "]";
else
return "Exports[" + packge + ":" + modules + "]";
}
}
/**
* 'provides' ServiceName 'with' QualifiedIdentifer ';'
*/
public static class ProvidesDirective extends Directive
implements ModuleElement.ProvidesDirective {
public final ClassSymbol service;
public final ClassSymbol impl;
public ProvidesDirective(ClassSymbol service, ClassSymbol impl) {
this.service = service;
this.impl = impl;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public ModuleElement.DirectiveKind getKind() {
return ModuleElement.DirectiveKind.PROVIDES;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public TypeElement getService() {
return service;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public TypeElement getImplementation() {
return impl;
}
@Override
public String toString() {
return "Provides[" + service + "," + impl + "]";
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ProvidesDirective)) {
return false;
}
ProvidesDirective other = (ProvidesDirective)obj;
return service == other.service && impl == other.impl;
}
@Override
public int hashCode() {
return service.hashCode() * 31 + impl.hashCode() * 37;
}
}
/**
* 'requires' ['public'] ModuleName ';'
*/
public static class RequiresDirective extends Directive
implements ModuleElement.RequiresDirective {
public final ModuleSymbol module;
public final Set<RequiresFlag> flags;
public RequiresDirective(ModuleSymbol module) {
this(module, EnumSet.noneOf(RequiresFlag.class));
}
public RequiresDirective(ModuleSymbol module, Set<RequiresFlag> flags) {
this.module = module;
this.flags = flags;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public ModuleElement.DirectiveKind getKind() {
return ModuleElement.DirectiveKind.REQUIRES;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public boolean isPublic() {
return flags.contains(RequiresFlag.PUBLIC);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public ModuleElement getDependency() {
return module;
}
@Override
public String toString() {
return "Requires[" + flags + "," + module + "]";
}
}
/**
* 'uses' ServiceName ';'
*/
public static class UsesDirective extends Directive
implements ModuleElement.UsesDirective {
public final ClassSymbol service;
public UsesDirective(ClassSymbol service) {
this.service = service;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public ModuleElement.DirectiveKind getKind() {
return ModuleElement.DirectiveKind.USES;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public TypeElement getService() {
return service;
}
@Override
public String toString() {
return "Uses[" + service + "]";
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof UsesDirective)) {
return false;
}
UsesDirective other = (UsesDirective)obj;
return service == other.service;
}
@Override
public int hashCode() {
return service.hashCode() * 31;
}
}
}

View File

@ -107,6 +107,7 @@ public class Flags {
public static final int ACC_SUPER = 0x0020; public static final int ACC_SUPER = 0x0020;
public static final int ACC_BRIDGE = 0x0040; public static final int ACC_BRIDGE = 0x0040;
public static final int ACC_VARARGS = 0x0080; public static final int ACC_VARARGS = 0x0080;
public static final int ACC_MODULE = 0x8000;
/***************************************** /*****************************************
* Internal compiler flags (no bits in the lower 16). * Internal compiler flags (no bits in the lower 16).
@ -277,6 +278,21 @@ public class Flags {
*/ */
public static final long TYPE_TRANSLATED = 1L<<50; public static final long TYPE_TRANSLATED = 1L<<50;
/**
* Flag to indicate class symbol is for module-info
*/
public static final long MODULE = 1L<<51;
/**
* Flag to indicate the given ModuleSymbol is an automatic module.
*/
public static final long AUTOMATIC_MODULE = 1L<<52;
/**
* Flag to indicate the given ModuleSymbol is a system module.
*/
public static final long SYSTEM_MODULE = 1L<<53;
/** Modifier masks. /** Modifier masks.
*/ */
public static final int public static final int
@ -385,7 +401,8 @@ public class Flags {
SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC), SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC),
THROWS(Flags.THROWS), THROWS(Flags.THROWS),
LAMBDA_METHOD(Flags.LAMBDA_METHOD), LAMBDA_METHOD(Flags.LAMBDA_METHOD),
TYPE_TRANSLATED(Flags.TYPE_TRANSLATED); TYPE_TRANSLATED(Flags.TYPE_TRANSLATED),
MODULE(Flags.MODULE);
Flag(long flag) { Flag(long flag) {
this.value = flag; this.value = flag;

View File

@ -65,6 +65,7 @@ public class Kinds {
VAR(Category.BASIC, KindName.VAR, KindSelector.VAR), VAR(Category.BASIC, KindName.VAR, KindSelector.VAR),
MTH(Category.BASIC, KindName.METHOD, KindSelector.MTH), MTH(Category.BASIC, KindName.METHOD, KindSelector.MTH),
POLY(Category.BASIC, KindSelector.POLY), POLY(Category.BASIC, KindSelector.POLY),
MDL(Category.BASIC, KindSelector.MDL),
ERR(Category.ERROR, KindSelector.ERR), ERR(Category.ERROR, KindSelector.ERR),
AMBIGUOUS(Category.RESOLUTION_TARGET), // overloaded target AMBIGUOUS(Category.RESOLUTION_TARGET), // overloaded target
HIDDEN(Category.RESOLUTION_TARGET), // not overloaded non-target HIDDEN(Category.RESOLUTION_TARGET), // not overloaded non-target
@ -169,9 +170,10 @@ public class Kinds {
public static final KindSelector VAR = new KindSelector(0x04); public static final KindSelector VAR = new KindSelector(0x04);
public static final KindSelector VAL = new KindSelector(0x0c); public static final KindSelector VAL = new KindSelector(0x0c);
public static final KindSelector MTH = new KindSelector(0x10); public static final KindSelector MTH = new KindSelector(0x10);
public static final KindSelector ERR = new KindSelector(0x3f);
public static final KindSelector POLY = new KindSelector(0x20); public static final KindSelector POLY = new KindSelector(0x20);
public static final KindSelector ASG = new KindSelector(0x44); public static final KindSelector MDL = new KindSelector(0x40);
public static final KindSelector ERR = new KindSelector(0x7f);
public static final KindSelector ASG = new KindSelector(0x84);
//common derived selectors //common derived selectors
public static final KindSelector TYP_PCK = of(TYP, PCK); public static final KindSelector TYP_PCK = of(TYP, PCK);
@ -212,6 +214,7 @@ public class Kinds {
if ((data & MTH.data) != 0) kinds.add(KindName.METHOD); if ((data & MTH.data) != 0) kinds.add(KindName.METHOD);
if ((data & TYP.data) != 0) kinds.add(KindName.CLASS); if ((data & TYP.data) != 0) kinds.add(KindName.CLASS);
if ((data & PCK.data) != 0) kinds.add(KindName.PACKAGE); if ((data & PCK.data) != 0) kinds.add(KindName.PACKAGE);
if ((data & MDL.data) != 0) kinds.add(KindName.MODULE);
return kinds; return kinds;
} }
} }
@ -230,7 +233,8 @@ public class Kinds {
CLASS("kindname.class"), CLASS("kindname.class"),
STATIC_INIT("kindname.static.init"), STATIC_INIT("kindname.static.init"),
INSTANCE_INIT("kindname.instance.init"), INSTANCE_INIT("kindname.instance.init"),
PACKAGE("kindname.package"); PACKAGE("kindname.package"),
MODULE("kindname.module");
private final String name; private final String name;

View File

@ -0,0 +1,335 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.code;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardLocation;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.JCDiagnostic;
import com.sun.tools.javac.util.JCDiagnostic.Fragment;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
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.StringUtils;
import static com.sun.tools.javac.code.Kinds.Kind.*;
/**
* This class provides operations to locate module definitions
* from the source and class files on the paths provided to javac.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class ModuleFinder {
/** The context key for the module finder. */
protected static final Context.Key<ModuleFinder> moduleFinderKey = new Context.Key<>();
/** The log to use for verbose output. */
private final Log log;
/** The symbol table. */
private final Symtab syms;
/** The name table. */
private final Names names;
private final ClassFinder classFinder;
/** Access to files
*/
private final JavaFileManager fileManager;
private final JCDiagnostic.Factory diags;
/** Get the ModuleFinder instance for this invocation. */
public static ModuleFinder instance(Context context) {
ModuleFinder instance = context.get(moduleFinderKey);
if (instance == null)
instance = new ModuleFinder(context);
return instance;
}
/** Construct a new module finder. */
protected ModuleFinder(Context context) {
context.put(moduleFinderKey, this);
names = Names.instance(context);
syms = Symtab.instance(context);
fileManager = context.get(JavaFileManager.class);
log = Log.instance(context);
classFinder = ClassFinder.instance(context);
diags = JCDiagnostic.Factory.instance(context);
}
class ModuleLocationIterator implements Iterator<Set<Location>> {
StandardLocation outer;
Set<Location> next = null;
Iterator<StandardLocation> outerIter = Arrays.asList(
StandardLocation.MODULE_SOURCE_PATH,
StandardLocation.UPGRADE_MODULE_PATH,
StandardLocation.SYSTEM_MODULES,
StandardLocation.MODULE_PATH
).iterator();
Iterator<Set<Location>> innerIter = null;
@Override
public boolean hasNext() {
while (next == null) {
while (innerIter == null || !innerIter.hasNext()) {
if (outerIter.hasNext()) {
outer = outerIter.next();
try {
innerIter = fileManager.listModuleLocations(outer).iterator();
} catch (IOException e) {
System.err.println("error listing module locations for " + outer + ": " + e); // FIXME
}
} else
return false;
}
if (innerIter.hasNext())
next = innerIter.next();
}
return true;
}
@Override
public Set<Location> next() {
hasNext();
if (next != null) {
Set<Location> result = next;
next = null;
return result;
}
throw new NoSuchElementException();
}
}
ModuleLocationIterator moduleLocationIterator = new ModuleLocationIterator();
public ModuleSymbol findModule(Name name) {
return findModule(syms.enterModule(name));
}
public ModuleSymbol findModule(ModuleSymbol msym) {
if (msym.kind != ERR && msym.sourceLocation == null && msym.classLocation == null) {
// fill in location
List<ModuleSymbol> list = scanModulePath(msym);
if (list.isEmpty()) {
msym.kind = ERR;
}
}
if (msym.kind != ERR && msym.module_info.sourcefile == null && msym.module_info.classfile == null) {
// fill in module-info
findModuleInfo(msym);
}
return msym;
}
public List<ModuleSymbol> findAllModules() {
List<ModuleSymbol> list = scanModulePath(null);
for (ModuleSymbol msym: list) {
if (msym.kind != ERR && msym.module_info.sourcefile == null && msym.module_info.classfile == null) {
// fill in module-info
findModuleInfo(msym);
}
}
return list;
}
public ModuleSymbol findSingleModule() {
try {
JavaFileObject src_fo = getModuleInfoFromLocation(StandardLocation.SOURCE_PATH, Kind.SOURCE);
JavaFileObject class_fo = getModuleInfoFromLocation(StandardLocation.CLASS_OUTPUT, Kind.CLASS);
JavaFileObject fo = (src_fo == null) ? class_fo
: (class_fo == null) ? src_fo
: classFinder.preferredFileObject(src_fo, class_fo);
ModuleSymbol msym;
if (fo == null) {
msym = syms.unnamedModule;
} else {
// Note: the following may trigger a re-entrant call to Modules.enter
// msym = new ModuleSymbol();
// ClassSymbol info = new ClassSymbol(Flags.MODULE, names.module_info, msym);
// info.modle = msym;
// info.classfile = fo;
// info.members_field = WriteableScope.create(info);
// msym.module_info = info;
msym = ModuleSymbol.create(null, names.module_info);
msym.module_info.classfile = fo;
msym.completer = sym -> classFinder.fillIn(msym.module_info);
// // TODO: should we do the following here, or as soon as we find the name in
// // the source or class file?
// // Consider the case when the class/source path module shadows one on the
// // module source path
// if (syms.modules.get(msym.name) != null) {
// // error: module already defined
// System.err.println("ERROR: module already defined: " + msym);
// } else {
// syms.modules.put(msym.name, msym);
// }
}
msym.classLocation = StandardLocation.CLASS_OUTPUT;
return msym;
} catch (IOException e) {
throw new Error(e); // FIXME
}
}
private JavaFileObject getModuleInfoFromLocation(Location location, Kind kind) throws IOException {
if (!fileManager.hasLocation(location))
return null;
return fileManager.getJavaFileForInput(location,
names.module_info.toString(),
kind);
}
private List<ModuleSymbol> scanModulePath(ModuleSymbol toFind) {
ListBuffer<ModuleSymbol> results = new ListBuffer<>();
Map<Name, Location> namesInSet = new HashMap<>();
while (moduleLocationIterator.hasNext()) {
Set<Location> locns = (moduleLocationIterator.next());
namesInSet.clear();
for (Location l: locns) {
try {
Name n = names.fromString(fileManager.inferModuleName(l));
if (namesInSet.put(n, l) == null) {
ModuleSymbol msym = syms.enterModule(n);
if (msym.sourceLocation != null || msym.classLocation != null) {
// module has already been found, so ignore this instance
continue;
}
if (moduleLocationIterator.outer == StandardLocation.MODULE_SOURCE_PATH) {
msym.sourceLocation = l;
if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
msym.classLocation = fileManager.getModuleLocation(StandardLocation.CLASS_OUTPUT, msym.name.toString());
}
} else {
msym.classLocation = l;
}
if (moduleLocationIterator.outer == StandardLocation.SYSTEM_MODULES ||
moduleLocationIterator.outer == StandardLocation.UPGRADE_MODULE_PATH) {
msym.flags_field |= Flags.SYSTEM_MODULE;
}
if (toFind == msym || toFind == null) {
// Note: cannot return msym directly, because we must finish
// processing this set first
results.add(msym);
}
} else {
log.error(Errors.DuplicateModuleOnPath(
getDescription(moduleLocationIterator.outer), n));
}
} catch (IOException e) {
// skip location for now? log error?
}
}
if (toFind != null && results.nonEmpty())
return results.toList();
}
return results.toList();
}
private void findModuleInfo(ModuleSymbol msym) {
try {
JavaFileObject src_fo = (msym.sourceLocation == null) ? null
: fileManager.getJavaFileForInput(msym.sourceLocation,
names.module_info.toString(), Kind.SOURCE);
JavaFileObject class_fo = (msym.classLocation == null) ? null
: fileManager.getJavaFileForInput(msym.classLocation,
names.module_info.toString(), Kind.CLASS);
JavaFileObject fo = (src_fo == null) ? class_fo :
(class_fo == null) ? src_fo :
classFinder.preferredFileObject(src_fo, class_fo);
if (fo == null) {
String moduleName = msym.sourceLocation == null && msym.classLocation != null ?
fileManager.inferModuleName(msym.classLocation) : null;
if (moduleName != null) {
msym.module_info.classfile = null;
msym.flags_field |= Flags.AUTOMATIC_MODULE;
} else {
msym.kind = ERR;
}
} else {
msym.module_info.classfile = fo;
msym.module_info.completer = new Symbol.Completer() {
@Override
public void complete(Symbol sym) throws CompletionFailure {
classFinder.fillIn(msym.module_info);
}
@Override
public String toString() {
return "ModuleInfoCompleter";
}
};
}
} catch (IOException e) {
msym.kind = ERR;
}
}
Fragment getDescription(StandardLocation l) {
switch (l) {
case MODULE_PATH: return Fragments.LocnModule_path;
case MODULE_SOURCE_PATH: return Fragments.LocnModule_source_path;
case SYSTEM_MODULES: return Fragments.LocnSystem_modules;
case UPGRADE_MODULE_PATH: return Fragments.LocnUpgrade_module_path;
default:
throw new AssertionError();
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -152,14 +152,14 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
if (seenCaptured.contains(t)) if (seenCaptured.contains(t))
return printAnnotations(t) + return printAnnotations(t) +
localize(locale, "compiler.misc.type.captureof.1", localize(locale, "compiler.misc.type.captureof.1",
capturedVarId(t, locale)); capturedVarId(t, locale));
else { else {
try { try {
seenCaptured = seenCaptured.prepend(t); seenCaptured = seenCaptured.prepend(t);
return printAnnotations(t) + return printAnnotations(t) +
localize(locale, "compiler.misc.type.captureof", localize(locale, "compiler.misc.type.captureof",
capturedVarId(t, locale), capturedVarId(t, locale),
visit(t.wildcard, locale)); visit(t.wildcard, locale));
} }
finally { finally {
seenCaptured = seenCaptured.tail; seenCaptured = seenCaptured.tail;
@ -274,6 +274,11 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
return visitType(t, locale); return visitType(t, locale);
} }
@Override
public String visitModuleType(ModuleType t, Locale locale) {
return visitType(t, locale);
}
public String visitType(Type t, Locale locale) { public String visitType(Type t, Locale locale) {
String s = (t.tsym == null || t.tsym.name == null) String s = (t.tsym == null || t.tsym.name == null)
? localize(locale, "compiler.misc.type.none") ? localize(locale, "compiler.misc.type.none")

View File

@ -137,6 +137,9 @@ public enum Source {
public boolean allowImprovedCatchAnalysis() { public boolean allowImprovedCatchAnalysis() {
return compareTo(JDK1_7) >= 0; return compareTo(JDK1_7) >= 0;
} }
public boolean allowModules() {
return compareTo(JDK1_9) >= 0;
}
public boolean allowTryWithResources() { public boolean allowTryWithResources() {
return compareTo(JDK1_7) >= 0; return compareTo(JDK1_7) >= 0;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,16 +27,26 @@ package com.sun.tools.javac.code;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited; import java.lang.annotation.Inherited;
import java.util.Collections;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import javax.lang.model.element.*; import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ElementVisitor;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.NestingKind;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.element.VariableElement;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.Attribute.Compound; import com.sun.tools.javac.code.Kinds.Kind;
import com.sun.tools.javac.code.TypeAnnotations.AnnotationType;
import com.sun.tools.javac.code.TypeMetadata.Entry;
import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata; import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
import com.sun.tools.javac.code.Scope.WriteableScope; import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.*;
@ -48,6 +58,7 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Name;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Kinds.Kind.*; import static com.sun.tools.javac.code.Kinds.Kind.*;
@ -843,7 +854,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
boolean isCurrentSymbolsAnnotation(Attribute.TypeCompound anno, int index) { boolean isCurrentSymbolsAnnotation(Attribute.TypeCompound anno, int index) {
return (anno.position.type == TargetType.CLASS_TYPE_PARAMETER || return (anno.position.type == TargetType.CLASS_TYPE_PARAMETER ||
anno.position.type == TargetType.METHOD_TYPE_PARAMETER) && anno.position.type == TargetType.METHOD_TYPE_PARAMETER) &&
anno.position.parameter_index == index; anno.position.parameter_index == index;
} }
@ -852,6 +863,122 @@ public abstract class Symbol extends AnnoConstruct implements Element {
return v.visitTypeParameter(this, p); return v.visitTypeParameter(this, p);
} }
} }
/** A class for module symbols.
*/
public static class ModuleSymbol extends TypeSymbol
implements ModuleElement {
public Name version;
public JavaFileManager.Location sourceLocation;
public JavaFileManager.Location classLocation;
/** All directives, in natural order. */
public List<com.sun.tools.javac.code.Directive> directives;
public List<com.sun.tools.javac.code.Directive.RequiresDirective> requires;
public List<com.sun.tools.javac.code.Directive.ExportsDirective> exports;
public List<com.sun.tools.javac.code.Directive.ProvidesDirective> provides;
public List<com.sun.tools.javac.code.Directive.UsesDirective> uses;
public ClassSymbol module_info;
public PackageSymbol unnamedPackage;
public Map<Name, PackageSymbol> visiblePackages;
public List<Symbol> enclosedPackages = List.nil();
public Completer usesProvidesCompleter = Completer.NULL_COMPLETER;
/**
* Create a ModuleSymbol with an associated module-info ClassSymbol.
* The name of the module may be null, if it is not known yet.
*/
public static ModuleSymbol create(Name name, Name module_info) {
ModuleSymbol msym = new ModuleSymbol(name, null);
ClassSymbol info = new ClassSymbol(Flags.MODULE, module_info, msym);
info.fullname = formFullName(module_info, msym);
info.flatname = info.fullname;
info.members_field = WriteableScope.create(info);
msym.module_info = info;
return msym;
}
public ModuleSymbol() {
super(MDL, 0, null, null, null);
this.type = new ModuleType(this);
}
public ModuleSymbol(Name name, Symbol owner) {
super(MDL, 0, name, null, owner);
this.type = new ModuleType(this);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public boolean isUnnamed() {
return name.isEmpty() && owner == null;
}
public boolean isNoModule() {
return false;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public ElementKind getKind() {
return ElementKind.MODULE;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public java.util.List<Directive> getDirectives() {
completeUsesProvides();
return Collections.unmodifiableList(directives);
}
public void completeUsesProvides() {
if (usesProvidesCompleter != Completer.NULL_COMPLETER) {
Completer c = usesProvidesCompleter;
usesProvidesCompleter = Completer.NULL_COMPLETER;
c.complete(this);
}
}
@Override
public ClassSymbol outermostClass() {
return null;
}
@Override
public String toString() {
// TODO: the following strings should be localized
// Do this with custom anon subtypes in Symtab
String n = (name == null) ? "<unknown>"
: (name.isEmpty()) ? "<unnamed>"
: String.valueOf(name);
return n;
}
@Override
public <R, P> R accept(ElementVisitor<R, P> v, P p) {
return v.visitModule(this, p);
}
@Override
public List<Symbol> getEnclosedElements() {
List<Symbol> list = List.nil();
for (Symbol sym : enclosedPackages) {
if (sym.members().anyMatch(m -> m.kind == TYP))
list = list.prepend(sym);
}
return list;
}
public void reset() {
this.directives = null;
this.requires = null;
this.exports = null;
this.provides = null;
this.uses = null;
this.visiblePackages = null;
}
}
/** A class for package symbols /** A class for package symbols
*/ */
@ -861,6 +988,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
public WriteableScope members_field; public WriteableScope members_field;
public Name fullname; public Name fullname;
public ClassSymbol package_info; // see bug 6443073 public ClassSymbol package_info; // see bug 6443073
public ModuleSymbol modle;
public PackageSymbol(Name name, Type type, Symbol owner) { public PackageSymbol(Name name, Type type, Symbol owner) {
super(PCK, 0, name, type, owner); super(PCK, 0, name, type, owner);
@ -929,7 +1057,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
@DefinedBy(Api.LANGUAGE_MODEL) @DefinedBy(Api.LANGUAGE_MODEL)
public Symbol getEnclosingElement() { public Symbol getEnclosingElement() {
return null; return modle != null && !modle.isNoModule() ? modle : null;
} }
@DefinedBy(Api.LANGUAGE_MODEL) @DefinedBy(Api.LANGUAGE_MODEL)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,18 +25,20 @@
package com.sun.tools.javac.code; package com.sun.tools.javac.code;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import javax.lang.model.element.ElementVisitor; import javax.lang.model.element.ElementVisitor;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.Scope.WriteableScope; import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.Completer; import com.sun.tools.javac.code.Symbol.Completer;
import com.sun.tools.javac.code.Symbol.CompletionFailure; import com.sun.tools.javac.code.Symbol.CompletionFailure;
import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol; import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symbol.TypeSymbol; import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol;
@ -47,17 +49,18 @@ import com.sun.tools.javac.code.Type.JCPrimitiveType;
import com.sun.tools.javac.code.Type.JCVoidType; import com.sun.tools.javac.code.Type.JCVoidType;
import com.sun.tools.javac.code.Type.MethodType; import com.sun.tools.javac.code.Type.MethodType;
import com.sun.tools.javac.code.Type.UnknownType; import com.sun.tools.javac.code.Type.UnknownType;
import com.sun.tools.javac.jvm.Target; import com.sun.tools.javac.comp.Modules;
import com.sun.tools.javac.util.Assert; import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Convert; import com.sun.tools.javac.util.Convert;
import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.Iterators;
import com.sun.tools.javac.util.JavacMessages; import com.sun.tools.javac.util.JavacMessages;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Names;
import com.sun.tools.javac.util.Options;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.Kind.*; import static com.sun.tools.javac.code.Kinds.Kind.*;
@ -100,17 +103,26 @@ public class Symtab {
public final JCVoidType voidType = new JCVoidType(); public final JCVoidType voidType = new JCVoidType();
private final Names names; private final Names names;
private final JavacMessages messages;
private final Completer initialCompleter; private final Completer initialCompleter;
private final Target target; private final Completer moduleCompleter;
/** A symbol for the unnamed module.
*/
public final ModuleSymbol unnamedModule;
/** The error module.
*/
public final ModuleSymbol errModule;
/** A symbol for no module, for use with -source 8 or less
*/
public final ModuleSymbol noModule;
/** A symbol for the root package. /** A symbol for the root package.
*/ */
public final PackageSymbol rootPackage; public final PackageSymbol rootPackage;
/** A symbol for the unnamed package.
*/
public final PackageSymbol unnamedPackage;
/** A symbol that stands for a missing symbol. /** A symbol that stands for a missing symbol.
*/ */
public final TypeSymbol noSymbol; public final TypeSymbol noSymbol;
@ -139,6 +151,10 @@ public class Symtab {
/** The builtin type of all methods. */ /** The builtin type of all methods. */
public final ClassSymbol methodClass; public final ClassSymbol methodClass;
/** A symbol for the java.base module.
*/
public final ModuleSymbol java_base;
/** Predefined types. /** Predefined types.
*/ */
public final Type objectType; public final Type objectType;
@ -208,7 +224,7 @@ public class Symtab {
*/ */
public final Type[] typeOfTag = new Type[TypeTag.getTypeTagCount()]; public final Type[] typeOfTag = new Type[TypeTag.getTypeTagCount()];
/** The name of the class that belongs to a basix type tag. /** The name of the class that belongs to a basic type tag.
*/ */
public final Name[] boxedName = new Name[TypeTag.getTypeTagCount()]; public final Name[] boxedName = new Name[TypeTag.getTypeTagCount()];
@ -217,13 +233,17 @@ public class Symtab {
* It should be updated from the outside to reflect classes defined * It should be updated from the outside to reflect classes defined
* by compiled source files. * by compiled source files.
*/ */
public final Map<Name, ClassSymbol> classes = new HashMap<>(); private final Map<Name, Map<ModuleSymbol,ClassSymbol>> classes = new HashMap<>();
/** A hashtable containing the encountered packages. /** A hashtable containing the encountered packages.
* the table should be updated from outside to reflect packages defined * the table should be updated from outside to reflect packages defined
* by compiled source files. * by compiled source files.
*/ */
public final Map<Name, PackageSymbol> packages = new HashMap<>(); private final Map<Name, Map<ModuleSymbol,PackageSymbol>> packages = new HashMap<>();
/** A hashtable giving the encountered modules.
*/
private final Map<Name, ModuleSymbol> modules = new LinkedHashMap<>();
public void initType(Type type, ClassSymbol c) { public void initType(Type type, ClassSymbol c) {
type.tsym = c; type.tsym = c;
@ -239,7 +259,7 @@ public class Symtab {
public void initType(Type type, String name, String bname) { public void initType(Type type, String name, String bname) {
initType(type, name); initType(type, name);
boxedName[type.getTag().ordinal()] = names.fromString("java.lang." + bname); boxedName[type.getTag().ordinal()] = names.fromString("java.lang." + bname);
} }
/** The class symbol that owns all predefined symbols. /** The class symbol that owns all predefined symbols.
@ -250,12 +270,13 @@ public class Symtab {
* @param s The name of the class. * @param s The name of the class.
*/ */
private Type enterClass(String s) { private Type enterClass(String s) {
return enterClass(names.fromString(s)).type; return enterClass(java_base, names.fromString(s)).type;
} }
public void synthesizeEmptyInterfaceIfMissing(final Type type) { public void synthesizeEmptyInterfaceIfMissing(final Type type) {
final Completer completer = type.tsym.completer; final Completer completer = type.tsym.completer;
type.tsym.completer = new Completer() { type.tsym.completer = new Completer() {
@Override
public void complete(Symbol sym) throws CompletionFailure { public void complete(Symbol sym) throws CompletionFailure {
try { try {
completer.complete(sym); completer.complete(sym);
@ -273,9 +294,10 @@ public class Symtab {
} }
public void synthesizeBoxTypeIfMissing(final Type type) { public void synthesizeBoxTypeIfMissing(final Type type) {
ClassSymbol sym = enterClass(boxedName[type.getTag().ordinal()]); ClassSymbol sym = enterClass(java_base, boxedName[type.getTag().ordinal()]);
final Completer completer = sym.completer; final Completer completer = sym.completer;
sym.completer = new Completer() { sym.completer = new Completer() {
@Override
public void complete(Symbol sym) throws CompletionFailure { public void complete(Symbol sym) throws CompletionFailure {
try { try {
completer.complete(sym); completer.complete(sym);
@ -308,7 +330,9 @@ public class Symtab {
// Enter a synthetic class that is used to mark classes in ct.sym. // Enter a synthetic class that is used to mark classes in ct.sym.
// This class does not have a class file. // This class does not have a class file.
private Type enterSyntheticAnnotation(String name) { private Type enterSyntheticAnnotation(String name) {
ClassType type = (ClassType)enterClass(name); // for now, leave the module null, to prevent problems from synthesizing the
// existence of a class in any specific module, including noModule
ClassType type = (ClassType)enterClass(java_base, names.fromString(name)).type;
ClassSymbol sym = (ClassSymbol)type.tsym; ClassSymbol sym = (ClassSymbol)type.tsym;
sym.completer = Completer.NULL_COMPLETER; sym.completer = Completer.NULL_COMPLETER;
sym.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE; sym.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE;
@ -328,22 +352,35 @@ public class Symtab {
context.put(symtabKey, this); context.put(symtabKey, this);
names = Names.instance(context); names = Names.instance(context);
target = Target.instance(context);
// Create the unknown type // Create the unknown type
unknownType = new UnknownType(); unknownType = new UnknownType();
// create the basic builtin symbols messages = JavacMessages.instance(context);
rootPackage = new PackageSymbol(names.empty, null); rootPackage = new PackageSymbol(names.empty, null);
packages.put(names.empty, rootPackage);
final JavacMessages messages = JavacMessages.instance(context); // create the basic builtin symbols
unnamedPackage = new PackageSymbol(names.empty, rootPackage) { unnamedModule = new ModuleSymbol(names.empty, null) {
@Override
public String toString() { public String toString() {
return messages.getLocalizedString("compiler.misc.unnamed.package"); return messages.getLocalizedString("compiler.misc.unnamed.module");
} }
}; };
addRootPackageFor(unnamedModule);
errModule = new ModuleSymbol(names.empty, null) { };
addRootPackageFor(errModule);
noModule = new ModuleSymbol(names.empty, null) {
@Override public boolean isNoModule() {
return true;
}
};
addRootPackageFor(noModule);
noSymbol = new TypeSymbol(NIL, 0, names.empty, Type.noType, rootPackage) { noSymbol = new TypeSymbol(NIL, 0, names.empty, Type.noType, rootPackage) {
@DefinedBy(Api.LANGUAGE_MODEL) @Override @DefinedBy(Api.LANGUAGE_MODEL)
public <R, P> R accept(ElementVisitor<R, P> v, P p) { public <R, P> R accept(ElementVisitor<R, P> v, P p) {
return v.visitUnknown(this, p); return v.visitUnknown(this, p);
} }
@ -389,8 +426,7 @@ public class Symtab {
// Get the initial completer for Symbols from the ClassFinder // Get the initial completer for Symbols from the ClassFinder
initialCompleter = ClassFinder.instance(context).getCompleter(); initialCompleter = ClassFinder.instance(context).getCompleter();
rootPackage.completer = initialCompleter; rootPackage.members_field = WriteableScope.create(rootPackage);
unnamedPackage.completer = initialCompleter;
// Enter symbols for basic types. // Enter symbols for basic types.
scope.enter(byteType.tsym); scope.enter(byteType.tsym);
@ -406,9 +442,22 @@ public class Symtab {
// Enter symbol for the errSymbol // Enter symbol for the errSymbol
scope.enter(errSymbol); scope.enter(errSymbol);
classes.put(predefClass.fullname, predefClass); Source source = Source.instance(context);
Options options = Options.instance(context);
boolean noModules = options.isSet("noModules");
if (source.allowModules() && !noModules) {
java_base = enterModule(names.java_base);
//avoid completing java.base during the Symtab initialization
java_base.completer = Completer.NULL_COMPLETER;
java_base.visiblePackages = Collections.emptyMap();
} else {
java_base = noModule;
}
// Enter predefined classes. // Get the initial completer for ModuleSymbols from Modules
moduleCompleter = Modules.instance(context).getCompleter();
// Enter predefined classes. All are assumed to be in the java.base module.
objectType = enterClass("java.lang.Object"); objectType = enterClass("java.lang.Object");
objectsType = enterClass("java.util.Objects"); objectsType = enterClass("java.util.Objects");
classType = enterClass("java.lang.Class"); classType = enterClass("java.lang.Class");
@ -434,7 +483,7 @@ public class Symtab {
cloneNotSupportedExceptionType = enterClass("java.lang.CloneNotSupportedException"); cloneNotSupportedExceptionType = enterClass("java.lang.CloneNotSupportedException");
annotationType = enterClass("java.lang.annotation.Annotation"); annotationType = enterClass("java.lang.annotation.Annotation");
classLoaderType = enterClass("java.lang.ClassLoader"); classLoaderType = enterClass("java.lang.ClassLoader");
enumSym = enterClass(names.java_lang_Enum); enumSym = enterClass(java_base, names.java_lang_Enum);
enumFinalFinalize = enumFinalFinalize =
new MethodSymbol(PROTECTED|FINAL|HYPOTHETICAL, new MethodSymbol(PROTECTED|FINAL|HYPOTHETICAL,
names.finalize, names.finalize,
@ -512,14 +561,16 @@ public class Symtab {
List.<Type>nil(), methodClass), List.<Type>nil(), methodClass),
arrayClass); arrayClass);
arrayClass.members().enter(arrayCloneMethod); arrayClass.members().enter(arrayCloneMethod);
if (java_base != noModule)
java_base.completer = sym -> moduleCompleter.complete(sym); //bootstrap issues
} }
/** Define a new class given its name and owner. /** Define a new class given its name and owner.
*/ */
public ClassSymbol defineClass(Name name, Symbol owner) { public ClassSymbol defineClass(Name name, Symbol owner) {
ClassSymbol c = new ClassSymbol(0, name, owner); ClassSymbol c = new ClassSymbol(0, name, owner);
if (owner.kind == PCK)
Assert.checkNull(classes.get(c.flatname), c);
c.completer = initialCompleter; c.completer = initialCompleter;
return c; return c;
} }
@ -527,12 +578,13 @@ public class Symtab {
/** Create a new toplevel or member class symbol with given name /** Create a new toplevel or member class symbol with given name
* and owner and enter in `classes' unless already there. * and owner and enter in `classes' unless already there.
*/ */
public ClassSymbol enterClass(Name name, TypeSymbol owner) { public ClassSymbol enterClass(ModuleSymbol msym, Name name, TypeSymbol owner) {
Assert.checkNonNull(msym);
Name flatname = TypeSymbol.formFlatName(name, owner); Name flatname = TypeSymbol.formFlatName(name, owner);
ClassSymbol c = classes.get(flatname); ClassSymbol c = getClass(msym, flatname);
if (c == null) { if (c == null) {
c = defineClass(name, owner); c = defineClass(name, owner);
classes.put(flatname, c); doEnterClass(msym, c);
} else if ((c.name != name || c.owner != owner) && owner.kind == TYP && c.owner.kind == PCK) { } else if ((c.name != name || c.owner != owner) && owner.kind == TYP && c.owner.kind == PCK) {
// reassign fields of classes that might have been loaded with // reassign fields of classes that might have been loaded with
// their flat names. // their flat names.
@ -544,71 +596,212 @@ public class Symtab {
return c; return c;
} }
/** public ClassSymbol getClass(ModuleSymbol msym, Name flatName) {
* Creates a new toplevel class symbol with given flat name and Assert.checkNonNull(msym, () -> flatName.toString());
* given class (or source) file. return classes.getOrDefault(flatName, Collections.emptyMap()).get(msym);
* }
* @param flatName a fully qualified binary class name
* @param classFile the class file or compilation unit defining public PackageSymbol lookupPackage(ModuleSymbol msym, Name flatName) {
* the class (may be {@code null}) Assert.checkNonNull(msym);
* @return a newly created class symbol
* @throws AssertionError if the class symbol already exists if (flatName.isEmpty()) {
*/ //unnamed packages only from the current module - visiblePackages contains *root* package, not unnamed package!
public ClassSymbol enterClass(Name flatName, JavaFileObject classFile) { return msym.unnamedPackage;
ClassSymbol cs = classes.get(flatName);
if (cs != null) {
String msg = Log.format("%s: completer = %s; class file = %s; source file = %s",
cs.fullname,
cs.completer,
cs.classfile,
cs.sourcefile);
throw new AssertionError(msg);
} }
Name packageName = Convert.packagePart(flatName);
PackageSymbol owner = packageName.isEmpty() if (msym == noModule) {
? unnamedPackage return enterPackage(msym, flatName);
: enterPackage(packageName); }
cs = defineClass(Convert.shortName(flatName), owner);
cs.classfile = classFile; msym.complete();
classes.put(flatName, cs);
return cs; PackageSymbol pack;
pack = msym.visiblePackages.get(flatName);
if (pack != null)
return pack;
pack = getPackage(msym, flatName);
if (pack != null && pack.exists())
return pack;
boolean dependsOnUnnamed = msym.requires != null &&
msym.requires.stream()
.map(rd -> rd.module)
.anyMatch(mod -> mod == unnamedModule);
if (dependsOnUnnamed) {
//msyms depends on the unnamed module, for which we generally don't know
//the list of packages it "exports" ahead of time. So try to lookup the package in the
//current module, and in the unnamed module and see if it exists in one of them
PackageSymbol unnamedPack = getPackage(unnamedModule, flatName);
if (unnamedPack != null && unnamedPack.exists()) {
msym.visiblePackages.put(unnamedPack.fullname, unnamedPack);
return unnamedPack;
}
pack = enterPackage(msym, flatName);
pack.complete();
if (pack.exists())
return pack;
unnamedPack = enterPackage(unnamedModule, flatName);
unnamedPack.complete();
if (unnamedPack.exists()) {
msym.visiblePackages.put(unnamedPack.fullname, unnamedPack);
return unnamedPack;
}
return pack;
}
return enterPackage(msym, flatName);
}
private static final Map<ModuleSymbol, ClassSymbol> EMPTY = new HashMap<>();
public void removeClass(ModuleSymbol msym, Name flatName) {
classes.getOrDefault(flatName, EMPTY).remove(msym);
}
public Iterable<ClassSymbol> getAllClasses() {
return () -> Iterators.createCompoundIterator(classes.values(), v -> v.values().iterator());
}
private void doEnterClass(ModuleSymbol msym, ClassSymbol cs) {
classes.computeIfAbsent(cs.flatname, n -> new HashMap<>()).put(msym, cs);
} }
/** Create a new member or toplevel class symbol with given flat name /** Create a new member or toplevel class symbol with given flat name
* and enter in `classes' unless already there. * and enter in `classes' unless already there.
*/ */
public ClassSymbol enterClass(Name flatname) { public ClassSymbol enterClass(ModuleSymbol msym, Name flatname) {
ClassSymbol c = classes.get(flatname); Assert.checkNonNull(msym);
if (c == null) PackageSymbol ps = lookupPackage(msym, Convert.packagePart(flatname));
return enterClass(flatname, (JavaFileObject)null); Assert.checkNonNull(ps);
else Assert.checkNonNull(ps.modle);
ClassSymbol c = getClass(ps.modle, flatname);
if (c == null) {
c = defineClass(Convert.shortName(flatname), ps);
doEnterClass(ps.modle, c);
return c;
} else
return c; return c;
} }
/** Check to see if a package exists, given its fully qualified name. /** Check to see if a package exists, given its fully qualified name.
*/ */
public boolean packageExists(Name fullname) { public boolean packageExists(ModuleSymbol msym, Name fullname) {
return enterPackage(fullname).exists(); Assert.checkNonNull(msym);
return enterPackage(msym, fullname).exists();
} }
/** Make a package, given its fully qualified name. /** Make a package, given its fully qualified name.
*/ */
public PackageSymbol enterPackage(Name fullname) { public PackageSymbol enterPackage(ModuleSymbol currModule, Name fullname) {
PackageSymbol p = packages.get(fullname); Assert.checkNonNull(currModule);
PackageSymbol p = getPackage(currModule, fullname);
if (p == null) { if (p == null) {
Assert.check(!fullname.isEmpty(), "rootPackage missing!"); Assert.check(!fullname.isEmpty(), () -> "rootPackage missing!; currModule: " + currModule);
p = new PackageSymbol( p = new PackageSymbol(
Convert.shortName(fullname), Convert.shortName(fullname),
enterPackage(Convert.packagePart(fullname))); enterPackage(currModule, Convert.packagePart(fullname)));
p.completer = initialCompleter; p.completer = initialCompleter;
packages.put(fullname, p); p.modle = currModule;
doEnterPackage(currModule, p);
} }
return p; return p;
} }
/** Make a package, given its unqualified name and enclosing package. private void doEnterPackage(ModuleSymbol msym, PackageSymbol pack) {
*/ packages.computeIfAbsent(pack.fullname, n -> new HashMap<>()).put(msym, pack);
public PackageSymbol enterPackage(Name name, PackageSymbol owner) { msym.enclosedPackages = msym.enclosedPackages.prepend(pack);
return enterPackage(TypeSymbol.formFullName(name, owner)); }
private void addRootPackageFor(ModuleSymbol module) {
doEnterPackage(module, rootPackage);
PackageSymbol unnamedPackage = new PackageSymbol(names.empty, rootPackage) {
@Override
public String toString() {
return messages.getLocalizedString("compiler.misc.unnamed.package");
}
};
unnamedPackage.modle = module;
unnamedPackage.completer = sym -> initialCompleter.complete(sym);
module.unnamedPackage = unnamedPackage;
}
public PackageSymbol getPackage(ModuleSymbol module, Name fullname) {
return packages.getOrDefault(fullname, Collections.emptyMap()).get(module);
}
public ModuleSymbol enterModule(Name name) {
ModuleSymbol msym = modules.get(name);
if (msym == null) {
msym = ModuleSymbol.create(name, names.module_info);
addRootPackageFor(msym);
msym.completer = sym -> moduleCompleter.complete(sym); //bootstrap issues
modules.put(name, msym);
}
return msym;
}
public void enterModule(ModuleSymbol msym, Name name) {
Assert.checkNull(modules.get(name));
Assert.checkNull(msym.name);
msym.name = name;
addRootPackageFor(msym);
ClassSymbol info = msym.module_info;
info.fullname = msym.name.append('.', names.module_info);
info.flatname = info.fullname;
modules.put(name, msym);
}
public ModuleSymbol getModule(Name name) {
return modules.get(name);
}
//temporary:
public ModuleSymbol inferModule(Name packageName) {
if (packageName.isEmpty())
return java_base == noModule ? noModule : unnamedModule;//!
ModuleSymbol msym = null;
Map<ModuleSymbol,PackageSymbol> map = packages.get(packageName);
if (map == null)
return null;
for (Map.Entry<ModuleSymbol,PackageSymbol> e: map.entrySet()) {
if (!e.getValue().members().isEmpty()) {
if (msym == null) {
msym = e.getKey();
} else {
return null;
}
}
}
return msym;
}
public List<ModuleSymbol> listPackageModules(Name packageName) {
if (packageName.isEmpty())
return List.nil();
List<ModuleSymbol> result = List.nil();
Map<ModuleSymbol,PackageSymbol> map = packages.get(packageName);
if (map != null) {
for (Map.Entry<ModuleSymbol, PackageSymbol> e: map.entrySet()) {
if (!e.getValue().members().isEmpty()) {
result = result.prepend(e.getKey());
}
}
}
return result;
}
public Collection<ModuleSymbol> getAllModules() {
return modules.values();
} }
} }

View File

@ -1525,7 +1525,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public static class PackageType extends Type implements NoType { public static class PackageType extends Type implements NoType {
PackageType(TypeSymbol tsym) { PackageType(PackageSymbol tsym) {
// Package types cannot be annotated // Package types cannot be annotated
super(tsym, TypeMetadata.EMPTY); super(tsym, TypeMetadata.EMPTY);
} }
@ -1561,6 +1561,49 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
} }
} }
public static class ModuleType extends Type implements NoType {
ModuleType(ModuleSymbol tsym) {
// Module types cannot be annotated
super(tsym, TypeMetadata.EMPTY);
}
@Override
public ModuleType cloneWithMetadata(TypeMetadata md) {
throw new AssertionError("Cannot add metadata to a module type");
}
@Override
public ModuleType annotatedType(List<Attribute.TypeCompound> annos) {
throw new AssertionError("Cannot annotate a module type");
}
@Override
public TypeTag getTag() {
return TypeTag.MODULE;
}
@Override
public <R,S> R accept(Type.Visitor<R,S> v, S s) {
return v.visitModuleType(this, s);
}
@Override
public String toString() {
return tsym.getQualifiedName().toString();
}
@Override
public TypeKind getKind() {
return TypeKind.MODULE;
}
@Override
public <R, P> R accept(TypeVisitor<R, P> v, P p) {
return v.visitNoType(this, p);
}
}
public static class TypeVar extends Type implements TypeVariable { public static class TypeVar extends Type implements TypeVariable {
/** The upper bound of this type variable; set from outside. /** The upper bound of this type variable; set from outside.
@ -2384,6 +2427,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
R visitArrayType(ArrayType t, S s); R visitArrayType(ArrayType t, S s);
R visitMethodType(MethodType t, S s); R visitMethodType(MethodType t, S s);
R visitPackageType(PackageType t, S s); R visitPackageType(PackageType t, S s);
R visitModuleType(ModuleType t, S s);
R visitTypeVar(TypeVar t, S s); R visitTypeVar(TypeVar t, S s);
R visitCapturedType(CapturedType t, S s); R visitCapturedType(CapturedType t, S s);
R visitForAll(ForAll t, S s); R visitForAll(ForAll t, S s);

View File

@ -49,6 +49,7 @@ import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry;
import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind; import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind;
import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Type.ModuleType;
import com.sun.tools.javac.code.TypeMetadata.Entry.Kind; import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
import com.sun.tools.javac.comp.Annotate; import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.comp.Attr; import com.sun.tools.javac.comp.Attr;
@ -651,6 +652,11 @@ public class TypeAnnotations {
return t.annotatedType(s); return t.annotatedType(s);
} }
@Override
public Type visitModuleType(ModuleType t, List<TypeCompound> s) {
return t.annotatedType(s);
}
@Override @Override
public Type visitCapturedType(CapturedType t, List<TypeCompound> s) { public Type visitCapturedType(CapturedType t, List<TypeCompound> s) {
return t.annotatedType(s); return t.annotatedType(s);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -89,6 +89,10 @@ public enum TypeTag {
*/ */
PACKAGE, PACKAGE,
/** The tag of all module "types".
*/
MODULE,
/** The tag of all (source-level) type variables. /** The tag of all (source-level) type variables.
*/ */
TYPEVAR, TYPEVAR,

View File

@ -3938,7 +3938,7 @@ public class Types {
* Return the class that boxes the given primitive. * Return the class that boxes the given primitive.
*/ */
public ClassSymbol boxedClass(Type t) { public ClassSymbol boxedClass(Type t) {
return syms.enterClass(syms.boxedName[t.getTag().ordinal()]); return syms.enterClass(syms.java_base, syms.boxedName[t.getTag().ordinal()]);
} }
/** /**
@ -3957,7 +3957,7 @@ public class Types {
for (int i=0; i<syms.boxedName.length; i++) { for (int i=0; i<syms.boxedName.length; i++) {
Name box = syms.boxedName[i]; Name box = syms.boxedName[i];
if (box != null && if (box != null &&
asSuper(t, syms.enterClass(box)) != null) asSuper(t, syms.enterClass(syms.java_base, box)) != null)
return syms.typeOfTag[i]; return syms.typeOfTag[i];
} }
return Type.noType; return Type.noType;
@ -4536,6 +4536,7 @@ public class Types {
public R visitArrayType(ArrayType t, S s) { return visitType(t, s); } public R visitArrayType(ArrayType t, S s) { return visitType(t, s); }
public R visitMethodType(MethodType t, S s) { return visitType(t, s); } public R visitMethodType(MethodType t, S s) { return visitType(t, s); }
public R visitPackageType(PackageType t, S s) { return visitType(t, s); } public R visitPackageType(PackageType t, S s) { return visitType(t, s); }
public R visitModuleType(ModuleType t, S s) { return visitType(t, s); }
public R visitTypeVar(TypeVar t, S s) { return visitType(t, s); } public R visitTypeVar(TypeVar t, S s) { return visitType(t, s); }
public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); } public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); }
public R visitForAll(ForAll t, S s) { return visitType(t, s); } public R visitForAll(ForAll t, S s) { return visitType(t, s); }

View File

@ -36,6 +36,7 @@ import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.TreeVisitor; import com.sun.source.tree.TreeVisitor;
import com.sun.source.util.SimpleTreeVisitor; import com.sun.source.util.SimpleTreeVisitor;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Directive.RequiresFlag;
import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Scope.WriteableScope; import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
@ -60,6 +61,7 @@ import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.JCDiagnostic.Fragment; import com.sun.tools.javac.util.JCDiagnostic.Fragment;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Flags.ANNOTATION; import static com.sun.tools.javac.code.Flags.ANNOTATION;
import static com.sun.tools.javac.code.Flags.BLOCK; import static com.sun.tools.javac.code.Flags.BLOCK;
@ -332,7 +334,15 @@ public class Attr extends JCTree.Visitor {
syms.errSymbol.name, syms.errSymbol.name,
null, null, null, null); null, null, null, null);
localEnv.enclClass.sym = syms.errSymbol; localEnv.enclClass.sym = syms.errSymbol;
return tree.accept(identAttributer, localEnv); return attribIdent(tree, localEnv);
}
/** Attribute a parsed identifier.
* @param tree Parsed identifier name
* @param env The env to use
*/
public Symbol attribIdent(JCTree tree, Env<AttrContext> env) {
return tree.accept(identAttributer, env);
} }
// where // where
private TreeVisitor<Symbol,Env<AttrContext>> identAttributer = new IdentAttributer(); private TreeVisitor<Symbol,Env<AttrContext>> identAttributer = new IdentAttributer();
@ -4238,13 +4248,19 @@ public class Attr extends JCTree.Visitor {
} }
/** /**
* Attribute an env for either a top level tree or class declaration. * Attribute an env for either a top level tree or class or module declaration.
*/ */
public void attrib(Env<AttrContext> env) { public void attrib(Env<AttrContext> env) {
if (env.tree.hasTag(TOPLEVEL)) switch (env.tree.getTag()) {
attribTopLevel(env); case MODULEDEF:
else attribModule(env.tree.pos(), ((JCModuleDecl)env.tree).sym);
attribClass(env.tree.pos(), env.enclClass.sym); break;
case TOPLEVEL:
attribTopLevel(env);
break;
default:
attribClass(env.tree.pos(), env.enclClass.sym);
}
} }
/** /**
@ -4260,6 +4276,21 @@ public class Attr extends JCTree.Visitor {
} }
} }
public void attribModule(DiagnosticPosition pos, ModuleSymbol m) {
try {
annotate.flush();
attribModule(m);
} catch (CompletionFailure ex) {
chk.completionError(pos, ex);
}
}
void attribModule(ModuleSymbol m) {
// Get environment current at the point of module definition.
Env<AttrContext> env = enter.typeEnvs.get(m);
attribStat(env.tree, env);
}
/** Main method: attribute class definition associated with given class symbol. /** Main method: attribute class definition associated with given class symbol.
* reporting completion failures at the given position. * reporting completion failures at the given position.
* @param pos The source position at which completion errors are to be * @param pos The source position at which completion errors are to be
@ -4358,6 +4389,10 @@ public class Attr extends JCTree.Visitor {
// nothing to do // nothing to do
} }
public void visitModuleDef(JCModuleDecl tree) {
tree.sym.completeUsesProvides();
}
/** Finish the attribution of a class. */ /** Finish the attribution of a class. */
private void attribClassBody(Env<AttrContext> env, ClassSymbol c) { private void attribClassBody(Env<AttrContext> env, ClassSymbol c) {
JCClassDecl tree = (JCClassDecl)env.tree; JCClassDecl tree = (JCClassDecl)env.tree;
@ -4929,4 +4964,22 @@ public class Attr extends JCTree.Visitor {
} }
} }
// </editor-fold> // </editor-fold>
public void setPackageSymbols(JCExpression pid, Symbol pkg) {
new TreeScanner() {
Symbol packge = pkg;
@Override
public void visitIdent(JCIdent that) {
that.sym = packge;
}
@Override
public void visitSelect(JCFieldAccess that) {
that.sym = packge;
packge = packge.owner;
super.visitSelect(that);
}
}.scan(pid);
}
} }

View File

@ -173,10 +173,10 @@ public class Check {
*/ */
char syntheticNameChar; char syntheticNameChar;
/** A table mapping flat names of all compiled classes in this run to their /** A table mapping flat names of all compiled classes for each module in this run
* symbols; maintained from outside. * to their symbols; maintained from outside.
*/ */
public Map<Name,ClassSymbol> compiled = new HashMap<>(); private Map<Pair<ModuleSymbol, Name>,ClassSymbol> compiled = new HashMap<>();
/** A handler for messages about deprecated usage. /** A handler for messages about deprecated usage.
*/ */
@ -404,7 +404,7 @@ public class Check {
for (int i = (index == null) ? 1 : index; ; i++) { for (int i = (index == null) ? 1 : index; ; i++) {
Name flatname = names.fromString(enclFlatnameStr Name flatname = names.fromString(enclFlatnameStr
+ syntheticNameChar + i + c.name); + syntheticNameChar + i + c.name);
if (compiled.get(flatname) == null) { if (getCompiled(c.packge().modle, flatname) == null) {
localClassNameIndexes.put(key, i + 1); localClassNameIndexes.put(key, i + 1);
return flatname; return flatname;
} }
@ -421,6 +421,22 @@ public class Check {
localClassNameIndexes.clear(); localClassNameIndexes.clear();
} }
public void putCompiled(ClassSymbol csym) {
compiled.put(Pair.of(csym.packge().modle, csym.flatname), csym);
}
public ClassSymbol getCompiled(ClassSymbol csym) {
return compiled.get(Pair.of(csym.packge().modle, csym.flatname));
}
public ClassSymbol getCompiled(ModuleSymbol msym, Name flatname) {
return compiled.get(Pair.of(msym, flatname));
}
public void removeCompiled(ClassSymbol csym) {
compiled.remove(Pair.of(csym.packge().modle, csym.flatname));
}
/* ************************************************************************* /* *************************************************************************
* Type Checking * Type Checking
**************************************************************************/ **************************************************************************/
@ -3473,7 +3489,7 @@ public class Check {
private boolean isCanonical(JCTree tree) { private boolean isCanonical(JCTree tree) {
while (tree.hasTag(SELECT)) { while (tree.hasTag(SELECT)) {
JCFieldAccess s = (JCFieldAccess) tree; JCFieldAccess s = (JCFieldAccess) tree;
if (s.sym.owner != TreeInfo.symbol(s.selected)) if (s.sym.owner.name != TreeInfo.symbol(s.selected).name)
return false; return false;
tree = s.selected; tree = s.selected;
} }
@ -3576,9 +3592,19 @@ public class Check {
// Check that packages imported are in scope (JLS 7.4.3, 6.3, 6.5.3.1, 6.5.3.2) // Check that packages imported are in scope (JLS 7.4.3, 6.3, 6.5.3.1, 6.5.3.2)
public void checkImportedPackagesObservable(final JCCompilationUnit toplevel) { public void checkImportedPackagesObservable(final JCCompilationUnit toplevel) {
for (JCImport imp : toplevel.getImports()) { OUTER: for (JCImport imp : toplevel.getImports()) {
if (!imp.staticImport && TreeInfo.name(imp.qualid) == names.asterisk) { if (!imp.staticImport && TreeInfo.name(imp.qualid) == names.asterisk) {
TypeSymbol tsym = ((JCFieldAccess)imp.qualid).selected.type.tsym; TypeSymbol tsym = ((JCFieldAccess)imp.qualid).selected.type.tsym;
if (toplevel.modle.visiblePackages != null) {
//TODO - unclear: selects like javax.* will get resolved from the current module
//(as javax is not an exported package from any module). And as javax in the current
//module typically does not contain any classes or subpackages, we need to go through
//the visible packages to find a sub-package:
for (PackageSymbol known : toplevel.modle.visiblePackages.values()) {
if (Convert.packagePart(known.fullname) == tsym.flatName())
continue OUTER;
}
}
if (tsym.kind == PCK && tsym.members().isEmpty() && !tsym.exists()) { if (tsym.kind == PCK && tsym.members().isEmpty() && !tsym.exists()) {
log.error(DiagnosticFlag.RESOLVE_ERROR, imp.pos, "doesnt.exist", tsym); log.error(DiagnosticFlag.RESOLVE_ERROR, imp.pos, "doesnt.exist", tsym);
} }

View File

@ -452,17 +452,21 @@ public class DeferredAttr extends JCTree.Visitor {
Log.DeferredDiagnosticHandler deferredDiagnosticHandler = diagHandlerCreator.apply(newTree); Log.DeferredDiagnosticHandler deferredDiagnosticHandler = diagHandlerCreator.apply(newTree);
try { try {
attr.attribTree(newTree, speculativeEnv, resultInfo); attr.attribTree(newTree, speculativeEnv, resultInfo);
unenterScanner.scan(newTree);
return newTree; return newTree;
} finally { } finally {
unenterScanner.scan(newTree); new UnenterScanner(env.toplevel.modle).scan(newTree);
log.popDiagnosticHandler(deferredDiagnosticHandler); log.popDiagnosticHandler(deferredDiagnosticHandler);
} }
} }
//where //where
protected UnenterScanner unenterScanner = new UnenterScanner();
class UnenterScanner extends TreeScanner { class UnenterScanner extends TreeScanner {
private final ModuleSymbol msym;
public UnenterScanner(ModuleSymbol msym) {
this.msym = msym;
}
@Override @Override
public void visitClassDef(JCClassDecl tree) { public void visitClassDef(JCClassDecl tree) {
ClassSymbol csym = tree.sym; ClassSymbol csym = tree.sym;
@ -471,9 +475,9 @@ public class DeferredAttr extends JCTree.Visitor {
//are left unchecked - in such cases there's nothing to clean up. //are left unchecked - in such cases there's nothing to clean up.
if (csym == null) return; if (csym == null) return;
typeEnvs.remove(csym); typeEnvs.remove(csym);
chk.compiled.remove(csym.flatname); chk.removeCompiled(csym);
chk.clearLocalClassNameIndexes(csym); chk.clearLocalClassNameIndexes(csym);
syms.classes.remove(csym.flatname); syms.removeClass(msym, csym.flatname);
super.visitClassDef(tree); super.visitClassDef(tree);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,9 @@
package com.sun.tools.javac.comp; package com.sun.tools.javac.comp;
import java.util.Map;
import java.util.Optional;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
@ -34,13 +37,13 @@ import com.sun.tools.javac.code.Scope.*;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.main.Option.PkgInfo; import com.sun.tools.javac.main.Option.PkgInfo;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.Kind.*; import static com.sun.tools.javac.code.Kinds.Kind.*;
@ -97,6 +100,8 @@ public class Enter extends JCTree.Visitor {
JavaFileManager fileManager; JavaFileManager fileManager;
PkgInfo pkginfoOpt; PkgInfo pkginfoOpt;
TypeEnvs typeEnvs; TypeEnvs typeEnvs;
Modules modules;
JCDiagnostic.Factory diags;
private final Todo todo; private final Todo todo;
@ -119,6 +124,8 @@ public class Enter extends JCTree.Visitor {
annotate = Annotate.instance(context); annotate = Annotate.instance(context);
lint = Lint.instance(context); lint = Lint.instance(context);
names = Names.instance(context); names = Names.instance(context);
modules = Modules.instance(context);
diags = JCDiagnostic.Factory.instance(context);
predefClassDef = make.ClassDef( predefClassDef = make.ClassDef(
make.Modifiers(PUBLIC), make.Modifiers(PUBLIC),
@ -229,6 +236,24 @@ public class Enter extends JCTree.Visitor {
: env.info.scope; : env.info.scope;
} }
/** Create a fresh environment for modules.
*
* @param tree The module definition.
* @param env The environment current outside of the module definition.
*/
public Env<AttrContext> moduleEnv(JCModuleDecl tree, Env<AttrContext> env) {
Assert.checkNonNull(tree.sym);
Env<AttrContext> localEnv =
env.dup(tree, env.info.dup(WriteableScope.create(tree.sym)));
localEnv.enclClass = predefClassDef;
localEnv.outer = env;
localEnv.info.isSelfCall = false;
localEnv.info.lint = null; // leave this to be filled in by Attr,
// when annotations have been processed
return localEnv;
}
/* ************************************************************************ /* ************************************************************************
* Visitor methods for phase 1: class enter * Visitor methods for phase 1: class enter
*************************************************************************/ *************************************************************************/
@ -276,57 +301,80 @@ public class Enter extends JCTree.Visitor {
@Override @Override
public void visitTopLevel(JCCompilationUnit tree) { public void visitTopLevel(JCCompilationUnit tree) {
// Assert.checkNonNull(tree.modle, tree.sourcefile.toString());
JavaFileObject prev = log.useSource(tree.sourcefile); JavaFileObject prev = log.useSource(tree.sourcefile);
boolean addEnv = false; boolean addEnv = false;
boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info", boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info",
JavaFileObject.Kind.SOURCE); JavaFileObject.Kind.SOURCE);
JCPackageDecl pd = tree.getPackage(); if (TreeInfo.isModuleInfo(tree)) {
if (pd != null) { tree.packge = syms.rootPackage;
tree.packge = pd.packge = syms.enterPackage(TreeInfo.fullName(pd.pid)); Env<AttrContext> topEnv = topLevelEnv(tree);
if ( pd.annotations.nonEmpty() classEnter(tree.defs, topEnv);
|| pkginfoOpt == PkgInfo.ALWAYS tree.modle.usesProvidesCompleter = modules.getUsesProvidesCompleter();
|| tree.docComments != null) {
if (isPkgInfo) {
addEnv = true;
} else if (pd.annotations.nonEmpty()) {
log.error(pd.annotations.head.pos(),
"pkg.annotations.sb.in.package-info.java");
}
}
} else { } else {
tree.packge = syms.unnamedPackage; JCPackageDecl pd = tree.getPackage();
} if (pd != null) {
tree.packge.complete(); // Find all classes in package. tree.packge = pd.packge = syms.enterPackage(tree.modle, TreeInfo.fullName(pd.pid));
Env<AttrContext> topEnv = topLevelEnv(tree); if ( pd.annotations.nonEmpty()
Env<AttrContext> packageEnv = isPkgInfo ? topEnv.dup(pd) : null; || pkginfoOpt == PkgInfo.ALWAYS
|| tree.docComments != null) {
// Save environment of package-info.java file. if (isPkgInfo) {
if (isPkgInfo) { addEnv = true;
Env<AttrContext> env0 = typeEnvs.get(tree.packge); } else if (pd.annotations.nonEmpty()) {
if (env0 != null) { log.error(pd.annotations.head.pos(),
JCCompilationUnit tree0 = env0.toplevel; "pkg.annotations.sb.in.package-info.java");
if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) { }
log.warning(pd != null ? pd.pid.pos() : null,
"pkg-info.already.seen",
tree.packge);
} }
} else {
tree.packge = tree.modle.unnamedPackage;
} }
typeEnvs.put(tree.packge, packageEnv);
for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner) Map<Name, PackageSymbol> visiblePackages = tree.modle.visiblePackages;
q.flags_field |= EXISTS; Optional<ModuleSymbol> dependencyWithPackage =
syms.listPackageModules(tree.packge.fullname)
.stream()
.filter(m -> m != tree.modle)
.filter(cand -> visiblePackages.get(tree.packge.fullname) == syms.getPackage(cand, tree.packge.fullname))
.findAny();
Name name = names.package_info; if (dependencyWithPackage.isPresent()) {
ClassSymbol c = syms.enterClass(name, tree.packge); log.error(pd, Errors.PackageInOtherModule(dependencyWithPackage.get()));
c.flatname = names.fromString(tree.packge + "." + name); }
c.sourcefile = tree.sourcefile;
tree.packge.complete(); // Find all classes in package.
Env<AttrContext> topEnv = topLevelEnv(tree);
Env<AttrContext> packageEnv = isPkgInfo ? topEnv.dup(pd) : null;
// Save environment of package-info.java file.
if (isPkgInfo) {
Env<AttrContext> env0 = typeEnvs.get(tree.packge);
if (env0 != null) {
JCCompilationUnit tree0 = env0.toplevel;
if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
log.warning(pd != null ? pd.pid.pos() : null,
"pkg-info.already.seen",
tree.packge);
}
}
typeEnvs.put(tree.packge, packageEnv);
for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner)
q.flags_field |= EXISTS;
Name name = names.package_info;
ClassSymbol c = syms.enterClass(tree.modle, name, tree.packge);
c.flatname = names.fromString(tree.packge + "." + name);
c.sourcefile = tree.sourcefile;
c.completer = Completer.NULL_COMPLETER; c.completer = Completer.NULL_COMPLETER;
c.members_field = WriteableScope.create(c); c.members_field = WriteableScope.create(c);
tree.packge.package_info = c; tree.packge.package_info = c;
} }
classEnter(tree.defs, topEnv); classEnter(tree.defs, topEnv);
if (addEnv) { if (addEnv) {
todo.append(packageEnv); todo.append(packageEnv);
}
} }
log.useSource(prev); log.useSource(prev);
result = null; result = null;
@ -342,7 +390,7 @@ public class Enter extends JCTree.Visitor {
PackageSymbol packge = (PackageSymbol)owner; PackageSymbol packge = (PackageSymbol)owner;
for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner) for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner)
q.flags_field |= EXISTS; q.flags_field |= EXISTS;
c = syms.enterClass(tree.name, packge); c = syms.enterClass(env.toplevel.modle, tree.name, packge);
packge.members().enterIfAbsent(c); packge.members().enterIfAbsent(c);
if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) { if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) {
log.error(tree.pos(), log.error(tree.pos(),
@ -356,7 +404,7 @@ public class Enter extends JCTree.Visitor {
} }
if (owner.kind == TYP) { if (owner.kind == TYP) {
// We are seeing a member class. // We are seeing a member class.
c = syms.enterClass(tree.name, (TypeSymbol)owner); c = syms.enterClass(env.toplevel.modle, tree.name, (TypeSymbol)owner);
if ((owner.flags_field & INTERFACE) != 0) { if ((owner.flags_field & INTERFACE) != 0) {
tree.mods.flags |= PUBLIC | STATIC; tree.mods.flags |= PUBLIC | STATIC;
} }
@ -371,13 +419,13 @@ public class Enter extends JCTree.Visitor {
tree.sym = c; tree.sym = c;
// Enter class into `compiled' table and enclosing scope. // Enter class into `compiled' table and enclosing scope.
if (chk.compiled.get(c.flatname) != null) { if (chk.getCompiled(c) != null) {
duplicateClass(tree.pos(), c); duplicateClass(tree.pos(), c);
result = types.createErrorType(tree.name, (TypeSymbol)owner, Type.noType); result = types.createErrorType(tree.name, (TypeSymbol)owner, Type.noType);
tree.sym = (ClassSymbol)result.tsym; tree.sym = (ClassSymbol)result.tsym;
return; return;
} }
chk.compiled.put(c.flatname, c); chk.putCompiled(c);
enclScope.enter(c); enclScope.enter(c);
// Set up an environment for class block and store in `typeEnvs' // Set up an environment for class block and store in `typeEnvs'
@ -421,6 +469,8 @@ public class Enter extends JCTree.Visitor {
// Recursively enter all member classes. // Recursively enter all member classes.
classEnter(tree.defs, localEnv); classEnter(tree.defs, localEnv);
// Assert.checkNonNull(c.modle, c.sourcefile.toString());
result = c.type; result = c.type;
} }
//where //where
@ -453,6 +503,13 @@ public class Enter extends JCTree.Visitor {
result = a; result = a;
} }
@Override
public void visitModuleDef(JCModuleDecl tree) {
Env<AttrContext> moduleEnv = moduleEnv(tree, env);
typeEnvs.put(tree.sym, moduleEnv);
todo.append(moduleEnv);
}
/** Default class enter visitor method: do nothing. /** Default class enter visitor method: do nothing.
*/ */
@Override @Override

View File

@ -743,6 +743,10 @@ public class Flow {
} }
} }
public void visitModuleDef(JCModuleDecl tree) {
// Do nothing for modules
}
/************************************************************************** /**************************************************************************
* main method * main method
*************************************************************************/ *************************************************************************/
@ -1305,6 +1309,10 @@ public class Flow {
} }
} }
public void visitModuleDef(JCModuleDecl tree) {
// Do nothing for modules
}
/************************************************************************** /**************************************************************************
* main method * main method
*************************************************************************/ *************************************************************************/
@ -2416,6 +2424,10 @@ public class Flow {
tree.underlyingType.accept(this); tree.underlyingType.accept(this);
} }
public void visitModuleDef(JCModuleDecl tree) {
// Do nothing for modules
}
/************************************************************************** /**************************************************************************
* main method * main method
*************************************************************************/ *************************************************************************/
@ -2605,6 +2617,10 @@ public class Flow {
super.visitTry(tree); super.visitTry(tree);
} }
public void visitModuleDef(JCModuleDecl tree) {
// Do nothing for modules
}
/************************************************************************** /**************************************************************************
* main method * main method
*************************************************************************/ *************************************************************************/

View File

@ -652,7 +652,7 @@ public class Lower extends TreeTranslator {
// Enter class symbol in owner scope and compiled table. // Enter class symbol in owner scope and compiled table.
enterSynthetic(odef.pos(), c, owner.members()); enterSynthetic(odef.pos(), c, owner.members());
chk.compiled.put(c.flatname, c); chk.putCompiled(c);
// Create class definition tree. // Create class definition tree.
JCClassDecl cdef = make.ClassDef( JCClassDecl cdef = make.ClassDef(
@ -1286,10 +1286,11 @@ public class Lower extends TreeTranslator {
*/ */
ClassSymbol accessConstructorTag() { ClassSymbol accessConstructorTag() {
ClassSymbol topClass = currentClass.outermostClass(); ClassSymbol topClass = currentClass.outermostClass();
ModuleSymbol topModle = topClass.packge().modle;
Name flatname = names.fromString("" + topClass.getQualifiedName() + Name flatname = names.fromString("" + topClass.getQualifiedName() +
target.syntheticNameChar() + target.syntheticNameChar() +
"1"); "1");
ClassSymbol ctag = chk.compiled.get(flatname); ClassSymbol ctag = chk.getCompiled(topModle, flatname);
if (ctag == null) if (ctag == null)
ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass).sym; ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass).sym;
// keep a record of all tags, to verify that all are generated as required // keep a record of all tags, to verify that all are generated as required
@ -2342,25 +2343,18 @@ public class Lower extends TreeTranslator {
public void visitPackageDef(JCPackageDecl tree) { public void visitPackageDef(JCPackageDecl tree) {
if (!needPackageInfoClass(tree)) if (!needPackageInfoClass(tree))
return; return;
Name name = names.package_info;
long flags = Flags.ABSTRACT | Flags.INTERFACE; long flags = Flags.ABSTRACT | Flags.INTERFACE;
// package-info is marked SYNTHETIC in JDK 1.6 and later releases // package-info is marked SYNTHETIC in JDK 1.6 and later releases
flags = flags | Flags.SYNTHETIC; flags = flags | Flags.SYNTHETIC;
JCClassDecl packageAnnotationsClass
= make.ClassDef(make.Modifiers(flags, tree.getAnnotations()),
name, List.<JCTypeParameter>nil(),
null, List.<JCExpression>nil(), List.<JCTree>nil());
ClassSymbol c = tree.packge.package_info; ClassSymbol c = tree.packge.package_info;
c.flags_field |= flags;
c.setAttributes(tree.packge); c.setAttributes(tree.packge);
c.flags_field |= flags;
ClassType ctype = (ClassType) c.type; ClassType ctype = (ClassType) c.type;
ctype.supertype_field = syms.objectType; ctype.supertype_field = syms.objectType;
ctype.interfaces_field = List.nil(); ctype.interfaces_field = List.nil();
packageAnnotationsClass.sym = c; createInfoClass(tree.annotations, c);
translated.append(packageAnnotationsClass);
} }
// where // where
private boolean needPackageInfoClass(JCPackageDecl pd) { private boolean needPackageInfoClass(JCPackageDecl pd) {
@ -2381,6 +2375,23 @@ public class Lower extends TreeTranslator {
throw new AssertionError(); throw new AssertionError();
} }
public void visitModuleDef(JCModuleDecl tree) {
ModuleSymbol msym = tree.sym;
ClassSymbol c = msym.module_info;
c.flags_field |= Flags.MODULE;
createInfoClass(List.<JCAnnotation>nil(), tree.sym.module_info);
}
private void createInfoClass(List<JCAnnotation> annots, ClassSymbol c) {
long flags = Flags.ABSTRACT | Flags.INTERFACE;
JCClassDecl infoClass =
make.ClassDef(make.Modifiers(flags, annots),
c.name, List.<JCTypeParameter>nil(),
null, List.<JCExpression>nil(), List.<JCTree>nil());
infoClass.sym = c;
translated.append(infoClass);
}
public void visitClassDef(JCClassDecl tree) { public void visitClassDef(JCClassDecl tree) {
Env<AttrContext> prevEnv = attrEnv; Env<AttrContext> prevEnv = attrEnv;
ClassSymbol currentClassPrev = currentClass; ClassSymbol currentClassPrev = currentClass;

File diff suppressed because it is too large Load Diff

View File

@ -93,10 +93,13 @@ public class Resolve {
JCDiagnostic.Factory diags; JCDiagnostic.Factory diags;
public final boolean allowMethodHandles; public final boolean allowMethodHandles;
public final boolean allowFunctionalInterfaceMostSpecific; public final boolean allowFunctionalInterfaceMostSpecific;
public final boolean allowModules;
public final boolean checkVarargsAccessAfterResolution; public final boolean checkVarargsAccessAfterResolution;
private final boolean compactMethodDiags; private final boolean compactMethodDiags;
final EnumSet<VerboseResolutionMode> verboseResolutionMode; final EnumSet<VerboseResolutionMode> verboseResolutionMode;
private final boolean checkModuleAccess;
WriteableScope polymorphicSignatureScope; WriteableScope polymorphicSignatureScope;
protected Resolve(Context context) { protected Resolve(Context context) {
@ -130,6 +133,12 @@ public class Resolve {
polymorphicSignatureScope = WriteableScope.create(syms.noSymbol); polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
inapplicableMethodException = new InapplicableMethodException(diags); inapplicableMethodException = new InapplicableMethodException(diags);
allowModules = source.allowModules();
// The following is required, for now, to support building
// Swing beaninfo via javadoc.
checkModuleAccess = !options.isSet("noModules");
} }
/** error symbols, which are returned when resolution fails /** error symbols, which are returned when resolution fails
@ -309,8 +318,19 @@ public class Resolve {
env.toplevel.packge == c.packge(); env.toplevel.packge == c.packge();
break; break;
default: // error recovery default: // error recovery
isAccessible = true;
break;
case PUBLIC: case PUBLIC:
isAccessible = true; isAccessible = true;
if (allowModules && checkModuleAccess) {
ModuleSymbol currModule = env.toplevel.modle;
currModule.complete();
PackageSymbol p = c.packge();
isAccessible =
(currModule == p.modle) || currModule.visiblePackages.get(p.fullname) == p || p == syms.rootPackage;
} else {
isAccessible = true;
}
break; break;
case PROTECTED: case PROTECTED:
isAccessible = isAccessible =
@ -1947,16 +1967,27 @@ public class Resolve {
*/ */
Symbol loadClass(Env<AttrContext> env, Name name) { Symbol loadClass(Env<AttrContext> env, Name name) {
try { try {
ClassSymbol c = finder.loadClass(name); ClassSymbol c = finder.loadClass(env.toplevel.modle, name);
return isAccessible(env, c) ? c : new AccessError(c); return isAccessible(env, c) ? c : new AccessError(c);
} catch (ClassFinder.BadClassFile err) { } catch (ClassFinder.BadClassFile err) {
throw err; throw err;
} catch (CompletionFailure ex) { } catch (CompletionFailure ex) {
//even if a class cannot be found in the current module and packages in modules it depends on that
//are exported for any or this module, the class may exist internally in some of these modules,
//or may exist in a module on which this module does not depend. Provide better diagnostic in
//such cases by looking for the class in any module:
for (ModuleSymbol ms : syms.getAllModules()) {
//do not load currently unloaded classes, to avoid too eager completion of random things in other modules:
ClassSymbol clazz = syms.getClass(ms, name);
if (clazz != null) {
return new AccessError(clazz);
}
}
return typeNotFound; return typeNotFound;
} }
} }
/** /**
* Find a type declared in a scope (not inherited). Return null * Find a type declared in a scope (not inherited). Return null
* if none is found. * if none is found.
@ -2157,7 +2188,7 @@ public class Resolve {
} }
if (kind.contains(KindSelector.PCK)) if (kind.contains(KindSelector.PCK))
return syms.enterPackage(name); return syms.lookupPackage(env.toplevel.modle, name);
else return bestSoFar; else return bestSoFar;
} }
@ -2173,7 +2204,7 @@ public class Resolve {
Symbol bestSoFar = typeNotFound; Symbol bestSoFar = typeNotFound;
PackageSymbol pack = null; PackageSymbol pack = null;
if (kind.contains(KindSelector.PCK)) { if (kind.contains(KindSelector.PCK)) {
pack = syms.enterPackage(fullname); pack = syms.lookupPackage(env.toplevel.modle, fullname);
if (pack.exists()) return pack; if (pack.exists()) return pack;
} }
if (kind.contains(KindSelector.TYP)) { if (kind.contains(KindSelector.TYP)) {
@ -3920,9 +3951,15 @@ public class Resolve {
else if ((sym.flags() & PUBLIC) != 0 else if ((sym.flags() & PUBLIC) != 0
|| (env != null && this.site != null || (env != null && this.site != null
&& !isAccessible(env, this.site))) { && !isAccessible(env, this.site))) {
return diags.create(dkind, log.currentSource(), if (sym.owner.kind == PCK) {
pos, "not.def.access.class.intf.cant.access", return diags.create(dkind, log.currentSource(),
sym, sym.location()); pos, "not.def.access.package.cant.access",
sym, sym.location());
} else {
return diags.create(dkind, log.currentSource(),
pos, "not.def.access.class.intf.cant.access",
sym, sym.location());
}
} }
else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) { else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
return diags.create(dkind, log.currentSource(), return diags.create(dkind, log.currentSource(),
@ -3935,6 +3972,18 @@ public class Resolve {
pos, "not.def.public.cant.access", sym, sym.location()); pos, "not.def.public.cant.access", sym, sym.location());
} }
} }
private String toString(Type type) {
StringBuilder sb = new StringBuilder();
sb.append(type);
if (type != null) {
sb.append("[tsym:").append(type.tsym);
if (type.tsym != null)
sb.append("packge:").append(type.tsym.packge());
sb.append("]");
}
return sb.toString();
}
} }
/** /**

View File

@ -162,6 +162,8 @@ public class TypeEnter implements Completer {
// if there remain any unimported toplevels (these must have // if there remain any unimported toplevels (these must have
// no classes at all), process their import statements as well. // no classes at all), process their import statements as well.
for (JCCompilationUnit tree : trees) { for (JCCompilationUnit tree : trees) {
if (tree.defs.nonEmpty() && tree.defs.head.hasTag(MODULEDEF))
continue;
if (!tree.starImportScope.isFilled()) { if (!tree.starImportScope.isFilled()) {
Env<AttrContext> topEnv = enter.topLevelEnv(tree); Env<AttrContext> topEnv = enter.topLevelEnv(tree);
finishImports(tree, () -> { completeClass.resolveImports(tree, topEnv); }); finishImports(tree, () -> { completeClass.resolveImports(tree, topEnv); });
@ -330,7 +332,7 @@ public class TypeEnter implements Completer {
chk.importAccessible(sym, packge); chk.importAccessible(sym, packge);
// Import-on-demand java.lang. // Import-on-demand java.lang.
PackageSymbol javaLang = syms.enterPackage(names.java_lang); PackageSymbol javaLang = syms.enterPackage(syms.java_base, names.java_lang);
if (javaLang.members().isEmpty() && !javaLang.exists()) if (javaLang.members().isEmpty() && !javaLang.exists())
throw new FatalError(diags.fragment("fatal.err.no.java.lang")); throw new FatalError(diags.fragment("fatal.err.no.java.lang"));
importAll(make.at(tree.pos()).Import(make.QualIdent(javaLang), false), javaLang, env); importAll(make.at(tree.pos()).Import(make.QualIdent(javaLang), false), javaLang, env);
@ -358,7 +360,9 @@ public class TypeEnter implements Completer {
Symbol p = env.toplevel.packge; Symbol p = env.toplevel.packge;
while (p.owner != syms.rootPackage) { while (p.owner != syms.rootPackage) {
p.owner.complete(); // enter all class members of p p.owner.complete(); // enter all class members of p
if (syms.classes.get(p.getQualifiedName()) != null) { //need to lookup the owning module/package:
PackageSymbol pack = syms.lookupPackage(env.toplevel.modle, p.owner.getQualifiedName());
if (syms.getClass(pack.modle, p.getQualifiedName()) != null) {
log.error(tree.pos, log.error(tree.pos,
"pkg.clashes.with.class.of.same.name", "pkg.clashes.with.class.of.same.name",
p); p);
@ -515,7 +519,7 @@ public class TypeEnter implements Completer {
return result; return result;
} }
protected Type modelMissingTypes(Type t, final JCExpression tree, final boolean interfaceExpected) { protected Type modelMissingTypes(Env<AttrContext> env, Type t, final JCExpression tree, final boolean interfaceExpected) {
if (!t.hasTag(ERROR)) if (!t.hasTag(ERROR))
return t; return t;
@ -525,19 +529,21 @@ public class TypeEnter implements Completer {
@Override @Override
public Type getModelType() { public Type getModelType() {
if (modelType == null) if (modelType == null)
modelType = new Synthesizer(getOriginalType(), interfaceExpected).visit(tree); modelType = new Synthesizer(env.toplevel.modle, getOriginalType(), interfaceExpected).visit(tree);
return modelType; return modelType;
} }
}; };
} }
// where: // where:
private class Synthesizer extends JCTree.Visitor { private class Synthesizer extends JCTree.Visitor {
ModuleSymbol msym;
Type originalType; Type originalType;
boolean interfaceExpected; boolean interfaceExpected;
List<ClassSymbol> synthesizedSymbols = List.nil(); List<ClassSymbol> synthesizedSymbols = List.nil();
Type result; Type result;
Synthesizer(Type originalType, boolean interfaceExpected) { Synthesizer(ModuleSymbol msym, Type originalType, boolean interfaceExpected) {
this.msym = msym;
this.originalType = originalType; this.originalType = originalType;
this.interfaceExpected = interfaceExpected; this.interfaceExpected = interfaceExpected;
} }
@ -564,7 +570,7 @@ public class TypeEnter implements Completer {
if (!tree.type.hasTag(ERROR)) { if (!tree.type.hasTag(ERROR)) {
result = tree.type; result = tree.type;
} else { } else {
result = synthesizeClass(tree.name, syms.unnamedPackage).type; result = synthesizeClass(tree.name, msym.unnamedPackage).type;
} }
} }
@ -654,7 +660,7 @@ public class TypeEnter implements Completer {
? Type.noType ? Type.noType
: syms.objectType; : syms.objectType;
} }
ct.supertype_field = modelMissingTypes(supertype, extending, false); ct.supertype_field = modelMissingTypes(baseEnv, supertype, extending, false);
// Determine interfaces. // Determine interfaces.
ListBuffer<Type> interfaces = new ListBuffer<>(); ListBuffer<Type> interfaces = new ListBuffer<>();
@ -669,7 +675,7 @@ public class TypeEnter implements Completer {
} else { } else {
if (all_interfaces == null) if (all_interfaces == null)
all_interfaces = new ListBuffer<Type>().appendList(interfaces); all_interfaces = new ListBuffer<Type>().appendList(interfaces);
all_interfaces.append(modelMissingTypes(it, iface, true)); all_interfaces.append(modelMissingTypes(baseEnv, it, iface, true));
} }
} }
@ -816,8 +822,8 @@ public class TypeEnter implements Completer {
// but admit classes in the unnamed package which have the same // but admit classes in the unnamed package which have the same
// name as a top-level package. // name as a top-level package.
if (checkClash && if (checkClash &&
sym.owner.kind == PCK && sym.owner != syms.unnamedPackage && sym.owner.kind == PCK && sym.owner != env.toplevel.modle.unnamedPackage &&
syms.packageExists(sym.fullname)) { syms.packageExists(env.toplevel.modle, sym.fullname)) {
log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), sym); log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), sym);
} }
if (sym.owner.kind == PCK && (sym.flags_field & PUBLIC) == 0 && if (sym.owner.kind == PCK && (sym.flags_field & PUBLIC) == 0 &&

View File

@ -31,6 +31,7 @@ import java.io.InputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -42,6 +43,7 @@ import java.nio.charset.CodingErrorAction;
import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException; import java.nio.charset.UnsupportedCharsetException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@ -58,6 +60,8 @@ import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.main.Option; import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.main.OptionHelper; import com.sun.tools.javac.main.OptionHelper;
import com.sun.tools.javac.main.OptionHelper.GrumpyHelper; import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.util.Abort;
import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.DefinedBy; import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.DefinedBy.Api;
@ -192,12 +196,34 @@ public abstract class BaseFileManager implements JavaFileManager {
Class.forName(classLoaderClass).asSubclass(ClassLoader.class); Class.forName(classLoaderClass).asSubclass(ClassLoader.class);
Class<?>[] constrArgTypes = { URL[].class, ClassLoader.class }; Class<?>[] constrArgTypes = { URL[].class, ClassLoader.class };
Constructor<? extends ClassLoader> constr = loader.getConstructor(constrArgTypes); Constructor<? extends ClassLoader> constr = loader.getConstructor(constrArgTypes);
return constr.newInstance(urls, thisClassLoader); return ensureReadable(constr.newInstance(urls, thisClassLoader));
} catch (ReflectiveOperationException t) { } catch (ReflectiveOperationException t) {
// ignore errors loading user-provided class loader, fall through // ignore errors loading user-provided class loader, fall through
} }
} }
return new URLClassLoader(urls, thisClassLoader); return ensureReadable(new URLClassLoader(urls, thisClassLoader));
}
/**
* Ensures that the unnamed module of the given classloader is readable to this
* module.
*/
private ClassLoader ensureReadable(ClassLoader targetLoader) {
try {
Method getModuleMethod = Class.class.getMethod("getModule");
Object thisModule = getModuleMethod.invoke(this.getClass());
Method getUnnamedModuleMethod = ClassLoader.class.getMethod("getUnnamedModule");
Object targetModule = getUnnamedModuleMethod.invoke(targetLoader);
Class<?> moduleClass = getModuleMethod.getReturnType();
Method addReadsMethod = moduleClass.getMethod("addReads", moduleClass);
addReadsMethod.invoke(thisModule, targetModule);
} catch (NoSuchMethodException e) {
// ignore
} catch (Exception e) {
throw new Abort(e);
}
return targetLoader;
} }
public boolean isDefaultBootClassPath() { public boolean isDefaultBootClassPath() {
@ -284,8 +310,14 @@ public abstract class BaseFileManager implements JavaFileManager {
*/ */
public boolean handleOptions(Map<Option, String> map) { public boolean handleOptions(Map<Option, String> map) {
boolean ok = true; boolean ok = true;
for (Map.Entry<Option, String> e: map.entrySet()) for (Map.Entry<Option, String> e: map.entrySet()) {
ok = ok & handleOption(e.getKey(), e.getValue()); try {
ok = ok & handleOption(e.getKey(), e.getValue());
} catch (IllegalArgumentException ex) {
log.error(Errors.IllegalArgumentForOption(e.getKey().getText(), ex.getMessage()));
ok = false;
}
}
return ok; return ok;
} }

View File

@ -201,6 +201,8 @@ public class JRTIndex {
if (Files.exists(dir)) { if (Files.exists(dir)) {
try (DirectoryStream<Path> modules = Files.newDirectoryStream(dir)) { try (DirectoryStream<Path> modules = Files.newDirectoryStream(dir)) {
for (Path module: modules) { for (Path module: modules) {
if (Files.isSymbolicLink(module))
module = Files.readSymbolicLink(module);
Path p = rd.resolveAgainst(module); Path p = rd.resolveAgainst(module);
if (!Files.exists(p)) if (!Files.exists(p))
continue; continue;

View File

@ -47,12 +47,14 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.ServiceLoader;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -70,6 +72,10 @@ import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.ModuleWrappers.Configuration;
import com.sun.tools.javac.util.ModuleWrappers.Layer;
import com.sun.tools.javac.util.ModuleWrappers.ModuleFinder;
import com.sun.tools.javac.util.ModuleWrappers.ServiceLoaderHelper;
import static java.nio.file.FileVisitOption.FOLLOW_LINKS; import static java.nio.file.FileVisitOption.FOLLOW_LINKS;
@ -421,16 +427,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
boolean recurse, boolean recurse,
ListBuffer<JavaFileObject> resultList) ListBuffer<JavaFileObject> resultList)
throws IOException { throws IOException {
// Very temporary and obnoxious interim hack if (Files.isRegularFile(container) && container.equals(Locations.thisSystemModules)) {
if (container.endsWith("bootmodules.jimage")) {
System.err.println("Warning: reference to bootmodules.jimage replaced by jrt:");
container = Locations.JRT_MARKER_FILE;
} else if (container.getNameCount() > 0 && container.getFileName().toString().endsWith(".jimage")) {
System.err.println("Warning: reference to " + container + " ignored");
return;
}
if (container == Locations.JRT_MARKER_FILE) {
try { try {
listJRTImage(subdirectory, listJRTImage(subdirectory,
fileKinds, fileKinds,
@ -443,7 +440,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
return; return;
} }
if (fsInfo.isDirectory(container)) { if (Files.isDirectory(container)) {
listDirectory(container, null, listDirectory(container, null,
subdirectory, subdirectory,
fileKinds, fileKinds,
@ -452,7 +449,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
return; return;
} }
if (Files.exists(container)) { if (Files.isRegularFile(container)) {
listArchive(container, listArchive(container,
subdirectory, subdirectory,
fileKinds, fileKinds,
@ -530,6 +527,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
return; return;
} }
locations.close();
for (FileSystem fs: fileSystems.values()) { for (FileSystem fs: fileSystems.values()) {
fs.close(); fs.close();
} }
@ -604,7 +602,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public boolean hasLocation(Location location) { public boolean hasLocation(Location location) {
return getLocation(location) != null; nullCheck(location);
return locations.hasLocation(location);
} }
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
@ -645,14 +644,14 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
return null; return null;
for (Path file: path) { for (Path file: path) {
if (file == Locations.JRT_MARKER_FILE) { if (file.equals(Locations.thisSystemModules)) {
JRTIndex.Entry e = getJRTIndex().getEntry(name.dirname()); JRTIndex.Entry e = getJRTIndex().getEntry(name.dirname());
if (symbolFileEnabled && e.ctSym.hidden) if (symbolFileEnabled && e.ctSym.hidden)
continue; continue;
Path p = e.files.get(name.basename()); Path p = e.files.get(name.basename());
if (p != null) if (p != null)
return PathFileObject.forJRTPath(this, p); return PathFileObject.forJRTPath(this, p);
} else if (fsInfo.isDirectory(file)) { } else if (Files.isDirectory(file)) {
try { try {
Path f = name.resolveAgainst(file); Path f = name.resolveAgainst(file);
if (Files.exists(f)) if (Files.exists(f))
@ -660,7 +659,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
fsInfo.getCanonicalFile(f), f); fsInfo.getCanonicalFile(f), f);
} catch (InvalidPathException ignore) { } catch (InvalidPathException ignore) {
} }
} else if (Files.exists(file)) { } else if (Files.isRegularFile(file)) {
FileSystem fs = getFileSystem(file); FileSystem fs = getFileSystem(file);
if (fs != null) { if (fs != null) {
Path fsRoot = fs.getRootDirectories().iterator().next(); Path fsRoot = fs.getRootDirectories().iterator().next();
@ -829,6 +828,69 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
return locations.getOutputLocation(SOURCE_OUTPUT); return locations.getOutputLocation(SOURCE_OUTPUT);
} }
@Override @DefinedBy(Api.COMPILER)
public Location getModuleLocation(Location location, String moduleName) throws IOException {
nullCheck(location);
nullCheck(moduleName);
return locations.getModuleLocation(location, moduleName);
}
@Override @DefinedBy(Api.COMPILER)
public <S> ServiceLoader<S> getServiceLoader(Location location, Class<S> service) throws IOException {
nullCheck(location);
nullCheck(service);
if (location.isModuleLocation()) {
Collection<Path> paths = locations.getLocation(location);
ModuleFinder finder = ModuleFinder.of(paths.toArray(new Path[paths.size()]));
Layer bootLayer = Layer.boot();
Configuration cf = bootLayer.configuration().resolveRequiresAndUses(ModuleFinder.empty(), finder, Collections.emptySet());
Layer layer = bootLayer.defineModulesWithOneLoader(cf, ClassLoader.getSystemClassLoader());
return ServiceLoaderHelper.load(layer, service);
} else {
return ServiceLoader.load(service, getClassLoader(location));
}
}
@Override @DefinedBy(Api.COMPILER)
public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
nullCheck(location);
if (!(fo instanceof PathFileObject))
throw new IllegalArgumentException(fo.getName());
int depth = 1; // allow 1 for filename
if (pkgName != null && !pkgName.isEmpty()) {
depth += 1;
for (int i = 0; i < pkgName.length(); i++) {
switch (pkgName.charAt(i)) {
case '/': case '.':
depth++;
}
}
}
Path p = Locations.normalize(((PathFileObject) fo).path);
int fc = p.getNameCount();
if (depth < fc) {
Path root = p.getRoot();
Path subpath = p.subpath(0, fc - depth);
Path dir = (root == null) ? subpath : root.resolve(subpath);
// need to find dir in location
return locations.getModuleLocation(location, dir);
} else {
return null;
}
}
@Override @DefinedBy(Api.COMPILER)
public String inferModuleName(Location location) {
nullCheck(location);
return locations.inferModuleName(location);
}
@Override @DefinedBy(Api.COMPILER)
public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
nullCheck(location);
return locations.listModuleLocations(location);
}
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public Path asPath(FileObject file) { public Path asPath(FileObject file) {
if (file instanceof PathFileObject) { if (file instanceof PathFileObject) {

View File

@ -0,0 +1,228 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.file;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import com.sun.tools.javac.jvm.ClassFile;
import static com.sun.tools.javac.jvm.ClassFile.*;
/**
* Stripped down ClassReader, just sufficient to read module names from module-info.class files
* while analyzing the module path.
*
* <p>
* <b>This is NOT part of any supported API. If you write code that depends on this, you do so at
* your own risk. This code and its internal interfaces are subject to change or deletion without
* notice.</b>
*/
public class ModuleNameReader {
static class BadClassFile extends Exception {
private static final long serialVersionUID = 0;
BadClassFile(String msg) {
super(msg);
}
}
private static final int INITIAL_BUFFER_SIZE = 0x0fff0;
/** The buffer containing the currently read class file.
*/
private byte[] buf = new byte[INITIAL_BUFFER_SIZE];
/** The current input pointer.
*/
private int bp;
/** The objects of the constant pool.
*/
private Object[] poolObj;
/** For every constant pool entry, an index into buf where the
* defining section of the entry is found.
*/
private int[] poolIdx;
ModuleNameReader() {
}
String readModuleName(Path p) throws IOException, BadClassFile {
try (InputStream in = Files.newInputStream(p)) {
bp = 0;
buf = readInputStream(buf, in);
int magic = nextInt();
if (magic != JAVA_MAGIC)
throw new BadClassFile("illegal.start.of.class.file");
int minorVersion = nextChar();
int majorVersion = nextChar();
indexPool();
int accessflags = nextChar();
return readModuleInfoName(nextChar());
}
}
/** Extract a character at position bp from buf.
*/
char getChar(int bp) {
return
(char)(((buf[bp] & 0xFF) << 8) + (buf[bp+1] & 0xFF));
}
/** Read a character.
*/
char nextChar() {
return (char)(((buf[bp++] & 0xFF) << 8) + (buf[bp++] & 0xFF));
}
/** Read an integer.
*/
int nextInt() {
return
((buf[bp++] & 0xFF) << 24) +
((buf[bp++] & 0xFF) << 16) +
((buf[bp++] & 0xFF) << 8) +
(buf[bp++] & 0xFF);
}
/** Index all constant pool entries, writing their start addresses into
* poolIdx.
*/
void indexPool() throws BadClassFile {
poolIdx = new int[nextChar()];
poolObj = new Object[poolIdx.length];
int i = 1;
while (i < poolIdx.length) {
poolIdx[i++] = bp;
byte tag = buf[bp++];
switch (tag) {
case CONSTANT_Utf8: case CONSTANT_Unicode: {
int len = nextChar();
bp = bp + len;
break;
}
case CONSTANT_Class:
case CONSTANT_String:
case CONSTANT_MethodType:
bp = bp + 2;
break;
case CONSTANT_MethodHandle:
bp = bp + 3;
break;
case CONSTANT_Fieldref:
case CONSTANT_Methodref:
case CONSTANT_InterfaceMethodref:
case CONSTANT_NameandType:
case CONSTANT_Integer:
case CONSTANT_Float:
case CONSTANT_InvokeDynamic:
bp = bp + 4;
break;
case CONSTANT_Long:
case CONSTANT_Double:
bp = bp + 8;
i++;
break;
default:
throw new BadClassFile("malformed constant pool");
}
}
}
/** Read the class name of a module-info.class file.
* The name is stored in a CONSTANT_Class entry, where the
* class name is of the form module-name/module-info.
*/
String readModuleInfoName(int i) throws BadClassFile {
int classIndex = poolIdx[i];
if (buf[classIndex] == CONSTANT_Class) {
int utf8Index = poolIdx[getChar(classIndex + 1)];
if (buf[utf8Index] == CONSTANT_Utf8) {
int len = getChar(utf8Index + 1);
int start = utf8Index + 3;
String suffix = "/module-info";
if (endsWith(buf, start, len, suffix))
return new String(ClassFile.internalize(buf, start, len - suffix.length()));
}
}
throw new BadClassFile("bad module-info name");
}
private boolean endsWith(byte[] buf, int start, int len, String suffix) {
if (len <= suffix.length())
return false;
for (int i = 0; i < suffix.length(); i++) {
if (buf[start + len - suffix.length() + i] != suffix.charAt(i))
return false;
}
return true;
}
private static byte[] readInputStream(byte[] buf, InputStream s) throws IOException {
try {
buf = ensureCapacity(buf, s.available());
int r = s.read(buf);
int bp = 0;
while (r != -1) {
bp += r;
buf = ensureCapacity(buf, bp);
r = s.read(buf, bp, buf.length - bp);
}
return buf;
} finally {
try {
s.close();
} catch (IOException e) {
/* Ignore any errors, as this stream may have already
* thrown a related exception which is the one that
* should be reported.
*/
}
}
}
/*
* ensureCapacity will increase the buffer as needed, taking note that
* the new buffer will always be greater than the needed and never
* exactly equal to the needed size or bp. If equal then the read (above)
* will infinitely loop as buf.length - bp == 0.
*/
private static byte[] ensureCapacity(byte[] buf, int needed) {
if (buf.length <= needed) {
byte[] old = buf;
buf = new byte[Integer.highestOneBit(needed) << 1];
System.arraycopy(old, 0, buf, 0, old.length);
}
return buf;
}
}

View File

@ -107,9 +107,8 @@ public class ClassFile {
V49(49, 0), // JDK 1.5: enum, generics, annotations V49(49, 0), // JDK 1.5: enum, generics, annotations
V50(50, 0), // JDK 1.6: stackmaps V50(50, 0), // JDK 1.6: stackmaps
V51(51, 0), // JDK 1.7 V51(51, 0), // JDK 1.7
V52(52, 0); // JDK 1.8: lambda, type annos, param names V52(52, 0), // JDK 1.8: lambda, type annos, param names
// JDK9 still marked as V52 // V53(53, 0); // JDK 1.9 V53(52, 0); // JDK 1.9: modules **** FIXME TO 53 BEFORE RELEASE *****
Version(int major, int minor) { Version(int major, int minor) {
this.major = major; this.major = major;
this.minor = minor; this.minor = minor;

View File

@ -44,6 +44,7 @@ import javax.tools.JavaFileObject;
import com.sun.tools.javac.comp.Annotate; import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter; import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Directive.*;
import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Scope.WriteableScope; import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
@ -100,6 +101,10 @@ public class ClassReader {
*/ */
boolean allowSimplifiedVarargs; boolean allowSimplifiedVarargs;
/** Switch: allow modules.
*/
boolean allowModules;
/** Lint option: warn about classfile issues /** Lint option: warn about classfile issues
*/ */
boolean lintClassfile; boolean lintClassfile;
@ -137,6 +142,9 @@ public class ClassReader {
*/ */
protected WriteableScope typevars; protected WriteableScope typevars;
private List<InterimUsesDirective> interimUses = List.nil();
private List<InterimProvidesDirective> interimProvides = List.nil();
/** The path name of the class file currently being read. /** The path name of the class file currently being read.
*/ */
protected JavaFileObject currentClassFile = null; protected JavaFileObject currentClassFile = null;
@ -145,6 +153,10 @@ public class ClassReader {
*/ */
protected Symbol currentOwner = null; protected Symbol currentOwner = null;
/** The module containing the class currently being read.
*/
protected ModuleSymbol currentModule = null;
/** The buffer containing the currently read class file. /** The buffer containing the currently read class file.
*/ */
byte[] buf = new byte[INITIAL_BUFFER_SIZE]; byte[] buf = new byte[INITIAL_BUFFER_SIZE];
@ -228,6 +240,7 @@ public class ClassReader {
Source source = Source.instance(context); Source source = Source.instance(context);
allowSimplifiedVarargs = source.allowSimplifiedVarargs(); allowSimplifiedVarargs = source.allowSimplifiedVarargs();
allowModules = source.allowModules();
saveParameterNames = options.isSet("save-parameter-names"); saveParameterNames = options.isSet("save-parameter-names");
@ -478,7 +491,7 @@ public class ClassReader {
// simplified to (buf[start] == '[') // simplified to (buf[start] == '[')
return (buf[start] == '[' || buf[start + len - 1] == ';') return (buf[start] == '[' || buf[start + len - 1] == ';')
? (Object)sigToType(buf, start, len) ? (Object)sigToType(buf, start, len)
: (Object)syms.enterClass(names.fromUtf(internalize(buf, start, : (Object)enterClass(names.fromUtf(internalize(buf, start,
len))); len)));
} }
@ -500,6 +513,23 @@ public class ClassReader {
return (ClassSymbol)obj; return (ClassSymbol)obj;
} }
Name readClassName(int i) {
int index = poolIdx[i];
if (index == 0) return null;
byte tag = buf[index];
if (tag != CONSTANT_Class) {
throw badClassFile("bad.const.pool.entry",
currentClassFile.toString(),
"CONSTANT_Class_info", i);
}
int nameIndex = poolIdx[getChar(index + 1)];
int len = getChar(nameIndex + 1);
int start = nameIndex + 3;
if (buf[start] == '[' || buf[start + len - 1] == ';')
throw badClassFile("wrong class name"); //TODO: proper diagnostics
return names.fromUtf(internalize(buf, start, len));
}
/** Read name. /** Read name.
*/ */
Name readName(int i) { Name readName(int i) {
@ -522,6 +552,34 @@ public class ClassReader {
return (NameAndType)obj; return (NameAndType)obj;
} }
/** Read the class name of a module-info.class file.
* The name is stored in a CONSTANT_Class entry, where the
* class name is of the form module-name.module-info.
*/
Name readModuleInfoName(int i) {
int classIndex = poolIdx[i];
if (buf[classIndex] == CONSTANT_Class) {
int utf8Index = poolIdx[getChar(classIndex + 1)];
if (buf[utf8Index] == CONSTANT_Utf8) {
int len = getChar(utf8Index + 1);
int start = utf8Index + 3;
return names.fromUtf(internalize(buf, start, len));
}
}
throw badClassFile("bad.module-info.name");
}
/** Read requires_flags.
*/
Set<RequiresFlag> readRequiresFlags(int flags) {
Set<RequiresFlag> set = EnumSet.noneOf(RequiresFlag.class);
for (RequiresFlag f: RequiresFlag.values()) {
if ((flags & f.value) != 0)
set.add(f);
}
return set;
}
/************************************************************************ /************************************************************************
* Reading Types * Reading Types
***********************************************************************/ ***********************************************************************/
@ -660,7 +718,7 @@ public class ClassReader {
switch (c) { switch (c) {
case ';': { // end case ';': { // end
ClassSymbol t = syms.enterClass(names.fromUtf(signatureBuffer, ClassSymbol t = enterClass(names.fromUtf(signatureBuffer,
startSbp, startSbp,
sbp - startSbp)); sbp - startSbp));
@ -674,7 +732,7 @@ public class ClassReader {
} }
case '<': // generic arguments case '<': // generic arguments
ClassSymbol t = syms.enterClass(names.fromUtf(signatureBuffer, ClassSymbol t = enterClass(names.fromUtf(signatureBuffer,
startSbp, startSbp,
sbp - startSbp)); sbp - startSbp));
outer = new ClassType(outer, sigToTypes('>'), t) { outer = new ClassType(outer, sigToTypes('>'), t) {
@ -737,7 +795,7 @@ public class ClassReader {
case '.': case '.':
//we have seen an enclosing non-generic class //we have seen an enclosing non-generic class
if (outer != Type.noType) { if (outer != Type.noType) {
t = syms.enterClass(names.fromUtf(signatureBuffer, t = enterClass(names.fromUtf(signatureBuffer,
startSbp, startSbp,
sbp - startSbp)); sbp - startSbp));
outer = new ClassType(outer, List.<Type>nil(), t); outer = new ClassType(outer, List.<Type>nil(), t);
@ -941,7 +999,12 @@ public class ClassReader {
new AttributeReader(names.InnerClasses, V45_3, CLASS_ATTRIBUTE) { new AttributeReader(names.InnerClasses, V45_3, CLASS_ATTRIBUTE) {
protected void read(Symbol sym, int attrLen) { protected void read(Symbol sym, int attrLen) {
ClassSymbol c = (ClassSymbol) sym; ClassSymbol c = (ClassSymbol) sym;
readInnerClasses(c); if (currentModule.module_info == c) {
//prevent entering the classes too soon:
skipInnerClasses();
} else {
readInnerClasses(c);
}
} }
}, },
@ -981,25 +1044,6 @@ public class ClassReader {
} }
}, },
new AttributeReader(names.MethodParameters, V52, MEMBER_ATTRIBUTE) {
protected void read(Symbol sym, int attrlen) {
int newbp = bp + attrlen;
if (saveParameterNames) {
sawMethodParameters = true;
int numEntries = nextByte();
parameterNameIndices = new int[numEntries];
haveParameterNameIndices = true;
for (int i = 0; i < numEntries; i++) {
int nameIndex = nextChar();
int flags = nextChar();
parameterNameIndices[i] = nameIndex;
}
}
bp = newbp;
}
},
new AttributeReader(names.SourceFile, V45_3, CLASS_ATTRIBUTE) { new AttributeReader(names.SourceFile, V45_3, CLASS_ATTRIBUTE) {
protected void read(Symbol sym, int attrLen) { protected void read(Symbol sym, int attrLen) {
ClassSymbol c = (ClassSymbol) sym; ClassSymbol c = (ClassSymbol) sym;
@ -1130,12 +1174,109 @@ public class ClassReader {
} }
}, },
// The following attributes for a Code attribute are not currently handled // The following attributes for a Code attribute are not currently handled
// StackMapTable // StackMapTable
// SourceDebugExtension // SourceDebugExtension
// LineNumberTable // LineNumberTable
// LocalVariableTypeTable // LocalVariableTypeTable
// standard v52 attributes
new AttributeReader(names.MethodParameters, V52, MEMBER_ATTRIBUTE) {
protected void read(Symbol sym, int attrlen) {
int newbp = bp + attrlen;
if (saveParameterNames) {
sawMethodParameters = true;
int numEntries = nextByte();
parameterNameIndices = new int[numEntries];
haveParameterNameIndices = true;
for (int i = 0; i < numEntries; i++) {
int nameIndex = nextChar();
int flags = nextChar();
parameterNameIndices[i] = nameIndex;
}
}
bp = newbp;
}
},
// standard v53 attributes
new AttributeReader(names.Module, V53, CLASS_ATTRIBUTE) {
@Override
protected boolean accepts(AttributeKind kind) {
return super.accepts(kind) && allowModules;
}
protected void read(Symbol sym, int attrLen) {
if (sym.kind == TYP && sym.owner.kind == MDL) {
ModuleSymbol msym = (ModuleSymbol) sym.owner;
ListBuffer<Directive> directives = new ListBuffer<>();
ListBuffer<RequiresDirective> requires = new ListBuffer<>();
int nrequires = nextChar();
for (int i = 0; i < nrequires; i++) {
Name name = readName(nextChar());
ModuleSymbol rsym = syms.enterModule(name);
Set<RequiresFlag> flags = readRequiresFlags(nextChar());
requires.add(new RequiresDirective(rsym, flags));
}
msym.requires = requires.toList();
directives.addAll(msym.requires);
ListBuffer<ExportsDirective> exports = new ListBuffer<>();
int nexports = nextChar();
for (int i = 0; i < nexports; i++) {
Name n = readName(nextChar());
PackageSymbol p = syms.enterPackage(currentModule, names.fromUtf(internalize(n)));
int nto = nextChar();
List<ModuleSymbol> to;
if (nto == 0) {
to = null;
} else {
ListBuffer<ModuleSymbol> lb = new ListBuffer<>();
for (int t = 0; t < nto; t++)
lb.append(syms.enterModule(readName(nextChar())));
to = lb.toList();
}
exports.add(new ExportsDirective(p, to));
}
msym.exports = exports.toList();
directives.addAll(msym.exports);
msym.directives = directives.toList();
ListBuffer<InterimUsesDirective> uses = new ListBuffer<>();
int nuses = nextChar();
for (int i = 0; i < nuses; i++) {
Name srvc = readClassName(nextChar());
uses.add(new InterimUsesDirective(srvc));
}
interimUses = uses.toList();
ListBuffer<InterimProvidesDirective> provides = new ListBuffer<>();
int nprovides = nextChar();
for (int i = 0; i < nprovides; i++) {
Name srvc = readClassName(nextChar());
Name impl = readClassName(nextChar());
provides.add(new InterimProvidesDirective(srvc, impl));
}
interimProvides = provides.toList();
}
}
},
new AttributeReader(names.Version, V53, CLASS_ATTRIBUTE) {
@Override
protected boolean accepts(AttributeKind kind) {
return super.accepts(kind) && allowModules;
}
protected void read(Symbol sym, int attrLen) {
if (sym.kind == TYP && sym.owner.kind == MDL) {
ModuleSymbol msym = (ModuleSymbol) sym.owner;
msym.version = readName(nextChar());
}
}
},
}; };
for (AttributeReader r: readers) for (AttributeReader r: readers)
@ -1388,7 +1529,7 @@ public class ClassReader {
int index = poolIdx[i]; int index = poolIdx[i];
int length = getChar(index + 1); int length = getChar(index + 1);
if (buf[index + length + 2] != ';') if (buf[index + length + 2] != ';')
return syms.enterClass(readName(i)).type; return enterClass(readName(i)).type;
return readType(i); return readType(i);
} }
@ -2175,6 +2316,16 @@ public class ClassReader {
} }
} }
void skipInnerClasses() {
int n = nextChar();
for (int i = 0; i < n; i++) {
nextChar();
nextChar();
nextChar();
nextChar();
}
}
/** Enter type variables of this classtype and all enclosing ones in /** Enter type variables of this classtype and all enclosing ones in
* `typevars'. * `typevars'.
*/ */
@ -2193,6 +2344,14 @@ public class ClassReader {
enterTypevars(sym.type); enterTypevars(sym.type);
} }
protected ClassSymbol enterClass(Name name) {
return syms.enterClass(currentModule, name);
}
protected ClassSymbol enterClass(Name name, TypeSymbol owner) {
return syms.enterClass(currentModule, name, owner);
}
/** Read contents of a given class symbol `c'. Both external and internal /** Read contents of a given class symbol `c'. Both external and internal
* versions of an inner class are read. * versions of an inner class are read.
*/ */
@ -2208,14 +2367,27 @@ public class ClassReader {
enterTypevars(ct.getEnclosingType()); enterTypevars(ct.getEnclosingType());
// read flags, or skip if this is an inner class // read flags, or skip if this is an inner class
long flags = adjustClassFlags(nextChar()); long f = nextChar();
if (c.owner.kind == PCK) c.flags_field = flags; long flags = adjustClassFlags(f);
if ((flags & MODULE) == 0) {
// read own class name and check that it matches if (c.owner.kind == PCK) c.flags_field = flags;
ClassSymbol self = readClassSymbol(nextChar()); // read own class name and check that it matches
if (c != self) currentModule = c.packge().modle;
throw badClassFile("class.file.wrong.class", ClassSymbol self = readClassSymbol(nextChar());
self.flatname); if (c != self) {
throw badClassFile("class.file.wrong.class",
self.flatname);
}
} else {
c.flags_field = flags;
Name modInfoName = readModuleInfoName(nextChar());
if (c.owner.name == null) {
syms.enterModule((ModuleSymbol) c.owner, Convert.packagePart(modInfoName));
} else {
// TODO: validate name
}
currentModule = (ModuleSymbol) c.owner;
}
// class attributes must be read before class // class attributes must be read before class
// skip ahead to read class attributes // skip ahead to read class attributes
@ -2272,7 +2444,7 @@ public class ClassReader {
if (outer != null) { // we have a member class if (outer != null) { // we have a member class
if (name == names.empty) if (name == names.empty)
name = names.one; name = names.one;
ClassSymbol member = syms.enterClass(name, outer); ClassSymbol member = enterClass(name, outer);
if ((flags & STATIC) == 0) { if ((flags & STATIC) == 0) {
((ClassType)member.type).setEnclosingType(outer.type); ((ClassType)member.type).setEnclosingType(outer.type);
if (member.erasure_field != null) if (member.erasure_field != null)
@ -2354,11 +2526,24 @@ public class ClassReader {
} else { } else {
c.setAnnotationTypeMetadata(AnnotationTypeMetadata.notAnAnnotationType()); c.setAnnotationTypeMetadata(AnnotationTypeMetadata.notAnAnnotationType());
} }
if (c == currentModule.module_info) {
if (interimUses.nonEmpty() || interimProvides.nonEmpty()) {
Assert.check(currentModule.isCompleted());
currentModule.usesProvidesCompleter =
new UsesProvidesCompleter(currentModule, interimUses, interimProvides);
} else {
currentModule.uses = List.nil();
currentModule.provides = List.nil();
}
}
} catch (IOException ex) { } catch (IOException ex) {
throw badClassFile("unable.to.access.file", ex.getMessage()); throw badClassFile("unable.to.access.file", ex.getMessage());
} catch (ArrayIndexOutOfBoundsException ex) { } catch (ArrayIndexOutOfBoundsException ex) {
throw badClassFile("bad.class.file", c.flatname); throw badClassFile("bad.class.file", c.flatname);
} finally { } finally {
interimUses = List.nil();
interimProvides = List.nil();
missingTypeVariables = List.nil(); missingTypeVariables = List.nil();
foundTypeVariables = List.nil(); foundTypeVariables = List.nil();
filling = false; filling = false;
@ -2429,6 +2614,10 @@ public class ClassReader {
} }
long adjustClassFlags(long flags) { long adjustClassFlags(long flags) {
if ((flags & ACC_MODULE) != 0) {
flags &= ~ACC_MODULE;
flags |= MODULE;
}
return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
} }
@ -2580,4 +2769,58 @@ public class ClassReader {
sym.getAnnotationTypeMetadata().setRepeatable(theRepeatable); sym.getAnnotationTypeMetadata().setRepeatable(theRepeatable);
} }
} }
private static final class InterimUsesDirective {
public final Name service;
public InterimUsesDirective(Name service) {
this.service = service;
}
}
private static final class InterimProvidesDirective {
public final Name service;
public final Name impl;
public InterimProvidesDirective(Name service, Name impl) {
this.service = service;
this.impl = impl;
}
}
private final class UsesProvidesCompleter implements Completer {
private final ModuleSymbol currentModule;
private final List<InterimUsesDirective> interimUsesCopy;
private final List<InterimProvidesDirective> interimProvidesCopy;
public UsesProvidesCompleter(ModuleSymbol currentModule, List<InterimUsesDirective> interimUsesCopy, List<InterimProvidesDirective> interimProvidesCopy) {
this.currentModule = currentModule;
this.interimUsesCopy = interimUsesCopy;
this.interimProvidesCopy = interimProvidesCopy;
}
@Override
public void complete(Symbol sym) throws CompletionFailure {
ListBuffer<Directive> directives = new ListBuffer<>();
directives.addAll(currentModule.directives);
ListBuffer<UsesDirective> uses = new ListBuffer<>();
for (InterimUsesDirective interim : interimUsesCopy) {
UsesDirective d = new UsesDirective(syms.enterClass(currentModule, interim.service));
uses.add(d);
directives.add(d);
}
currentModule.uses = uses.toList();
ListBuffer<ProvidesDirective> provides = new ListBuffer<>();
for (InterimProvidesDirective interim : interimProvidesCopy) {
ProvidesDirective d = new ProvidesDirective(syms.enterClass(currentModule, interim.service),
syms.enterClass(currentModule, interim.impl));
provides.add(d);
directives.add(d);
}
currentModule.provides = provides.toList();
currentModule.directives = directives.toList();
}
}
} }

View File

@ -33,10 +33,12 @@ import java.util.HashSet;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
import javax.tools.FileObject; import javax.tools.FileObject;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Attribute.RetentionPolicy; import com.sun.tools.javac.code.Attribute.RetentionPolicy;
import com.sun.tools.javac.code.Directive.*;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Types.UniqueType; import com.sun.tools.javac.code.Types.UniqueType;
@ -97,6 +99,12 @@ public class ClassWriter extends ClassFile {
/** Type utilities. */ /** Type utilities. */
private Types types; private Types types;
/**
* If true, class files will be written in module-specific subdirectories
* of the CLASS_OUTPUT location.
*/
public boolean multiModuleMode;
/** The initial sizes of the data and constant pool buffers. /** The initial sizes of the data and constant pool buffers.
* Sizes are increased when buffers get full. * Sizes are increased when buffers get full.
*/ */
@ -934,6 +942,58 @@ public class ClassWriter extends ClassFile {
} }
} }
/**********************************************************************
* Writing module attributes
**********************************************************************/
/** Write the Module attribute if needed.
* Returns the number of attributes written (0 or 1).
*/
int writeModuleAttribute(ClassSymbol c) {
ModuleSymbol m = (ModuleSymbol) c.owner;
int alenIdx = writeAttr(names.Module);
ListBuffer<RequiresDirective> requires = new ListBuffer<>();
for (RequiresDirective r: m.requires) {
if (!r.flags.contains(RequiresFlag.EXTRA))
requires.add(r);
}
databuf.appendChar(requires.size());
for (RequiresDirective r: requires) {
databuf.appendChar(pool.put(r.module.name));
databuf.appendChar(RequiresFlag.value(r.flags));
}
List<ExportsDirective> exports = m.exports;
databuf.appendChar(exports.size());
for (ExportsDirective e: exports) {
databuf.appendChar(pool.put(names.fromUtf(externalize(e.packge.flatName()))));
if (e.modules == null) {
databuf.appendChar(0);
} else {
databuf.appendChar(e.modules.size());
for (ModuleSymbol msym: e.modules)
databuf.appendChar(pool.put(msym.name));
}
}
List<UsesDirective> uses = m.uses;
databuf.appendChar(uses.size());
for (UsesDirective s: uses) {
databuf.appendChar(pool.put(s.service));
}
List<ProvidesDirective> services = m.provides;
databuf.appendChar(services.size());
for (ProvidesDirective s: services) {
databuf.appendChar(pool.put(s.service));
databuf.appendChar(pool.put(s.impl));
}
endAttr(alenIdx);
return 1;
}
/********************************************************************** /**********************************************************************
* Writing Objects * Writing Objects
**********************************************************************/ **********************************************************************/
@ -1564,9 +1624,17 @@ public class ClassWriter extends ClassFile {
public JavaFileObject writeClass(ClassSymbol c) public JavaFileObject writeClass(ClassSymbol c)
throws IOException, PoolOverflow, StringOverflow throws IOException, PoolOverflow, StringOverflow
{ {
String name = (c.owner.kind == MDL ? c.name : c.flatname).toString();
Location outLocn;
if (multiModuleMode) {
ModuleSymbol msym = c.owner.kind == MDL ? (ModuleSymbol) c.owner : c.packge().modle;
outLocn = fileManager.getModuleLocation(CLASS_OUTPUT, msym.name.toString());
} else {
outLocn = CLASS_OUTPUT;
}
JavaFileObject outFile JavaFileObject outFile
= fileManager.getJavaFileForOutput(CLASS_OUTPUT, = fileManager.getJavaFileForOutput(outLocn,
c.flatname.toString(), name,
JavaFileObject.Kind.CLASS, JavaFileObject.Kind.CLASS,
c.sourcefile); c.sourcefile);
OutputStream out = outFile.openOutputStream(); OutputStream out = outFile.openOutputStream();
@ -1604,11 +1672,17 @@ public class ClassWriter extends ClassFile {
List<Type> interfaces = types.interfaces(c.type); List<Type> interfaces = types.interfaces(c.type);
List<Type> typarams = c.type.getTypeArguments(); List<Type> typarams = c.type.getTypeArguments();
int flags = adjustFlags(c.flags() & ~DEFAULT); int flags;
if ((flags & PROTECTED) != 0) flags |= PUBLIC; if (c.owner.kind == MDL) {
flags = flags & ClassFlags & ~STRICTFP; flags = ACC_MODULE;
if ((flags & INTERFACE) == 0) flags |= ACC_SUPER; } else {
if (c.isInner() && c.name.isEmpty()) flags &= ~FINAL; flags = adjustFlags(c.flags() & ~DEFAULT);
if ((flags & PROTECTED) != 0) flags |= PUBLIC;
flags = flags & ClassFlags & ~STRICTFP;
if ((flags & INTERFACE) == 0) flags |= ACC_SUPER;
if (c.isInner() && c.name.isEmpty()) flags &= ~FINAL;
}
if (dumpClassModifiers) { if (dumpClassModifiers) {
PrintWriter pw = log.getWriter(Log.WriterKind.ERROR); PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
pw.println(); pw.println();
@ -1693,6 +1767,9 @@ public class ClassWriter extends ClassFile {
acount += writeJavaAnnotations(c.getRawAttributes()); acount += writeJavaAnnotations(c.getRawAttributes());
acount += writeTypeAnnotations(c.getRawTypeAttributes(), false); acount += writeTypeAnnotations(c.getRawTypeAttributes(), false);
acount += writeEnclosingMethodAttribute(c); acount += writeEnclosingMethodAttribute(c);
if (c.owner.kind == MDL) {
acount += writeModuleAttribute(c);
}
acount += writeExtraClassAttributes(c); acount += writeExtraClassAttributes(c);
poolbuf.appendInt(JAVA_MAGIC); poolbuf.appendInt(JAVA_MAGIC);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,12 +33,14 @@ import java.util.List;
import javax.tools.FileObject; import javax.tools.FileObject;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
import javax.tools.JavaFileManager.Location;
import javax.tools.StandardLocation; import javax.tools.StandardLocation;
import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type;
@ -82,6 +84,12 @@ public class JNIWriter {
*/ */
private boolean checkAll; private boolean checkAll;
/**
* If true, class files will be written in module-specific subdirectories
* of the NATIVE_HEADER_OUTPUT location.
*/
public boolean multiModuleMode;
private Context context; private Context context;
private static final boolean isWindows = private static final boolean isWindows =
@ -168,8 +176,15 @@ public class JNIWriter {
*/ */
public FileObject write(ClassSymbol c) throws IOException { public FileObject write(ClassSymbol c) throws IOException {
String className = c.flatName().toString(); String className = c.flatName().toString();
Location outLocn;
if (multiModuleMode) {
ModuleSymbol msym = c.owner.kind == MDL ? (ModuleSymbol) c.owner : c.packge().modle;
outLocn = fileManager.getModuleLocation(StandardLocation.NATIVE_HEADER_OUTPUT, msym.name.toString());
} else {
outLocn = StandardLocation.NATIVE_HEADER_OUTPUT;
}
FileObject outFile FileObject outFile
= fileManager.getFileForOutput(StandardLocation.NATIVE_HEADER_OUTPUT, = fileManager.getFileForOutput(outLocn,
"", className.replaceAll("[.$]", "_") + ".h", null); "", className.replaceAll("[.$]", "_") + ".h", null);
PrintWriter out = new PrintWriter(outFile.openWriter()); PrintWriter out = new PrintWriter(outFile.openWriter());
try { try {
@ -675,5 +690,10 @@ public class JNIWriter {
public R visitType(Type t, P p) { public R visitType(Type t, P p) {
return defaultAction(t, p); return defaultAction(t, p);
} }
@Override
public R visitModuleType(Type.ModuleType t, P p) {
return defaultAction(t, p);
}
} }
} }

View File

@ -29,17 +29,24 @@ import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardJavaFileManager; import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation; import javax.tools.StandardLocation;
@ -53,6 +60,8 @@ import com.sun.tools.javac.jvm.Target;
import com.sun.tools.javac.main.OptionHelper.GrumpyHelper; import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
import com.sun.tools.javac.platform.PlatformDescription; import com.sun.tools.javac.platform.PlatformDescription;
import com.sun.tools.javac.platform.PlatformUtils; import com.sun.tools.javac.platform.PlatformUtils;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.ListBuffer;
@ -77,6 +86,7 @@ public class Arguments {
private Set<Path> files; private Set<Path> files;
private Map<Option, String> deferredFileManagerOptions; private Map<Option, String> deferredFileManagerOptions;
private Set<JavaFileObject> fileObjects; private Set<JavaFileObject> fileObjects;
private boolean emptyAllowed;
private final Options options; private final Options options;
private JavaFileManager fileManager; private JavaFileManager fileManager;
@ -248,14 +258,12 @@ public class Arguments {
*/ */
public Set<JavaFileObject> getFileObjects() { public Set<JavaFileObject> getFileObjects() {
if (fileObjects == null) { if (fileObjects == null) {
if (files == null) { fileObjects = new LinkedHashSet<>();
fileObjects = Collections.emptySet(); }
} else { if (files != null) {
fileObjects = new LinkedHashSet<>(); JavacFileManager jfm = (JavacFileManager) getFileManager();
JavacFileManager jfm = (JavacFileManager) getFileManager(); for (JavaFileObject fo: jfm.getJavaFileObjectsFromPaths(files))
for (JavaFileObject fo: jfm.getJavaFileObjectsFromPaths(files)) fileObjects.add(fo);
fileObjects.add(fo);
}
} }
return fileObjects; return fileObjects;
} }
@ -291,8 +299,10 @@ public class Arguments {
checkOptionAllowed(platformString == null, checkOptionAllowed(platformString == null,
option -> error("err.release.bootclasspath.conflict", option.getText()), option -> error("err.release.bootclasspath.conflict", option.getText()),
Option.BOOTCLASSPATH, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND, Option.BOOTCLASSPATH, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND,
Option.XBOOTCLASSPATH_PREPEND, Option.ENDORSEDDIRS, Option.EXTDIRS, Option.SOURCE, Option.XBOOTCLASSPATH_PREPEND,
Option.TARGET); Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS,
Option.EXTDIRS, Option.DJAVA_EXT_DIRS,
Option.SOURCE, Option.TARGET);
if (platformString != null) { if (platformString != null) {
PlatformDescription platformDescription = PlatformUtils.lookupPlatformDescription(platformString); PlatformDescription platformDescription = PlatformUtils.lookupPlatformDescription(platformString);
@ -396,13 +406,53 @@ public class Arguments {
* ILLEGAL_STATE * ILLEGAL_STATE
*/ */
public boolean validate() { public boolean validate() {
JavaFileManager fm = getFileManager();
if (options.isSet(Option.M)) {
if (!fm.hasLocation(StandardLocation.CLASS_OUTPUT)) {
log.error(Errors.OutputDirMustBeSpecifiedWithDashMOption);
} else if (!fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) {
log.error(Errors.ModulesourcepathMustBeSpecifiedWithDashMOption);
} else {
java.util.List<String> modules = Arrays.asList(options.get(Option.M).split(","));
try {
for (String module : modules) {
Location sourceLoc = fm.getModuleLocation(StandardLocation.MODULE_SOURCE_PATH, module);
if (sourceLoc == null) {
log.error(Errors.ModuleNotFoundInModuleSourcePath(module));
} else {
Location classLoc = fm.getModuleLocation(StandardLocation.CLASS_OUTPUT, module);
for (JavaFileObject file : fm.list(sourceLoc, "", EnumSet.of(JavaFileObject.Kind.SOURCE), true)) {
String className = fm.inferBinaryName(sourceLoc, file);
JavaFileObject classFile = fm.getJavaFileForInput(classLoc, className, Kind.CLASS);
if (classFile == null || classFile.getLastModified() < file.getLastModified()) {
if (fileObjects == null)
fileObjects = new HashSet<>();
fileObjects.add(file);
}
}
}
}
} catch (IOException ex) {
log.printLines(PrefixKind.JAVAC, "msg.io");
ex.printStackTrace(log.getWriter(WriterKind.NOTICE));
return false;
}
}
}
if (isEmpty()) { if (isEmpty()) {
// It is allowed to compile nothing if just asking for help or version info. // It is allowed to compile nothing if just asking for help or version info.
// But also note that none of these options are supported in API mode. // But also note that none of these options are supported in API mode.
if (options.isSet(Option.HELP) if (options.isSet(Option.HELP)
|| options.isSet(Option.X) || options.isSet(Option.X)
|| options.isSet(Option.VERSION) || options.isSet(Option.VERSION)
|| options.isSet(Option.FULLVERSION)) || options.isSet(Option.FULLVERSION)
|| options.isSet(Option.M))
return true;
if (emptyAllowed)
return true; return true;
if (JavaCompiler.explicitAnnotationProcessingRequested(options)) { if (JavaCompiler.explicitAnnotationProcessingRequested(options)) {
@ -423,6 +473,32 @@ public class Arguments {
return false; return false;
} }
// The following checks are to help avoid accidental confusion between
// directories of modules and exploded module directories.
if (fm instanceof StandardJavaFileManager) {
StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
if (sfm.hasLocation(StandardLocation.CLASS_OUTPUT)) {
Path outDir = sfm.getLocationAsPaths(StandardLocation.CLASS_OUTPUT).iterator().next();
if (sfm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) {
// multi-module mode
if (Files.exists(outDir.resolve("module-info.class"))) {
log.error(Errors.MultiModuleOutdirCannotBeExplodedModule(outDir));
}
} else {
// single-module or legacy mode
boolean lintPaths = options.isUnset(Option.XLINT_CUSTOM,
"-" + LintCategory.PATH.option);
if (lintPaths) {
Path outDirParent = outDir.getParent();
if (outDirParent != null && Files.exists(outDirParent.resolve("module-info.class"))) {
log.warning(LintCategory.PATH, Warnings.OutdirIsInExplodedModule(outDir));
}
}
}
}
}
String sourceString = options.get(Option.SOURCE); String sourceString = options.get(Option.SOURCE);
Source source = (sourceString != null) Source source = (sourceString != null)
? Source.lookup(sourceString) ? Source.lookup(sourceString)
@ -471,10 +547,13 @@ public class Arguments {
} }
} }
if (options.isSet(Option.SOURCEPATH) && options.isSet(Option.MODULESOURCEPATH)) {
error("err.sourcepath.modulesourcepath.conflict");
}
boolean lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option); boolean lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option);
if (lintOptions && source.compareTo(Source.DEFAULT) < 0 && !options.isSet(Option.RELEASE)) { if (lintOptions && source.compareTo(Source.DEFAULT) < 0 && !options.isSet(Option.RELEASE)) {
JavaFileManager fm = getFileManager();
if (fm instanceof BaseFileManager) { if (fm instanceof BaseFileManager) {
if (((BaseFileManager) fm).isDefaultBootClassPath()) if (((BaseFileManager) fm).isDefaultBootClassPath())
log.warning(LintCategory.OPTIONS, "source.no.bootclasspath", source.name); log.warning(LintCategory.OPTIONS, "source.no.bootclasspath", source.name);
@ -484,22 +563,106 @@ public class Arguments {
boolean obsoleteOptionFound = false; boolean obsoleteOptionFound = false;
if (source.compareTo(Source.MIN) < 0) { if (source.compareTo(Source.MIN) < 0) {
log.error("option.removed.source", source.name, Source.MIN.name); log.error(Errors.OptionRemovedSource(source.name, Source.MIN.name));
} else if (source == Source.MIN && lintOptions) { } else if (source == Source.MIN && lintOptions) {
log.warning(LintCategory.OPTIONS, "option.obsolete.source", source.name); log.warning(LintCategory.OPTIONS, Warnings.OptionObsoleteSource(source.name));
obsoleteOptionFound = true; obsoleteOptionFound = true;
} }
if (target.compareTo(Target.MIN) < 0) { if (target.compareTo(Target.MIN) < 0) {
log.error("option.removed.target", target.name, Target.MIN.name); log.error(Errors.OptionRemovedTarget(target.name, Target.MIN.name));
} else if (target == Target.MIN && lintOptions) { } else if (target == Target.MIN && lintOptions) {
log.warning(LintCategory.OPTIONS, "option.obsolete.target", target.name); log.warning(LintCategory.OPTIONS, Warnings.OptionObsoleteTarget(target.name));
obsoleteOptionFound = true; obsoleteOptionFound = true;
} }
final Target t = target;
checkOptionAllowed(t.compareTo(Target.JDK1_8) <= 0,
option -> error("err.option.not.allowed.with.target", option.getText(), t.name),
Option.BOOTCLASSPATH,
Option.XBOOTCLASSPATH_PREPEND, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND,
Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS,
Option.EXTDIRS, Option.DJAVA_EXT_DIRS);
checkOptionAllowed(t.compareTo(Target.JDK1_9) >= 0,
option -> error("err.option.not.allowed.with.target", option.getText(), t.name),
Option.MODULESOURCEPATH, Option.UPGRADEMODULEPATH,
Option.SYSTEM, Option.MODULEPATH, Option.ADDMODS, Option.LIMITMODS,
Option.XPATCH);
if (fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) {
if (!options.isSet(Option.PROC, "only")
&& !fm.hasLocation(StandardLocation.CLASS_OUTPUT)) {
log.error(Errors.NoOutputDir);
}
if (options.isSet(Option.XMODULE)) {
log.error(Errors.XmoduleNoModuleSourcepath);
}
}
if (fm.hasLocation(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH) &&
fm.hasLocation(StandardLocation.ANNOTATION_PROCESSOR_PATH)) {
log.error(Errors.ProcessorpathNoProcessormodulepath);
}
if (obsoleteOptionFound) if (obsoleteOptionFound)
log.warning(LintCategory.OPTIONS, "option.obsolete.suppression"); log.warning(LintCategory.OPTIONS, "option.obsolete.suppression");
String addExports = options.get(Option.XADDEXPORTS);
if (addExports != null) {
// Each entry must be of the form module/package=target-list where target-list is a
// comma-separated list of module or ALL-UNNAMED.
// All module/package pairs must be unique.
Pattern p = Pattern.compile("([^/]+)/([^=]+)=(.*)");
Map<String,List<String>> map = new LinkedHashMap<>();
for (String e: addExports.split("\0")) {
Matcher m = p.matcher(e);
if (!m.matches()) {
log.error(Errors.XaddexportsMalformedEntry(e));
continue;
}
String eModule = m.group(1); // TODO: check a valid dotted identifier
String ePackage = m.group(2); // TODO: check a valid dotted identifier
String eTargets = m.group(3); // TODO: check a valid list of dotted identifier or ALL-UNNAMED
String eModPkg = eModule + '/' + ePackage;
List<String> l = map.get(eModPkg);
map.put(eModPkg, (l == null) ? List.of(eTargets) : l.prepend(eTargets));
}
map.forEach((key, value) -> {
if (value.size() > 1) {
log.error(Errors.XaddexportsTooMany(key));
// TODO: consider adding diag fragments for the entries
}
});
}
String addReads = options.get(Option.XADDREADS);
if (addReads != null) {
// Each entry must be of the form module=source-list where source-list is a
// comma separated list of module or ALL-UNNAMED.
// All target modules (i.e. on left of '=') must be unique.
Pattern p = Pattern.compile("([^=]+)=(.*)");
Map<String,List<String>> map = new LinkedHashMap<>();
for (String e: addReads.split("\0")) {
Matcher m = p.matcher(e);
if (!m.matches()) {
log.error(Errors.XaddreadsMalformedEntry(e));
continue;
}
String eModule = m.group(1); // TODO: check a valid dotted identifier
String eSources = m.group(2); // TODO: check a valid list of dotted identifier or ALL-UNNAMED
List<String> l = map.get(eModule);
map.put(eModule, (l == null) ? List.of(eSources) : l.prepend(eSources));
}
map.forEach((key, value) -> {
if (value.size() > 1) {
log.error(Errors.XaddreadsTooMany(key));
// TODO: consider adding diag fragments for the entries
}
});
}
return !errors; return !errors;
} }
@ -513,6 +676,10 @@ public class Arguments {
&& classNames.isEmpty(); && classNames.isEmpty();
} }
public void allowEmpty() {
this.emptyAllowed = true;
}
/** /**
* Gets the file manager options which may have been deferred * Gets the file manager options which may have been deferred
* during processArgs. * during processArgs.
@ -626,6 +793,7 @@ public class Arguments {
} }
private void report(String key, Object... args) { private void report(String key, Object... args) {
// Would be good to have support for -XDrawDiagnostics here
log.printRawLines(ownName + ": " + log.localize(PrefixKind.JAVAC, key, args)); log.printRawLines(ownName + ": " + log.localize(PrefixKind.JAVAC, key, args));
} }

View File

@ -39,6 +39,7 @@ import java.util.Set;
import javax.annotation.processing.Processor; import javax.annotation.processing.Processor;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.ElementVisitor;
import javax.tools.DiagnosticListener; import javax.tools.DiagnosticListener;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
@ -67,12 +68,20 @@ import com.sun.tools.javac.tree.JCTree.JCMemberReference;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.JCDiagnostic.Factory;
import com.sun.tools.javac.util.Log.WriterKind; import com.sun.tools.javac.util.Log.WriterKind;
import static com.sun.tools.javac.code.Kinds.Kind.*; import static com.sun.tools.javac.code.Kinds.Kind.*;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.main.Option.*; import static com.sun.tools.javac.main.Option.*;
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*; import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
import static javax.tools.StandardLocation.CLASS_OUTPUT; import static javax.tools.StandardLocation.CLASS_OUTPUT;
/** This class could be the main entry point for GJC when GJC is used as a /** This class could be the main entry point for GJC when GJC is used as a
@ -276,6 +285,18 @@ public class JavaCompiler {
*/ */
protected Flow flow; protected Flow flow;
/** The modules visitor
*/
protected Modules modules;
/** The module finder
*/
protected ModuleFinder moduleFinder;
/** The diagnostics factory
*/
protected JCDiagnostic.Factory diags;
/** The type eraser. /** The type eraser.
*/ */
protected TransTypes transTypes; protected TransTypes transTypes;
@ -336,6 +357,8 @@ public class JavaCompiler {
**/ **/
protected boolean implicitSourceFilesRead; protected boolean implicitSourceFilesRead;
protected boolean enterDone;
protected CompileStates compileStates; protected CompileStates compileStates;
/** Construct a new compiler using a shared context. /** Construct a new compiler using a shared context.
@ -382,6 +405,9 @@ public class JavaCompiler {
annotate = Annotate.instance(context); annotate = Annotate.instance(context);
types = Types.instance(context); types = Types.instance(context);
taskListener = MultiTaskListener.instance(context); taskListener = MultiTaskListener.instance(context);
modules = Modules.instance(context);
moduleFinder = ModuleFinder.instance(context);
diags = Factory.instance(context);
finder.sourceCompleter = sourceCompleter; finder.sourceCompleter = sourceCompleter;
@ -430,6 +456,18 @@ public class JavaCompiler {
if (platformProvider != null) if (platformProvider != null)
closeables = closeables.prepend(platformProvider); closeables = closeables.prepend(platformProvider);
silentFail = new Symbol(ABSENT_TYP, 0, names.empty, Type.noType, syms.rootPackage) {
@DefinedBy(Api.LANGUAGE_MODEL)
public <R, P> R accept(ElementVisitor<R, P> v, P p) {
return v.visitUnknown(this, p);
}
@Override
public boolean exists() {
return false;
}
};
} }
/* Switches: /* Switches:
@ -512,6 +550,11 @@ public class JavaCompiler {
*/ */
protected Set<JavaFileObject> inputFiles = new HashSet<>(); protected Set<JavaFileObject> inputFiles = new HashSet<>();
/** Used by the resolveBinaryNameOrIdent to say that the given type cannot be found, and that
* an error has already been produced about that.
*/
private final Symbol silentFail;
protected boolean shouldStop(CompileState cs) { protected boolean shouldStop(CompileState cs) {
CompileState shouldStopPolicy = (errorCount() > 0 || unrecoverableError()) CompileState shouldStopPolicy = (errorCount() > 0 || unrecoverableError())
? shouldStopPolicyIfError ? shouldStopPolicyIfError
@ -625,18 +668,44 @@ public class JavaCompiler {
* @param name The name to resolve * @param name The name to resolve
*/ */
public Symbol resolveBinaryNameOrIdent(String name) { public Symbol resolveBinaryNameOrIdent(String name) {
ModuleSymbol msym;
String typeName;
int sep = name.indexOf('/');
if (sep == -1) {
msym = modules.getDefaultModule();
typeName = name;
} else if (source.allowModules() && !options.isSet("noModules")) {
Name modName = names.fromString(name.substring(0, sep));
msym = moduleFinder.findModule(modName);
typeName = name.substring(sep + 1);
} else {
log.error(Errors.InvalidModuleSpecifier(name));
return silentFail;
}
return resolveBinaryNameOrIdent(msym, typeName);
}
/** Resolve an identifier which may be the binary name of a class or
* the Java name of a class or package.
* @param msym The module in which the search should be performed
* @param name The name to resolve
*/
public Symbol resolveBinaryNameOrIdent(ModuleSymbol msym, String name) {
try { try {
Name flatname = names.fromString(name.replace("/", ".")); Name flatname = names.fromString(name.replace("/", "."));
return finder.loadClass(flatname); return finder.loadClass(msym, flatname);
} catch (CompletionFailure ignore) { } catch (CompletionFailure ignore) {
return resolveIdent(name); return resolveIdent(msym, name);
} }
} }
/** Resolve an identifier. /** Resolve an identifier.
* @param msym The module in which the search should be performed
* @param name The identifier to resolve * @param name The identifier to resolve
*/ */
public Symbol resolveIdent(String name) { public Symbol resolveIdent(ModuleSymbol msym, String name) {
if (name.equals("")) if (name.equals(""))
return syms.errSymbol; return syms.errSymbol;
JavaFileObject prev = log.useSource(null); JavaFileObject prev = log.useSource(null);
@ -650,7 +719,8 @@ public class JavaCompiler {
} }
JCCompilationUnit toplevel = JCCompilationUnit toplevel =
make.TopLevel(List.<JCTree>nil()); make.TopLevel(List.<JCTree>nil());
toplevel.packge = syms.unnamedPackage; toplevel.modle = msym;
toplevel.packge = msym.unnamedPackage;
return attr.attribIdent(tree, toplevel); return attr.attribIdent(tree, toplevel);
} finally { } finally {
log.useSource(prev); log.useSource(prev);
@ -737,6 +807,16 @@ public class JavaCompiler {
taskListener.started(e); taskListener.started(e);
} }
// Process module declarations.
// If module resolution fails, ignore trees, and if trying to
// complete a specific symbol, throw CompletionFailure.
// Note that if module resolution failed, we may not even
// have enough modules available to access java.lang, and
// so risk getting FatalError("no.java.lang") from MemberEnter.
if (!modules.enter(List.of(tree), c)) {
throw new CompletionFailure(c, diags.fragment("cant.resolve.modules"));
}
enter.complete(List.of(tree), c); enter.complete(List.of(tree), c);
if (!taskListener.isEmpty()) { if (!taskListener.isEmpty()) {
@ -748,7 +828,16 @@ public class JavaCompiler {
boolean isPkgInfo = boolean isPkgInfo =
tree.sourcefile.isNameCompatible("package-info", tree.sourcefile.isNameCompatible("package-info",
JavaFileObject.Kind.SOURCE); JavaFileObject.Kind.SOURCE);
if (isPkgInfo) { boolean isModuleInfo =
tree.sourcefile.isNameCompatible("module-info",
JavaFileObject.Kind.SOURCE);
if (isModuleInfo) {
if (enter.getEnv(tree.modle) == null) {
JCDiagnostic diag =
diagFactory.fragment("file.does.not.contain.module");
throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
}
} else if (isPkgInfo) {
if (enter.getEnv(tree.packge) == null) { if (enter.getEnv(tree.packge) == null) {
JCDiagnostic diag = JCDiagnostic diag =
diagFactory.fragment("file.does.not.contain.package", diagFactory.fragment("file.does.not.contain.package",
@ -812,8 +901,12 @@ public class JavaCompiler {
// These method calls must be chained to avoid memory leaks // These method calls must be chained to avoid memory leaks
processAnnotations( processAnnotations(
enterTrees(stopIfError(CompileState.PARSE, parseFiles(sourceFileObjects))), enterTrees(
classnames); stopIfError(CompileState.PARSE,
initModules(stopIfError(CompileState.PARSE, parseFiles(sourceFileObjects))))
),
classnames
);
// If it's safe to do so, skip attr / flow / gen for implicit classes // If it's safe to do so, skip attr / flow / gen for implicit classes
if (taskListener.isEmpty() && if (taskListener.isEmpty() &&
@ -912,7 +1005,20 @@ public class JavaCompiler {
public List<JCCompilationUnit> enterTreesIfNeeded(List<JCCompilationUnit> roots) { public List<JCCompilationUnit> enterTreesIfNeeded(List<JCCompilationUnit> roots) {
if (shouldStop(CompileState.ATTR)) if (shouldStop(CompileState.ATTR))
return List.nil(); return List.nil();
return enterTrees(roots); return enterTrees(initModules(roots));
}
public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
List<JCCompilationUnit> result = initModules(roots, null);
if (roots.isEmpty()) {
enterDone = true;
}
return result;
}
List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots, ClassSymbol c) {
modules.enter(roots, c);
return roots;
} }
/** /**
@ -931,6 +1037,8 @@ public class JavaCompiler {
enter.main(roots); enter.main(roots);
enterDone = true;
if (!taskListener.isEmpty()) { if (!taskListener.isEmpty()) {
for (JCCompilationUnit unit: roots) { for (JCCompilationUnit unit: roots) {
TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit); TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
@ -1085,7 +1193,8 @@ public class JavaCompiler {
if (sym == null || if (sym == null ||
(sym.kind == PCK && !processPcks) || (sym.kind == PCK && !processPcks) ||
sym.kind == ABSENT_TYP) { sym.kind == ABSENT_TYP) {
log.error("proc.cant.find.class", nameStr); if (sym != silentFail)
log.error(Errors.ProcCantFindClass(nameStr));
errors = true; errors = true;
continue; continue;
} }
@ -1100,10 +1209,10 @@ public class JavaCompiler {
continue; continue;
} }
Assert.check(sym.kind == PCK); Assert.check(sym.kind == PCK);
log.warning("proc.package.does.not.exist", nameStr); log.warning(Warnings.ProcPackageDoesNotExist(nameStr));
pckSymbols = pckSymbols.prepend((PackageSymbol)sym); pckSymbols = pckSymbols.prepend((PackageSymbol)sym);
} catch (CompletionFailure e) { } catch (CompletionFailure e) {
log.error("proc.cant.find.class", nameStr); log.error(Errors.ProcCantFindClass(nameStr));
errors = true; errors = true;
continue; continue;
} }
@ -1154,6 +1263,7 @@ public class JavaCompiler {
return return
options.isSet(PROCESSOR) || options.isSet(PROCESSOR) ||
options.isSet(PROCESSORPATH) || options.isSet(PROCESSORPATH) ||
options.isSet(PROCESSORMODULEPATH) ||
options.isSet(PROC, "only") || options.isSet(PROC, "only") ||
options.isSet(XPRINT); options.isSet(XPRINT);
} }
@ -1388,14 +1498,14 @@ public class JavaCompiler {
make.at(Position.FIRSTPOS); make.at(Position.FIRSTPOS);
TreeMaker localMake = make.forToplevel(env.toplevel); TreeMaker localMake = make.forToplevel(env.toplevel);
if (env.tree.hasTag(JCTree.Tag.PACKAGEDEF)) { if (env.tree.hasTag(JCTree.Tag.PACKAGEDEF) || env.tree.hasTag(JCTree.Tag.MODULEDEF)) {
if (!(sourceOutput)) { if (!(sourceOutput)) {
if (shouldStop(CompileState.LOWER)) if (shouldStop(CompileState.LOWER))
return; return;
List<JCTree> pdef = lower.translateTopLevelClass(env, env.tree, localMake); List<JCTree> def = lower.translateTopLevelClass(env, env.tree, localMake);
if (pdef.head != null) { if (def.head != null) {
Assert.check(pdef.tail.isEmpty()); Assert.check(def.tail.isEmpty());
results.add(new Pair<>(env, (JCClassDecl)pdef.head)); results.add(new Pair<>(env, (JCClassDecl)def.head));
} }
} }
return; return;
@ -1589,6 +1699,10 @@ public class JavaCompiler {
} }
} }
public boolean isEnterDone() {
return enterDone;
}
/** Close the compiler, flushing the logs /** Close the compiler, flushing the logs
*/ */
public void close() { public void close() {

View File

@ -27,6 +27,7 @@ package com.sun.tools.javac.main;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.net.URL; import java.net.URL;
import java.nio.file.NoSuchFileException; import java.nio.file.NoSuchFileException;
@ -144,7 +145,8 @@ public class Main {
try { try {
// A fresh context was created above, so jfm must be a JavacFileManager // A fresh context was created above, so jfm must be a JavacFileManager
((JavacFileManager)fileManager).close(); ((JavacFileManager)fileManager).close();
} catch (IOException ignore) { } catch (IOException ex) {
bugMessage(ex);
} }
} }
return result; return result;
@ -204,11 +206,13 @@ public class Main {
if (batchMode) if (batchMode)
CacheFSInfo.preRegister(context); CacheFSInfo.preRegister(context);
boolean ok = true;
// init file manager // init file manager
fileManager = context.get(JavaFileManager.class); fileManager = context.get(JavaFileManager.class);
if (fileManager instanceof BaseFileManager) { if (fileManager instanceof BaseFileManager) {
((BaseFileManager) fileManager).setContext(context); // reinit with options ((BaseFileManager) fileManager).setContext(context); // reinit with options
((BaseFileManager) fileManager).handleOptions(args.getDeferredFileManagerOptions()); ok &= ((BaseFileManager) fileManager).handleOptions(args.getDeferredFileManagerOptions());
} }
// handle this here so it works even if no other options given // handle this here so it works even if no other options given
@ -219,7 +223,7 @@ public class Main {
showClass(showClass); showClass(showClass);
} }
boolean ok = args.validate(); ok &= args.validate();
if (!ok || log.nerrors > 0) if (!ok || log.nerrors > 0)
return Result.CMDERR; return Result.CMDERR;
@ -348,28 +352,28 @@ public class Main {
void showClass(String className) { void showClass(String className) {
PrintWriter pw = log.getWriter(WriterKind.NOTICE); PrintWriter pw = log.getWriter(WriterKind.NOTICE);
pw.println("javac: show class: " + className); pw.println("javac: show class: " + className);
URL url = getClass().getResource('/' + className.replace('.', '/') + ".class"); URL url = getClass().getResource('/' + className.replace('.', '/') + ".class");
if (url == null) if (url != null) {
pw.println(" class not found");
else {
pw.println(" " + url); pw.println(" " + url);
try { }
final String algorithm = "MD5";
byte[] digest; try (InputStream in = getClass().getResourceAsStream('/' + className.replace('.', '/') + ".class")) {
MessageDigest md = MessageDigest.getInstance(algorithm); final String algorithm = "MD5";
try (DigestInputStream in = new DigestInputStream(url.openStream(), md)) { byte[] digest;
byte[] buf = new byte[8192]; MessageDigest md = MessageDigest.getInstance(algorithm);
int n; try (DigestInputStream din = new DigestInputStream(in, md)) {
do { n = in.read(buf); } while (n > 0); byte[] buf = new byte[8192];
digest = md.digest(); int n;
} do { n = din.read(buf); } while (n > 0);
StringBuilder sb = new StringBuilder(); digest = md.digest();
for (byte b: digest)
sb.append(String.format("%02x", b));
pw.println(" " + algorithm + " checksum: " + sb);
} catch (NoSuchAlgorithmException | IOException e) {
pw.println(" cannot compute digest: " + e);
} }
StringBuilder sb = new StringBuilder();
for (byte b: digest)
sb.append(String.format("%02x", b));
pw.println(" " + algorithm + " checksum: " + sb);
} catch (NoSuchAlgorithmException | IOException e) {
pw.println(" cannot compute digest: " + e);
} }
} }

View File

@ -184,6 +184,23 @@ public enum Option {
SOURCEPATH("-sourcepath", "opt.arg.path", "opt.sourcepath", STANDARD, FILEMANAGER), SOURCEPATH("-sourcepath", "opt.arg.path", "opt.sourcepath", STANDARD, FILEMANAGER),
MODULESOURCEPATH("-modulesourcepath", "opt.arg.mspath", "opt.modulesourcepath", STANDARD, FILEMANAGER),
MODULEPATH("-modulepath", "opt.arg.path", "opt.modulepath", STANDARD, FILEMANAGER),
MP("-mp", "opt.arg.path", "opt.modulepath", STANDARD, FILEMANAGER) {
@Override
public boolean process(OptionHelper helper, String option, String arg) {
return super.process(helper, "-modulepath", arg);
}
},
UPGRADEMODULEPATH("-upgrademodulepath", "opt.arg.path", "opt.upgrademodulepath", STANDARD, FILEMANAGER),
SYSTEM("-system", "opt.arg.jdk", "opt.system", STANDARD, FILEMANAGER),
XPATCH("-Xpatch:", "opt.arg.path", "opt.Xpatch", EXTENDED, FILEMANAGER),
BOOTCLASSPATH("-bootclasspath", "opt.arg.path", "opt.bootclasspath", STANDARD, FILEMANAGER) { BOOTCLASSPATH("-bootclasspath", "opt.arg.path", "opt.bootclasspath", STANDARD, FILEMANAGER) {
@Override @Override
public boolean process(OptionHelper helper, String option, String arg) { public boolean process(OptionHelper helper, String option, String arg) {
@ -230,6 +247,8 @@ public enum Option {
PROCESSORPATH("-processorpath", "opt.arg.path", "opt.processorpath", STANDARD, FILEMANAGER), PROCESSORPATH("-processorpath", "opt.arg.path", "opt.processorpath", STANDARD, FILEMANAGER),
PROCESSORMODULEPATH("-processormodulepath", "opt.arg.path", "opt.processormodulepath", STANDARD, FILEMANAGER),
PARAMETERS("-parameters","opt.parameters", STANDARD, BASIC), PARAMETERS("-parameters","opt.parameters", STANDARD, BASIC),
D("-d", "opt.arg.directory", "opt.d", STANDARD, FILEMANAGER), D("-d", "opt.arg.directory", "opt.d", STANDARD, FILEMANAGER),
@ -478,9 +497,9 @@ public enum Option {
PLUGIN("-Xplugin:", "opt.arg.plugin", "opt.plugin", EXTENDED, BASIC) { PLUGIN("-Xplugin:", "opt.arg.plugin", "opt.plugin", EXTENDED, BASIC) {
@Override @Override
public boolean process(OptionHelper helper, String option) { public boolean process(OptionHelper helper, String option) {
String p = option.substring(option.indexOf(':') + 1); String p = option.substring(option.indexOf(':') + 1).trim();
String prev = helper.get(PLUGIN); String prev = helper.get(PLUGIN);
helper.put(PLUGIN.text, (prev == null) ? p : prev + '\0' + p.trim()); helper.put(PLUGIN.text, (prev == null) ? p : prev + '\0' + p);
return false; return false;
} }
}, },
@ -507,6 +526,106 @@ public enum Option {
} }
}, },
XADDEXPORTS("-XaddExports:", "opt.arg.addExports", "opt.addExports", EXTENDED, BASIC) {
@Override
public boolean process(OptionHelper helper, String option) {
if (option.matches(".*,.*=.*")) { // temporary, for backwards compatibility
return processOldStyle(helper, option);
}
String p = option.substring(option.indexOf(':') + 1).trim();
String prev = helper.get(XADDEXPORTS);
helper.put(XADDEXPORTS.text, (prev == null) ? p : prev + '\0' + p);
return false;
}
// convert old style option into a series of new-style options
private boolean processOldStyle(OptionHelper helper, String option) {
String p = option.substring(option.indexOf(':') + 1).trim();
String[] entries = p.split("[ ,]+");
Map<String, String> map = new LinkedHashMap<>();
for (String e: entries) {
// Each entry is of the form module/package=target
// we must group values for the same module/package together
int eq = e.indexOf('=');
if (eq == -1) {
// don't bother with error message for backwards compatible support
continue;
}
String modPkg = e.substring(0, eq);
String target = e.substring(eq + 1);
String targets = map.get(modPkg);
map.put(modPkg, (targets == null) ? target : targets + "," + target);
}
boolean ok = true;
for (Map.Entry<String, String> e: map.entrySet()) {
// process as new-style options
String key = e.getKey();
String value = e.getValue();
ok = ok & process(helper, XADDEXPORTS.text + key + "=" + value);
};
return ok;
}
},
XADDREADS("-XaddReads:", "opt.arg.addReads", "opt.addReads", EXTENDED, BASIC) {
@Override
public boolean process(OptionHelper helper, String option) {
if (option.matches(".*,.*=.*")) { // temporary, for backwards compatibility
return processOldStyle(helper, option);
}
String p = option.substring(option.indexOf(':') + 1).trim();
String prev = helper.get(XADDREADS);
helper.put(XADDREADS.text, (prev == null) ? p : prev + '\0' + p);
return false;
}
// convert old style option into a series of new-style options
private boolean processOldStyle(OptionHelper helper, String option) {
String p = option.substring(option.indexOf(':') + 1).trim();
String[] entries = p.split("[ ,]+");
Map<String, String> map = new LinkedHashMap<>();
for (String e: entries) {
// Each entry is of the form module=target
// we must group values for the same module together
int eq = e.indexOf('=');
if (eq == -1) {
// don't bother with error message for backwards compatible support
continue;
}
String modPkg = e.substring(0, eq);
String target = e.substring(eq + 1);
String targets = map.get(modPkg);
map.put(modPkg, (targets == null) ? target : targets + "," + target);
}
boolean ok = true;
for (Map.Entry<String, String> e: map.entrySet()) {
// process as new-style options
String key = e.getKey();
String value = e.getValue();
ok = ok & process(helper, XADDEXPORTS.text + key + "=" + value);
};
return ok;
}
},
XMODULE("-Xmodule:", "opt.arg.module", "opt.module", EXTENDED, BASIC) {
@Override
public boolean process(OptionHelper helper, String option) {
String prev = helper.get(XMODULE);
if (prev != null) {
helper.error("err.option.too.many", XMODULE.text);
}
String p = option.substring(option.indexOf(':') + 1);
helper.put(XMODULE.text, p);
return false;
}
},
M("-m", "opt.arg.m", "opt.m", STANDARD, BASIC),
ADDMODS("-addmods", "opt.arg.addmods", "opt.addmods", STANDARD, BASIC),
LIMITMODS("-limitmods", "opt.arg.limitmods", "opt.limitmods", STANDARD, BASIC),
// This option exists only for the purpose of documenting itself. // This option exists only for the purpose of documenting itself.
// It's actually implemented by the CommandLine class. // It's actually implemented by the CommandLine class.
AT("@", "opt.arg.file", "opt.AT", STANDARD, INFO, true) { AT("@", "opt.arg.file", "opt.AT", STANDARD, INFO, true) {
@ -516,19 +635,19 @@ public enum Option {
} }
}, },
/* // Standalone positional argument: source file or type name.
* TODO: With apt, the matches method accepts anything if
* -XclassAsDecls is used; code elsewhere does the lookup to
* see if the class name is both legal and found.
*
* In apt, the process method adds the candidate class file
* name to a separate list.
*/
SOURCEFILE("sourcefile", null, HIDDEN, INFO) { SOURCEFILE("sourcefile", null, HIDDEN, INFO) {
@Override @Override
public boolean matches(String s) { public boolean matches(String s) {
return s.endsWith(".java") // Java source file if (s.endsWith(".java")) // Java source file
|| SourceVersion.isName(s); // Legal type name return true;
int sep = s.indexOf('/');
if (sep != -1) {
return SourceVersion.isName(s.substring(0, sep))
&& SourceVersion.isName(s.substring(sep + 1));
} else {
return SourceVersion.isName(s); // Legal type name
}
} }
@Override @Override
public boolean process(OptionHelper helper, String option) { public boolean process(OptionHelper helper, String option) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -34,6 +34,8 @@ import javax.lang.model.util.Elements;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import static javax.lang.model.util.ElementFilter.methodsIn; import static javax.lang.model.util.ElementFilter.methodsIn;
import com.sun.source.util.JavacTask;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope; import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
@ -52,6 +54,9 @@ import com.sun.tools.javac.util.Name;
import static com.sun.tools.javac.code.Kinds.Kind.*; import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE; import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.code.TypeTag.CLASS;
import com.sun.tools.javac.comp.CompileStates;
import com.sun.tools.javac.comp.CompileStates.CompileState;
import com.sun.tools.javac.comp.Modules;
import static com.sun.tools.javac.tree.JCTree.Tag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*;
/** /**
@ -66,9 +71,12 @@ public class JavacElements implements Elements {
private final JavaCompiler javaCompiler; private final JavaCompiler javaCompiler;
private final Symtab syms; private final Symtab syms;
private final Modules modules;
private final Names names; private final Names names;
private final Types types; private final Types types;
private final Enter enter; private final Enter enter;
private final JavacTaskImpl javacTaskImpl;
private final CompileStates compileStates;
public static JavacElements instance(Context context) { public static JavacElements instance(Context context) {
JavacElements instance = context.get(JavacElements.class); JavacElements instance = context.get(JavacElements.class);
@ -81,43 +89,66 @@ public class JavacElements implements Elements {
context.put(JavacElements.class, this); context.put(JavacElements.class, this);
javaCompiler = JavaCompiler.instance(context); javaCompiler = JavaCompiler.instance(context);
syms = Symtab.instance(context); syms = Symtab.instance(context);
modules = Modules.instance(context);
names = Names.instance(context); names = Names.instance(context);
types = Types.instance(context); types = Types.instance(context);
enter = Enter.instance(context); enter = Enter.instance(context);
JavacTask t = context.get(JavacTask.class);
javacTaskImpl = t instanceof JavacTaskImpl ? (JavacTaskImpl) t : null;
compileStates = CompileStates.instance(context);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public ModuleSymbol getModuleElement(CharSequence name) {
ensureEntered("getModuleElement");
String strName = name.toString();
if (strName.equals(""))
return syms.unnamedModule;
return modules.getObservableModule(names.fromString(strName));
} }
@DefinedBy(Api.LANGUAGE_MODEL) @DefinedBy(Api.LANGUAGE_MODEL)
public PackageSymbol getPackageElement(CharSequence name) { public PackageSymbol getPackageElement(CharSequence name) {
ensureEntered("getPackageElement");
return getPackageElement(modules.getDefaultModule(), name);
}
public PackageSymbol getPackageElement(ModuleElement module, CharSequence name) {
String strName = name.toString(); String strName = name.toString();
if (strName.equals("")) if (strName.equals(""))
return syms.unnamedPackage; return syms.unnamedModule.unnamedPackage;
return SourceVersion.isName(strName) return SourceVersion.isName(strName)
? nameToSymbol(strName, PackageSymbol.class) ? nameToSymbol((ModuleSymbol) module, strName, PackageSymbol.class)
: null; : null;
} }
@DefinedBy(Api.LANGUAGE_MODEL) @DefinedBy(Api.LANGUAGE_MODEL)
public ClassSymbol getTypeElement(CharSequence name) { public ClassSymbol getTypeElement(CharSequence name) {
ensureEntered("getTypeElement");
return getTypeElement(modules.getDefaultModule(), name);
}
public ClassSymbol getTypeElement(ModuleElement module, CharSequence name) {
String strName = name.toString(); String strName = name.toString();
return SourceVersion.isName(strName) return SourceVersion.isName(strName)
? nameToSymbol(strName, ClassSymbol.class) ? nameToSymbol((ModuleSymbol) module, strName, ClassSymbol.class)
: null; : null;
} }
/** /**
* Returns a symbol given the type's or packages's canonical name, * Returns a symbol given the type's or package's canonical name,
* or null if the name isn't found. * or null if the name isn't found.
*/ */
private <S extends Symbol> S nameToSymbol(String nameStr, Class<S> clazz) { private <S extends Symbol> S nameToSymbol(ModuleSymbol module, String nameStr, Class<S> clazz) {
Name name = names.fromString(nameStr); Name name = names.fromString(nameStr);
// First check cache. // First check cache.
Symbol sym = (clazz == ClassSymbol.class) Symbol sym = (clazz == ClassSymbol.class)
? syms.classes.get(name) ? syms.getClass(module, name)
: syms.packages.get(name); : syms.lookupPackage(module, name);
try { try {
if (sym == null) if (sym == null)
sym = javaCompiler.resolveIdent(nameStr); sym = javaCompiler.resolveIdent(module, nameStr);
sym.complete(); sym.complete();
@ -333,6 +364,12 @@ public class JavacElements implements Elements {
return cast(Symbol.class, e).packge(); return cast(Symbol.class, e).packge();
} }
@DefinedBy(Api.LANGUAGE_MODEL)
public ModuleElement getModuleOf(Element e) {
Symbol sym = cast(Symbol.class, e);
return (sym.kind == MDL) ? ((ModuleElement) e) : sym.packge().modle;
}
@DefinedBy(Api.LANGUAGE_MODEL) @DefinedBy(Api.LANGUAGE_MODEL)
public boolean isDeprecated(Element e) { public boolean isDeprecated(Element e) {
Symbol sym = cast(Symbol.class, e); Symbol sym = cast(Symbol.class, e);
@ -601,6 +638,15 @@ public class JavacElements implements Elements {
: null; : null;
} }
private void ensureEntered(String methodName) {
if (javacTaskImpl != null) {
javacTaskImpl.ensureEntered();
}
if (!javaCompiler.isEnterDone()) {
throw new IllegalStateException("Cannot use Elements." + methodName + " before the TaskEvent.Kind.ENTER finished event.");
}
}
/** /**
* Returns an object cast to the specified type. * Returns an object cast to the specified type.
* @throws NullPointerException if the object is {@code null} * @throws NullPointerException if the object is {@code null}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -34,6 +34,7 @@ import com.sun.tools.javac.code.*;
import com.sun.tools.javac.parser.Tokens.*; import com.sun.tools.javac.parser.Tokens.*;
import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
import com.sun.tools.javac.resources.CompilerProperties; import com.sun.tools.javac.resources.CompilerProperties;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
@ -158,6 +159,7 @@ public class JavacParser implements Parser {
this.allowStaticInterfaceMethods = source.allowStaticInterfaceMethods(); this.allowStaticInterfaceMethods = source.allowStaticInterfaceMethods();
this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast(); this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast();
this.allowTypeAnnotations = source.allowTypeAnnotations(); this.allowTypeAnnotations = source.allowTypeAnnotations();
this.allowModules = source.allowModules();
this.allowAnnotationsAfterTypeParams = source.allowAnnotationsAfterTypeParams(); this.allowAnnotationsAfterTypeParams = source.allowAnnotationsAfterTypeParams();
this.allowUnderscoreIdentifier = source.allowUnderscoreIdentifier(); this.allowUnderscoreIdentifier = source.allowUnderscoreIdentifier();
this.allowPrivateInterfaceMethods = source.allowPrivateInterfaceMethods(); this.allowPrivateInterfaceMethods = source.allowPrivateInterfaceMethods();
@ -206,6 +208,10 @@ public class JavacParser implements Parser {
*/ */
boolean allowMethodReferences; boolean allowMethodReferences;
/** Switch: should we recognize modules?
*/
boolean allowModules;
/** Switch: should we allow default methods in interfaces? /** Switch: should we allow default methods in interfaces?
*/ */
boolean allowDefaultMethods; boolean allowDefaultMethods;
@ -3096,59 +3102,65 @@ public class JavacParser implements Parser {
Token firstToken = token; Token firstToken = token;
JCModifiers mods = null; JCModifiers mods = null;
boolean consumedToplevelDoc = false; boolean consumedToplevelDoc = false;
boolean seenImport = false;
boolean seenPackage = false;
ListBuffer<JCTree> defs = new ListBuffer<>(); ListBuffer<JCTree> defs = new ListBuffer<>();
if (token.kind == MONKEYS_AT)
mods = modifiersOpt();
if (token.kind == PACKAGE) { if (token.kind == IDENTIFIER && token.name() == names.module) {
int packagePos = token.pos; defs.append(moduleDecl(token.comment(CommentStyle.JAVADOC)));
List<JCAnnotation> annotations = List.nil();
seenPackage = true;
if (mods != null) {
checkNoMods(mods.flags);
annotations = mods.annotations;
mods = null;
}
nextToken();
JCExpression pid = qualident(false);
accept(SEMI);
JCPackageDecl pd = F.at(packagePos).PackageDecl(annotations, pid);
attach(pd, firstToken.comment(CommentStyle.JAVADOC));
consumedToplevelDoc = true; consumedToplevelDoc = true;
storeEnd(pd, token.pos); } else {
defs.append(pd); boolean seenImport = false;
boolean seenPackage = false;
if (token.kind == MONKEYS_AT)
mods = modifiersOpt();
if (token.kind == PACKAGE) {
int packagePos = token.pos;
List<JCAnnotation> annotations = List.nil();
seenPackage = true;
if (mods != null) {
checkNoMods(mods.flags);
annotations = mods.annotations;
mods = null;
}
nextToken();
JCExpression pid = qualident(false);
accept(SEMI);
JCPackageDecl pd = F.at(packagePos).PackageDecl(annotations, pid);
attach(pd, firstToken.comment(CommentStyle.JAVADOC));
consumedToplevelDoc = true;
storeEnd(pd, token.pos);
defs.append(pd);
}
boolean checkForImports = true;
boolean firstTypeDecl = true;
while (token.kind != EOF) {
if (token.pos <= endPosTable.errorEndPos) {
// error recovery
skip(checkForImports, false, false, false);
if (token.kind == EOF)
break;
}
if (checkForImports && mods == null && token.kind == IMPORT) {
seenImport = true;
defs.append(importDeclaration());
} else {
Comment docComment = token.comment(CommentStyle.JAVADOC);
if (firstTypeDecl && !seenImport && !seenPackage) {
docComment = firstToken.comment(CommentStyle.JAVADOC);
consumedToplevelDoc = true;
}
JCTree def = typeDeclaration(mods, docComment);
if (def instanceof JCExpressionStatement)
def = ((JCExpressionStatement)def).expr;
defs.append(def);
if (def instanceof JCClassDecl)
checkForImports = false;
mods = null;
firstTypeDecl = false;
}
}
} }
boolean checkForImports = true;
boolean firstTypeDecl = true;
while (token.kind != EOF) {
if (token.pos <= endPosTable.errorEndPos) {
// error recovery
skip(checkForImports, false, false, false);
if (token.kind == EOF)
break;
}
if (checkForImports && mods == null && token.kind == IMPORT) {
seenImport = true;
defs.append(importDeclaration());
} else {
Comment docComment = token.comment(CommentStyle.JAVADOC);
if (firstTypeDecl && !seenImport && !seenPackage) {
docComment = firstToken.comment(CommentStyle.JAVADOC);
consumedToplevelDoc = true;
}
JCTree def = typeDeclaration(mods, docComment);
if (def instanceof JCExpressionStatement)
def = ((JCExpressionStatement)def).expr;
defs.append(def);
if (def instanceof JCClassDecl)
checkForImports = false;
mods = null;
firstTypeDecl = false;
}
}
JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(defs.toList()); JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(defs.toList());
if (!consumedToplevelDoc) if (!consumedToplevelDoc)
attach(toplevel, firstToken.comment(CommentStyle.JAVADOC)); attach(toplevel, firstToken.comment(CommentStyle.JAVADOC));
@ -3163,6 +3175,75 @@ public class JavacParser implements Parser {
return toplevel; return toplevel;
} }
JCModuleDecl moduleDecl(Comment dc) {
int pos = token.pos;
if (!allowModules) {
log.error(pos, Errors.ModulesNotSupportedInSource(source.name));
allowModules = true;
}
nextToken();
JCExpression name = qualident(false);
List<JCDirective> directives = null;
accept(LBRACE);
directives = moduleDirectiveList();
accept(RBRACE);
accept(EOF);
JCModuleDecl result = toP(F.at(pos).ModuleDef(name, directives));
attach(result, dc);
return result;
}
List<JCDirective> moduleDirectiveList() {
ListBuffer<JCDirective> defs = new ListBuffer<>();
while (token.kind == IDENTIFIER) {
int pos = token.pos;
if (token.name() == names.requires) {
nextToken();
boolean isPublic = false;
if (token.kind == PUBLIC) {
isPublic = true;
nextToken();
}
JCExpression moduleName = qualident(false);
accept(SEMI);
defs.append(toP(F.at(pos).Requires(isPublic, moduleName)));
} else if (token.name() == names.exports) {
nextToken();
JCExpression pkgName = qualident(false);
List<JCExpression> moduleNames = null;
if (token.kind == IDENTIFIER && token.name() == names.to) {
nextToken();
moduleNames = qualidentList();
}
accept(SEMI);
defs.append(toP(F.at(pos).Exports(pkgName, moduleNames)));
} else if (token.name() == names.provides) {
nextToken();
JCExpression serviceName = qualident(false);
if (token.kind == IDENTIFIER && token.name() == names.with) {
nextToken();
JCExpression implName = qualident(false);
accept(SEMI);
defs.append(toP(F.at(pos).Provides(serviceName, implName)));
} else {
error(token.pos, "expected", "'" + names.with + "'");
skip(false, false, false, false);
}
} else if (token.name() == names.uses) {
nextToken();
JCExpression service = qualident(false);
accept(SEMI);
defs.append(toP(F.at(pos).Uses(service)));
} else {
break;
}
}
return defs.toList();
}
/** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";" /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
*/ */
protected JCTree importDeclaration() { protected JCTree importDeclaration() {

View File

@ -27,8 +27,10 @@ package com.sun.tools.javac.processing;
import java.io.Closeable; import java.io.Closeable;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.lang.reflect.Method;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.nio.file.Path; import java.nio.file.Path;
@ -42,6 +44,7 @@ import javax.lang.model.element.*;
import javax.lang.model.util.*; import javax.lang.model.util.*;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardJavaFileManager; import javax.tools.StandardJavaFileManager;
import static javax.tools.StandardLocation.*; import static javax.tools.StandardLocation.*;
@ -49,6 +52,7 @@ import static javax.tools.StandardLocation.*;
import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskEvent;
import com.sun.tools.javac.api.MultiTaskListener; import com.sun.tools.javac.api.MultiTaskListener;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.ClassType; import com.sun.tools.javac.code.Type.ClassType;
import com.sun.tools.javac.code.Types; import com.sun.tools.javac.code.Types;
@ -56,12 +60,14 @@ import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Check; import com.sun.tools.javac.comp.Check;
import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.comp.Modules;
import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.main.JavaCompiler;
import com.sun.tools.javac.model.JavacElements; import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.model.JavacTypes; import com.sun.tools.javac.model.JavacTypes;
import com.sun.tools.javac.platform.PlatformDescription; import com.sun.tools.javac.platform.PlatformDescription;
import com.sun.tools.javac.platform.PlatformDescription.PluginInfo; import com.sun.tools.javac.platform.PlatformDescription.PluginInfo;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.Abort; import com.sun.tools.javac.util.Abort;
@ -77,10 +83,10 @@ import com.sun.tools.javac.util.JavacMessages;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.MatchingUtils; import com.sun.tools.javac.util.MatchingUtils;
import com.sun.tools.javac.util.ModuleHelper;
import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Names;
import com.sun.tools.javac.util.Options; import com.sun.tools.javac.util.Options;
import com.sun.tools.javac.util.ServiceLoader;
import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING; import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
import static com.sun.tools.javac.code.Kinds.Kind.*; import static com.sun.tools.javac.code.Kinds.Kind.*;
@ -112,8 +118,10 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
private final JavacMessager messager; private final JavacMessager messager;
private final JavacElements elementUtils; private final JavacElements elementUtils;
private final JavacTypes typeUtils; private final JavacTypes typeUtils;
private final Types types;
private final JavaCompiler compiler; private final JavaCompiler compiler;
private final Modules modules;
private final ModuleHelper moduleHelper;
private final Types types;
/** /**
* Holds relevant state history of which processors have been * Holds relevant state history of which processors have been
@ -154,7 +162,10 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
Source source; Source source;
private ClassLoader processorClassLoader; private ClassLoader processorClassLoader;
private SecurityException processorClassLoaderException; private ServiceLoader<Processor> serviceLoader;
private SecurityException processorLoaderException;
private final JavaFileManager fileManager;
/** /**
* JavacMessages object used for localization * JavacMessages object used for localization
@ -167,6 +178,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
private final Enter enter; private final Enter enter;
private final Completer initialCompleter; private final Completer initialCompleter;
private final Check chk; private final Check chk;
private final ModuleSymbol defaultModule;
private final Context context; private final Context context;
@ -196,6 +208,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
fatalErrors = options.isSet("fatalEnterError"); fatalErrors = options.isSet("fatalEnterError");
showResolveErrors = options.isSet("showResolveErrors"); showResolveErrors = options.isSet("showResolveErrors");
werror = options.isSet(WERROR); werror = options.isSet(WERROR);
fileManager = context.get(JavaFileManager.class);
platformAnnotations = initPlatformAnnotations(); platformAnnotations = initPlatformAnnotations();
// Initialize services before any processors are initialized // Initialize services before any processors are initialized
@ -204,6 +217,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
messager = new JavacMessager(context, this); messager = new JavacMessager(context, this);
elementUtils = JavacElements.instance(context); elementUtils = JavacElements.instance(context);
typeUtils = JavacTypes.instance(context); typeUtils = JavacTypes.instance(context);
modules = Modules.instance(context);
types = Types.instance(context); types = Types.instance(context);
processorOptions = initProcessorOptions(); processorOptions = initProcessorOptions();
unmatchedProcessorOptions = initUnmatchedProcessorOptions(); unmatchedProcessorOptions = initUnmatchedProcessorOptions();
@ -214,7 +228,11 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
enter = Enter.instance(context); enter = Enter.instance(context);
initialCompleter = ClassFinder.instance(context).getCompleter(); initialCompleter = ClassFinder.instance(context).getCompleter();
chk = Check.instance(context); chk = Check.instance(context);
initProcessorClassLoader(); moduleHelper = ModuleHelper.instance(context);
initProcessorLoader();
defaultModule = source.allowModules() && options.isUnset("noModules")
? symtab.unnamedModule : symtab.noModule;
} }
public void setProcessors(Iterable<? extends Processor> processors) { public void setProcessors(Iterable<? extends Processor> processors) {
@ -234,19 +252,28 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
return Collections.unmodifiableSet(platformAnnotations); return Collections.unmodifiableSet(platformAnnotations);
} }
private void initProcessorClassLoader() { private void initProcessorLoader() {
JavaFileManager fileManager = context.get(JavaFileManager.class);
try { try {
// If processorpath is not explicitly set, use the classpath. if (fileManager.hasLocation(ANNOTATION_PROCESSOR_MODULE_PATH)) {
processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) try {
? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH) serviceLoader = fileManager.getServiceLoader(ANNOTATION_PROCESSOR_MODULE_PATH, Processor.class);
: fileManager.getClassLoader(CLASS_PATH); } catch (IOException e) {
throw new Abort(e);
}
} else {
// If processorpath is not explicitly set, use the classpath.
processorClassLoader = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH)
: fileManager.getClassLoader(CLASS_PATH);
if (processorClassLoader != null && processorClassLoader instanceof Closeable) { moduleHelper.addExports(processorClassLoader);
compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader);
if (processorClassLoader != null && processorClassLoader instanceof Closeable) {
compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader);
}
} }
} catch (SecurityException e) { } catch (SecurityException e) {
processorClassLoaderException = e; processorLoaderException = e;
} }
} }
@ -266,14 +293,18 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
} else if (processors != null) { } else if (processors != null) {
processorIterator = processors.iterator(); processorIterator = processors.iterator();
} else { } else {
String processorNames = options.get(PROCESSOR); if (processorLoaderException == null) {
if (processorClassLoaderException == null) {
/* /*
* If the "-processor" option is used, search the appropriate * If the "-processor" option is used, search the appropriate
* path for the named class. Otherwise, use a service * path for the named class. Otherwise, use a service
* provider mechanism to create the processor iterator. * provider mechanism to create the processor iterator.
*/ */
if (processorNames != null) { String processorNames = options.get(PROCESSOR);
if (fileManager.hasLocation(ANNOTATION_PROCESSOR_MODULE_PATH)) {
processorIterator = (processorNames == null) ?
new ServiceIterator(serviceLoader, log) :
new NameServiceIterator(serviceLoader, log, processorNames);
} else if (processorNames != null) {
processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log); processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log);
} else { } else {
processorIterator = new ServiceIterator(processorClassLoader, log); processorIterator = new ServiceIterator(processorClassLoader, log);
@ -286,7 +317,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
* in service configuration file.) Otherwise, we cannot continue. * in service configuration file.) Otherwise, we cannot continue.
*/ */
processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader", processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader",
processorClassLoaderException); processorLoaderException);
} }
} }
PlatformDescription platformProvider = context.get(PlatformDescription.class); PlatformDescription platformProvider = context.get(PlatformDescription.class);
@ -304,6 +335,18 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
discoveredProcs = new DiscoveredProcessors(compoundIterator); discoveredProcs = new DiscoveredProcessors(compoundIterator);
} }
public <S> ServiceLoader<S> getServiceLoader(Class<S> service) {
if (fileManager.hasLocation(ANNOTATION_PROCESSOR_MODULE_PATH)) {
try {
return fileManager.getServiceLoader(ANNOTATION_PROCESSOR_MODULE_PATH, service);
} catch (IOException e) {
throw new Abort(e);
}
} else {
return ServiceLoader.load(service, getProcessorClassLoader());
}
}
/** /**
* Returns an empty processor iterator if no processors are on the * Returns an empty processor iterator if no processors are on the
* relevant path, otherwise if processors are present, logs an * relevant path, otherwise if processors are present, logs an
@ -316,8 +359,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
* @param e If non-null, pass this exception to Abort * @param e If non-null, pass this exception to Abort
*/ */
private Iterator<Processor> handleServiceLoaderUnavailability(String key, Exception e) { private Iterator<Processor> handleServiceLoaderUnavailability(String key, Exception e) {
JavaFileManager fileManager = context.get(JavaFileManager.class);
if (fileManager instanceof JavacFileManager) { if (fileManager instanceof JavacFileManager) {
StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager; StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager;
Iterable<? extends Path> workingPath = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH) Iterable<? extends Path> workingPath = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
@ -355,9 +396,9 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
* needed but unavailable. * needed but unavailable.
*/ */
private class ServiceIterator implements Iterator<Processor> { private class ServiceIterator implements Iterator<Processor> {
private Iterator<Processor> iterator; Iterator<Processor> iterator;
private Log log; Log log;
private ServiceLoader<Processor> loader; ServiceLoader<Processor> loader;
ServiceIterator(ClassLoader classLoader, Log log) { ServiceIterator(ClassLoader classLoader, Log log) {
this.log = log; this.log = log;
@ -375,9 +416,16 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
} }
} }
ServiceIterator(ServiceLoader<Processor> loader, Log log) {
this.log = log;
this.loader = loader;
this.iterator = loader.iterator();
}
@Override
public boolean hasNext() { public boolean hasNext() {
try { try {
return iterator.hasNext(); return internalHasNext();
} catch(ServiceConfigurationError sce) { } catch(ServiceConfigurationError sce) {
log.error("proc.bad.config.file", sce.getLocalizedMessage()); log.error("proc.bad.config.file", sce.getLocalizedMessage());
throw new Abort(sce); throw new Abort(sce);
@ -386,9 +434,14 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
} }
} }
boolean internalHasNext() {
return iterator.hasNext();
}
@Override
public Processor next() { public Processor next() {
try { try {
return iterator.next(); return internalNext();
} catch (ServiceConfigurationError sce) { } catch (ServiceConfigurationError sce) {
log.error("proc.bad.config.file", sce.getLocalizedMessage()); log.error("proc.bad.config.file", sce.getLocalizedMessage());
throw new Abort(sce); throw new Abort(sce);
@ -397,6 +450,11 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
} }
} }
Processor internalNext() {
return iterator.next();
}
@Override
public void remove() { public void remove() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@ -412,6 +470,58 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
} }
} }
private class NameServiceIterator extends ServiceIterator {
private Map<String, Processor> namedProcessorsMap = new HashMap<>();;
private Iterator<String> processorNames = null;
private Processor nextProc = null;
public NameServiceIterator(ServiceLoader<Processor> loader, Log log, String theNames) {
super(loader, log);
this.processorNames = Arrays.asList(theNames.split(",")).iterator();
}
@Override
boolean internalHasNext() {
if (nextProc != null) {
return true;
}
if (!processorNames.hasNext()) {
namedProcessorsMap = null;
return false;
}
String processorName = processorNames.next();
Processor theProcessor = namedProcessorsMap.get(processorName);
if (theProcessor != null) {
namedProcessorsMap.remove(processorName);
nextProc = theProcessor;
return true;
} else {
while (iterator.hasNext()) {
theProcessor = iterator.next();
String name = theProcessor.getClass().getName();
if (name.equals(processorName)) {
nextProc = theProcessor;
return true;
} else {
namedProcessorsMap.put(name, theProcessor);
}
}
log.error(Errors.ProcProcessorNotFound(processorName));
return false;
}
}
@Override
Processor internalNext() {
if (hasNext()) {
Processor p = nextProc;
nextProc = null;
return p;
} else {
throw new NoSuchElementException();
}
}
}
private static class NameProcessIterator implements Iterator<Processor> { private static class NameProcessIterator implements Iterator<Processor> {
Processor nextProc = null; Processor nextProc = null;
@ -437,8 +547,10 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
Processor processor; Processor processor;
try { try {
try { try {
Class<?> processorClass = processorCL.loadClass(processorName);
ensureReadable(processorClass);
processor = processor =
(Processor) (processorCL.loadClass(processorName).newInstance()); (Processor) (processorClass.newInstance());
} catch (ClassNotFoundException cnfe) { } catch (ClassNotFoundException cnfe) {
log.error("proc.processor.not.found", processorName); log.error("proc.processor.not.found", processorName);
return false; return false;
@ -473,6 +585,26 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
public void remove () { public void remove () {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/**
* Ensures that the module of the given class is readable to this
* module.
*/
private void ensureReadable(Class<?> targetClass) {
try {
Method getModuleMethod = Class.class.getMethod("getModule");
Object thisModule = getModuleMethod.invoke(this.getClass());
Object targetModule = getModuleMethod.invoke(targetClass);
Class<?> moduleClass = getModuleMethod.getReturnType();
Method addReadsMethod = moduleClass.getMethod("addReads", moduleClass);
addReadsMethod.invoke(thisModule, targetModule);
} catch (NoSuchMethodException e) {
// ignore
} catch (Exception e) {
throw new InternalError(e);
}
}
} }
public boolean atLeastOneProcessor() { public boolean atLeastOneProcessor() {
@ -605,7 +737,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
// TODO: These two classes can probably be rewritten better... // TODO: These two classes can probably be rewritten better...
/** /**
* This class holds information about the processors that have * This class holds information about the processors that have
* been discoverd so far as well as the means to discover more, if * been discovered so far as well as the means to discover more, if
* necessary. A single iterator should be used per round of * necessary. A single iterator should be used per round of
* annotation processing. The iterator first visits already * annotation processing. The iterator first visits already
* discovered processors then fails over to the service provider * discovered processors then fails over to the service provider
@ -1000,21 +1132,24 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
if (file.getKind() != JavaFileObject.Kind.CLASS) if (file.getKind() != JavaFileObject.Kind.CLASS)
throw new AssertionError(file); throw new AssertionError(file);
ClassSymbol cs; ClassSymbol cs;
// TODO: for now, we assume that generated code is in a default module;
// in time, we need a way to be able to specify the module for generated code
if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) { if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) {
Name packageName = Convert.packagePart(name); Name packageName = Convert.packagePart(name);
PackageSymbol p = symtab.enterPackage(packageName); PackageSymbol p = symtab.enterPackage(defaultModule, packageName);
if (p.package_info == null) if (p.package_info == null)
p.package_info = symtab.enterClass(Convert.shortName(name), p); p.package_info = symtab.enterClass(defaultModule, Convert.shortName(name), p);
cs = p.package_info; cs = p.package_info;
cs.reset(); cs.reset();
if (cs.classfile == null) if (cs.classfile == null)
cs.classfile = file; cs.classfile = file;
cs.completer = initialCompleter; cs.completer = initialCompleter;
} else { } else {
cs = symtab.enterClass(name); cs = symtab.enterClass(defaultModule, name);
cs.reset(); cs.reset();
cs.classfile = file; cs.classfile = file;
cs.completer = initialCompleter; cs.completer = initialCompleter;
cs.owner.members().enter(cs); //XXX - OverwriteBetweenCompilations; syms.getClass is not sufficient anymore
} }
list = list.prepend(cs); list = list.prepend(cs);
} }
@ -1023,7 +1158,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
/** Enter a set of syntax trees. */ /** Enter a set of syntax trees. */
private void enterTrees(List<JCCompilationUnit> roots) { private void enterTrees(List<JCCompilationUnit> roots) {
compiler.enterTrees(roots); compiler.enterTrees(compiler.initModules(roots));
} }
/** Run a processing round. */ /** Run a processing round. */
@ -1099,11 +1234,12 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
filer.newRound(); filer.newRound();
messager.newRound(); messager.newRound();
compiler.newRound(); compiler.newRound();
modules.newRound();
types.newRound(); types.newRound();
boolean foundError = false; boolean foundError = false;
for (ClassSymbol cs : symtab.classes.values()) { for (ClassSymbol cs : symtab.getAllClasses()) {
if (cs.kind == ERR) { if (cs.kind == ERR) {
foundError = true; foundError = true;
break; break;
@ -1111,7 +1247,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
} }
if (foundError) { if (foundError) {
for (ClassSymbol cs : symtab.classes.values()) { for (ClassSymbol cs : symtab.getAllClasses()) {
if (cs.classfile != null || cs.kind == ERR) { if (cs.classfile != null || cs.kind == ERR) {
cs.reset(); cs.reset();
cs.type = new ClassType(cs.type.getEnclosingType(), null, cs); cs.type = new ClassType(cs.type.getEnclosingType(), null, cs);
@ -1350,6 +1486,13 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
} }
node.packge.reset(); node.packge.reset();
} }
boolean isModuleInfo = node.sourcefile.isNameCompatible("module-info", Kind.SOURCE);
if (isModuleInfo) {
node.modle.reset();
node.modle.completer = sym -> modules.enter(List.of(node), node.modle.module_info);
node.modle.module_info.reset();
node.modle.module_info.members_field = WriteableScope.create(node.modle.module_info);
}
node.packge = null; node.packge = null;
topLevel = node; topLevel = node;
try { try {

View File

@ -1,4 +1,3 @@
# #
# Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@ -813,6 +812,10 @@ compiler.err.no.match.entry=\
compiler.err.not.annotation.type=\ compiler.err.not.annotation.type=\
{0} is not an annotation type {0} is not an annotation type
# 0: symbol, 1: symbol
compiler.err.not.def.access.package.cant.access=\
{0} is not visible because package {1} is not visible
# 0: symbol, 1: symbol # 0: symbol, 1: symbol
compiler.err.not.def.access.class.intf.cant.access=\ compiler.err.not.def.access.class.intf.cant.access=\
{0} in {1} is defined in an inaccessible class or interface {0} in {1} is defined in an inaccessible class or interface
@ -1176,6 +1179,43 @@ compiler.err.cant.read.file=\
compiler.err.plugin.not.found=\ compiler.err.plugin.not.found=\
plug-in not found: {0} plug-in not found: {0}
# 0: path
compiler.warn.locn.unknown.file.on.module.path=\
unknown file on module path: {0}
# 0: path
compiler.err.locn.bad.module-info=\
problem reading module-info.class in {0}
# 0: path
compiler.err.locn.cant.read.directory=\
cannot read directory {0}
# 0: path
compiler.err.locn.cant.read.file=\
cannot read file {0}
# 0: path
compiler.err.locn.cant.get.module.name.for.jar=\
cannot determine module name for {0}
# 0: path
compiler.err.multi-module.outdir.cannot.be.exploded.module=\
in multi-module mode, the output directory cannot be an exploded module: {0}
# 0: path
compiler.warn.outdir.is.in.exploded.module=\
the output directory is within an exploded module: {0}
# 0: path
compiler.err.locn.module-info.not.allowed.on.patch.path=\
module-info.class not allowed on patch path: {0}
# 0: string
compiler.err.locn.invalid.arg.for.xpatch=\
invalid argument for -Xpatch option: {0}
##### #####
# Fatal Errors # Fatal Errors
@ -1379,6 +1419,10 @@ compiler.warn.constant.SVUID=\
compiler.warn.dir.path.element.not.found=\ compiler.warn.dir.path.element.not.found=\
bad path element "{0}": no such directory bad path element "{0}": no such directory
# 0: file name
compiler.warn.dir.path.element.not.directory=\
bad path element "{0}": not a directory
compiler.warn.finally.cannot.complete=\ compiler.warn.finally.cannot.complete=\
finally clause cannot complete normally finally clause cannot complete normally
@ -1492,7 +1536,7 @@ compiler.warn.future.attr=\
{0} attribute introduced in version {1}.{2} class files is ignored in version {3}.{4} class files {0} attribute introduced in version {1}.{2} class files is ignored in version {3}.{4} class files
# Warnings related to annotation processing # Warnings related to annotation processing
# 0: name # 0: string
compiler.warn.proc.package.does.not.exist=\ compiler.warn.proc.package.does.not.exist=\
package {0} does not exist package {0} does not exist
@ -1733,6 +1777,9 @@ compiler.misc.type.none=\
compiler.misc.unnamed.package=\ compiler.misc.unnamed.package=\
unnamed package unnamed package
compiler.misc.unnamed.module=\
unnamed module
##### #####
# 0: symbol, 1: message segment # 0: symbol, 1: message segment
@ -1789,6 +1836,9 @@ compiler.misc.bad.signature=\
compiler.misc.bad.type.annotation.value=\ compiler.misc.bad.type.annotation.value=\
bad type annotation target type value: {0} bad type annotation target type value: {0}
compiler.misc.bad.module-info.name=\
bad class name
compiler.misc.class.file.wrong.class=\ compiler.misc.class.file.wrong.class=\
class file contains wrong class: {0} class file contains wrong class: {0}
@ -1810,6 +1860,9 @@ compiler.misc.file.doesnt.contain.class=\
compiler.misc.file.does.not.contain.package=\ compiler.misc.file.does.not.contain.package=\
file does not contain package {0} file does not contain package {0}
compiler.misc.file.does.not.contain.module=\
file does not contain module declaration
compiler.misc.illegal.start.of.class.file=\ compiler.misc.illegal.start.of.class.file=\
illegal start of class file illegal start of class file
@ -2176,6 +2229,9 @@ compiler.misc.kindname.class=\
compiler.misc.kindname.package=\ compiler.misc.kindname.package=\
package package
compiler.misc.kindname.module=\
module
compiler.misc.kindname.static.init=\ compiler.misc.kindname.static.init=\
static initializer static initializer
@ -2278,6 +2334,12 @@ compiler.misc.inapplicable.method=\
######################################## ########################################
# Diagnostics for language feature changes # Diagnostics for language feature changes
######################################## ########################################
# 0: string
compiler.err.modules.not.supported.in.source=\
modules are not supported in -source {0}\n\
(use -source 9 or higher to enable modules)
# 0: string # 0: string
compiler.misc.diamond.and.anon.class.not.supported.in.source=\ compiler.misc.diamond.and.anon.class.not.supported.in.source=\
cannot use ''<>'' with anonymous inner classes in -source {0}\n\ cannot use ''<>'' with anonymous inner classes in -source {0}\n\
@ -2608,4 +2670,170 @@ compiler.err.dc.unterminated.signature=\
compiler.err.dc.unterminated.string=\ compiler.err.dc.unterminated.string=\
unterminated string unterminated string
###
# errors related to modules
compiler.err.expected.module=\
expected ''module''
# 0: symbol
compiler.err.module.not.found=\
module not found: {0}
compiler.err.too.many.modules=\
too many module declarations found
# 0: symbol
compiler.err.duplicate.module=\
duplicate module: {0}
# 0: symbol
compiler.err.duplicate.requires=\
duplicate requires: {0}
# 0: symbol
compiler.err.duplicate.exports=\
duplicate export: {0}
# 0: symbol, 1: symbol
compiler.err.duplicate.provides=\
duplicate provides: service {0}, implementation {1}
# 0: symbol
compiler.err.duplicate.uses=\
duplicate uses: {0}
# 0: symbol
compiler.err.service.implementation.is.abstract=\
the service implementation is an abstract class: {0}
# 0: symbol
compiler.err.service.implementation.is.inner=\
the service implementation is an inner class: {0}
# 0: symbol
compiler.err.service.definition.is.inner=\
the service definition is an inner class: {0}
# 0: symbol
compiler.err.service.implementation.doesnt.have.a.no.args.constructor=\
the service implementation does not have a default constructor: {0}
# 0: symbol
compiler.err.service.implementation.no.args.constructor.not.public=\
the no arguments constructor of the service implementation is not public: {0}
# 0: symbol
compiler.err.package.empty.or.not.found=\
package is empty or does not exist: {0}
compiler.err.no.output.dir=\
no class output directory specified
compiler.err.unnamed.pkg.not.allowed.named.modules=\
unnamed package is not allowed in named modules
# 0: name, 1: name
compiler.err.module.name.mismatch=\
module name {0} does not match expected name {1}
compiler.err.module.decl.sb.in.module-info.java=\
module declarations should be in a file named module-info.java
compiler.err.unexpected.after.module=\
unexpected input after module declaration
compiler.err.module-info.with.xmodule.sourcepath=\
illegal combination of -Xmodule and module-info on sourcepath
compiler.err.module-info.with.xmodule.classpath=\
illegal combination of -Xmodule and module-info on classpath
compiler.err.xmodule.no.module.sourcepath=\
illegal combination of -Xmodule and -modulesourcepath
compiler.err.processorpath.no.processormodulepath=\
illegal combination of -processorpath and -processormodulepath
# 0: symbol
compiler.err.package.in.other.module=\
package exists in another module: {0}
# 0: symbol, 1: name, 2: symbol, 3: symbol
compiler.err.package.clash.from.requires=\
module {0} reads package {1} from both {2} and {3}
# 0: string
compiler.err.module.not.found.in.module.source.path=\
module {0} not found in module source path
compiler.err.output.dir.must.be.specified.with.dash.m.option=\
class output directory must be specified if -m option is used
compiler.err.modulesourcepath.must.be.specified.with.dash.m.option=\
module source path must be specified if -m option is used
# 0: symbol
compiler.err.service.implementation.not.in.right.module=\
service implementation must be defined in the same module as the provides directive
# 0: symbol
compiler.err.cyclic.requires=\
cyclic dependence involving {0}
# 0: fragment, 1: name
compiler.err.duplicate.module.on.path=\
duplicate module on {0}\nmodule in {1}
# 0: string
compiler.err.xaddexports.malformed.entry=\
bad value for -XaddExports: {0}
# 0: string
compiler.err.xaddexports.too.many=\
multiple -XaddExports options for {0}
# 0: string
compiler.err.xaddreads.malformed.entry=\
bad value for -XaddReads: {0}
# 0: string
compiler.err.xaddreads.too.many=\
multiple -XaddReads options for {0}
compiler.err.addmods.all.module.path.invalid=\
-addmods ALL-MODULE-PATH can only be used when compiling the unnamed module
compiler.misc.locn.module_source_path=\
module source path
compiler.misc.locn.upgrade_module_path=\
upgrade module path
compiler.misc.locn.system_modules=\
system modules
compiler.misc.locn.module_path=\
application module path
compiler.misc.cant.resolve.modules=\
cannot resolve modules
# 0: symbol
compiler.err.cant.find.module=\
cannot find module: {0}
# 0: string
compiler.err.invalid.module.specifier=\
module specifier not allowed: {0}
# 0: symbol
compiler.warn.service.provided.but.not.exported.or.used=\
service interface provided but not exported or used
###
# errors related to options
# 0: string, 1: string
compiler.err.illegal.argument.for.option=\
illegal argument for {0}: {1}

View File

@ -39,20 +39,34 @@ javac.opt.deprecation=\
Output source locations where deprecated APIs are used Output source locations where deprecated APIs are used
javac.opt.classpath=\ javac.opt.classpath=\
Specify where to find user class files and annotation processors Specify where to find user class files and annotation processors
javac.opt.modulepath=\
Specify where to find application modules
javac.opt.sourcepath=\ javac.opt.sourcepath=\
Specify where to find input source files Specify where to find input source files
javac.opt.m=\
Compile only the specified module, check timestamps
javac.opt.modulesourcepath=\
Specify where to find input source files for multiple modules
javac.opt.bootclasspath=\ javac.opt.bootclasspath=\
Override location of bootstrap class files Override location of bootstrap class files
javac.opt.system=\
Override location of system modules
javac.opt.upgrademodulepath=\
Override location of upgradeable modules
javac.opt.Xbootclasspath.p=\ javac.opt.Xbootclasspath.p=\
Prepend to the bootstrap class path Prepend to the bootstrap class path
javac.opt.Xbootclasspath.a=\ javac.opt.Xbootclasspath.a=\
Append to the bootstrap class path Append to the bootstrap class path
javac.opt.Xpatch=\
Specify location of module class files to patch
javac.opt.endorseddirs=\ javac.opt.endorseddirs=\
Override location of endorsed standards path Override location of endorsed standards path
javac.opt.extdirs=\ javac.opt.extdirs=\
Override location of installed extensions Override location of installed extensions
javac.opt.processorpath=\ javac.opt.processorpath=\
Specify where to find annotation processors Specify where to find annotation processors
javac.opt.processormodulepath=\
Specify a module path where to find annotation processors
javac.opt.processor=\ javac.opt.processor=\
Names of the annotation processors to run; bypasses default discovery process Names of the annotation processors to run; bypasses default discovery process
javac.opt.parameters=\ javac.opt.parameters=\
@ -95,6 +109,12 @@ javac.opt.arg.key.equals.value=\
key[=value] key[=value]
javac.opt.arg.path=\ javac.opt.arg.path=\
<path> <path>
javac.opt.arg.mspath=\
<module-source-path>
javac.opt.arg.m=\
<module-name>
javac.opt.arg.jdk=\
<jdk>|none
javac.opt.arg.dirs=\ javac.opt.arg.dirs=\
<dirs> <dirs>
javac.opt.arg.directory=\ javac.opt.arg.directory=\
@ -252,6 +272,29 @@ javac.opt.AT=\
Read options and filenames from file Read options and filenames from file
javac.opt.diags=\ javac.opt.diags=\
Select a diagnostic mode Select a diagnostic mode
javac.opt.addExports=\n\
\ Specify a package to be considered as exported from its defining module\n\
\ to additional modules, or to all unnamed modules if <other-module> is ALL-UNNAMED.
javac.opt.arg.addExports=\
<module>/<package>=<other-module>(,<other-module>)*
javac.opt.addReads=\n\
\ Specify additional modules to be considered as required by a given module.\n\
\ <other-module> may be ALL-UNNAMED to require the unnamed module.
javac.opt.arg.addReads=\
<module>=<other-module>(,<other-module>)*
javac.opt.module=\
Specify a module to which the classes being compiled belong.
javac.opt.arg.module=\
<module-name>
javac.opt.addmods=\n\
\ Root modules to resolve in addition to the initial modules, or all modules\n\
\ on the module path if <module> is ALL-MODULE-PATH.
javac.opt.arg.addmods=\
<module>(,<module>)*
javac.opt.limitmods=\
Limit the universe of observable modules
javac.opt.arg.limitmods=\
<module>(,<module>)*
## errors ## errors
@ -269,6 +312,10 @@ javac.err.invalid.profile=\
invalid profile: {0} invalid profile: {0}
javac.err.invalid.target=\ javac.err.invalid.target=\
invalid target release: {0} invalid target release: {0}
javac.err.option.not.allowed.with.target=\
option {0} not allowed with target {1}
javac.err.option.too.many=\
option {0} can only be specified once
javac.err.no.source.files=\ javac.err.no.source.files=\
no source files no source files
javac.err.no.source.files.classes=\ javac.err.no.source.files.classes=\
@ -279,6 +326,8 @@ javac.err.invalid.source=\
invalid source release: {0} invalid source release: {0}
javac.err.error.writing.file=\ javac.err.error.writing.file=\
error writing {0}; {1} error writing {0}; {1}
javac.err.sourcepath.modulesourcepath.conflict=\
cannot specify both -sourcepath and -modulesourcepath
javac.warn.source.target.conflict=\ javac.warn.source.target.conflict=\
source release {0} requires target release {1} source release {0} requires target release {1}
javac.warn.target.default.source.conflict=\ javac.warn.target.default.source.conflict=\

View File

@ -1,522 +0,0 @@
/*
* Copyright (c) 2006, 2014, 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.javac.sym;
import com.sun.tools.javac.api.JavacTaskImpl;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.jvm.ClassWriter;
import com.sun.tools.javac.jvm.Pool;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Names;
import com.sun.tools.javac.util.Pair;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import static javax.tools.JavaFileObject.Kind.CLASS;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import static com.sun.tools.javac.code.Kinds.Kind.*;
/**
* Used to generate a "symbol file" representing rt.jar that only
* includes supported or legacy proprietary API. Valid annotation
* processor options:
*
* <dl>
* <dt>com.sun.tools.javac.sym.Jar</dt>
* <dd>Specifies the location of rt.jar.</dd>
* <dt>com.sun.tools.javac.sym.Dest</dt>
* <dd>Specifies the destination directory.</dd>
* </dl>
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Peter von der Ah\u00e9
*/
@SupportedOptions({
"com.sun.tools.javac.sym.Jar",
"com.sun.tools.javac.sym.Dest",
"com.sun.tools.javac.sym.Profiles"})
@SupportedAnnotationTypes("*")
public class CreateSymbols extends AbstractProcessor {
static Set<String> getLegacyPackages() {
ResourceBundle legacyBundle
= ResourceBundle.getBundle("com.sun.tools.javac.resources.legacy");
Set<String> keys = new HashSet<>();
for (Enumeration<String> e = legacyBundle.getKeys(); e.hasMoreElements(); )
keys.add(e.nextElement());
return keys;
}
@DefinedBy(Api.ANNOTATION_PROCESSING)
public boolean process(Set<? extends TypeElement> tes, RoundEnvironment renv) {
try {
if (renv.processingOver())
createSymbols();
} catch (IOException e) {
CharSequence msg = e.getLocalizedMessage();
if (msg == null)
msg = e.toString();
processingEnv.getMessager()
.printMessage(Diagnostic.Kind.ERROR, msg);
} catch (Throwable t) {
t.printStackTrace();
Throwable cause = t.getCause();
if (cause == null)
cause = t;
CharSequence msg = cause.getLocalizedMessage();
if (msg == null)
msg = cause.toString();
processingEnv.getMessager()
.printMessage(Diagnostic.Kind.ERROR, msg);
}
return true;
}
void createSymbols() throws IOException {
Set<String> legacy = getLegacyPackages();
Set<String> legacyProprietary = getLegacyPackages();
Set<String> documented = new HashSet<>();
Set<PackageSymbol> packages =
((JavacProcessingEnvironment)processingEnv).getSpecifiedPackages();
Map<String,String> pOptions = processingEnv.getOptions();
String jarName = pOptions.get("com.sun.tools.javac.sym.Jar");
if (jarName == null)
throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Jar=LOCATION_OF_JAR");
String destName = pOptions.get("com.sun.tools.javac.sym.Dest");
if (destName == null)
throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Dest=LOCATION_OF_JAR");
String profileSpec=pOptions.get("com.sun.tools.javac.sym.Profiles");
if (profileSpec == null)
throw new RuntimeException("Must use -Acom.sun.tools.javac.sym.Profiles=PROFILES_SPEC");
Profiles profiles = Profiles.read(new File(profileSpec));
for (PackageSymbol psym : packages) {
String name = psym.getQualifiedName().toString();
legacyProprietary.remove(name);
documented.add(name);
}
JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
Location jarLocation = StandardLocation.locationFor(jarName);
File jarFile = new File(jarName);
fm.setLocation(jarLocation, List.of(jarFile));
fm.setLocation(StandardLocation.CLASS_PATH, List.<File>nil());
fm.setLocation(StandardLocation.SOURCE_PATH, List.<File>nil());
{
ArrayList<File> bootClassPath = new ArrayList<>();
bootClassPath.add(jarFile);
for (File path : fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH)) {
if (!new File(path.getName()).equals(new File("rt.jar")))
bootClassPath.add(path);
}
System.err.println("Using boot class path = " + bootClassPath);
fm.setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootClassPath);
}
// System.out.println(fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH));
File destDir = new File(destName);
if (!destDir.exists())
if (!destDir.mkdirs())
throw new RuntimeException("Could not create " + destDir);
fm.setLocation(StandardLocation.CLASS_OUTPUT, List.of(destDir));
Set<String> hiddenPackages = new HashSet<>();
Set<String> crisp = new HashSet<>();
List<String> options = List.of("-XDdev");
// options = options.prepend("-doe");
// options = options.prepend("-verbose");
JavacTaskImpl task = (JavacTaskImpl)
tool.getTask(null, fm, null, options, null, null);
com.sun.tools.javac.main.JavaCompiler compiler =
com.sun.tools.javac.main.JavaCompiler.instance(task.getContext());
ClassWriter writer = ClassWriter.instance(task.getContext());
Symtab syms = Symtab.instance(task.getContext());
Names names = Names.instance(task.getContext());
Attribute.Compound proprietaryAnno =
new Attribute.Compound(syms.proprietaryType,
List.<Pair<Symbol.MethodSymbol,Attribute>>nil());
Attribute.Compound[] profileAnnos = new Attribute.Compound[profiles.getProfileCount() + 1];
Symbol.MethodSymbol profileValue = (MethodSymbol) syms.profileType.tsym.members().findFirst(names.value);
for (int i = 1; i < profileAnnos.length; i++) {
profileAnnos[i] = new Attribute.Compound(syms.profileType,
List.<Pair<Symbol.MethodSymbol, Attribute>>of(
new Pair<Symbol.MethodSymbol, Attribute>(profileValue,
new Attribute.Constant(syms.intType, i))));
}
Type.moreInfo = true;
Types types = Types.instance(task.getContext());
Pool pool = new Pool(types);
for (JavaFileObject file : fm.list(jarLocation, "", EnumSet.of(CLASS), true)) {
String className = fm.inferBinaryName(jarLocation, file);
int index = className.lastIndexOf('.');
String pckName = index == -1 ? "" : className.substring(0, index);
boolean addLegacyAnnotation = false;
if (documented.contains(pckName)) {
if (!legacy.contains(pckName))
crisp.add(pckName);
// System.out.println("Documented: " + className);
} else if (legacyProprietary.contains(pckName)) {
addLegacyAnnotation = true;
// System.out.println("Legacy proprietary: " + className);
} else {
// System.out.println("Hidden " + className);
hiddenPackages.add(pckName);
continue;
}
TypeSymbol sym = (TypeSymbol)compiler.resolveIdent(className);
if (sym.kind != TYP) {
if (className.indexOf('$') < 0) {
System.err.println("Ignoring (other) " + className + " : " + sym);
System.err.println(" " + sym.getClass().getSimpleName() + " " + sym.type);
}
continue;
}
sym.complete();
if (sym.getEnclosingElement().getKind() != ElementKind.PACKAGE) {
System.err.println("Ignoring (bad) " + sym.getQualifiedName());
continue;
}
ClassSymbol cs = (ClassSymbol) sym;
if (addLegacyAnnotation) {
cs.prependAttributes(List.of(proprietaryAnno));
}
int p = profiles.getProfile(cs.fullname.toString().replace(".", "/"));
if (0 < p && p < profileAnnos.length)
cs.prependAttributes(List.of(profileAnnos[p]));
writeClass(pool, cs, writer);
}
if (false) {
for (String pckName : crisp)
System.out.println("Crisp: " + pckName);
for (String pckName : hiddenPackages)
System.out.println("Hidden: " + pckName);
for (String pckName : legacyProprietary)
System.out.println("Legacy proprietary: " + pckName);
for (String pckName : documented)
System.out.println("Documented: " + pckName);
}
}
void writeClass(final Pool pool, final ClassSymbol cs, final ClassWriter writer)
throws IOException
{
try {
pool.reset();
cs.pool = pool;
writer.writeClass(cs);
for (Symbol sym : cs.members().getSymbols(NON_RECURSIVE)) {
if (sym.kind == TYP) {
ClassSymbol nestedClass = (ClassSymbol)sym;
nestedClass.complete();
writeClass(pool, nestedClass, writer);
}
}
} catch (ClassWriter.StringOverflow | ClassWriter.PoolOverflow ex) {
throw new RuntimeException(ex);
}
}
@DefinedBy(Api.ANNOTATION_PROCESSING)
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
// used for debugging
public static void main(String... args) {
String rt_jar = args[0];
String dest = args[1];
args = new String[] {
"-Xbootclasspath:" + rt_jar,
"-XDprocess.packages",
"-proc:only",
"-processor",
"com.sun.tools.javac.sym.CreateSymbols",
"-Acom.sun.tools.javac.sym.Jar=" + rt_jar,
"-Acom.sun.tools.javac.sym.Dest=" + dest,
// <editor-fold defaultstate="collapsed">
"java.applet",
"java.awt",
"java.awt.color",
"java.awt.datatransfer",
"java.awt.dnd",
"java.awt.event",
"java.awt.font",
"java.awt.geom",
"java.awt.im",
"java.awt.im.spi",
"java.awt.image",
"java.awt.image.renderable",
"java.awt.print",
"java.beans",
"java.beans.beancontext",
"java.io",
"java.lang",
"java.lang.annotation",
"java.lang.instrument",
"java.lang.management",
"java.lang.ref",
"java.lang.reflect",
"java.math",
"java.net",
"java.nio",
"java.nio.channels",
"java.nio.channels.spi",
"java.nio.charset",
"java.nio.charset.spi",
"java.rmi",
"java.rmi.activation",
"java.rmi.dgc",
"java.rmi.registry",
"java.rmi.server",
"java.security",
"java.security.acl",
"java.security.cert",
"java.security.interfaces",
"java.security.spec",
"java.sql",
"java.text",
"java.text.spi",
"java.util",
"java.util.concurrent",
"java.util.concurrent.atomic",
"java.util.concurrent.locks",
"java.util.jar",
"java.util.logging",
"java.util.prefs",
"java.util.regex",
"java.util.spi",
"java.util.zip",
"javax.accessibility",
"javax.activation",
"javax.activity",
"javax.annotation",
"javax.annotation.processing",
"javax.crypto",
"javax.crypto.interfaces",
"javax.crypto.spec",
"javax.imageio",
"javax.imageio.event",
"javax.imageio.metadata",
"javax.imageio.plugins.jpeg",
"javax.imageio.plugins.bmp",
"javax.imageio.spi",
"javax.imageio.stream",
"javax.jws",
"javax.jws.soap",
"javax.lang.model",
"javax.lang.model.element",
"javax.lang.model.type",
"javax.lang.model.util",
"javax.management",
"javax.management.loading",
"javax.management.monitor",
"javax.management.relation",
"javax.management.openmbean",
"javax.management.timer",
"javax.management.modelmbean",
"javax.management.remote",
"javax.management.remote.rmi",
"javax.naming",
"javax.naming.directory",
"javax.naming.event",
"javax.naming.ldap",
"javax.naming.spi",
"javax.net",
"javax.net.ssl",
"javax.print",
"javax.print.attribute",
"javax.print.attribute.standard",
"javax.print.event",
"javax.rmi",
"javax.rmi.CORBA",
"javax.rmi.ssl",
"javax.script",
"javax.security.auth",
"javax.security.auth.callback",
"javax.security.auth.kerberos",
"javax.security.auth.login",
"javax.security.auth.spi",
"javax.security.auth.x500",
"javax.security.cert",
"javax.security.sasl",
"javax.sound.sampled",
"javax.sound.sampled.spi",
"javax.sound.midi",
"javax.sound.midi.spi",
"javax.sql",
"javax.sql.rowset",
"javax.sql.rowset.serial",
"javax.sql.rowset.spi",
"javax.swing",
"javax.swing.border",
"javax.swing.colorchooser",
"javax.swing.filechooser",
"javax.swing.event",
"javax.swing.table",
"javax.swing.text",
"javax.swing.text.html",
"javax.swing.text.html.parser",
"javax.swing.text.rtf",
"javax.swing.tree",
"javax.swing.undo",
"javax.swing.plaf",
"javax.swing.plaf.basic",
"javax.swing.plaf.metal",
"javax.swing.plaf.multi",
"javax.swing.plaf.synth",
"javax.tools",
"javax.transaction",
"javax.transaction.xa",
"javax.xml.parsers",
"javax.xml.bind",
"javax.xml.bind.annotation",
"javax.xml.bind.annotation.adapters",
"javax.xml.bind.attachment",
"javax.xml.bind.helpers",
"javax.xml.bind.util",
"javax.xml.soap",
"javax.xml.ws",
"javax.xml.ws.handler",
"javax.xml.ws.handler.soap",
"javax.xml.ws.http",
"javax.xml.ws.soap",
"javax.xml.ws.spi",
"javax.xml.transform",
"javax.xml.transform.sax",
"javax.xml.transform.dom",
"javax.xml.transform.stax",
"javax.xml.transform.stream",
"javax.xml",
"javax.xml.crypto",
"javax.xml.crypto.dom",
"javax.xml.crypto.dsig",
"javax.xml.crypto.dsig.dom",
"javax.xml.crypto.dsig.keyinfo",
"javax.xml.crypto.dsig.spec",
"javax.xml.datatype",
"javax.xml.validation",
"javax.xml.namespace",
"javax.xml.xpath",
"javax.xml.stream",
"javax.xml.stream.events",
"javax.xml.stream.util",
"org.ietf.jgss",
"org.omg.CORBA",
"org.omg.CORBA.DynAnyPackage",
"org.omg.CORBA.ORBPackage",
"org.omg.CORBA.TypeCodePackage",
"org.omg.stub.java.rmi",
"org.omg.CORBA.portable",
"org.omg.CORBA_2_3",
"org.omg.CORBA_2_3.portable",
"org.omg.CosNaming",
"org.omg.CosNaming.NamingContextExtPackage",
"org.omg.CosNaming.NamingContextPackage",
"org.omg.SendingContext",
"org.omg.PortableServer",
"org.omg.PortableServer.CurrentPackage",
"org.omg.PortableServer.POAPackage",
"org.omg.PortableServer.POAManagerPackage",
"org.omg.PortableServer.ServantLocatorPackage",
"org.omg.PortableServer.portable",
"org.omg.PortableInterceptor",
"org.omg.PortableInterceptor.ORBInitInfoPackage",
"org.omg.Messaging",
"org.omg.IOP",
"org.omg.IOP.CodecFactoryPackage",
"org.omg.IOP.CodecPackage",
"org.omg.Dynamic",
"org.omg.DynamicAny",
"org.omg.DynamicAny.DynAnyPackage",
"org.omg.DynamicAny.DynAnyFactoryPackage",
"org.w3c.dom",
"org.w3c.dom.events",
"org.w3c.dom.bootstrap",
"org.w3c.dom.ls",
"org.xml.sax",
"org.xml.sax.ext",
"org.xml.sax.helpers",
"org.w3c.dom",
"org.w3c.dom.bootstrap",
"org.w3c.dom.ls",
"org.w3c.dom.ranges",
"org.w3c.dom.traversal",
"org.w3c.dom.html",
"org.w3c.dom.stylesheets",
"org.w3c.dom.css",
"org.w3c.dom.events",
"org.w3c.dom.views",
"com.sun.management",
"com.sun.security.auth",
"com.sun.security.auth.callback",
"com.sun.security.auth.login",
"com.sun.security.auth.module",
"com.sun.security.jgss",
"com.sun.net.httpserver",
"com.sun.net.httpserver.spi",
"javax.smartcardio"
// </editor-fold>
};
com.sun.tools.javac.Main.compile(args);
}
}

View File

@ -1,305 +0,0 @@
/*
* Copyright (c) 2006, 2014, 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.javac.sym;
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import com.sun.tools.javac.util.Assert;
/**
* Provide details about profile contents.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*/
public abstract class Profiles {
// for debugging
public static void main(String[] args) throws IOException {
Profiles p = Profiles.read(new File(args[0]));
if (args.length >= 2) {
Map<Integer,Set<String>> lists = new TreeMap<>();
for (int i = 1; i <= 4; i++)
lists.put(i, new TreeSet<String>());
File rt_jar_lst = new File(args[1]);
for (String line: Files.readAllLines(rt_jar_lst.toPath(), Charset.defaultCharset())) {
if (line.endsWith(".class")) {
String type = line.substring(0, line.length() - 6);
int profile = p.getProfile(type);
for (int i = profile; i <= 4; i++)
lists.get(i).add(type);
}
}
for (int i = 1; i <= 4; i++) {
try (BufferedWriter out = new BufferedWriter(new FileWriter(i + ".txt"))) {
for (String type : lists.get(i)) {
out.write(type);
out.newLine();
}
}
}
}
}
public static Profiles read(File file) throws IOException {
try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(file))) {
Properties p = new Properties();
p.load(in);
if (p.containsKey("java/lang/Object"))
return new SimpleProfiles(p);
else
return new MakefileProfiles(p);
}
}
public abstract int getProfileCount();
public abstract int getProfile(String typeName);
public abstract Set<String> getPackages(int profile);
private static class MakefileProfiles extends Profiles {
static class Package {
final Package parent;
final String name;
Map<String, Package> subpackages = new TreeMap<>();
int profile;
Map<String, Integer> includedTypes = new TreeMap<>();
Map<String, Integer> excludedTypes = new TreeMap<>();
Package(Package parent, String name) {
this.parent = parent;
this.name = name;
}
int getProfile() {
return (parent == null) ? profile : Math.max(parent.getProfile(), profile);
}
int getProfile(String simpleTypeName) {
Integer i;
if ((i = includedTypes.get(simpleTypeName)) != null)
return i;
if ((i = includedTypes.get("*")) != null)
return i;
if ((i = excludedTypes.get(simpleTypeName)) != null)
return i + 1;
if ((i = excludedTypes.get("*")) != null)
return i + 1;
return getProfile();
}
String getName() {
return (parent == null) ? name : (parent.getName() + "/" + name);
}
void getPackages(int profile, Set<String> results) {
int prf = getProfile();
if (prf != 0 && profile >= prf)
results.add(getName());
for (Package pkg: subpackages.values())
pkg.getPackages(profile, results);
}
}
final Map<String, Package> packages = new TreeMap<>();
final int maxProfile = 4; // Three compact profiles plus full JRE
MakefileProfiles(Properties p) {
// consider crypto, only if java/lang package exists
boolean foundJavaLang = false;
for (int profile = 1; profile <= maxProfile; profile++) {
String prefix = (profile < maxProfile ? "PROFILE_" + profile : "FULL_JRE");
String inclPackages = p.getProperty(prefix + "_RTJAR_INCLUDE_PACKAGES");
if (inclPackages == null)
break;
for (String pkg: inclPackages.substring(1).trim().split("\\s+")) {
if (pkg.endsWith("/"))
pkg = pkg.substring(0, pkg.length() - 1);
if (foundJavaLang == false && pkg.equals("java/lang"))
foundJavaLang = true;
includePackage(profile, pkg);
}
String inclTypes = p.getProperty(prefix + "_RTJAR_INCLUDE_TYPES");
if (inclTypes != null) {
for (String type: inclTypes.replace("$$", "$").split("\\s+")) {
if (type.endsWith(".class"))
includeType(profile, type.substring(0, type.length() - 6));
}
}
String exclTypes = p.getProperty(prefix + "_RTJAR_EXCLUDE_TYPES");
if (exclTypes != null) {
for (String type: exclTypes.replace("$$", "$").split("\\s+")) {
if (type.endsWith(".class"))
excludeType(profile, type.substring(0, type.length() - 6));
}
}
}
/*
* A hack to force javax/crypto package into the compact1 profile,
* because this package exists in jce.jar, and therefore not in
* ct.sym. Note javax/crypto should exist in a profile along with
* javax/net/ssl package. Thus, this package is added to compact1,
* implying that it should exist in all three profiles.
*/
if (foundJavaLang)
includePackage(1, "javax/crypto");
}
@Override
public int getProfileCount() {
return maxProfile;
}
@Override
public int getProfile(String typeName) {
int sep = typeName.lastIndexOf("/");
String packageName = typeName.substring(0, sep);
String simpleName = typeName.substring(sep + 1);
Package p = getPackage(packageName);
return p.getProfile(simpleName);
}
@Override
public Set<String> getPackages(int profile) {
Set<String> results = new TreeSet<>();
for (Package p: packages.values())
p.getPackages(profile, results);
return results;
}
private void includePackage(int profile, String packageName) {
// System.err.println("include package " + packageName);
Package p = getPackage(packageName);
Assert.check(p.profile == 0);
p.profile = profile;
}
private void includeType(int profile, String typeName) {
// System.err.println("include type " + typeName);
int sep = typeName.lastIndexOf("/");
String packageName = typeName.substring(0, sep);
String simpleName = typeName.substring(sep + 1);
Package p = getPackage(packageName);
Assert.check(!p.includedTypes.containsKey(simpleName));
p.includedTypes.put(simpleName, profile);
}
private void excludeType(int profile, String typeName) {
// System.err.println("exclude type " + typeName);
int sep = typeName.lastIndexOf("/");
String packageName = typeName.substring(0, sep);
String simpleName = typeName.substring(sep + 1);
Package p = getPackage(packageName);
Assert.check(!p.excludedTypes.containsKey(simpleName));
p.excludedTypes.put(simpleName, profile);
}
private Package getPackage(String packageName) {
int sep = packageName.lastIndexOf("/");
Package parent;
Map<String, Package> parentSubpackages;
String simpleName;
if (sep == -1) {
parent = null;
parentSubpackages = packages;
simpleName = packageName;
} else {
parent = getPackage(packageName.substring(0, sep));
parentSubpackages = parent.subpackages;
simpleName = packageName.substring(sep + 1);
}
Package p = parentSubpackages.get(simpleName);
if (p == null) {
parentSubpackages.put(simpleName, p = new Package(parent, simpleName));
}
return p;
}
}
private static class SimpleProfiles extends Profiles {
private final Map<String, Integer> map;
private final int profileCount;
SimpleProfiles(Properties p) {
int max = 0;
map = new HashMap<>();
for (Map.Entry<Object,Object> e: p.entrySet()) {
String typeName = (String) e.getKey();
int profile = Integer.valueOf((String) e.getValue());
map.put(typeName, profile);
max = Math.max(max, profile);
}
profileCount = max;
}
@Override
public int getProfileCount() {
return profileCount;
}
@Override
public int getProfile(String typeName) {
return map.get(typeName);
}
@Override
public Set<String> getPackages(int profile) {
Set<String> results = new TreeSet<>();
for (Map.Entry<String,Integer> e: map.entrySet()) {
String tn = e.getKey();
int prf = e.getValue();
int sep = tn.lastIndexOf("/");
if (sep > 0 && profile >= prf)
results.add(tn);
}
return results;
}
}
}

View File

@ -35,14 +35,20 @@ import javax.tools.JavaFileObject;
import com.sun.source.tree.*; import com.sun.source.tree.*;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Directive.RequiresDirective;
import com.sun.tools.javac.code.Scope.*; import com.sun.tools.javac.code.Scope.*;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.tree.JCTree.Tag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*;
import javax.tools.JavaFileManager.Location;
import com.sun.tools.javac.code.Directive.ExportsDirective;
/** /**
* Root class for abstract syntax tree nodes. It provides definitions * Root class for abstract syntax tree nodes. It provides definitions
* for specific tree nodes as subclasses nested inside. * for specific tree nodes as subclasses nested inside.
@ -344,6 +350,12 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
DIV_ASG(DIV), // /= DIV_ASG(DIV), // /=
MOD_ASG(MOD), // %= MOD_ASG(MOD), // %=
MODULEDEF,
EXPORTS,
PROVIDES,
REQUIRES,
USES,
/** A synthetic let expression, of type LetExpr. /** A synthetic let expression, of type LetExpr.
*/ */
LETEXPR; // ala scheme LETEXPR; // ala scheme
@ -484,8 +496,12 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public static class JCCompilationUnit extends JCTree implements CompilationUnitTree { public static class JCCompilationUnit extends JCTree implements CompilationUnitTree {
/** All definitions in this file (ClassDef, Import, and Skip) */ /** All definitions in this file (ClassDef, Import, and Skip) */
public List<JCTree> defs; public List<JCTree> defs;
/* The source file name. */ /** The source file name. */
public JavaFileObject sourcefile; public JavaFileObject sourcefile;
/** The module to which this compilation unit belongs. */
public ModuleSymbol modle;
/** The location in which this compilation unit was found. */
public Location locn;
/** The package to which this compilation unit belongs. */ /** The package to which this compilation unit belongs. */
public PackageSymbol packge; public PackageSymbol packge;
/** A scope containing top level classes. */ /** A scope containing top level classes. */
@ -2593,8 +2609,202 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
} }
} }
public static abstract class JCDirective extends JCTree
implements DirectiveTree {
}
public static class JCModuleDecl extends JCTree implements ModuleTree {
public JCExpression qualId;
public List<JCDirective> directives;
public ModuleSymbol sym;
protected JCModuleDecl(JCExpression qualId, List<JCDirective> directives) {
this.qualId = qualId;
this.directives = directives;
}
@Override
public void accept(Visitor v) { v.visitModuleDef(this); }
@Override
public Kind getKind() {
return Kind.MODULE;
}
// @Override
public JCExpression getName() {
return qualId;
}
@Override
public List<JCDirective> getDirectives() {
return directives;
}
@Override
public <R, D> R accept(TreeVisitor<R, D> v, D d) {
return v.visitModule(this, d);
}
@Override
public Tag getTag() {
return MODULEDEF;
}
}
public static class JCExports extends JCDirective
implements ExportsTree {
public JCExpression qualid;
public List<JCExpression> moduleNames;
public ExportsDirective directive;
protected JCExports(JCExpression qualId, List<JCExpression> moduleNames) {
this.qualid = qualId;
this.moduleNames = moduleNames;
}
@Override
public void accept(Visitor v) { v.visitExports(this); }
@Override
public Kind getKind() {
return Kind.EXPORTS;
}
@Override
public JCExpression getExportName() {
return qualid;
}
@Override
public List<JCExpression> getModuleNames() {
return moduleNames;
}
@Override
public <R, D> R accept(TreeVisitor<R, D> v, D d) {
return v.visitExports(this, d);
}
@Override
public Tag getTag() {
return EXPORTS;
}
}
public static class JCProvides extends JCDirective
implements ProvidesTree {
public JCExpression serviceName;
public JCExpression implName;
protected JCProvides(JCExpression serviceName, JCExpression implName) {
this.serviceName = serviceName;
this.implName = implName;
}
@Override
public void accept(Visitor v) { v.visitProvides(this); }
@Override
public Kind getKind() {
return Kind.PROVIDES;
}
@Override
public <R, D> R accept(TreeVisitor<R, D> v, D d) {
return v.visitProvides(this, d);
}
@Override
public JCExpression getServiceName() {
return serviceName;
}
@Override
public JCExpression getImplementationName() {
return implName;
}
@Override
public Tag getTag() {
return PROVIDES;
}
}
public static class JCRequires extends JCDirective
implements RequiresTree {
public boolean isPublic;
public JCExpression moduleName;
public RequiresDirective directive;
protected JCRequires(boolean isPublic, JCExpression moduleName) {
this.isPublic = isPublic;
this.moduleName = moduleName;
}
@Override
public void accept(Visitor v) { v.visitRequires(this); }
@Override
public Kind getKind() {
return Kind.REQUIRES;
}
@Override
public <R, D> R accept(TreeVisitor<R, D> v, D d) {
return v.visitRequires(this, d);
}
@Override
public boolean isPublic() {
return isPublic;
}
@Override
public JCExpression getModuleName() {
return moduleName;
}
@Override
public Tag getTag() {
return REQUIRES;
}
}
public static class JCUses extends JCDirective
implements UsesTree {
public JCExpression qualid;
protected JCUses(JCExpression qualId) {
this.qualid = qualId;
}
@Override
public void accept(Visitor v) { v.visitUses(this); }
@Override
public Kind getKind() {
return Kind.USES;
}
@Override
public JCExpression getServiceName() {
return qualid;
}
@Override
public <R, D> R accept(TreeVisitor<R, D> v, D d) {
return v.visitUses(this, d);
}
@Override
public Tag getTag() {
return USES;
}
}
public static class JCErroneous extends JCExpression public static class JCErroneous extends JCExpression
implements com.sun.source.tree.ErroneousTree { implements ErroneousTree {
public List<? extends JCTree> errs; public List<? extends JCTree> errs;
protected JCErroneous(List<? extends JCTree> errs) { protected JCErroneous(List<? extends JCTree> errs) {
this.errs = errs; this.errs = errs;
@ -2731,6 +2941,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args); JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args);
JCModifiers Modifiers(long flags, List<JCAnnotation> annotations); JCModifiers Modifiers(long flags, List<JCAnnotation> annotations);
JCErroneous Erroneous(List<? extends JCTree> errs); JCErroneous Erroneous(List<? extends JCTree> errs);
JCModuleDecl ModuleDef(JCExpression qualId, List<JCDirective> directives);
JCExports Exports(JCExpression qualId, List<JCExpression> moduleNames);
JCProvides Provides(JCExpression serviceName, JCExpression implName);
JCRequires Requires(boolean isPublic, JCExpression qualId);
JCUses Uses(JCExpression qualId);
LetExpr LetExpr(List<JCVariableDecl> defs, JCExpression expr); LetExpr LetExpr(List<JCVariableDecl> defs, JCExpression expr);
} }
@ -2791,6 +3006,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public void visitModifiers(JCModifiers that) { visitTree(that); } public void visitModifiers(JCModifiers that) { visitTree(that); }
public void visitAnnotatedType(JCAnnotatedType that) { visitTree(that); } public void visitAnnotatedType(JCAnnotatedType that) { visitTree(that); }
public void visitErroneous(JCErroneous that) { visitTree(that); } public void visitErroneous(JCErroneous that) { visitTree(that); }
public void visitModuleDef(JCModuleDecl that) { visitTree(that); }
public void visitExports(JCExports that) { visitTree(that); }
public void visitProvides(JCProvides that) { visitTree(that); }
public void visitRequires(JCRequires that) { visitTree(that); }
public void visitUses(JCUses that) { visitTree(that); }
public void visitLetExpr(LetExpr that) { visitTree(that); } public void visitLetExpr(LetExpr that) { visitTree(that); }
public void visitTree(JCTree that) { Assert.error(); } public void visitTree(JCTree that) { Assert.error(); }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -438,6 +438,74 @@ public class Pretty extends JCTree.Visitor {
} }
} }
@Override
public void visitModuleDef(JCModuleDecl tree) {
try {
print("module ");
printExpr(tree.qualId);
if (tree.directives == null) {
print(";");
} else {
printBlock(tree.directives);
}
println();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public void visitExports(JCExports tree) {
try {
print("exports ");
printExpr(tree.qualid);
if (tree.moduleNames != null) {
print(" to ");
printExprs(tree.moduleNames);
}
print(";");
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public void visitProvides(JCProvides tree) {
try {
print("provides ");
printExpr(tree.serviceName);
print(" with ");
printExpr(tree.implName);
print(";");
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public void visitRequires(JCRequires tree) {
try {
print("requires ");
if (tree.isPublic)
print("public ");
printExpr(tree.moduleName);
print(";");
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
public void visitUses(JCUses tree) {
try {
print("uses ");
printExpr(tree.qualid);
print(";");
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public void visitImport(JCImport tree) { public void visitImport(JCImport tree) {
try { try {
print("import "); print("import ");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -505,6 +505,44 @@ public class TreeCopier<P> implements TreeVisitor<JCTree,P> {
return M.at(t.pos).Wildcard(kind, inner); return M.at(t.pos).Wildcard(kind, inner);
} }
@Override
public JCTree visitModule(ModuleTree node, P p) {
JCModuleDecl t = (JCModuleDecl) node;
JCExpression qualId = copy(t.qualId);
List<JCDirective> directives = copy(t.directives);
return M.at(t.pos).ModuleDef(qualId, directives);
}
@Override
public JCExports visitExports(ExportsTree node, P p) {
JCExports t = (JCExports) node;
JCExpression qualId = copy(t.qualid, p);
List<JCExpression> moduleNames = copy(t.moduleNames, p);
return M.at(t.pos).Exports(qualId, moduleNames);
}
@Override
public JCProvides visitProvides(ProvidesTree node, P p) {
JCProvides t = (JCProvides) node;
JCExpression serviceName = copy(t.serviceName, p);
JCExpression implName = copy(t.implName, p);
return M.at(t.pos).Provides(serviceName, implName);
}
@Override
public JCRequires visitRequires(RequiresTree node, P p) {
JCRequires t = (JCRequires) node;
JCExpression moduleName = copy(t.moduleName, p);
return M.at(t.pos).Requires(t.isPublic, moduleName);
}
@Override
public JCUses visitUses(UsesTree node, P p) {
JCUses t = (JCUses) node;
JCExpression serviceName = copy(t.qualid, p);
return M.at(t.pos).Uses(serviceName);
}
@DefinedBy(Api.COMPILER_TREE) @DefinedBy(Api.COMPILER_TREE)
public JCTree visitOther(Tree node, P p) { public JCTree visitOther(Tree node, P p) {
JCTree tree = (JCTree) node; JCTree tree = (JCTree) node;

View File

@ -42,6 +42,7 @@ import static com.sun.tools.javac.code.TypeTag.BOT;
import static com.sun.tools.javac.tree.JCTree.Tag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*;
import static com.sun.tools.javac.tree.JCTree.Tag.BLOCK; import static com.sun.tools.javac.tree.JCTree.Tag.BLOCK;
import static com.sun.tools.javac.tree.JCTree.Tag.SYNCHRONIZED; import static com.sun.tools.javac.tree.JCTree.Tag.SYNCHRONIZED;
import javax.tools.JavaFileObject;
/** Utility class containing inspector methods for trees. /** Utility class containing inspector methods for trees.
* *
@ -762,7 +763,12 @@ public class TreeInfo {
node = skipParens(node); node = skipParens(node);
switch (node.getTag()) { switch (node.getTag()) {
case TOPLEVEL: case TOPLEVEL:
return ((JCCompilationUnit) node).packge; JCCompilationUnit cut = (JCCompilationUnit) node;
if (isModuleInfo(cut) && cut.defs.nonEmpty() && cut.defs.head.hasTag(MODULEDEF))
return symbolFor(cut.defs.head);
return cut.packge;
case MODULEDEF:
return ((JCModuleDecl) node).sym;
case PACKAGEDEF: case PACKAGEDEF:
return ((JCPackageDecl) node).packge; return ((JCPackageDecl) node).packge;
case CLASSDEF: case CLASSDEF:
@ -1144,4 +1150,21 @@ public class TreeInfo {
finder.scan(e); finder.scan(e);
return finder.foundTypeAnno; return finder.foundTypeAnno;
} }
public static boolean isModuleInfo(JCCompilationUnit tree) {
return tree.sourcefile.isNameCompatible("module-info", JavaFileObject.Kind.SOURCE);
}
public static JCModuleDecl getModule(JCCompilationUnit t) {
if (t.defs.nonEmpty()) {
JCTree def = t.defs.head;
if (def.hasTag(MODULEDEF))
return (JCModuleDecl) def;
}
return null;
}
public static boolean isPackageInfo(JCCompilationUnit tree) {
return tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE);
}
} }

View File

@ -125,6 +125,7 @@ public class TreeMaker implements JCTree.Factory {
Assert.check(node instanceof JCClassDecl Assert.check(node instanceof JCClassDecl
|| node instanceof JCPackageDecl || node instanceof JCPackageDecl
|| node instanceof JCImport || node instanceof JCImport
|| node instanceof JCModuleDecl
|| node instanceof JCSkip || node instanceof JCSkip
|| node instanceof JCErroneous || node instanceof JCErroneous
|| (node instanceof JCExpressionStatement || (node instanceof JCExpressionStatement
@ -536,6 +537,41 @@ public class TreeMaker implements JCTree.Factory {
return Modifiers(flags, List.<JCAnnotation>nil()); return Modifiers(flags, List.<JCAnnotation>nil());
} }
@Override
public JCModuleDecl ModuleDef(JCExpression qualid, List<JCDirective> directives) {
JCModuleDecl tree = new JCModuleDecl(qualid, directives);
tree.pos = pos;
return tree;
}
@Override
public JCExports Exports(JCExpression qualId, List<JCExpression> moduleNames) {
JCExports tree = new JCExports(qualId, moduleNames);
tree.pos = pos;
return tree;
}
@Override
public JCProvides Provides(JCExpression serviceName, JCExpression implName) {
JCProvides tree = new JCProvides(serviceName, implName);
tree.pos = pos;
return tree;
}
@Override
public JCRequires Requires(boolean isPublic, JCExpression qualId) {
JCRequires tree = new JCRequires(isPublic, qualId);
tree.pos = pos;
return tree;
}
@Override
public JCUses Uses(JCExpression qualId) {
JCUses tree = new JCUses(qualId);
tree.pos = pos;
return tree;
}
public JCAnnotatedType AnnotatedType(List<JCAnnotation> annotations, JCExpression underlyingType) { public JCAnnotatedType AnnotatedType(List<JCAnnotation> annotations, JCExpression underlyingType) {
JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType); JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType);
tree.pos = pos; tree.pos = pos;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -71,6 +71,34 @@ public class TreeScanner extends Visitor {
scan(tree.pid); scan(tree.pid);
} }
@Override
public void visitModuleDef(JCModuleDecl tree) {
scan(tree.qualId);
scan(tree.directives);
}
@Override
public void visitExports(JCExports tree) {
scan(tree.qualid);
scan(tree.moduleNames);
}
@Override
public void visitProvides(JCProvides tree) {
scan(tree.serviceName);
scan(tree.implName);
}
@Override
public void visitRequires(JCRequires tree) {
scan(tree.moduleName);
}
@Override
public void visitUses(JCUses tree) {
scan(tree.qualid);
}
public void visitImport(JCImport tree) { public void visitImport(JCImport tree) {
scan(tree.qualid); scan(tree.qualid);
} }

View File

@ -0,0 +1,112 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ModuleHelper {
/** The context key for the module helper. */
protected static final Context.Key<ModuleHelper> moduleHelperKey = new Context.Key<>();
/** Get the JavaCompiler instance for this context. */
public static ModuleHelper instance(Context context) {
ModuleHelper instance = context.get(moduleHelperKey);
if (instance == null)
instance = new ModuleHelper(context);
return instance;
}
public ModuleHelper(Context context) {
context.put(moduleHelperKey, this);
Options options = Options.instance(context);
allowAccessToInternalAPI = options.isSet("accessInternalAPI");
}
final boolean allowAccessToInternalAPI;
private void exportPackageToModule(String packageName, Object target)
throws ClassNotFoundException, NoSuchMethodException, IllegalArgumentException,
InvocationTargetException, IllegalAccessException {
if (addExportsMethod == null) {
Class<?> moduleClass = Class.forName("java.lang.reflect.Module");
addExportsMethod = moduleClass.getDeclaredMethod("addExports",
new Class<?>[] { String.class, moduleClass });
}
addExportsMethod.invoke(from, new Object[] { packageName, target });
}
static final String[] javacInternalPackages = new String[] {
"com.sun.tools.javac.api",
"com.sun.tools.javac.code",
"com.sun.tools.javac.comp",
"com.sun.tools.javac.file",
"com.sun.tools.javac.jvm",
"com.sun.tools.javac.main",
"com.sun.tools.javac.model",
"com.sun.tools.javac.parser",
"com.sun.tools.javac.platform",
"com.sun.tools.javac.processing",
"com.sun.tools.javac.tree",
"com.sun.tools.javac.util",
"com.sun.tools.doclint",
};
public void addExports(ClassLoader classLoader) {
try {
if (allowAccessToInternalAPI) {
if (from == null) {
if (getModuleMethod == null) {
getModuleMethod = Class.class.getDeclaredMethod("getModule", new Class<?>[0]);
}
from = getModuleMethod.invoke(getClass(), new Object[0]);
}
if (getUnnamedModuleMethod == null) {
getUnnamedModuleMethod = ClassLoader.class.getDeclaredMethod("getUnnamedModule", new Class<?>[0]);
}
Object target = getUnnamedModuleMethod.invoke(classLoader, new Object[0]);
for (String pack: javacInternalPackages) {
exportPackageToModule(pack, target);
}
}
} catch (Exception e) {
// do nothing
}
}
// a module instance
private Object from = null;
// on java.lang.reflect.Module
private static Method addExportsMethod = null;
// on java.lang.ClassLoader
private static Method getUnnamedModuleMethod = null;
// on java.lang.Class
private static Method getModuleMethod = null;
}

View File

@ -0,0 +1,284 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.Collection;
import java.util.ServiceLoader;
/** This class provides wrappers for classes and methods that are new in JDK 9, and which are not
* available on older versions of the platform on which javac may be compiled and run.
* In future releases, when javac is always compiled on JDK 9 or later, the use of these wrappers
* can be replaced by use of the real underlying classes.
*/
public class ModuleWrappers {
public static final class ServiceLoaderHelper {
@SuppressWarnings("unchecked")
public static <S> ServiceLoader<S> load(Layer layer, Class<S> service) {
try {
Class<?> layerClass = LayerHelper.getLayerClass();
Method loadMethod = ServiceLoader.class
.getDeclaredMethod("load", layerClass, Class.class);
Object result = loadMethod.invoke(ServiceLoader.class, layer.theRealLayer, service);
return (ServiceLoader<S>)result;
} catch (NoSuchMethodException |
SecurityException |
IllegalArgumentException |
IllegalAccessException |
InvocationTargetException ex) {
throw new Abort(ex);
}
}
}
public static class ModuleFinder {
Object theRealModuleFinder;
private ModuleFinder(Object moduleFinder) {
this.theRealModuleFinder = moduleFinder;
}
public static ModuleFinder of(Path... dirs) {
try {
Object result = ModuleFinderHelper.getOfMethod()
.invoke(ModuleFinderHelper.moduleFinderInterface, (Object)dirs);
ModuleFinder mFinder = new ModuleFinder(result);
return mFinder;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new Abort(ex);
}
}
public static ModuleFinder empty() {
try {
Object result = ModuleFinderHelper.getEmptyMethod()
.invoke(ModuleFinderHelper.moduleFinderInterface);
ModuleFinder mFinder = new ModuleFinder(result);
return mFinder;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new Abort(ex);
}
}
}
private static class ModuleFinderHelper {
static Method ofMethod = null;
static Method emptyMethod = null;
static Class<?> moduleFinderInterface;
static Method getOfMethod() {
if (ModuleFinderHelper.ofMethod == null) {
try {
getModuleFinderInterface();
ofMethod = moduleFinderInterface.getDeclaredMethod("of", Path[].class);
} catch (NoSuchMethodException | SecurityException ex) {
throw new Abort(ex);
}
}
return ofMethod;
}
static Method getEmptyMethod() {
if (emptyMethod == null) {
try {
getModuleFinderInterface();
emptyMethod = moduleFinderInterface.getDeclaredMethod("empty");
} catch (NoSuchMethodException | SecurityException ex) {
throw new Abort(ex);
}
}
return emptyMethod;
}
static Class<?> getModuleFinderInterface() {
if (moduleFinderInterface == null) {
try {
moduleFinderInterface = Class.forName("java.lang.module.ModuleFinder", false, ClassLoader.getSystemClassLoader());
} catch (ClassNotFoundException ex) {
throw new Abort(ex);
}
}
return moduleFinderInterface;
}
}
public static final class Configuration {
Object theRealConfiguration;
private Configuration(Object configuration) {
this.theRealConfiguration = configuration;
}
public Configuration resolveRequiresAndUses(
ModuleFinder beforeFinder,
ModuleFinder afterFinder,
Collection<String> roots) {
try {
Object result = ConfigurationHelper.getResolveRequiresAndUses()
.invoke(theRealConfiguration,
beforeFinder.theRealModuleFinder,
afterFinder.theRealModuleFinder,
roots
);
Configuration configuration = new Configuration(result);
return configuration;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new Abort(ex);
}
}
}
private static class ConfigurationHelper {
static Method resolveRequiresAndUsesMethod;
static Class<?> configurationClass;
static Method getResolveRequiresAndUses() {
if (resolveRequiresAndUsesMethod == null) {
try {
getConfigurationClass();
Class<?> moduleFinderInterface = ModuleFinderHelper.getModuleFinderInterface();
Class<?> configurationClass = ConfigurationHelper.getConfigurationClass();
resolveRequiresAndUsesMethod = configurationClass.getDeclaredMethod("resolveRequiresAndUses",
moduleFinderInterface,
moduleFinderInterface,
Collection.class
);
} catch (NoSuchMethodException | SecurityException ex) {
throw new Abort(ex);
}
}
return resolveRequiresAndUsesMethod;
}
static Class<?> getConfigurationClass() {
if (configurationClass == null) {
try {
configurationClass = Class.forName("java.lang.module.Configuration", false, ClassLoader.getSystemClassLoader());
} catch (ClassNotFoundException ex) {
throw new Abort(ex);
}
}
return configurationClass;
}
}
public static final class Layer {
Object theRealLayer;
private Layer(Object layer) {
this.theRealLayer = layer;
}
public static Layer boot() {
try {
Object result = LayerHelper.getBootMethod().invoke(LayerHelper.getLayerClass());
Layer layer = new Layer(result);
return layer;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new Abort(ex);
}
}
public Configuration configuration() {
try {
Object result = LayerHelper.getConfigurationMethod().invoke(theRealLayer);
Layer layer = new Layer(result);
return new Configuration(result);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new Abort(ex);
}
}
public Layer defineModulesWithOneLoader(Configuration configuration, ClassLoader parentClassLoader) {
try {
Object result = LayerHelper.getDefineModulesWithOneLoaderMethod()
.invoke(theRealLayer, configuration.theRealConfiguration, parentClassLoader);
Layer layer = new Layer(result);
return layer;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new Abort(ex);
}
}
}
private static class LayerHelper {
static Class<?> layerClass;
static Method bootMethod;
static Method defineModulesWithOneLoaderMethod = null;
static Method configurationMethod;
static Class<?> getLayerClass() {
if (layerClass == null) {
try {
layerClass = Class.forName("java.lang.reflect.Layer", false, ClassLoader.getSystemClassLoader());
} catch (ClassNotFoundException ex) {
throw new Abort(ex);
}
}
return layerClass;
}
static Method getBootMethod() {
if (bootMethod == null) {
try {
bootMethod = getLayerClass().getDeclaredMethod("boot");
} catch (NoSuchMethodException | SecurityException ex) {
throw new Abort(ex);
}
}
return bootMethod;
}
static Method getDefineModulesWithOneLoaderMethod() {
if (defineModulesWithOneLoaderMethod == null) {
try {
defineModulesWithOneLoaderMethod = getLayerClass().getDeclaredMethod("defineModulesWithOneLoader",
ConfigurationHelper.getConfigurationClass(),
ClassLoader.class
);
} catch (NoSuchMethodException | SecurityException ex) {
throw new Abort(ex);
}
}
return defineModulesWithOneLoaderMethod;
}
static Method getConfigurationMethod() {
if (configurationMethod == null) {
try {
configurationMethod = getLayerClass().getDeclaredMethod("configuration");
} catch (NoSuchMethodException | SecurityException ex) {
throw new Abort(ex);
}
}
return configurationMethod;
}
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -127,9 +127,11 @@ public abstract class Name implements javax.lang.model.element.Name {
int prefixOffset = prefix.getByteOffset(); int prefixOffset = prefix.getByteOffset();
int prefixLength = prefix.getByteLength(); int prefixLength = prefix.getByteLength();
if (thisLength < prefixLength)
return false;
int i = 0; int i = 0;
while (i < prefixLength && while (i < prefixLength &&
i < thisLength &&
thisBytes[thisOffset + i] == prefixBytes[prefixOffset + i]) thisBytes[thisOffset + i] == prefixBytes[prefixOffset + i])
i++; i++;
return i == prefixLength; return i == prefixLength;

Some files were not shown because too many files have changed in this diff Show More