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:
parent
8cffe4fb02
commit
001ebb3a72
@ -32,23 +32,35 @@ include JavaCompilation.gmk
|
||||
include SetupJavaCompilers.gmk
|
||||
|
||||
################################################################################
|
||||
# Setup the rules to build the interim langtools jar, which is compiled by
|
||||
# the boot 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
|
||||
# as it will be used together with the interim javac.
|
||||
$(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)))
|
||||
# Setup the rules to build interim langtools, which is compiled by the boot
|
||||
# javac and can be run on the boot jdk. This will be used to compile
|
||||
# the rest of the product. Each module is compiled separately to allow a modular
|
||||
# boot jdk to override system classes using -Xoverride:.
|
||||
|
||||
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)
|
||||
|
@ -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.
|
||||
#
|
||||
# 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.debug = true
|
||||
javac.debuglevel = source,lines,vars
|
||||
javac.extra.opts=-XDignore.symbol.file=true
|
||||
javac.includes=
|
||||
javac.lint.opts = -Xlint:all,-deprecation -Werror
|
||||
javac.source = 8
|
||||
javac.target = 8
|
||||
javac.opts = -XDignore.symbol.file=true -Xlint:all,-deprecation,-options -Werror -g:source,lines,vars
|
||||
javac.source = 9
|
||||
javac.target = 9
|
||||
|
||||
#javac configuration for bootstrap build (these will be passed to the compiler from the given boot JDK):
|
||||
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 = \
|
||||
langtools.resource.includes = \
|
||||
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™ Language Specification
|
||||
javadoc.jls.option=-tag "jls:a:See <cite>${javadoc.jls.cite}</cite>:" \
|
||||
-tag "implNote:a:Implementation Note:"
|
||||
|
||||
# Version info -- override as needed
|
||||
jdk.version = 9
|
||||
build.number = b00
|
||||
@ -89,3 +44,14 @@ milestone = internal
|
||||
# FIXME -- need to include openjdk as needed
|
||||
release = ${jdk.version}-${milestone}
|
||||
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
@ -39,6 +39,10 @@ $(eval $(call SetupJavaCompilation, COMPILE_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: \
|
||||
$(COMPILE_CREATE_SYMBOLS) \
|
||||
$(wildcard $(LANGTOOLS_TOPDIR)/make/data/symbols/*)
|
||||
@ -46,6 +50,7 @@ $(SUPPORT_OUTPUTDIR)/symbols/ct.sym-files/_the.symbols: \
|
||||
$(MKDIR) -p $(@D)
|
||||
$(ECHO) Creating ct.sym classes
|
||||
$(JAVA) $(INTERIM_LANGTOOLS_ARGS) \
|
||||
$(COMPILECREATESYMBOLS_ADD_EXPORTS) \
|
||||
-classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols \
|
||||
build.tools.symbolgenerator.CreateSymbols \
|
||||
build-ctsym \
|
||||
|
@ -3,16 +3,12 @@
|
||||
<component name="AntConfiguration">
|
||||
<buildFile url="file://$PROJECT_DIR$/.idea/build.xml">
|
||||
<properties>
|
||||
<property name="boot.java.home" value="$JDKPath$" />
|
||||
<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="javac.debuglevel" value="source,lines,vars" />
|
||||
<property name="jtreg.jpda.jvmargs" value="-agentlib:jdwp=transport=dt_socket,server=n,address=localhost:5900,suspend=y" />
|
||||
<property name="jtreg.jpda.jvmargs" value="-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=5900" />
|
||||
</properties>
|
||||
<executeOn event="afterCompilation" target="post-make" />
|
||||
</buildFile>
|
||||
</component>
|
||||
</project>
|
||||
|
||||
|
||||
|
@ -15,8 +15,7 @@
|
||||
<java classname="org.apache.tools.ant.Main" fork="true" spawn="true">
|
||||
<arg value="-f"/>
|
||||
<arg value="@{antfile}"/>
|
||||
<arg value="-Dboot.java.home=${boot.java.home}"/>
|
||||
<arg value="-Dtarget.java.home=${target.java.home}"/>
|
||||
<arg value="-Dlangtools.jdk.home=${langtools.jdk.home}"/>
|
||||
<arg value="-Djtreg.home=${jtreg.home}"/>
|
||||
<arg value="-Djtreg.tests=${jtreg.tests}"/>
|
||||
<arg value="-Djtreg.jpda.jvmargs=${jtreg.jpda.jvmargs}"/>
|
||||
@ -28,18 +27,13 @@
|
||||
</sequential>
|
||||
</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="jtreg-debug" depends="build-all-tools,-def-jtreg">
|
||||
<target name="jtreg-debug" depends="build-all-tools, -def-jtreg">
|
||||
<exec-target target="jtreg-debug-internal"/>
|
||||
</target>
|
||||
|
||||
<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>
|
||||
</project>
|
||||
|
||||
|
@ -8,12 +8,11 @@
|
||||
<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.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$/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>
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
|
@ -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.
|
||||
*/
|
||||
enum Task {
|
||||
/** javac task - invoked during compilation */
|
||||
JAVAC("javac", MessageKind.JAVAC_ERROR, MessageKind.JAVAC_WARNING, MessageKind.JAVAC_NOTE,
|
||||
/** exec task - invoked during compilation */
|
||||
JAVAC("exec", MessageKind.JAVAC_ERROR, MessageKind.JAVAC_WARNING, MessageKind.JAVAC_NOTE,
|
||||
MessageKind.JAVAC_NESTED_DIAG, MessageKind.JAVAC_CRASH),
|
||||
/** jtreg task - invoked during test execution */
|
||||
JTREG("jtreg", MessageKind.JTREG_TEST_PASSED, MessageKind.JTREG_TEST_FAILED, MessageKind.JTREG_TEST_ERROR, MessageKind.JTREG_TEST_REPORT),
|
||||
|
@ -7,14 +7,14 @@
|
||||
<option name="MAKE_PROJECT_ON_SAVE" value="true" />
|
||||
</component>
|
||||
<component name="RunManager" selected="Application.javac">
|
||||
<!-- standard tools -->
|
||||
<!-- javac -->
|
||||
<configuration default="false" name="javac" type="Application" factoryName="Application">
|
||||
<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="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="" />
|
||||
<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="ENV_VARIABLES" />
|
||||
<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" />
|
||||
</method>
|
||||
</configuration>
|
||||
<!-- javadoc -->
|
||||
<configuration default="false" name="javadoc" type="Application" factoryName="Application">
|
||||
<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="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="" />
|
||||
<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="ENV_VARIABLES" />
|
||||
<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" />
|
||||
</method>
|
||||
</configuration>
|
||||
<!-- javap -->
|
||||
<configuration default="false" name="javap" type="Application" factoryName="Application">
|
||||
<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="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="" />
|
||||
<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="ENV_VARIABLES" />
|
||||
<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" />
|
||||
</method>
|
||||
</configuration>
|
||||
<!-- javah -->
|
||||
<configuration default="false" name="javah" type="Application" factoryName="Application">
|
||||
<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="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="" />
|
||||
<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="ENV_VARIABLES" />
|
||||
<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" />
|
||||
</method>
|
||||
</configuration>
|
||||
<!-- sjavac -->
|
||||
<configuration default="false" name="sjavac" type="Application" factoryName="Application">
|
||||
<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="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="" />
|
||||
<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="ENV_VARIABLES" />
|
||||
<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" />
|
||||
</method>
|
||||
</configuration>
|
||||
<!-- jshell -->
|
||||
<configuration default="false" name="jshell" type="Application" factoryName="Application">
|
||||
<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="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="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="ENV_VARIABLES" />
|
||||
<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" />
|
||||
</method>
|
||||
</configuration>
|
||||
<!-- bootstrap javac -->
|
||||
<configuration default="false" name="javac (bootstrap)" type="Application" factoryName="Application">
|
||||
<option name="MAIN_CLASS_NAME" value="com.sun.tools.javac.Main" />
|
||||
<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" />
|
||||
<!-- jtreg run -->
|
||||
<configuration default="false" name="jtreg (run)" type="AntRunConfiguration" factoryName="Ant Target">
|
||||
<antsettings antfile="file://$PROJECT_DIR$/.idea/build.xml" target="jtreg" />
|
||||
<method>
|
||||
<option name="Make" enabled="false" />
|
||||
<option name="AntTarget" enabled="true" antfile="file://$PROJECT_DIR$/.idea/build.xml" target="build-bootstrap-javac" />
|
||||
</method>
|
||||
</configuration>
|
||||
<!-- jtreg debug -->
|
||||
@ -181,4 +174,3 @@
|
||||
</buildFile>
|
||||
</component>
|
||||
</project>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/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.
|
||||
#
|
||||
# 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`
|
||||
;;
|
||||
esac
|
||||
mylib="$mydir/../lib"
|
||||
mylib="$mydir/../modules"
|
||||
|
||||
# By default, put the jar file and its dependencies on the bootclasspath.
|
||||
# This is always required on a Mac, because the system langtools classes
|
||||
# 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
|
||||
# patch langtools modules
|
||||
bcp=-Xpatch:"$mylib"
|
||||
|
||||
# tools currently assumes that assertions are enabled in the launcher
|
||||
ea=-ea:com.sun.tools...
|
||||
@ -71,4 +59,4 @@ done
|
||||
unset DUALCASE
|
||||
|
||||
IFS=$nl
|
||||
"#TARGET_JAVA#" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} #PROGRAM# ${toolOpts}
|
||||
"#TARGET_JAVA#" $bcp ${ea} ${javaOpts} #PROGRAM# ${toolOpts}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?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
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -48,20 +48,12 @@
|
||||
|
||||
<!-- 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) -->
|
||||
|
||||
<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>
|
||||
<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"
|
||||
destdir="${build.dir}/${module.name}/classes"
|
||||
includes="${includes}"
|
||||
@ -72,7 +64,6 @@
|
||||
target="${javac.target}"
|
||||
debug="${javac.debug}"
|
||||
debuglevel="${javac.debuglevel}">
|
||||
<compilerarg value="-J-Xbootclasspath/p:${build.bootstrap.dir}/classes"/>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
@ -81,12 +72,11 @@
|
||||
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">
|
||||
<echo level="info" message="${with_bootclasspath}"/>
|
||||
<echo level="info" message="Run ${use_bootstrap}${langtools.tool.name} with args ${langtools.tool.args}"/>
|
||||
<echo level="info" message="Run ${langtools.tool.name} with args ${langtools.tool.args}"/>
|
||||
<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 name="-def-resolve-main-class">
|
||||
@ -102,17 +92,14 @@
|
||||
</macrodef>
|
||||
</target>
|
||||
|
||||
<target name="-build-classes" depends="-get-tool-if-set,-build-classes-bootstrap-javac,-build-classes-all" />
|
||||
<target name="-build-classes-bootstrap-javac" if="langtools.tool.bootstrap">
|
||||
<antcall target="build-bootstrap-javac-classes"/>
|
||||
</target>
|
||||
<target name="-build-classes-all" unless="langtools.tool.bootstrap">
|
||||
<target name="-build-classes" depends="-get-tool-if-set,-build-classes-all" />
|
||||
<target name="-build-classes-all">
|
||||
<antcall target="build-all-classes"/>
|
||||
</target>
|
||||
|
||||
<!-- 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>
|
||||
<echo level="info" message="run ${run.classname}"/>
|
||||
<run mainclass="${run.classname}" args=""/>
|
||||
@ -123,22 +110,12 @@
|
||||
test all tools.
|
||||
-->
|
||||
|
||||
<target name="jtreg" depends="-get-tool-if-set,-jtreg-bootstrap-javac,-jtreg-all"
|
||||
description="Test langtools tools or bootstrap javac"
|
||||
<target name="jtreg" depends="-get-tool-if-set,-jtreg-all"
|
||||
description="Test langtools tools"
|
||||
/>
|
||||
|
||||
<target name="-jtreg-bootstrap-javac" if="langtools.tool.bootstrap">
|
||||
<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">
|
||||
<target name="-jtreg-all">
|
||||
<echo level="info" message="Testing all tools"/>
|
||||
<echo level="verbose" message="(Set langtools.tool.bootstrap to test bootstrap javac)"/>
|
||||
<antcall>
|
||||
<target name="langtools.jtreg"/>
|
||||
<target name="-show-jtreg"/>
|
||||
@ -173,29 +150,27 @@
|
||||
|
||||
<!-- 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">
|
||||
<echo level="info" message="Debug ${use_bootstrap}${langtools.tool.name} with args ${langtools.tool.args}"/>
|
||||
<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 ${langtools.tool.name} with args ${langtools.tool.args}"/>
|
||||
<start-debugger/>
|
||||
<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>
|
||||
|
||||
<!-- 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>
|
||||
<start-debugger/>
|
||||
<run mainclass="${debug.classname}" args="" jpda.jvmargs="${jpda.jvmargs}"/>
|
||||
</target>
|
||||
|
||||
<!-- 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>
|
||||
<start-debugger/>
|
||||
<jtreg-tool name="debug"
|
||||
samevm="false"
|
||||
tests="${jtreg.tests}"
|
||||
jpda.jvmargs="${jpda.jvmargs}"
|
||||
langtools.classes="${with_bootclasspath}"/>
|
||||
jpda.jvmargs="${jpda.jvmargs}"/>
|
||||
</target>
|
||||
|
||||
<!-- Update a class being debugged. -->
|
||||
@ -206,11 +181,7 @@
|
||||
<antcall target="compile-single">
|
||||
<param name="includes" value="${class}.java"/>
|
||||
</antcall>
|
||||
<condition property="build.classes.dir"
|
||||
value="${build.dir}/${module.name}/classes"
|
||||
else="${boot.build.dir}/${module.name}/classes">
|
||||
<isset property="use_bootstrap"/>
|
||||
</condition>
|
||||
<property name="build.classes.dir" value="${build.dir}/${module.name}/classes" />
|
||||
<nbjpdareload>
|
||||
<fileset dir="${build.classes.dir}">
|
||||
<include name="${class}.class"/>
|
||||
@ -218,23 +189,11 @@
|
||||
</nbjpdareload>
|
||||
</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. -->
|
||||
|
||||
<target name="-get-tool-if-set" depends="-def-select-tool">
|
||||
<select-tool
|
||||
toolproperty="langtools.tool.name"
|
||||
bootstrapproperty="langtools.tool.bootstrap"
|
||||
propertyfile="${langtools.properties}"
|
||||
askIfUnset="false"
|
||||
/>
|
||||
@ -244,32 +203,22 @@
|
||||
<select-tool
|
||||
toolproperty="langtools.tool.name"
|
||||
argsproperty="langtools.tool.args"
|
||||
bootstrapproperty="langtools.tool.bootstrap"
|
||||
propertyfile="${langtools.properties}"
|
||||
askIfUnset="true"
|
||||
/>
|
||||
</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 -->
|
||||
<target name="-def-run">
|
||||
<macrodef name="run">
|
||||
<attribute name="mainclass"/>
|
||||
<attribute name="args" default=""/>
|
||||
<attribute name="bcp" default="${with_bootclasspath}"/>
|
||||
<attribute name="build.modules" default="${build.modules}"/>
|
||||
<attribute name="jpda.jvmargs" default=""/>
|
||||
|
||||
<sequential>
|
||||
<java fork="true" jvm="${target.java.home}/bin/java" classname="@{mainclass}">
|
||||
<jvmarg line="-Xbootclasspath/p:@{bcp}"/>
|
||||
<java fork="true" jvm="${langtools.jdk.home}/bin/java" classname="@{mainclass}">
|
||||
<jvmarg line="-Xpatch:@{build.modules}"/>
|
||||
<jvmarg line="@{jpda.jvmargs}"/>
|
||||
<arg line="@{args}"/>
|
||||
</java>
|
||||
@ -285,11 +234,7 @@
|
||||
<nbjpdastart name="${ant.project.name}" addressproperty="jpda.address" transport="dt_socket">
|
||||
<bootclasspath>
|
||||
<pathelement path="${langtools.classes}"/>
|
||||
<pathelement location="${target.java.home}/jre/lib/rt.jar"/>
|
||||
</bootclasspath>
|
||||
<sourcepath>
|
||||
<pathelement path="${langtools.sources}"/>
|
||||
</sourcepath>
|
||||
</nbjpdastart>
|
||||
<property
|
||||
name="@{jpda.jvmargs.property}"
|
||||
@ -300,6 +245,7 @@
|
||||
</target>
|
||||
|
||||
<target name="-def-select-tool">
|
||||
<property name="build.toolclasses.dir" location="${build.dir}/toolclasses"/>
|
||||
<mkdir dir="${build.toolclasses.dir}"/>
|
||||
<javac srcdir="${make.tools.dir}"
|
||||
includes="anttasks/SelectTool*"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?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
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -408,9 +408,6 @@
|
||||
</arity>
|
||||
</context>
|
||||
</action>
|
||||
<action name="javadoc">
|
||||
<target>javadoc</target>
|
||||
</action>
|
||||
<action name="select-tool">
|
||||
<target>select-tool</target>
|
||||
</action>
|
||||
@ -477,7 +474,6 @@
|
||||
<ide-action name="build"/>
|
||||
<ide-action name="rebuild"/>
|
||||
<ide-action name="clean"/>
|
||||
<ide-action name="javadoc"/>
|
||||
<separator/>
|
||||
<ide-action name="run"/>
|
||||
<ide-action name="debug"/>
|
||||
@ -490,37 +486,35 @@
|
||||
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4">
|
||||
<compilation-unit>
|
||||
<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>
|
||||
<source-level>1.8</source-level>
|
||||
</compilation-unit>
|
||||
<compilation-unit>
|
||||
<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>
|
||||
<built-to>${root}/build/jdk.compiler/classes</built-to>
|
||||
<source-level>1.8</source-level>
|
||||
</compilation-unit>
|
||||
<compilation-unit>
|
||||
<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>
|
||||
<built-to>${root}/build/jdk.jdeps/classes</built-to>
|
||||
<source-level>1.8</source-level>
|
||||
</compilation-unit>
|
||||
<compilation-unit>
|
||||
<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>
|
||||
<built-to>${root}/build/jdk.javadoc/classes</built-to>
|
||||
<source-level>1.8</source-level>
|
||||
</compilation-unit>
|
||||
<compilation-unit>
|
||||
<package-root>${root}/src/jdk.jshell/share/classes</package-root>
|
||||
<package-root>${root}/build/bootstrap/jdk.jshell/gensrc</package-root>
|
||||
<package-root>${root}/../jdk/src/jdk.internal.le/share/classes</package-root>
|
||||
<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>
|
||||
<package-root>${root}/build/gensrc/jdk.jshell</package-root>
|
||||
<classpath mode="compile">${root}/build/java.compiler/classes:${root}/build/jdk.compiler/classes</classpath>
|
||||
<built-to>${root}/build/jdk.jshell/classes</built-to>
|
||||
<source-level>1.8</source-level>
|
||||
</compilation-unit>
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -74,18 +74,7 @@ public class SelectToolTask extends Task {
|
||||
|
||||
enum ToolChoices {
|
||||
NONE(""),
|
||||
BOOSTRAP_JAVAC("bootstrap-javac", true) {
|
||||
@Override
|
||||
public ToolChoices baseTool() {
|
||||
return JAVAC;
|
||||
}
|
||||
},
|
||||
JAVAC("javac") {
|
||||
@Override
|
||||
public ToolChoices asBootstrap() {
|
||||
return BOOSTRAP_JAVAC;
|
||||
}
|
||||
},
|
||||
JAVAC("javac"),
|
||||
JAVADOC("javadoc"),
|
||||
JAVAH("javah"),
|
||||
JAVAP("javap"),
|
||||
@ -103,14 +92,6 @@ public class SelectToolTask extends Task {
|
||||
this.bootstrap = bootstrap;
|
||||
}
|
||||
|
||||
public ToolChoices asBootstrap() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ToolChoices baseTool() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toolName;
|
||||
@ -145,15 +126,6 @@ public class SelectToolTask extends Task {
|
||||
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
|
||||
* a default value for a property.
|
||||
@ -169,7 +141,6 @@ public class SelectToolTask extends Task {
|
||||
|
||||
Properties props = readProperties(propertyFile);
|
||||
toolName = props.getProperty("tool.name");
|
||||
toolBootstrap = props.getProperty("tool.bootstrap") != null;
|
||||
if (toolName != null) {
|
||||
toolArgs = props.getProperty(toolName + ".args", "");
|
||||
}
|
||||
@ -183,8 +154,6 @@ public class SelectToolTask extends Task {
|
||||
// finally, return required values, if any
|
||||
if (toolProperty != null && !(toolName == null || toolName.equals(""))) {
|
||||
p.setProperty(toolProperty, toolName);
|
||||
if (toolBootstrap)
|
||||
p.setProperty(bootstrapProperty, "true");
|
||||
|
||||
if (argsProperty != null && toolArgs != null)
|
||||
p.setProperty(argsProperty, toolArgs);
|
||||
@ -198,20 +167,15 @@ public class SelectToolTask extends Task {
|
||||
|
||||
ToolChoices tool = (ToolChoices)toolChoice.getSelectedItem();
|
||||
|
||||
toolName = tool.baseTool().toolName;
|
||||
toolBootstrap = tool.bootstrap;
|
||||
toolName = tool.toolName;
|
||||
toolArgs = argsField.getText();
|
||||
if (defaultCheck.isSelected()) {
|
||||
if (toolName.equals("")) {
|
||||
fileProps.remove("tool.name");
|
||||
fileProps.remove("tool.bootstrap");
|
||||
} else {
|
||||
fileProps.remove("tool.bootstrap");
|
||||
fileProps.put("tool.name", toolName);
|
||||
if (toolBootstrap) {
|
||||
fileProps.put("tool.bootstrap", "true");
|
||||
} else {
|
||||
fileProps.remove("tool.bootstrap");
|
||||
}
|
||||
fileProps.put(toolName + ".args", toolArgs);
|
||||
}
|
||||
writeProperties(propertyFile, fileProps);
|
||||
@ -237,8 +201,6 @@ public class SelectToolTask extends Task {
|
||||
toolChoice = new JComboBox<>(toolChoices.toArray());
|
||||
ToolChoices tool = toolName != null ? ToolChoices.valueOf(toolName.toUpperCase()) : null;
|
||||
if (toolName != null) {
|
||||
if (toolBootstrap)
|
||||
tool = tool.asBootstrap();
|
||||
toolChoice.setSelectedItem(tool);
|
||||
}
|
||||
toolChoice.addItemListener(new ItemListener() {
|
||||
@ -348,14 +310,13 @@ public class SelectToolTask extends Task {
|
||||
String getDefaultArgsForTool(Properties props, ToolChoices tool) {
|
||||
if (tool == null)
|
||||
return "";
|
||||
String toolName = tool.baseTool().toolName;
|
||||
String toolName = tool.toolName;
|
||||
return toolName.equals("") ? "" : props.getProperty(toolName + ".args", "");
|
||||
}
|
||||
|
||||
// Ant task parameters
|
||||
private boolean askIfUnset;
|
||||
private String toolProperty;
|
||||
private String bootstrapProperty;
|
||||
private String argsProperty;
|
||||
private File propertyFile;
|
||||
|
||||
@ -367,6 +328,5 @@ public class SelectToolTask extends Task {
|
||||
|
||||
// Result values for the client
|
||||
private String toolName;
|
||||
private boolean toolBootstrap;
|
||||
private String toolArgs;
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,10 +23,13 @@
|
||||
|
||||
package crules;
|
||||
|
||||
import java.lang.reflect.Layer;
|
||||
import java.lang.reflect.Module;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.tools.JavaFileObject;
|
||||
@ -52,6 +55,11 @@ public class CodingRulesAnalyzerPlugin implements Plugin {
|
||||
|
||||
@DefinedBy(Api.COMPILER_TREE)
|
||||
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;
|
||||
Context context = impl.getContext();
|
||||
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 {
|
||||
private final Map<Kind, List<AbstractCodingRulesAnalyzer>> analyzers = new HashMap<>();
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
* 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"),
|
||||
FILE("file", "File", "java.io"),
|
||||
FILE_OBJECT("file object", "JavaFileObject", "javax.tools"),
|
||||
PATH("path", "Path", "java.nio.file"),
|
||||
NAME("name", "Name", "com.sun.tools.javac.util"),
|
||||
NUMBER("number", "int", null),
|
||||
OPTION_NAME("option name", "Option", "com.sun.tools.javac.main"),
|
||||
|
@ -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.
|
||||
*
|
||||
* 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"}.
|
||||
*
|
||||
* If this element represents an unnamed {@linkplain
|
||||
* PackageElement#getSimpleName package}, an empty name is
|
||||
* returned.
|
||||
* PackageElement#getSimpleName package} or unnamed {@linkplain
|
||||
* ModuleElement#getSimpleName module}, an empty name is returned.
|
||||
*
|
||||
* If it represents a {@linkplain ExecutableElement#getSimpleName
|
||||
* 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 TypeElement#getSimpleName
|
||||
* @see VariableElement#getSimpleName
|
||||
* @see ModuleElement#getSimpleName
|
||||
*/
|
||||
Name getSimpleName();
|
||||
|
||||
@ -137,7 +138,7 @@ public interface Element extends javax.lang.model.AnnotatedConstruct {
|
||||
* top-level type}, its package is returned.
|
||||
*
|
||||
* <li> If this is a {@linkplain
|
||||
* PackageElement#getEnclosingElement package}, {@code null} is
|
||||
* PackageElement#getEnclosingElement package}, its module is
|
||||
* returned.
|
||||
*
|
||||
* <li> If this is a {@linkplain
|
||||
@ -150,6 +151,9 @@ public interface Element extends javax.lang.model.AnnotatedConstruct {
|
||||
* parameter}, {@linkplain ExecutableElement the executable
|
||||
* element} which declares the parameter is returned.
|
||||
*
|
||||
* <li> If this is a {@linkplain ModuleElement#getEnclosingElement
|
||||
* module}, {@code null} is returned.
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* @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
|
||||
* not considered to enclose subpackages.
|
||||
*
|
||||
* A {@linkplain ModuleElement#getEnclosedElements module}
|
||||
* encloses packages within it.
|
||||
*
|
||||
* Other kinds of elements are not currently considered to enclose
|
||||
* any elements; however, that may change as this API or the
|
||||
* programming language evolves.
|
||||
@ -177,8 +184,9 @@ public interface Element extends javax.lang.model.AnnotatedConstruct {
|
||||
* methods in {@link ElementFilter}.
|
||||
*
|
||||
* @return the enclosed elements, or an empty list if none
|
||||
* @see PackageElement#getEnclosedElements
|
||||
* @see TypeElement#getEnclosedElements
|
||||
* @see PackageElement#getEnclosedElements
|
||||
* @see ModuleElement#getEnclosedElements
|
||||
* @see Elements#getAllMembers
|
||||
* @jls 8.8.9 Default Constructor
|
||||
* @jls 8.9 Enums
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -94,7 +94,13 @@ public enum ElementKind {
|
||||
* A resource variable.
|
||||
* @since 1.7
|
||||
*/
|
||||
RESOURCE_VARIABLE;
|
||||
RESOURCE_VARIABLE,
|
||||
|
||||
/**
|
||||
* A module.
|
||||
* @since 9
|
||||
*/
|
||||
MODULE;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
@ -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™ 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();
|
||||
}
|
||||
}
|
@ -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.
|
||||
*
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* Returns {@code true} is this is an unnamed package and {@code
|
||||
* Returns {@code true} if this is an unnamed package and {@code
|
||||
* 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
|
||||
* @jls 7.4.2 Unnamed Packages
|
||||
*/
|
||||
boolean isUnnamed();
|
||||
|
||||
/**
|
||||
* Returns {@code null} since a package is not enclosed by another
|
||||
* element.
|
||||
* Returns the enclosing module.
|
||||
*
|
||||
* @return {@code null}
|
||||
* @return the enclosing module
|
||||
*/
|
||||
@Override
|
||||
Element getEnclosingElement();
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -151,7 +151,14 @@ public enum TypeKind {
|
||||
*
|
||||
* @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
|
||||
|
@ -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.
|
||||
*
|
||||
* 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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.ModuleElement;
|
||||
import static javax.lang.model.SourceVersion.*;
|
||||
|
||||
|
||||
@ -71,4 +72,15 @@ public abstract class AbstractElementVisitor9<R, P> extends AbstractElementVisit
|
||||
protected AbstractElementVisitor9(){
|
||||
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);
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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 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 =
|
||||
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 =
|
||||
Collections.unmodifiableSet(EnumSet.of(ElementKind.CLASS,
|
||||
ElementKind.ENUM,
|
||||
@ -183,6 +192,28 @@ public class ElementFilter {
|
||||
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.
|
||||
private static <E extends Element> List<E> listFilter(Iterable<? extends Element> elements,
|
||||
Set<ElementKind> targetKinds,
|
||||
@ -207,4 +238,62 @@ public class ElementFilter {
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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){
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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 javax.lang.model.element.*;
|
||||
import javax.lang.model.type.*;
|
||||
|
||||
|
||||
/**
|
||||
@ -63,6 +62,15 @@ public interface Elements {
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@ -128,6 +136,16 @@ public interface Elements {
|
||||
*/
|
||||
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
|
||||
* declared directly. For a class the result also includes its
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.ModuleElement;
|
||||
import static javax.lang.model.SourceVersion.*;
|
||||
|
||||
/**
|
||||
@ -90,4 +91,17 @@ public class SimpleElementVisitor9<R, P> extends SimpleElementVisitor8<R, P> {
|
||||
protected SimpleElementVisitor9(R 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);
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.util.Iterator;
|
||||
import java.util.Objects;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import javax.tools.JavaFileObject.Kind;
|
||||
|
||||
@ -163,4 +164,24 @@ public class ForwardingJavaFileManager<M extends JavaFileManager> implements Jav
|
||||
public void close() throws IOException {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
|
||||
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
|
||||
*/
|
||||
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
|
||||
* @see #close
|
||||
*/
|
||||
@Override
|
||||
void flush() throws IOException;
|
||||
|
||||
/**
|
||||
@ -398,5 +412,84 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
|
||||
* @throws IOException if an I/O error occurred
|
||||
* @see #flush
|
||||
*/
|
||||
@Override
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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,
|
||||
|
||||
/**
|
||||
* Location to search for modules containing annotation processors.
|
||||
* @since 9
|
||||
*/
|
||||
ANNOTATION_PROCESSOR_MODULE_PATH,
|
||||
|
||||
/**
|
||||
* Location to search for platform classes. Sometimes called
|
||||
* the boot class path.
|
||||
@ -72,7 +78,31 @@ public enum StandardLocation implements Location {
|
||||
* Location of new native header files.
|
||||
* @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
|
||||
@ -90,8 +120,11 @@ public enum StandardLocation implements Location {
|
||||
for (Location location : values())
|
||||
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; }
|
||||
@Override
|
||||
public boolean isOutputLocation() { return name.endsWith("_OUTPUT"); }
|
||||
});
|
||||
return locations.get(name);
|
||||
@ -100,8 +133,10 @@ public enum StandardLocation implements Location {
|
||||
private static final ConcurrentMap<String,Location> locations
|
||||
= new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public String getName() { return name(); }
|
||||
|
||||
@Override
|
||||
public boolean isOutputLocation() {
|
||||
switch (this) {
|
||||
case CLASS_OUTPUT:
|
||||
@ -112,4 +147,18 @@ public enum StandardLocation implements Location {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,10 +25,11 @@
|
||||
|
||||
package javax.tools;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceConfigurationError;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* Provides methods for locating tool providers, for example,
|
||||
@ -40,8 +41,8 @@ import java.util.Map;
|
||||
*/
|
||||
public class ToolProvider {
|
||||
|
||||
private static final String systemJavaCompilerName
|
||||
= "com.sun.tools.javac.api.JavacTool";
|
||||
private static final String systemJavaCompilerModule = "jdk.compiler";
|
||||
private static final String systemJavaCompilerName = "com.sun.tools.javac.api.JavacTool";
|
||||
|
||||
/**
|
||||
* Returns the Java™ programming language compiler provided
|
||||
@ -52,13 +53,17 @@ public class ToolProvider {
|
||||
* {@linkplain java.nio.file.FileSystem filesystem}.</p>
|
||||
* @return the compiler provided with this platform or
|
||||
* {@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() {
|
||||
return instance().getSystemTool(JavaCompiler.class, systemJavaCompilerName);
|
||||
return getSystemTool(JavaCompiler.class,
|
||||
systemJavaCompilerModule, systemJavaCompilerName);
|
||||
}
|
||||
|
||||
private static final String systemDocumentationToolName
|
||||
= "jdk.javadoc.internal.api.JavadocTool";
|
||||
private static final String systemDocumentationToolModule = "jdk.javadoc";
|
||||
private static final String systemDocumentationToolName = "jdk.javadoc.internal.api.JavadocTool";
|
||||
|
||||
/**
|
||||
* Returns the Java™ programming language documentation tool provided
|
||||
@ -69,9 +74,13 @@ public class ToolProvider {
|
||||
* {@linkplain java.nio.file.FileSystem filesystem}.</p>
|
||||
* @return the documentation tool provided with this platform or
|
||||
* {@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() {
|
||||
return instance().getSystemTool(DocumentationTool.class, systemDocumentationToolName);
|
||||
return getSystemTool(DocumentationTool.class,
|
||||
systemDocumentationToolModule, systemDocumentationToolName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,41 +96,70 @@ public class ToolProvider {
|
||||
return ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
|
||||
private static final boolean useLegacy;
|
||||
|
||||
private static ToolProvider instance;
|
||||
|
||||
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);
|
||||
static {
|
||||
Class<?> c = null;
|
||||
try {
|
||||
return c.asSubclass(clazz).newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException | RuntimeException | Error e) {
|
||||
throw new Error(e);
|
||||
c = Class.forName("java.lang.reflect.Module");
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
useLegacy = (c == null);
|
||||
}
|
||||
|
||||
private <T> Class<? extends T> getSystemToolClass(Class<T> clazz, String name) {
|
||||
Reference<Class<?>> refClass = toolClasses.get(name);
|
||||
Class<?> c = (refClass == null ? null : refClass.get());
|
||||
if (c == null) {
|
||||
/**
|
||||
* Get an instance of a system tool using the service loader.
|
||||
* @implNote By default, this returns the implementation in the specified module.
|
||||
* 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 {
|
||||
c = Class.forName(name, false, ClassLoader.getSystemClassLoader());
|
||||
} catch (ClassNotFoundException | RuntimeException | Error e) {
|
||||
return Class.forName(className, true, ClassLoader.getSystemClassLoader()).asSubclass(clazz).newInstance();
|
||||
} catch (ReflectiveOperationException 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -21,31 +23,15 @@
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @deprecated Class1Pkg2. This class is deprecated
|
||||
*
|
||||
* @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";
|
||||
uses javax.tools.DocumentationTool;
|
||||
uses javax.tools.JavaCompiler;
|
||||
}
|
||||
|
@ -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 { }
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -603,6 +603,35 @@ public interface Tree {
|
||||
*/
|
||||
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
|
||||
* you are looking for.
|
||||
|
@ -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.
|
||||
*
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* This can occur if the language evolves and new kinds
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -21,28 +24,22 @@
|
||||
* 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.
|
||||
*
|
||||
* @param a blah.
|
||||
* @param b blah.
|
||||
* Returns the name of the service type.
|
||||
* @return the name of the service type
|
||||
*/
|
||||
void method1(int a, int b);
|
||||
|
||||
/**
|
||||
* Another test method.
|
||||
*
|
||||
* @param c blah.
|
||||
*/
|
||||
void method2(int c);
|
||||
|
||||
ExpressionTree getServiceName();
|
||||
}
|
@ -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.
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} This implementation calls {@code defaultAction}.
|
||||
*
|
||||
* @param node {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of {@code defaultAction}
|
||||
*/
|
||||
public R visitModule(ModuleTree node, P p) {
|
||||
return defaultAction(node, p);
|
||||
}
|
||||
|
||||
@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) {
|
||||
return defaultAction(node, p);
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
||||
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}.
|
||||
*
|
||||
|
@ -195,6 +195,9 @@ public class DocLint implements Plugin {
|
||||
} else {
|
||||
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)) {
|
||||
env.messages.setStatsEnabled(true);
|
||||
} else if (arg.equals("-bootclasspath") && i + 1 < args.length) {
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.LinkedHashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
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.Log;
|
||||
import com.sun.tools.javac.util.PropagatedException;
|
||||
import com.sun.tools.javac.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* Provides basic functionality for implementations of JavacTask.
|
||||
@ -195,8 +195,7 @@ public class BasicJavacTask extends JavacTask {
|
||||
|
||||
Set<List<String>> pluginsToCall = new LinkedHashSet<>(pluginOpts);
|
||||
JavacProcessingEnvironment pEnv = JavacProcessingEnvironment.instance(context);
|
||||
ClassLoader cl = pEnv.getProcessorClassLoader();
|
||||
ServiceLoader<Plugin> sl = ServiceLoader.load(Plugin.class, cl);
|
||||
ServiceLoader<Plugin> sl = pEnv.getServiceLoader(Plugin.class);
|
||||
for (Plugin plugin : sl) {
|
||||
for (List<String> p : pluginsToCall) {
|
||||
if (plugin.getName().equals(p.head)) {
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.Target;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
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)
|
||||
public int isSupportedOption(String option) {
|
||||
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)
|
||||
public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
|
||||
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)
|
||||
public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
|
||||
try {
|
||||
@ -414,9 +481,20 @@ public class ClientCodeWrapper {
|
||||
}
|
||||
|
||||
@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 {
|
||||
((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) {
|
||||
throw e;
|
||||
} catch (RuntimeException | Error e) {
|
||||
@ -434,6 +512,28 @@ public class ClientCodeWrapper {
|
||||
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 {
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
import javax.tools.*;
|
||||
import javax.tools.JavaFileObject.Kind;
|
||||
|
||||
import com.sun.source.tree.*;
|
||||
import com.sun.tools.javac.code.*;
|
||||
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.file.BaseFileManager;
|
||||
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.JCTree.JCClassDecl;
|
||||
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.DefinedBy.Api;
|
||||
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
|
||||
* classes in the abstract syntax trees
|
||||
*/
|
||||
public Iterable<? extends TypeElement> enter() {
|
||||
public Iterable<? extends Element> enter() {
|
||||
return enter(null);
|
||||
}
|
||||
|
||||
@ -264,11 +271,13 @@ public class JavacTaskImpl extends BasicJavacTask {
|
||||
* @return a list of elements corresponding to the top level
|
||||
* 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())
|
||||
return List.nil();
|
||||
|
||||
boolean wasInitialized = compiler != null;
|
||||
|
||||
prepareCompiler(true);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
List<JCCompilationUnit> units = compiler.initModules(roots.toList());
|
||||
|
||||
try {
|
||||
List<JCCompilationUnit> units = compiler.enterTrees(roots.toList());
|
||||
units = compiler.enterTrees(units);
|
||||
|
||||
if (notYetEntered.isEmpty())
|
||||
compiler.processAnnotations(units);
|
||||
|
||||
ListBuffer<TypeElement> elements = new ListBuffer<>();
|
||||
ListBuffer<Element> elements = new ListBuffer<>();
|
||||
for (JCCompilationUnit unit : units) {
|
||||
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);
|
||||
boolean isPkgInfo = unit.sourcefile.isNameCompatible("package-info",
|
||||
JavaFileObject.Kind.SOURCE);
|
||||
if (isPkgInfo) {
|
||||
elements.append(unit.packge);
|
||||
} 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.
|
||||
// An alternative implementation would be to move this code to JavaCompiler and
|
||||
// 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
|
||||
|
||||
final ListBuffer<Element> results = new ListBuffer<>();
|
||||
@ -383,8 +408,13 @@ public class JavacTaskImpl extends BasicJavacTask {
|
||||
if (cdef.sym != null)
|
||||
elems.append(cdef.sym);
|
||||
break;
|
||||
case TOPLEVEL:
|
||||
JCCompilationUnit unit = (JCCompilationUnit) env.tree;
|
||||
case MODULEDEF:
|
||||
JCModuleDecl mod = (JCModuleDecl) env.tree;
|
||||
if (mod.sym != null)
|
||||
elems.append(mod.sym);
|
||||
break;
|
||||
case PACKAGEDEF:
|
||||
JCCompilationUnit unit = env.toplevel;
|
||||
if (unit.packge != null)
|
||||
elems.append(unit.packge);
|
||||
break;
|
||||
@ -413,7 +443,7 @@ public class JavacTaskImpl extends BasicJavacTask {
|
||||
* @param classes a list of class elements
|
||||
* @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<>();
|
||||
try {
|
||||
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();
|
||||
}
|
||||
|
||||
public void ensureEntered() {
|
||||
args.allowEmpty();
|
||||
enter(null);
|
||||
}
|
||||
|
||||
abstract class Filter {
|
||||
void run(Queue<Env<AttrContext>> list, Iterable<? extends TypeElement> classes) {
|
||||
Set<TypeElement> set = new HashSet<>();
|
||||
for (TypeElement item: classes)
|
||||
void run(Queue<Env<AttrContext>> list, Iterable<? extends Element> elements) {
|
||||
Set<Element> set = new HashSet<>();
|
||||
for (Element item: elements) {
|
||||
set.add(item);
|
||||
}
|
||||
|
||||
ListBuffer<Env<AttrContext>> defer = new ListBuffer<>();
|
||||
while (list.peek() != null) {
|
||||
Env<AttrContext> env = list.remove();
|
||||
ClassSymbol csym = env.enclClass.sym;
|
||||
if (csym != null && set.contains(csym.outermostClass()))
|
||||
Symbol test = null;
|
||||
|
||||
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);
|
||||
else
|
||||
defer = defer.append(env);
|
||||
|
@ -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.
|
||||
*
|
||||
* 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) {
|
||||
for (String cls : classes)
|
||||
if (!SourceVersion.isName(cls)) // implicit null check
|
||||
for (String cls : classes) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (compilationUnits != null) {
|
||||
|
@ -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.ClassSymbol;
|
||||
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.TypeSymbol;
|
||||
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.Env;
|
||||
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.file.BaseFileManager;
|
||||
import com.sun.tools.javac.model.JavacElements;
|
||||
@ -156,6 +158,7 @@ import static com.sun.tools.javac.code.TypeTag.*;
|
||||
public class JavacTrees extends DocTrees {
|
||||
|
||||
// in a world of a single context per compilation, these would all be final
|
||||
private Modules modules;
|
||||
private Resolve resolve;
|
||||
private Enter enter;
|
||||
private Log log;
|
||||
@ -206,6 +209,7 @@ public class JavacTrees extends DocTrees {
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
modules = Modules.instance(context);
|
||||
attr = Attr.instance(context);
|
||||
enter = Enter.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.
|
||||
Type t = attr.attribType(ref.qualifierExpression, env);
|
||||
if (t.isErroneous()) {
|
||||
if (ref.memberName == null) {
|
||||
// Attr/Resolve assume packages exist and create symbols as needed
|
||||
// so use getPackageElement to restrict search to existing packages
|
||||
PackageSymbol pck = elements.getPackageElement(ref.qualifierExpression.toString());
|
||||
if (pck != null) {
|
||||
return pck;
|
||||
} else if (ref.qualifierExpression.hasTag(JCTree.Tag.IDENT)) {
|
||||
JCCompilationUnit toplevel =
|
||||
treeMaker.TopLevel(List.<JCTree>nil());
|
||||
final ModuleSymbol msym = modules.getDefaultModule();
|
||||
toplevel.modle = msym;
|
||||
toplevel.packge = msym.unnamedPackage;
|
||||
Symbol sym = attr.attribIdent(ref.qualifierExpression, toplevel);
|
||||
|
||||
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"
|
||||
// for compatibility with javadoc
|
||||
tsym = env.enclClass.sym;
|
||||
memberName = ((JCIdent) ref.qualifierExpression).name;
|
||||
} else
|
||||
} else {
|
||||
return null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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() {
|
||||
@Override
|
||||
@ -1209,13 +1224,12 @@ public class JavacTrees extends DocTrees {
|
||||
|
||||
};
|
||||
jcCompilationUnit.lineMap = jcCompilationUnit.getLineMap();
|
||||
jcCompilationUnit.modle = psym.modle;
|
||||
jcCompilationUnit.sourcefile = jfo;
|
||||
jcCompilationUnit.namedImportScope = new NamedImportScope(psym, jcCompilationUnit.toplevelScope);
|
||||
jcCompilationUnit.packge = psym;
|
||||
jcCompilationUnit.starImportScope = null;
|
||||
jcCompilationUnit.sourcefile = jfo;
|
||||
jcCompilationUnit.starImportScope = new StarImportScope(psym);
|
||||
jcCompilationUnit.toplevelScope = WriteableScope.create(psym);
|
||||
|
||||
return new TreePath(jcCompilationUnit);
|
||||
}
|
||||
}
|
||||
|
@ -37,11 +37,13 @@ import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileManager.Location;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import com.sun.tools.javac.code.Scope.WriteableScope;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.Completer;
|
||||
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.TypeSymbol;
|
||||
import com.sun.tools.javac.comp.Annotate;
|
||||
@ -118,6 +120,10 @@ public class ClassFinder {
|
||||
*/
|
||||
final Name completionFailureName;
|
||||
|
||||
/** Module specified with -Xmodule:
|
||||
*/
|
||||
final Name moduleOverride;
|
||||
|
||||
/** Access to files
|
||||
*/
|
||||
private final JavaFileManager fileManager;
|
||||
@ -178,7 +184,7 @@ public class ClassFinder {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/** Construct a new class reader. */
|
||||
/** Construct a new class finder. */
|
||||
protected ClassFinder(Context context) {
|
||||
context.put(classFinderKey, this);
|
||||
reader = ClassReader.instance(context);
|
||||
@ -205,6 +211,9 @@ public class ClassFinder {
|
||||
? names.fromString(options.get("failcomplete"))
|
||||
: null;
|
||||
|
||||
moduleOverride = options.isSet(XMODULE) ? names.fromString(options.get(XMODULE))
|
||||
: null;
|
||||
|
||||
// Temporary, until more info is available from the module system.
|
||||
boolean useCtProps;
|
||||
JavaFileManager fm = context.get(JavaFileManager.class);
|
||||
@ -237,7 +246,7 @@ public class ClassFinder {
|
||||
* available from the module system.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@ -318,7 +327,7 @@ public class ClassFinder {
|
||||
for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) {
|
||||
Symbol encl = owner.members().findFirst(name);
|
||||
if (encl == null)
|
||||
encl = syms.classes.get(TypeSymbol.formFlatName(name, owner));
|
||||
encl = syms.getClass(c.packge().modle, TypeSymbol.formFlatName(name, owner));
|
||||
if (encl != null)
|
||||
encl.complete();
|
||||
}
|
||||
@ -328,7 +337,7 @@ public class ClassFinder {
|
||||
/** Fill in definition of class `c' from corresponding class or
|
||||
* source file.
|
||||
*/
|
||||
private void fillIn(ClassSymbol c) {
|
||||
void fillIn(ClassSymbol c) {
|
||||
if (completionFailureName == c.fullname) {
|
||||
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
|
||||
* The class is entered into `classes' only if load was successful.
|
||||
*/
|
||||
public ClassSymbol loadClass(Name flatname) throws CompletionFailure {
|
||||
boolean absent = syms.classes.get(flatname) == null;
|
||||
ClassSymbol c = syms.enterClass(flatname);
|
||||
public ClassSymbol loadClass(ModuleSymbol msym, Name flatname) throws CompletionFailure {
|
||||
Assert.checkNonNull(msym);
|
||||
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) {
|
||||
try {
|
||||
c.complete();
|
||||
} catch (CompletionFailure ex) {
|
||||
if (absent) syms.classes.remove(flatname);
|
||||
if (absent) syms.removeClass(ps.modle, flatname);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
@ -438,7 +454,7 @@ public class ClassFinder {
|
||||
? p.package_info
|
||||
: (ClassSymbol) p.members_field.findFirst(classname);
|
||||
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
|
||||
c.classfile = file;
|
||||
if (isPkgInfo) {
|
||||
@ -479,6 +495,7 @@ public class ClassFinder {
|
||||
/**
|
||||
* specifies types of files to be read when filling in a package symbol
|
||||
*/
|
||||
// Note: overridden by JavadocClassFinder
|
||||
protected EnumSet<JavaFileObject.Kind> getPackageFileKinds() {
|
||||
return EnumSet.of(JavaFileObject.Kind.CLASS, JavaFileObject.Kind.SOURCE);
|
||||
}
|
||||
@ -502,16 +519,83 @@ public class ClassFinder {
|
||||
if (p.members_field == null)
|
||||
p.members_field = WriteableScope.create(p);
|
||||
|
||||
preferCurrent = false;
|
||||
if (userPathsFirst) {
|
||||
ModuleSymbol msym = p.modle;
|
||||
|
||||
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);
|
||||
preferCurrent = true;
|
||||
scanPlatformPath(p);
|
||||
} else {
|
||||
scanPlatformPath(p);
|
||||
scanUserPaths(p);
|
||||
scanModulePaths(p, msym);
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -107,6 +107,7 @@ public class Flags {
|
||||
public static final int ACC_SUPER = 0x0020;
|
||||
public static final int ACC_BRIDGE = 0x0040;
|
||||
public static final int ACC_VARARGS = 0x0080;
|
||||
public static final int ACC_MODULE = 0x8000;
|
||||
|
||||
/*****************************************
|
||||
* Internal compiler flags (no bits in the lower 16).
|
||||
@ -277,6 +278,21 @@ public class Flags {
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
public static final int
|
||||
@ -385,7 +401,8 @@ public class Flags {
|
||||
SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC),
|
||||
THROWS(Flags.THROWS),
|
||||
LAMBDA_METHOD(Flags.LAMBDA_METHOD),
|
||||
TYPE_TRANSLATED(Flags.TYPE_TRANSLATED);
|
||||
TYPE_TRANSLATED(Flags.TYPE_TRANSLATED),
|
||||
MODULE(Flags.MODULE);
|
||||
|
||||
Flag(long flag) {
|
||||
this.value = flag;
|
||||
|
@ -65,6 +65,7 @@ public class Kinds {
|
||||
VAR(Category.BASIC, KindName.VAR, KindSelector.VAR),
|
||||
MTH(Category.BASIC, KindName.METHOD, KindSelector.MTH),
|
||||
POLY(Category.BASIC, KindSelector.POLY),
|
||||
MDL(Category.BASIC, KindSelector.MDL),
|
||||
ERR(Category.ERROR, KindSelector.ERR),
|
||||
AMBIGUOUS(Category.RESOLUTION_TARGET), // overloaded 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 VAL = new KindSelector(0x0c);
|
||||
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 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
|
||||
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 & TYP.data) != 0) kinds.add(KindName.CLASS);
|
||||
if ((data & PCK.data) != 0) kinds.add(KindName.PACKAGE);
|
||||
if ((data & MDL.data) != 0) kinds.add(KindName.MODULE);
|
||||
return kinds;
|
||||
}
|
||||
}
|
||||
@ -230,7 +233,8 @@ public class Kinds {
|
||||
CLASS("kindname.class"),
|
||||
STATIC_INIT("kindname.static.init"),
|
||||
INSTANCE_INIT("kindname.instance.init"),
|
||||
PACKAGE("kindname.package");
|
||||
PACKAGE("kindname.package"),
|
||||
MODULE("kindname.module");
|
||||
|
||||
private final String name;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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.
|
||||
*
|
||||
* 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))
|
||||
return printAnnotations(t) +
|
||||
localize(locale, "compiler.misc.type.captureof.1",
|
||||
capturedVarId(t, locale));
|
||||
capturedVarId(t, locale));
|
||||
else {
|
||||
try {
|
||||
seenCaptured = seenCaptured.prepend(t);
|
||||
return printAnnotations(t) +
|
||||
localize(locale, "compiler.misc.type.captureof",
|
||||
capturedVarId(t, locale),
|
||||
visit(t.wildcard, locale));
|
||||
capturedVarId(t, locale),
|
||||
visit(t.wildcard, locale));
|
||||
}
|
||||
finally {
|
||||
seenCaptured = seenCaptured.tail;
|
||||
@ -274,6 +274,11 @@ public abstract class Printer implements Type.Visitor<String, Locale>, Symbol.Vi
|
||||
return visitType(t, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitModuleType(ModuleType t, Locale locale) {
|
||||
return visitType(t, locale);
|
||||
}
|
||||
|
||||
public String visitType(Type t, Locale locale) {
|
||||
String s = (t.tsym == null || t.tsym.name == null)
|
||||
? localize(locale, "compiler.misc.type.none")
|
||||
|
@ -137,6 +137,9 @@ public enum Source {
|
||||
public boolean allowImprovedCatchAnalysis() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
public boolean allowModules() {
|
||||
return compareTo(JDK1_9) >= 0;
|
||||
}
|
||||
public boolean allowTryWithResources() {
|
||||
return compareTo(JDK1_7) >= 0;
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.Inherited;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
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 com.sun.tools.javac.code.Attribute.Compound;
|
||||
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.code.Kinds.Kind;
|
||||
import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
|
||||
import com.sun.tools.javac.code.Scope.WriteableScope;
|
||||
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.DefinedBy.Api;
|
||||
import com.sun.tools.javac.util.Name;
|
||||
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.code.Kinds.*;
|
||||
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) {
|
||||
return (anno.position.type == TargetType.CLASS_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);
|
||||
}
|
||||
}
|
||||
/** 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
|
||||
*/
|
||||
@ -861,6 +988,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
|
||||
public WriteableScope members_field;
|
||||
public Name fullname;
|
||||
public ClassSymbol package_info; // see bug 6443073
|
||||
public ModuleSymbol modle;
|
||||
|
||||
public PackageSymbol(Name name, Type type, Symbol owner) {
|
||||
super(PCK, 0, name, type, owner);
|
||||
@ -929,7 +1057,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
|
||||
|
||||
@DefinedBy(Api.LANGUAGE_MODEL)
|
||||
public Symbol getEnclosingElement() {
|
||||
return null;
|
||||
return modle != null && !modle.isNoModule() ? modle : null;
|
||||
}
|
||||
|
||||
@DefinedBy(Api.LANGUAGE_MODEL)
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,18 +25,20 @@
|
||||
|
||||
package com.sun.tools.javac.code;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.lang.model.element.ElementVisitor;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
|
||||
import com.sun.tools.javac.code.Scope.WriteableScope;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.Completer;
|
||||
import com.sun.tools.javac.code.Symbol.CompletionFailure;
|
||||
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.TypeSymbol;
|
||||
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.MethodType;
|
||||
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.Context;
|
||||
import com.sun.tools.javac.util.Convert;
|
||||
import com.sun.tools.javac.util.DefinedBy;
|
||||
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.List;
|
||||
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.Options;
|
||||
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.code.Kinds.Kind.*;
|
||||
@ -100,17 +103,26 @@ public class Symtab {
|
||||
public final JCVoidType voidType = new JCVoidType();
|
||||
|
||||
private final Names names;
|
||||
private final JavacMessages messages;
|
||||
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.
|
||||
*/
|
||||
public final PackageSymbol rootPackage;
|
||||
|
||||
/** A symbol for the unnamed package.
|
||||
*/
|
||||
public final PackageSymbol unnamedPackage;
|
||||
|
||||
/** A symbol that stands for a missing symbol.
|
||||
*/
|
||||
public final TypeSymbol noSymbol;
|
||||
@ -139,6 +151,10 @@ public class Symtab {
|
||||
/** The builtin type of all methods. */
|
||||
public final ClassSymbol methodClass;
|
||||
|
||||
/** A symbol for the java.base module.
|
||||
*/
|
||||
public final ModuleSymbol java_base;
|
||||
|
||||
/** Predefined types.
|
||||
*/
|
||||
public final Type objectType;
|
||||
@ -208,7 +224,7 @@ public class Symtab {
|
||||
*/
|
||||
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()];
|
||||
|
||||
@ -217,13 +233,17 @@ public class Symtab {
|
||||
* It should be updated from the outside to reflect classes defined
|
||||
* 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.
|
||||
* the table should be updated from outside to reflect packages defined
|
||||
* 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) {
|
||||
type.tsym = c;
|
||||
@ -239,7 +259,7 @@ public class Symtab {
|
||||
|
||||
public void initType(Type type, String name, String bname) {
|
||||
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.
|
||||
@ -250,12 +270,13 @@ public class Symtab {
|
||||
* @param s The name of the class.
|
||||
*/
|
||||
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) {
|
||||
final Completer completer = type.tsym.completer;
|
||||
type.tsym.completer = new Completer() {
|
||||
@Override
|
||||
public void complete(Symbol sym) throws CompletionFailure {
|
||||
try {
|
||||
completer.complete(sym);
|
||||
@ -273,9 +294,10 @@ public class Symtab {
|
||||
}
|
||||
|
||||
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;
|
||||
sym.completer = new Completer() {
|
||||
@Override
|
||||
public void complete(Symbol sym) throws CompletionFailure {
|
||||
try {
|
||||
completer.complete(sym);
|
||||
@ -308,7 +330,9 @@ public class Symtab {
|
||||
// Enter a synthetic class that is used to mark classes in ct.sym.
|
||||
// This class does not have a class file.
|
||||
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;
|
||||
sym.completer = Completer.NULL_COMPLETER;
|
||||
sym.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE;
|
||||
@ -328,22 +352,35 @@ public class Symtab {
|
||||
context.put(symtabKey, this);
|
||||
|
||||
names = Names.instance(context);
|
||||
target = Target.instance(context);
|
||||
|
||||
// Create the unknown type
|
||||
unknownType = new UnknownType();
|
||||
|
||||
// create the basic builtin symbols
|
||||
messages = JavacMessages.instance(context);
|
||||
|
||||
rootPackage = new PackageSymbol(names.empty, null);
|
||||
packages.put(names.empty, rootPackage);
|
||||
final JavacMessages messages = JavacMessages.instance(context);
|
||||
unnamedPackage = new PackageSymbol(names.empty, rootPackage) {
|
||||
|
||||
// create the basic builtin symbols
|
||||
unnamedModule = new ModuleSymbol(names.empty, null) {
|
||||
@Override
|
||||
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) {
|
||||
@DefinedBy(Api.LANGUAGE_MODEL)
|
||||
@Override @DefinedBy(Api.LANGUAGE_MODEL)
|
||||
public <R, P> R accept(ElementVisitor<R, P> v, P p) {
|
||||
return v.visitUnknown(this, p);
|
||||
}
|
||||
@ -389,8 +426,7 @@ public class Symtab {
|
||||
|
||||
// Get the initial completer for Symbols from the ClassFinder
|
||||
initialCompleter = ClassFinder.instance(context).getCompleter();
|
||||
rootPackage.completer = initialCompleter;
|
||||
unnamedPackage.completer = initialCompleter;
|
||||
rootPackage.members_field = WriteableScope.create(rootPackage);
|
||||
|
||||
// Enter symbols for basic types.
|
||||
scope.enter(byteType.tsym);
|
||||
@ -406,9 +442,22 @@ public class Symtab {
|
||||
// Enter symbol for the 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");
|
||||
objectsType = enterClass("java.util.Objects");
|
||||
classType = enterClass("java.lang.Class");
|
||||
@ -434,7 +483,7 @@ public class Symtab {
|
||||
cloneNotSupportedExceptionType = enterClass("java.lang.CloneNotSupportedException");
|
||||
annotationType = enterClass("java.lang.annotation.Annotation");
|
||||
classLoaderType = enterClass("java.lang.ClassLoader");
|
||||
enumSym = enterClass(names.java_lang_Enum);
|
||||
enumSym = enterClass(java_base, names.java_lang_Enum);
|
||||
enumFinalFinalize =
|
||||
new MethodSymbol(PROTECTED|FINAL|HYPOTHETICAL,
|
||||
names.finalize,
|
||||
@ -512,14 +561,16 @@ public class Symtab {
|
||||
List.<Type>nil(), methodClass),
|
||||
arrayClass);
|
||||
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.
|
||||
*/
|
||||
public ClassSymbol defineClass(Name name, Symbol owner) {
|
||||
ClassSymbol c = new ClassSymbol(0, name, owner);
|
||||
if (owner.kind == PCK)
|
||||
Assert.checkNull(classes.get(c.flatname), c);
|
||||
c.completer = initialCompleter;
|
||||
return c;
|
||||
}
|
||||
@ -527,12 +578,13 @@ public class Symtab {
|
||||
/** Create a new toplevel or member class symbol with given name
|
||||
* 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);
|
||||
ClassSymbol c = classes.get(flatname);
|
||||
ClassSymbol c = getClass(msym, flatname);
|
||||
if (c == null) {
|
||||
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) {
|
||||
// reassign fields of classes that might have been loaded with
|
||||
// their flat names.
|
||||
@ -544,71 +596,212 @@ public class Symtab {
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new toplevel class symbol with given flat name and
|
||||
* given class (or source) file.
|
||||
*
|
||||
* @param flatName a fully qualified binary class name
|
||||
* @param classFile the class file or compilation unit defining
|
||||
* the class (may be {@code null})
|
||||
* @return a newly created class symbol
|
||||
* @throws AssertionError if the class symbol already exists
|
||||
*/
|
||||
public ClassSymbol enterClass(Name flatName, JavaFileObject classFile) {
|
||||
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);
|
||||
public ClassSymbol getClass(ModuleSymbol msym, Name flatName) {
|
||||
Assert.checkNonNull(msym, () -> flatName.toString());
|
||||
return classes.getOrDefault(flatName, Collections.emptyMap()).get(msym);
|
||||
}
|
||||
|
||||
public PackageSymbol lookupPackage(ModuleSymbol msym, Name flatName) {
|
||||
Assert.checkNonNull(msym);
|
||||
|
||||
if (flatName.isEmpty()) {
|
||||
//unnamed packages only from the current module - visiblePackages contains *root* package, not unnamed package!
|
||||
return msym.unnamedPackage;
|
||||
}
|
||||
Name packageName = Convert.packagePart(flatName);
|
||||
PackageSymbol owner = packageName.isEmpty()
|
||||
? unnamedPackage
|
||||
: enterPackage(packageName);
|
||||
cs = defineClass(Convert.shortName(flatName), owner);
|
||||
cs.classfile = classFile;
|
||||
classes.put(flatName, cs);
|
||||
return cs;
|
||||
|
||||
if (msym == noModule) {
|
||||
return enterPackage(msym, flatName);
|
||||
}
|
||||
|
||||
msym.complete();
|
||||
|
||||
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
|
||||
* and enter in `classes' unless already there.
|
||||
*/
|
||||
public ClassSymbol enterClass(Name flatname) {
|
||||
ClassSymbol c = classes.get(flatname);
|
||||
if (c == null)
|
||||
return enterClass(flatname, (JavaFileObject)null);
|
||||
else
|
||||
public ClassSymbol enterClass(ModuleSymbol msym, Name flatname) {
|
||||
Assert.checkNonNull(msym);
|
||||
PackageSymbol ps = lookupPackage(msym, Convert.packagePart(flatname));
|
||||
Assert.checkNonNull(ps);
|
||||
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;
|
||||
}
|
||||
|
||||
/** Check to see if a package exists, given its fully qualified name.
|
||||
*/
|
||||
public boolean packageExists(Name fullname) {
|
||||
return enterPackage(fullname).exists();
|
||||
public boolean packageExists(ModuleSymbol msym, Name fullname) {
|
||||
Assert.checkNonNull(msym);
|
||||
return enterPackage(msym, fullname).exists();
|
||||
}
|
||||
|
||||
/** Make a package, given its fully qualified name.
|
||||
*/
|
||||
public PackageSymbol enterPackage(Name fullname) {
|
||||
PackageSymbol p = packages.get(fullname);
|
||||
public PackageSymbol enterPackage(ModuleSymbol currModule, Name fullname) {
|
||||
Assert.checkNonNull(currModule);
|
||||
PackageSymbol p = getPackage(currModule, fullname);
|
||||
if (p == null) {
|
||||
Assert.check(!fullname.isEmpty(), "rootPackage missing!");
|
||||
Assert.check(!fullname.isEmpty(), () -> "rootPackage missing!; currModule: " + currModule);
|
||||
p = new PackageSymbol(
|
||||
Convert.shortName(fullname),
|
||||
enterPackage(Convert.packagePart(fullname)));
|
||||
Convert.shortName(fullname),
|
||||
enterPackage(currModule, Convert.packagePart(fullname)));
|
||||
p.completer = initialCompleter;
|
||||
packages.put(fullname, p);
|
||||
p.modle = currModule;
|
||||
doEnterPackage(currModule, p);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/** Make a package, given its unqualified name and enclosing package.
|
||||
*/
|
||||
public PackageSymbol enterPackage(Name name, PackageSymbol owner) {
|
||||
return enterPackage(TypeSymbol.formFullName(name, owner));
|
||||
private void doEnterPackage(ModuleSymbol msym, PackageSymbol pack) {
|
||||
packages.computeIfAbsent(pack.fullname, n -> new HashMap<>()).put(msym, pack);
|
||||
msym.enclosedPackages = msym.enclosedPackages.prepend(pack);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -1525,7 +1525,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
|
||||
|
||||
public static class PackageType extends Type implements NoType {
|
||||
|
||||
PackageType(TypeSymbol tsym) {
|
||||
PackageType(PackageSymbol tsym) {
|
||||
// Package types cannot be annotated
|
||||
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 {
|
||||
|
||||
/** 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 visitMethodType(MethodType t, S s);
|
||||
R visitPackageType(PackageType t, S s);
|
||||
R visitModuleType(ModuleType t, S s);
|
||||
R visitTypeVar(TypeVar t, S s);
|
||||
R visitCapturedType(CapturedType t, S s);
|
||||
R visitForAll(ForAll t, S s);
|
||||
|
@ -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.Symbol.VarSymbol;
|
||||
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.comp.Annotate;
|
||||
import com.sun.tools.javac.comp.Attr;
|
||||
@ -651,6 +652,11 @@ public class TypeAnnotations {
|
||||
return t.annotatedType(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type visitModuleType(ModuleType t, List<TypeCompound> s) {
|
||||
return t.annotatedType(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type visitCapturedType(CapturedType t, List<TypeCompound> s) {
|
||||
return t.annotatedType(s);
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -89,6 +89,10 @@ public enum TypeTag {
|
||||
*/
|
||||
PACKAGE,
|
||||
|
||||
/** The tag of all module "types".
|
||||
*/
|
||||
MODULE,
|
||||
|
||||
/** The tag of all (source-level) type variables.
|
||||
*/
|
||||
TYPEVAR,
|
||||
|
@ -3938,7 +3938,7 @@ public class Types {
|
||||
* Return the class that boxes the given primitive.
|
||||
*/
|
||||
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++) {
|
||||
Name box = syms.boxedName[i];
|
||||
if (box != null &&
|
||||
asSuper(t, syms.enterClass(box)) != null)
|
||||
asSuper(t, syms.enterClass(syms.java_base, box)) != null)
|
||||
return syms.typeOfTag[i];
|
||||
}
|
||||
return Type.noType;
|
||||
@ -4536,6 +4536,7 @@ public class Types {
|
||||
public R visitArrayType(ArrayType 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 visitModuleType(ModuleType 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 visitForAll(ForAll t, S s) { return visitType(t, s); }
|
||||
|
@ -36,6 +36,7 @@ import com.sun.source.tree.MemberSelectTree;
|
||||
import com.sun.source.tree.TreeVisitor;
|
||||
import com.sun.source.util.SimpleTreeVisitor;
|
||||
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.Scope.WriteableScope;
|
||||
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.Fragment;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
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.BLOCK;
|
||||
@ -332,7 +334,15 @@ public class Attr extends JCTree.Visitor {
|
||||
syms.errSymbol.name,
|
||||
null, null, null, null);
|
||||
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
|
||||
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) {
|
||||
if (env.tree.hasTag(TOPLEVEL))
|
||||
attribTopLevel(env);
|
||||
else
|
||||
attribClass(env.tree.pos(), env.enclClass.sym);
|
||||
switch (env.tree.getTag()) {
|
||||
case MODULEDEF:
|
||||
attribModule(env.tree.pos(), ((JCModuleDecl)env.tree).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.
|
||||
* reporting completion failures at the given position.
|
||||
* @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
|
||||
}
|
||||
|
||||
public void visitModuleDef(JCModuleDecl tree) {
|
||||
tree.sym.completeUsesProvides();
|
||||
}
|
||||
|
||||
/** Finish the attribution of a class. */
|
||||
private void attribClassBody(Env<AttrContext> env, ClassSymbol c) {
|
||||
JCClassDecl tree = (JCClassDecl)env.tree;
|
||||
@ -4929,4 +4964,22 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
// </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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -173,10 +173,10 @@ public class Check {
|
||||
*/
|
||||
char syntheticNameChar;
|
||||
|
||||
/** A table mapping flat names of all compiled classes in this run to their
|
||||
* symbols; maintained from outside.
|
||||
/** A table mapping flat names of all compiled classes for each module in this run
|
||||
* 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.
|
||||
*/
|
||||
@ -404,7 +404,7 @@ public class Check {
|
||||
for (int i = (index == null) ? 1 : index; ; i++) {
|
||||
Name flatname = names.fromString(enclFlatnameStr
|
||||
+ syntheticNameChar + i + c.name);
|
||||
if (compiled.get(flatname) == null) {
|
||||
if (getCompiled(c.packge().modle, flatname) == null) {
|
||||
localClassNameIndexes.put(key, i + 1);
|
||||
return flatname;
|
||||
}
|
||||
@ -421,6 +421,22 @@ public class Check {
|
||||
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
|
||||
**************************************************************************/
|
||||
@ -3473,7 +3489,7 @@ public class Check {
|
||||
private boolean isCanonical(JCTree tree) {
|
||||
while (tree.hasTag(SELECT)) {
|
||||
JCFieldAccess s = (JCFieldAccess) tree;
|
||||
if (s.sym.owner != TreeInfo.symbol(s.selected))
|
||||
if (s.sym.owner.name != TreeInfo.symbol(s.selected).name)
|
||||
return false;
|
||||
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)
|
||||
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) {
|
||||
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()) {
|
||||
log.error(DiagnosticFlag.RESOLVE_ERROR, imp.pos, "doesnt.exist", tsym);
|
||||
}
|
||||
|
@ -452,17 +452,21 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
Log.DeferredDiagnosticHandler deferredDiagnosticHandler = diagHandlerCreator.apply(newTree);
|
||||
try {
|
||||
attr.attribTree(newTree, speculativeEnv, resultInfo);
|
||||
unenterScanner.scan(newTree);
|
||||
return newTree;
|
||||
} finally {
|
||||
unenterScanner.scan(newTree);
|
||||
new UnenterScanner(env.toplevel.modle).scan(newTree);
|
||||
log.popDiagnosticHandler(deferredDiagnosticHandler);
|
||||
}
|
||||
}
|
||||
//where
|
||||
protected UnenterScanner unenterScanner = new UnenterScanner();
|
||||
|
||||
class UnenterScanner extends TreeScanner {
|
||||
private final ModuleSymbol msym;
|
||||
|
||||
public UnenterScanner(ModuleSymbol msym) {
|
||||
this.msym = msym;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitClassDef(JCClassDecl tree) {
|
||||
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.
|
||||
if (csym == null) return;
|
||||
typeEnvs.remove(csym);
|
||||
chk.compiled.remove(csym.flatname);
|
||||
chk.removeCompiled(csym);
|
||||
chk.clearLocalClassNameIndexes(csym);
|
||||
syms.classes.remove(csym.flatname);
|
||||
syms.removeClass(msym, csym.flatname);
|
||||
super.visitClassDef(tree);
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,9 @@
|
||||
|
||||
package com.sun.tools.javac.comp;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
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.Type.*;
|
||||
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.JCTree.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.code.Kinds.Kind.*;
|
||||
|
||||
@ -97,6 +100,8 @@ public class Enter extends JCTree.Visitor {
|
||||
JavaFileManager fileManager;
|
||||
PkgInfo pkginfoOpt;
|
||||
TypeEnvs typeEnvs;
|
||||
Modules modules;
|
||||
JCDiagnostic.Factory diags;
|
||||
|
||||
private final Todo todo;
|
||||
|
||||
@ -119,6 +124,8 @@ public class Enter extends JCTree.Visitor {
|
||||
annotate = Annotate.instance(context);
|
||||
lint = Lint.instance(context);
|
||||
names = Names.instance(context);
|
||||
modules = Modules.instance(context);
|
||||
diags = JCDiagnostic.Factory.instance(context);
|
||||
|
||||
predefClassDef = make.ClassDef(
|
||||
make.Modifiers(PUBLIC),
|
||||
@ -229,6 +236,24 @@ public class Enter extends JCTree.Visitor {
|
||||
: 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
|
||||
*************************************************************************/
|
||||
@ -276,57 +301,80 @@ public class Enter extends JCTree.Visitor {
|
||||
|
||||
@Override
|
||||
public void visitTopLevel(JCCompilationUnit tree) {
|
||||
// Assert.checkNonNull(tree.modle, tree.sourcefile.toString());
|
||||
|
||||
JavaFileObject prev = log.useSource(tree.sourcefile);
|
||||
boolean addEnv = false;
|
||||
boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info",
|
||||
JavaFileObject.Kind.SOURCE);
|
||||
JCPackageDecl pd = tree.getPackage();
|
||||
if (pd != null) {
|
||||
tree.packge = pd.packge = syms.enterPackage(TreeInfo.fullName(pd.pid));
|
||||
if ( pd.annotations.nonEmpty()
|
||||
|| pkginfoOpt == PkgInfo.ALWAYS
|
||||
|| 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");
|
||||
}
|
||||
}
|
||||
if (TreeInfo.isModuleInfo(tree)) {
|
||||
tree.packge = syms.rootPackage;
|
||||
Env<AttrContext> topEnv = topLevelEnv(tree);
|
||||
classEnter(tree.defs, topEnv);
|
||||
tree.modle.usesProvidesCompleter = modules.getUsesProvidesCompleter();
|
||||
} else {
|
||||
tree.packge = syms.unnamedPackage;
|
||||
}
|
||||
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);
|
||||
JCPackageDecl pd = tree.getPackage();
|
||||
if (pd != null) {
|
||||
tree.packge = pd.packge = syms.enterPackage(tree.modle, TreeInfo.fullName(pd.pid));
|
||||
if ( pd.annotations.nonEmpty()
|
||||
|| pkginfoOpt == PkgInfo.ALWAYS
|
||||
|| 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 {
|
||||
tree.packge = tree.modle.unnamedPackage;
|
||||
}
|
||||
typeEnvs.put(tree.packge, packageEnv);
|
||||
|
||||
for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner)
|
||||
q.flags_field |= EXISTS;
|
||||
Map<Name, PackageSymbol> visiblePackages = tree.modle.visiblePackages;
|
||||
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;
|
||||
ClassSymbol c = syms.enterClass(name, tree.packge);
|
||||
c.flatname = names.fromString(tree.packge + "." + name);
|
||||
c.sourcefile = tree.sourcefile;
|
||||
if (dependencyWithPackage.isPresent()) {
|
||||
log.error(pd, Errors.PackageInOtherModule(dependencyWithPackage.get()));
|
||||
}
|
||||
|
||||
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.members_field = WriteableScope.create(c);
|
||||
tree.packge.package_info = c;
|
||||
}
|
||||
classEnter(tree.defs, topEnv);
|
||||
if (addEnv) {
|
||||
todo.append(packageEnv);
|
||||
c.members_field = WriteableScope.create(c);
|
||||
tree.packge.package_info = c;
|
||||
}
|
||||
classEnter(tree.defs, topEnv);
|
||||
if (addEnv) {
|
||||
todo.append(packageEnv);
|
||||
}
|
||||
}
|
||||
log.useSource(prev);
|
||||
result = null;
|
||||
@ -342,7 +390,7 @@ public class Enter extends JCTree.Visitor {
|
||||
PackageSymbol packge = (PackageSymbol)owner;
|
||||
for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner)
|
||||
q.flags_field |= EXISTS;
|
||||
c = syms.enterClass(tree.name, packge);
|
||||
c = syms.enterClass(env.toplevel.modle, tree.name, packge);
|
||||
packge.members().enterIfAbsent(c);
|
||||
if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) {
|
||||
log.error(tree.pos(),
|
||||
@ -356,7 +404,7 @@ public class Enter extends JCTree.Visitor {
|
||||
}
|
||||
if (owner.kind == TYP) {
|
||||
// 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) {
|
||||
tree.mods.flags |= PUBLIC | STATIC;
|
||||
}
|
||||
@ -371,13 +419,13 @@ public class Enter extends JCTree.Visitor {
|
||||
tree.sym = c;
|
||||
|
||||
// Enter class into `compiled' table and enclosing scope.
|
||||
if (chk.compiled.get(c.flatname) != null) {
|
||||
if (chk.getCompiled(c) != null) {
|
||||
duplicateClass(tree.pos(), c);
|
||||
result = types.createErrorType(tree.name, (TypeSymbol)owner, Type.noType);
|
||||
tree.sym = (ClassSymbol)result.tsym;
|
||||
return;
|
||||
}
|
||||
chk.compiled.put(c.flatname, c);
|
||||
chk.putCompiled(c);
|
||||
enclScope.enter(c);
|
||||
|
||||
// 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.
|
||||
classEnter(tree.defs, localEnv);
|
||||
|
||||
// Assert.checkNonNull(c.modle, c.sourcefile.toString());
|
||||
|
||||
result = c.type;
|
||||
}
|
||||
//where
|
||||
@ -453,6 +503,13 @@ public class Enter extends JCTree.Visitor {
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
|
@ -743,6 +743,10 @@ public class Flow {
|
||||
}
|
||||
}
|
||||
|
||||
public void visitModuleDef(JCModuleDecl tree) {
|
||||
// Do nothing for modules
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* main method
|
||||
*************************************************************************/
|
||||
@ -1305,6 +1309,10 @@ public class Flow {
|
||||
}
|
||||
}
|
||||
|
||||
public void visitModuleDef(JCModuleDecl tree) {
|
||||
// Do nothing for modules
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* main method
|
||||
*************************************************************************/
|
||||
@ -2416,6 +2424,10 @@ public class Flow {
|
||||
tree.underlyingType.accept(this);
|
||||
}
|
||||
|
||||
public void visitModuleDef(JCModuleDecl tree) {
|
||||
// Do nothing for modules
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* main method
|
||||
*************************************************************************/
|
||||
@ -2605,6 +2617,10 @@ public class Flow {
|
||||
super.visitTry(tree);
|
||||
}
|
||||
|
||||
public void visitModuleDef(JCModuleDecl tree) {
|
||||
// Do nothing for modules
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* main method
|
||||
*************************************************************************/
|
||||
|
@ -652,7 +652,7 @@ public class Lower extends TreeTranslator {
|
||||
|
||||
// Enter class symbol in owner scope and compiled table.
|
||||
enterSynthetic(odef.pos(), c, owner.members());
|
||||
chk.compiled.put(c.flatname, c);
|
||||
chk.putCompiled(c);
|
||||
|
||||
// Create class definition tree.
|
||||
JCClassDecl cdef = make.ClassDef(
|
||||
@ -1286,10 +1286,11 @@ public class Lower extends TreeTranslator {
|
||||
*/
|
||||
ClassSymbol accessConstructorTag() {
|
||||
ClassSymbol topClass = currentClass.outermostClass();
|
||||
ModuleSymbol topModle = topClass.packge().modle;
|
||||
Name flatname = names.fromString("" + topClass.getQualifiedName() +
|
||||
target.syntheticNameChar() +
|
||||
"1");
|
||||
ClassSymbol ctag = chk.compiled.get(flatname);
|
||||
ClassSymbol ctag = chk.getCompiled(topModle, flatname);
|
||||
if (ctag == null)
|
||||
ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass).sym;
|
||||
// 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) {
|
||||
if (!needPackageInfoClass(tree))
|
||||
return;
|
||||
return;
|
||||
|
||||
Name name = names.package_info;
|
||||
long flags = Flags.ABSTRACT | Flags.INTERFACE;
|
||||
// package-info is marked SYNTHETIC in JDK 1.6 and later releases
|
||||
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;
|
||||
c.flags_field |= flags;
|
||||
c.setAttributes(tree.packge);
|
||||
c.flags_field |= flags;
|
||||
ClassType ctype = (ClassType) c.type;
|
||||
ctype.supertype_field = syms.objectType;
|
||||
ctype.interfaces_field = List.nil();
|
||||
packageAnnotationsClass.sym = c;
|
||||
|
||||
translated.append(packageAnnotationsClass);
|
||||
createInfoClass(tree.annotations, c);
|
||||
}
|
||||
// where
|
||||
private boolean needPackageInfoClass(JCPackageDecl pd) {
|
||||
@ -2381,6 +2375,23 @@ public class Lower extends TreeTranslator {
|
||||
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) {
|
||||
Env<AttrContext> prevEnv = attrEnv;
|
||||
ClassSymbol currentClassPrev = currentClass;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -93,10 +93,13 @@ public class Resolve {
|
||||
JCDiagnostic.Factory diags;
|
||||
public final boolean allowMethodHandles;
|
||||
public final boolean allowFunctionalInterfaceMostSpecific;
|
||||
public final boolean allowModules;
|
||||
public final boolean checkVarargsAccessAfterResolution;
|
||||
private final boolean compactMethodDiags;
|
||||
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
|
||||
|
||||
private final boolean checkModuleAccess;
|
||||
|
||||
WriteableScope polymorphicSignatureScope;
|
||||
|
||||
protected Resolve(Context context) {
|
||||
@ -130,6 +133,12 @@ public class Resolve {
|
||||
polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
|
||||
|
||||
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
|
||||
@ -309,8 +318,19 @@ public class Resolve {
|
||||
env.toplevel.packge == c.packge();
|
||||
break;
|
||||
default: // error recovery
|
||||
isAccessible = true;
|
||||
break;
|
||||
case PUBLIC:
|
||||
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;
|
||||
case PROTECTED:
|
||||
isAccessible =
|
||||
@ -1947,16 +1967,27 @@ public class Resolve {
|
||||
*/
|
||||
Symbol loadClass(Env<AttrContext> env, Name name) {
|
||||
try {
|
||||
ClassSymbol c = finder.loadClass(name);
|
||||
ClassSymbol c = finder.loadClass(env.toplevel.modle, name);
|
||||
return isAccessible(env, c) ? c : new AccessError(c);
|
||||
} catch (ClassFinder.BadClassFile err) {
|
||||
throw err;
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find a type declared in a scope (not inherited). Return null
|
||||
* if none is found.
|
||||
@ -2157,7 +2188,7 @@ public class Resolve {
|
||||
}
|
||||
|
||||
if (kind.contains(KindSelector.PCK))
|
||||
return syms.enterPackage(name);
|
||||
return syms.lookupPackage(env.toplevel.modle, name);
|
||||
else return bestSoFar;
|
||||
}
|
||||
|
||||
@ -2173,7 +2204,7 @@ public class Resolve {
|
||||
Symbol bestSoFar = typeNotFound;
|
||||
PackageSymbol pack = null;
|
||||
if (kind.contains(KindSelector.PCK)) {
|
||||
pack = syms.enterPackage(fullname);
|
||||
pack = syms.lookupPackage(env.toplevel.modle, fullname);
|
||||
if (pack.exists()) return pack;
|
||||
}
|
||||
if (kind.contains(KindSelector.TYP)) {
|
||||
@ -3920,9 +3951,15 @@ public class Resolve {
|
||||
else if ((sym.flags() & PUBLIC) != 0
|
||||
|| (env != null && this.site != null
|
||||
&& !isAccessible(env, this.site))) {
|
||||
return diags.create(dkind, log.currentSource(),
|
||||
pos, "not.def.access.class.intf.cant.access",
|
||||
sym, sym.location());
|
||||
if (sym.owner.kind == PCK) {
|
||||
return diags.create(dkind, log.currentSource(),
|
||||
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) {
|
||||
return diags.create(dkind, log.currentSource(),
|
||||
@ -3935,6 +3972,18 @@ public class Resolve {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -162,6 +162,8 @@ public class TypeEnter implements Completer {
|
||||
// if there remain any unimported toplevels (these must have
|
||||
// no classes at all), process their import statements as well.
|
||||
for (JCCompilationUnit tree : trees) {
|
||||
if (tree.defs.nonEmpty() && tree.defs.head.hasTag(MODULEDEF))
|
||||
continue;
|
||||
if (!tree.starImportScope.isFilled()) {
|
||||
Env<AttrContext> topEnv = enter.topLevelEnv(tree);
|
||||
finishImports(tree, () -> { completeClass.resolveImports(tree, topEnv); });
|
||||
@ -330,7 +332,7 @@ public class TypeEnter implements Completer {
|
||||
chk.importAccessible(sym, packge);
|
||||
|
||||
// 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())
|
||||
throw new FatalError(diags.fragment("fatal.err.no.java.lang"));
|
||||
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;
|
||||
while (p.owner != syms.rootPackage) {
|
||||
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,
|
||||
"pkg.clashes.with.class.of.same.name",
|
||||
p);
|
||||
@ -515,7 +519,7 @@ public class TypeEnter implements Completer {
|
||||
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))
|
||||
return t;
|
||||
|
||||
@ -525,19 +529,21 @@ public class TypeEnter implements Completer {
|
||||
@Override
|
||||
public Type getModelType() {
|
||||
if (modelType == null)
|
||||
modelType = new Synthesizer(getOriginalType(), interfaceExpected).visit(tree);
|
||||
modelType = new Synthesizer(env.toplevel.modle, getOriginalType(), interfaceExpected).visit(tree);
|
||||
return modelType;
|
||||
}
|
||||
};
|
||||
}
|
||||
// where:
|
||||
private class Synthesizer extends JCTree.Visitor {
|
||||
ModuleSymbol msym;
|
||||
Type originalType;
|
||||
boolean interfaceExpected;
|
||||
List<ClassSymbol> synthesizedSymbols = List.nil();
|
||||
Type result;
|
||||
|
||||
Synthesizer(Type originalType, boolean interfaceExpected) {
|
||||
Synthesizer(ModuleSymbol msym, Type originalType, boolean interfaceExpected) {
|
||||
this.msym = msym;
|
||||
this.originalType = originalType;
|
||||
this.interfaceExpected = interfaceExpected;
|
||||
}
|
||||
@ -564,7 +570,7 @@ public class TypeEnter implements Completer {
|
||||
if (!tree.type.hasTag(ERROR)) {
|
||||
result = tree.type;
|
||||
} 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
|
||||
: syms.objectType;
|
||||
}
|
||||
ct.supertype_field = modelMissingTypes(supertype, extending, false);
|
||||
ct.supertype_field = modelMissingTypes(baseEnv, supertype, extending, false);
|
||||
|
||||
// Determine interfaces.
|
||||
ListBuffer<Type> interfaces = new ListBuffer<>();
|
||||
@ -669,7 +675,7 @@ public class TypeEnter implements Completer {
|
||||
} else {
|
||||
if (all_interfaces == null)
|
||||
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
|
||||
// name as a top-level package.
|
||||
if (checkClash &&
|
||||
sym.owner.kind == PCK && sym.owner != syms.unnamedPackage &&
|
||||
syms.packageExists(sym.fullname)) {
|
||||
sym.owner.kind == PCK && sym.owner != env.toplevel.modle.unnamedPackage &&
|
||||
syms.packageExists(env.toplevel.modle, sym.fullname)) {
|
||||
log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), sym);
|
||||
}
|
||||
if (sym.owner.kind == PCK && (sym.flags_field & PUBLIC) == 0 &&
|
||||
|
@ -31,6 +31,7 @@ import java.io.InputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.ByteBuffer;
|
||||
@ -42,6 +43,7 @@ import java.nio.charset.CodingErrorAction;
|
||||
import java.nio.charset.IllegalCharsetNameException;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
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.OptionHelper;
|
||||
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.DefinedBy;
|
||||
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<?>[] constrArgTypes = { URL[].class, ClassLoader.class };
|
||||
Constructor<? extends ClassLoader> constr = loader.getConstructor(constrArgTypes);
|
||||
return constr.newInstance(urls, thisClassLoader);
|
||||
return ensureReadable(constr.newInstance(urls, thisClassLoader));
|
||||
} catch (ReflectiveOperationException t) {
|
||||
// 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() {
|
||||
@ -284,8 +310,14 @@ public abstract class BaseFileManager implements JavaFileManager {
|
||||
*/
|
||||
public boolean handleOptions(Map<Option, String> map) {
|
||||
boolean ok = true;
|
||||
for (Map.Entry<Option, String> e: map.entrySet())
|
||||
ok = ok & handleOption(e.getKey(), e.getValue());
|
||||
for (Map.Entry<Option, String> e: map.entrySet()) {
|
||||
try {
|
||||
ok = ok & handleOption(e.getKey(), e.getValue());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
log.error(Errors.IllegalArgumentForOption(e.getKey().getText(), ex.getMessage()));
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -201,6 +201,8 @@ public class JRTIndex {
|
||||
if (Files.exists(dir)) {
|
||||
try (DirectoryStream<Path> modules = Files.newDirectoryStream(dir)) {
|
||||
for (Path module: modules) {
|
||||
if (Files.isSymbolicLink(module))
|
||||
module = Files.readSymbolicLink(module);
|
||||
Path p = rd.resolveAgainst(module);
|
||||
if (!Files.exists(p))
|
||||
continue;
|
||||
|
@ -47,12 +47,14 @@ import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
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.List;
|
||||
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;
|
||||
|
||||
@ -421,16 +427,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
boolean recurse,
|
||||
ListBuffer<JavaFileObject> resultList)
|
||||
throws IOException {
|
||||
// Very temporary and obnoxious interim hack
|
||||
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) {
|
||||
if (Files.isRegularFile(container) && container.equals(Locations.thisSystemModules)) {
|
||||
try {
|
||||
listJRTImage(subdirectory,
|
||||
fileKinds,
|
||||
@ -443,7 +440,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
return;
|
||||
}
|
||||
|
||||
if (fsInfo.isDirectory(container)) {
|
||||
if (Files.isDirectory(container)) {
|
||||
listDirectory(container, null,
|
||||
subdirectory,
|
||||
fileKinds,
|
||||
@ -452,7 +449,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
return;
|
||||
}
|
||||
|
||||
if (Files.exists(container)) {
|
||||
if (Files.isRegularFile(container)) {
|
||||
listArchive(container,
|
||||
subdirectory,
|
||||
fileKinds,
|
||||
@ -530,6 +527,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
return;
|
||||
}
|
||||
|
||||
locations.close();
|
||||
for (FileSystem fs: fileSystems.values()) {
|
||||
fs.close();
|
||||
}
|
||||
@ -604,7 +602,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
|
||||
@Override @DefinedBy(Api.COMPILER)
|
||||
public boolean hasLocation(Location location) {
|
||||
return getLocation(location) != null;
|
||||
nullCheck(location);
|
||||
return locations.hasLocation(location);
|
||||
}
|
||||
|
||||
@Override @DefinedBy(Api.COMPILER)
|
||||
@ -645,14 +644,14 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
return null;
|
||||
|
||||
for (Path file: path) {
|
||||
if (file == Locations.JRT_MARKER_FILE) {
|
||||
if (file.equals(Locations.thisSystemModules)) {
|
||||
JRTIndex.Entry e = getJRTIndex().getEntry(name.dirname());
|
||||
if (symbolFileEnabled && e.ctSym.hidden)
|
||||
continue;
|
||||
Path p = e.files.get(name.basename());
|
||||
if (p != null)
|
||||
return PathFileObject.forJRTPath(this, p);
|
||||
} else if (fsInfo.isDirectory(file)) {
|
||||
} else if (Files.isDirectory(file)) {
|
||||
try {
|
||||
Path f = name.resolveAgainst(file);
|
||||
if (Files.exists(f))
|
||||
@ -660,7 +659,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
fsInfo.getCanonicalFile(f), f);
|
||||
} catch (InvalidPathException ignore) {
|
||||
}
|
||||
} else if (Files.exists(file)) {
|
||||
} else if (Files.isRegularFile(file)) {
|
||||
FileSystem fs = getFileSystem(file);
|
||||
if (fs != null) {
|
||||
Path fsRoot = fs.getRootDirectories().iterator().next();
|
||||
@ -829,6 +828,69 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
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)
|
||||
public Path asPath(FileObject file) {
|
||||
if (file instanceof PathFileObject) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
}
|
@ -107,9 +107,8 @@ public class ClassFile {
|
||||
V49(49, 0), // JDK 1.5: enum, generics, annotations
|
||||
V50(50, 0), // JDK 1.6: stackmaps
|
||||
V51(51, 0), // JDK 1.7
|
||||
V52(52, 0); // JDK 1.8: lambda, type annos, param names
|
||||
// JDK9 still marked as V52 // V53(53, 0); // JDK 1.9
|
||||
|
||||
V52(52, 0), // JDK 1.8: lambda, type annos, param names
|
||||
V53(52, 0); // JDK 1.9: modules **** FIXME TO 53 BEFORE RELEASE *****
|
||||
Version(int major, int minor) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
|
@ -44,6 +44,7 @@ import javax.tools.JavaFileObject;
|
||||
import com.sun.tools.javac.comp.Annotate;
|
||||
import com.sun.tools.javac.comp.Annotate.AnnotationTypeCompleter;
|
||||
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.Scope.WriteableScope;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
@ -100,6 +101,10 @@ public class ClassReader {
|
||||
*/
|
||||
boolean allowSimplifiedVarargs;
|
||||
|
||||
/** Switch: allow modules.
|
||||
*/
|
||||
boolean allowModules;
|
||||
|
||||
/** Lint option: warn about classfile issues
|
||||
*/
|
||||
boolean lintClassfile;
|
||||
@ -137,6 +142,9 @@ public class ClassReader {
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
protected JavaFileObject currentClassFile = null;
|
||||
@ -145,6 +153,10 @@ public class ClassReader {
|
||||
*/
|
||||
protected Symbol currentOwner = null;
|
||||
|
||||
/** The module containing the class currently being read.
|
||||
*/
|
||||
protected ModuleSymbol currentModule = null;
|
||||
|
||||
/** The buffer containing the currently read class file.
|
||||
*/
|
||||
byte[] buf = new byte[INITIAL_BUFFER_SIZE];
|
||||
@ -228,6 +240,7 @@ public class ClassReader {
|
||||
|
||||
Source source = Source.instance(context);
|
||||
allowSimplifiedVarargs = source.allowSimplifiedVarargs();
|
||||
allowModules = source.allowModules();
|
||||
|
||||
saveParameterNames = options.isSet("save-parameter-names");
|
||||
|
||||
@ -478,7 +491,7 @@ public class ClassReader {
|
||||
// simplified to (buf[start] == '[')
|
||||
return (buf[start] == '[' || buf[start + len - 1] == ';')
|
||||
? (Object)sigToType(buf, start, len)
|
||||
: (Object)syms.enterClass(names.fromUtf(internalize(buf, start,
|
||||
: (Object)enterClass(names.fromUtf(internalize(buf, start,
|
||||
len)));
|
||||
}
|
||||
|
||||
@ -500,6 +513,23 @@ public class ClassReader {
|
||||
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.
|
||||
*/
|
||||
Name readName(int i) {
|
||||
@ -522,6 +552,34 @@ public class ClassReader {
|
||||
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
|
||||
***********************************************************************/
|
||||
@ -660,7 +718,7 @@ public class ClassReader {
|
||||
switch (c) {
|
||||
|
||||
case ';': { // end
|
||||
ClassSymbol t = syms.enterClass(names.fromUtf(signatureBuffer,
|
||||
ClassSymbol t = enterClass(names.fromUtf(signatureBuffer,
|
||||
startSbp,
|
||||
sbp - startSbp));
|
||||
|
||||
@ -674,7 +732,7 @@ public class ClassReader {
|
||||
}
|
||||
|
||||
case '<': // generic arguments
|
||||
ClassSymbol t = syms.enterClass(names.fromUtf(signatureBuffer,
|
||||
ClassSymbol t = enterClass(names.fromUtf(signatureBuffer,
|
||||
startSbp,
|
||||
sbp - startSbp));
|
||||
outer = new ClassType(outer, sigToTypes('>'), t) {
|
||||
@ -737,7 +795,7 @@ public class ClassReader {
|
||||
case '.':
|
||||
//we have seen an enclosing non-generic class
|
||||
if (outer != Type.noType) {
|
||||
t = syms.enterClass(names.fromUtf(signatureBuffer,
|
||||
t = enterClass(names.fromUtf(signatureBuffer,
|
||||
startSbp,
|
||||
sbp - startSbp));
|
||||
outer = new ClassType(outer, List.<Type>nil(), t);
|
||||
@ -941,7 +999,12 @@ public class ClassReader {
|
||||
new AttributeReader(names.InnerClasses, V45_3, CLASS_ATTRIBUTE) {
|
||||
protected void read(Symbol sym, int attrLen) {
|
||||
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) {
|
||||
protected void read(Symbol sym, int attrLen) {
|
||||
ClassSymbol c = (ClassSymbol) sym;
|
||||
@ -1130,12 +1174,109 @@ public class ClassReader {
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// The following attributes for a Code attribute are not currently handled
|
||||
// StackMapTable
|
||||
// SourceDebugExtension
|
||||
// LineNumberTable
|
||||
// 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)
|
||||
@ -1388,7 +1529,7 @@ public class ClassReader {
|
||||
int index = poolIdx[i];
|
||||
int length = getChar(index + 1);
|
||||
if (buf[index + length + 2] != ';')
|
||||
return syms.enterClass(readName(i)).type;
|
||||
return enterClass(readName(i)).type;
|
||||
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
|
||||
* `typevars'.
|
||||
*/
|
||||
@ -2193,6 +2344,14 @@ public class ClassReader {
|
||||
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
|
||||
* versions of an inner class are read.
|
||||
*/
|
||||
@ -2208,14 +2367,27 @@ public class ClassReader {
|
||||
enterTypevars(ct.getEnclosingType());
|
||||
|
||||
// read flags, or skip if this is an inner class
|
||||
long flags = adjustClassFlags(nextChar());
|
||||
if (c.owner.kind == PCK) c.flags_field = flags;
|
||||
|
||||
// read own class name and check that it matches
|
||||
ClassSymbol self = readClassSymbol(nextChar());
|
||||
if (c != self)
|
||||
throw badClassFile("class.file.wrong.class",
|
||||
self.flatname);
|
||||
long f = nextChar();
|
||||
long flags = adjustClassFlags(f);
|
||||
if ((flags & MODULE) == 0) {
|
||||
if (c.owner.kind == PCK) c.flags_field = flags;
|
||||
// read own class name and check that it matches
|
||||
currentModule = c.packge().modle;
|
||||
ClassSymbol self = readClassSymbol(nextChar());
|
||||
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
|
||||
// skip ahead to read class attributes
|
||||
@ -2272,7 +2444,7 @@ public class ClassReader {
|
||||
if (outer != null) { // we have a member class
|
||||
if (name == names.empty)
|
||||
name = names.one;
|
||||
ClassSymbol member = syms.enterClass(name, outer);
|
||||
ClassSymbol member = enterClass(name, outer);
|
||||
if ((flags & STATIC) == 0) {
|
||||
((ClassType)member.type).setEnclosingType(outer.type);
|
||||
if (member.erasure_field != null)
|
||||
@ -2354,11 +2526,24 @@ public class ClassReader {
|
||||
} else {
|
||||
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) {
|
||||
throw badClassFile("unable.to.access.file", ex.getMessage());
|
||||
} catch (ArrayIndexOutOfBoundsException ex) {
|
||||
throw badClassFile("bad.class.file", c.flatname);
|
||||
} finally {
|
||||
interimUses = List.nil();
|
||||
interimProvides = List.nil();
|
||||
missingTypeVariables = List.nil();
|
||||
foundTypeVariables = List.nil();
|
||||
filling = false;
|
||||
@ -2429,6 +2614,10 @@ public class ClassReader {
|
||||
}
|
||||
|
||||
long adjustClassFlags(long flags) {
|
||||
if ((flags & ACC_MODULE) != 0) {
|
||||
flags &= ~ACC_MODULE;
|
||||
flags |= MODULE;
|
||||
}
|
||||
return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
|
||||
}
|
||||
|
||||
@ -2580,4 +2769,58 @@ public class ClassReader {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,10 +33,12 @@ import java.util.HashSet;
|
||||
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileManager.Location;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.code.*;
|
||||
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.Type.*;
|
||||
import com.sun.tools.javac.code.Types.UniqueType;
|
||||
@ -97,6 +99,12 @@ public class ClassWriter extends ClassFile {
|
||||
/** Type utilities. */
|
||||
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.
|
||||
* 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
|
||||
**********************************************************************/
|
||||
@ -1564,9 +1624,17 @@ public class ClassWriter extends ClassFile {
|
||||
public JavaFileObject writeClass(ClassSymbol c)
|
||||
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
|
||||
= fileManager.getJavaFileForOutput(CLASS_OUTPUT,
|
||||
c.flatname.toString(),
|
||||
= fileManager.getJavaFileForOutput(outLocn,
|
||||
name,
|
||||
JavaFileObject.Kind.CLASS,
|
||||
c.sourcefile);
|
||||
OutputStream out = outFile.openOutputStream();
|
||||
@ -1604,11 +1672,17 @@ public class ClassWriter extends ClassFile {
|
||||
List<Type> interfaces = types.interfaces(c.type);
|
||||
List<Type> typarams = c.type.getTypeArguments();
|
||||
|
||||
int 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;
|
||||
int flags;
|
||||
if (c.owner.kind == MDL) {
|
||||
flags = ACC_MODULE;
|
||||
} else {
|
||||
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) {
|
||||
PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
|
||||
pw.println();
|
||||
@ -1693,6 +1767,9 @@ public class ClassWriter extends ClassFile {
|
||||
acount += writeJavaAnnotations(c.getRawAttributes());
|
||||
acount += writeTypeAnnotations(c.getRawTypeAttributes(), false);
|
||||
acount += writeEnclosingMethodAttribute(c);
|
||||
if (c.owner.kind == MDL) {
|
||||
acount += writeModuleAttribute(c);
|
||||
}
|
||||
acount += writeExtraClassAttributes(c);
|
||||
|
||||
poolbuf.appendInt(JAVA_MAGIC);
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.JavaFileManager;
|
||||
import javax.tools.JavaFileManager.Location;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import com.sun.tools.javac.code.Attribute;
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
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.Symtab;
|
||||
import com.sun.tools.javac.code.Type;
|
||||
@ -82,6 +84,12 @@ public class JNIWriter {
|
||||
*/
|
||||
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 static final boolean isWindows =
|
||||
@ -168,8 +176,15 @@ public class JNIWriter {
|
||||
*/
|
||||
public FileObject write(ClassSymbol c) throws IOException {
|
||||
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
|
||||
= fileManager.getFileForOutput(StandardLocation.NATIVE_HEADER_OUTPUT,
|
||||
= fileManager.getFileForOutput(outLocn,
|
||||
"", className.replaceAll("[.$]", "_") + ".h", null);
|
||||
PrintWriter out = new PrintWriter(outFile.openWriter());
|
||||
try {
|
||||
@ -675,5 +690,10 @@ public class JNIWriter {
|
||||
public R visitType(Type t, P p) {
|
||||
return defaultAction(t, p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R visitModuleType(Type.ModuleType t, P p) {
|
||||
return defaultAction(t, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,17 +29,24 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileManager.Location;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.JavaFileObject.Kind;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
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.platform.PlatformDescription;
|
||||
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.List;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
@ -77,6 +86,7 @@ public class Arguments {
|
||||
private Set<Path> files;
|
||||
private Map<Option, String> deferredFileManagerOptions;
|
||||
private Set<JavaFileObject> fileObjects;
|
||||
private boolean emptyAllowed;
|
||||
private final Options options;
|
||||
|
||||
private JavaFileManager fileManager;
|
||||
@ -248,14 +258,12 @@ public class Arguments {
|
||||
*/
|
||||
public Set<JavaFileObject> getFileObjects() {
|
||||
if (fileObjects == null) {
|
||||
if (files == null) {
|
||||
fileObjects = Collections.emptySet();
|
||||
} else {
|
||||
fileObjects = new LinkedHashSet<>();
|
||||
JavacFileManager jfm = (JavacFileManager) getFileManager();
|
||||
for (JavaFileObject fo: jfm.getJavaFileObjectsFromPaths(files))
|
||||
fileObjects.add(fo);
|
||||
}
|
||||
fileObjects = new LinkedHashSet<>();
|
||||
}
|
||||
if (files != null) {
|
||||
JavacFileManager jfm = (JavacFileManager) getFileManager();
|
||||
for (JavaFileObject fo: jfm.getJavaFileObjectsFromPaths(files))
|
||||
fileObjects.add(fo);
|
||||
}
|
||||
return fileObjects;
|
||||
}
|
||||
@ -291,8 +299,10 @@ public class Arguments {
|
||||
checkOptionAllowed(platformString == null,
|
||||
option -> error("err.release.bootclasspath.conflict", option.getText()),
|
||||
Option.BOOTCLASSPATH, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND,
|
||||
Option.XBOOTCLASSPATH_PREPEND, Option.ENDORSEDDIRS, Option.EXTDIRS, Option.SOURCE,
|
||||
Option.TARGET);
|
||||
Option.XBOOTCLASSPATH_PREPEND,
|
||||
Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS,
|
||||
Option.EXTDIRS, Option.DJAVA_EXT_DIRS,
|
||||
Option.SOURCE, Option.TARGET);
|
||||
|
||||
if (platformString != null) {
|
||||
PlatformDescription platformDescription = PlatformUtils.lookupPlatformDescription(platformString);
|
||||
@ -396,13 +406,53 @@ public class Arguments {
|
||||
* ILLEGAL_STATE
|
||||
*/
|
||||
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()) {
|
||||
// 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.
|
||||
if (options.isSet(Option.HELP)
|
||||
|| options.isSet(Option.X)
|
||||
|| options.isSet(Option.VERSION)
|
||||
|| options.isSet(Option.FULLVERSION))
|
||||
|| options.isSet(Option.FULLVERSION)
|
||||
|| options.isSet(Option.M))
|
||||
return true;
|
||||
|
||||
if (emptyAllowed)
|
||||
return true;
|
||||
|
||||
if (JavaCompiler.explicitAnnotationProcessingRequested(options)) {
|
||||
@ -423,6 +473,32 @@ public class Arguments {
|
||||
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);
|
||||
Source source = (sourceString != null)
|
||||
? 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);
|
||||
|
||||
if (lintOptions && source.compareTo(Source.DEFAULT) < 0 && !options.isSet(Option.RELEASE)) {
|
||||
JavaFileManager fm = getFileManager();
|
||||
if (fm instanceof BaseFileManager) {
|
||||
if (((BaseFileManager) fm).isDefaultBootClassPath())
|
||||
log.warning(LintCategory.OPTIONS, "source.no.bootclasspath", source.name);
|
||||
@ -484,22 +563,106 @@ public class Arguments {
|
||||
boolean obsoleteOptionFound = false;
|
||||
|
||||
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) {
|
||||
log.warning(LintCategory.OPTIONS, "option.obsolete.source", source.name);
|
||||
log.warning(LintCategory.OPTIONS, Warnings.OptionObsoleteSource(source.name));
|
||||
obsoleteOptionFound = true;
|
||||
}
|
||||
|
||||
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) {
|
||||
log.warning(LintCategory.OPTIONS, "option.obsolete.target", target.name);
|
||||
log.warning(LintCategory.OPTIONS, Warnings.OptionObsoleteTarget(target.name));
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -513,6 +676,10 @@ public class Arguments {
|
||||
&& classNames.isEmpty();
|
||||
}
|
||||
|
||||
public void allowEmpty() {
|
||||
this.emptyAllowed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file manager options which may have been deferred
|
||||
* during processArgs.
|
||||
@ -626,6 +793,7 @@ public class Arguments {
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@ import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.Processor;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.ElementVisitor;
|
||||
import javax.tools.DiagnosticListener;
|
||||
import javax.tools.JavaFileManager;
|
||||
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.JCVariableDecl;
|
||||
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 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.main.Option.*;
|
||||
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
|
||||
|
||||
import static javax.tools.StandardLocation.CLASS_OUTPUT;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** The modules visitor
|
||||
*/
|
||||
protected Modules modules;
|
||||
|
||||
/** The module finder
|
||||
*/
|
||||
protected ModuleFinder moduleFinder;
|
||||
|
||||
/** The diagnostics factory
|
||||
*/
|
||||
protected JCDiagnostic.Factory diags;
|
||||
|
||||
/** The type eraser.
|
||||
*/
|
||||
protected TransTypes transTypes;
|
||||
@ -336,6 +357,8 @@ public class JavaCompiler {
|
||||
**/
|
||||
protected boolean implicitSourceFilesRead;
|
||||
|
||||
protected boolean enterDone;
|
||||
|
||||
protected CompileStates compileStates;
|
||||
|
||||
/** Construct a new compiler using a shared context.
|
||||
@ -382,6 +405,9 @@ public class JavaCompiler {
|
||||
annotate = Annotate.instance(context);
|
||||
types = Types.instance(context);
|
||||
taskListener = MultiTaskListener.instance(context);
|
||||
modules = Modules.instance(context);
|
||||
moduleFinder = ModuleFinder.instance(context);
|
||||
diags = Factory.instance(context);
|
||||
|
||||
finder.sourceCompleter = sourceCompleter;
|
||||
|
||||
@ -430,6 +456,18 @@ public class JavaCompiler {
|
||||
|
||||
if (platformProvider != null)
|
||||
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:
|
||||
@ -512,6 +550,11 @@ public class JavaCompiler {
|
||||
*/
|
||||
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) {
|
||||
CompileState shouldStopPolicy = (errorCount() > 0 || unrecoverableError())
|
||||
? shouldStopPolicyIfError
|
||||
@ -625,18 +668,44 @@ public class JavaCompiler {
|
||||
* @param name The name to resolve
|
||||
*/
|
||||
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 {
|
||||
Name flatname = names.fromString(name.replace("/", "."));
|
||||
return finder.loadClass(flatname);
|
||||
return finder.loadClass(msym, flatname);
|
||||
} catch (CompletionFailure ignore) {
|
||||
return resolveIdent(name);
|
||||
return resolveIdent(msym, name);
|
||||
}
|
||||
}
|
||||
|
||||
/** Resolve an identifier.
|
||||
* @param msym The module in which the search should be performed
|
||||
* @param name The identifier to resolve
|
||||
*/
|
||||
public Symbol resolveIdent(String name) {
|
||||
public Symbol resolveIdent(ModuleSymbol msym, String name) {
|
||||
if (name.equals(""))
|
||||
return syms.errSymbol;
|
||||
JavaFileObject prev = log.useSource(null);
|
||||
@ -650,7 +719,8 @@ public class JavaCompiler {
|
||||
}
|
||||
JCCompilationUnit toplevel =
|
||||
make.TopLevel(List.<JCTree>nil());
|
||||
toplevel.packge = syms.unnamedPackage;
|
||||
toplevel.modle = msym;
|
||||
toplevel.packge = msym.unnamedPackage;
|
||||
return attr.attribIdent(tree, toplevel);
|
||||
} finally {
|
||||
log.useSource(prev);
|
||||
@ -737,6 +807,16 @@ public class JavaCompiler {
|
||||
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);
|
||||
|
||||
if (!taskListener.isEmpty()) {
|
||||
@ -748,7 +828,16 @@ public class JavaCompiler {
|
||||
boolean isPkgInfo =
|
||||
tree.sourcefile.isNameCompatible("package-info",
|
||||
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) {
|
||||
JCDiagnostic diag =
|
||||
diagFactory.fragment("file.does.not.contain.package",
|
||||
@ -812,8 +901,12 @@ public class JavaCompiler {
|
||||
|
||||
// These method calls must be chained to avoid memory leaks
|
||||
processAnnotations(
|
||||
enterTrees(stopIfError(CompileState.PARSE, parseFiles(sourceFileObjects))),
|
||||
classnames);
|
||||
enterTrees(
|
||||
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 (taskListener.isEmpty() &&
|
||||
@ -912,7 +1005,20 @@ public class JavaCompiler {
|
||||
public List<JCCompilationUnit> enterTreesIfNeeded(List<JCCompilationUnit> roots) {
|
||||
if (shouldStop(CompileState.ATTR))
|
||||
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);
|
||||
|
||||
enterDone = true;
|
||||
|
||||
if (!taskListener.isEmpty()) {
|
||||
for (JCCompilationUnit unit: roots) {
|
||||
TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, unit);
|
||||
@ -1085,7 +1193,8 @@ public class JavaCompiler {
|
||||
if (sym == null ||
|
||||
(sym.kind == PCK && !processPcks) ||
|
||||
sym.kind == ABSENT_TYP) {
|
||||
log.error("proc.cant.find.class", nameStr);
|
||||
if (sym != silentFail)
|
||||
log.error(Errors.ProcCantFindClass(nameStr));
|
||||
errors = true;
|
||||
continue;
|
||||
}
|
||||
@ -1100,10 +1209,10 @@ public class JavaCompiler {
|
||||
continue;
|
||||
}
|
||||
Assert.check(sym.kind == PCK);
|
||||
log.warning("proc.package.does.not.exist", nameStr);
|
||||
log.warning(Warnings.ProcPackageDoesNotExist(nameStr));
|
||||
pckSymbols = pckSymbols.prepend((PackageSymbol)sym);
|
||||
} catch (CompletionFailure e) {
|
||||
log.error("proc.cant.find.class", nameStr);
|
||||
log.error(Errors.ProcCantFindClass(nameStr));
|
||||
errors = true;
|
||||
continue;
|
||||
}
|
||||
@ -1154,6 +1263,7 @@ public class JavaCompiler {
|
||||
return
|
||||
options.isSet(PROCESSOR) ||
|
||||
options.isSet(PROCESSORPATH) ||
|
||||
options.isSet(PROCESSORMODULEPATH) ||
|
||||
options.isSet(PROC, "only") ||
|
||||
options.isSet(XPRINT);
|
||||
}
|
||||
@ -1388,14 +1498,14 @@ public class JavaCompiler {
|
||||
make.at(Position.FIRSTPOS);
|
||||
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 (shouldStop(CompileState.LOWER))
|
||||
return;
|
||||
List<JCTree> pdef = lower.translateTopLevelClass(env, env.tree, localMake);
|
||||
if (pdef.head != null) {
|
||||
Assert.check(pdef.tail.isEmpty());
|
||||
results.add(new Pair<>(env, (JCClassDecl)pdef.head));
|
||||
return;
|
||||
List<JCTree> def = lower.translateTopLevelClass(env, env.tree, localMake);
|
||||
if (def.head != null) {
|
||||
Assert.check(def.tail.isEmpty());
|
||||
results.add(new Pair<>(env, (JCClassDecl)def.head));
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -1589,6 +1699,10 @@ public class JavaCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnterDone() {
|
||||
return enterDone;
|
||||
}
|
||||
|
||||
/** Close the compiler, flushing the logs
|
||||
*/
|
||||
public void close() {
|
||||
|
@ -27,6 +27,7 @@ package com.sun.tools.javac.main;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URL;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
@ -144,7 +145,8 @@ public class Main {
|
||||
try {
|
||||
// A fresh context was created above, so jfm must be a JavacFileManager
|
||||
((JavacFileManager)fileManager).close();
|
||||
} catch (IOException ignore) {
|
||||
} catch (IOException ex) {
|
||||
bugMessage(ex);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -204,11 +206,13 @@ public class Main {
|
||||
if (batchMode)
|
||||
CacheFSInfo.preRegister(context);
|
||||
|
||||
boolean ok = true;
|
||||
|
||||
// init file manager
|
||||
fileManager = context.get(JavaFileManager.class);
|
||||
if (fileManager instanceof BaseFileManager) {
|
||||
((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
|
||||
@ -219,7 +223,7 @@ public class Main {
|
||||
showClass(showClass);
|
||||
}
|
||||
|
||||
boolean ok = args.validate();
|
||||
ok &= args.validate();
|
||||
if (!ok || log.nerrors > 0)
|
||||
return Result.CMDERR;
|
||||
|
||||
@ -348,28 +352,28 @@ public class Main {
|
||||
void showClass(String className) {
|
||||
PrintWriter pw = log.getWriter(WriterKind.NOTICE);
|
||||
pw.println("javac: show class: " + className);
|
||||
|
||||
URL url = getClass().getResource('/' + className.replace('.', '/') + ".class");
|
||||
if (url == null)
|
||||
pw.println(" class not found");
|
||||
else {
|
||||
if (url != null) {
|
||||
pw.println(" " + url);
|
||||
try {
|
||||
final String algorithm = "MD5";
|
||||
byte[] digest;
|
||||
MessageDigest md = MessageDigest.getInstance(algorithm);
|
||||
try (DigestInputStream in = new DigestInputStream(url.openStream(), md)) {
|
||||
byte[] buf = new byte[8192];
|
||||
int n;
|
||||
do { n = in.read(buf); } while (n > 0);
|
||||
digest = md.digest();
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
try (InputStream in = getClass().getResourceAsStream('/' + className.replace('.', '/') + ".class")) {
|
||||
final String algorithm = "MD5";
|
||||
byte[] digest;
|
||||
MessageDigest md = MessageDigest.getInstance(algorithm);
|
||||
try (DigestInputStream din = new DigestInputStream(in, md)) {
|
||||
byte[] buf = new byte[8192];
|
||||
int n;
|
||||
do { n = din.read(buf); } while (n > 0);
|
||||
digest = md.digest();
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,6 +184,23 @@ public enum Option {
|
||||
|
||||
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) {
|
||||
@Override
|
||||
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),
|
||||
|
||||
PROCESSORMODULEPATH("-processormodulepath", "opt.arg.path", "opt.processormodulepath", STANDARD, FILEMANAGER),
|
||||
|
||||
PARAMETERS("-parameters","opt.parameters", STANDARD, BASIC),
|
||||
|
||||
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) {
|
||||
@Override
|
||||
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);
|
||||
helper.put(PLUGIN.text, (prev == null) ? p : prev + '\0' + p.trim());
|
||||
helper.put(PLUGIN.text, (prev == null) ? p : prev + '\0' + p);
|
||||
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.
|
||||
// It's actually implemented by the CommandLine class.
|
||||
AT("@", "opt.arg.file", "opt.AT", STANDARD, INFO, true) {
|
||||
@ -516,19 +635,19 @@ public enum Option {
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
// Standalone positional argument: source file or type name.
|
||||
SOURCEFILE("sourcefile", null, HIDDEN, INFO) {
|
||||
@Override
|
||||
public boolean matches(String s) {
|
||||
return s.endsWith(".java") // Java source file
|
||||
|| SourceVersion.isName(s); // Legal type name
|
||||
if (s.endsWith(".java")) // Java source file
|
||||
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
|
||||
public boolean process(OptionHelper helper, String option) {
|
||||
|
@ -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.
|
||||
*
|
||||
* 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 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.Scope.WriteableScope;
|
||||
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.Scope.LookupKind.NON_RECURSIVE;
|
||||
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.*;
|
||||
|
||||
/**
|
||||
@ -66,9 +71,12 @@ public class JavacElements implements Elements {
|
||||
|
||||
private final JavaCompiler javaCompiler;
|
||||
private final Symtab syms;
|
||||
private final Modules modules;
|
||||
private final Names names;
|
||||
private final Types types;
|
||||
private final Enter enter;
|
||||
private final JavacTaskImpl javacTaskImpl;
|
||||
private final CompileStates compileStates;
|
||||
|
||||
public static JavacElements instance(Context context) {
|
||||
JavacElements instance = context.get(JavacElements.class);
|
||||
@ -81,43 +89,66 @@ public class JavacElements implements Elements {
|
||||
context.put(JavacElements.class, this);
|
||||
javaCompiler = JavaCompiler.instance(context);
|
||||
syms = Symtab.instance(context);
|
||||
modules = Modules.instance(context);
|
||||
names = Names.instance(context);
|
||||
types = Types.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)
|
||||
public PackageSymbol getPackageElement(CharSequence name) {
|
||||
ensureEntered("getPackageElement");
|
||||
return getPackageElement(modules.getDefaultModule(), name);
|
||||
}
|
||||
|
||||
public PackageSymbol getPackageElement(ModuleElement module, CharSequence name) {
|
||||
String strName = name.toString();
|
||||
if (strName.equals(""))
|
||||
return syms.unnamedPackage;
|
||||
return syms.unnamedModule.unnamedPackage;
|
||||
return SourceVersion.isName(strName)
|
||||
? nameToSymbol(strName, PackageSymbol.class)
|
||||
? nameToSymbol((ModuleSymbol) module, strName, PackageSymbol.class)
|
||||
: null;
|
||||
}
|
||||
|
||||
@DefinedBy(Api.LANGUAGE_MODEL)
|
||||
public ClassSymbol getTypeElement(CharSequence name) {
|
||||
ensureEntered("getTypeElement");
|
||||
return getTypeElement(modules.getDefaultModule(), name);
|
||||
}
|
||||
|
||||
public ClassSymbol getTypeElement(ModuleElement module, CharSequence name) {
|
||||
String strName = name.toString();
|
||||
return SourceVersion.isName(strName)
|
||||
? nameToSymbol(strName, ClassSymbol.class)
|
||||
? nameToSymbol((ModuleSymbol) module, strName, ClassSymbol.class)
|
||||
: 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.
|
||||
*/
|
||||
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);
|
||||
// First check cache.
|
||||
Symbol sym = (clazz == ClassSymbol.class)
|
||||
? syms.classes.get(name)
|
||||
: syms.packages.get(name);
|
||||
? syms.getClass(module, name)
|
||||
: syms.lookupPackage(module, name);
|
||||
|
||||
try {
|
||||
if (sym == null)
|
||||
sym = javaCompiler.resolveIdent(nameStr);
|
||||
sym = javaCompiler.resolveIdent(module, nameStr);
|
||||
|
||||
sym.complete();
|
||||
|
||||
@ -333,6 +364,12 @@ public class JavacElements implements Elements {
|
||||
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)
|
||||
public boolean isDeprecated(Element e) {
|
||||
Symbol sym = cast(Symbol.class, e);
|
||||
@ -601,6 +638,15 @@ public class JavacElements implements Elements {
|
||||
: 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.
|
||||
* @throws NullPointerException if the object is {@code null}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.Comment.CommentStyle;
|
||||
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.JCTree.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
@ -158,6 +159,7 @@ public class JavacParser implements Parser {
|
||||
this.allowStaticInterfaceMethods = source.allowStaticInterfaceMethods();
|
||||
this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast();
|
||||
this.allowTypeAnnotations = source.allowTypeAnnotations();
|
||||
this.allowModules = source.allowModules();
|
||||
this.allowAnnotationsAfterTypeParams = source.allowAnnotationsAfterTypeParams();
|
||||
this.allowUnderscoreIdentifier = source.allowUnderscoreIdentifier();
|
||||
this.allowPrivateInterfaceMethods = source.allowPrivateInterfaceMethods();
|
||||
@ -206,6 +208,10 @@ public class JavacParser implements Parser {
|
||||
*/
|
||||
boolean allowMethodReferences;
|
||||
|
||||
/** Switch: should we recognize modules?
|
||||
*/
|
||||
boolean allowModules;
|
||||
|
||||
/** Switch: should we allow default methods in interfaces?
|
||||
*/
|
||||
boolean allowDefaultMethods;
|
||||
@ -3096,59 +3102,65 @@ public class JavacParser implements Parser {
|
||||
Token firstToken = token;
|
||||
JCModifiers mods = null;
|
||||
boolean consumedToplevelDoc = false;
|
||||
boolean seenImport = false;
|
||||
boolean seenPackage = false;
|
||||
ListBuffer<JCTree> defs = new ListBuffer<>();
|
||||
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));
|
||||
if (token.kind == IDENTIFIER && token.name() == names.module) {
|
||||
defs.append(moduleDecl(token.comment(CommentStyle.JAVADOC)));
|
||||
consumedToplevelDoc = true;
|
||||
storeEnd(pd, token.pos);
|
||||
defs.append(pd);
|
||||
} else {
|
||||
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());
|
||||
if (!consumedToplevelDoc)
|
||||
attach(toplevel, firstToken.comment(CommentStyle.JAVADOC));
|
||||
@ -3163,6 +3175,75 @@ public class JavacParser implements Parser {
|
||||
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 } [ "." "*" ] ";"
|
||||
*/
|
||||
protected JCTree importDeclaration() {
|
||||
|
@ -27,8 +27,10 @@ package com.sun.tools.javac.processing;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
@ -42,6 +44,7 @@ import javax.lang.model.element.*;
|
||||
import javax.lang.model.util.*;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.JavaFileObject.Kind;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
|
||||
import static javax.tools.StandardLocation.*;
|
||||
@ -49,6 +52,7 @@ import static javax.tools.StandardLocation.*;
|
||||
import com.sun.source.util.TaskEvent;
|
||||
import com.sun.tools.javac.api.MultiTaskListener;
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.code.Scope.WriteableScope;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
import com.sun.tools.javac.code.Type.ClassType;
|
||||
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.Enter;
|
||||
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.main.JavaCompiler;
|
||||
import com.sun.tools.javac.model.JavacElements;
|
||||
import com.sun.tools.javac.model.JavacTypes;
|
||||
import com.sun.tools.javac.platform.PlatformDescription;
|
||||
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.JCTree.*;
|
||||
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.Log;
|
||||
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.Names;
|
||||
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.Kinds.Kind.*;
|
||||
@ -112,8 +118,10 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
private final JavacMessager messager;
|
||||
private final JavacElements elementUtils;
|
||||
private final JavacTypes typeUtils;
|
||||
private final Types types;
|
||||
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
|
||||
@ -154,7 +162,10 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
Source source;
|
||||
|
||||
private ClassLoader processorClassLoader;
|
||||
private SecurityException processorClassLoaderException;
|
||||
private ServiceLoader<Processor> serviceLoader;
|
||||
private SecurityException processorLoaderException;
|
||||
|
||||
private final JavaFileManager fileManager;
|
||||
|
||||
/**
|
||||
* JavacMessages object used for localization
|
||||
@ -167,6 +178,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
private final Enter enter;
|
||||
private final Completer initialCompleter;
|
||||
private final Check chk;
|
||||
private final ModuleSymbol defaultModule;
|
||||
|
||||
private final Context context;
|
||||
|
||||
@ -196,6 +208,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
fatalErrors = options.isSet("fatalEnterError");
|
||||
showResolveErrors = options.isSet("showResolveErrors");
|
||||
werror = options.isSet(WERROR);
|
||||
fileManager = context.get(JavaFileManager.class);
|
||||
platformAnnotations = initPlatformAnnotations();
|
||||
|
||||
// Initialize services before any processors are initialized
|
||||
@ -204,6 +217,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
messager = new JavacMessager(context, this);
|
||||
elementUtils = JavacElements.instance(context);
|
||||
typeUtils = JavacTypes.instance(context);
|
||||
modules = Modules.instance(context);
|
||||
types = Types.instance(context);
|
||||
processorOptions = initProcessorOptions();
|
||||
unmatchedProcessorOptions = initUnmatchedProcessorOptions();
|
||||
@ -214,7 +228,11 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
enter = Enter.instance(context);
|
||||
initialCompleter = ClassFinder.instance(context).getCompleter();
|
||||
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) {
|
||||
@ -234,19 +252,28 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
return Collections.unmodifiableSet(platformAnnotations);
|
||||
}
|
||||
|
||||
private void initProcessorClassLoader() {
|
||||
JavaFileManager fileManager = context.get(JavaFileManager.class);
|
||||
private void initProcessorLoader() {
|
||||
try {
|
||||
// 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 (fileManager.hasLocation(ANNOTATION_PROCESSOR_MODULE_PATH)) {
|
||||
try {
|
||||
serviceLoader = fileManager.getServiceLoader(ANNOTATION_PROCESSOR_MODULE_PATH, Processor.class);
|
||||
} 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) {
|
||||
compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader);
|
||||
moduleHelper.addExports(processorClassLoader);
|
||||
|
||||
if (processorClassLoader != null && processorClassLoader instanceof Closeable) {
|
||||
compiler.closeables = compiler.closeables.prepend((Closeable) processorClassLoader);
|
||||
}
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
processorClassLoaderException = e;
|
||||
processorLoaderException = e;
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,14 +293,18 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
} else if (processors != null) {
|
||||
processorIterator = processors.iterator();
|
||||
} else {
|
||||
String processorNames = options.get(PROCESSOR);
|
||||
if (processorClassLoaderException == null) {
|
||||
if (processorLoaderException == null) {
|
||||
/*
|
||||
* If the "-processor" option is used, search the appropriate
|
||||
* path for the named class. Otherwise, use a service
|
||||
* 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);
|
||||
} else {
|
||||
processorIterator = new ServiceIterator(processorClassLoader, log);
|
||||
@ -286,7 +317,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
* in service configuration file.) Otherwise, we cannot continue.
|
||||
*/
|
||||
processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader",
|
||||
processorClassLoaderException);
|
||||
processorLoaderException);
|
||||
}
|
||||
}
|
||||
PlatformDescription platformProvider = context.get(PlatformDescription.class);
|
||||
@ -304,6 +335,18 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
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
|
||||
* 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
|
||||
*/
|
||||
private Iterator<Processor> handleServiceLoaderUnavailability(String key, Exception e) {
|
||||
JavaFileManager fileManager = context.get(JavaFileManager.class);
|
||||
|
||||
if (fileManager instanceof JavacFileManager) {
|
||||
StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager;
|
||||
Iterable<? extends Path> workingPath = fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
|
||||
@ -355,9 +396,9 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
* needed but unavailable.
|
||||
*/
|
||||
private class ServiceIterator implements Iterator<Processor> {
|
||||
private Iterator<Processor> iterator;
|
||||
private Log log;
|
||||
private ServiceLoader<Processor> loader;
|
||||
Iterator<Processor> iterator;
|
||||
Log log;
|
||||
ServiceLoader<Processor> loader;
|
||||
|
||||
ServiceIterator(ClassLoader classLoader, 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() {
|
||||
try {
|
||||
return iterator.hasNext();
|
||||
return internalHasNext();
|
||||
} catch(ServiceConfigurationError sce) {
|
||||
log.error("proc.bad.config.file", sce.getLocalizedMessage());
|
||||
throw new Abort(sce);
|
||||
@ -386,9 +434,14 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
}
|
||||
}
|
||||
|
||||
boolean internalHasNext() {
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Processor next() {
|
||||
try {
|
||||
return iterator.next();
|
||||
return internalNext();
|
||||
} catch (ServiceConfigurationError sce) {
|
||||
log.error("proc.bad.config.file", sce.getLocalizedMessage());
|
||||
throw new Abort(sce);
|
||||
@ -397,6 +450,11 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
}
|
||||
}
|
||||
|
||||
Processor internalNext() {
|
||||
return iterator.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
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> {
|
||||
Processor nextProc = null;
|
||||
@ -437,8 +547,10 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
Processor processor;
|
||||
try {
|
||||
try {
|
||||
Class<?> processorClass = processorCL.loadClass(processorName);
|
||||
ensureReadable(processorClass);
|
||||
processor =
|
||||
(Processor) (processorCL.loadClass(processorName).newInstance());
|
||||
(Processor) (processorClass.newInstance());
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
log.error("proc.processor.not.found", processorName);
|
||||
return false;
|
||||
@ -473,6 +585,26 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
public void remove () {
|
||||
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() {
|
||||
@ -605,7 +737,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
// TODO: These two classes can probably be rewritten better...
|
||||
/**
|
||||
* 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
|
||||
* annotation processing. The iterator first visits already
|
||||
* 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)
|
||||
throw new AssertionError(file);
|
||||
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)) {
|
||||
Name packageName = Convert.packagePart(name);
|
||||
PackageSymbol p = symtab.enterPackage(packageName);
|
||||
PackageSymbol p = symtab.enterPackage(defaultModule, packageName);
|
||||
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.reset();
|
||||
if (cs.classfile == null)
|
||||
cs.classfile = file;
|
||||
cs.completer = initialCompleter;
|
||||
} else {
|
||||
cs = symtab.enterClass(name);
|
||||
cs = symtab.enterClass(defaultModule, name);
|
||||
cs.reset();
|
||||
cs.classfile = file;
|
||||
cs.completer = initialCompleter;
|
||||
cs.owner.members().enter(cs); //XXX - OverwriteBetweenCompilations; syms.getClass is not sufficient anymore
|
||||
}
|
||||
list = list.prepend(cs);
|
||||
}
|
||||
@ -1023,7 +1158,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
|
||||
/** Enter a set of syntax trees. */
|
||||
private void enterTrees(List<JCCompilationUnit> roots) {
|
||||
compiler.enterTrees(roots);
|
||||
compiler.enterTrees(compiler.initModules(roots));
|
||||
}
|
||||
|
||||
/** Run a processing round. */
|
||||
@ -1099,11 +1234,12 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
filer.newRound();
|
||||
messager.newRound();
|
||||
compiler.newRound();
|
||||
modules.newRound();
|
||||
types.newRound();
|
||||
|
||||
boolean foundError = false;
|
||||
|
||||
for (ClassSymbol cs : symtab.classes.values()) {
|
||||
for (ClassSymbol cs : symtab.getAllClasses()) {
|
||||
if (cs.kind == ERR) {
|
||||
foundError = true;
|
||||
break;
|
||||
@ -1111,7 +1247,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
}
|
||||
|
||||
if (foundError) {
|
||||
for (ClassSymbol cs : symtab.classes.values()) {
|
||||
for (ClassSymbol cs : symtab.getAllClasses()) {
|
||||
if (cs.classfile != null || cs.kind == ERR) {
|
||||
cs.reset();
|
||||
cs.type = new ClassType(cs.type.getEnclosingType(), null, cs);
|
||||
@ -1350,6 +1486,13 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
|
||||
}
|
||||
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;
|
||||
topLevel = node;
|
||||
try {
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#
|
||||
# Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# 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=\
|
||||
{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
|
||||
compiler.err.not.def.access.class.intf.cant.access=\
|
||||
{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=\
|
||||
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
|
||||
@ -1379,6 +1419,10 @@ compiler.warn.constant.SVUID=\
|
||||
compiler.warn.dir.path.element.not.found=\
|
||||
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=\
|
||||
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
|
||||
|
||||
# Warnings related to annotation processing
|
||||
# 0: name
|
||||
# 0: string
|
||||
compiler.warn.proc.package.does.not.exist=\
|
||||
package {0} does not exist
|
||||
|
||||
@ -1733,6 +1777,9 @@ compiler.misc.type.none=\
|
||||
compiler.misc.unnamed.package=\
|
||||
unnamed package
|
||||
|
||||
compiler.misc.unnamed.module=\
|
||||
unnamed module
|
||||
|
||||
#####
|
||||
|
||||
# 0: symbol, 1: message segment
|
||||
@ -1789,6 +1836,9 @@ compiler.misc.bad.signature=\
|
||||
compiler.misc.bad.type.annotation.value=\
|
||||
bad type annotation target type value: {0}
|
||||
|
||||
compiler.misc.bad.module-info.name=\
|
||||
bad class name
|
||||
|
||||
compiler.misc.class.file.wrong.class=\
|
||||
class file contains wrong class: {0}
|
||||
|
||||
@ -1810,6 +1860,9 @@ compiler.misc.file.doesnt.contain.class=\
|
||||
compiler.misc.file.does.not.contain.package=\
|
||||
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=\
|
||||
illegal start of class file
|
||||
|
||||
@ -2176,6 +2229,9 @@ compiler.misc.kindname.class=\
|
||||
compiler.misc.kindname.package=\
|
||||
package
|
||||
|
||||
compiler.misc.kindname.module=\
|
||||
module
|
||||
|
||||
compiler.misc.kindname.static.init=\
|
||||
static initializer
|
||||
|
||||
@ -2278,6 +2334,12 @@ compiler.misc.inapplicable.method=\
|
||||
########################################
|
||||
# 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
|
||||
compiler.misc.diamond.and.anon.class.not.supported.in.source=\
|
||||
cannot use ''<>'' with anonymous inner classes in -source {0}\n\
|
||||
@ -2608,4 +2670,170 @@ compiler.err.dc.unterminated.signature=\
|
||||
compiler.err.dc.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}
|
||||
|
@ -39,20 +39,34 @@ javac.opt.deprecation=\
|
||||
Output source locations where deprecated APIs are used
|
||||
javac.opt.classpath=\
|
||||
Specify where to find user class files and annotation processors
|
||||
javac.opt.modulepath=\
|
||||
Specify where to find application modules
|
||||
javac.opt.sourcepath=\
|
||||
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=\
|
||||
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=\
|
||||
Prepend to the bootstrap class path
|
||||
javac.opt.Xbootclasspath.a=\
|
||||
Append to the bootstrap class path
|
||||
javac.opt.Xpatch=\
|
||||
Specify location of module class files to patch
|
||||
javac.opt.endorseddirs=\
|
||||
Override location of endorsed standards path
|
||||
javac.opt.extdirs=\
|
||||
Override location of installed extensions
|
||||
javac.opt.processorpath=\
|
||||
Specify where to find annotation processors
|
||||
javac.opt.processormodulepath=\
|
||||
Specify a module path where to find annotation processors
|
||||
javac.opt.processor=\
|
||||
Names of the annotation processors to run; bypasses default discovery process
|
||||
javac.opt.parameters=\
|
||||
@ -95,6 +109,12 @@ javac.opt.arg.key.equals.value=\
|
||||
key[=value]
|
||||
javac.opt.arg.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=\
|
||||
<dirs>
|
||||
javac.opt.arg.directory=\
|
||||
@ -252,6 +272,29 @@ javac.opt.AT=\
|
||||
Read options and filenames from file
|
||||
javac.opt.diags=\
|
||||
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
|
||||
|
||||
@ -269,6 +312,10 @@ javac.err.invalid.profile=\
|
||||
invalid profile: {0}
|
||||
javac.err.invalid.target=\
|
||||
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=\
|
||||
no source files
|
||||
javac.err.no.source.files.classes=\
|
||||
@ -279,6 +326,8 @@ javac.err.invalid.source=\
|
||||
invalid source release: {0}
|
||||
javac.err.error.writing.file=\
|
||||
error writing {0}; {1}
|
||||
javac.err.sourcepath.modulesourcepath.conflict=\
|
||||
cannot specify both -sourcepath and -modulesourcepath
|
||||
javac.warn.source.target.conflict=\
|
||||
source release {0} requires target release {1}
|
||||
javac.warn.target.default.source.conflict=\
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -35,14 +35,20 @@ import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.source.tree.*;
|
||||
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.Symbol.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.DefinedBy.Api;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
import com.sun.tools.javac.util.List;
|
||||
|
||||
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
|
||||
* for specific tree nodes as subclasses nested inside.
|
||||
@ -344,6 +350,12 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
DIV_ASG(DIV), // /=
|
||||
MOD_ASG(MOD), // %=
|
||||
|
||||
MODULEDEF,
|
||||
EXPORTS,
|
||||
PROVIDES,
|
||||
REQUIRES,
|
||||
USES,
|
||||
|
||||
/** A synthetic let expression, of type LetExpr.
|
||||
*/
|
||||
LETEXPR; // ala scheme
|
||||
@ -484,8 +496,12 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
public static class JCCompilationUnit extends JCTree implements CompilationUnitTree {
|
||||
/** All definitions in this file (ClassDef, Import, and Skip) */
|
||||
public List<JCTree> defs;
|
||||
/* The source file name. */
|
||||
/** The source file name. */
|
||||
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. */
|
||||
public PackageSymbol packge;
|
||||
/** 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
|
||||
implements com.sun.source.tree.ErroneousTree {
|
||||
implements ErroneousTree {
|
||||
public List<? extends JCTree> errs;
|
||||
protected JCErroneous(List<? extends JCTree> errs) {
|
||||
this.errs = errs;
|
||||
@ -2731,6 +2941,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args);
|
||||
JCModifiers Modifiers(long flags, List<JCAnnotation> annotations);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -2791,6 +3006,11 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
public void visitModifiers(JCModifiers that) { visitTree(that); }
|
||||
public void visitAnnotatedType(JCAnnotatedType 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 visitTree(JCTree that) { Assert.error(); }
|
||||
|
@ -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.
|
||||
*
|
||||
* 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) {
|
||||
try {
|
||||
print("import ");
|
||||
|
@ -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.
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
|
||||
@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)
|
||||
public JCTree visitOther(Tree node, P p) {
|
||||
JCTree tree = (JCTree) node;
|
||||
|
@ -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.BLOCK;
|
||||
import static com.sun.tools.javac.tree.JCTree.Tag.SYNCHRONIZED;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
/** Utility class containing inspector methods for trees.
|
||||
*
|
||||
@ -762,7 +763,12 @@ public class TreeInfo {
|
||||
node = skipParens(node);
|
||||
switch (node.getTag()) {
|
||||
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:
|
||||
return ((JCPackageDecl) node).packge;
|
||||
case CLASSDEF:
|
||||
@ -1144,4 +1150,21 @@ public class TreeInfo {
|
||||
finder.scan(e);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -125,6 +125,7 @@ public class TreeMaker implements JCTree.Factory {
|
||||
Assert.check(node instanceof JCClassDecl
|
||||
|| node instanceof JCPackageDecl
|
||||
|| node instanceof JCImport
|
||||
|| node instanceof JCModuleDecl
|
||||
|| node instanceof JCSkip
|
||||
|| node instanceof JCErroneous
|
||||
|| (node instanceof JCExpressionStatement
|
||||
@ -536,6 +537,41 @@ public class TreeMaker implements JCTree.Factory {
|
||||
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) {
|
||||
JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType);
|
||||
tree.pos = pos;
|
||||
|
@ -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.
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
|
||||
@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) {
|
||||
scan(tree.qualid);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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.
|
||||
*
|
||||
* 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 prefixLength = prefix.getByteLength();
|
||||
|
||||
if (thisLength < prefixLength)
|
||||
return false;
|
||||
|
||||
int i = 0;
|
||||
while (i < prefixLength &&
|
||||
i < thisLength &&
|
||||
thisBytes[thisOffset + i] == prefixBytes[prefixOffset + i])
|
||||
i++;
|
||||
return i == prefixLength;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user