This commit is contained in:
Lana Steuck 2016-11-23 19:15:26 +00:00
commit 4e0763e316
75 changed files with 2125 additions and 542 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, 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
@ -165,12 +165,12 @@ public class ForwardingJavaFileManager<M extends JavaFileManager> implements Jav
fileManager.close();
}
public Location getModuleLocation(Location location, String moduleName) throws IOException {
return fileManager.getModuleLocation(location, moduleName);
public Location getLocationForModule(Location location, String moduleName) throws IOException {
return fileManager.getLocationForModule(location, moduleName);
}
public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
return fileManager.getModuleLocation(location, fo, pkgName);
public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
return fileManager.getLocationForModule(location, fo, pkgName);
}
public <S> ServiceLoader<S> getServiceLoader(Location location, Class<S> service) throws IOException {
@ -181,7 +181,7 @@ public class ForwardingJavaFileManager<M extends JavaFileManager> implements Jav
return fileManager.inferModuleName(location);
}
public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
return fileManager.listModuleLocations(location);
public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
return fileManager.listLocationsForModules(location);
}
}

View File

@ -109,6 +109,28 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
/**
* Interface for locations of file objects. Used by file managers
* to determine where to place or search for file objects.
*
* <p>Informally, a {@code Location} corresponds to a "search path", such as a class
* path or module path, as used by command-line tools that use the default file system.
*
* <p>Some locations are typically used to identify a place in which
* a tool can find files to be read; others are typically used to identify
* a place where a tool can write files. If a location is used to identify
* a place for reading files, those files may be organized in a simple
* <em>package/class</em> hierarchy: such locations are described as
* <strong>package-oriented</strong>.
* Alternatively, the files may be organized in a <em>module/package/class</em>
* hierarchy: such locations are described as <strong>module-oriented</strong>.
* If a location is typically used to identify a place where a tool can write files,
* it is up to the tool that writes the files to specify how those files will be
* organized.
*
* <p>You can access the classes in a package-oriented location using methods like
* {@link JavaFileManager#getJavaFileForInput} or {@link JavaFileManager#list}.
* It is not possible to directly list the classes in a module-oriented
* location. Instead, you can get a package-oriented location for any specific module
* using methods like {@link JavaFileManager#getLocationForModule} or
* {@link JavaFileManager#listLocationsForModule}.
*/
interface Location {
/**
@ -119,30 +141,41 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
String getName();
/**
* Determines if this is an output location. An output
* location is a location that is conventionally used for
* Determines if this is an output location.
* An output location is a location that is conventionally used for
* output.
*
* @apiNote An output location may be used to write files in either
* a package-oriented organization or in a module-oriented organization.
*
* @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.
* Indicates if this location is module-oriented location, and therefore
* expected to contain classes in a <em>module/package/class</em>
* hierarchy, as compared to a package-oriented location, which
* is expected to contain classes in a <em>package/class</em> hierarchy.
* The result of this method is undefined if this is an output
* location.
*
* @implNote This implementation returns true if the name includes
* the word "MODULE".
*
* @return true if this location is expected to contain modules
* @since 9
*/
default boolean isModuleLocation() {
return false;
default boolean isModuleOrientedLocation() {
return getName().matches("\\bMODULE\\b");
}
}
/**
* Returns a class loader for loading plug-ins from the given
* location. For example, to load annotation processors, a
* compiler will request a class loader for the {@link
* package-oriented location.
* For example, to load annotation processors,
* a compiler will request a class loader for the {@link
* StandardLocation#ANNOTATION_PROCESSOR_PATH
* ANNOTATION_PROCESSOR_PATH} location.
*
@ -154,13 +187,14 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
* in the current security context
* @throws IllegalStateException if {@link #close} has been called
* and this file manager cannot be reopened
* @throws IllegalArgumentException if the location is a module-oriented location
*/
ClassLoader getClassLoader(Location location);
/**
* Lists all file objects matching the given criteria in the given
* location. List file objects in "subpackages" if recurse is
* true.
* package-oriented location.
* List file objects in "subpackages" if recurse is true.
*
* <p>Note: even if the given location is unknown to this file
* manager, it may not return {@code null}. Also, an unknown
@ -174,6 +208,7 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
* @throws IOException if an I/O error occurred, or if {@link
* #close} has been called and this file manager cannot be
* reopened
* @throws IllegalArgumentException if the location is a module-oriented location
* @throws IllegalStateException if {@link #close} has been called
* and this file manager cannot be reopened
*/
@ -184,14 +219,15 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
throws IOException;
/**
* Infers a binary name of a file object based on a location. The
* binary name returned might not be a valid binary name according to
* Infers a binary name of a file object based on a package-oriented location.
* The binary name returned might not be a valid binary name according to
* <cite>The Java&trade; Language Specification</cite>.
*
* @param location a location
* @param file a file object
* @return a binary name or {@code null} the file object is not
* found in the given location
* @throws IllegalArgumentException if the location is a module-oriented location
* @throws IllegalStateException if {@link #close} has been called
* and this file manager cannot be reopened
*/
@ -239,7 +275,7 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
/**
* Returns a {@linkplain JavaFileObject file object} for input
* representing the specified class of the specified kind in the
* given location.
* given package-oriented location.
*
* @param location a location
* @param className the name of a class
@ -250,7 +286,8 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
* file does not exist
* @throws IllegalArgumentException if the location is not known
* to this file manager and the file manager does not support
* unknown locations, or if the kind is not valid
* unknown locations, or if the kind is not valid, or if the
* location is a module-oriented location
* @throws IOException if an I/O error occurred, or if {@link
* #close} has been called and this file manager cannot be
* reopened
@ -265,7 +302,7 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
/**
* Returns a {@linkplain JavaFileObject file object} for output
* representing the specified class of the specified kind in the
* given location.
* given package-oriented location.
*
* <p>Optionally, this file manager might consider the sibling as
* a hint for where to place the output. The exact semantics of
@ -276,7 +313,7 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
* the originating source file as sibling when calling this
* method.
*
* @param location a location
* @param location a package-oriented location
* @param className the name of a class
* @param kind the kind of file, must be one of {@link
* JavaFileObject.Kind#SOURCE SOURCE} or {@link
@ -287,7 +324,8 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
* @throws IllegalArgumentException if sibling is not known to
* this file manager, or if the location is not known to this file
* manager and the file manager does not support unknown
* locations, or if the kind is not valid
* locations, or if the kind is not valid, or if the location is
* not an output location
* @throws IOException if an I/O error occurred, or if {@link
* #close} has been called and this file manager cannot be
* reopened
@ -303,7 +341,7 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
/**
* Returns a {@linkplain FileObject file object} for input
* representing the specified <a href="JavaFileManager.html#relative_name">relative
* name</a> in the specified package in the given location.
* name</a> in the specified package in the given package-oriented location.
*
* <p>If the returned object represents a {@linkplain
* JavaFileObject.Kind#SOURCE source} or {@linkplain
@ -325,14 +363,15 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
* a valid result would be a file object representing the file
* <code>"C:\Documents&nbsp;and&nbsp;Settings\UncleBob\src\share\classes\com\sun\tools\javac\resources\compiler.properties"</code>.
*
* @param location a location
* @param location a package-oriented location
* @param packageName a package name
* @param relativeName a relative name
* @return a file object, might return {@code null} if the file
* does not exist
* @throws IllegalArgumentException if the location is not known
* to this file manager and the file manager does not support
* unknown locations, or if {@code relativeName} is not valid
* unknown locations, or if {@code relativeName} is not valid,
* or if the location is a module-oriented location
* @throws IOException if an I/O error occurred, or if {@link
* #close} has been called and this file manager cannot be
* reopened
@ -368,7 +407,7 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
* relative name or next to the sibling argument. See {@link
* #getFileForInput getFileForInput} for an example.
*
* @param location a location
* @param location an output location
* @param packageName a package name
* @param relativeName a relative name
* @param sibling a file object to be used as hint for placement;
@ -377,7 +416,8 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
* @throws IllegalArgumentException if sibling is not known to
* this file manager, or if the location is not known to this file
* manager and the file manager does not support unknown
* locations, or if {@code relativeName} is not valid
* locations, or if {@code relativeName} is not valid,
* or if the location is not an output location
* @throws IOException if an I/O error occurred, or if {@link
* #close} has been called and this file manager cannot be
* reopened
@ -416,7 +456,12 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
void close() throws IOException;
/**
* Gets a location for a named module within a module-oriented location.
* Gets a location for a named module within a location, which may be either
* a module-oriented location or an output location.
* The result will be an output location if the given location is
* an output location, or it will be a package-oriented location.
*
* @implSpec This implementation throws {@code UnsupportedOperationException}.
*
* @param location the module-oriented location
* @param moduleName the name of the module to be found
@ -424,33 +469,49 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
*
* @throws IOException if an I/O error occurred
* @throws UnsupportedOperationException if this operation if not supported by this file manager
* @throws IllegalArgumentException if the location is neither an output location nor a
* module-oriented location
* @since 9
*/ // TODO: describe failure modes
default Location getModuleLocation(Location location, String moduleName) throws IOException {
default Location getLocationForModule(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.
* source or class, to be found in a module-oriented location.
* The result will be a package-oriented location.
*
* @param location a module-oriented location
* @apiNote the package name is used to identify the position of the file object
* within the <em>module/package/class</em> hierarchy identified by by the location.
*
* @implSpec This implementation throws {@code UnsupportedOperationException}.
*
* @param location the 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
* @throws IllegalArgumentException if the location is not a module-oriented location
* @since 9
*/ // TODO: describe failure modes
default Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
*/
default Location getLocationForModule(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
* If the location is a module-oriented location, the service loader will use the
* service declarations in the modules found in that location. Otherwise, a service loader
* is created using the package-oriented location, in which case, the services are
* determined using the provider-configuration files in {@code META-INF/services}.
*
* @implSpec This implementation throws {@code UnsupportedOperationException}.
*
* @param location the module-oriented 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
@ -465,13 +526,16 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
/**
* Infer the name of the module from its location, as returned by
* getModuleLocation or listModuleLocations.
* {@code getLocationForModule} or {@code listModuleLocations}.
*
* @param location a location representing a module
* @implSpec This implementation throws {@code UnsupportedOperationException}.
*
* @param location a package-oriented 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
* @throws IllegalArgumentException if the location is not one known to this file manager
* @since 9
*/ // TODO: describe failure modes
default String inferModuleName(Location location) throws IOException {
@ -479,16 +543,20 @@ public interface JavaFileManager extends Closeable, Flushable, OptionChecker {
}
/**
* Lists the modules in a module-oriented location.
* Lists the locations for all the modules in a module-oriented location.
* The locations that are returned will be package-oriented locations.
*
* @param location the location for which to list the modules
* @implSpec This implementation throws {@code UnsupportedOperationException}.
*
* @param location the module-oriented 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
* @throws IllegalArgumentException if the location is not a module-oriented location
* @since 9
*/ // TODO: describe failure modes
default Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
default Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
throw new UnsupportedOperationException();
}

View File

@ -109,7 +109,9 @@ public enum StandardLocation implements Location {
* property must hold: {@code locationFor(x) ==
* locationFor(y)} if and only if {@code x.equals(y)}.
* The returned location will be an output location if and only if
* name ends with {@code "_OUTPUT"}.
* name ends with {@code "_OUTPUT"}. It will be considered to
* be a module-oriented location if the name contains the word
* {@code "MODULE"}.
*
* @param name a name
* @return a location
@ -149,7 +151,7 @@ public enum StandardLocation implements Location {
}
@Override
public boolean isModuleLocation() {
public boolean isModuleOrientedLocation() {
switch (this) {
case MODULE_SOURCE_PATH:
case ANNOTATION_PROCESSOR_MODULE_PATH:

View File

@ -57,7 +57,7 @@ public class ToolProvider {
* {@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.
* and {@code null} otherwise.
*/
public static JavaCompiler getSystemJavaCompiler() {
return getSystemTool(JavaCompiler.class,
@ -78,7 +78,7 @@ public class ToolProvider {
* {@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.
* and {@code null} otherwise.
*/
public static DocumentationTool getSystemDocumentationTool() {
return getSystemTool(DocumentationTool.class,
@ -86,16 +86,19 @@ public class ToolProvider {
}
/**
* Returns the class loader for tools provided with this platform.
* This does not include user-installed tools. Use the
* {@linkplain java.util.ServiceLoader service provider mechanism}
* for locating user installed tools.
*
* @return the class loader for tools provided with this platform
* or {@code null} if no tools are provided
* Returns a class loader that may be used to load system tools,
* or {@code null} if no such special loader is provided.
* @implSpec This implementation always returns {@code null}.
* @deprecated This method is subject to removal in a future version of
* Java SE.
* Use the {@link java.util.spi.ToolProvider system tool provider} or
* {@link java.util.ServiceLoader service loader} mechanisms to
* locate system tools as well as user-installed tools.
* @return a class loader, or {@code null}
*/
@Deprecated
public static ClassLoader getSystemToolClassLoader() {
return ClassLoader.getSystemClassLoader();
return null;
}
private static final boolean useLegacy;

View File

@ -348,9 +348,9 @@ public class ClientCodeWrapper {
}
@Override @DefinedBy(Api.COMPILER)
public Location getModuleLocation(Location location, String moduleName) throws IOException {
public Location getLocationForModule(Location location, String moduleName) throws IOException {
try {
return clientJavaFileManager.getModuleLocation(location, moduleName);
return clientJavaFileManager.getLocationForModule(location, moduleName);
} catch (ClientCodeException e) {
throw e;
} catch (RuntimeException | Error e) {
@ -359,9 +359,9 @@ public class ClientCodeWrapper {
}
@Override @DefinedBy(Api.COMPILER)
public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
try {
return clientJavaFileManager.getModuleLocation(location, fo, pkgName);
return clientJavaFileManager.getLocationForModule(location, fo, pkgName);
} catch (ClientCodeException e) {
throw e;
} catch (RuntimeException | Error e) {
@ -381,9 +381,9 @@ public class ClientCodeWrapper {
}
@Override @DefinedBy(Api.COMPILER)
public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
try {
return clientJavaFileManager.listModuleLocations(location);
return clientJavaFileManager.listLocationsForModules(location);
} catch (ClientCodeException e) {
throw e;
} catch (RuntimeException | Error e) {

View File

@ -131,7 +131,7 @@ public class ModuleFinder {
if (outerIter.hasNext()) {
outer = outerIter.next();
try {
innerIter = fileManager.listModuleLocations(outer).iterator();
innerIter = fileManager.listLocationsForModules(outer).iterator();
} catch (IOException e) {
System.err.println("error listing module locations for " + outer + ": " + e); // FIXME
}
@ -282,7 +282,7 @@ public class ModuleFinder {
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());
msym.classLocation = fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT, msym.name.toString());
}
} else {
msym.classLocation = l;

View File

@ -364,7 +364,7 @@ public class Modules extends JCTree.Visitor {
if (msym.sourceLocation == null) {
msym.sourceLocation = locn;
if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
msym.classLocation = fileManager.getModuleLocation(
msym.classLocation = fileManager.getLocationForModule(
StandardLocation.CLASS_OUTPUT, msym.name.toString());
}
}
@ -466,7 +466,7 @@ public class Modules extends JCTree.Visitor {
private Location getModuleLocation(JavaFileObject fo, Name pkgName) throws IOException {
// For now, just check module source path.
// We may want to check source path as well.
return fileManager.getModuleLocation(StandardLocation.MODULE_SOURCE_PATH,
return fileManager.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH,
fo, (pkgName == null) ? null : pkgName.toString());
}

View File

@ -249,8 +249,11 @@ public abstract class BaseFileManager implements JavaFileManager {
return false;
}
if (!o.handleOption(helper, current, remaining))
throw new IllegalArgumentException(current);
try {
o.handleOption(helper, current, remaining);
} catch (Option.InvalidValueException e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
return true;
}

View File

@ -671,7 +671,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
@Override @DefinedBy(Api.COMPILER)
public ClassLoader getClassLoader(Location location) {
nullCheck(location);
checkNotModuleOrientedLocation(location);
Iterable<? extends File> path = getLocation(location);
if (path == null)
return null;
@ -694,6 +694,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
boolean recurse)
throws IOException
{
checkNotModuleOrientedLocation(location);
// validatePackageName(packageName);
nullCheck(packageName);
nullCheck(kinds);
@ -715,8 +716,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
@Override @DefinedBy(Api.COMPILER)
public String inferBinaryName(Location location, JavaFileObject file) {
checkNotModuleOrientedLocation(location);
Objects.requireNonNull(file);
Objects.requireNonNull(location);
// Need to match the path semantics of list(location, ...)
Iterable<? extends Path> path = getLocationAsPaths(location);
if (path == null) {
@ -750,7 +751,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
JavaFileObject.Kind kind)
throws IOException
{
nullCheck(location);
checkNotModuleOrientedLocation(location);
// validateClassName(className);
nullCheck(className);
nullCheck(kind);
@ -765,7 +766,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
String relativeName)
throws IOException
{
nullCheck(location);
checkNotModuleOrientedLocation(location);
// validatePackageName(packageName);
nullCheck(packageName);
if (!isRelativeUri(relativeName))
@ -798,7 +799,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
FileObject sibling)
throws IOException
{
nullCheck(location);
checkOutputLocation(location);
// validateClassName(className);
nullCheck(className);
nullCheck(kind);
@ -814,7 +815,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
FileObject sibling)
throws IOException
{
nullCheck(location);
checkOutputLocation(location);
// validatePackageName(packageName);
nullCheck(packageName);
if (!isRelativeUri(relativeName))
@ -948,10 +949,14 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
}
@Override @DefinedBy(Api.COMPILER)
public Location getModuleLocation(Location location, String moduleName) throws IOException {
nullCheck(location);
public Location getLocationForModule(Location location, String moduleName) throws IOException {
Objects.requireNonNull(location);
if (!location.isOutputLocation() && !location.isModuleOrientedLocation())
throw new IllegalArgumentException(
"location is not an output location or a module-oriented location: "
+ location.getName());
nullCheck(moduleName);
return locations.getModuleLocation(location, moduleName);
return locations.getLocationForModule(location, moduleName);
}
@Override @DefinedBy(Api.COMPILER)
@ -959,7 +964,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
nullCheck(location);
nullCheck(service);
Module.getModule(getClass()).addUses(service);
if (location.isModuleLocation()) {
if (location.isModuleOrientedLocation()) {
Collection<Path> paths = locations.getLocation(location);
ModuleFinder finder = ModuleFinder.of(paths.toArray(new Path[paths.size()]));
Layer bootLayer = Layer.boot();
@ -972,8 +977,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
}
@Override @DefinedBy(Api.COMPILER)
public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
nullCheck(location);
public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
checkModuleOrientedLocation(location);
if (!(fo instanceof PathFileObject))
throw new IllegalArgumentException(fo.getName());
int depth = 1; // allow 1 for filename
@ -993,7 +998,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
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);
return locations.getLocationForModule(location, dir);
} else {
return null;
}
@ -1001,14 +1006,14 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
@Override @DefinedBy(Api.COMPILER)
public String inferModuleName(Location location) {
nullCheck(location);
checkNotModuleOrientedLocation(location);
return locations.inferModuleName(location);
}
@Override @DefinedBy(Api.COMPILER)
public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
nullCheck(location);
return locations.listModuleLocations(location);
public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
checkModuleOrientedLocation(location);
return locations.listLocationsForModules(location);
}
@Override @DefinedBy(Api.COMPILER)
@ -1087,6 +1092,24 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
return e.toString();
}
private void checkOutputLocation(Location location) {
Objects.requireNonNull(location);
if (!location.isOutputLocation())
throw new IllegalArgumentException("location is not an output location: " + location.getName());
}
private void checkModuleOrientedLocation(Location location) {
Objects.requireNonNull(location);
if (!location.isModuleOrientedLocation())
throw new IllegalArgumentException("location is not module-oriented: " + location.getName());
}
private void checkNotModuleOrientedLocation(Location location) {
Objects.requireNonNull(location);
if (location.isModuleOrientedLocation())
throw new IllegalArgumentException("location is module-oriented: " + location.getName());
}
/* Converters between files and paths.
* These are temporary until we can update the StandardJavaFileManager API.
*/

View File

@ -415,16 +415,16 @@ public class Locations {
abstract void setPaths(Iterable<? extends Path> files) throws IOException;
/**
* @see JavaFileManager#getModuleLocation(Location, String)
* @see JavaFileManager#getLocationForModule(Location, String)
*/
Location getModuleLocation(String moduleName) throws IOException {
Location getLocationForModule(String moduleName) throws IOException {
return null;
}
/**
* @see JavaFileManager#getModuleLocation(Location, JavaFileObject, String)
* @see JavaFileManager#getLocationForModule(Location, JavaFileObject, String)
*/
Location getModuleLocation(Path dir) {
Location getLocationForModule(Path dir) {
return null;
}
@ -436,9 +436,9 @@ public class Locations {
}
/**
* @see JavaFileManager#listModuleLocations
* @see JavaFileManager#listLocationsForModules
*/
Iterable<Set<Location>> listModuleLocations() throws IOException {
Iterable<Set<Location>> listLocationsForModules() throws IOException {
return null;
}
}
@ -524,7 +524,7 @@ public class Locations {
}
@Override
Location getModuleLocation(String name) {
Location getLocationForModule(String name) {
if (moduleLocations == null)
moduleLocations = new HashMap<>();
Location l = moduleLocations.get(name);
@ -904,7 +904,7 @@ public class Locations {
}
@Override
Iterable<Set<Location>> listModuleLocations() {
Iterable<Set<Location>> listLocationsForModules() {
if (searchPath == null)
return Collections.emptyList();
@ -1320,17 +1320,17 @@ public class Locations {
}
@Override
Location getModuleLocation(String name) {
Location getLocationForModule(String name) {
return (moduleLocations == null) ? null : moduleLocations.get(name);
}
@Override
Location getModuleLocation(Path dir) {
Location getLocationForModule(Path dir) {
return (pathLocations == null) ? null : pathLocations.get(dir);
}
@Override
Iterable<Set<Location>> listModuleLocations() {
Iterable<Set<Location>> listLocationsForModules() {
if (moduleLocations == null)
return Collections.emptySet();
Set<Location> locns = new LinkedHashSet<>();
@ -1411,13 +1411,13 @@ public class Locations {
}
@Override
Location getModuleLocation(String name) throws IOException {
Location getLocationForModule(String name) throws IOException {
initSystemModules();
return systemModules.get(name);
}
@Override
Iterable<Set<Location>> listModuleLocations() throws IOException {
Iterable<Set<Location>> listLocationsForModules() throws IOException {
initSystemModules();
Set<Location> locns = new LinkedHashSet<>();
for (Location l: systemModules.values())
@ -1591,14 +1591,14 @@ public class Locations {
h.setPaths(files);
}
Location getModuleLocation(Location location, String name) throws IOException {
Location getLocationForModule(Location location, String name) throws IOException {
LocationHandler h = getHandler(location);
return (h == null ? null : h.getModuleLocation(name));
return (h == null ? null : h.getLocationForModule(name));
}
Location getModuleLocation(Location location, Path dir) {
Location getLocationForModule(Location location, Path dir) {
LocationHandler h = getHandler(location);
return (h == null ? null : h.getModuleLocation(dir));
return (h == null ? null : h.getLocationForModule(dir));
}
String inferModuleName(Location location) {
@ -1606,9 +1606,9 @@ public class Locations {
return (h == null ? null : h.inferModuleName());
}
Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
LocationHandler h = getHandler(location);
return (h == null ? null : h.listModuleLocations());
return (h == null ? null : h.listLocationsForModules());
}
protected LocationHandler getHandler(Location location) {

View File

@ -1626,7 +1626,7 @@ public class ClassWriter extends ClassFile {
Location outLocn;
if (multiModuleMode) {
ModuleSymbol msym = c.owner.kind == MDL ? (ModuleSymbol) c.owner : c.packge().modle;
outLocn = fileManager.getModuleLocation(CLASS_OUTPUT, msym.name.toString());
outLocn = fileManager.getLocationForModule(CLASS_OUTPUT, msym.name.toString());
} else {
outLocn = CLASS_OUTPUT;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -179,7 +179,7 @@ public class JNIWriter {
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());
outLocn = fileManager.getLocationForModule(StandardLocation.NATIVE_HEADER_OUTPUT, msym.name.toString());
} else {
outLocn = StandardLocation.NATIVE_HEADER_OUTPUT;
}

View File

@ -160,16 +160,6 @@ public class Arguments {
return ownName;
}
@Override
public void error(String key, Object... args) {
Arguments.this.error(key, args);
}
@Override
public void error(JCDiagnostic.Error error) {
Arguments.this.error(error);
}
@Override
public void addFile(Path p) {
files.add(p);
@ -221,11 +211,6 @@ public class Arguments {
options.remove(name);
}
@Override
public void error(String key, Object... args) {
Arguments.this.error(key, args);
}
@Override
public Log getLog() {
return Arguments.this.log;
@ -262,6 +247,17 @@ public class Arguments {
errorMode = ErrorMode.ILLEGAL_STATE;
}
/**
* Minimal initialization for tools, like javadoc,
* to be able to process javac options for themselves,
* and then call validate.
* @param ownName the name of this tool; used to prefix messages
*/
public void init(String ownName) {
this.ownName = ownName;
errorMode = ErrorMode.LOG;
}
/**
* Gets the files to be compiled.
* @return the files to be compiled
@ -379,7 +375,10 @@ public class Arguments {
}
if (option != null) {
if (!option.handleOption(helper, arg, argIter)) {
try {
option.handleOption(helper, arg, argIter);
} catch (Option.InvalidValueException e) {
error(e);
return false;
}
continue;
@ -416,11 +415,11 @@ public class Arguments {
java.util.List<String> modules = Arrays.asList(options.get(Option.MODULE).split(","));
try {
for (String module : modules) {
Location sourceLoc = fm.getModuleLocation(StandardLocation.MODULE_SOURCE_PATH, module);
Location sourceLoc = fm.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH, module);
if (sourceLoc == null) {
log.error(Errors.ModuleNotFoundInModuleSourcePath(module));
} else {
Location classLoc = fm.getModuleLocation(StandardLocation.CLASS_OUTPUT, module);
Location classLoc = fm.getLocationForModule(StandardLocation.CLASS_OUTPUT, module);
for (JavaFileObject file : fm.list(sourceLoc, "", EnumSet.of(JavaFileObject.Kind.SOURCE), true)) {
String className = fm.inferBinaryName(sourceLoc, file);
@ -446,24 +445,23 @@ public class Arguments {
// 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.MODULE))
|| options.isSet(Option.X)
|| options.isSet(Option.VERSION)
|| options.isSet(Option.FULLVERSION)
|| options.isSet(Option.MODULE)) {
return true;
if (emptyAllowed)
return true;
if (!errors) {
if (JavaCompiler.explicitAnnotationProcessingRequested(options)) {
error("err.no.source.files.classes");
} else {
error("err.no.source.files");
}
}
return false;
if (!emptyAllowed) {
if (!errors) {
if (JavaCompiler.explicitAnnotationProcessingRequested(options)) {
error("err.no.source.files.classes");
} else {
error("err.no.source.files");
}
}
return false;
}
}
if (!checkDirectory(Option.D)) {
@ -555,7 +553,6 @@ public class Arguments {
}
boolean lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option);
if (lintOptions && source.compareTo(Source.DEFAULT) < 0 && !options.isSet(Option.RELEASE)) {
if (fm instanceof BaseFileManager) {
if (((BaseFileManager) fm).isDefaultBootClassPath())
@ -710,7 +707,6 @@ public class Arguments {
for (String moduleName : addModules.split(",")) {
switch (moduleName) {
case "":
case "ALL-DEFAULT":
case "ALL-SYSTEM":
case "ALL-MODULE-PATH":
break;
@ -718,7 +714,7 @@ public class Arguments {
default:
if (!SourceVersion.isName(moduleName, sv)) {
// syntactically invalid module name: e.g. --add-modules m1,m!
log.warning(Warnings.BadNameForOption(Option.ADD_MODULES, moduleName));
log.error(Errors.BadNameForOption(Option.ADD_MODULES, moduleName));
}
break;
}
@ -742,7 +738,7 @@ public class Arguments {
default:
if (!SourceVersion.isName(moduleName, sv)) {
// syntactically invalid module name: e.g. --limit-modules m1,m!
log.warning(Warnings.BadNameForOption(Option.LIMIT_MODULES, moduleName));
log.error(Errors.BadNameForOption(Option.LIMIT_MODULES, moduleName));
}
break;
}
@ -757,7 +753,7 @@ public class Arguments {
public boolean isEmpty() {
return ((files == null) || files.isEmpty())
&& ((fileObjects == null) || fileObjects.isEmpty())
&& classNames.isEmpty();
&& (classNames == null || classNames.isEmpty());
}
public void allowEmpty() {
@ -886,6 +882,21 @@ public class Arguments {
}
}
void error(Option.InvalidValueException f) {
String msg = f.getMessage();
errors = true;
switch (errorMode) {
case ILLEGAL_ARGUMENT: {
throw new PropagatedException(new IllegalArgumentException(msg, f.getCause()));
}
case ILLEGAL_STATE: {
throw new PropagatedException(new IllegalStateException(msg, f.getCause()));
}
case LOG:
log.printRawLines(ownName + ": " + msg);
}
}
void warning(String key, Object... args) {
report(key, args);
}

View File

@ -194,7 +194,10 @@ public class Main {
@Override
public void put(String name, String value) { }
};
Option.HELP.process(h, "-help");
try {
Option.HELP.process(h, "-help");
} catch (Option.InvalidValueException ignore) {
}
return Result.CMDERR;
}

View File

@ -93,9 +93,8 @@ public enum Option {
G_NONE("-g:none", "opt.g.none", STANDARD, BASIC) {
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) {
helper.put("-g:", "none");
return false;
}
},
@ -138,11 +137,10 @@ public enum Option {
}
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) {
String prev = helper.get(XDOCLINT_CUSTOM);
String next = (prev == null) ? option : (prev + " " + option);
helper.put(XDOCLINT_CUSTOM.primaryName, next);
return false;
}
},
@ -154,20 +152,18 @@ public enum Option {
}
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) {
String prev = helper.get(XDOCLINT_PACKAGE);
String next = (prev == null) ? option : (prev + " " + option);
helper.put(XDOCLINT_PACKAGE.primaryName, next);
return false;
}
},
// -nowarn is retained for command-line backward compatibility
NOWARN("-nowarn", "opt.nowarn", STANDARD, BASIC) {
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) {
helper.put("-Xlint:none", option);
return false;
}
},
@ -176,9 +172,8 @@ public enum Option {
// -deprecation is retained for command-line backward compatibility
DEPRECATION("-deprecation", "opt.deprecation", STANDARD, BASIC) {
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) {
helper.put("-Xlint:deprecation", option);
return false;
}
},
@ -201,15 +196,13 @@ public enum Option {
// the the module=path pairs by an invalid path character, NULL.
// The standard file manager code knows to split apart the NULL-separated components.
@Override
public boolean process(OptionHelper helper, String option, String arg) {
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
if (arg.isEmpty()) {
helper.error("err.no.value.for.option", option);
return true;
throw helper.newInvalidValueException("err.no.value.for.option", option);
} else if (getPattern().matcher(arg).matches()) {
String prev = helper.get(PATCH_MODULE);
if (prev == null) {
super.process(helper, option, arg);
return false;
} else {
String argModulePackage = arg.substring(0, arg.indexOf('='));
boolean isRepeated = Arrays.stream(prev.split("\0"))
@ -217,16 +210,13 @@ public enum Option {
.collect(Collectors.toSet())
.contains(argModulePackage);
if (isRepeated) {
helper.error("err.repeated.value.for.patch.module", argModulePackage);
return true;
throw helper.newInvalidValueException("err.repeated.value.for.patch.module", argModulePackage);
} else {
super.process(helper, option, prev + '\0' + arg);
return false;
}
}
} else {
helper.error("err.bad.value.for.option", option, arg);
return true;
throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
}
}
@ -238,10 +228,10 @@ public enum Option {
BOOT_CLASS_PATH("--boot-class-path -bootclasspath", "opt.arg.path", "opt.bootclasspath", STANDARD, FILEMANAGER) {
@Override
public boolean process(OptionHelper helper, String option, String arg) {
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
helper.remove("-Xbootclasspath/p:");
helper.remove("-Xbootclasspath/a:");
return super.process(helper, option, arg);
super.process(helper, option, arg);
}
},
@ -251,10 +241,10 @@ public enum Option {
XBOOTCLASSPATH("-Xbootclasspath:", "opt.arg.path", "opt.bootclasspath", EXTENDED, FILEMANAGER) {
@Override
public boolean process(OptionHelper helper, String option, String arg) {
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
helper.remove("-Xbootclasspath/p:");
helper.remove("-Xbootclasspath/a:");
return super.process(helper, "-bootclasspath", arg);
super.process(helper, "-bootclasspath", arg);
}
},
@ -262,8 +252,8 @@ public enum Option {
DJAVA_EXT_DIRS("-Djava.ext.dirs=", "opt.arg.dirs", "opt.extdirs", EXTENDED, FILEMANAGER) {
@Override
public boolean process(OptionHelper helper, String option, String arg) {
return EXTDIRS.process(helper, "-extdirs", arg);
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
EXTDIRS.process(helper, "-extdirs", arg);
}
},
@ -271,8 +261,8 @@ public enum Option {
DJAVA_ENDORSED_DIRS("-Djava.endorsed.dirs=", "opt.arg.dirs", "opt.endorseddirs", EXTENDED, FILEMANAGER) {
@Override
public boolean process(OptionHelper helper, String option, String arg) {
return ENDORSEDDIRS.process(helper, "-endorseddirs", arg);
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
ENDORSEDDIRS.process(helper, "-endorseddirs", arg);
}
},
@ -298,25 +288,23 @@ public enum Option {
SOURCE("-source", "opt.arg.release", "opt.source", STANDARD, BASIC) {
@Override
public boolean process(OptionHelper helper, String option, String operand) {
public void process(OptionHelper helper, String option, String operand) throws InvalidValueException {
Source source = Source.lookup(operand);
if (source == null) {
helper.error("err.invalid.source", operand);
return true;
throw helper.newInvalidValueException("err.invalid.source", operand);
}
return super.process(helper, option, operand);
super.process(helper, option, operand);
}
},
TARGET("-target", "opt.arg.release", "opt.target", STANDARD, BASIC) {
@Override
public boolean process(OptionHelper helper, String option, String operand) {
public void process(OptionHelper helper, String option, String operand) throws InvalidValueException {
Target target = Target.lookup(operand);
if (target == null) {
helper.error("err.invalid.target", operand);
return true;
throw helper.newInvalidValueException("err.invalid.target", operand);
}
return super.process(helper, option, operand);
super.process(helper, option, operand);
}
},
@ -345,46 +333,45 @@ public enum Option {
PROFILE("-profile", "opt.arg.profile", "opt.profile", STANDARD, BASIC) {
@Override
public boolean process(OptionHelper helper, String option, String operand) {
public void process(OptionHelper helper, String option, String operand) throws InvalidValueException {
Profile profile = Profile.lookup(operand);
if (profile == null) {
helper.error("err.invalid.profile", operand);
return true;
throw helper.newInvalidValueException("err.invalid.profile", operand);
}
return super.process(helper, option, operand);
super.process(helper, option, operand);
}
},
VERSION("-version", "opt.version", STANDARD, INFO) {
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) throws InvalidValueException {
Log log = helper.getLog();
String ownName = helper.getOwnName();
log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "version", ownName, JavaCompiler.version());
return super.process(helper, option);
super.process(helper, option);
}
},
FULLVERSION("-fullversion", null, HIDDEN, INFO) {
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) throws InvalidValueException {
Log log = helper.getLog();
String ownName = helper.getOwnName();
log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "fullVersion", ownName, JavaCompiler.fullVersion());
return super.process(helper, option);
super.process(helper, option);
}
},
// Note: -h is already taken for "native header output directory".
HELP("--help -help", "opt.help", STANDARD, INFO) {
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) throws InvalidValueException {
Log log = helper.getLog();
String ownName = helper.getOwnName();
log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "msg.usage.header", ownName);
showHelp(log, OptionKind.STANDARD);
log.printNewline(WriterKind.STDOUT);
return super.process(helper, option);
super.process(helper, option);
}
},
@ -401,31 +388,28 @@ public enum Option {
// Mapping for processor options created in
// JavacProcessingEnvironment
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) throws InvalidValueException {
int argLength = option.length();
if (argLength == 2) {
helper.error("err.empty.A.argument");
return true;
throw helper.newInvalidValueException("err.empty.A.argument");
}
int sepIndex = option.indexOf('=');
String key = option.substring(2, (sepIndex != -1 ? sepIndex : argLength) );
if (!JavacProcessingEnvironment.isValidOptionName(key)) {
helper.error("err.invalid.A.key", option);
return true;
throw helper.newInvalidValueException("err.invalid.A.key", option);
}
helper.put(option, option);
return false;
}
},
X("-X", "opt.X", STANDARD, INFO) {
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) throws InvalidValueException {
Log log = helper.getLog();
showHelp(log, OptionKind.EXTENDED);
log.printNewline(WriterKind.STDOUT);
log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "msg.usage.nonstandard.footer");
return super.process(helper, option);
super.process(helper, option);
}
},
@ -433,16 +417,16 @@ public enum Option {
// It's actually implemented by the launcher.
J("-J", "opt.arg.flag", "opt.J", STANDARD, INFO, ArgKind.ADJACENT) {
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) {
throw new AssertionError("the -J flag should be caught by the launcher.");
}
},
MOREINFO("-moreinfo", null, HIDDEN, BASIC) {
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) throws InvalidValueException {
Type.moreInfo = true;
return super.process(helper, option);
super.process(helper, option);
}
},
@ -462,9 +446,8 @@ public enum Option {
// display warnings for generic unchecked operations
WARNUNCHECKED("-warnunchecked", null, HIDDEN, BASIC) {
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) {
helper.put("-Xlint:unchecked", option);
return false;
}
},
@ -474,15 +457,14 @@ public enum Option {
XSTDOUT("-Xstdout", "opt.arg.file", "opt.Xstdout", EXTENDED, INFO) {
@Override
public boolean process(OptionHelper helper, String option, String arg) {
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
try {
Log log = helper.getLog();
log.setWriters(new PrintWriter(new FileWriter(arg), true));
} catch (java.io.IOException e) {
helper.error("err.error.writing.file", arg, e);
return true;
throw helper.newInvalidValueException("err.error.writing.file", arg, e);
}
return super.process(helper, option, arg);
super.process(helper, option, arg);
}
},
@ -507,11 +489,10 @@ public enum Option {
PLUGIN("-Xplugin:", "opt.arg.plugin", "opt.plugin", EXTENDED, BASIC) {
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) {
String p = option.substring(option.indexOf(':') + 1).trim();
String prev = helper.get(PLUGIN);
helper.put(PLUGIN.primaryName, (prev == null) ? p : prev + '\0' + p);
return false;
}
},
@ -519,22 +500,22 @@ public enum Option {
DEBUG("--debug:", null, HIDDEN, BASIC) {
@Override
public boolean process(OptionHelper helper, String option) {
return HiddenGroup.DEBUG.process(helper, option);
public void process(OptionHelper helper, String option) throws InvalidValueException {
HiddenGroup.DEBUG.process(helper, option);
}
},
SHOULDSTOP("--should-stop:", null, HIDDEN, BASIC) {
@Override
public boolean process(OptionHelper helper, String option) {
return HiddenGroup.SHOULDSTOP.process(helper, option);
public void process(OptionHelper helper, String option) throws InvalidValueException {
HiddenGroup.SHOULDSTOP.process(helper, option);
}
},
DIAGS("--diags:", null, HIDDEN, BASIC) {
@Override
public boolean process(OptionHelper helper, String option) {
return HiddenGroup.DIAGS.process(helper, option);
public void process(OptionHelper helper, String option) throws InvalidValueException {
HiddenGroup.DIAGS.process(helper, option);
}
},
@ -548,33 +529,29 @@ public enum Option {
return s.startsWith(primaryName);
}
@Override
public boolean process(OptionHelper helper, String option) {
return process(helper, option, option.substring(primaryName.length()));
public void process(OptionHelper helper, String option) {
process(helper, option, option.substring(primaryName.length()));
}
@Override
public boolean process(OptionHelper helper, String option, String arg) {
public void process(OptionHelper helper, String option, String arg) {
int eq = arg.indexOf('=');
String key = (eq < 0) ? arg : arg.substring(0, eq);
String value = (eq < 0) ? arg : arg.substring(eq+1);
helper.put(key, value);
return false;
}
},
ADD_EXPORTS("--add-exports", "opt.arg.addExports", "opt.addExports", EXTENDED, BASIC) {
@Override
public boolean process(OptionHelper helper, String option, String arg) {
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
if (arg.isEmpty()) {
helper.error("err.no.value.for.option", option);
return true;
throw helper.newInvalidValueException("err.no.value.for.option", option);
} else if (getPattern().matcher(arg).matches()) {
String prev = helper.get(ADD_EXPORTS);
helper.put(ADD_EXPORTS.primaryName, (prev == null) ? arg : prev + '\0' + arg);
return false;
} else {
helper.error("err.bad.value.for.option", option, arg);
return true;
throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
}
}
@ -586,17 +563,14 @@ public enum Option {
ADD_READS("--add-reads", "opt.arg.addReads", "opt.addReads", EXTENDED, BASIC) {
@Override
public boolean process(OptionHelper helper, String option, String arg) {
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
if (arg.isEmpty()) {
helper.error("err.no.value.for.option", option);
return true;
throw helper.newInvalidValueException("err.no.value.for.option", option);
} else if (getPattern().matcher(arg).matches()) {
String prev = helper.get(ADD_READS);
helper.put(ADD_READS.primaryName, (prev == null) ? arg : prev + '\0' + arg);
return false;
} else {
helper.error("err.bad.value.for.option", option, arg);
return true;
throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
}
}
@ -608,14 +582,12 @@ public enum Option {
XMODULE("-Xmodule:", "opt.arg.module", "opt.module", EXTENDED, BASIC) {
@Override
public boolean process(OptionHelper helper, String option, String arg) {
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
String prev = helper.get(XMODULE);
if (prev != null) {
helper.error("err.option.too.many", XMODULE.primaryName);
return true;
throw helper.newInvalidValueException("err.option.too.many", XMODULE.primaryName);
}
helper.put(XMODULE.primaryName, arg);
return false;
}
},
@ -623,19 +595,16 @@ public enum Option {
ADD_MODULES("--add-modules", "opt.arg.addmods", "opt.addmods", STANDARD, BASIC) {
@Override
public boolean process(OptionHelper helper, String option, String arg) {
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
if (arg.isEmpty()) {
helper.error("err.no.value.for.option", option);
return true;
throw helper.newInvalidValueException("err.no.value.for.option", option);
} else if (getPattern().matcher(arg).matches()) {
String prev = helper.get(ADD_MODULES);
// since the individual values are simple names, we can simply join the
// values of multiple --add-modules options with ','
helper.put(ADD_MODULES.primaryName, (prev == null) ? arg : prev + ',' + arg);
return false;
} else {
helper.error("err.bad.value.for.option", option, arg);
return true;
throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
}
}
@ -647,16 +616,13 @@ public enum Option {
LIMIT_MODULES("--limit-modules", "opt.arg.limitmods", "opt.limitmods", STANDARD, BASIC) {
@Override
public boolean process(OptionHelper helper, String option, String arg) {
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
if (arg.isEmpty()) {
helper.error("err.no.value.for.option", option);
return true;
throw helper.newInvalidValueException("err.no.value.for.option", option);
} else if (getPattern().matcher(arg).matches()) {
helper.put(LIMIT_MODULES.primaryName, arg); // last one wins
return false;
} else {
helper.error("err.bad.value.for.option", option, arg);
return true;
throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
}
}
@ -670,7 +636,7 @@ public enum Option {
// It's actually implemented by the CommandLine class.
AT("@", "opt.arg.file", "opt.AT", STANDARD, INFO, ArgKind.ADJACENT) {
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) {
throw new AssertionError("the @ flag should be caught by CommandLine.");
}
},
@ -690,22 +656,19 @@ public enum Option {
}
}
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) throws InvalidValueException {
if (option.endsWith(".java") ) {
Path p = Paths.get(option);
if (!Files.exists(p)) {
helper.error("err.file.not.found", p);
return true;
throw helper.newInvalidValueException("err.file.not.found", p);
}
if (!Files.isRegularFile(p)) {
helper.error("err.file.not.file", p);
return true;
throw helper.newInvalidValueException("err.file.not.file", p);
}
helper.addFile(p);
} else {
helper.addClassName(option);
}
return false;
}
},
@ -714,24 +677,44 @@ public enum Option {
INHERIT_RUNTIME_ENVIRONMENT("--inherit-runtime-environment", "opt.inherit_runtime_environment",
EXTENDED, BASIC) {
@Override
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) throws InvalidValueException {
try {
Class.forName(JDK9Wrappers.VMHelper.VM_CLASSNAME);
String[] runtimeArgs = JDK9Wrappers.VMHelper.getRuntimeArguments();
for (String arg : runtimeArgs) {
System.err.println("runtime arg: " + arg);
// Handle any supported runtime options; ignore all others.
// The runtime arguments always use the single token form, e.g. "--name=value".
for (Option o : getSupportedRuntimeOptions()) {
if (o.matches(arg)) {
o.handleOption(helper, arg, Collections.emptyIterator());
switch (o) {
case ADD_MODULES:
int eq = arg.indexOf('=');
Assert.check(eq > 0, () -> ("invalid runtime option:" + arg));
// --add-modules=ALL-DEFAULT is not supported at compile-time
// so remove it from list, and only process the rest
// if the set is non-empty.
// Note that --add-modules=ALL-DEFAULT is automatically added
// by the standard javac launcher.
String mods = Arrays.stream(arg.substring(eq + 1).split(","))
.filter(s -> !s.isEmpty() && !s.equals("ALL-DEFAULT"))
.collect(Collectors.joining(","));
if (!mods.isEmpty()) {
String updatedArg = arg.substring(0, eq + 1) + mods;
o.handleOption(helper, updatedArg, Collections.emptyIterator());
}
break;
default:
o.handleOption(helper, arg, Collections.emptyIterator());
break;
}
break;
}
}
}
} catch (ClassNotFoundException | SecurityException e) {
helper.error("err.cannot.access.runtime.env");
throw helper.newInvalidValueException("err.cannot.access.runtime.env");
}
return false;
}
private Option[] getSupportedRuntimeOptions() {
@ -747,6 +730,23 @@ public enum Option {
}
};
/**
* This exception is thrown when an invalid value is given for an option.
* The detail string gives a detailed, localized message, suitable for use
* in error messages reported to the user.
*/
public static class InvalidValueException extends Exception {
private static final long serialVersionUID = -1;
public InvalidValueException(String msg) {
super(msg);
}
public InvalidValueException(String msg, Throwable cause) {
super(msg, cause);
}
}
/**
* The kind of argument, if any, accepted by this option. The kind is augmented
* by characters in the name of the option.
@ -831,14 +831,13 @@ public enum Option {
this.text = text;
}
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) throws InvalidValueException {
String p = option.substring(option.indexOf(':') + 1).trim();
String[] subOptions = p.split(";");
for (String subOption : subOptions) {
subOption = text + "." + subOption.trim();
XD.process(helper, subOption, subOption);
}
return false;
}
static boolean skip(String name) {
@ -1038,7 +1037,7 @@ public enum Option {
* @return true if the operation was successful, and false otherwise
* @implNote The return value is the opposite of that used by {@link #process}.
*/
public boolean handleOption(OptionHelper helper, String arg, Iterator<String> rest) {
public void handleOption(OptionHelper helper, String arg, Iterator<String> rest) throws InvalidValueException {
if (hasArg()) {
String option;
String operand;
@ -1051,15 +1050,14 @@ public enum Option {
operand = arg.substring(sep + 1);
} else {
if (!rest.hasNext()) {
helper.error("err.req.arg", arg);
return false;
throw helper.newInvalidValueException("err.req.arg", arg);
}
option = arg;
operand = rest.next();
}
return !process(helper, option, operand);
process(helper, option, operand);
} else {
return !process(helper, arg);
process(helper, arg);
}
}
@ -1068,14 +1066,14 @@ public enum Option {
* or which contains an argument within it, following a separator.
* @param helper a helper to provide access to the environment
* @param option the option to be processed
* @return true if an error occurred
* @throws InvalidValueException if an error occurred
*/
public boolean process(OptionHelper helper, String option) {
public void process(OptionHelper helper, String option) throws InvalidValueException {
if (argKind == ArgKind.NONE) {
return process(helper, primaryName, option);
process(helper, primaryName, option);
} else {
int sep = findSeparator(option);
return process(helper, primaryName, option.substring(sep + 1));
process(helper, primaryName, option.substring(sep + 1));
}
}
@ -1085,9 +1083,8 @@ public enum Option {
* @param option the option to be processed
* @param arg the value to associate with the option, or a default value
* to be used if the option does not otherwise take an argument.
* @return true if an error occurred
*/
public boolean process(OptionHelper helper, String option, String arg) {
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
if (choices != null) {
if (choiceKind == ChoiceKind.ONEOF) {
// some clients like to see just one of option+choice set
@ -1110,7 +1107,6 @@ public enum Option {
helper.put(primaryName, arg);
if (group == OptionGroup.FILEMANAGER)
helper.handleFileManagerOption(this, arg);
return false;
}
/**

View File

@ -43,29 +43,55 @@ import com.sun.tools.javac.util.Log.PrefixKind;
public abstract class OptionHelper {
/** Get the current value of an option. */
/**
* Get the current value of an option.
* @param option the option
* @return the value of the option
*/
public abstract String get(Option option);
/** Set the value of an option. */
/**
* Set the value of an option.
* @param name the primary name of the option
* @param value the value for the option
*/
public abstract void put(String name, String value);
/** Remove any prior value for an option. */
/**
* Remove any prior value for an option.
* @param name the primary name of the option
*/
public abstract void remove(String name);
/** Handle a file manager option. */
/**
* Handle a file manager option.
* @param option the option
* @param value the value for the option
* @return true if the option was handled successfully, and false otherwise
*/
public abstract boolean handleFileManagerOption(Option option, String value);
/** Get access to the Log for the compilation. */
/**
* Get access to the Log for the compilation.
* @return the log
*/
public abstract Log getLog();
/** Get the name of the tool, such as "javac", to be used in info like -help. */
/**
* Get the name of the tool, such as "javac", to be used in info like -help.
* @return the name of the tool
*/
public abstract String getOwnName();
/** Report an error. */
abstract void error(String key, Object... args);
/** Report an error. */
abstract void error(JCDiagnostic.Error error);
/**
* Returns a new InvalidValueException, with a localized detail message.
* @param key the resource key for the message
* @param args the arguments, if any, for the resource string
* @return the InvalidValueException
*/
Option.InvalidValueException newInvalidValueException(String key, Object... args) {
return new Option.InvalidValueException(getLog().localize(PrefixKind.JAVAC, key, args));
}
/** Record a file to be compiled. */
abstract void addFile(Path p);
@ -111,16 +137,6 @@ public abstract class OptionHelper {
throw new IllegalArgumentException();
}
@Override
void error(String key, Object... args) {
throw new IllegalArgumentException(log.localize(PrefixKind.JAVAC, key, args));
}
@Override
void error(JCDiagnostic.Error error) {
throw new IllegalArgumentException(log.localize(error));
}
@Override
public void addFile(Path p) {
throw new IllegalArgumentException(p.toString());

View File

@ -2848,6 +2848,10 @@ compiler.err.duplicate.module.on.path=\
compiler.warn.bad.name.for.option=\
bad name in value for {0} option: ''{1}''
# 0: option name, 1: string
compiler.err.bad.name.for.option=\
bad name in value for {0} option: ''{1}''
# 0: option name, 1: symbol
compiler.warn.module.for.option.not.found=\
module name in {0} option not found: {1}

View File

@ -204,8 +204,8 @@ public class SmartFileManager extends ForwardingJavaFileManager<JavaFileManager>
}
@Override @DefinedBy(Api.COMPILER)
public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
return super.getModuleLocation(location, locUnwrap(fo), pkgName);
public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
return super.getLocationForModule(location, locUnwrap(fo), pkgName);
}
private static String packageNameFromFileName(String fn) {

View File

@ -246,7 +246,7 @@ public class JavadocFormatter {
@Override @DefinedBy(Api.COMPILER_TREE)
public Object visitStartElement(StartElementTree node, Object p) {
switch (HtmlTag.get(node.getName())) {
switch (getHtmlTag(node.getName())) {
case P:
if (lastNode!= null && lastNode.getKind() == DocTree.Kind.START_ELEMENT &&
HtmlTag.get(((StartElementTree) lastNode).getName()) == HtmlTag.LI) {
@ -397,7 +397,7 @@ public class JavadocFormatter {
}
private void handleEndElement(Name name) {
switch (HtmlTag.get(name)) {
switch (getHtmlTag(name)) {
case BLOCKQUOTE:
indent -= INDENT;
break;
@ -629,6 +629,12 @@ public class JavadocFormatter {
}
}
private static HtmlTag getHtmlTag(Name name) {
HtmlTag tag = HtmlTag.get(name);
return tag != null ? tag : HtmlTag.HTML; //using HtmlTag.HTML as default no-op value
}
private static Map<StartElementTree, Integer> countTableColumns(DocCommentTree dct) {
Map<StartElementTree, Integer> result = new IdentityHashMap<>();
@ -639,7 +645,7 @@ public class JavadocFormatter {
@Override @DefinedBy(Api.COMPILER_TREE)
public Void visitStartElement(StartElementTree node, Void p) {
switch (HtmlTag.get(node.getName())) {
switch (getHtmlTag(node.getName())) {
case TABLE: currentTable = node; break;
case TR:
currentMaxColumns = Math.max(currentMaxColumns, currentRowColumns);

View File

@ -393,7 +393,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
for (ModuleSymbol msym : modules.allModules()) {
PackageSymbol p = syms.getPackage(msym, pack);
if (p != null && !p.members().isEmpty()) {
return fm.getModuleLocation(location, msym.name.toString());
return fm.getLocationForModule(location, msym.name.toString());
}
}

View File

@ -45,6 +45,7 @@ import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.main.CommandLine;
import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.file.BaseFileManager;
import com.sun.tools.javac.main.Arguments;
import com.sun.tools.javac.main.OptionHelper;
import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
import com.sun.tools.javac.platform.PlatformDescription;
@ -309,12 +310,16 @@ public class Start extends ToolOption.Helper {
if (o == ToolOption.LOCALE && i > 0)
usageError("main.locale_first");
if (o.hasArg) {
oneArg(argv, i++);
o.process(this, argv[i]);
} else {
setOption(arg);
o.process(this);
try {
if (o.hasArg) {
oneArg(argv, i++);
o.process(this, argv[i]);
} else {
setOption(arg);
o.process(this);
}
} catch (Option.InvalidValueException e) {
usageError("main.option.invalid.value", e.getMessage());
}
} else if (arg.equals("-XDaccessInternalAPI")) {
// pass this hidden option down to the doclet, if it wants it
@ -367,6 +372,11 @@ public class Start extends ToolOption.Helper {
((BaseFileManager) fileManager).handleOptions(fileManagerOpts);
}
Arguments arguments = Arguments.instance(context);
arguments.init(messager.programName);
arguments.allowEmpty();
arguments.validate();
String platformString = compOpts.get("--release");
if (platformString != null) {
@ -560,7 +570,7 @@ public class Start extends ToolOption.Helper {
@Override
OptionHelper getOptionHelper() {
return new GrumpyHelper(null) {
return new GrumpyHelper(messager) {
@Override
public String get(com.sun.tools.javac.main.Option option) {
return compOpts.get(option);

View File

@ -31,6 +31,7 @@ import java.util.StringTokenizer;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.main.Option.InvalidValueException;
import com.sun.tools.javac.main.OptionHelper;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Options;
@ -141,14 +142,14 @@ public enum ToolOption {
ADD_MODULES("--add-modules", true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.ADD_MODULES.process(helper.getOptionHelper(), opt, arg);
}
},
LIMIT_MODULES("--limit-modules", true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.LIMIT_MODULES.process(helper.getOptionHelper(), opt, arg);
}
},
@ -191,28 +192,28 @@ public enum ToolOption {
ADD_READS("--add-reads", true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.ADD_READS.process(helper.getOptionHelper(), opt, arg);
}
},
ADD_EXPORTS("--add-exports", true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.ADD_EXPORTS.process(helper.getOptionHelper(), opt, arg);
}
},
XMODULE("-Xmodule:", false) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.XMODULE.process(helper.getOptionHelper(), arg);
}
},
PATCH_MODULE("--patch-module", true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.PATCH_MODULE.process(helper.getOptionHelper(), opt, arg);
}
},
@ -356,7 +357,7 @@ public enum ToolOption {
this.hasArg = hasArg;
}
void process(Helper helper, String arg) { }
void process(Helper helper, String arg) throws Option.InvalidValueException { }
void process(Helper helper) { }

View File

@ -126,6 +126,7 @@ main.illegal_package_name=Illegal package name: "{0}"
main.release.bootclasspath.conflict=option {0} cannot be used together with -release
main.unsupported.release.version=release version {0} not supported
main.release.not.standard.file.manager=-release option specified, but the provided JavaFileManager is not a StandardJavaFileManager.
main.option.invalid.value={0}
tag.illegal_char_in_arr_dim=Tag {0}: Syntax Error in array dimension, method parameters: {1}
tag.illegal_see_tag=Tag {0}: Syntax Error in method parameters: {1}
tag.missing_comma_space=Tag {0}: Missing comma or space in method parameters: {1}

View File

@ -166,6 +166,7 @@ public class IndexBuilder {
adjustIndexMap(utils.getFields(te));
adjustIndexMap(utils.getMethods(te));
adjustIndexMap(utils.getConstructors(te));
adjustIndexMap(utils.getEnumConstants(te));
}

View File

@ -816,7 +816,7 @@ public class ElementsTable {
private Location getModuleLocation(Location location, String msymName)
throws ToolException {
try {
return fm.getModuleLocation(location, msymName);
return fm.getLocationForModule(location, msymName);
} catch (IOException ioe) {
String text = messager.getText("main.doclet_could_not_get_location", msymName);
throw new ToolException(ERROR, text, ioe);

View File

@ -51,6 +51,7 @@ import javax.tools.StandardLocation;
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.file.BaseFileManager;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.main.Arguments;
import com.sun.tools.javac.main.CommandLine;
import com.sun.tools.javac.main.OptionHelper;
import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
@ -59,6 +60,7 @@ import com.sun.tools.javac.platform.PlatformUtils;
import com.sun.tools.javac.util.ClientCodeException;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Log.WriterKind;
import com.sun.tools.javac.util.Options;
import jdk.javadoc.doclet.Doclet;
@ -325,9 +327,14 @@ public class Start extends ToolOption.Helper {
if (argv.length > 0 && "-Xold".equals(argv[0])) {
warn("main.legacy_api");
String[] nargv = Arrays.copyOfRange(argv, 1, argv.length);
return com.sun.tools.javadoc.Main.execute(nargv) == 0
? OK
: ERROR;
int rc = com.sun.tools.javadoc.Main.execute(
messager.programName,
messager.getWriter(WriterKind.ERROR),
messager.getWriter(WriterKind.WARNING),
messager.getWriter(WriterKind.NOTICE),
"com.sun.tools.doclets.standard.Standard",
nargv);
return (rc == 0) ? OK : ERROR;
}
return begin(Arrays.asList(argv), Collections.<JavaFileObject> emptySet());
}
@ -400,9 +407,14 @@ public class Start extends ToolOption.Helper {
}
warn("main.legacy_api");
String[] array = options.toArray(new String[options.size()]);
return com.sun.tools.javadoc.Main.execute(array) == 0
? OK
: ERROR;
int rc = com.sun.tools.javadoc.Main.execute(
messager.programName,
messager.getWriter(WriterKind.ERROR),
messager.getWriter(WriterKind.WARNING),
messager.getWriter(WriterKind.NOTICE),
"com.sun.tools.doclets.standard.Standard",
array);
return (rc == 0) ? OK : ERROR;
}
Result result = OK;
@ -410,6 +422,11 @@ public class Start extends ToolOption.Helper {
result = parseAndExecute(options, fileObjects)
? OK
: ERROR;
} catch (com.sun.tools.javac.main.Option.InvalidValueException e) {
messager.printError(e.getMessage());
Throwable t = e.getCause();
dumpStack(t == null ? e : t);
return ERROR;
} catch (OptionException toe) {
if (toe.message != null)
messager.printError(toe.message);
@ -482,8 +499,8 @@ public class Start extends ToolOption.Helper {
* Main program - internal
*/
@SuppressWarnings("unchecked")
private boolean parseAndExecute(List<String> argList,
Iterable<? extends JavaFileObject> fileObjects) throws ToolException, OptionException {
private boolean parseAndExecute(List<String> argList, Iterable<? extends JavaFileObject> fileObjects)
throws ToolException, OptionException, com.sun.tools.javac.main.Option.InvalidValueException {
long tm = System.currentTimeMillis();
List<String> javaNames = new ArrayList<>();
@ -491,11 +508,19 @@ public class Start extends ToolOption.Helper {
compOpts = Options.instance(context);
// Make sure no obsolete source/target messages are reported
com.sun.tools.javac.main.Option.XLINT.process(getOptionHelper(), "-Xlint:-options");
try {
com.sun.tools.javac.main.Option.XLINT_CUSTOM.process(getOptionHelper(), "-Xlint:-options");
} catch (com.sun.tools.javac.main.Option.InvalidValueException ignore) {
}
doclet.init(locale, messager);
parseArgs(argList, javaNames);
Arguments arguments = Arguments.instance(context);
arguments.init(ProgramName);
arguments.allowEmpty();
arguments.validate();
if (fileManager instanceof BaseFileManager) {
((BaseFileManager) fileManager).handleOptions(fileManagerOpts);
}
@ -805,7 +830,7 @@ public class Start extends ToolOption.Helper {
}
private void parseArgs(List<String> args, List<String> javaNames) throws ToolException,
OptionException {
OptionException, com.sun.tools.javac.main.Option.InvalidValueException {
for (int i = 0 ; i < args.size() ; i++) {
String arg = args.get(i);
ToolOption o = ToolOption.get(arg);
@ -929,7 +954,7 @@ public class Start extends ToolOption.Helper {
@Override
OptionHelper getOptionHelper() {
return new GrumpyHelper(null) {
return new GrumpyHelper(messager) {
@Override
public String get(com.sun.tools.javac.main.Option option) {
return compOpts.get(option);

View File

@ -35,6 +35,7 @@ import java.util.Map;
import javax.lang.model.element.ElementKind;
import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.main.Option.InvalidValueException;
import com.sun.tools.javac.main.Option.OptionKind;
import com.sun.tools.javac.main.OptionHelper;
import com.sun.tools.javac.util.Options;
@ -56,70 +57,70 @@ public enum ToolOption {
BOOTCLASSPATH("-bootclasspath", STANDARD, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.BOOT_CLASS_PATH.process(helper.getOptionHelper(), primaryName, arg);
}
},
CLASS_PATH("--class-path -classpath -cp", STANDARD, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.CLASS_PATH.process(helper.getOptionHelper(), primaryName, arg);
}
},
EXTDIRS("-extdirs", STANDARD, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.EXTDIRS.process(helper.getOptionHelper(), primaryName, arg);
}
},
SOURCE_PATH("--source-path -sourcepath", STANDARD, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.SOURCE_PATH.process(helper.getOptionHelper(), primaryName, arg);
}
},
MODULE_SOURCE_PATH("--module-source-path", STANDARD, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.MODULE_SOURCE_PATH.process(helper.getOptionHelper(), primaryName, arg);
}
},
UPGRADE_MODULE_PATH("--upgrade-module-path", STANDARD, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.UPGRADE_MODULE_PATH.process(helper.getOptionHelper(), primaryName, arg);
}
},
SYSTEM("--system", STANDARD, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.SYSTEM.process(helper.getOptionHelper(), primaryName, arg);
}
},
MODULE_PATH("--module-path -p", STANDARD, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.MODULE_PATH.process(helper.getOptionHelper(), primaryName, arg);
}
},
ADD_MODULES("--add-modules", STANDARD, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.ADD_MODULES.process(helper.getOptionHelper(), primaryName, arg);
}
},
LIMIT_MODULES("--limit-modules", STANDARD, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.LIMIT_MODULES.process(helper.getOptionHelper(), primaryName, arg);
}
},
@ -133,63 +134,63 @@ public enum ToolOption {
ENCODING("-encoding", STANDARD, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.ENCODING.process(helper.getOptionHelper(), primaryName, arg);
}
},
RELEASE("--release", STANDARD, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.RELEASE.process(helper.getOptionHelper(), primaryName, arg);
}
},
SOURCE("-source", STANDARD, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.SOURCE.process(helper.getOptionHelper(), primaryName, arg);
}
},
XMAXERRS("-Xmaxerrs", EXTENDED, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.XMAXERRS.process(helper.getOptionHelper(), primaryName, arg);
}
},
XMAXWARNS("-Xmaxwarns", EXTENDED, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.XMAXWARNS.process(helper.getOptionHelper(), primaryName, arg);
}
},
ADD_READS("--add-reads", EXTENDED, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.ADD_READS.process(helper.getOptionHelper(), primaryName, arg);
}
},
ADD_EXPORTS("--add-exports", EXTENDED, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.ADD_EXPORTS.process(helper.getOptionHelper(), primaryName, arg);
}
},
XMODULE("-Xmodule:", EXTENDED, false) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.XMODULE.process(helper.getOptionHelper(), arg);
}
},
PATCH_MODULE("--patch-module", EXTENDED, true) {
@Override
public void process(Helper helper, String arg) {
public void process(Helper helper, String arg) throws InvalidValueException {
Option.PATCH_MODULE.process(helper.getOptionHelper(), primaryName, arg);
}
},
@ -388,7 +389,7 @@ public enum ToolOption {
this.hasSuffix = lastChar == ':' || lastChar == '=';
}
void process(Helper helper, String arg) throws OptionException { }
void process(Helper helper, String arg) throws OptionException, Option.InvalidValueException { }
void process(Helper helper) throws OptionException { }

View File

@ -910,7 +910,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
StandardLocation.MODULE_PATH
};
for (Location segment: locns) {
for (Set<Location> set: fileManager.listModuleLocations(segment)) {
for (Set<Location> set: fileManager.listLocationsForModules(segment)) {
Location result = null;
for (Location l: set) {
String name = fileManager.inferModuleName(l);

View File

@ -537,8 +537,9 @@ class JdepsTask {
config.splitPackages().entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.forEach(e -> System.out.format("split package: %s %s%n", e.getKey(),
e.getValue().toString()));
.forEach(e -> log.println(getMessage("split.package",
e.getKey(),
e.getValue().toString())));
// check if any module specified in --require is missing
Stream.concat(options.addmods.stream(), options.requires.stream())
@ -745,8 +746,12 @@ class JdepsTask {
if (!jdkInternals.isEmpty()) {
log.println();
log.format("%-40s %s%n", "JDK Internal API", "Suggested Replacement");
log.format("%-40s %s%n", "----------------", "---------------------");
String internalApiTitle = getMessage("internal.api.column.header");
String replacementApiTitle = getMessage("public.api.replacement.column.header");
log.format("%-40s %s%n", internalApiTitle, replacementApiTitle);
log.format("%-40s %s%n",
internalApiTitle.replaceAll(".", "-"),
replacementApiTitle.replaceAll(".", "-"));
jdkInternals.entrySet().stream()
.forEach(e -> {
String key = e.getKey();
@ -800,12 +805,13 @@ class JdepsTask {
log.println();
if (!options.requires.isEmpty())
log.format("Inverse transitive dependences on %s%n", options.requires);
log.println(getMessage("inverse.transitive.dependencies.on",
options.requires));
else
log.format("Inverse transitive dependences matching %s%n",
log.println(getMessage("inverse.transitive.dependencies.matching",
options.regex != null
? options.regex.toString()
: "packages " + options.packageNames);
: "packages " + options.packageNames));
analyzer.inverseDependences().stream()
.sorted(Comparator.comparing(this::sortPath))
@ -870,7 +876,7 @@ class JdepsTask {
boolean ok = builder.run();
if (!ok && !options.nowarning) {
log.println("ERROR: missing dependencies");
reportError("err.missing.dependences");
builder.visitMissingDeps(
new Analyzer.Visitor() {
@Override

View File

@ -176,6 +176,7 @@ main.opt.multi-release=\
err.command.set={0} and {1} options are specified.
err.unknown.option=unknown option: {0}
err.missing.arg=no value given for {0}
err.missing.dependences=missing dependencies
err.invalid.arg.for.option=invalid argument for option: {0}
err.option.after.class=option must be specified before classes: {0}
err.genmoduleinfo.not.jarfile={0} is a modular JAR file that cannot be specified with the --generate-module-info option
@ -201,5 +202,10 @@ Please modify your code to eliminate dependence on any JDK internal APIs.\n\
For the most recent update on JDK internal API replacements, please check:\n\
{0}
split.package=split package: {0} {1}\n
inverse.transitive.dependencies.on=Inverse transitive dependences on {0}
inverse.transitive.dependencies.matching=Inverse transitive dependences matching {0}
internal.api.column.header=JDK Internal API
public.api.replacement.column.header=Suggested Replacement
artifact.not.found=not found
jdeps.wiki.url=https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool

View File

@ -283,9 +283,9 @@ class ConsoleIOContext extends IOContext {
if (firstInvocation) {
convertor = d -> d.signature();
} else {
convertor = d -> formatter.formatJavadoc(d.signature(),
d.javadoc() != null ? d.javadoc()
: repl.messageFormat("jshell.console.no.javadoc"));
convertor = d -> formatter.formatJavadoc(d.signature(), d.javadoc()) +
(d.javadoc() == null ? repl.messageFormat("jshell.console.no.javadoc")
: "");
}
doc = repl.analysis.documentation(prefix + buffer, cursor + prefix.length(), !firstInvocation)
.stream()

View File

@ -45,6 +45,7 @@ import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@ -1051,8 +1052,12 @@ public class JShellTool implements MessageHandler {
}
static final CompletionProvider EMPTY_COMPLETION_PROVIDER = new FixedCompletionProvider();
private static final CompletionProvider KEYWORD_COMPLETION_PROVIDER = new FixedCompletionProvider("-all ", "-start ", "-history ");
private static final CompletionProvider RELOAD_OPTIONS_COMPLETION_PROVIDER = new FixedCompletionProvider("-restore", "-quiet");
private static final CompletionProvider SNIPPET_HISTORY_OPTION_COMPLETION_PROVIDER = new FixedCompletionProvider("-all", "-start ", "-history");
private static final CompletionProvider SAVE_OPTION_COMPLETION_PROVIDER = new FixedCompletionProvider("-all ", "-start ", "-history ");
private static final CompletionProvider SNIPPET_OPTION_COMPLETION_PROVIDER = new FixedCompletionProvider("-all", "-start " );
private static final CompletionProvider RELOAD_OPTIONS_COMPLETION_PROVIDER = new FixedCompletionProvider("-restore ", "-quiet ");
private static final CompletionProvider RESTORE_COMPLETION_PROVIDER = new FixedCompletionProvider("-restore");
private static final CompletionProvider QUIET_COMPLETION_PROVIDER = new FixedCompletionProvider("-quiet");
private static final CompletionProvider SET_MODE_OPTIONS_COMPLETION_PROVIDER = new FixedCompletionProvider("-command", "-quiet", "-delete");
private static final CompletionProvider FILE_COMPLETION_PROVIDER = fileCompletions(p -> true);
private final Map<String, Command> commands = new LinkedHashMap<>();
@ -1106,24 +1111,62 @@ public class JShellTool implements MessageHandler {
p.getFileName().toString().endsWith(".jar"));
}
// Completion based on snippet supplier
private CompletionProvider snippetCompletion(Supplier<Stream<? extends Snippet>> snippetsSupplier) {
return (prefix, cursor, anchor) -> {
anchor[0] = 0;
int space = prefix.lastIndexOf(' ');
Set<String> prior = new HashSet<>(Arrays.asList(prefix.split(" ")));
if (prior.contains("-all") || prior.contains("-history")) {
return Collections.emptyList();
}
String argPrefix = prefix.substring(space + 1);
return snippetsSupplier.get()
.filter(k -> !prior.contains(String.valueOf(k.id()))
&& (!(k instanceof DeclarationSnippet)
|| !prior.contains(((DeclarationSnippet) k).name())))
.flatMap(k -> (k instanceof DeclarationSnippet)
? Stream.of(String.valueOf(k.id()), ((DeclarationSnippet) k).name())
: Stream.of(String.valueOf(k.id())))
.filter(k -> k.startsWith(prefix))
? Stream.of(String.valueOf(k.id()) + " ", ((DeclarationSnippet) k).name() + " ")
: Stream.of(String.valueOf(k.id()) + " "))
.filter(k -> k.startsWith(argPrefix))
.map(k -> new ArgSuggestion(k))
.collect(Collectors.toList());
};
}
private CompletionProvider snippetKeywordCompletion(Supplier<Stream<? extends Snippet>> snippetsSupplier) {
// Completion based on snippet supplier with -all -start (and sometimes -history) options
private CompletionProvider snippetWithOptionCompletion(CompletionProvider optionProvider,
Supplier<Stream<? extends Snippet>> snippetsSupplier) {
return (code, cursor, anchor) -> {
List<Suggestion> result = new ArrayList<>();
result.addAll(KEYWORD_COMPLETION_PROVIDER.completionSuggestions(code, cursor, anchor));
int pastSpace = code.lastIndexOf(' ') + 1; // zero if no space
if (pastSpace == 0) {
result.addAll(optionProvider.completionSuggestions(code, cursor, anchor));
}
result.addAll(snippetCompletion(snippetsSupplier).completionSuggestions(code, cursor, anchor));
anchor[0] += pastSpace;
return result;
};
}
// Completion of help, commands and subjects
private CompletionProvider helpCompletion() {
return (code, cursor, anchor) -> {
List<Suggestion> result;
int pastSpace = code.indexOf(' ') + 1; // zero if no space
if (pastSpace == 0) {
result = new FixedCompletionProvider(commands.values().stream()
.filter(cmd -> cmd.kind.showInHelp || cmd.kind == CommandKind.HELP_SUBJECT)
.map(c -> c.command + " ")
.toArray(size -> new String[size]))
.completionSuggestions(code, cursor, anchor);
} else if (code.startsWith("/se")) {
result = new FixedCompletionProvider(SET_SUBCOMMANDS)
.completionSuggestions(code.substring(pastSpace), cursor - pastSpace, anchor);
} else {
result = Collections.emptyList();
}
anchor[0] += pastSpace;
return result;
};
}
@ -1133,7 +1176,7 @@ public class JShellTool implements MessageHandler {
List<Suggestion> result = new ArrayList<>();
int space = code.indexOf(' ');
if (space == (-1)) {
result.addAll(KEYWORD_COMPLETION_PROVIDER.completionSuggestions(code, cursor, anchor));
result.addAll(SAVE_OPTION_COMPLETION_PROVIDER.completionSuggestions(code, cursor, anchor));
}
result.addAll(FILE_COMPLETION_PROVIDER.completionSuggestions(code.substring(space + 1), cursor - space - 1, anchor));
anchor[0] += space + 1;
@ -1143,9 +1186,25 @@ public class JShellTool implements MessageHandler {
private static CompletionProvider reloadCompletion() {
return (code, cursor, anchor) -> {
List<Suggestion> result = new ArrayList<>();
CompletionProvider provider;
int pastSpace = code.indexOf(' ') + 1; // zero if no space
result.addAll(RELOAD_OPTIONS_COMPLETION_PROVIDER.completionSuggestions(code.substring(pastSpace), cursor - pastSpace, anchor));
if (pastSpace == 0) {
provider = RELOAD_OPTIONS_COMPLETION_PROVIDER;
} else {
switch (code.substring(0, pastSpace - 1)) {
case "-quiet":
provider = RESTORE_COMPLETION_PROVIDER;
break;
case "-restore":
provider = QUIET_COMPLETION_PROVIDER;
break;
default:
provider = EMPTY_COMPLETION_PROVIDER;
break;
}
}
List<Suggestion> result = provider.completionSuggestions(
code.substring(pastSpace), cursor - pastSpace, anchor);
anchor[0] += pastSpace;
return result;
};
@ -1210,10 +1269,12 @@ public class JShellTool implements MessageHandler {
{
registerCommand(new Command("/list",
arg -> cmdList(arg),
snippetKeywordCompletion(this::allSnippets)));
snippetWithOptionCompletion(SNIPPET_HISTORY_OPTION_COMPLETION_PROVIDER,
this::allSnippets)));
registerCommand(new Command("/edit",
arg -> cmdEdit(arg),
snippetCompletion(this::allSnippets)));
snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
this::allSnippets)));
registerCommand(new Command("/drop",
arg -> cmdDrop(arg),
snippetCompletion(this::dropableSnippets),
@ -1226,13 +1287,16 @@ public class JShellTool implements MessageHandler {
FILE_COMPLETION_PROVIDER));
registerCommand(new Command("/vars",
arg -> cmdVars(arg),
snippetKeywordCompletion(this::allVarSnippets)));
snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
this::allVarSnippets)));
registerCommand(new Command("/methods",
arg -> cmdMethods(arg),
snippetKeywordCompletion(this::allMethodSnippets)));
snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
this::allMethodSnippets)));
registerCommand(new Command("/types",
arg -> cmdTypes(arg),
snippetKeywordCompletion(this::allTypeSnippets)));
snippetWithOptionCompletion(SNIPPET_OPTION_COMPLETION_PROVIDER,
this::allTypeSnippets)));
registerCommand(new Command("/imports",
arg -> cmdImports(),
EMPTY_COMPLETION_PROVIDER));
@ -1258,7 +1322,7 @@ public class JShellTool implements MessageHandler {
CommandKind.HIDDEN));
registerCommand(new Command("/help",
arg -> cmdHelp(arg),
EMPTY_COMPLETION_PROVIDER));
helpCompletion()));
registerCommand(new Command("/set",
arg -> cmdSet(arg),
new ContinuousCompletionProvider(Map.of(
@ -1276,7 +1340,7 @@ public class JShellTool implements MessageHandler {
registerCommand(new Command("/?",
"help.quest",
arg -> cmdHelp(arg),
EMPTY_COMPLETION_PROVIDER,
helpCompletion(),
CommandKind.NORMAL));
registerCommand(new Command("/!",
"help.bang",
@ -1962,6 +2026,8 @@ public class JShellTool implements MessageHandler {
case ASSIGNMENT_SUBKIND:
case OTHER_EXPRESSION_SUBKIND:
case TEMP_VAR_EXPRESSION_SUBKIND:
case STATEMENT_SUBKIND:
case UNKNOWN_SUBKIND:
if (!src.endsWith(";")) {
src = src + ";";
}

View File

@ -233,7 +233,7 @@ class CompletenessAnalyzer {
// Declarations and type parameters (thus expressions)
EXTENDS(TokenKind.EXTENDS, XEXPR|XDECL), // extends
COMMA(TokenKind.COMMA, XEXPR|XDECL|XTERM), // ,
COMMA(TokenKind.COMMA, XEXPR|XDECL), // ,
AMP(TokenKind.AMP, XEXPR|XDECL), // &
GT(TokenKind.GT, XEXPR|XDECL), // >
LT(TokenKind.LT, XEXPR|XDECL1), // <
@ -541,7 +541,10 @@ class CompletenessAnalyzer {
ct = new CT(TK.tokenKindToTK(prevTK, current.kind), advance());
break;
}
if (ct.kind.isStart() && !prevTK.isOkToTerminate()) {
// Detect an error if we are at starting position and the last
// token wasn't a terminating one. Special case: within braces,
// comma can proceed semicolon, e.g. the values list in enum
if (ct.kind.isStart() && !prevTK.isOkToTerminate() && prevTK != COMMA) {
return new CT(ERROR, current, "No '" + prevTK + "' before '" + ct.kind + "'");
}
if (stack.isEmpty() || ct.kind.isError()) {
@ -653,12 +656,7 @@ class CompletenessAnalyzer {
}
switch (token.kind) {
case EQ:
// Check for array initializer
nextToken();
if (token.kind == BRACES) {
nextToken();
return lastly(SEMI);
}
return parseExpressionStatement();
case BRACES:
case SEMI:

View File

@ -719,11 +719,11 @@ class Eval {
/**
* If there are classes to load, loads by calling the execution engine.
* @param classbytecoes names of the classes to load.
* @param classbytecodes names of the classes to load.
*/
private void load(Collection<ClassBytecodes> classbytecoes) {
if (!classbytecoes.isEmpty()) {
ClassBytecodes[] cbcs = classbytecoes.toArray(new ClassBytecodes[classbytecoes.size()]);
private void load(Collection<ClassBytecodes> classbytecodes) {
if (!classbytecodes.isEmpty()) {
ClassBytecodes[] cbcs = classbytecodes.toArray(new ClassBytecodes[classbytecodes.size()]);
try {
state.executionControl().load(cbcs);
state.classTracker.markLoaded(cbcs);
@ -731,6 +731,7 @@ class Eval {
state.classTracker.markLoaded(cbcs, ex.installed());
} catch (NotImplementedException ex) {
state.debug(ex, "Seriously?!? load not implemented");
state.closeDown();
} catch (EngineTerminationException ex) {
state.closeDown();
}

View File

@ -30,6 +30,7 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
@ -92,7 +93,6 @@ public class JShell implements AutoCloseable {
final BiFunction<Snippet, Integer, String> idGenerator;
final List<String> extraRemoteVMOptions;
final List<String> extraCompilerOptions;
final ExecutionControl.Generator executionControlGenerator;
private int nextKeyIndex = 1;
@ -102,13 +102,13 @@ public class JShell implements AutoCloseable {
private final Map<Subscription, Consumer<SnippetEvent>> keyStatusListeners = new HashMap<>();
private boolean closed = false;
private ExecutionControl executionControl = null;
private final ExecutionControl executionControl;
private SourceCodeAnalysisImpl sourceCodeAnalysis = null;
private static final String L10N_RB_NAME = "jdk.jshell.resources.l10n";
private static ResourceBundle outputRB = null;
JShell(Builder b) {
JShell(Builder b) throws IllegalStateException {
this.in = b.in;
this.out = b.out;
this.err = b.err;
@ -116,11 +116,18 @@ public class JShell implements AutoCloseable {
this.idGenerator = b.idGenerator;
this.extraRemoteVMOptions = b.extraRemoteVMOptions;
this.extraCompilerOptions = b.extraCompilerOptions;
this.executionControlGenerator = b.executionControlGenerator==null
? failOverExecutionControlGenerator(JdiDefaultExecutionControl.launch(),
JdiDefaultExecutionControl.listen("localhost"),
JdiDefaultExecutionControl.listen(null))
ExecutionControl.Generator executionControlGenerator = b.executionControlGenerator==null
? failOverExecutionControlGenerator(
JdiDefaultExecutionControl.listen(InetAddress.getLoopbackAddress().getHostAddress()),
JdiDefaultExecutionControl.launch(),
JdiDefaultExecutionControl.listen(null)
)
: b.executionControlGenerator;
try {
executionControl = executionControlGenerator.generate(new ExecutionEnvImpl());
} catch (Throwable ex) {
throw new IllegalStateException("Launching JShell execution engine threw: " + ex.getMessage(), ex);
}
this.maps = new SnippetMaps(this);
this.keyMap = new KeyMap(this);
@ -331,9 +338,10 @@ public class JShell implements AutoCloseable {
* functionality. This creates a remote process for execution. It is
* thus important to close the returned instance.
*
* @throws IllegalStateException if the {@code JShell} instance could not be created.
* @return the state engine
*/
public JShell build() {
public JShell build() throws IllegalStateException {
return new JShell(this);
}
}
@ -345,9 +353,10 @@ public class JShell implements AutoCloseable {
* That is, create an instance of {@code JShell}.
* <p>
* Equivalent to {@link JShell#builder() JShell.builder()}{@link JShell.Builder#build() .build()}.
* @throws IllegalStateException if the {@code JShell} instance could not be created.
* @return an instance of {@code JShell}.
*/
public static JShell create() {
public static JShell create() throws IllegalStateException {
return builder().build();
}
@ -458,6 +467,7 @@ public class JShell implements AutoCloseable {
* Note that the unnamed package is not accessible from the package in which
* {@link JShell#eval(String)} code is placed.
* @param path the path to add to the classpath.
* @throws IllegalStateException if this {@code JShell} instance is closed.
*/
public void addToClasspath(String path) {
// Compiler
@ -504,7 +514,11 @@ public class JShell implements AutoCloseable {
public void close() {
if (!closed) {
closeDown();
executionControl().close();
try {
executionControl().close();
} catch (Throwable ex) {
// don't care about exceptions on close
}
if (sourceCodeAnalysis != null) {
sourceCodeAnalysis.close();
}
@ -733,14 +747,8 @@ public class JShell implements AutoCloseable {
}
// --- private / package-private implementation support ---
ExecutionControl executionControl() {
if (executionControl == null) {
try {
executionControl = executionControlGenerator.generate(new ExecutionEnvImpl());
} catch (Throwable ex) {
throw new InternalError("Launching execution engine threw: " + ex.getMessage(), ex);
}
}
return executionControl;
}

View File

@ -73,7 +73,7 @@ class MemoryFileManager implements JavaFileManager {
// Upcoming Jigsaw
private Method inferModuleNameMethod = null;
private Method listModuleLocationsMethod = null;
private Method listLocationsForModulesMethod = null;
Iterable<? extends Path> getLocationAsPaths(Location loc) {
return this.stdFileManager.getLocationAsPaths(loc);
@ -203,13 +203,13 @@ class MemoryFileManager implements JavaFileManager {
}
// Make compatible with Jigsaw
public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
try {
if (listModuleLocationsMethod == null) {
listModuleLocationsMethod = JavaFileManager.class.getDeclaredMethod("listModuleLocations", Location.class);
if (listLocationsForModulesMethod == null) {
listLocationsForModulesMethod = JavaFileManager.class.getDeclaredMethod("listLocationsForModules", Location.class);
}
@SuppressWarnings("unchecked")
Iterable<Set<Location>> result = (Iterable<Set<Location>>) listModuleLocationsMethod.invoke(stdFileManager, location);
Iterable<Set<Location>> result = (Iterable<Set<Location>>) listLocationsForModulesMethod.invoke(stdFileManager, location);
return result;
} catch (NoSuchMethodException | SecurityException ex) {
throw new InternalError("Cannot lookup JavaFileManager method", ex);

View File

@ -102,11 +102,13 @@ import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toCollection;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
@ -129,6 +131,8 @@ import static jdk.jshell.Util.REPL_DOESNOTMATTER_CLASS_NAME;
import static jdk.jshell.SourceCodeAnalysis.Completeness.DEFINITELY_INCOMPLETE;
import static jdk.jshell.TreeDissector.printType;
import static java.util.stream.Collectors.joining;
/**
* The concrete implementation of SourceCodeAnalysis.
* @author Robert Field
@ -1341,9 +1345,9 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
.collect(joining(" & "));
}
case FIELD:
return elementHeader(at, el.getEnclosingElement(), includeParameterNames, false) + "." + el.getSimpleName() + ":" + el.asType();
return appendDot(elementHeader(at, el.getEnclosingElement(), includeParameterNames, false)) + el.getSimpleName() + ":" + el.asType();
case ENUM_CONSTANT:
return elementHeader(at, el.getEnclosingElement(), includeParameterNames, false) + "." + el.getSimpleName();
return appendDot(elementHeader(at, el.getEnclosingElement(), includeParameterNames, false)) + el.getSimpleName();
case EXCEPTION_PARAMETER: case LOCAL_VARIABLE: case PARAMETER: case RESOURCE_VARIABLE:
return el.getSimpleName() + ":" + el.asType();
case CONSTRUCTOR: case METHOD: {
@ -1407,6 +1411,9 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
return el.toString();
}
}
private String appendDot(String fqn) {
return fqn.isEmpty() ? fqn : fqn + ".";
}
private TypeMirror unwrapArrayType(TypeMirror arrayType) {
if (arrayType.getKind() == TypeKind.ARRAY) {
return ((ArrayType)arrayType).getComponentType();

View File

@ -63,7 +63,10 @@ import static jdk.jshell.execution.Util.remoteInputOutput;
*/
public class JdiDefaultExecutionControl extends JdiExecutionControl {
private static final String REMOTE_AGENT = RemoteExecutionControl.class.getName();
/**
* Default time-out expressed in milliseconds.
*/
private static final int DEFAULT_TIMEOUT = 5000;
private VirtualMachine vm;
private Process process;
@ -73,24 +76,60 @@ public class JdiDefaultExecutionControl extends JdiExecutionControl {
/**
* Creates an ExecutionControl instance based on a JDI
* {@code LaunchingConnector}.
* {@code LaunchingConnector}. Same as
* {@code JdiDefaultExecutionControl.create(defaultRemoteAgent(), true, null, defaultTimeout())}.
*
* @return the generator
*/
public static ExecutionControl.Generator launch() {
return env -> create(env, true, null);
return create(defaultRemoteAgent(), true, null, defaultTimeout());
}
/**
* Creates an ExecutionControl instance based on a JDI
* {@code ListeningConnector}.
* {@code ListeningConnector}. Same as
* {@code JdiDefaultExecutionControl.create(defaultRemoteAgent(), false, host, defaultTimeout())}.
*
* @param host explicit hostname to use, if null use discovered
* hostname, applies to listening only (!isLaunch)
* @return the generator
*/
public static ExecutionControl.Generator listen(String host) {
return env -> create(env, false, host);
return create(defaultRemoteAgent(), false, host, defaultTimeout());
}
/**
* Creates a JDI based ExecutionControl instance.
*
* @param remoteAgent the remote agent to launch
* @param isLaunch does JDI do the launch? That is, LaunchingConnector,
* otherwise we start explicitly and use ListeningConnector
* @param host explicit hostname to use, if null use discovered
* hostname, applies to listening only (!isLaunch)
* @param timeout the start-up time-out in milliseconds
* @return the generator
*/
public static ExecutionControl.Generator create(String remoteAgent,
boolean isLaunch, String host, int timeout) {
return env -> create(env, remoteAgent, isLaunch, host, timeout);
}
/**
* Default remote agent.
*
* @return the name of the standard remote agent
*/
public static String defaultRemoteAgent() {
return RemoteExecutionControl.class.getName();
}
/**
* Default remote connection time-out
*
* @return time to wait for connection before failing, expressed in milliseconds.
*/
public static int defaultTimeout() {
return DEFAULT_TIMEOUT;
}
/**
@ -103,6 +142,7 @@ public class JdiDefaultExecutionControl extends JdiExecutionControl {
*
* @param env the context passed by
* {@link jdk.jshell.spi.ExecutionControl#start(jdk.jshell.spi.ExecutionEnv) }
* @param remoteAgent the remote agent to launch
* @param isLaunch does JDI do the launch? That is, LaunchingConnector,
* otherwise we start explicitly and use ListeningConnector
* @param host explicit hostname to use, if null use discovered
@ -110,16 +150,16 @@ public class JdiDefaultExecutionControl extends JdiExecutionControl {
* @return the channel
* @throws IOException if there are errors in set-up
*/
private static ExecutionControl create(ExecutionEnv env,
boolean isLaunch, String host) throws IOException {
private static ExecutionControl create(ExecutionEnv env, String remoteAgent,
boolean isLaunch, String host, int timeout) throws IOException {
try (final ServerSocket listener = new ServerSocket(0, 1, InetAddress.getLoopbackAddress())) {
// timeout after 60 seconds
listener.setSoTimeout(60000);
// timeout on I/O-socket
listener.setSoTimeout(timeout);
int port = listener.getLocalPort();
// Set-up the JDI connection
JdiInitiator jdii = new JdiInitiator(port,
env.extraRemoteVMOptions(), REMOTE_AGENT, isLaunch, host);
env.extraRemoteVMOptions(), remoteAgent, isLaunch, host, timeout);
VirtualMachine vm = jdii.vm();
Process process = jdii.process();
@ -197,7 +237,7 @@ public class JdiDefaultExecutionControl extends JdiExecutionControl {
for (ThreadReference thread : vm().allThreads()) {
// could also tag the thread (e.g. using name), to find it easier
for (StackFrame frame : thread.frames()) {
if (REMOTE_AGENT.equals(frame.location().declaringType().name()) &&
if (defaultRemoteAgent().equals(frame.location().declaringType().name()) &&
( "invoke".equals(frame.location().method().name())
|| "varValue".equals(frame.location().method().name()))) {
ObjectReference thiz = frame.thisObject();

View File

@ -25,6 +25,7 @@
package jdk.jshell.execution;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -35,6 +36,13 @@ import com.sun.jdi.VirtualMachine;
import com.sun.jdi.connect.Connector;
import com.sun.jdi.connect.LaunchingConnector;
import com.sun.jdi.connect.ListeningConnector;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import com.sun.jdi.connect.IllegalConnectorArgumentsException;
/**
* Sets up a JDI connection, providing the resulting JDI {@link VirtualMachine}
@ -42,6 +50,12 @@ import com.sun.jdi.connect.ListeningConnector;
*/
public class JdiInitiator {
// factor for the timeout on all of connect
private static final double CONNECT_TIMEOUT_FACTOR = 1.5;
// Over-all connect time-out
private final int connectTimeout;
private VirtualMachine vm;
private Process process = null;
private final Connector connector;
@ -58,10 +72,12 @@ public class JdiInitiator {
* otherwise we start explicitly and use ListeningConnector
* @param host explicit hostname to use, if null use discovered
* hostname, applies to listening only (!isLaunch)
* @param timeout the start-up time-out in milliseconds
*/
public JdiInitiator(int port, List<String> remoteVMOptions, String remoteAgent,
boolean isLaunch, String host) {
boolean isLaunch, String host, int timeout) {
this.remoteAgent = remoteAgent;
this.connectTimeout = (int) (timeout * CONNECT_TIMEOUT_FACTOR);
String connectorName
= isLaunch
? "com.sun.jdi.CommandLineLaunch"
@ -74,8 +90,11 @@ public class JdiInitiator {
= isLaunch
? launchArgs(port, String.join(" ", remoteVMOptions))
: new HashMap<>();
if (host != null && !isLaunch) {
argumentName2Value.put("localAddress", host);
if (!isLaunch) {
argumentName2Value.put("timeout", ""+timeout);
if (host != null && !isLaunch) {
argumentName2Value.put("localAddress", host);
}
}
this.connectorArgs = mergeConnectorArgs(connector, argumentName2Value);
this.vm = isLaunch
@ -106,13 +125,12 @@ public class JdiInitiator {
private VirtualMachine launchTarget() {
LaunchingConnector launcher = (LaunchingConnector) connector;
try {
VirtualMachine new_vm = launcher.launch(connectorArgs);
VirtualMachine new_vm = timedVirtualMachineCreation(() -> launcher.launch(connectorArgs), null);
process = new_vm.process();
return new_vm;
} catch (Exception ex) {
reportLaunchFail(ex, "launch");
} catch (Throwable ex) {
throw reportLaunchFail(ex, "launch");
}
return null;
}
/**
@ -140,15 +158,52 @@ public class JdiInitiator {
ProcessBuilder pb = new ProcessBuilder(args);
process = pb.start();
// Forward out, err, and in
// Accept the connection from the remote agent
vm = listener.accept(connectorArgs);
listener.stopListening(connectorArgs);
vm = timedVirtualMachineCreation(() -> listener.accept(connectorArgs),
() -> process.waitFor());
return vm;
} catch (Exception ex) {
reportLaunchFail(ex, "listen");
} catch (Throwable ex) {
if (process != null) {
process.destroyForcibly();
}
throw reportLaunchFail(ex, "listen");
} finally {
try {
listener.stopListening(connectorArgs);
} catch (IOException | IllegalConnectorArgumentsException ex) {
// ignore
}
}
return null;
}
VirtualMachine timedVirtualMachineCreation(Callable<VirtualMachine> creator,
Callable<Integer> processComplete) throws Exception {
VirtualMachine result;
ExecutorService executor = Executors.newCachedThreadPool(runnable -> {
Thread thread = Executors.defaultThreadFactory().newThread(runnable);
thread.setDaemon(true);
return thread;
});
try {
Future<VirtualMachine> future = executor.submit(creator);
if (processComplete != null) {
executor.submit(() -> {
Integer i = processComplete.call();
future.cancel(true);
return i;
});
}
try {
result = future.get(connectTimeout, TimeUnit.MILLISECONDS);
} catch (TimeoutException ex) {
future.cancel(true);
throw ex;
}
} finally {
executor.shutdownNow();
}
return result;
}
private Connector findConnector(String name) {
@ -194,8 +249,10 @@ public class JdiInitiator {
return argumentName2Value;
}
private void reportLaunchFail(Exception ex, String context) {
throw new InternalError("Failed remote " + context + ": " + connector +
private InternalError reportLaunchFail(Throwable ex, String context) {
return new InternalError("Failed remote " + context + ": "
+ ex.toString()
+ " @ " + connector +
" -- " + connectorArgs, ex);
}

View File

@ -38,6 +38,9 @@ jdk/javadoc/doclet/testIOException/TestIOException.java
jdk/jshell/EditorPadTest.java 8161276 windows-all Test set-up cannot press buttons
jdk/jshell/ToolBasicTest.java 8139873 generic-all JShell tests failing
jdk/jshell/ExternalEditorTest.java 8170108 generic-all
jdk/jshell/ToolFormatTest.java 8170216 solaris-sparcv9
jdk/jshell/ReplaceTest.java 8170216 solaris-sparcv9
###########################################################################
#

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8131019
* @bug 8131019 8169561
* @summary Test JavadocFormatter
* @library /tools/lib
* @modules jdk.compiler/jdk.internal.shellsupport.doc
@ -388,6 +388,17 @@ public class JavadocFormatterTest {
if (!Objects.equals(actual, expected)) {
throw new AssertionError("Incorrect output: " + actual);
}
//unknown HTML tag:
actual = new JavadocFormatter(66, false).formatJavadoc("test",
"1234 <unknown any any>1234</unknown> 1234");
expected = "test\n" +
"1234 1234 1234\n";
if (!Objects.equals(actual, expected)) {
throw new AssertionError("Incorrect output: " + actual);
}
}
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8141492 8071982 8141636
* @bug 8141492 8071982 8141636 8147890
* @summary Test the search feature of javadoc.
* @author bpatel
* @library ../lib
@ -31,7 +31,6 @@
* @build JavadocTester
* @run main TestSearch
*/
public class TestSearch extends JavadocTester {
public static void main(String... args) throws Exception {
@ -241,146 +240,160 @@ public class TestSearch extends JavadocTester {
// Test for search tags markup in index file.
checkOutput("index-all.html", expectedOutput,
"<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#phrasewithspaces\">"
+ "phrase with spaces</a></span> - Search tag in pkg</dt>",
+ "phrase with spaces</a></span> - Search tag in pkg</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#pkg\">"
+ "pkg</a></span> - Search tag in pkg</dt>",
+ "pkg</a></span> - Search tag in pkg</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#pkg2.5\">"
+ "pkg2.5</a></span> - Search tag in pkg</dt>",
+ "pkg2.5</a></span> - Search tag in pkg</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#r\">"
+ "r</a></span> - Search tag in pkg</dt>",
+ "r</a></span> - Search tag in pkg</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg1/RegClass.html#searchphrase\">"
+ "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
+ "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg1/RegClass.html#SearchWordWithDescription\">"
+ "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
+ "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestAnnotationType.html#searchphrasewithdescdeprecated\">"
+ "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
+ "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestClass.html#SearchTagDeprecatedClass\">"
+ "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
+ "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestEnum.html#searchphrasedeprecated\">"
+ "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
+ "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestEnum.html#searchphrasedeprecated\">"
+ "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
+ "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestError.html#SearchTagDeprecatedMethod\">"
+ "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
+ "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestError.html#SearchTagDeprecatedMethod\">"
+ "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
+ "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#SingleWord\">"
+ "SingleWord</a></span> - Search tag in pkg</dt>",
+ "SingleWord</a></span> - Search tag in pkg</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg/AnotherClass.ModalExclusionType.html"
+ "#nested%7B@indexnested_tag_test%7D\">nested {@index nested_tag_test}</a></span> - "
+ "Search tag in pkg.AnotherClass.ModalExclusionType.NO_EXCLUDE</dt>",
+ "#nested%7B@indexnested_tag_test%7D\">nested {@index nested_tag_test}</a></span> - "
+ "Search tag in pkg.AnotherClass.ModalExclusionType.NO_EXCLUDE</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg/AnotherClass.ModalExclusionType.html"
+ "#html-span-see-/span-\">html &lt;span&gt; see &lt;/span&gt;</a></span> - Search "
+ "tag in pkg.AnotherClass.ModalExclusionType.APPLICATION_EXCLUDE</dt>",
+ "#html-span-see-/span-\">html &lt;span&gt; see &lt;/span&gt;</a></span> - Search "
+ "tag in pkg.AnotherClass.ModalExclusionType.APPLICATION_EXCLUDE</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg/AnotherClass.html#quoted\">quoted</a>"
+ "</span> - Search tag in pkg.AnotherClass.CONSTANT1</dt>");
+ "</span> - Search tag in pkg.AnotherClass.CONSTANT1</dt>",
"<dt><span class=\"memberNameLink\"><a href=\"pkg2/TestEnum.html#ONE\">ONE</a></span> - "
+ "pkg2.<a href=\"pkg2/TestEnum.html\" title=\"enum in pkg2\">TestEnum</a></dt>",
"<dt><span class=\"memberNameLink\"><a href=\"pkg2/TestEnum.html#THREE\">THREE</a></span> - "
+ "pkg2.<a href=\"pkg2/TestEnum.html\" title=\"enum in pkg2\">TestEnum</a></dt>",
"<dt><span class=\"memberNameLink\"><a href=\"pkg2/TestEnum.html#TWO\">TWO</a></span> - "
+ "pkg2.<a href=\"pkg2/TestEnum.html\" title=\"enum in pkg2\">TestEnum</a></dt>");
checkOutput("index-all.html", true,
"<div class=\"block\"><span class=\"deprecationComment\">class_test1 passes. Search tag"
+ " <a id=\"SearchTagDeprecatedClass\">SearchTagDeprecatedClass</a></span></div>",
+ " <a id=\"SearchTagDeprecatedClass\">SearchTagDeprecatedClass</a></span></div>",
"<div class=\"block\"><span class=\"deprecationComment\">error_test3 passes. Search tag for\n"
+ " method <a id=\"SearchTagDeprecatedMethod\">SearchTagDeprecatedMethod</a></span></div>");
+ " method <a id=\"SearchTagDeprecatedMethod\">SearchTagDeprecatedMethod</a></span></div>");
}
void checkSplitIndex() {
// Test for search tags markup in split index file.
checkOutput("index-files/index-12.html", true,
checkOutput("index-files/index-13.html", true,
"<dt><span class=\"searchTagLink\"><a href=\"../pkg1/RegClass.html#searchphrase\">"
+ "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
+ "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"../pkg1/RegClass.html#SearchWordWithDescription\">"
+ "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
+ "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"../pkg2/TestAnnotationType.html#searchphrasewithdescdeprecated\">"
+ "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
+ "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"../pkg2/TestClass.html#SearchTagDeprecatedClass\">"
+ "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
+ "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"../pkg2/TestEnum.html#searchphrasedeprecated\">"
+ "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
+ "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"../pkg2/TestEnum.html#searchphrasedeprecated\">"
+ "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
+ "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"../pkg2/TestError.html#SearchTagDeprecatedMethod\">"
+ "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
+ "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"../pkg2/TestError.html#SearchTagDeprecatedMethod\">"
+ "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
+ "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"../pkg/package-summary.html#SingleWord\">"
+ "SingleWord</a></span> - Search tag in pkg</dt>");
checkOutput("index-files/index-9.html", true,
+ "SingleWord</a></span> - Search tag in pkg</dt>");
checkOutput("index-files/index-10.html", true,
"<dt><span class=\"searchTagLink\"><a href=\"../pkg/package-summary.html#phrasewithspaces\">"
+ "phrase with spaces</a></span> - Search tag in pkg</dt>",
+ "phrase with spaces</a></span> - Search tag in pkg</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"../pkg/package-summary.html#pkg\">"
+ "pkg</a></span> - Search tag in pkg</dt>",
+ "pkg</a></span> - Search tag in pkg</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"../pkg/package-summary.html#pkg2.5\">"
+ "pkg2.5</a></span> - Search tag in pkg</dt>");
checkOutput("index-files/index-11.html", true,
+ "pkg2.5</a></span> - Search tag in pkg</dt>");
checkOutput("index-files/index-12.html", true,
"<dt><span class=\"searchTagLink\"><a href=\"../pkg/package-summary.html#r\">"
+ "r</a></span> - Search tag in pkg</dt>");
+ "r</a></span> - Search tag in pkg</dt>");
checkOutput("index-files/index-8.html", true,
"<dt><span class=\"searchTagLink\"><a href=\"../pkg/AnotherClass.ModalExclusionType.html"
+ "#nested%7B@indexnested_tag_test%7D\">nested {@index nested_tag_test}</a></span> - "
+ "Search tag in pkg.AnotherClass.ModalExclusionType.NO_EXCLUDE</dt>");
+ "#nested%7B@indexnested_tag_test%7D\">nested {@index nested_tag_test}</a></span> - "
+ "Search tag in pkg.AnotherClass.ModalExclusionType.NO_EXCLUDE</dt>");
checkOutput("index-files/index-5.html", true,
"<dt><span class=\"searchTagLink\"><a href=\"../pkg/AnotherClass.ModalExclusionType.html"
+ "#html-span-see-/span-\">html &lt;span&gt; see &lt;/span&gt;</a></span> - Search "
+ "tag in pkg.AnotherClass.ModalExclusionType.APPLICATION_EXCLUDE</dt>");
checkOutput("index-files/index-10.html", true,
+ "#html-span-see-/span-\">html &lt;span&gt; see &lt;/span&gt;</a></span> - Search "
+ "tag in pkg.AnotherClass.ModalExclusionType.APPLICATION_EXCLUDE</dt>");
checkOutput("index-files/index-11.html", true,
"<dt><span class=\"searchTagLink\"><a href=\"../pkg/AnotherClass.html#quoted\">quoted</a>"
+ "</span> - Search tag in pkg.AnotherClass.CONSTANT1</dt>");
+ "</span> - Search tag in pkg.AnotherClass.CONSTANT1</dt>");
checkOutput("index-files/index-9.html", true,
"<dt><span class=\"memberNameLink\"><a href=\"../pkg2/TestEnum.html#ONE\">ONE</a>"
+ "</span> - pkg2.<a href=\"../pkg2/TestEnum.html\" title=\"enum in pkg2\">TestEnum</a></dt>");
checkOutput("index-files/index-14.html", true,
"<dt><span class=\"memberNameLink\"><a href=\"../pkg2/TestEnum.html#THREE\">THREE</a></span> - "
+ "pkg2.<a href=\"../pkg2/TestEnum.html\" title=\"enum in pkg2\">TestEnum</a></dt>",
"<dt><span class=\"memberNameLink\"><a href=\"../pkg2/TestEnum.html#TWO\">TWO</a></span> - "
+ "pkg2.<a href=\"../pkg2/TestEnum.html\" title=\"enum in pkg2\">TestEnum</a></dt>");
}
void checkIndexNoComment() {
// Test for search tags markup in index file when javadoc is executed with -nocomment.
checkOutput("index-all.html", false,
"<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#phrasewithspaces\">"
+ "phrase with spaces</a></span> - Search tag in pkg</dt>",
+ "phrase with spaces</a></span> - Search tag in pkg</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#pkg\">"
+ "pkg</a></span> - Search tag in pkg</dt>",
+ "pkg</a></span> - Search tag in pkg</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#pkg2.5\">"
+ "pkg2.5</a></span> - Search tag in pkg</dt>",
+ "pkg2.5</a></span> - Search tag in pkg</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#r\">"
+ "r</a></span> - Search tag in pkg</dt>",
+ "r</a></span> - Search tag in pkg</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg1/RegClass.html#searchphrase\">"
+ "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
+ "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg1/RegClass.html#SearchWordWithDescription\">"
+ "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
+ "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestAnnotationType.html#searchphrasewithdescdeprecated\">"
+ "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
+ "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestClass.html#SearchTagDeprecatedClass\">"
+ "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
+ "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#SingleWord\">"
+ "SingleWord</a></span> - Search tag in pkg</dt>",
+ "SingleWord</a></span> - Search tag in pkg</dt>",
"<div class=\"block\"><span class=\"deprecationComment\">class_test1 passes. Search tag"
+ " <a id=\"SearchTagDeprecatedClass\">SearchTagDeprecatedClass</a></span></div>",
+ " <a id=\"SearchTagDeprecatedClass\">SearchTagDeprecatedClass</a></span></div>",
"<div class=\"block\"><span class=\"deprecationComment\">error_test3 passes. Search tag for\n"
+ " method <a id=\"SearchTagDeprecatedMethod\">SearchTagDeprecatedMethod</a></span></div>");
+ " method <a id=\"SearchTagDeprecatedMethod\">SearchTagDeprecatedMethod</a></span></div>");
checkOutput("index-all.html", true,
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestEnum.html#searchphrasedeprecated\">"
+ "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
+ "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestError.html#SearchTagDeprecatedMethod\">"
+ "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>");
+ "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>");
}
void checkIndexNoDeprecated() {
// Test for search tags markup in index file when javadoc is executed using -nodeprecated.
checkOutput("index-all.html", true,
"<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#phrasewithspaces\">"
+ "phrase with spaces</a></span> - Search tag in pkg</dt>",
+ "phrase with spaces</a></span> - Search tag in pkg</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg1/RegClass.html#searchphrase\">"
+ "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
+ "search phrase</a></span> - Search tag in pkg1.RegClass</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg1/RegClass.html#SearchWordWithDescription\">"
+ "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
+ "SearchWordWithDescription</a></span> - Search tag in pkg1.RegClass.CONSTANT_FIELD_1</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg/package-summary.html#SingleWord\">"
+ "SingleWord</a></span> - Search tag in pkg</dt>");
+ "SingleWord</a></span> - Search tag in pkg</dt>");
checkOutput("index-all.html", false,
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestAnnotationType.html#searchphrasewithdescdeprecated\">"
+ "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
+ "search phrase with desc deprecated</a></span> - Search tag in pkg2.TestAnnotationType</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestClass.html#SearchTagDeprecatedClass\">"
+ "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
+ "SearchTagDeprecatedClass</a></span> - Search tag in pkg2.TestClass</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestEnum.html#searchphrasedeprecated\">"
+ "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
+ "search phrase deprecated</a></span> - Search tag in pkg2.TestEnum.ONE</dt>",
"<dt><span class=\"searchTagLink\"><a href=\"pkg2/TestError.html#SearchTagDeprecatedMethod\">"
+ "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
+ "SearchTagDeprecatedMethod</a></span> - Search tag in pkg2.TestError</dt>",
"<div class=\"block\"><span class=\"deprecationComment\">class_test1 passes. Search tag"
+ " <a id=\"SearchTagDeprecatedClass\">SearchTagDeprecatedClass</a></span></div>",
+ " <a id=\"SearchTagDeprecatedClass\">SearchTagDeprecatedClass</a></span></div>",
"<div class=\"block\"><span class=\"deprecationComment\">error_test3 passes. Search tag for\n"
+ " method <a id=\"SearchTagDeprecatedMethod\">SearchTagDeprecatedMethod</a></span></div>");
+ " method <a id=\"SearchTagDeprecatedMethod\">SearchTagDeprecatedMethod</a></span></div>");
}
void checkJavaFXOutput() {

View File

@ -0,0 +1,167 @@
/*
* Copyright (c) 2002, 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.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8169676
* @summary boolean result of Option.process is often ignored
* @modules jdk.compiler/com.sun.tools.javac.api
* @modules jdk.compiler/com.sun.tools.javac.main
* @modules jdk.javadoc/jdk.javadoc.internal.api
* @modules jdk.javadoc/jdk.javadoc.internal.tool
* @library /tools/lib
* @build toolbox.JavacTask toolbox.JavadocTask toolbox.TestRunner toolbox.ToolBox
* @run main BadOptionsTest
*/
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import javax.lang.model.SourceVersion;
import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.doclet.Reporter;
import toolbox.JavadocTask;
import toolbox.ModuleBuilder;
import toolbox.Task;
import toolbox.TestRunner;
import toolbox.ToolBox;
/*
* This is primarily a test of the error reporting mechanisms
* for bad options provided by javac and utilized by javadoc.
* It is not an exhaustive test of all bad option forms detected
* by javac/javadoc.
*/
public class BadOptionsTest extends TestRunner {
public static void main(String... args) throws Exception {
BadOptionsTest t = new BadOptionsTest();
t.runTests();
}
private final ToolBox tb = new ToolBox();
private final Path src = Paths.get("src");
BadOptionsTest() throws IOException {
super(System.err);
init();
}
void init() throws IOException {
tb.writeJavaFiles(src,
"public class C { }");
}
@Test
public void testAddModulesEmptyArg() {
Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
.options("--add-modules=")
.files(src.resolve("C.java"))
.run(Task.Expect.FAIL)
.writeAll();
checkFound(result.getOutput(Task.OutputKind.DIRECT),
"javadoc: error - no value for --add-modules option");
checkNotFound(result, "Exception", "at jdk.javadoc/");
}
@Test
public void testAddModulesBadName() {
Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
.options("-quiet",
"--add-modules", "123")
.files(src.resolve("C.java"))
.run(Task.Expect.FAIL)
.writeAll();
checkFound(result.getOutput(Task.OutputKind.DIRECT),
"error: bad name in value for --add-modules option: '123'");
checkNotFound(result, "Exception", "at jdk.javadoc/");
}
@Test
public void testAddExportsEmptyArg() {
Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
.options("--add-exports=")
.files(src.resolve("C.java"))
.run(Task.Expect.FAIL)
.writeAll();
checkFound(result.getOutput(Task.OutputKind.DIRECT),
"javadoc: error - no value for --add-exports option");
checkNotFound(result, "Exception", "at jdk.javadoc/");
}
@Test
public void testAddExportsBadArg() {
Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
.options("--add-exports=m/p")
.files(src.resolve("C.java"))
.run(Task.Expect.FAIL)
.writeAll();
checkFound(result.getOutput(Task.OutputKind.DIRECT),
"javadoc: error - bad value for --add-exports option");
checkNotFound(result, "Exception", "at jdk.javadoc/");
}
@Test
public void testAddExportsBadName() {
Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
.options("--add-exports", "m!/p1=m2")
.files(src.resolve("C.java"))
.run()
.writeAll();
checkFound(result.getOutput(Task.OutputKind.DIRECT),
"warning: bad name in value for --add-exports option: 'm!'");
checkNotFound(result, "Exception", "at jdk.javadoc/");
}
private void checkFound(String log, String... expect) {
for (String e : expect) {
if (!log.contains(e)) {
error("Expected string not found: '" + e + "'");
}
}
}
private void checkNotFound(Task.Result result, String... unexpected) {
for (Task.OutputKind k : Task.OutputKind.values()) {
String r = result.getOutput(k);
for (String u : unexpected) {
if (r.contains(u)) {
error("Unexpected string found: '" + u + "'");
}
}
}
}
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8144095 8164825
* @bug 8144095 8164825 8169818 8153402
* @summary Test Command Completion
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@ -61,12 +61,13 @@ public class CommandCompletionTest extends ReplToolTesting {
public void testList() {
test(false, new String[] {"--no-startup"},
a -> assertCompletion(a, "/l|", false, "/list "),
a -> assertCompletion(a, "/list |", false, "-all ", "-history ", "-start "),
a -> assertCompletion(a, "/list -h|", false, "-history "),
a -> assertCompletion(a, "/list |", false, "-all", "-history", "-start "),
a -> assertCompletion(a, "/list -h|", false, "-history"),
a -> assertCompletion(a, "/list q|", false),
a -> assertVariable(a, "int", "xray"),
a -> assertCompletion(a, "/list |", false, "-all ", "-history ", "-start ", "1", "xray"),
a -> assertCompletion(a, "/list x|", false, "xray")
a -> assertCompletion(a, "/list |", false, "-all", "-history", "-start ", "1 ", "xray "),
a -> assertCompletion(a, "/list x|", false, "xray "),
a -> assertCompletion(a, "/list xray |", false)
);
}
@ -76,8 +77,8 @@ public class CommandCompletionTest extends ReplToolTesting {
a -> assertClass(a, "class cTest {}", "class", "cTest"),
a -> assertMethod(a, "int mTest() { return 0; }", "()I", "mTest"),
a -> assertVariable(a, "int", "fTest"),
a -> assertCompletion(a, "/drop |", false, "1", "2", "3", "cTest", "fTest", "mTest"),
a -> assertCompletion(a, "/drop f|", false, "fTest")
a -> assertCompletion(a, "/drop |", false, "1 ", "2 ", "3 ", "cTest ", "fTest ", "mTest "),
a -> assertCompletion(a, "/drop f|", false, "fTest ")
);
}
@ -88,8 +89,54 @@ public class CommandCompletionTest extends ReplToolTesting {
a -> assertClass(a, "class cTest {}", "class", "cTest"),
a -> assertMethod(a, "int mTest() { return 0; }", "()I", "mTest"),
a -> assertVariable(a, "int", "fTest"),
a -> assertCompletion(a, "/edit |", false, "1", "2", "3", "cTest", "fTest", "mTest"),
a -> assertCompletion(a, "/edit f|", false, "fTest")
a -> assertCompletion(a, "/edit |", false,
"-all" , "-start " , "1 ", "2 ", "3 ", "cTest ", "fTest ", "mTest "),
a -> assertCompletion(a, "/edit cTest |", false,
"2 ", "3 ", "fTest ", "mTest "),
a -> assertCompletion(a, "/edit 1 fTest |", false,
"2 ", "mTest "),
a -> assertCompletion(a, "/edit f|", false, "fTest "),
a -> assertCompletion(a, "/edit mTest f|", false, "fTest ")
);
}
public void testHelp() {
assertCompletion("/help |", false,
"/! ", "/-<n> ", "/<id> ", "/? ", "/classpath ", "/drop ",
"/edit ", "/exit ", "/help ", "/history ", "/imports ",
"/list ", "/methods ", "/open ", "/reload ", "/reset ",
"/save ", "/set ", "/types ", "/vars ", "intro ", "shortcuts ");
assertCompletion("/? |", false,
"/! ", "/-<n> ", "/<id> ", "/? ", "/classpath ", "/drop ",
"/edit ", "/exit ", "/help ", "/history ", "/imports ",
"/list ", "/methods ", "/open ", "/reload ", "/reset ",
"/save ", "/set ", "/types ", "/vars ", "intro ", "shortcuts ");
assertCompletion("/help /s|", false,
"/save ", "/set ");
assertCompletion("/help /set |", false,
"editor", "feedback", "format", "mode", "prompt", "start", "truncation");
assertCompletion("/help /edit |", false);
}
public void testReload() {
assertCompletion("/reload |", false, "-quiet ", "-restore ");
assertCompletion("/reload -restore |", false, "-quiet");
assertCompletion("/reload -quiet |", false, "-restore");
assertCompletion("/reload -restore -quiet |", false);
}
public void testVarsMethodsTypes() {
test(false, new String[]{"--no-startup"},
a -> assertCompletion(a, "/v|", false, "/vars "),
a -> assertCompletion(a, "/m|", false, "/methods "),
a -> assertCompletion(a, "/t|", false, "/types "),
a -> assertClass(a, "class cTest {}", "class", "cTest"),
a -> assertMethod(a, "int mTest() { return 0; }", "()I", "mTest"),
a -> assertVariable(a, "int", "fTest"),
a -> assertCompletion(a, "/vars |", false, "-all", "-start ", "3 ", "fTest "),
a -> assertCompletion(a, "/meth |", false, "-all", "-start ", "2 ", "mTest "),
a -> assertCompletion(a, "/typ |", false, "-all", "-start ", "1 ", "cTest "),
a -> assertCompletion(a, "/var f|", false, "fTest ")
);
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8149524 8131024 8165211 8080071 8130454 8167343 8129559
* @bug 8149524 8131024 8165211 8080071 8130454 8167343 8129559 8114842
* @summary Test SourceCodeAnalysis
* @build KullaTesting TestingInputStream
* @run testng CompletenessTest
@ -118,6 +118,10 @@ public class CompletenessTest extends KullaTesting {
"baz: while (true) if (t()) printf('-'); else break baz",
"java.util.function.IntFunction<int[]> ggg = int[]::new",
"List<? extends Object> l",
"int[] m = {1, 2}",
"int[] m = {1, 2}, n = null",
"int[] m = {1, 2}, n",
"int[] m = {1, 2}, n = {3, 4}",
};
static final String[] considered_incomplete = new String[] {
@ -177,6 +181,11 @@ public class CompletenessTest extends KullaTesting {
"void f()",
"void f() throws E",
"@A(",
"int n = 4,",
"int n,",
"int[] m = {1, 2},",
"int[] m = {1, 2}, n = {3, 4},",
"Map<String,"
};
static final String[] unknown = new String[] {
@ -315,5 +324,7 @@ public class CompletenessTest extends KullaTesting {
assertStatus("if (t) if ", DEFINITELY_INCOMPLETE, "if (t) if"); //Bug
assertStatus("int m() {} dfd", COMPLETE, "int m() {}");
assertStatus("int p = ", DEFINITELY_INCOMPLETE, "int p ="); //Bug
assertStatus("int[] m = {1, 2}, n = new int[0]; int i;", COMPLETE,
"int[] m = {1, 2}, n = new int[0];");
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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.
*/
import jdk.jshell.JShell;
import jdk.jshell.execution.JdiDefaultExecutionControl;
import jdk.jshell.execution.RemoteExecutionControl;
import static jdk.jshell.execution.JdiDefaultExecutionControl.defaultTimeout;
class DyingRemoteAgent extends RemoteExecutionControl {
static final boolean INFRA_VERIFY = false;
public static void main(String[] args) throws Exception {
if (INFRA_VERIFY) {
RemoteExecutionControl.main(args);
} else {
System.exit(1);
}
}
static JShell state(boolean isLaunch, String host) {
return JShell.builder().executionEngine(
JdiDefaultExecutionControl.create(
DyingRemoteAgent.class.getName(),
isLaunch,
host,
defaultTimeout())).build();
}
}

View File

@ -125,7 +125,6 @@ public abstract class EditorTestBase extends ReplToolTesting {
);
}
@Test(enabled = false) // TODO 8163816
public void testEditClass1() {
testEditor(
a -> assertClass(a, "class A {}", "class", "A"),
@ -163,7 +162,6 @@ public abstract class EditorTestBase extends ReplToolTesting {
);
}
@Test(enabled = false) // TODO 8163816
public void testEditMethod1() {
testEditor(
a -> assertMethod(a, "void f() {}", "()void", "f"),
@ -247,6 +245,18 @@ public abstract class EditorTestBase extends ReplToolTesting {
);
}
@Test
public void testStatementMush() {
testEditor(
a -> assertCommand(a, "System.out.println(\"Hello\")",
"", "", null, "Hello\n", ""),
a -> assertEditOutput(a, "/ed", "b ==> 10", () -> {
writeSource(getSource() + "\nint b = 10");
exit();
})
);
}
public static ExecutorService getExecutor() {
if (executor == null) {
executor = Executors.newSingleThreadExecutor();

View File

@ -24,7 +24,7 @@
/*
* @test
* @summary Testing external editor.
* @bug 8143955 8080843
* @bug 8143955 8080843 8163816 8143006
* @modules jdk.jshell/jdk.internal.jshell.tool
* @build ReplToolTesting CustomEditor EditorTestBase
* @run testng ExternalEditorTest

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8131029 8160127 8159935 8169519
* @summary Test that fail-over works for fail-over ExecutionControl generators.
* @modules jdk.jshell/jdk.jshell.execution
* jdk.jshell/jdk.jshell.spi
* @build KullaTesting ExecutionControlTestBase
* @run testng FailOverExecutionControlDyingLaunchTest
*/
import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import jdk.jshell.execution.JdiDefaultExecutionControl;
import static jdk.jshell.execution.JdiDefaultExecutionControl.defaultTimeout;
import static jdk.jshell.execution.Util.failOverExecutionControlGenerator;
@Test
public class FailOverExecutionControlDyingLaunchTest extends ExecutionControlTestBase {
@BeforeMethod
@Override
public void setUp() {
setUp(builder -> builder.executionEngine(failOverExecutionControlGenerator(
JdiDefaultExecutionControl.create(
DyingRemoteAgent.class.getName(),
true,
null,
defaultTimeout()),
JdiDefaultExecutionControl.launch())));
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8131029 8160127 8159935 8169519
* @summary Test that fail-over works for fail-over ExecutionControl generators.
* @modules jdk.jshell/jdk.jshell.execution
* jdk.jshell/jdk.jshell.spi
* @build KullaTesting ExecutionControlTestBase
* @run testng FailOverExecutionControlHangingLaunchTest
*/
import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import jdk.jshell.execution.JdiDefaultExecutionControl;
import static jdk.jshell.execution.JdiDefaultExecutionControl.defaultTimeout;
import static jdk.jshell.execution.Util.failOverExecutionControlGenerator;
@Test
public class FailOverExecutionControlHangingLaunchTest extends ExecutionControlTestBase {
@BeforeMethod
@Override
public void setUp() {
setUp(builder -> builder.executionEngine(failOverExecutionControlGenerator(
JdiDefaultExecutionControl.create(
HangingRemoteAgent.class.getName(),
true,
null,
defaultTimeout()),
JdiDefaultExecutionControl.launch())));
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8131029 8160127 8159935 8169519
* @summary Test that fail-over works for fail-over ExecutionControl generators.
* @modules jdk.jshell/jdk.jshell.execution
* jdk.jshell/jdk.jshell.spi
* @build KullaTesting ExecutionControlTestBase
* @run testng FailOverExecutionControlHangingListenTest
*/
import java.net.InetAddress;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import jdk.jshell.execution.JdiDefaultExecutionControl;
import static jdk.jshell.execution.JdiDefaultExecutionControl.defaultTimeout;
import static jdk.jshell.execution.Util.failOverExecutionControlGenerator;
@Test
public class FailOverExecutionControlHangingListenTest extends ExecutionControlTestBase {
@BeforeMethod
@Override
public void setUp() {
String loopback = InetAddress.getLoopbackAddress().getHostAddress();
setUp(builder -> builder.executionEngine(failOverExecutionControlGenerator(
JdiDefaultExecutionControl.create(
HangingRemoteAgent.class.getName(),
false,
loopback,
defaultTimeout()),
JdiDefaultExecutionControl.listen(loopback))));
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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.
*/
import jdk.jshell.JShell;
import jdk.jshell.execution.JdiDefaultExecutionControl;
import jdk.jshell.execution.RemoteExecutionControl;
/**
* Hang for three minutes (long enough to cause a timeout).
*/
class HangingRemoteAgent extends RemoteExecutionControl {
private static final long DELAY = 4000L;
private static final int TIMEOUT = 2000;
private static final boolean INFRA_VERIFY = false;
public static void main(String[] args) throws Exception {
if (INFRA_VERIFY) {
RemoteExecutionControl.main(args);
} else {
long end = System.currentTimeMillis() + DELAY;
long remaining;
while ((remaining = end - System.currentTimeMillis()) > 0L) {
try {
Thread.sleep(remaining);
} catch (InterruptedException ex) {
// loop again
}
}
}
}
static JShell state(boolean isLaunch, String host) {
return JShell.builder().executionEngine(
JdiDefaultExecutionControl.create(
HangingRemoteAgent.class.getName(),
isLaunch,
host,
TIMEOUT)).build();
}
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8131019
* @bug 8131019 8169561
* @summary Test Javadoc
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@ -65,6 +65,11 @@ public class JavadocTest extends KullaTesting {
assertJavadoc("clz.undef|");
}
public void testVariableInRepl() {
assertEval("Object o;");
assertSignature("o|", "o:java.lang.Object");
}
private void prepareZip() {
String clazz =
"package test;\n" +

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8169519 8166581
* @summary Tests for JDI connector failure
* @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
* @run testng JdiBadOptionLaunchExecutionControlTest
*/
import org.testng.annotations.Test;
import jdk.jshell.JShell;
import jdk.jshell.execution.JdiDefaultExecutionControl;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@Test
public class JdiBadOptionLaunchExecutionControlTest {
private static final String EXPECTED_ERROR =
"Launching JShell execution engine threw: Failed remote launch: java.util.concurrent.ExecutionException: com.sun.jdi.connect.VMStartException: VM initialization failed";
public void badOptionLaunchTest() {
try {
JShell.builder()
.executionEngine(JdiDefaultExecutionControl.launch())
.remoteVMOptions("-BadBadOption")
.build();
} catch (IllegalStateException ex) {
assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
return;
}
fail("Expected IllegalStateException");
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8169519 8166581
* @summary Tests for JDI connector failure
* @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
* @run testng JdiBadOptionListenExecutionControlTest
*/
import org.testng.annotations.Test;
import jdk.jshell.JShell;
import jdk.jshell.execution.JdiDefaultExecutionControl;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@Test
public class JdiBadOptionListenExecutionControlTest {
private static final String EXPECTED_ERROR =
"Launching JShell execution engine threw: Failed remote listen:";
public void badOptionListenTest() {
try {
JShell.builder()
.executionEngine(JdiDefaultExecutionControl.listen(null))
.remoteVMOptions("-BadBadOption")
.build();
} catch (IllegalStateException ex) {
assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
return;
}
fail("Expected IllegalStateException");
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8169519
* @summary Tests for JDI connector failure
* @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
* @run testng JdiBogusHostListenExecutionControlTest
*/
import org.testng.annotations.Test;
import jdk.jshell.JShell;
import jdk.jshell.execution.JdiDefaultExecutionControl;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@Test
public class JdiBogusHostListenExecutionControlTest {
private static final String EXPECTED_ERROR =
"Launching JShell execution engine threw: Failed remote listen: java.net.SocketException: Unresolved address @ com.sun.jdi.SocketListe";
public void badOptionListenTest() {
try {
JShell.builder()
.executionEngine(JdiDefaultExecutionControl.listen("BattyRumbleBuckets-Snurfle-99-Blip"))
.build();
} catch (IllegalStateException ex) {
assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
return;
}
fail("Expected IllegalStateException");
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8169519
* @summary Tests for JDI connector failure
* @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
* @build DyingRemoteAgent
* @run testng JdiFailingLaunchExecutionControlTest
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@Test
public class JdiFailingLaunchExecutionControlTest {
private static final String EXPECTED_ERROR =
"Launching JShell execution engine threw: Accept timed out";
public void failLaunchTest() {
try {
System.err.printf("Unexpected return value: %s\n", DyingRemoteAgent.state(true, null).eval("33;"));
} catch (IllegalStateException ex) {
assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
return;
}
fail("Expected IllegalStateException");
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8169519
* @summary Tests for JDI connector failure
* @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
* @build DyingRemoteAgent
* @run testng JdiFailingListenExecutionControlTest
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@Test
public class JdiFailingListenExecutionControlTest {
private static final String EXPECTED_ERROR =
"Launching JShell execution engine threw: Accept timed out";
public void failListenTest() {
try {
System.err.printf("Unexpected return value: %s\n", DyingRemoteAgent.state(true, null).eval("33;"));
} catch (IllegalStateException ex) {
assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
return;
}
fail("Expected IllegalStateException");
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8169519
* @summary Tests for JDI connector timeout failure
* @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
* @build HangingRemoteAgent
* @run testng JdiHangingLaunchExecutionControlTest
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@Test
public class JdiHangingLaunchExecutionControlTest {
private static final String EXPECTED_ERROR =
"Launching JShell execution engine threw: Accept timed out";
public void hangLaunchTimeoutTest() {
try {
System.err.printf("Unexpected return value: %s\n",
HangingRemoteAgent.state(true, null).eval("33;"));
} catch (IllegalStateException ex) {
assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
return;
}
fail("Expected IllegalStateException");
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8169519
* @summary Tests for JDI connector timeout failure
* @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution
* @build HangingRemoteAgent
* @run testng JdiHangingListenExecutionControlTest
*/
import org.testng.annotations.Test;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@Test
public class JdiHangingListenExecutionControlTest {
private static final String EXPECTED_ERROR =
"Launching JShell execution engine threw: Accept timed out";
public void hangListenTimeoutTest() {
try {
System.err.printf("Unexpected return value: %s\n",
HangingRemoteAgent.state(false, null).eval("33;"));
} catch (IllegalStateException ex) {
assertTrue(ex.getMessage().startsWith(EXPECTED_ERROR), ex.getMessage());
return;
}
fail("Expected IllegalStateException");
}
}

View File

@ -476,7 +476,7 @@ public class ReplToolTesting {
code = code.replace("|", "");
assertTrue(cursor > -1, "'|' not found: " + code);
List<Suggestion> completions =
js.commandCompletionSuggestions(code, cursor, new int[1]); //XXX: ignoring anchor for now
js.commandCompletionSuggestions(code, cursor, new int[] {-1}); //XXX: ignoring anchor for now
return completions.stream()
.filter(s -> isSmart == s.matchesType())
.map(s -> s.continuation())

View File

@ -22,7 +22,7 @@
*/
/*
* @test 8151754 8080883 8160089
* @test 8151754 8080883 8160089 8166581
* @summary Testing start-up options.
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@ -48,6 +48,7 @@ import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@Test
public class StartOptionTest {
@ -135,6 +136,17 @@ public class StartOptionTest {
start("", "Argument to startup missing.", "--no-startup", "--startup");
}
public void testStartupFailedOption() throws Exception {
try {
start("", "", "-R-hoge-foo-bar");
} catch (IllegalStateException ex) {
String s = ex.getMessage();
assertTrue(s.startsWith("Launching JShell execution engine threw: Failed remote"), s);
return;
}
fail("Expected IllegalStateException");
}
public void testStartupUnknown() throws Exception {
start("", "File 'UNKNOWN' for '--startup' is not found.", "--startup", "UNKNOWN");
}

View File

@ -118,6 +118,7 @@ public class UserJdiUserRemoteTest extends ExecutionControlTestBase {
class MyExecutionControl extends JdiExecutionControl {
private static final String REMOTE_AGENT = MyRemoteExecutionControl.class.getName();
private static final int TIMEOUT = 2000;
private VirtualMachine vm;
private Process process;
@ -147,8 +148,8 @@ class MyExecutionControl extends JdiExecutionControl {
*/
static ExecutionControl make(ExecutionEnv env, UserJdiUserRemoteTest test) throws IOException {
try (final ServerSocket listener = new ServerSocket(0)) {
// timeout after 60 seconds
listener.setSoTimeout(60000);
// timeout for socket
listener.setSoTimeout(TIMEOUT);
int port = listener.getLocalPort();
// Set-up the JDI connection
@ -158,7 +159,7 @@ class MyExecutionControl extends JdiExecutionControl {
+ System.getProperty("path.separator")
+ System.getProperty("user.dir"));
JdiInitiator jdii = new JdiInitiator(port,
opts, REMOTE_AGENT, true, null);
opts, REMOTE_AGENT, true, null, TIMEOUT);
VirtualMachine vm = jdii.vm();
Process process = jdii.process();

View File

@ -31,6 +31,7 @@
*/
import java.lang.reflect.Field;
import java.lang.reflect.Module;
import java.io.File;
import java.io.ByteArrayOutputStream;
import javax.tools.*;
@ -39,9 +40,9 @@ public class T6410653 {
public static void main(String... args) throws Exception {
File testSrc = new File(System.getProperty("test.src"));
String source = new File(testSrc, "T6410653.java").getPath();
ClassLoader cl = ToolProvider.getSystemToolClassLoader();
Tool compiler = ToolProvider.getSystemJavaCompiler();
Class<?> log = Class.forName("com.sun.tools.javac.util.Log", true, cl);
Module compilerModule = compiler.getClass().getModule();
Class<?> log = Class.forName(compilerModule, "com.sun.tools.javac.util.Log");
Field useRawMessages = log.getDeclaredField("useRawMessages");
useRawMessages.setAccessible(true);
useRawMessages.setBoolean(null, true);

View File

@ -170,7 +170,7 @@ public class DetectMutableStaticFields {
ConstantPoolException,
InvalidDescriptor {
JavaFileManager.Location location =
fm.getModuleLocation(StandardLocation.SYSTEM_MODULES, moduleName);
fm.getLocationForModule(StandardLocation.SYSTEM_MODULES, moduleName);
if (location == null)
throw new AssertionError("can't find module " + moduleName);

View File

@ -73,8 +73,8 @@ public class T6397104 {
if (hasLocation) {
for (Location location : StandardLocation.values()) {
System.err.format(" location:%s, moduleLocn:%b%n",
location, location.isModuleLocation());
if (location.isModuleLocation()) {
location, location.isModuleOrientedLocation());
if (!location.isOutputLocation()) {
continue;
}
fm.setLocation(location, Arrays.asList(new File(".")));

View File

@ -62,7 +62,7 @@ public class TestClientCodeWrapper extends JavacTestingAbstractProcessor {
defaultFileManager = fm;
for (Method m: getMethodsExcept(JavaFileManager.class,
"close", "getJavaFileForInput", "getModuleLocation", "getServiceLoader")) {
"close", "getJavaFileForInput", "getLocationForModule", "getServiceLoader")) {
test(m);
}
@ -401,15 +401,15 @@ public class TestClientCodeWrapper extends JavacTestingAbstractProcessor {
}
@Override
public Location getModuleLocation(Location location, String moduleName) throws IOException {
throwUserExceptionIfNeeded(fileManagerMethod, "getModuleLocation");
return super.getModuleLocation(location, moduleName);
public Location getLocationForModule(Location location, String moduleName) throws IOException {
throwUserExceptionIfNeeded(fileManagerMethod, "getLocationForModule");
return super.getLocationForModule(location, moduleName);
}
@Override
public Location getModuleLocation(Location location, JavaFileObject fo, String pkgName) throws IOException {
throwUserExceptionIfNeeded(fileManagerMethod, "getModuleLocation");
return super.getModuleLocation(location, fo, pkgName);
public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
throwUserExceptionIfNeeded(fileManagerMethod, "getLocationForModule");
return super.getLocationForModule(location, fo, pkgName);
}
@Override
@ -419,9 +419,9 @@ public class TestClientCodeWrapper extends JavacTestingAbstractProcessor {
}
@Override
public Iterable<Set<Location>> listModuleLocations(Location location) throws IOException {
throwUserExceptionIfNeeded(fileManagerMethod, "listModuleLocations");
return super.listModuleLocations(location);
public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
throwUserExceptionIfNeeded(fileManagerMethod, "listLocationsForModules");
return super.listLocationsForModules(location);
}
public FileObject wrap(FileObject fo) {

View File

@ -55,6 +55,8 @@ public class ToolProviderTest {
Objects.requireNonNull(ToolProvider.getSystemDocumentationTool());
Objects.requireNonNull(ToolProvider.getSystemJavaCompiler());
Objects.requireNonNull(ToolProvider.getSystemToolClassLoader());
if (ToolProvider.getSystemToolClassLoader() != null) {
throw new AssertionError("unexpected value for getSystemToolClassLoader");
}
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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.
*/
// key: compiler.err.bad.name.for.option
// options: --add-modules Bad!Name
class BadNameForOption { }

View File

@ -126,12 +126,12 @@ public class AddModulesTest extends ModuleTestBase {
"--add-modules", "BadModule!")
.outdir(classes)
.files(findJavaFiles(src))
.run()
.run(Task.Expect.FAIL)
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
checkOutputContains(log,
"- compiler.warn.bad.name.for.option: --add-modules, BadModule!");
"- compiler.err.bad.name.for.option: --add-modules, BadModule!");
}
@Test

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 0000000
* @summary Test use of ALL-DEFAULT token
* @library /tools/lib
* @modules
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.JavaTask ModuleTestBase
* @run main AllDefaultTest
*/
import java.nio.file.Path;
import toolbox.JavacTask;
import toolbox.Task;
public class AllDefaultTest extends ModuleTestBase {
public static void main(String... args) throws Exception {
AllDefaultTest t = new AllDefaultTest();
t.runTests();
}
@Test
public void testCompileTime_notAllowed(Path base) throws Exception {
tb.writeJavaFiles(base, "class C { }");
String out = new JavacTask(tb)
.options("-XDrawDiagnostics",
"--add-modules=ALL-DEFAULT")
.files(tb.findJavaFiles(base))
.run(Task.Expect.FAIL)
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
if (!out.contains("- compiler.err.bad.name.for.option: --add-modules, ALL-DEFAULT")) {
error("expected text not found");
}
}
@Test
public void testRuntimeTime_ignored_1(Path base) throws Exception {
tb.writeJavaFiles(base, "class C { }");
new JavacTask(tb, Task.Mode.EXEC)
.options("-XDrawDiagnostics",
"-J--add-modules=ALL-DEFAULT",
"--inherit-runtime-environment")
.files(tb.findJavaFiles(base))
.run()
.writeAll();
}
@Test
public void testRuntimeTime_ignored_2(Path base) throws Exception {
tb.writeJavaFiles(base, "class C { }");
new JavacTask(tb, Task.Mode.EXEC)
.options("-XDrawDiagnostics",
"-J--add-modules=jdk.compiler",
"--inherit-runtime-environment")
.files(tb.findJavaFiles(base))
.run()
.writeAll();
}
}

View File

@ -144,11 +144,11 @@ public class LimitModulesTest extends ModuleTestBase {
"--limit-modules", "BadModule!")
.outdir(classes)
.files(findJavaFiles(src))
.run()
.run(Task.Expect.FAIL)
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
if (!log.contains("- compiler.warn.bad.name.for.option: --limit-modules, BadModule!"))
if (!log.contains("- compiler.err.bad.name.for.option: --limit-modules, BadModule!"))
throw new Exception("expected output not found");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* 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
@ -82,6 +82,6 @@ public class ReleaseOptionClashes {
compiler.run(null, null, System.out, options.toArray(new String[0]));
}
ClassLoader cl = ToolProvider.getSystemToolClassLoader();
Tool compiler = ToolProvider.getSystemJavaCompiler();
ClassLoader cl = compiler.getClass().getClassLoader();
}

View File

@ -0,0 +1,171 @@
/*
* Copyright (c) 2002, 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.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8169676
* @summary boolean result of Option.process is often ignored
* @modules jdk.compiler/com.sun.tools.javac.api
* @modules jdk.compiler/com.sun.tools.javac.main
* @modules jdk.javadoc/jdk.javadoc.internal.api
* @modules jdk.javadoc/jdk.javadoc.internal.tool
* @library /tools/lib
* @build toolbox.JavacTask toolbox.JavadocTask toolbox.TestRunner toolbox.ToolBox
* @run main BadOptionsTest
*/
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import javax.lang.model.SourceVersion;
import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.doclet.Reporter;
import toolbox.JavadocTask;
import toolbox.ModuleBuilder;
import toolbox.Task;
import toolbox.TestRunner;
import toolbox.ToolBox;
/*
* This is primarily a test of the error reporting mechanisms
* for bad options provided by javac and utilized by javadoc.
* It is not an exhaustive test of all bad option forms detected
* by javac/javadoc.
*/
public class BadOptionsTest extends TestRunner {
public static void main(String... args) throws Exception {
BadOptionsTest t = new BadOptionsTest();
t.runTests();
}
private final ToolBox tb = new ToolBox();
private final Path src = Paths.get("src");
BadOptionsTest() throws IOException {
super(System.err);
init();
}
void init() throws IOException {
tb.writeJavaFiles(src,
"public class C { }");
}
@Test
public void testAddModulesEmptyArg() {
Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
.options("-Xold",
"--add-modules", "")
.files(src.resolve("C.java"))
.run(Task.Expect.FAIL)
.writeAll();
checkFound(result.getOutput(Task.OutputKind.DIRECT),
"javadoc: error - no value for --add-modules option");
checkNotFound(result, "Exception", "at jdk.javadoc/");
}
@Test
public void testAddModulesBadName() {
Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
.options("-Xold", "-quiet",
"--add-modules", "123")
.files(src.resolve("C.java"))
.run(Task.Expect.FAIL)
.writeAll();
checkFound(result.getOutput(Task.OutputKind.DIRECT),
"error: bad name in value for --add-modules option: '123'");
checkNotFound(result, "Exception", "at jdk.javadoc/");
}
@Test
public void testAddExportsEmptyArg() {
Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
.options("-Xold",
"--add-exports", "")
.files(src.resolve("C.java"))
.run(Task.Expect.FAIL)
.writeAll();
checkFound(result.getOutput(Task.OutputKind.DIRECT),
"javadoc: error - no value for --add-exports option");
checkNotFound(result, "Exception", "at jdk.javadoc/");
}
@Test
public void testAddExportsBadArg() {
Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
.options("-Xold",
"--add-exports", "m/p")
.files(src.resolve("C.java"))
.run(Task.Expect.FAIL)
.writeAll();
checkFound(result.getOutput(Task.OutputKind.DIRECT),
"javadoc: error - bad value for --add-exports option");
checkNotFound(result, "Exception", "at jdk.javadoc/");
}
@Test
public void testAddExportsBadName() {
Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
.options("-Xold",
"--add-exports", "m!/p1=m2")
.files(src.resolve("C.java"))
.run()
.writeAll();
checkFound(result.getOutput(Task.OutputKind.DIRECT),
"warning: bad name in value for --add-exports option: 'm!'");
checkNotFound(result, "Exception", "at jdk.javadoc/");
}
private void checkFound(String log, String... expect) {
for (String e : expect) {
if (!log.contains(e)) {
error("Expected string not found: '" + e + "'");
}
}
}
private void checkNotFound(Task.Result result, String... unexpected) {
for (Task.OutputKind k : Task.OutputKind.values()) {
String r = result.getOutput(k);
for (String u : unexpected) {
if (r.contains(u)) {
error("Unexpected string found: '" + u + "'");
}
}
}
}
}