7026941: 199: path options ignored when reusing filemanager across tasks
Reviewed-by: jlahoda, jfranck
This commit is contained in:
parent
8aa391d4c9
commit
15853aca13
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -202,9 +202,6 @@ public class ClientCodeWrapper {
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Wrapper classes">
|
||||
|
||||
// FIXME: all these classes should be converted to use multi-catch when
|
||||
// that is available in the bootstrap compiler.
|
||||
|
||||
protected class WrappedJavaFileManager implements JavaFileManager {
|
||||
protected JavaFileManager clientJavaFileManager;
|
||||
WrappedJavaFileManager(JavaFileManager clientJavaFileManager) {
|
||||
|
@ -161,6 +161,15 @@ public class JavacTaskImpl extends BasicJavacTask {
|
||||
compilerMain.log = Log.instance(context);
|
||||
compilerMain.setOptions(Options.instance(context));
|
||||
compilerMain.filenames = new LinkedHashSet<>();
|
||||
compilerMain.deferredFileManagerOptions = new LinkedHashMap<>();
|
||||
// The following line is conceptually wrong. It should not refer to args
|
||||
// which may include inappropriate file manager options.
|
||||
// (Ideally, args should not even be passed into JavacTaskImpl at all.)
|
||||
// The "no filenames in args" check should have been handled by the use of
|
||||
// the GrumpyHelper in JavacTool.getTask, but processArgs also has some
|
||||
// additional checking, which should be factored out and called separately.
|
||||
// If we fix this, then filenames and deferredFileManagerOptions in Main
|
||||
// can revert to being protected or private, not public.
|
||||
Collection<File> filenames = compilerMain.processArgs(CommandLine.parse(args), classNames);
|
||||
if (filenames != null && !filenames.isEmpty())
|
||||
throw new IllegalArgumentException("Malformed arguments " + toString(filenames, " "));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -158,11 +158,6 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
symbolFileEnabled = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefaultBootClassPath() {
|
||||
return locations.isDefaultBootClassPath();
|
||||
}
|
||||
|
||||
public JavaFileObject getFileForInput(String name) {
|
||||
return getRegularFile(new File(name));
|
||||
}
|
||||
@ -579,15 +574,6 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
|
||||
}
|
||||
}
|
||||
|
||||
private String defaultEncodingName;
|
||||
private String getDefaultEncodingName() {
|
||||
if (defaultEncodingName == null) {
|
||||
defaultEncodingName =
|
||||
new OutputStreamWriter(new ByteArrayOutputStream()).getEncoding();
|
||||
}
|
||||
return defaultEncodingName;
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader(Location location) {
|
||||
nullCheck(location);
|
||||
Iterable<? extends File> path = getLocation(location);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,12 +22,10 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.tools.javac.file;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Iterator;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
@ -38,64 +36,72 @@ import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileManager.Location;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import com.sun.tools.javac.code.Lint;
|
||||
import com.sun.tools.javac.main.Option;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
import com.sun.tools.javac.util.Log;
|
||||
import com.sun.tools.javac.util.Options;
|
||||
import com.sun.tools.javac.util.StringUtils;
|
||||
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import static javax.tools.StandardLocation.*;
|
||||
import static com.sun.tools.javac.main.Option.*;
|
||||
import static javax.tools.StandardLocation.CLASS_PATH;
|
||||
import static javax.tools.StandardLocation.PLATFORM_CLASS_PATH;
|
||||
import static javax.tools.StandardLocation.SOURCE_PATH;
|
||||
|
||||
/** This class converts command line arguments, environment variables
|
||||
* and system properties (in File.pathSeparator-separated String form)
|
||||
* into a boot class path, user class path, and source path (in
|
||||
* {@code Collection<String>} form).
|
||||
import static com.sun.tools.javac.main.Option.BOOTCLASSPATH;
|
||||
import static com.sun.tools.javac.main.Option.DJAVA_ENDORSED_DIRS;
|
||||
import static com.sun.tools.javac.main.Option.DJAVA_EXT_DIRS;
|
||||
import static com.sun.tools.javac.main.Option.ENDORSEDDIRS;
|
||||
import static com.sun.tools.javac.main.Option.EXTDIRS;
|
||||
import static com.sun.tools.javac.main.Option.XBOOTCLASSPATH;
|
||||
import static com.sun.tools.javac.main.Option.XBOOTCLASSPATH_APPEND;
|
||||
import static com.sun.tools.javac.main.Option.XBOOTCLASSPATH_PREPEND;
|
||||
|
||||
/**
|
||||
* This class converts command line arguments, environment variables and system properties (in
|
||||
* File.pathSeparator-separated String form) into a boot class path, user class path, and source
|
||||
* path (in {@code Collection<String>} form).
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
* <p>
|
||||
* <b>This is NOT part of any supported API. If you write code that depends on this, you do so at
|
||||
* your own risk. This code and its internal interfaces are subject to change or deletion without
|
||||
* notice.</b>
|
||||
*/
|
||||
public class Locations {
|
||||
|
||||
/** The log to use for warning output */
|
||||
/**
|
||||
* The log to use for warning output
|
||||
*/
|
||||
private Log log;
|
||||
|
||||
/** Collection of command-line options */
|
||||
private Options options;
|
||||
|
||||
/** Handler for -Xlint options */
|
||||
private Lint lint;
|
||||
|
||||
/** Access to (possibly cached) file info */
|
||||
/**
|
||||
* Access to (possibly cached) file info
|
||||
*/
|
||||
private FSInfo fsInfo;
|
||||
|
||||
/** Whether to warn about non-existent path elements */
|
||||
/**
|
||||
* Whether to warn about non-existent path elements
|
||||
*/
|
||||
private boolean warn;
|
||||
|
||||
// TODO: remove need for this
|
||||
private boolean inited = false; // TODO? caching bad?
|
||||
|
||||
public Locations() {
|
||||
initHandlers();
|
||||
}
|
||||
|
||||
public void update(Log log, Options options, Lint lint, FSInfo fsInfo) {
|
||||
// could replace Lint by "boolean warn"
|
||||
public void update(Log log, Lint lint, FSInfo fsInfo) {
|
||||
this.log = log;
|
||||
this.options = options;
|
||||
this.lint = lint;
|
||||
warn = lint.isEnabled(Lint.LintCategory.PATH);
|
||||
this.fsInfo = fsInfo;
|
||||
}
|
||||
|
||||
@ -104,14 +110,14 @@ public class Locations {
|
||||
}
|
||||
|
||||
public boolean isDefaultBootClassPath() {
|
||||
BootClassPathLocationHandler h =
|
||||
(BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH);
|
||||
BootClassPathLocationHandler h
|
||||
= (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH);
|
||||
return h.isDefault();
|
||||
}
|
||||
|
||||
boolean isDefaultBootClassPathRtJar(File file) {
|
||||
BootClassPathLocationHandler h =
|
||||
(BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH);
|
||||
BootClassPathLocationHandler h
|
||||
= (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH);
|
||||
return h.isDefaultRtJar(file);
|
||||
}
|
||||
|
||||
@ -127,6 +133,7 @@ public class Locations {
|
||||
|
||||
/**
|
||||
* Split a path into its elements. Empty path elements will be ignored.
|
||||
*
|
||||
* @param path The path to be split
|
||||
* @return The elements of the path
|
||||
*/
|
||||
@ -135,12 +142,13 @@ public class Locations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a path into its elements. If emptyPathDefault is not null, all
|
||||
* empty elements in the path, including empty elements at either end of
|
||||
* the path, will be replaced with the value of emptyPathDefault.
|
||||
* Split a path into its elements. If emptyPathDefault is not null, all empty elements in the
|
||||
* path, including empty elements at either end of the path, will be replaced with the value of
|
||||
* emptyPathDefault.
|
||||
*
|
||||
* @param path The path to be split
|
||||
* @param emptyPathDefault The value to substitute for empty path elements,
|
||||
* or null, to ignore empty path elements
|
||||
* @param emptyPathDefault The value to substitute for empty path elements, or null, to ignore
|
||||
* empty path elements
|
||||
* @return The elements of the path
|
||||
*/
|
||||
private static Iterable<File> getPathEntries(String path, File emptyPathDefault) {
|
||||
@ -148,33 +156,38 @@ public class Locations {
|
||||
int start = 0;
|
||||
while (start <= path.length()) {
|
||||
int sep = path.indexOf(File.pathSeparatorChar, start);
|
||||
if (sep == -1)
|
||||
if (sep == -1) {
|
||||
sep = path.length();
|
||||
if (start < sep)
|
||||
}
|
||||
if (start < sep) {
|
||||
entries.add(new File(path.substring(start, sep)));
|
||||
else if (emptyPathDefault != null)
|
||||
} else if (emptyPathDefault != null) {
|
||||
entries.add(emptyPathDefault);
|
||||
}
|
||||
start = sep + 1;
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility class to help evaluate a path option.
|
||||
* Duplicate entries are ignored, jar class paths can be expanded.
|
||||
* Utility class to help evaluate a path option. Duplicate entries are ignored, jar class paths
|
||||
* can be expanded.
|
||||
*/
|
||||
private class Path extends LinkedHashSet<File> {
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
|
||||
private boolean expandJarClassPaths = false;
|
||||
private Set<File> canonicalValues = new HashSet<>();
|
||||
private final Set<File> canonicalValues = new HashSet<>();
|
||||
|
||||
public Path expandJarClassPaths(boolean x) {
|
||||
expandJarClassPaths = x;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** What to use when path element is the empty string */
|
||||
/**
|
||||
* What to use when path element is the empty string
|
||||
*/
|
||||
private File emptyPathDefault = null;
|
||||
|
||||
public Path emptyPathDefault(File x) {
|
||||
@ -182,15 +195,15 @@ public class Locations {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Path() { super(); }
|
||||
|
||||
public Path addDirectories(String dirs, boolean warn) {
|
||||
boolean prev = expandJarClassPaths;
|
||||
expandJarClassPaths = true;
|
||||
try {
|
||||
if (dirs != null)
|
||||
for (File dir : getPathEntries(dirs))
|
||||
if (dirs != null) {
|
||||
for (File dir : getPathEntries(dirs)) {
|
||||
addDirectory(dir, warn);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
} finally {
|
||||
expandJarClassPaths = prev;
|
||||
@ -203,19 +216,22 @@ public class Locations {
|
||||
|
||||
private void addDirectory(File dir, boolean warn) {
|
||||
if (!dir.isDirectory()) {
|
||||
if (warn)
|
||||
if (warn) {
|
||||
log.warning(Lint.LintCategory.PATH,
|
||||
"dir.path.element.not.found", dir);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
File[] files = dir.listFiles();
|
||||
if (files == null)
|
||||
if (files == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (File direntry : files) {
|
||||
if (isArchive(direntry))
|
||||
if (isArchive(direntry)) {
|
||||
addFile(direntry, warn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,8 +248,9 @@ public class Locations {
|
||||
|
||||
public Path addFiles(Iterable<? extends File> files, boolean warn) {
|
||||
if (files != null) {
|
||||
for (File file: files)
|
||||
for (File file : files) {
|
||||
addFile(file, warn);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -248,7 +265,7 @@ public class Locations {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! fsInfo.exists(file)) {
|
||||
if (!fsInfo.exists(file)) {
|
||||
/* No such file or directory exists */
|
||||
if (warn) {
|
||||
log.warning(Lint.LintCategory.PATH,
|
||||
@ -288,12 +305,13 @@ public class Locations {
|
||||
}
|
||||
|
||||
/* Now what we have left is either a directory or a file name
|
||||
conforming to archive naming convention */
|
||||
conforming to archive naming convention */
|
||||
super.add(file);
|
||||
canonicalValues.add(canonFile);
|
||||
|
||||
if (expandJarClassPaths && fsInfo.isFile(file))
|
||||
if (expandJarClassPaths && fsInfo.isFile(file)) {
|
||||
addJarClassPath(file, warn);
|
||||
}
|
||||
}
|
||||
|
||||
// Adds referenced classpath elements from a jar's Class-Path
|
||||
@ -302,7 +320,7 @@ public class Locations {
|
||||
// filenames, but if we do, we should redo all path-related code.
|
||||
private void addJarClassPath(File jarFile, boolean warn) {
|
||||
try {
|
||||
for (File f: fsInfo.getJarClassPath(jarFile)) {
|
||||
for (File f : fsInfo.getJarClassPath(jarFile)) {
|
||||
addFile(f, warn);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
@ -312,53 +330,56 @@ public class Locations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Base class for handling support for the representation of Locations.
|
||||
* Implementations are responsible for handling the interactions between
|
||||
* the command line options for a location, and API access via setLocation.
|
||||
* Base class for handling support for the representation of Locations. Implementations are
|
||||
* responsible for handling the interactions between the command line options for a location,
|
||||
* and API access via setLocation.
|
||||
*
|
||||
* @see #initHandlers
|
||||
* @see #getHandler
|
||||
*/
|
||||
protected abstract class LocationHandler {
|
||||
|
||||
final Location location;
|
||||
final Set<Option> options;
|
||||
|
||||
/**
|
||||
* Create a handler. The location and options provide a way to map
|
||||
* from a location or an option to the corresponding handler.
|
||||
* Create a handler. The location and options provide a way to map from a location or an
|
||||
* option to the corresponding handler.
|
||||
*
|
||||
* @param location the location for which this is the handler
|
||||
* @param options the options affecting this location
|
||||
* @see #initHandlers
|
||||
*/
|
||||
protected LocationHandler(Location location, Option... options) {
|
||||
this.location = location;
|
||||
this.options = options.length == 0 ?
|
||||
EnumSet.noneOf(Option.class):
|
||||
EnumSet.copyOf(Arrays.asList(options));
|
||||
this.options = options.length == 0
|
||||
? EnumSet.noneOf(Option.class)
|
||||
: EnumSet.copyOf(Arrays.asList(options));
|
||||
}
|
||||
|
||||
// TODO: TEMPORARY, while Options still used for command line options
|
||||
void update(Options optionTable) {
|
||||
for (Option o: options) {
|
||||
String v = optionTable.get(o);
|
||||
if (v != null) {
|
||||
handleOption(o, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @see JavaFileManager#handleOption */
|
||||
/**
|
||||
* @see JavaFileManager#handleOption
|
||||
*/
|
||||
abstract boolean handleOption(Option option, String value);
|
||||
/** @see StandardJavaFileManager#getLocation */
|
||||
|
||||
/**
|
||||
* @see StandardJavaFileManager#getLocation
|
||||
*/
|
||||
abstract Collection<File> getLocation();
|
||||
/** @see StandardJavaFileManager#setLocation */
|
||||
|
||||
/**
|
||||
* @see StandardJavaFileManager#setLocation
|
||||
*/
|
||||
abstract void setLocation(Iterable<? extends File> files) throws IOException;
|
||||
}
|
||||
|
||||
/**
|
||||
* General purpose implementation for output locations,
|
||||
* such as -d/CLASS_OUTPUT and -s/SOURCE_OUTPUT.
|
||||
* All options are treated as equivalent (i.e. aliases.)
|
||||
* The value is a single file, possibly null.
|
||||
* General purpose implementation for output locations, such as -d/CLASS_OUTPUT and
|
||||
* -s/SOURCE_OUTPUT. All options are treated as equivalent (i.e. aliases.) The value is a single
|
||||
* file, possibly null.
|
||||
*/
|
||||
private class OutputLocationHandler extends LocationHandler {
|
||||
|
||||
private File outputDir;
|
||||
|
||||
OutputLocationHandler(Location location, Option... options) {
|
||||
@ -367,14 +388,15 @@ public class Locations {
|
||||
|
||||
@Override
|
||||
boolean handleOption(Option option, String value) {
|
||||
if (!options.contains(option))
|
||||
if (!options.contains(option)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: could/should validate outputDir exists and is a directory
|
||||
// need to decide how best to report issue for benefit of
|
||||
// direct API call on JavaFileManager.handleOption(specifies IAE)
|
||||
// vs. command line decoding.
|
||||
outputDir = new File(value);
|
||||
outputDir = (value == null) ? null : new File(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -389,27 +411,30 @@ public class Locations {
|
||||
outputDir = null;
|
||||
} else {
|
||||
Iterator<? extends File> pathIter = files.iterator();
|
||||
if (!pathIter.hasNext())
|
||||
if (!pathIter.hasNext()) {
|
||||
throw new IllegalArgumentException("empty path for directory");
|
||||
}
|
||||
File dir = pathIter.next();
|
||||
if (pathIter.hasNext())
|
||||
if (pathIter.hasNext()) {
|
||||
throw new IllegalArgumentException("path too long for directory");
|
||||
if (!dir.exists())
|
||||
}
|
||||
if (!dir.exists()) {
|
||||
throw new FileNotFoundException(dir + ": does not exist");
|
||||
else if (!dir.isDirectory())
|
||||
} else if (!dir.isDirectory()) {
|
||||
throw new IOException(dir + ": not a directory");
|
||||
}
|
||||
outputDir = dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* General purpose implementation for search path locations,
|
||||
* such as -sourcepath/SOURCE_PATH and -processorPath/ANNOTATION_PROCESS_PATH.
|
||||
* All options are treated as equivalent (i.e. aliases.)
|
||||
* General purpose implementation for search path locations, such as -sourcepath/SOURCE_PATH and
|
||||
* -processorPath/ANNOTATION_PROCESS_PATH. All options are treated as equivalent (i.e. aliases.)
|
||||
* The value is an ordered set of files and/or directories.
|
||||
*/
|
||||
private class SimpleLocationHandler extends LocationHandler {
|
||||
|
||||
protected Collection<File> searchPath;
|
||||
|
||||
SimpleLocationHandler(Location location, Option... options) {
|
||||
@ -418,10 +443,11 @@ public class Locations {
|
||||
|
||||
@Override
|
||||
boolean handleOption(Option option, String value) {
|
||||
if (!options.contains(option))
|
||||
if (!options.contains(option)) {
|
||||
return false;
|
||||
searchPath = value == null ? null :
|
||||
Collections.unmodifiableCollection(createPath().addFiles(value));
|
||||
}
|
||||
searchPath = value == null ? null
|
||||
: Collections.unmodifiableCollection(createPath().addFiles(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -451,11 +477,11 @@ public class Locations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtype of SimpleLocationHandler for -classpath/CLASS_PATH.
|
||||
* If no value is given, a default is provided, based on system properties
|
||||
* and other values.
|
||||
* Subtype of SimpleLocationHandler for -classpath/CLASS_PATH. If no value is given, a default
|
||||
* is provided, based on system properties and other values.
|
||||
*/
|
||||
private class ClassPathLocationHandler extends SimpleLocationHandler {
|
||||
|
||||
ClassPathLocationHandler() {
|
||||
super(StandardLocation.CLASS_PATH,
|
||||
Option.CLASSPATH, Option.CP);
|
||||
@ -472,15 +498,20 @@ public class Locations {
|
||||
String cp = value;
|
||||
|
||||
// CLASSPATH environment variable when run from `javac'.
|
||||
if (cp == null) cp = System.getProperty("env.class.path");
|
||||
if (cp == null) {
|
||||
cp = System.getProperty("env.class.path");
|
||||
}
|
||||
|
||||
// If invoked via a java VM (not the javac launcher), use the
|
||||
// platform class path
|
||||
if (cp == null && System.getProperty("application.home") == null)
|
||||
if (cp == null && System.getProperty("application.home") == null) {
|
||||
cp = System.getProperty("java.class.path");
|
||||
}
|
||||
|
||||
// Default to current working directory.
|
||||
if (cp == null) cp = ".";
|
||||
if (cp == null) {
|
||||
cp = ".";
|
||||
}
|
||||
|
||||
return createPath().addFiles(cp);
|
||||
}
|
||||
@ -488,38 +519,37 @@ public class Locations {
|
||||
@Override
|
||||
protected Path createPath() {
|
||||
return new Path()
|
||||
.expandJarClassPaths(true) // Only search user jars for Class-Paths
|
||||
.emptyPathDefault(new File(".")); // Empty path elt ==> current directory
|
||||
.expandJarClassPaths(true) // Only search user jars for Class-Paths
|
||||
.emptyPathDefault(new File(".")); // Empty path elt ==> current directory
|
||||
}
|
||||
|
||||
private void lazy() {
|
||||
if (searchPath == null)
|
||||
if (searchPath == null) {
|
||||
setLocation(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom subtype of LocationHandler for PLATFORM_CLASS_PATH.
|
||||
* Various options are supported for different components of the
|
||||
* platform class path.
|
||||
* Setting a value with setLocation overrides all existing option values.
|
||||
* Setting any option overrides any value set with setLocation, and reverts
|
||||
* to using default values for options that have not been set.
|
||||
* Setting -bootclasspath or -Xbootclasspath overrides any existing
|
||||
* value for -Xbootclasspath/p: and -Xbootclasspath/a:.
|
||||
* Custom subtype of LocationHandler for PLATFORM_CLASS_PATH. Various options are supported for
|
||||
* different components of the platform class path. Setting a value with setLocation overrides
|
||||
* all existing option values. Setting any option overrides any value set with setLocation, and
|
||||
* reverts to using default values for options that have not been set. Setting -bootclasspath or
|
||||
* -Xbootclasspath overrides any existing value for -Xbootclasspath/p: and -Xbootclasspath/a:.
|
||||
*/
|
||||
private class BootClassPathLocationHandler extends LocationHandler {
|
||||
|
||||
private Collection<File> searchPath;
|
||||
final Map<Option, String> optionValues = new EnumMap<>(Option.class);
|
||||
|
||||
/**
|
||||
* rt.jar as found on the default bootclasspath.
|
||||
* If the user specified a bootclasspath, null is used.
|
||||
* rt.jar as found on the default bootclasspath. If the user specified a bootclasspath, null
|
||||
* is used.
|
||||
*/
|
||||
private File defaultBootClassPathRtJar = null;
|
||||
|
||||
/**
|
||||
* Is bootclasspath the default?
|
||||
* Is bootclasspath the default?
|
||||
*/
|
||||
private boolean isDefaultBootClassPath;
|
||||
|
||||
@ -544,8 +574,9 @@ public class Locations {
|
||||
|
||||
@Override
|
||||
boolean handleOption(Option option, String value) {
|
||||
if (!options.contains(option))
|
||||
if (!options.contains(option)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
option = canonicalize(option);
|
||||
optionValues.put(option, value);
|
||||
@ -557,20 +588,20 @@ public class Locations {
|
||||
return true;
|
||||
}
|
||||
// where
|
||||
// TODO: would be better if option aliasing was handled at a higher
|
||||
// level
|
||||
private Option canonicalize(Option option) {
|
||||
switch (option) {
|
||||
case XBOOTCLASSPATH:
|
||||
return Option.BOOTCLASSPATH;
|
||||
case DJAVA_ENDORSED_DIRS:
|
||||
return Option.ENDORSEDDIRS;
|
||||
case DJAVA_EXT_DIRS:
|
||||
return Option.EXTDIRS;
|
||||
default:
|
||||
return option;
|
||||
}
|
||||
// TODO: would be better if option aliasing was handled at a higher
|
||||
// level
|
||||
private Option canonicalize(Option option) {
|
||||
switch (option) {
|
||||
case XBOOTCLASSPATH:
|
||||
return Option.BOOTCLASSPATH;
|
||||
case DJAVA_ENDORSED_DIRS:
|
||||
return Option.ENDORSEDDIRS;
|
||||
case DJAVA_EXT_DIRS:
|
||||
return Option.EXTDIRS;
|
||||
default:
|
||||
return option;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Collection<File> getLocation() {
|
||||
@ -602,10 +633,11 @@ public class Locations {
|
||||
String xbootclasspathAppendOpt = optionValues.get(XBOOTCLASSPATH_APPEND);
|
||||
path.addFiles(xbootclasspathPrependOpt);
|
||||
|
||||
if (endorseddirsOpt != null)
|
||||
if (endorseddirsOpt != null) {
|
||||
path.addDirectories(endorseddirsOpt);
|
||||
else
|
||||
} else {
|
||||
path.addDirectories(System.getProperty("java.endorsed.dirs"), false);
|
||||
}
|
||||
|
||||
if (bootclasspathOpt != null) {
|
||||
path.addFiles(bootclasspathOpt);
|
||||
@ -615,8 +647,9 @@ public class Locations {
|
||||
path.addFiles(files, false);
|
||||
File rt_jar = new File("rt.jar");
|
||||
for (File file : getPathEntries(files)) {
|
||||
if (new File(file.getName()).equals(rt_jar))
|
||||
if (new File(file.getName()).equals(rt_jar)) {
|
||||
defaultBootClassPathRtJar = file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -625,22 +658,24 @@ public class Locations {
|
||||
// Strictly speaking, standard extensions are not bootstrap
|
||||
// classes, but we treat them identically, so we'll pretend
|
||||
// that they are.
|
||||
if (extdirsOpt != null)
|
||||
if (extdirsOpt != null) {
|
||||
path.addDirectories(extdirsOpt);
|
||||
else
|
||||
} else {
|
||||
path.addDirectories(System.getProperty("java.ext.dirs"), false);
|
||||
}
|
||||
|
||||
isDefaultBootClassPath =
|
||||
(xbootclasspathPrependOpt == null) &&
|
||||
(bootclasspathOpt == null) &&
|
||||
(xbootclasspathAppendOpt == null);
|
||||
isDefaultBootClassPath
|
||||
= (xbootclasspathPrependOpt == null)
|
||||
&& (bootclasspathOpt == null)
|
||||
&& (xbootclasspathAppendOpt == null);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
private void lazy() {
|
||||
if (searchPath == null)
|
||||
if (searchPath == null) {
|
||||
searchPath = Collections.unmodifiableCollection(computePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -661,14 +696,15 @@ public class Locations {
|
||||
new OutputLocationHandler((StandardLocation.NATIVE_HEADER_OUTPUT), Option.H)
|
||||
};
|
||||
|
||||
for (LocationHandler h: handlers) {
|
||||
for (LocationHandler h : handlers) {
|
||||
handlersForLocation.put(h.location, h);
|
||||
for (Option o: h.options)
|
||||
for (Option o : h.options) {
|
||||
handlersForOption.put(o, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean handleOption(Option option, String value) {
|
||||
public boolean handleOption(Option option, String value) {
|
||||
LocationHandler h = handlersForOption.get(option);
|
||||
return (h == null ? false : h.handleOption(option, value));
|
||||
}
|
||||
@ -679,8 +715,9 @@ public class Locations {
|
||||
}
|
||||
|
||||
File getOutputLocation(Location location) {
|
||||
if (!location.isOutputLocation())
|
||||
if (!location.isOutputLocation()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
LocationHandler h = getHandler(location);
|
||||
return ((OutputLocationHandler) h).outputDir;
|
||||
}
|
||||
@ -688,10 +725,11 @@ public class Locations {
|
||||
void setLocation(Location location, Iterable<? extends File> files) throws IOException {
|
||||
LocationHandler h = getHandler(location);
|
||||
if (h == null) {
|
||||
if (location.isOutputLocation())
|
||||
if (location.isOutputLocation()) {
|
||||
h = new OutputLocationHandler(location);
|
||||
else
|
||||
} else {
|
||||
h = new SimpleLocationHandler(location);
|
||||
}
|
||||
handlersForLocation.put(location, h);
|
||||
}
|
||||
h.setLocation(files);
|
||||
@ -699,33 +737,21 @@ public class Locations {
|
||||
|
||||
protected LocationHandler getHandler(Location location) {
|
||||
location.getClass(); // null check
|
||||
lazy();
|
||||
return handlersForLocation.get(location);
|
||||
}
|
||||
|
||||
// TOGO
|
||||
protected void lazy() {
|
||||
if (!inited) {
|
||||
warn = lint.isEnabled(Lint.LintCategory.PATH);
|
||||
|
||||
for (LocationHandler h: handlersForLocation.values()) {
|
||||
h.update(options);
|
||||
}
|
||||
|
||||
inited = true;
|
||||
}
|
||||
}
|
||||
|
||||
/** Is this the name of an archive file? */
|
||||
/**
|
||||
* Is this the name of an archive file?
|
||||
*/
|
||||
private boolean isArchive(File file) {
|
||||
String n = StringUtils.toLowerCase(file.getName());
|
||||
return fsInfo.isFile(file)
|
||||
&& (n.endsWith(".jar") || n.endsWith(".zip"));
|
||||
&& (n.endsWith(".jar") || n.endsWith(".zip"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for converting a search path string to an array
|
||||
* of directory and JAR file URLs.
|
||||
* Utility method for converting a search path string to an array of directory and JAR file
|
||||
* URLs.
|
||||
*
|
||||
* Note that this method is called by apt and the DocletInvoker.
|
||||
*
|
||||
@ -747,8 +773,7 @@ public class Locations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory or JAR file URL corresponding to the specified
|
||||
* local file name.
|
||||
* Returns the directory or JAR file URL corresponding to the specified local file name.
|
||||
*
|
||||
* @param file the File object
|
||||
* @return the resulting directory or JAR file URL, or null if unknown
|
||||
|
@ -394,6 +394,7 @@ public class JavaCompiler {
|
||||
processPcks = options.isSet("process.packages");
|
||||
werror = options.isSet(WERROR);
|
||||
|
||||
// Should this be with other option checking, in Main
|
||||
if (source.compareTo(Source.DEFAULT) < 0) {
|
||||
if (options.isUnset(XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option)) {
|
||||
if (fileManager instanceof BaseFileManager) {
|
||||
@ -403,6 +404,7 @@ public class JavaCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
// Should this be with other option checking, in Main
|
||||
checkForObsoleteOptions(target);
|
||||
|
||||
verboseCompilePolicy = options.isSet("verboseCompilePolicy");
|
||||
@ -434,6 +436,7 @@ public class JavaCompiler {
|
||||
log.setDiagnosticFormatter(RichDiagnosticFormatter.instance(context));
|
||||
}
|
||||
|
||||
// Should this be with other option checking, in Main
|
||||
private void checkForObsoleteOptions(Target target) {
|
||||
// Unless lint checking on options is disabled, check for
|
||||
// obsolete source and target options.
|
||||
|
@ -33,8 +33,9 @@ import java.security.DigestInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.Processor;
|
||||
@ -56,6 +57,7 @@ import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.Log.PrefixKind;
|
||||
import com.sun.tools.javac.util.Log.WriterKind;
|
||||
import com.sun.tools.javac.util.ServiceLoader;
|
||||
|
||||
import static com.sun.tools.javac.main.Option.*;
|
||||
|
||||
/** This class provides a command line interface to the javac compiler.
|
||||
@ -120,6 +122,13 @@ public class Main {
|
||||
options.put(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleFileManagerOption(Option option, String value) {
|
||||
options.put(option.getText(), value);
|
||||
deferredFileManagerOptions.put(option, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(String name) {
|
||||
options.remove(name);
|
||||
@ -172,11 +181,13 @@ public class Main {
|
||||
|
||||
/** The list of source files to process
|
||||
*/
|
||||
public Set<File> filenames = null; // XXX sb protected
|
||||
public Set<File> filenames = null; // XXX should be protected or private
|
||||
|
||||
/** List of class files names passed on the command line
|
||||
*/
|
||||
public ListBuffer<String> classnames = null; // XXX sb protected
|
||||
protected ListBuffer<String> classnames = null;
|
||||
|
||||
public Map<Option, String> deferredFileManagerOptions; // XXX should be protected or private
|
||||
|
||||
/** Report a usage error.
|
||||
*/
|
||||
@ -395,6 +406,7 @@ public class Main {
|
||||
|
||||
filenames = new LinkedHashSet<>();
|
||||
classnames = new ListBuffer<>();
|
||||
deferredFileManagerOptions = new LinkedHashMap<>();
|
||||
JavaCompiler comp = null;
|
||||
/*
|
||||
* TODO: Logic below about what is an acceptable command line
|
||||
@ -446,6 +458,11 @@ public class Main {
|
||||
if (batchMode)
|
||||
CacheFSInfo.preRegister(context);
|
||||
|
||||
fileManager = context.get(JavaFileManager.class);
|
||||
if (fileManager instanceof BaseFileManager) {
|
||||
((BaseFileManager) fileManager).handleOptions(deferredFileManagerOptions);
|
||||
}
|
||||
|
||||
// FIXME: this code will not be invoked if using JavacTask.parse/analyze/generate
|
||||
// invoke any available plugins
|
||||
String plugins = options.get(PLUGIN);
|
||||
@ -511,8 +528,6 @@ public class Main {
|
||||
comp.closeables = comp.closeables.prepend(log.getWriter(WriterKind.NOTICE));
|
||||
}
|
||||
|
||||
fileManager = context.get(JavaFileManager.class);
|
||||
|
||||
if (!files.isEmpty()) {
|
||||
// add filenames to fileObjects
|
||||
comp = JavaCompiler.instance(context);
|
||||
|
@ -83,6 +83,7 @@ public enum Option {
|
||||
|
||||
XLINT_CUSTOM("-Xlint:", EXTENDED, BASIC, ANYOF, getXLintChoices()) {
|
||||
private static final String LINT_KEY_FORMAT = " %-19s %s";
|
||||
@Override
|
||||
void help(Log log, OptionKind kind) {
|
||||
if (this.kind != kind)
|
||||
return;
|
||||
@ -667,6 +668,8 @@ public enum Option {
|
||||
}
|
||||
}
|
||||
helper.put(option, arg);
|
||||
if (group == OptionGroup.FILEMANAGER)
|
||||
helper.handleFileManagerOption(this, arg);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -50,6 +50,9 @@ public abstract class OptionHelper {
|
||||
/** Remove any prior value for an option. */
|
||||
public abstract void remove(String name);
|
||||
|
||||
/** Handle a file manager option. */
|
||||
public abstract boolean handleFileManagerOption(Option option, String value);
|
||||
|
||||
/** Get access to the Log for the compilation. */
|
||||
public abstract Log getLog();
|
||||
|
||||
@ -98,6 +101,11 @@ public abstract class OptionHelper {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleFileManagerOption(Option option, String value) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
@Override
|
||||
void error(String key, Object... args) {
|
||||
throw new IllegalArgumentException(log.localize(PrefixKind.JAVAC, key, args));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -167,11 +167,6 @@ public class JavacPathFileManager extends BaseFileManager implements PathFileMan
|
||||
return getClassLoader(lb.toArray(new URL[lb.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefaultBootClassPath() {
|
||||
return locations.isDefaultBootClassPath();
|
||||
}
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Location handling">
|
||||
|
||||
public boolean hasLocation(Location location) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,7 +26,6 @@
|
||||
package com.sun.tools.javac.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
@ -47,6 +46,8 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.JavaFileObject.Kind;
|
||||
|
||||
@ -64,7 +65,7 @@ import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
|
||||
* There are no references here to file-system specific objects such as
|
||||
* java.io.File or java.nio.file.Path.
|
||||
*/
|
||||
public abstract class BaseFileManager {
|
||||
public abstract class BaseFileManager implements JavaFileManager {
|
||||
protected BaseFileManager(Charset charset) {
|
||||
this.charset = charset;
|
||||
byteBufferCache = new ByteBufferCache();
|
||||
@ -73,12 +74,13 @@ public abstract class BaseFileManager {
|
||||
|
||||
/**
|
||||
* Set the context for JavacPathFileManager.
|
||||
* @param context the context containing items to be associated with the file manager
|
||||
*/
|
||||
public void setContext(Context context) {
|
||||
log = Log.instance(context);
|
||||
options = Options.instance(context);
|
||||
classLoaderClass = options.get("procloader");
|
||||
locations.update(log, options, Lint.instance(context), FSInfo.instance(context));
|
||||
locations.update(log, Lint.instance(context), FSInfo.instance(context));
|
||||
}
|
||||
|
||||
protected Locations createLocations() {
|
||||
@ -123,14 +125,19 @@ public abstract class BaseFileManager {
|
||||
Class<?>[] constrArgTypes = { URL[].class, ClassLoader.class };
|
||||
Constructor<? extends ClassLoader> constr = loader.getConstructor(constrArgTypes);
|
||||
return constr.newInstance(urls, thisClassLoader);
|
||||
} catch (Throwable t) {
|
||||
} catch (ReflectiveOperationException t) {
|
||||
// ignore errors loading user-provided class loader, fall through
|
||||
}
|
||||
}
|
||||
return new URLClassLoader(urls, thisClassLoader);
|
||||
}
|
||||
|
||||
public boolean isDefaultBootClassPath() {
|
||||
return locations.isDefaultBootClassPath();
|
||||
}
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Option handling">
|
||||
@Override
|
||||
public boolean handleOption(String current, Iterator<String> remaining) {
|
||||
OptionHelper helper = new GrumpyHelper(log) {
|
||||
@Override
|
||||
@ -147,7 +154,13 @@ public abstract class BaseFileManager {
|
||||
public void remove(String name) {
|
||||
options.remove(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleFileManagerOption(Option option, String value) {
|
||||
return handleOption(option, value);
|
||||
}
|
||||
};
|
||||
|
||||
for (Option o: javacFileManagerOptions) {
|
||||
if (o.matches(current)) {
|
||||
if (o.hasArg()) {
|
||||
@ -159,7 +172,7 @@ public abstract class BaseFileManager {
|
||||
if (!o.process(helper, current))
|
||||
return true;
|
||||
}
|
||||
// operand missing, or process returned false
|
||||
// operand missing, or process returned true
|
||||
throw new IllegalArgumentException(current);
|
||||
}
|
||||
}
|
||||
@ -170,6 +183,7 @@ public abstract class BaseFileManager {
|
||||
private static final Set<Option> javacFileManagerOptions =
|
||||
Option.getJavacFileManagerOptions();
|
||||
|
||||
@Override
|
||||
public int isSupportedOption(String option) {
|
||||
for (Option o : javacFileManagerOptions) {
|
||||
if (o.matches(option))
|
||||
@ -178,7 +192,27 @@ public abstract class BaseFileManager {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public abstract boolean isDefaultBootClassPath();
|
||||
/**
|
||||
* Common back end for OptionHelper handleFileManagerOption.
|
||||
* @param option the option whose value to be set
|
||||
* @param value the value for the option
|
||||
* @return true if successful, and false otherwise
|
||||
*/
|
||||
public boolean handleOption(Option option, String value) {
|
||||
return locations.handleOption(option, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call handleOption for collection of options and corresponding values.
|
||||
* @param map a collection of options and corresponding values
|
||||
* @return true if all the calls are successful
|
||||
*/
|
||||
public boolean handleOptions(Map<Option, String> map) {
|
||||
boolean ok = true;
|
||||
for (Map.Entry<Option, String> e: map.entrySet())
|
||||
ok = ok & handleOption(e.getKey(), e.getValue());
|
||||
return ok;
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
|
||||
@ -205,10 +239,7 @@ public abstract class BaseFileManager {
|
||||
CharsetDecoder decoder;
|
||||
try {
|
||||
decoder = getDecoder(encodingName, ignoreEncodingErrors);
|
||||
} catch (IllegalCharsetNameException e) {
|
||||
log.error("unsupported.encoding", encodingName);
|
||||
return (CharBuffer)CharBuffer.allocate(1).flip();
|
||||
} catch (UnsupportedCharsetException e) {
|
||||
} catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
|
||||
log.error("unsupported.encoding", encodingName);
|
||||
return (CharBuffer)CharBuffer.allocate(1).flip();
|
||||
}
|
||||
@ -286,6 +317,9 @@ public abstract class BaseFileManager {
|
||||
// <editor-fold defaultstate="collapsed" desc="ByteBuffers">
|
||||
/**
|
||||
* Make a byte buffer from an input stream.
|
||||
* @param in the stream
|
||||
* @return a byte buffer containing the contents of the stream
|
||||
* @throws IOException if an error occurred while reading the stream
|
||||
*/
|
||||
public ByteBuffer makeByteBuffer(InputStream in)
|
||||
throws IOException {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,18 +32,23 @@ import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.javadoc.*;
|
||||
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.util.BaseFileManager;
|
||||
import com.sun.tools.javac.util.ClientCodeException;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
import com.sun.tools.javac.util.Log;
|
||||
import com.sun.tools.javac.util.Options;
|
||||
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
|
||||
/**
|
||||
@ -71,7 +76,7 @@ public class Start extends ToolOption.Helper {
|
||||
private static final String standardDocletClassName =
|
||||
"com.sun.tools.doclets.standard.Standard";
|
||||
|
||||
private long defaultFilter = PUBLIC | PROTECTED;
|
||||
private final long defaultFilter = PUBLIC | PROTECTED;
|
||||
|
||||
private final Messager messager;
|
||||
|
||||
@ -324,6 +329,15 @@ public class Start extends ToolOption.Helper {
|
||||
javaNames.append(arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (fileManager == null) {
|
||||
JavacFileManager.preRegister(context);
|
||||
fileManager = context.get(JavaFileManager.class);
|
||||
}
|
||||
if (fileManager instanceof BaseFileManager) {
|
||||
((BaseFileManager) fileManager).handleOptions(fileManagerOpts);
|
||||
}
|
||||
|
||||
compOpts.notifyListeners();
|
||||
|
||||
if (javaNames.isEmpty() && subPackages.isEmpty() && isEmpty(fileObjects)) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,10 +25,14 @@
|
||||
|
||||
package com.sun.tools.javadoc;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.main.Option;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
import com.sun.tools.javac.util.Options;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
|
||||
/**
|
||||
@ -45,42 +49,42 @@ public enum ToolOption {
|
||||
BOOTCLASSPATH("-bootclasspath", true) {
|
||||
@Override
|
||||
public void process(Helper helper, String arg) {
|
||||
helper.setCompilerOpt(opt, arg);
|
||||
helper.setFileManagerOpt(Option.BOOTCLASSPATH, arg);
|
||||
}
|
||||
},
|
||||
|
||||
CLASSPATH("-classpath", true) {
|
||||
@Override
|
||||
public void process(Helper helper, String arg) {
|
||||
helper.setCompilerOpt(opt, arg);
|
||||
helper.setFileManagerOpt(Option.CLASSPATH, arg);
|
||||
}
|
||||
},
|
||||
|
||||
CP("-cp", true) {
|
||||
@Override
|
||||
public void process(Helper helper, String arg) {
|
||||
helper.setCompilerOpt(opt, arg);
|
||||
helper.setFileManagerOpt(Option.CP, arg);
|
||||
}
|
||||
},
|
||||
|
||||
EXTDIRS("-extdirs", true) {
|
||||
@Override
|
||||
public void process(Helper helper, String arg) {
|
||||
helper.setCompilerOpt(opt, arg);
|
||||
helper.setFileManagerOpt(Option.EXTDIRS, arg);
|
||||
}
|
||||
},
|
||||
|
||||
SOURCEPATH("-sourcepath", true) {
|
||||
@Override
|
||||
public void process(Helper helper, String arg) {
|
||||
helper.setCompilerOpt(opt, arg);
|
||||
helper.setFileManagerOpt(Option.SOURCEPATH, arg);
|
||||
}
|
||||
},
|
||||
|
||||
SYSCLASSPATH("-sysclasspath", true) {
|
||||
@Override
|
||||
public void process(Helper helper, String arg) {
|
||||
helper.setCompilerOpt("-bootclasspath", arg);
|
||||
helper.setFileManagerOpt(Option.BOOTCLASSPATH, arg);
|
||||
}
|
||||
},
|
||||
|
||||
@ -274,6 +278,9 @@ public enum ToolOption {
|
||||
/** Excluded packages, from -exclude. */
|
||||
final ListBuffer<String> excludedPackages = new ListBuffer<>();
|
||||
|
||||
// File manager options
|
||||
final Map<Option, String> fileManagerOpts = new LinkedHashMap<>();
|
||||
|
||||
/** javac options, set by various options. */
|
||||
Options compOpts; // = Options.instance(context)
|
||||
|
||||
@ -306,7 +313,7 @@ public enum ToolOption {
|
||||
|
||||
abstract void usageError(String msg, Object... args);
|
||||
|
||||
protected void addToList(ListBuffer<String> list, String str){
|
||||
void addToList(ListBuffer<String> list, String str){
|
||||
StringTokenizer st = new StringTokenizer(str, ":");
|
||||
String current;
|
||||
while(st.hasMoreTokens()){
|
||||
@ -315,18 +322,22 @@ public enum ToolOption {
|
||||
}
|
||||
}
|
||||
|
||||
protected void setFilter(long filterBits) {
|
||||
void setFilter(long filterBits) {
|
||||
if (showAccess != null) {
|
||||
usageError("main.incompatible.access.flags");
|
||||
}
|
||||
showAccess = new ModifierFilter(filterBits);
|
||||
}
|
||||
|
||||
private void setCompilerOpt(String opt, String arg) {
|
||||
void setCompilerOpt(String opt, String arg) {
|
||||
if (compOpts.get(opt) != null) {
|
||||
usageError("main.option.already.seen", opt);
|
||||
}
|
||||
compOpts.put(opt, arg);
|
||||
}
|
||||
|
||||
void setFileManagerOpt(Option opt, String arg) {
|
||||
fileManagerOpts.put(opt, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -57,12 +57,8 @@ public class T6358166 extends AbstractProcessor {
|
||||
|
||||
static void test(JavacFileManager fm, JavaFileObject f, String... args) throws Throwable {
|
||||
Context context = new Context();
|
||||
fm.setContext(context);
|
||||
|
||||
Main compilerMain = new Main("javac", new PrintWriter(System.err, true));
|
||||
compilerMain.setOptions(Options.instance(context));
|
||||
compilerMain.filenames = new LinkedHashSet<File>();
|
||||
compilerMain.processArgs(args);
|
||||
Main compilerMain = initCompilerMain(context, fm, args);
|
||||
|
||||
JavaCompiler c = JavaCompiler.instance(context);
|
||||
|
||||
@ -76,6 +72,19 @@ public class T6358166 extends AbstractProcessor {
|
||||
throw new AssertionError("elapsed time is suspect: " + msec);
|
||||
}
|
||||
|
||||
static Main initCompilerMain(Context context, JavacFileManager fm, String... args) {
|
||||
fm.setContext(context);
|
||||
context.put(JavaFileManager.class, fm);
|
||||
|
||||
Main compilerMain = new Main("javac", new PrintWriter(System.err, true));
|
||||
compilerMain.setOptions(Options.instance(context));
|
||||
compilerMain.filenames = new LinkedHashSet<File>();
|
||||
compilerMain.deferredFileManagerOptions = new LinkedHashMap<>();
|
||||
compilerMain.processArgs(args);
|
||||
fm.handleOptions(compilerMain.deferredFileManagerOptions);
|
||||
return compilerMain;
|
||||
}
|
||||
|
||||
public boolean process(Set<? extends TypeElement> tes, RoundEnvironment renv) {
|
||||
return true;
|
||||
}
|
||||
|
@ -68,12 +68,9 @@ public class T6358168 extends AbstractProcessor {
|
||||
|
||||
static void testNoAnnotationProcessing(JavacFileManager fm, JavaFileObject f) throws Throwable {
|
||||
Context context = new Context();
|
||||
fm.setContext(context);
|
||||
|
||||
Main compilerMain = new Main("javac", new PrintWriter(System.err, true));
|
||||
compilerMain.setOptions(Options.instance(context));
|
||||
compilerMain.filenames = new LinkedHashSet<File>();
|
||||
compilerMain.processArgs(new String[] { "-d", "." });
|
||||
String[] args = { "-d", "." };
|
||||
Main compilerMain = initCompilerMain(context, fm, args);
|
||||
|
||||
JavaCompiler compiler = JavaCompiler.instance(context);
|
||||
compiler.compile(List.of(f));
|
||||
@ -87,16 +84,14 @@ public class T6358168 extends AbstractProcessor {
|
||||
|
||||
static void testAnnotationProcessing(JavacFileManager fm, JavaFileObject f) throws Throwable {
|
||||
Context context = new Context();
|
||||
fm.setContext(context);
|
||||
|
||||
Main compilerMain = new Main("javac", new PrintWriter(System.err, true));
|
||||
compilerMain.setOptions(Options.instance(context));
|
||||
compilerMain.filenames = new LinkedHashSet<File>();
|
||||
compilerMain.processArgs(new String[] {
|
||||
"-XprintRounds",
|
||||
"-processorpath", testClasses,
|
||||
"-processor", self,
|
||||
"-d", "."});
|
||||
String[] args = {
|
||||
"-XprintRounds",
|
||||
"-processorpath", testClasses,
|
||||
"-processor", self,
|
||||
"-d", "."
|
||||
};
|
||||
Main compilerMain = initCompilerMain(context, fm, args);
|
||||
|
||||
JavaCompiler compiler = JavaCompiler.instance(context);
|
||||
compiler.compile(List.of(f));
|
||||
@ -108,6 +103,19 @@ public class T6358168 extends AbstractProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
static Main initCompilerMain(Context context, JavacFileManager fm, String... args) {
|
||||
fm.setContext(context);
|
||||
context.put(JavaFileManager.class, fm);
|
||||
|
||||
Main compilerMain = new Main("javac", new PrintWriter(System.err, true));
|
||||
compilerMain.setOptions(Options.instance(context));
|
||||
compilerMain.filenames = new LinkedHashSet<File>();
|
||||
compilerMain.deferredFileManagerOptions = new LinkedHashMap<>();
|
||||
compilerMain.processArgs(args);
|
||||
fm.handleOptions(compilerMain.deferredFileManagerOptions);
|
||||
return compilerMain;
|
||||
}
|
||||
|
||||
public boolean process(Set<? extends TypeElement> tes, RoundEnvironment renv) {
|
||||
return true;
|
||||
}
|
||||
|
632
langtools/test/tools/javac/api/TestSearchPaths.java
Normal file
632
langtools/test/tools/javac/api/TestSearchPaths.java
Normal file
@ -0,0 +1,632 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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 7026941
|
||||
* @summary path options ignored when reusing filemanager across tasks
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaCompiler.CompilationTask;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.StandardLocation;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
import static javax.tools.StandardLocation.*;
|
||||
|
||||
/**
|
||||
* Test for combinations of using javac command-line options and fileManager setLocation
|
||||
* calls to affect the locations available in the fileManager.
|
||||
*
|
||||
* Using a single Java compiler and file manager, for each of the standard locations,
|
||||
* a series of operations is performed, using either compiler options or setLocation
|
||||
* calls. Each operation includes a compilation, and then a check for the value of
|
||||
* the standard location available in the file manager.
|
||||
*
|
||||
* The operations generate and use unique files to minimize the possibility of false
|
||||
* positive results.
|
||||
*/
|
||||
public class TestSearchPaths {
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
TestSearchPaths t = new TestSearchPaths();
|
||||
t.run();
|
||||
}
|
||||
|
||||
void run() throws Exception {
|
||||
compiler = ToolProvider.getSystemJavaCompiler();
|
||||
fileManager = compiler.getStandardFileManager(null, null, null);
|
||||
|
||||
// basic output path
|
||||
testClassOutput();
|
||||
|
||||
// basic search paths
|
||||
testClassPath();
|
||||
testSourcePath();
|
||||
testPlatformClassPath();
|
||||
|
||||
// annotation processing
|
||||
testAnnotationProcessorPath();
|
||||
testSourceOutput();
|
||||
|
||||
// javah equivalent
|
||||
testNativeHeaderOutput();
|
||||
|
||||
// future-proof: guard against new StandardLocations being added
|
||||
if (!tested.equals(EnumSet.allOf(StandardLocation.class))) {
|
||||
error("not all standard locations have been tested");
|
||||
out.println("not yet tested: " + EnumSet.complementOf(tested));
|
||||
}
|
||||
|
||||
if (errors > 0) {
|
||||
throw new Exception(errors + " errors occurred");
|
||||
}
|
||||
}
|
||||
|
||||
void testClassOutput() throws IOException {
|
||||
String test = "testClassOutput";
|
||||
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
File classes = createDir(test + "/" + i + "/classes");
|
||||
List<String> options;
|
||||
switch (i) {
|
||||
default:
|
||||
options = getOptions("-d", classes.getPath());
|
||||
break;
|
||||
|
||||
case 3:
|
||||
setLocation(CLASS_OUTPUT, classes);
|
||||
options = null;
|
||||
break;
|
||||
}
|
||||
List<JavaFileObject> sources = getSources("class C" + i + " { }");
|
||||
callTask(options, sources);
|
||||
checkPath(CLASS_OUTPUT, Mode.EQUALS, classes);
|
||||
checkFile(CLASS_OUTPUT, "C" + i + ".class");
|
||||
}
|
||||
|
||||
tested.add(CLASS_OUTPUT);
|
||||
}
|
||||
|
||||
void testClassPath() throws IOException {
|
||||
String test = "testClassPath";
|
||||
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
File classes = createDir(test + "/" + i + "/classes");
|
||||
File classpath = new File("testClassOutput/" + i + "/classes");
|
||||
List<String> options;
|
||||
switch (i) {
|
||||
default:
|
||||
options = getOptions("-d", classes.getPath(), "-classpath", classpath.getPath());
|
||||
break;
|
||||
|
||||
case 3:
|
||||
setLocation(CLASS_PATH, classpath);
|
||||
options = getOptions("-d", classes.getPath());
|
||||
break;
|
||||
|
||||
case 4:
|
||||
options = getOptions("-d", classes.getPath(), "-cp", classpath.getPath());
|
||||
break;
|
||||
}
|
||||
List<JavaFileObject> sources = getSources("class D" + i + " { C" + i + " c; }");
|
||||
callTask(options, sources);
|
||||
checkPath(CLASS_PATH, Mode.EQUALS, classpath);
|
||||
checkFile(CLASS_OUTPUT, "D" + i + ".class");
|
||||
}
|
||||
|
||||
tested.add(CLASS_PATH);
|
||||
}
|
||||
|
||||
void testSourcePath() throws IOException {
|
||||
String test = "testSourcePath";
|
||||
setLocation(CLASS_PATH); // empty
|
||||
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
File src = createDir(test + "/" + i + "/src");
|
||||
writeFile(src, "C" + i + ".java", "class C" + i + "{ }");
|
||||
File classes = createDir(test + "/" + i + "/classes");
|
||||
File srcpath = src;
|
||||
List<String> options;
|
||||
switch (i) {
|
||||
default:
|
||||
options = getOptions("-d", classes.getPath(), "-sourcepath", srcpath.getPath());
|
||||
break;
|
||||
|
||||
case 3:
|
||||
setLocation(SOURCE_PATH, srcpath);
|
||||
options = getOptions("-d", classes.getPath());
|
||||
break;
|
||||
}
|
||||
List<JavaFileObject> sources = getSources("class D" + i + " { C" + i + " c; }");
|
||||
callTask(options, sources);
|
||||
checkPath(SOURCE_PATH, Mode.EQUALS, srcpath);
|
||||
checkFile(CLASS_OUTPUT, "D" + i + ".class");
|
||||
}
|
||||
|
||||
tested.add(SOURCE_PATH);
|
||||
}
|
||||
|
||||
void testPlatformClassPath() throws IOException {
|
||||
String test = "testPlatformClassPath";
|
||||
|
||||
List<File> defaultPath = getLocation(PLATFORM_CLASS_PATH);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (File f: defaultPath) {
|
||||
if (sb.length() > 0)
|
||||
sb.append(File.pathSeparator);
|
||||
sb.append(f);
|
||||
}
|
||||
String defaultPathString = sb.toString();
|
||||
|
||||
setLocation(CLASS_PATH); // empty
|
||||
setLocation(SOURCE_PATH); // empty
|
||||
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
File classes = createDir(test + "/" + i + "/classes");
|
||||
File testJars = createDir(test + "/" + i + "/testJars");
|
||||
File testClasses = createDir(test + "/" + i + "/testClasses");
|
||||
callTask(getOptions("-d", testClasses.getPath()), getSources("class C" + i + " { }"));
|
||||
|
||||
List<String> options;
|
||||
Mode mode;
|
||||
List<File> match;
|
||||
String reference = "C" + i + " c;";
|
||||
|
||||
File jar;
|
||||
|
||||
switch (i) {
|
||||
case 1:
|
||||
options = getOptions("-d", classes.getPath(), "-Xbootclasspath/p:" + testClasses);
|
||||
mode = Mode.STARTS_WITH;
|
||||
match = Arrays.asList(testClasses);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// the default values for -extdirs and -endorseddirs come after the bootclasspath;
|
||||
// so to check -Xbootclasspath/a: we specify empty values for those options.
|
||||
options = getOptions("-d", classes.getPath(),
|
||||
"-Xbootclasspath/a:" + testClasses,
|
||||
"-extdirs", "",
|
||||
"-endorseddirs", "");
|
||||
mode = Mode.ENDS_WITH;
|
||||
match = Arrays.asList(testClasses);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
options = getOptions("-d", classes.getPath(), "-Xbootclasspath:" + defaultPathString);
|
||||
mode = Mode.EQUALS;
|
||||
match = defaultPath;
|
||||
reference = "";
|
||||
break;
|
||||
|
||||
case 4:
|
||||
fileManager.setLocation(PLATFORM_CLASS_PATH, null);
|
||||
jar = new File(testJars, "j" + i + ".jar");
|
||||
writeJar(jar, testClasses, "C" + i + ".class");
|
||||
options = getOptions("-d", classes.getPath(), "-endorseddirs", testJars.getPath());
|
||||
mode = Mode.CONTAINS;
|
||||
match = Arrays.asList(jar);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
fileManager.setLocation(PLATFORM_CLASS_PATH, null);
|
||||
jar = new File(testJars, "j" + i + ".jar");
|
||||
writeJar(jar, testClasses, "C" + i + ".class");
|
||||
options = getOptions("-d", classes.getPath(), "-Djava.endorsed.dirs=" + testJars.getPath());
|
||||
mode = Mode.CONTAINS;
|
||||
match = Arrays.asList(jar);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
fileManager.setLocation(PLATFORM_CLASS_PATH, null);
|
||||
jar = new File(testJars, "j" + i + ".jar");
|
||||
writeJar(jar, testClasses, "C" + i + ".class");
|
||||
options = getOptions("-d", classes.getPath(), "-extdirs", testJars.getPath());
|
||||
mode = Mode.CONTAINS;
|
||||
match = Arrays.asList(jar);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
fileManager.setLocation(PLATFORM_CLASS_PATH, null);
|
||||
jar = new File(testJars, "j" + i + ".jar");
|
||||
writeJar(jar, testClasses, "C" + i + ".class");
|
||||
options = getOptions("-d", classes.getPath(), "-Djava.ext.dirs=" + testJars.getPath());
|
||||
mode = Mode.CONTAINS;
|
||||
match = Arrays.asList(jar);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
setLocation(PLATFORM_CLASS_PATH, defaultPath);
|
||||
options = getOptions("-d", classes.getPath());
|
||||
mode = Mode.EQUALS;
|
||||
match = defaultPath;
|
||||
reference = "";
|
||||
break;
|
||||
|
||||
default:
|
||||
options = getOptions("-d", classes.getPath(), "-bootclasspath", defaultPathString);
|
||||
mode = Mode.EQUALS;
|
||||
match = defaultPath;
|
||||
reference = "";
|
||||
break;
|
||||
}
|
||||
List<JavaFileObject> sources = getSources("class D" + i + " { " + reference + " }");
|
||||
|
||||
callTask(options, sources);
|
||||
checkPath(PLATFORM_CLASS_PATH, mode, match);
|
||||
checkFile(CLASS_OUTPUT, "D" + i + ".class");
|
||||
}
|
||||
|
||||
tested.add(PLATFORM_CLASS_PATH);
|
||||
}
|
||||
|
||||
void testAnnotationProcessorPath() throws IOException {
|
||||
String test = "testAnnotationProcessorPath";
|
||||
|
||||
String template =
|
||||
"import java.util.*;\n"
|
||||
+ "import javax.annotation.processing.*;\n"
|
||||
+ "import javax.lang.model.*;\n"
|
||||
+ "import javax.lang.model.element.*;\n"
|
||||
+ "@SupportedAnnotationTypes(\"*\")\n"
|
||||
+ "public class A%d extends AbstractProcessor {\n"
|
||||
+ " public boolean process(Set<? extends TypeElement> annos, RoundEnvironment rEnv) {\n"
|
||||
+ " return true;\n"
|
||||
+ " }\n"
|
||||
+ " public SourceVersion getSupportedSourceVersion() {\n"
|
||||
+ " return SourceVersion.latest();\n"
|
||||
+ " }\n"
|
||||
+ "}";
|
||||
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
File classes = createDir(test + "/" + i + "/classes");
|
||||
File annodir = createDir(test + "/" + i + "/processors");
|
||||
callTask(getOptions("-d", annodir.getPath()), getSources(String.format(template, i)));
|
||||
File annopath = annodir;
|
||||
List<String> options;
|
||||
switch (i) {
|
||||
default:
|
||||
options = getOptions("-d", classes.getPath(),
|
||||
"-processorpath", annopath.getPath(),
|
||||
"-processor", "A" + i);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
setLocation(ANNOTATION_PROCESSOR_PATH, annopath);
|
||||
options = getOptions("-d", classes.getPath(),
|
||||
"-processor", "A" + i);
|
||||
break;
|
||||
}
|
||||
List<JavaFileObject> sources = getSources("class D" + i + " { }");
|
||||
callTask(options, sources);
|
||||
checkPath(ANNOTATION_PROCESSOR_PATH, Mode.EQUALS, annopath);
|
||||
checkFile(CLASS_OUTPUT, "D" + i + ".class");
|
||||
}
|
||||
|
||||
tested.add(ANNOTATION_PROCESSOR_PATH);
|
||||
}
|
||||
|
||||
void testSourceOutput() throws IOException {
|
||||
String test = "testAnnotationProcessorPath";
|
||||
|
||||
String source =
|
||||
"import java.io.*;\n"
|
||||
+ "import java.util.*;\n"
|
||||
+ "import javax.annotation.processing.*;\n"
|
||||
+ "import javax.lang.model.*;\n"
|
||||
+ "import javax.lang.model.element.*;\n"
|
||||
+ "import javax.tools.*;\n"
|
||||
+ "@SupportedOptions(\"name\")\n"
|
||||
+ "@SupportedAnnotationTypes(\"*\")\n"
|
||||
+ "public class A extends AbstractProcessor {\n"
|
||||
+ " int round = 0;\n"
|
||||
+ " public boolean process(Set<? extends TypeElement> annos, RoundEnvironment rEnv) {\n"
|
||||
+ " if (round++ == 0) try {\n"
|
||||
+ " String name = processingEnv.getOptions().get(\"name\");\n"
|
||||
+ " JavaFileObject fo = processingEnv.getFiler().createSourceFile(name);\n"
|
||||
+ " try (Writer out = fo.openWriter()) {\n"
|
||||
+ " out.write(\"class \" + name + \" { }\");\n"
|
||||
+ " }\n"
|
||||
+ " } catch (IOException e) { throw new Error(e); }\n"
|
||||
+ " return true;\n"
|
||||
+ " }\n"
|
||||
+ " public SourceVersion getSupportedSourceVersion() {\n"
|
||||
+ " return SourceVersion.latest();\n"
|
||||
+ " }\n"
|
||||
+ "}";
|
||||
|
||||
File annodir = createDir(test + "/processors");
|
||||
callTask(getOptions("-d", annodir.getPath()), getSources(source));
|
||||
setLocation(ANNOTATION_PROCESSOR_PATH, annodir);
|
||||
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
File classes = createDir(test + "/" + i + "/classes");
|
||||
File genSrc = createDir(test + "/" + "/genSrc");
|
||||
List<String> options;
|
||||
switch (i) {
|
||||
default:
|
||||
options = getOptions("-d", classes.getPath(),
|
||||
"-processor", "A", "-Aname=G" + i,
|
||||
"-s", genSrc.getPath());
|
||||
break;
|
||||
|
||||
case 3:
|
||||
setLocation(SOURCE_OUTPUT, genSrc);
|
||||
options = getOptions("-d", classes.getPath(),
|
||||
"-processor", "A", "-Aname=G" + i);
|
||||
break;
|
||||
}
|
||||
List<JavaFileObject> sources = getSources("class D" + i + " { }");
|
||||
callTask(options, sources);
|
||||
checkPath(SOURCE_OUTPUT, Mode.EQUALS, genSrc);
|
||||
checkFile(CLASS_OUTPUT, "D" + i + ".class");
|
||||
checkFile(CLASS_OUTPUT, "G" + i + ".class");
|
||||
}
|
||||
tested.add(SOURCE_OUTPUT);
|
||||
}
|
||||
|
||||
void testNativeHeaderOutput() throws IOException {
|
||||
String test = "testNativeHeaderOutput";
|
||||
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
File classes = createDir(test + "/" + i + "/classes");
|
||||
File headers = createDir(test + "/" + i + "/hdrs");
|
||||
List<String> options;
|
||||
switch (i) {
|
||||
default:
|
||||
options = getOptions("-d", classes.getPath(), "-h", headers.getPath());
|
||||
break;
|
||||
|
||||
case 3:
|
||||
setLocation(NATIVE_HEADER_OUTPUT, headers);
|
||||
options = getOptions("-d", classes.getPath());
|
||||
break;
|
||||
}
|
||||
List<JavaFileObject> sources = getSources("class C" + i + " { native void m(); }");
|
||||
callTask(options, sources);
|
||||
checkPath(NATIVE_HEADER_OUTPUT, Mode.EQUALS, headers);
|
||||
checkFile(NATIVE_HEADER_OUTPUT, "C" + i + ".h");
|
||||
}
|
||||
|
||||
tested.add(StandardLocation.NATIVE_HEADER_OUTPUT);
|
||||
}
|
||||
|
||||
List<String> getOptions(String... args) {
|
||||
return Arrays.asList(args);
|
||||
}
|
||||
|
||||
List<JavaFileObject> getSources(String... sources) {
|
||||
List<JavaFileObject> list = new ArrayList<>();
|
||||
for (String s: sources)
|
||||
list.add(getSource(s));
|
||||
return list;
|
||||
}
|
||||
|
||||
JavaFileObject getSource(final String source) {
|
||||
return new SimpleJavaFileObject(getURIFromSource(source), JavaFileObject.Kind.SOURCE) {
|
||||
@Override
|
||||
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
||||
return source;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void callTask(List<String> options, List<JavaFileObject> files) {
|
||||
out.print("compile: ");
|
||||
if (options != null) {
|
||||
for (String o: options) {
|
||||
if (o.length() > 64) {
|
||||
o = o.substring(0, 32) + "..." + o.substring(o.length() - 32);
|
||||
}
|
||||
out.print(" " + o);
|
||||
}
|
||||
}
|
||||
for (JavaFileObject f: files)
|
||||
out.print(" " + f.getName());
|
||||
out.println();
|
||||
CompilationTask t = compiler.getTask(out, fileManager, null, options, null, files);
|
||||
boolean ok = t.call();
|
||||
if (!ok)
|
||||
error("compilation failed");
|
||||
}
|
||||
|
||||
enum Mode { EQUALS, CONTAINS, STARTS_WITH, ENDS_WITH };
|
||||
|
||||
void checkFile(StandardLocation l, String path) {
|
||||
if (!l.isOutputLocation()) {
|
||||
error("Not an output location: " + l);
|
||||
return;
|
||||
}
|
||||
|
||||
List<File> files = getLocation(l);
|
||||
if (files == null) {
|
||||
error("location is unset: " + l);
|
||||
return;
|
||||
}
|
||||
|
||||
if (files.size() != 1)
|
||||
error("unexpected number of entries on " + l + ": " + files.size());
|
||||
|
||||
File f = new File(files.get(0), path);
|
||||
if (!f.exists())
|
||||
error("file not found: " + f);
|
||||
}
|
||||
|
||||
void checkPath(StandardLocation l, Mode m, File expect) {
|
||||
checkPath(l, m, Arrays.asList(expect));
|
||||
}
|
||||
|
||||
void checkPath(StandardLocation l, Mode m, List<File> expect) {
|
||||
List<File> files = getLocation(l);
|
||||
if (files == null) {
|
||||
error("location is unset: " + l);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (m) {
|
||||
case EQUALS:
|
||||
if (!Objects.equals(files, expect)) {
|
||||
error("location does not match the expected files: " + l);
|
||||
out.println("found: " + files);
|
||||
out.println("expect: " + expect);
|
||||
}
|
||||
break;
|
||||
|
||||
case CONTAINS:
|
||||
int containsIndex = Collections.indexOfSubList(files, expect);
|
||||
if (containsIndex == -1) {
|
||||
error("location does not contain the expected files: " + l);
|
||||
out.println("found: " + files);
|
||||
out.println("expect: " + expect);
|
||||
}
|
||||
break;
|
||||
|
||||
case STARTS_WITH:
|
||||
int startsIndex = Collections.indexOfSubList(files, expect);
|
||||
if (startsIndex != 0) {
|
||||
error("location does not start with the expected files: " + l);
|
||||
out.println("found: " + files);
|
||||
out.println("expect: " + expect);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENDS_WITH:
|
||||
int endsIndex = Collections.lastIndexOfSubList(files, expect);
|
||||
if (endsIndex != files.size() - expect.size()) {
|
||||
error("location does not end with the expected files: " + l);
|
||||
out.println("found: " + files);
|
||||
out.println("expect: " + expect);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
List<File> getLocation(StandardLocation l) {
|
||||
Iterable<? extends File> iter = fileManager.getLocation(l);
|
||||
if (iter == null)
|
||||
return null;
|
||||
List<File> files = new ArrayList<>();
|
||||
for (File f: iter)
|
||||
files.add(f);
|
||||
return files;
|
||||
}
|
||||
|
||||
void setLocation(StandardLocation l, File... files) throws IOException {
|
||||
fileManager.setLocation(l, Arrays.asList(files));
|
||||
}
|
||||
|
||||
void setLocation(StandardLocation l, List<File> files) throws IOException {
|
||||
fileManager.setLocation(l, files);
|
||||
}
|
||||
|
||||
void writeFile(File dir, String path, String body) throws IOException {
|
||||
try (FileWriter w = new FileWriter(new File(dir, path))) {
|
||||
w.write(body);
|
||||
}
|
||||
}
|
||||
|
||||
void writeJar(File jar, File dir, String... entries) throws IOException {
|
||||
try (JarOutputStream j = new JarOutputStream(Files.newOutputStream(jar.toPath()))) {
|
||||
for (String entry: entries) {
|
||||
j.putNextEntry(new JarEntry(entry));
|
||||
j.write(Files.readAllBytes(dir.toPath().resolve(entry)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final Pattern packagePattern
|
||||
= Pattern.compile("package\\s+(((?:\\w+\\.)*)(?:\\w+))");
|
||||
private static final Pattern classPattern
|
||||
= Pattern.compile("(?:public\\s+)?(?:class|enum|interface)\\s+(\\w+)");
|
||||
|
||||
|
||||
private static URI getURIFromSource(String source) {
|
||||
String packageName = null;
|
||||
|
||||
Matcher matcher = packagePattern.matcher(source);
|
||||
if (matcher.find()) {
|
||||
packageName = matcher.group(1).replace(".", "/");
|
||||
}
|
||||
|
||||
matcher = classPattern.matcher(source);
|
||||
if (matcher.find()) {
|
||||
String className = matcher.group(1);
|
||||
String path = ((packageName == null) ? "" : packageName + "/") + className + ".java";
|
||||
return URI.create("myfo:///" + path);
|
||||
} else {
|
||||
throw new Error("Could not extract the java class "
|
||||
+ "name from the provided source");
|
||||
}
|
||||
}
|
||||
|
||||
File createDir(String path) {
|
||||
File dir = new File(path);
|
||||
dir.mkdirs();
|
||||
return dir;
|
||||
}
|
||||
|
||||
JavaCompiler compiler;
|
||||
StandardJavaFileManager fileManager;
|
||||
|
||||
/**
|
||||
* Map for recording which standard locations have been tested.
|
||||
*/
|
||||
EnumSet<StandardLocation> tested = EnumSet.noneOf(StandardLocation.class);
|
||||
|
||||
/**
|
||||
* Logging stream. Used directly with test and for getTask calls.
|
||||
*/
|
||||
final PrintWriter out = new PrintWriter(System.err, true);
|
||||
|
||||
/**
|
||||
* Count of errors so far.
|
||||
*/
|
||||
int errors;
|
||||
|
||||
void error(String message) {
|
||||
errors++;
|
||||
out.println("Error: " + message);
|
||||
}
|
||||
}
|
@ -105,14 +105,13 @@ class ArgTypeCompilerFactory implements Example.Compiler.Factory {
|
||||
|
||||
Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(files);
|
||||
|
||||
Context c = new Context();
|
||||
ArgTypeMessages.preRegister(c);
|
||||
ArgTypeJavaCompiler.preRegister(c);
|
||||
Context c = initContext();
|
||||
JavacTaskImpl t = (JavacTaskImpl) tool.getTask(out, fm, null, opts, null, fos, c);
|
||||
return t.call();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run the test using the standard simple entry point.
|
||||
*/
|
||||
@ -135,10 +134,8 @@ class ArgTypeCompilerFactory implements Example.Compiler.Factory {
|
||||
args.add(f.getPath());
|
||||
|
||||
Main main = new Main("javac", out);
|
||||
Context c = new Context();
|
||||
Context c = initContext();
|
||||
JavacFileManager.preRegister(c); // can't create it until Log has been set up
|
||||
ArgTypeJavaCompiler.preRegister(c);
|
||||
ArgTypeMessages.preRegister(c);
|
||||
Main.Result result = main.compile(args.toArray(new String[args.size()]), c);
|
||||
|
||||
return result.isOK();
|
||||
@ -161,18 +158,25 @@ class ArgTypeCompilerFactory implements Example.Compiler.Factory {
|
||||
for (File f: files)
|
||||
args.add(f.getPath());
|
||||
|
||||
Context c = new Context();
|
||||
Context c = initContext();
|
||||
JavacFileManager.preRegister(c); // can't create it until Log has been set up
|
||||
ArgTypeJavaCompiler.preRegister(c);
|
||||
ArgTypeMessages.preRegister(c);
|
||||
Main m = new Main("javac", out);
|
||||
Main.Result result = m.compile(args.toArray(new String[args.size()]), c);
|
||||
|
||||
return result.isOK();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Context initContext() {
|
||||
Context context = new Context();
|
||||
ArgTypeMessages.preRegister(context);
|
||||
Options options = Options.instance(context);
|
||||
options.addListener(() -> {
|
||||
Log log = Log.instance(context);
|
||||
log.setDiagnosticFormatter(new ArgTypeDiagnosticFormatter(options));
|
||||
});
|
||||
return context;
|
||||
}
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Custom Javac components">
|
||||
|
||||
@ -227,29 +231,6 @@ class ArgTypeCompilerFactory implements Example.Compiler.Factory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trivial subtype of JavaCompiler to get access to the protected compilerKey field.
|
||||
* The factory is used to ensure that the log is initialized with an instance of
|
||||
* ArgTypeDiagnosticFormatter before we create the required JavaCompiler.
|
||||
*/
|
||||
static class ArgTypeJavaCompiler extends JavaCompiler {
|
||||
static void preRegister(Context context) {
|
||||
context.put(compilerKey, new Context.Factory<JavaCompiler>() {
|
||||
public JavaCompiler make(Context c) {
|
||||
Log log = Log.instance(c);
|
||||
Options options = Options.instance(c);
|
||||
log.setDiagnosticFormatter(new ArgTypeDiagnosticFormatter(options));
|
||||
return new JavaCompiler(c);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// not used
|
||||
private ArgTypeJavaCompiler() {
|
||||
super(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Diagnostic formatter which "localizes" a message as a line
|
||||
* containing a key, and a possibly empty set of descriptive strings for the
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -55,7 +55,7 @@ public class T6430209 {
|
||||
// run annotation processor b6341534 so we can check diagnostics
|
||||
// -proc:only -processor b6341534 -cp . ./src/*.java
|
||||
String testSrc = System.getProperty("test.src", ".");
|
||||
String testClasses = System.getProperty("test.classes") + System.getProperty("path.separator") + "../../lib";
|
||||
String testClassPath = System.getProperty("test.class.path");
|
||||
JavacTool tool = JavacTool.create();
|
||||
MyDiagListener dl = new MyDiagListener();
|
||||
StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null);
|
||||
@ -64,7 +64,7 @@ public class T6430209 {
|
||||
new File(testSrc, "test0.java"), new File(testSrc, "test1.java")));
|
||||
Iterable<String> opts = Arrays.asList("-proc:only",
|
||||
"-processor", "b6341534",
|
||||
"-processorpath", testClasses);
|
||||
"-processorpath", testClassPath);
|
||||
StringWriter out = new StringWriter();
|
||||
JavacTask task = tool.getTask(out, fm, dl, opts, null, files);
|
||||
task.call();
|
||||
|
Loading…
x
Reference in New Issue
Block a user