8035063: Option handling in sjavac needs to be rewritten
Summary: Option handling code rewritten. Exclusion / inclusion patterns changed from package to directories.
Reviewed-by: jjg, jfranck
--- a/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java Mon Apr 21 22:51:49 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CleanProperties.java Tue Apr 22 16:51:10 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -29,13 +29,14 @@
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
+import com.sun.tools.sjavac.options.Options;
+
/**
* The clean properties transform should not be necessary.
* Eventually we will cleanup the property file sources in the OpenJDK instead.
@@ -51,7 +52,7 @@
// Any extra information is ignored for clean properties.
}
- public void setExtra(String[] a) {
+ public void setExtra(Options a) {
// Any extra information is ignored for clean properties.
}
--- a/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java Mon Apr 21 22:51:49 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileJavaPackages.java Tue Apr 22 16:51:10 2014 +0200
@@ -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,15 +25,16 @@
package com.sun.tools.sjavac;
+import java.io.PrintStream;
import java.net.URI;
import java.util.Arrays;
import java.util.Random;
import java.util.Set;
import java.util.Map;
+import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.server.JavacServer;
import com.sun.tools.sjavac.server.SysInfo;
-import java.io.PrintStream;
/**
* This transform compiles a set of packages containing Java sources.
@@ -54,13 +55,12 @@
// We hope to improve this in the future.
final static int limitOnConcurrency = 3;
- String serverSettings;
+ Options args;
+
public void setExtra(String e) {
- serverSettings = e;
}
- String[] args;
- public void setExtra(String[] a) {
+ public void setExtra(Options a) {
args = a;
}
@@ -82,14 +82,14 @@
boolean concurrentCompiles = true;
// Fetch the id.
- String id = Util.extractStringOption("id", serverSettings);
+ String id = Util.extractStringOption("id", args.getServerConf());
if (id == null || id.equals("")) {
// No explicit id set. Create a random id so that the requests can be
// grouped properly in the server.
id = "id"+(((new Random()).nextLong())&Long.MAX_VALUE);
}
// Only keep portfile and sjavac settings..
- String psServerSettings = Util.cleanSubOptions("--server:", Util.set("portfile","sjavac","background","keepalive"), serverSettings);
+ String psServerSettings = Util.cleanSubOptions(Util.set("portfile","sjavac","background","keepalive"), args.getServerConf());
// Get maximum heap size from the server!
SysInfo sysinfo = JavacServer.connectGetSysInfo(psServerSettings, out, err);
@@ -223,7 +223,7 @@
@Override
public void run() {
rn[ii] = JavacServer.useServer(cleanedServerSettings,
- Main.removeWrapperArgs(args),
+ args.prepJavacArgs(),
cc.srcs,
fvisible_sources,
fvisible_classes,
--- a/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java Mon Apr 21 22:51:49 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CompileProperties.java Tue Apr 22 16:51:10 2014 +0200
@@ -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
@@ -37,6 +37,8 @@
import java.util.HashSet;
import java.util.Map;
+import com.sun.tools.sjavac.options.Options;
+
/**
* Compile properties transform a properties file into a Java source file.
* Java has built in support for reading properties from either a text file
@@ -58,7 +60,7 @@
extra = e;
}
- public void setExtra(String[] a) {
+ public void setExtra(Options a) {
}
public boolean transform(Map<String,Set<URI>> pkgSrcs,
--- a/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java Mon Apr 21 22:51:49 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/CopyFile.java Tue Apr 22 16:51:10 2014 +0200
@@ -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
@@ -31,6 +31,8 @@
import java.util.HashSet;
import java.util.Map;
+import com.sun.tools.sjavac.options.Options;
+
/**
* The copy file transform simply copies a matching file from -src to -d .
* Such files are typically images, xml documents and other data files.
@@ -45,7 +47,7 @@
public void setExtra(String e) {
}
- public void setExtra(String[] a) {
+ public void setExtra(Options a) {
}
public boolean transform(Map<String,Set<URI>> pkgSrcs,
--- a/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java Mon Apr 21 22:51:49 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java Tue Apr 22 16:51:10 2014 +0200
@@ -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
@@ -26,6 +26,7 @@
package com.sun.tools.sjavac;
import java.io.*;
+import java.nio.file.Path;
import java.util.Collections;
import java.util.Date;
import java.util.Set;
@@ -37,6 +38,9 @@
import java.net.URI;
import java.util.*;
+import com.sun.tools.sjavac.options.Options;
+import com.sun.tools.sjavac.options.SourceLocation;
+
/**
* The javac state class maintains the previous (prev) and the current (now)
* build states and everything else that goes into the javac_state file.
@@ -117,25 +121,20 @@
// It can also map from a jar file to the set of visible classes for that jar file.
Map<URI,Set<String>> visibleClasses;
- // Setup two transforms that always exist.
- private CopyFile copyFiles = new CopyFile();
+ // Setup transform that always exist.
private CompileJavaPackages compileJavaPackages = new CompileJavaPackages();
// Where to send stdout and stderr.
private PrintStream out, err;
- JavacState(String[] args, File bd, File gd, File hd, boolean permitUnidentifiedArtifacts, boolean removeJavacState,
- PrintStream o, PrintStream e) {
+ JavacState(Options options, boolean removeJavacState, PrintStream o, PrintStream e) {
out = o;
err = e;
- numCores = Main.findNumberOption(args, "-j");
- theArgs = "";
- for (String a : removeArgsNotAffectingState(args)) {
- theArgs = theArgs+a+" ";
- }
- binDir = bd;
- gensrcDir = gd;
- headerDir = hd;
+ numCores = options.getNumCores();
+ theArgs = options.getStateArgsString();
+ binDir = Util.pathToFile(options.getDestDir());
+ gensrcDir = Util.pathToFile(options.getGenSrcDir());
+ headerDir = Util.pathToFile(options.getHeaderDir());
javacStateFilename = binDir.getPath()+File.separator+"javac_state";
javacState = new File(javacStateFilename);
if (removeJavacState && javacState.exists()) {
@@ -148,7 +147,7 @@
// We do not want to risk building a broken incremental build.
// BUT since the makefiles still copy things straight into the bin_dir et al,
// we avoid deleting files here, if the option --permit-unidentified-classes was supplied.
- if (!permitUnidentifiedArtifacts) {
+ if (!options.isUnidentifiedArtifactPermitted()) {
deleteContents(binDir);
deleteContents(gensrcDir);
deleteContents(headerDir);
@@ -301,9 +300,8 @@
/**
* Load a javac_state file.
*/
- public static JavacState load(String[] args, File binDir, File gensrcDir, File headerDir,
- boolean permitUnidentifiedArtifacts, PrintStream out, PrintStream err) {
- JavacState db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, false, out, err);
+ public static JavacState load(Options options, PrintStream out, PrintStream err) {
+ JavacState db = new JavacState(options, false, out, err);
Module lastModule = null;
Package lastPackage = null;
Source lastSource = null;
@@ -370,22 +368,22 @@
noFileFound = true;
} catch (IOException e) {
Log.info("Dropping old javac_state because of errors when reading it.");
- db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+ db = new JavacState(options, true, out, err);
foundCorrectVerNr = true;
newCommandLine = false;
syntaxError = false;
}
if (foundCorrectVerNr == false && !noFileFound) {
Log.info("Dropping old javac_state since it is of an old version.");
- db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+ db = new JavacState(options, true, out, err);
} else
if (newCommandLine == true && !noFileFound) {
Log.info("Dropping old javac_state since a new command line is used!");
- db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+ db = new JavacState(options, true, out, err);
} else
if (syntaxError == true) {
Log.info("Dropping old javac_state since it contains syntax errors.");
- db = new JavacState(args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
+ db = new JavacState(options, true, out, err);
}
db.prev.calculateDependents();
return db;
@@ -467,12 +465,6 @@
return sr;
}
- /**
- * Acquire the copying transform.
- */
- public Transformer getCopier() {
- return copyFiles;
- }
/**
* If artifacts have gone missing, force a recompile of the packages
@@ -629,7 +621,7 @@
public void performCopying(File binDir, Map<String,Transformer> suffixRules) {
Map<String,Transformer> sr = new HashMap<>();
for (Map.Entry<String,Transformer> e : suffixRules.entrySet()) {
- if (e.getValue() == copyFiles) {
+ if (e.getValue().getClass().equals(CopyFile.class)) {
sr.put(e.getKey(), e.getValue());
}
}
@@ -643,10 +635,11 @@
public void performTranslation(File gensrcDir, Map<String,Transformer> suffixRules) {
Map<String,Transformer> sr = new HashMap<>();
for (Map.Entry<String,Transformer> e : suffixRules.entrySet()) {
- if (e.getValue() != copyFiles &&
- e.getValue() != compileJavaPackages) {
- sr.put(e.getKey(), e.getValue());
- }
+ Class<?> trClass = e.getValue().getClass();
+ if (trClass == CompileJavaPackages.class || trClass == CopyFile.class)
+ continue;
+
+ sr.put(e.getKey(), e.getValue());
}
perform(gensrcDir, sr);
}
@@ -654,14 +647,11 @@
/**
* Compile all the java sources. Return true, if it needs to be called again!
*/
- public boolean performJavaCompilations(File binDir,
- String serverSettings,
- String[] args,
+ public boolean performJavaCompilations(Options args,
Set<String> recentlyCompiled,
boolean[] rcValue) {
Map<String,Transformer> suffixRules = new HashMap<>();
suffixRules.put(".java", compileJavaPackages);
- compileJavaPackages.setExtra(serverSettings);
compileJavaPackages.setExtra(args);
rcValue[0] = perform(binDir, suffixRules);
@@ -813,7 +803,10 @@
for (Source s : now.sources().values()) {
// Don't include link only sources when comparing sources to compile
if (!s.isLinkedOnly()) {
- calculatedSources.add(s.file().getPath());
+ String path = s.file().getPath();
+ if (mightNeedRewriting)
+ path = Util.normalizeDriveLetter(path);
+ calculatedSources.add(path);
}
}
// Read in the file and create another set of filenames with full paths.
--- a/langtools/src/share/classes/com/sun/tools/sjavac/Log.java Mon Apr 21 22:51:49 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Log.java Tue Apr 22 16:51:10 2014 +0200
@@ -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
@@ -71,17 +71,19 @@
err.println(msg);
}
- static public void setLogLevel(String l, PrintStream o, PrintStream e)
- throws ProblemException {
+ static public void initializeLog(PrintStream o, PrintStream e) {
out = o;
err = e;
+ }
+
+ static public void setLogLevel(String l) {
switch (l) {
case "warn": level = WARN; break;
case "info": level = INFO; break;
case "debug": level = DEBUG; break;
case "trace": level = TRACE; break;
default:
- throw new ProblemException("No such log level \"" + l + "\"");
+ throw new IllegalArgumentException("No such log level \"" + l + "\"");
}
}
--- a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java Mon Apr 21 22:51:49 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java Tue Apr 22 16:51:10 2014 +0200
@@ -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,13 +25,14 @@
package com.sun.tools.sjavac;
-import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.nio.file.Path;
+import java.nio.file.Files;
+import com.sun.tools.sjavac.options.Options;
+import com.sun.tools.sjavac.options.SourceLocation;
import com.sun.tools.sjavac.server.JavacServer;
/**
@@ -151,24 +152,8 @@
The resulting classes are written into bin.
*/
- // This is the final destination for classes and copied files.
- private File bin_dir;
- // This is where the annotation process will put generated sources.
- private File gensrc_dir;
- // This is where javac -h puts the generated c-header files.
- private File header_dir;
-
- // This file contains the list of sources genereated by the makefile.
- // We double check that our calculated list of sources matches this list,
- // if not, then we terminate with an error!
- private File makefile_source_list;
- // The challenging task to manage an incremental build is done by javac_state.
private JavacState javac_state;
- // The suffix rules tells you for example, that .java files should be compiled,
- // and .html files should be copied and .properties files be translated.
- Map<String,Transformer> suffix_rules;
-
public static void main(String... args) {
if (args.length > 0 && args[0].startsWith("--startserver:")) {
if (args.length>1) {
@@ -199,118 +184,142 @@
}
public int go(String[] args, PrintStream out, PrintStream err) {
+
+ Log.initializeLog(out, err);
+
+ Options options;
try {
- if (args.length == 0 || findJavaSourceFiles(args) || findAtFile(args) || null==Util.findServerSettings(args)) {
- printHelp();
- return 0;
- }
+ options = Options.parseArgs(args);
+ } catch (IllegalArgumentException e) {
+ Log.error(e.getMessage());
+ return -1;
+ }
+
+ Log.setLogLevel(options.getLogLevel());
- Log.setLogLevel(findLogLevel(args), out, err);
- String server_settings = Util.findServerSettings(args);
- args = verifyImplicitOption(args);
- // Find the source root directories, and add the -src option before these, if not there already.
- args = addSrcBeforeDirectories(args);
- // Check that there is at least one -src supplied.
- checkSrcOption(args);
- // Check that there is one -d supplied.
- bin_dir = findDirectoryOption(args,"-d","output", true, false, true);
- gensrc_dir = findDirectoryOption(args,"-s","gensrc", false, false, true);
- header_dir = findDirectoryOption(args,"-h","headers", false, false, true);
- makefile_source_list = findFileOption(args,"--compare-found-sources","makefile source list", false);
+ if (!validateOptions(options))
+ return -1;
+
+ if (!createIfMissing(options.getDestDir()))
+ return -1;
- // Load the prev build state database.
- javac_state = JavacState.load(args, bin_dir, gensrc_dir, header_dir,
- findBooleanOption(args, "--permit-unidentified-artifacts"), out, err);
+ Path gensrc = options.getGenSrcDir();
+ if (gensrc != null && !createIfMissing(gensrc))
+ return -1;
+
+ Path hdrdir = options.getHeaderDir();
+ if (hdrdir != null && !createIfMissing(hdrdir))
+ return -1;
+
+ // Load the prev build state database.
+ javac_state = JavacState.load(options, out, err);
- // Setup the suffix rules from the command line.
- suffix_rules = javac_state.getJavaSuffixRule();
- findTranslateOptions(args, suffix_rules);
- if (suffix_rules.keySet().size() > 1 && gensrc_dir == null) {
- Log.error("You have translators but no gensrc dir (-s) specified!");
- return -1;
- }
- findCopyOptions(args, suffix_rules);
+ // Setup the suffix rules from the command line.
+ Map<String, Transformer> suffixRules = new HashMap<>();
+
+ // Handling of .java-compilation
+ suffixRules.putAll(javac_state.getJavaSuffixRule());
+
+ // Handling of -copy and -tr
+ suffixRules.putAll(options.getTranslationRules());
+
+ // All found modules are put here.
+ Map<String,Module> modules = new HashMap<>();
+ // We start out in the legacy empty no-name module.
+ // As soon as we stumble on a module-info.java file we change to that module.
+ Module current_module = new Module("", "");
+ modules.put("", current_module);
- // All found modules are put here.
- Map<String,Module> modules = new HashMap<>();
- // We start out in the legacy empty no-name module.
- // As soon as we stumble on a module-info.java file we change to that module.
- Module current_module = new Module("", "");
- modules.put("", current_module);
+ // Find all sources, use the suffix rules to know which files are sources.
+ Map<String,Source> sources = new HashMap<>();
- // Find all sources, use the suffix rules to know which files are sources.
- Map<String,Source> sources = new HashMap<>();
- // Find the files, this will automatically populate the found modules
- // with found packages where the sources are found!
- findFiles(args, "-src", suffix_rules.keySet(), sources, modules, current_module, false);
+ // Find the files, this will automatically populate the found modules
+ // with found packages where the sources are found!
+ findSourceFiles(options.getSources(),
+ suffixRules.keySet(),
+ sources,
+ modules,
+ current_module,
+ options.isDefaultPackagePermitted(),
+ false);
- if (sources.isEmpty()) {
- Log.error("Found nothing to compile!");
- return -1;
- }
+ if (sources.isEmpty()) {
+ Log.error("Found nothing to compile!");
+ return -1;
+ }
- // Create a map of all source files that are available for linking. Both -src and
- // -sourcepath point to such files. It is possible to specify multiple
- // -sourcepath options to enable different filtering rules. If the
- // filters are the same for multiple sourcepaths, they may be concatenated
- // using :(;). Before sending the list of sourcepaths to javac, they are
- // all concatenated. The list created here is used by the SmartFileWrapper to
- // make sure only the correct sources are actually available.
- // We might find more modules here as well.
- Map<String,Source> sources_to_link_to = new HashMap<>();
- findFiles(args, "-src", Util.set(".java"), sources_to_link_to, modules, current_module, true);
- findFiles(args, "-sourcepath", Util.set(".java"), sources_to_link_to, modules, current_module, true);
- // Rewrite the -src option to make it through to the javac instances.
- rewriteOptions(args, "-src", "-sourcepath");
+ // Create a map of all source files that are available for linking. Both -src and
+ // -sourcepath point to such files. It is possible to specify multiple
+ // -sourcepath options to enable different filtering rules. If the
+ // filters are the same for multiple sourcepaths, they may be concatenated
+ // using :(;). Before sending the list of sourcepaths to javac, they are
+ // all concatenated. The list created here is used by the SmartFileWrapper to
+ // make sure only the correct sources are actually available.
+ // We might find more modules here as well.
+ Map<String,Source> sources_to_link_to = new HashMap<>();
- // Find all class files allowable for linking.
- // And pickup knowledge of all modules found here.
- // This cannot currently filter classes inside jar files.
-// Map<String,Source> classes_to_link_to = new HashMap<String,Source>();
-// findFiles(args, "-classpath", Util.set(".class"), classes_to_link_to, modules, current_module, true);
+ List<SourceLocation> sourceResolutionLocations = new ArrayList<>();
+ sourceResolutionLocations.addAll(options.getSources());
+ sourceResolutionLocations.addAll(options.getSourceSearchPaths());
+ findSourceFiles(sourceResolutionLocations,
+ Collections.singleton(".java"),
+ sources_to_link_to,
+ modules,
+ current_module,
+ options.isDefaultPackagePermitted(),
+ true);
- // Find all module sources allowable for linking.
-// Map<String,Source> modules_to_link_to = new HashMap<String,Source>();
-// findFiles(args, "-modulepath", Util.set(".class"), modules_to_link_to, modules, current_module, true);
+ // Find all class files allowable for linking.
+ // And pickup knowledge of all modules found here.
+ // This cannot currently filter classes inside jar files.
+// Map<String,Source> classes_to_link_to = new HashMap<String,Source>();
+// findFiles(args, "-classpath", Util.set(".class"), classes_to_link_to, modules, current_module, true);
- // Add the set of sources to the build database.
- javac_state.now().flattenPackagesSourcesAndArtifacts(modules);
- javac_state.now().checkInternalState("checking sources", false, sources);
- javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to);
- javac_state.setVisibleSources(sources_to_link_to);
+ // Find all module sources allowable for linking.
+// Map<String,Source> modules_to_link_to = new HashMap<String,Source>();
+// findFiles(args, "-modulepath", Util.set(".class"), modules_to_link_to, modules, current_module, true);
- // If there is any change in the source files, taint packages
- // and mark the database in need of saving.
- javac_state.checkSourceStatus(false);
+ // Add the set of sources to the build database.
+ javac_state.now().flattenPackagesSourcesAndArtifacts(modules);
+ javac_state.now().checkInternalState("checking sources", false, sources);
+ javac_state.now().checkInternalState("checking linked sources", true, sources_to_link_to);
+ javac_state.setVisibleSources(sources_to_link_to);
- // Find all existing artifacts. Their timestamp will match the last modified timestamps stored
- // in javac_state, simply because loading of the JavacState will clean out all artifacts
- // that do not match the javac_state database.
- javac_state.findAllArtifacts();
+ // If there is any change in the source files, taint packages
+ // and mark the database in need of saving.
+ javac_state.checkSourceStatus(false);
+
+ // Find all existing artifacts. Their timestamp will match the last modified timestamps stored
+ // in javac_state, simply because loading of the JavacState will clean out all artifacts
+ // that do not match the javac_state database.
+ javac_state.findAllArtifacts();
- // Remove unidentified artifacts from the bin, gensrc and header dirs.
- // (Unless we allow them to be there.)
- // I.e. artifacts that are not known according to the build database (javac_state).
- // For examples, files that have been manually copied into these dirs.
- // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
- // in javac_state) have already been removed when the javac_state was loaded.
- if (!findBooleanOption(args, "--permit-unidentified-artifacts")) {
- javac_state.removeUnidentifiedArtifacts();
- }
- // Go through all sources and taint all packages that miss artifacts.
- javac_state.taintPackagesThatMissArtifacts();
+ // Remove unidentified artifacts from the bin, gensrc and header dirs.
+ // (Unless we allow them to be there.)
+ // I.e. artifacts that are not known according to the build database (javac_state).
+ // For examples, files that have been manually copied into these dirs.
+ // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
+ // in javac_state) have already been removed when the javac_state was loaded.
+ if (!options.isUnidentifiedArtifactPermitted()) {
+ javac_state.removeUnidentifiedArtifacts();
+ }
+ // Go through all sources and taint all packages that miss artifacts.
+ javac_state.taintPackagesThatMissArtifacts();
- // Now clean out all known artifacts belonging to tainted packages.
- javac_state.deleteClassArtifactsInTaintedPackages();
- // Copy files, for example property files, images files, xml files etc etc.
- javac_state.performCopying(bin_dir, suffix_rules);
- // Translate files, for example compile properties or compile idls.
- javac_state.performTranslation(gensrc_dir, suffix_rules);
- // Add any potentially generated java sources to the tobe compiled list.
- // (Generated sources must always have a package.)
- Map<String,Source> generated_sources = new HashMap<>();
- Source.scanRoot(gensrc_dir, Util.set(".java"), null, null, null, null,
- generated_sources, modules, current_module, false, true, false);
+ // Now clean out all known artifacts belonging to tainted packages.
+ javac_state.deleteClassArtifactsInTaintedPackages();
+ // Copy files, for example property files, images files, xml files etc etc.
+ javac_state.performCopying(Util.pathToFile(options.getDestDir()), suffixRules);
+ // Translate files, for example compile properties or compile idls.
+ javac_state.performTranslation(Util.pathToFile(gensrc), suffixRules);
+ // Add any potentially generated java sources to the tobe compiled list.
+ // (Generated sources must always have a package.)
+ Map<String,Source> generated_sources = new HashMap<>();
+
+ try {
+
+ Source.scanRoot(Util.pathToFile(options.getGenSrcDir()), Util.set(".java"), null, null, null, null,
+ generated_sources, modules, current_module, false, true, false);
javac_state.now().flattenPackagesSourcesAndArtifacts(modules);
// Recheck the the source files and their timestamps again.
javac_state.checkSourceStatus(true);
@@ -320,7 +329,7 @@
// right, then incremental builds will fail with subtility.
// If any difference is detected, then we will fail hard here.
// This is an important safety net.
- javac_state.compareWithMakefileList(makefile_source_list);
+ javac_state.compareWithMakefileList(Util.pathToFile(options.getSourceReferenceList()));
// Do the compilations, repeatedly until no tainted packages exist.
boolean again;
@@ -330,7 +339,7 @@
do {
// Clean out artifacts in tainted packages.
javac_state.deleteClassArtifactsInTaintedPackages();
- again = javac_state.performJavaCompilations(bin_dir, server_settings, args, recently_compiled, rc);
+ again = javac_state.performJavaCompilations(options, recently_compiled, rc);
if (!rc[0]) break;
} while (again);
// Only update the state if the compile went well.
@@ -351,620 +360,71 @@
}
}
- /**
- * Are java source files passed on the command line?
- */
- private boolean findJavaSourceFiles(String[] args) {
- String prev = "";
- for (String s : args) {
- if (s.endsWith(".java") && !prev.equals("-xf") && !prev.equals("-if")) {
- return true;
- }
- prev = s;
- }
- return false;
- }
+ private static boolean validateOptions(Options options) {
+
+ String err = null;
- /**
- * Is an at file passed on the command line?
- */
- private boolean findAtFile(String[] args) {
- for (String s : args) {
- if (s.startsWith("@")) {
- return true;
- }
+ if (options.getDestDir() == null) {
+ err = "Please specify output directory.";
+ } else if (options.isJavaFilesAmongJavacArgs()) {
+ err = "Sjavac does not handle explicit compilation of single .java files.";
+ } else if (options.isAtFilePresent()) {
+ err = "Sjavac does not handle @-files.";
+ } else if (options.getServerConf() == null) {
+ err = "No server configuration provided.";
+ } else if (!options.getImplicitPolicy().equals("none")) {
+ err = "The only allowed setting for sjavac is -implicit:none";
+ } else if (options.getSources().isEmpty()) {
+ err = "You have to specify -src.";
+ } else if (options.getTranslationRules().size() > 1
+ && options.getGenSrcDir() == null) {
+ err = "You have translators but no gensrc dir (-s) specified!";
}
- return false;
- }
- /**
- * Find the log level setting.
- */
- private String findLogLevel(String[] args) {
- for (String s : args) {
- if (s.startsWith("--log=") && s.length()>6) {
- return s.substring(6);
- }
- if (s.equals("-verbose")) {
- return "info";
- }
- }
- return "info";
+ if (err != null)
+ Log.error(err);
+
+ return err == null;
+
}
- /**
- * Remove smart javac wrapper arguments, before feeding
- * the args to the plain javac.
- */
- static String[] removeWrapperArgs(String[] args) {
- String[] out = new String[args.length];
- // The first source path index is remembered
- // here. So that all following can be concatenated to it.
- int source_path = -1;
- // The same for class path.
- int class_path = -1;
- // And module path.
- int module_path = -1;
- int j = 0;
- for (int i = 0; i<args.length; ++i) {
- if (args[i].equals("-src") ||
- args[i].equals("-x") ||
- args[i].equals("-i") ||
- args[i].equals("-xf") ||
- args[i].equals("-if") ||
- args[i].equals("-copy") ||
- args[i].equals("-tr") ||
- args[i].equals("-j")) {
- // Just skip it and skip following value
- i++;
- } else if (args[i].startsWith("--server:")) {
- // Just skip it.
- } else if (args[i].startsWith("--log=")) {
- // Just skip it.
- } else if (args[i].equals("--permit-unidentified-artifacts")) {
- // Just skip it.
- } else if (args[i].equals("--permit-sources-without-package")) {
- // Just skip it.
- } else if (args[i].equals("--compare-found-sources")) {
- // Just skip it and skip verify file name
- i++;
- } else if (args[i].equals("-sourcepath")) {
- if (source_path == -1) {
- source_path = j;
- out[j] = args[i];
- out[j+1] = args[i+1];
- j+=2;
- i++;
- } else {
- // Skip this and its argument, but
- // append argument to found sourcepath.
- out[source_path+1] = out[source_path+1]+File.pathSeparatorChar+args[i+1];
- i++;
- }
- } else if (args[i].equals("-classpath") || args[i].equals("-cp")) {
- if (class_path == -1) {
- class_path = j;
- out[j] = args[i];
- out[j+1] = args[i+1];
- j+=2;
- i++;
- } else {
- // Skip this and its argument, but
- // append argument to found sourcepath.
- out[class_path+1] = out[class_path+1]+File.pathSeparatorChar+args[i+1];
- i++;
- }
- } else if (args[i].equals("-modulepath")) {
- if (module_path == -1) {
- module_path = j;
- out[j] = args[i];
- out[j+1] = args[i+1];
- j+=2;
- i++;
- } else {
- // Skip this and its argument, but
- // append argument to found sourcepath.
- out[module_path+1] = out[module_path+1]+File.pathSeparatorChar+args[i+1];
- i++;
- }
- } else {
- // Copy argument.
- out[j] = args[i];
- j++;
- }
+ private static boolean createIfMissing(Path dir) {
+
+ if (Files.isDirectory(dir))
+ return true;
+
+ if (Files.exists(dir)) {
+ Log.error(dir + " is not a directory.");
+ return false;
}
- String[] ret = new String[j];
- System.arraycopy(out, 0, ret, 0, j);
- return ret;
- }
- /**
- * Make sure directory exist, create it if not.
- */
- private static boolean makeSureExists(File dir) {
- // Make sure the dest directories exist.
- if (!dir.exists()) {
- if (!dir.mkdirs()) {
- Log.error("Could not create the directory "+dir.getPath());
- return false;
- }
+ try {
+ Files.createDirectories(dir);
+ } catch (IOException e) {
+ Log.error("Could not create directory: " + e.getMessage());
+ return false;
}
+
return true;
}
- /**
- * Verify that a package pattern is valid.
- */
- private static void checkPattern(String s) throws ProblemException {
- // Package names like foo.bar.gamma are allowed, and
- // package names suffixed with .* like foo.bar.* are
- // also allowed.
- Pattern p = Pattern.compile("[a-zA-Z_]{1}[a-zA-Z0-9_]*(\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*)*(\\.\\*)?+");
- Matcher m = p.matcher(s);
- if (!m.matches()) {
- throw new ProblemException("The string \""+s+"\" is not a proper package name pattern.");
- }
- }
-
- /**
- * Verify that a translate pattern is valid.
- */
- private static void checkTranslatePattern(String s) throws ProblemException {
- // .prop=com.sun.tools.javac.smart.CompileProperties
- // .idl=com.sun.corba.CompileIdl
- // .g3=antlr.CompileGrammar,debug=true
- Pattern p = Pattern.compile(
- "\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*=[a-z_]{1}[a-z0-9_]*(\\.[a-z_]{1}[a-z0-9_]*)*"+
- "(\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*)(,.*)?");
- Matcher m = p.matcher(s);
- if (!m.matches()) {
- throw new ProblemException("The string \""+s+"\" is not a proper translate pattern.");
- }
- }
-
- /**
- * Verify that a copy pattern is valid.
- */
- private static void checkCopyPattern(String s) throws ProblemException {
- // .gif
- // .html
- Pattern p = Pattern.compile(
- "\\.[a-zA-Z_]{1}[a-zA-Z0-9_]*");
- Matcher m = p.matcher(s);
- if (!m.matches()) {
- throw new ProblemException("The string \""+s+"\" is not a proper suffix.");
- }
- }
-
- /**
- * Verify that a source file name is valid.
- */
- private static void checkFilePattern(String s) throws ProblemException {
- // File names like foo/bar/gamma/Bar.java are allowed,
- // as well as /bar/jndi.properties as well as,
- // */bar/Foo.java
- Pattern p = null;
- if (File.separatorChar == '\\') {
- p = Pattern.compile("\\*?(.+\\\\)*.+");
- }
- else if (File.separatorChar == '/') {
- p = Pattern.compile("\\*?(.+/)*.+");
- } else {
- throw new ProblemException("This platform uses the unsupported "+File.separatorChar+
- " as file separator character. Please add support for it!");
- }
- Matcher m = p.matcher(s);
- if (!m.matches()) {
- throw new ProblemException("The string \""+s+"\" is not a proper file name.");
- }
- }
-
- /**
- * Scan the arguments to find an option is used.
- */
- private static boolean hasOption(String[] args, String option) {
- for (String a : args) {
- if (a.equals(option)) return true;
- }
- return false;
- }
-
- /**
- * Check if -implicit is supplied, if so check that it is none.
- * If -implicit is not supplied, supply -implicit:none
- * Only implicit:none is allowed because otherwise the multicore compilations
- * and dependency tracking will be tangled up.
- */
- private static String[] verifyImplicitOption(String[] args)
- throws ProblemException {
-
- boolean foundImplicit = false;
- for (String a : args) {
- if (a.startsWith("-implicit:")) {
- foundImplicit = true;
- if (!a.equals("-implicit:none")) {
- throw new ProblemException("The only allowed setting for sjavac is -implicit:none, it is also the default.");
- }
- }
- }
- if (foundImplicit) {
- return args;
- }
- // -implicit:none not found lets add it.
- String[] newargs = new String[args.length+1];
- System.arraycopy(args,0, newargs, 0, args.length);
- newargs[args.length] = "-implicit:none";
- return newargs;
- }
- /**
- * Rewrite a single option into something else.
- */
- private static void rewriteOptions(String[] args, String option, String new_option) {
- for (int i=0; i<args.length; ++i) {
- if (args[i].equals(option)) {
- args[i] = new_option;
- }
- }
- }
-
- /**
- * Scan the arguments to find an option that specifies a directory.
- * Create the directory if necessary.
- */
- private static File findDirectoryOption(String[] args, String option, String name, boolean needed, boolean allow_dups, boolean create)
- throws ProblemException, ProblemException {
- File dir = null;
- for (int i = 0; i<args.length; ++i) {
- if (args[i].equals(option)) {
- if (dir != null) {
- throw new ProblemException("You have already specified the "+name+" dir!");
- }
- if (i+1 >= args.length) {
- throw new ProblemException("You have to specify a directory following "+option+".");
- }
- if (args[i+1].indexOf(File.pathSeparatorChar) != -1) {
- throw new ProblemException("You must only specify a single directory for "+option+".");
- }
- dir = new File(args[i+1]);
- if (!dir.exists()) {
- if (!create) {
- throw new ProblemException("This directory does not exist: "+dir.getPath());
- } else
- if (!makeSureExists(dir)) {
- throw new ProblemException("Cannot create directory "+dir.getPath());
- }
- }
- if (!dir.isDirectory()) {
- throw new ProblemException("\""+args[i+1]+"\" is not a directory.");
- }
- }
- }
- if (dir == null && needed) {
- throw new ProblemException("You have to specify "+option);
- }
- try {
- if (dir != null)
- return dir.getCanonicalFile();
- } catch (IOException e) {
- throw new ProblemException(""+e);
- }
- return null;
- }
+ /** Find source files in the given source locations. */
+ public static void findSourceFiles(List<SourceLocation> sourceLocations,
+ Set<String> sourceTypes,
+ Map<String,Source> foundFiles,
+ Map<String, Module> foundModules,
+ Module currentModule,
+ boolean permitSourcesInDefaultPackage,
+ boolean inLinksrc) {
- /**
- * Option is followed by path.
- */
- private static boolean shouldBeFollowedByPath(String o) {
- return o.equals("-s") ||
- o.equals("-h") ||
- o.equals("-d") ||
- o.equals("-sourcepath") ||
- o.equals("-classpath") ||
- o.equals("-cp") ||
- o.equals("-bootclasspath") ||
- o.equals("-src");
- }
-
- /**
- * Add -src before source root directories if not already there.
- */
- private static String[] addSrcBeforeDirectories(String[] args) {
- List<String> newargs = new ArrayList<>();
- for (int i = 0; i<args.length; ++i) {
- File dir = new File(args[i]);
- if (dir.exists() && dir.isDirectory()) {
- if (i == 0 || !shouldBeFollowedByPath(args[i-1])) {
- newargs.add("-src");
- }
- }
- newargs.add(args[i]);
- }
- return newargs.toArray(new String[0]);
- }
-
- /**
- * Check the -src options.
- */
- private static void checkSrcOption(String[] args)
- throws ProblemException {
- Set<File> dirs = new HashSet<>();
- for (int i = 0; i<args.length; ++i) {
- if (args[i].equals("-src")) {
- if (i+1 >= args.length) {
- throw new ProblemException("You have to specify a directory following -src.");
- }
- StringTokenizer st = new StringTokenizer(args[i+1], File.pathSeparator);
- while (st.hasMoreElements()) {
- File dir = new File(st.nextToken());
- if (!dir.exists()) {
- throw new ProblemException("This directory does not exist: "+dir.getPath());
- }
- if (!dir.isDirectory()) {
- throw new ProblemException("\""+dir.getPath()+"\" is not a directory.");
- }
- if (dirs.contains(dir)) {
- throw new ProblemException("The src directory \""+dir.getPath()+"\" is specified more than once!");
- }
- dirs.add(dir);
- }
- }
- }
- if (dirs.isEmpty()) {
- throw new ProblemException("You have to specify -src.");
+ for (SourceLocation source : sourceLocations) {
+ source.findSourceFiles(sourceTypes,
+ foundFiles,
+ foundModules,
+ currentModule,
+ permitSourcesInDefaultPackage,
+ inLinksrc);
}
}
-
- /**
- * Scan the arguments to find an option that specifies a file.
- */
- private static File findFileOption(String[] args, String option, String name, boolean needed)
- throws ProblemException, ProblemException {
- File file = null;
- for (int i = 0; i<args.length; ++i) {
- if (args[i].equals(option)) {
- if (file != null) {
- throw new ProblemException("You have already specified the "+name+" file!");
- }
- if (i+1 >= args.length) {
- throw new ProblemException("You have to specify a file following "+option+".");
- }
- file = new File(args[i+1]);
- if (file.isDirectory()) {
- throw new ProblemException("\""+args[i+1]+"\" is not a file.");
- }
- if (!file.exists() && needed) {
- throw new ProblemException("The file \""+args[i+1]+"\" does not exist.");
- }
-
- }
- }
- if (file == null && needed) {
- throw new ProblemException("You have to specify "+option);
- }
- return file;
- }
-
- /**
- * Look for a specific switch, return true if found.
- */
- public static boolean findBooleanOption(String[] args, String option) {
- for (String arg : args) {
- if (arg.equals(option))
- return true;
- }
- return false;
- }
-
- /**
- * Scan the arguments to find an option that specifies a number.
- */
- public static int findNumberOption(String[] args, String option) {
- int rc = 0;
- for (int i = 0; i<args.length; ++i) {
- if (args[i].equals(option)) {
- if (args.length > i+1) {
- rc = Integer.parseInt(args[i+1]);
- }
- }
- }
- return rc;
- }
-
- /**
- * Scan the arguments to find the option (-tr) that setup translation rules to java source
- * from different sources. For example: .properties are translated using CompileProperties
- * The found translators are stored as suffix rules.
- */
- private static void findTranslateOptions(String[] args, Map<String,Transformer> suffix_rules)
- throws ProblemException, ProblemException {
-
- for (int i = 0; i<args.length; ++i) {
- if (args[i].equals("-tr")) {
- if (i+1 >= args.length) {
- throw new ProblemException("You have to specify a translate rule following -tr.");
- }
- String s = args[i+1];
- checkTranslatePattern(s);
- int ep = s.indexOf("=");
- String suffix = s.substring(0,ep);
- String classname = s.substring(ep+1);
- if (suffix_rules.get(suffix) != null) {
- throw new ProblemException("You have already specified a "+
- "rule for the suffix "+suffix);
- }
- if (s.equals(".class")) {
- throw new ProblemException("You cannot have a translator for .class files!");
- }
- if (s.equals(".java")) {
- throw new ProblemException("You cannot have a translator for .java files!");
- }
- String extra = null;
- int exp = classname.indexOf(",");
- if (exp != -1) {
- extra = classname.substring(exp+1);
- classname = classname.substring(0,exp);
- }
- try {
- Class<?> cl = Class.forName(classname);
- Transformer t = (Transformer)cl.newInstance();
- t.setExtra(extra);
- suffix_rules.put(suffix, t);
- }
- catch (Exception e) {
- throw new ProblemException("Cannot use "+classname+" as a translator!");
- }
- }
- }
- }
-
- /**
- * Scan the arguments to find the option (-copy) that setup copying rules into the bin dir.
- * For example: -copy .html
- * The found copiers are stored as suffix rules as well. No translation is done, just copying.
- */
- private void findCopyOptions(String[] args, Map<String,Transformer> suffix_rules)
- throws ProblemException, ProblemException {
-
- for (int i = 0; i<args.length; ++i) {
- if (args[i].equals("-copy")) {
- if (i+1 >= args.length) {
- throw new ProblemException("You have to specify a translate rule following -tr.");
- }
- String s = args[i+1];
- checkCopyPattern(s);
- if (suffix_rules.get(s) != null) {
- throw new ProblemException("You have already specified a "+
- "rule for the suffix "+s);
- }
- if (s.equals(".class")) {
- throw new ProblemException("You cannot have a copy rule for .class files!");
- }
- if (s.equals(".java")) {
- throw new ProblemException("You cannot have a copy rule for .java files!");
- }
- suffix_rules.put(s, javac_state.getCopier());
- }
- }
- }
-
- /**
- * Rewrite a / separated path into \ separated, but only
- * if we are running on a platform were File.separatorChar=='\', ie winapi.
- */
- private String fixupSeparator(String p) {
- if (File.separatorChar == '/') return p;
- return p.replaceAll("/", "\\\\");
- }
-
- /**
- * Scan the arguments for -i -x -xf -if followed by the option
- * -src, -sourcepath, -modulepath or -classpath and produce a map of all the
- * files to referenced for that particular option.
- *
- * Store the found sources and the found modules in the supplied maps.
- */
- private boolean findFiles(String[] args, String option, Set<String> suffixes,
- Map<String,Source> found_files, Map<String, Module> found_modules,
- Module current_module, boolean inLinksrc)
- throws ProblemException, ProblemException
- {
- // Track which source roots, source path roots and class path roots have been added.
- Set<File> roots = new HashSet<>();
- // Track the current set of package includes,excludes as well as excluded source files,
- // to be used in the next -src/-sourcepath/-classpath
- List<String> includes = new LinkedList<>();
- List<String> excludes = new LinkedList<>();
- List<String> excludefiles = new LinkedList<>();
- List<String> includefiles = new LinkedList<>();
- // This include is used to find all modules in the source.
- List<String> moduleinfo = new LinkedList<>();
- moduleinfo.add("module-info.java");
-
- for (int i = 0; i<args.length; ++i) {
- if (args[i].equals("-i")) {
- if (i+1 >= args.length) {
- throw new ProblemException("You have to specify a package pattern following -i");
- }
- String incl = args[i+1];
- checkPattern(incl);
- includes.add(incl);
- }
- if (args[i].equals("-x")) {
- if (i+1 >= args.length) {
- throw new ProblemException("You have to specify a package pattern following -x");
- }
- String excl = args[i+1];
- checkPattern(excl);
- excludes.add(excl);
- }
- if (args[i].equals("-xf")) {
- if (i+1 >= args.length) {
- throw new ProblemException("You have to specify a file following -xf");
- }
- String exclf = args[i+1];
- checkFilePattern(exclf);
- exclf = Util.normalizeDriveLetter(exclf);
- excludefiles.add(fixupSeparator(exclf));
- }
- if (args[i].equals("-if")) {
- if (i+1 >= args.length) {
- throw new ProblemException("You have to specify a file following -xf");
- }
- String inclf = args[i+1];
- checkFilePattern(inclf);
- inclf = Util.normalizeDriveLetter(inclf);
- includefiles.add(fixupSeparator(inclf));
- }
- if (args[i].equals(option)) {
- if (i+1 >= args.length) {
- throw new ProblemException("You have to specify a directory following "+option);
- }
- String[] root_dirs = args[i+1].split(File.pathSeparator);
- for (String r : root_dirs) {
- File root = new File(r);
- if (!root.isDirectory()) {
- throw new ProblemException("\""+r+"\" is not a directory.");
- }
- try {
- root = root.getCanonicalFile();
- } catch (IOException e) {
- throw new ProblemException(""+e);
- }
- if (roots.contains(root)) {
- throw new ProblemException("\""+r+"\" has already been used for "+option);
- }
- if (root.equals(bin_dir)) {
- throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -d");
- }
- if (root.equals(gensrc_dir)) {
- throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -s");
- }
- if (root.equals(header_dir)) {
- throw new ProblemException("\""+r+"\" cannot be used both for "+option+" and -h");
- }
- roots.add(root);
- Source.scanRoot(root, suffixes, excludes, includes, excludefiles, includefiles,
- found_files, found_modules, current_module,
- findBooleanOption(args, "--permit-sources-without-package"),
- false, inLinksrc);
- }
- }
- if (args[i].equals("-src") ||
- args[i].equals("-sourcepath") ||
- args[i].equals("-modulepath") ||
- args[i].equals("-classpath") ||
- args[i].equals("-cp"))
- {
- // Reset the includes,excludes and excludefiles after they have been used.
- includes = new LinkedList<>();
- excludes = new LinkedList<>();
- excludefiles = new LinkedList<>();
- includefiles = new LinkedList<>();
- }
- }
- return true;
- }
-
}
-
--- a/langtools/src/share/classes/com/sun/tools/sjavac/Source.java Mon Apr 21 22:51:49 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Source.java Tue Apr 22 16:51:10 2014 +0200
@@ -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
@@ -201,7 +201,7 @@
// It might contain other source files however, (for -tr and -copy) these will
// always be included, since no package pattern can match the root directory.
currentModule = addFilesInDir(root, root_prefix, root, suffixes, permitSourcesWithoutPackage,
- excludeFiles, includeFiles, false,
+ excludeFiles, includeFiles,
foundFiles, foundModules, currentModule,
inGensrc, inLinksrc);
@@ -211,24 +211,28 @@
// Descend into the directory structure.
scanDirectory(d, root_prefix, root, suffixes,
excludes, includes, excludeFiles, includeFiles,
- false, foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
+ foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
}
}
}
/**
* Test if a path matches any of the patterns given.
- * The pattern foo.bar matches only foo.bar
- * The pattern foo.* matches foo.bar and foo.bar.zoo etc
+ * The pattern foo/bar matches only foo/bar
+ * The pattern foo/* matches foo/bar and foo/bar/zoo etc
*/
static private boolean hasMatch(String path, List<String> patterns) {
+
+ // Convert Windows '\' to '/' for the sake of comparing with the patterns
+ path = path.replace(File.separatorChar, '/');
+
for (String p : patterns) {
// Exact match
- if (p.equals(path)) {
+ if (p.equals(path))
return true;
- }
+
// Single dot the end matches this package and all its subpackages.
- if (p.endsWith(".*")) {
+ if (p.endsWith("/*")) {
// Remove the wildcard
String patprefix = p.substring(0,p.length()-2);
// Does the path start with the pattern prefix?
@@ -237,7 +241,7 @@
// If the path is longer, then make sure that
// the next part of the path starts with a dot (.) to prevent
// wildcard matching in the middle of a package name.
- if (path.length()==patprefix.length() || path.charAt(patprefix.length())=='.') {
+ if (path.length()==patprefix.length() || path.charAt(patprefix.length())=='/') {
return true;
}
}
@@ -251,6 +255,9 @@
// The pattern foo/bar.java only matches foo/bar.java
// The pattern */bar.java matches foo/bar.java and zoo/bar.java etc
static private boolean hasFileMatch(String path, List<String> patterns) {
+ // Convert Windows '\' to '/' for the sake of comparing with the patterns
+ path = path.replace(File.separatorChar, '/');
+
path = Util.normalizeDriveLetter(path);
for (String p : patterns) {
// Exact match
@@ -276,7 +283,7 @@
*/
static private Module addFilesInDir(File dir, int rootPrefix, File root,
Set<String> suffixes, boolean allow_javas,
- List<String> excludeFiles, List<String> includeFiles, boolean all,
+ List<String> excludeFiles, List<String> includeFiles,
Map<String,Source> foundFiles,
Map<String,Module> foundModules,
Module currentModule,
@@ -285,79 +292,82 @@
throws ProblemException
{
for (File f : dir.listFiles()) {
- if (f.isFile()) {
- boolean should_add =
- (excludeFiles == null || excludeFiles.isEmpty() || !hasFileMatch(f.getPath(), excludeFiles))
- && (includeFiles == null || includeFiles.isEmpty() || hasFileMatch(f.getPath(), includeFiles));
+
+ if (!f.isFile())
+ continue;
+
+ boolean should_add =
+ (excludeFiles == null || excludeFiles.isEmpty() || !hasFileMatch(f.getPath(), excludeFiles))
+ && (includeFiles == null || includeFiles.isEmpty() || hasFileMatch(f.getPath(), includeFiles));
+
+ if (!should_add)
+ continue;
- if (should_add) {
- if (!allow_javas && f.getName().endsWith(".java")) {
- throw new ProblemException("No .java files are allowed in the source root "+dir.getPath()+
- ", please remove "+f.getName());
- }
- // Extract the file name relative the root.
- String fn = f.getPath().substring(rootPrefix);
- // Extract the package name.
- int sp = fn.lastIndexOf(File.separatorChar);
- String pkg = "";
- if (sp != -1) {
- pkg = fn.substring(0,sp).replace(File.separatorChar,'.');
- }
- // Is this a module-info.java file?
- if (fn.endsWith("module-info.java")) {
- // Aha! We have recursed into a module!
- if (!currentModule.name().equals("")) {
- throw new ProblemException("You have an extra module-info.java inside a module! Please remove "+fn);
+ if (!allow_javas && f.getName().endsWith(".java")) {
+ throw new ProblemException("No .java files are allowed in the source root "+dir.getPath()+
+ ", please remove "+f.getName());
+ }
+ // Extract the file name relative the root.
+ String fn = f.getPath().substring(rootPrefix);
+ // Extract the package name.
+ int sp = fn.lastIndexOf(File.separatorChar);
+ String pkg = "";
+ if (sp != -1) {
+ pkg = fn.substring(0,sp);
+ }
+ // Is this a module-info.java file?
+ if (fn.endsWith("module-info.java")) {
+ // Aha! We have recursed into a module!
+ if (!currentModule.name().equals("")) {
+ throw new ProblemException("You have an extra module-info.java inside a module! Please remove "+fn);
+ }
+ String module_name = fn.substring(0,fn.length()-16);
+ currentModule = new Module(module_name, f.getPath());
+ foundModules.put(module_name, currentModule);
+ }
+ // Extract the suffix.
+ int dp = fn.lastIndexOf(".");
+ String suffix = "";
+ if (dp > 0) {
+ suffix = fn.substring(dp);
+ }
+ // Should the file be added?
+ if (suffixes.contains(suffix)) {
+ Source of = foundFiles.get(f.getPath());
+ if (of != null) {
+ throw new ProblemException("You have already added the file "+fn+" from "+of.file().getPath());
+ }
+ of = currentModule.lookupSource(f.getPath());
+ if (of != null) {
+ // Oups, the source is already added, could be ok, could be not, lets check.
+ if (inLinksrc) {
+ // So we are collecting sources for linking only.
+ if (of.isLinkedOnly()) {
+ // Ouch, this one is also for linking only. Bad.
+ throw new ProblemException("You have already added the link only file "+fn+" from "+of.file().getPath());
}
- String module_name = fn.substring(0,fn.length()-16);
- currentModule = new Module(module_name, f.getPath());
- foundModules.put(module_name, currentModule);
- }
- // Extract the suffix.
- int dp = fn.lastIndexOf(".");
- String suffix = "";
- if (dp > 0) {
- suffix = fn.substring(dp);
- }
- // Should the file be added?
- if (all || suffixes.contains(suffix)) {
- Source of = foundFiles.get(f.getPath());
- if (of != null) {
- throw new ProblemException("You have already added the file "+fn+" from "+of.file().getPath());
- }
- of = currentModule.lookupSource(f.getPath());
- if (of != null) {
- // Oups, the source is already added, could be ok, could be not, lets check.
- if (inLinksrc) {
- // So we are collecting sources for linking only.
- if (of.isLinkedOnly()) {
- // Ouch, this one is also for linking only. Bad.
- throw new ProblemException("You have already added the link only file "+fn+" from "+of.file().getPath());
- }
- // Ok, the existing source is to be compiled. Thus this link only is redundant
- // since all compiled are also linked to. Continue to the next source.
- // But we need to add the source, so that it will be visible to linking,
- // if not the multi core compile will fail because a JavaCompiler cannot
- // find the necessary dependencies for its part of the source.
- foundFiles.put(f.getPath(), of);
- continue;
- } else {
- // We are looking for sources to compile, if we find an existing to be compiled
- // source with the same name, it is an internal error, since we must
- // find the sources to be compiled before we find the sources to be linked to.
- throw new ProblemException("Internal error: Double add of file "+fn+" from "+of.file().getPath());
- }
- }
- Source s = new Source(currentModule, f.getPath(), f, root);
- if (inGensrc) s.markAsGenerated();
- if (inLinksrc) {
- s.markAsLinkedOnly();
- }
- pkg = currentModule.name()+":"+pkg;
- foundFiles.put(f.getPath(), s);
- currentModule.addSource(pkg, s);
+ // Ok, the existing source is to be compiled. Thus this link only is redundant
+ // since all compiled are also linked to. Continue to the next source.
+ // But we need to add the source, so that it will be visible to linking,
+ // if not the multi core compile will fail because a JavaCompiler cannot
+ // find the necessary dependencies for its part of the source.
+ foundFiles.put(f.getPath(), of);
+ continue;
+ } else {
+ // We are looking for sources to compile, if we find an existing to be compiled
+ // source with the same name, it is an internal error, since we must
+ // find the sources to be compiled before we find the sources to be linked to.
+ throw new ProblemException("Internal error: Double add of file "+fn+" from "+of.file().getPath());
}
}
+ Source s = new Source(currentModule, f.getPath(), f, root);
+ if (inGensrc) s.markAsGenerated();
+ if (inLinksrc) {
+ s.markAsLinkedOnly();
+ }
+ pkg = currentModule.name()+":"+pkg;
+ foundFiles.put(f.getPath(), s);
+ currentModule.addSource(pkg, s);
}
}
return currentModule;
@@ -368,23 +378,22 @@
static private void scanDirectory(File dir, int rootPrefix, File root,
Set<String> suffixes,
List<String> excludes, List<String> includes,
- List<String> excludeFiles, List<String> includeFiles, boolean all,
+ List<String> excludeFiles, List<String> includeFiles,
Map<String,Source> foundFiles,
Map<String,Module> foundModules,
Module currentModule, boolean inGensrc, boolean inLinksrc)
throws ProblemException {
- String pkg_name = "";
- // Remove the root prefix from the dir path, and replace file separator with dots
- // to get the package name.
+ String path = "";
+ // Remove the root prefix from the dir path
if (dir.getPath().length() > rootPrefix) {
- pkg_name = dir.getPath().substring(rootPrefix).replace(File.separatorChar,'.');
+ path = dir.getPath().substring(rootPrefix);
}
// Should this package directory be included and not excluded?
- if (all || ((includes==null || includes.isEmpty() || hasMatch(pkg_name, includes)) &&
- (excludes==null || excludes.isEmpty() || !hasMatch(pkg_name, excludes)))) {
+ if ((includes==null || includes.isEmpty() || hasMatch(path, includes)) &&
+ (excludes==null || excludes.isEmpty() || !hasMatch(path, excludes))) {
// Add the source files.
- currentModule = addFilesInDir(dir, rootPrefix, root, suffixes, true, excludeFiles, includeFiles, all,
+ currentModule = addFilesInDir(dir, rootPrefix, root, suffixes, true, excludeFiles, includeFiles,
foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
}
@@ -392,7 +401,7 @@
if (d.isDirectory()) {
// Descend into the directory structure.
scanDirectory(d, rootPrefix, root, suffixes,
- excludes, includes, excludeFiles, includeFiles, all,
+ excludes, includes, excludeFiles, includeFiles,
foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
}
}
--- a/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java Mon Apr 21 22:51:49 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Transformer.java Tue Apr 22 16:51:10 2014 +0200
@@ -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
@@ -30,6 +30,8 @@
import java.util.Set;
import java.util.Map;
+import com.sun.tools.sjavac.options.Options;
+
/**
* The transform interface is used to transform content inside a package, from one form to another.
* Usually the output form is an unpredictable number of output files. (eg class files)
@@ -95,5 +97,5 @@
PrintStream err);
void setExtra(String e);
- void setExtra(String[] args);
+ void setExtra(Options args);
}
--- a/langtools/src/share/classes/com/sun/tools/sjavac/Util.java Mon Apr 21 22:51:49 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Util.java Tue Apr 22 16:51:10 2014 +0200
@@ -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
@@ -26,6 +26,7 @@
package com.sun.tools.sjavac;
import java.io.File;
+import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@@ -94,14 +95,12 @@
* do settings = cleanOptions("--server:",Util.set("-portfile"),settings);
* now settings equals "--server:portfile=bar"
*
- * @param optionPrefix The option name, including colon, eg --server:
* @param allowsSubOptions A set of the allowed sub options, id portfile etc.
* @param s The option settings string.
*/
- public static String cleanSubOptions(String optionPrefix, Set<String> allowedSubOptions, String s) {
+ public static String cleanSubOptions(Set<String> allowedSubOptions, String s) {
StringBuilder sb = new StringBuilder();
- if (!s.startsWith(optionPrefix)) return "";
- StringTokenizer st = new StringTokenizer(s.substring(optionPrefix.length()), ",");
+ StringTokenizer st = new StringTokenizer(s, ",");
while (st.hasMoreTokens()) {
String o = st.nextToken();
int p = o.indexOf('=');
@@ -157,4 +156,9 @@
}
return null;
}
+
+ // TODO: Remove when refactoring from java.io.File to java.nio.file.Path.
+ public static File pathToFile(Path path) {
+ return path == null ? null : path.toFile();
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/ArgumentIterator.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,83 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.options;
+
+import java.util.Iterator;
+
+public class ArgumentIterator implements Iterator<String> {
+
+ /** The underlying argument iterator */
+ private Iterator<String> iter;
+
+ /** Extra state used to implement peek and current */
+ private String current;
+ private String buffered;
+
+ public ArgumentIterator(Iterable<String> iter) {
+ this.iter = iter.iterator();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return buffered != null || iter.hasNext();
+ }
+
+ @Override
+ public String next() {
+ fillBuffer();
+ current = buffered;
+ buffered = null;
+ return current;
+ }
+
+ /**
+ * @return the last element returned by next() (or {@code null} if next has
+ * never been invoked on this iterator).
+ */
+ public String current() {
+ return current;
+ }
+
+ /** Can't remove current element, since we may have buffered it. */
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @return Returns the next element without advancing the iterator
+ */
+ public String peek() {
+ fillBuffer();
+ return buffered;
+ }
+
+ private void fillBuffer() {
+ if (buffered == null && iter.hasNext())
+ buffered = iter.next();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,360 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.options;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.sun.tools.sjavac.CopyFile;
+import com.sun.tools.sjavac.Transformer;
+
+
+/**
+ * Sjavac options can be classified as:
+ *
+ * (1) relevant only for sjavac, such as --server
+ * (2) relevant for sjavac and javac, such as -d, or
+ * (3) relevant only for javac, such as -g.
+ *
+ * This enum represents all options from (1) and (2). Note that instances of
+ * this enum only entail static information about the option. For storage of
+ * option values, refer to com.sun.tools.sjavac.options.Options.
+ */
+public enum Option {
+
+ SRC("-src", "Location of source files to be compiled") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ List<Path> paths = getFileListArg(iter, helper);
+ if (paths != null)
+ helper.sourceRoots(paths);
+ }
+ },
+ SOURCEPATH("-sourcepath", "Specify search path for sources.") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ List<Path> paths = getFileListArg(iter, helper);
+ if (paths != null)
+ helper.sourcepath(paths);
+ }
+ },
+ MODULEPATH("-modulepath", "Specify search path for modules.") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ List<Path> paths = getFileListArg(iter, helper);
+ if (paths != null)
+ helper.modulepath(paths);
+ }
+ },
+ CLASSPATH("-classpath", "Specify search path for classes.") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ List<Path> paths = getFileListArg(iter, helper);
+ if (paths != null)
+ helper.classpath(paths);
+ }
+ },
+ CP("-cp", "An alias for -classpath") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ CLASSPATH.processMatching(iter, helper);
+ }
+ },
+ X("-x", "Exclude directory from the subsequent source directory") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ String pattern = getFilePatternArg(iter, helper);
+ if (pattern != null)
+ helper.exclude(pattern);
+ }
+ },
+ I("-i", "Include only the given directory from the subsequent source directory") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ String pattern = getFilePatternArg(iter, helper);
+ if (pattern != null)
+ helper.include(pattern);
+ }
+ },
+ XF("-xf", "Exclude a given file") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ String pattern = getFilePatternArg(iter, helper);
+ if (pattern != null)
+ helper.excludeFile(pattern);
+ }
+ },
+ IF("-if", "Include only the given file") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ String pattern = getFilePatternArg(iter, helper);
+ if (pattern != null)
+ helper.includeFile(pattern);
+ }
+ },
+ TR("-tr", "Translate resources") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+
+ if (!iter.hasNext()) {
+ helper.reportError(arg + " must be followed by a translation rule");
+ return;
+ }
+
+ String trArg = iter.next();
+
+ // Validate argument syntax. Examples:
+ // .prop=com.sun.tools.javac.smart.CompileProperties
+ // .idl=com.sun.corba.CompileIdl
+ // .g3=antlr.CompileGrammar,debug=true
+ String ident = "[a-zA-Z_][a-zA-Z0-9_]*";
+ Pattern p = Pattern.compile("(?<suffix>\\." + ident + ")=" +
+ "(?<class>" + ident + "(\\." + ident + ")*)" +
+ "(?<extra>,.*)?");
+ // Check syntax
+ Matcher m = p.matcher(trArg);
+ if (!m.matches()) {
+ helper.reportError("The string \"" + trArg + "\" is not a " +
+ "valid translate pattern");
+ return;
+ }
+
+ // Extract relevant parts
+ String suffix = m.group("suffix");
+ String classname = m.group("class");
+ String extra = m.group("extra");
+
+ // Valid suffix?
+ if (suffix.matches("\\.(class|java)")) {
+ helper.reportError("You cannot have a translator for " +
+ suffix + " files!");
+ return;
+ }
+
+ // Construct transformer
+ try {
+ Class<?> trCls = Class.forName(classname);
+ Transformer transformer = (Transformer) trCls.newInstance();
+ transformer.setExtra(extra);
+ helper.addTransformer(suffix, transformer);
+ } catch (Exception e) {
+ helper.reportError("Cannot use " + classname +
+ " as a translator: " + e.getMessage());
+ }
+ }
+ },
+ COPY("-copy", "Copy resources") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ if (!iter.hasNext()) {
+ helper.reportError(arg + " must be followed by a resource type");
+ return;
+ }
+
+ String copyArg = iter.next();
+
+ // Validate argument syntax. Examples: .gif, .html
+ if (!copyArg.matches("\\.[a-zA-Z_][a-zA-Z0-9_]*")) {
+ helper.reportError("The string \"" + copyArg + "\" is not a " +
+ "valid resource type.");
+ return;
+ }
+
+ helper.addTransformer(copyArg, new CopyFile());
+ }
+ },
+ J("-j", "Number of cores") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ if (!iter.hasNext() || !iter.peek().matches("\\d+")) {
+ helper.reportError(arg + " must be followed by an integer");
+ return;
+ }
+ helper.numCores(Integer.parseInt(iter.next()));
+ }
+ },
+ SERVER("--server:", "Specify server configuration file of running server") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ helper.serverConf(iter.current().substring(arg.length()));
+ }
+ },
+ STARTSERVER("--startserver:", "Start server and use the given configuration file") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ helper.startServerConf(iter.current().substring(arg.length()));
+ }
+ },
+ IMPLICIT("-implicit:", "Specify how to treat implicitly referenced source code") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ helper.implicit(iter.current().substring(arg.length()));
+ }
+ },
+ LOG("--log=", "Specify logging level") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ helper.logLevel(iter.current().substring(arg.length()));
+ }
+ },
+ VERBOSE("-verbose", "Set verbosity level to \"info\"") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ helper.logLevel("info");
+ }
+ },
+ PERMIT_UNIDENTIFIED_ARTIFACTS("--permit-unidentified-artifacts", "Keep unidentified artifacts in destination directory") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ helper.permitUnidentifiedArtifacts();
+ }
+ },
+ PERMIT_SOURCES_WITHOUT_PACKAGE("--permit-sources-without-package", "Permit sources in the default package") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ helper.permitDefaultPackage();
+ }
+ },
+ COMPARE_FOUND_SOURCES("--compare-found-sources", "Compare found sources with given sources") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ Path referenceSourceList = getFileArg(iter, helper, true, false);
+ if (referenceSourceList != null)
+ helper.compareFoundSources(referenceSourceList);
+ }
+ },
+ D("-d", "Output destination directory") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ Path dir = getFileArg(iter, helper, false, true);
+ if (dir != null)
+ helper.destDir(dir);
+ }
+ },
+ S("-s", "Directory for generated sources") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ Path dir = getFileArg(iter, helper, false, true);
+ if (dir != null)
+ helper.generatedSourcesDir(dir);
+ }
+ },
+ H("-h", "Directory for header files") {
+ @Override
+ protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+ Path dir = getFileArg(iter, helper, false, true);
+ if (dir != null)
+ helper.headerDir(dir);
+ }
+ };
+
+ public final String arg;
+
+ final String description;
+
+ private Option(String arg, String description) {
+ this.arg = arg;
+ this.description = description;
+ }
+
+ /** Retrieve and verify syntax of file list argument. */
+ List<Path> getFileListArg(ArgumentIterator iter, OptionHelper helper) {
+ if (!iter.hasNext()) {
+ helper.reportError(arg + " must be followed by a list of files " +
+ "separated by " + File.pathSeparator);
+ return null;
+ }
+ List<Path> result = new ArrayList<>();
+ for (String pathStr : iter.next().split(File.pathSeparator))
+ result.add(Paths.get(pathStr));
+ return result;
+ }
+
+ /** Retrieve and verify syntax of file argument. */
+ Path getFileArg(ArgumentIterator iter, OptionHelper helper, boolean fileAcceptable, boolean dirAcceptable) {
+
+ if (!iter.hasNext()) {
+ String errmsg = arg + " must be followed by ";
+ if (fileAcceptable && dirAcceptable) errmsg += "a file or directory.";
+ else if (fileAcceptable) errmsg += "a file.";
+ else if (dirAcceptable) errmsg += "a directory.";
+ else throw new IllegalArgumentException("File or directory must be acceptable.");
+ helper.reportError(errmsg);
+ return null;
+ }
+
+ return Paths.get(iter.next());
+ }
+
+ /** Retrieve the next file or package argument. */
+ String getFilePatternArg(ArgumentIterator iter, OptionHelper helper) {
+
+ if (!iter.hasNext()) {
+ helper.reportError(arg + " must be followed by a file or directory pattern.");
+ return null;
+ }
+
+ return iter.next();
+ }
+
+ // Future cleanup: Change the "=" syntax to ":" syntax to be consistent and
+ // to follow the javac-option style.
+
+ public boolean hasOption() {
+ return arg.endsWith(":") || arg.endsWith("=");
+ }
+
+
+ /**
+ * Process current argument of argIter.
+ *
+ * It's final, since the option customization is typically done in
+ * processMatching.
+ *
+ * @param argIter Iterator to read current and succeeding arguments from.
+ * @param helper The helper to report back to.
+ * @return true iff the argument was processed by this option.
+ */
+ public final boolean processCurrent(ArgumentIterator argIter,
+ OptionHelper helper) {
+ String fullArg = argIter.current(); // "-tr" or "-log=level"
+ if (hasOption() ? fullArg.startsWith(arg) : fullArg.equals(arg)) {
+ processMatching(argIter, helper);
+ return true;
+ }
+ // Did not match
+ return false;
+ }
+
+ /** Called by process if the current argument matches this option. */
+ protected abstract void processMatching(ArgumentIterator argIter,
+ OptionHelper helper);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,146 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.options;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+
+import com.sun.tools.sjavac.Transformer;
+
+/**
+ * This class is used to decode sjavac options.
+ * See com.sun.tools.sjavac.options.Options for example usage.
+ */
+public abstract class OptionHelper {
+
+ /** Handle error */
+ public abstract void reportError(String msg);
+
+ /** Record a package exclusion pattern */
+ public abstract void exclude(String excl);
+
+ /** Record a package inclusion pattern */
+ public abstract void include(String incl);
+
+ /** Record a file exclusion */
+ public abstract void excludeFile(String exclFile);
+
+ /** Record a file inclusion */
+ public abstract void includeFile(String inclFile);
+
+ /** Record a root of sources to be compiled */
+ public abstract void sourceRoots(List<Path> path);
+
+ /** Record a suffix + transformer */
+ public abstract void addTransformer(String suffix, Transformer tr);
+
+ /** Record a sourcepath to be used */
+ public abstract void sourcepath(List<Path> path);
+
+ /** Record a modulepath to be used */
+ public abstract void modulepath(List<Path> path);
+
+ /** Record a classpath to be used */
+ public abstract void classpath(List<Path> path);
+
+ /** Record the number of cores */
+ public abstract void numCores(int parseInt);
+
+ /** Record desired log level */
+ public abstract void logLevel(String level);
+
+ /** Record path for reference source list */
+ public abstract void compareFoundSources(Path referenceList);
+
+ /** Record the fact that unidentified artifacts are permitted */
+ public abstract void permitUnidentifiedArtifacts();
+
+ /** Record the fact that sources in the default package are permitted */
+ public abstract void permitDefaultPackage();
+
+ /** Record server configuration parameters */
+ public abstract void serverConf(String serverConf);
+
+ /** Record server launch configuration parameters */
+ public abstract void startServerConf(String serverConf);
+
+ /** Record some arguments to be passed on to javac */
+ public abstract void javacArg(String... arg);
+
+ /** Sets the destination directory for the compilation */
+ public abstract void destDir(Path dir);
+
+ /** Sets the directory for generated sources */
+ public abstract void generatedSourcesDir(Path genSrcDir);
+
+ /** Sets the directory for generated headers */
+ public abstract void headerDir(Path dir);
+
+ /** Sets the implicit policy */
+ public abstract void implicit(String policy);
+
+
+ /**
+ * Traverses an array of arguments and performs the appropriate callbacks.
+ *
+ * @param args the arguments to traverse.
+ */
+ void traverse(String[] args) {
+
+ ArgumentIterator argIter = new ArgumentIterator(Arrays.asList(args));
+
+ nextArg:
+ while (argIter.hasNext()) {
+
+ String arg = argIter.next();
+
+ if (arg.startsWith("-")) {
+ for (Option opt : Option.values()) {
+ if (opt.processCurrent(argIter, this))
+ continue nextArg;
+ }
+
+ javacArg(arg);
+
+ // Does this javac argument take an argument? If so, don't
+ // let it pass on to sjavac as a source root directory.
+ for (com.sun.tools.javac.main.Option javacOpt : com.sun.tools.javac.main.Option.values()) {
+ if (javacOpt.matches(arg)) {
+ boolean takesArgument = javacOpt.hasArg();
+ boolean separateToken = !arg.contains(":") && !arg.contains("=");
+ if (takesArgument && separateToken)
+ javacArg(argIter.next());
+ }
+ }
+ } else {
+ sourceRoots(Arrays.asList(Paths.get(arg)));
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,490 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.options;
+
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.tools.sjavac.Transformer;
+
+/**
+ * Instances of this class represent values for sjavac command line options.
+ */
+public class Options {
+
+ // Output directories
+ private Path destDir, genSrcDir, headerDir;
+
+ // Input directories
+ private List<SourceLocation> sources = new ArrayList<>();
+ private List<SourceLocation> sourceSearchPaths = new ArrayList<>();
+ private List<SourceLocation> classSearchPaths = new ArrayList<>();
+ private List<SourceLocation> moduleSearchPaths = new ArrayList<>();
+
+ private String logLevel = "info";
+
+ private boolean permitUnidentifiedArtifact = false;
+ private boolean permitSourcesInDefaultPackage = false;
+
+ private Path sourceReferenceList;
+ private int numCores = 4;
+ private String implicitPolicy = "none";
+ private List<String> javacArgs = new ArrayList<>();
+
+ private Map<String, Transformer> trRules = new HashMap<>();
+
+ private boolean startServer = false;
+
+ // Server configuration string
+ private String serverConf;
+
+ /** Get the policy for implicit classes */
+ public String getImplicitPolicy() {
+ return implicitPolicy;
+ }
+
+ /** Get the path for generated sources (or null if no such path is set) */
+ public Path getGenSrcDir() {
+ return genSrcDir;
+ }
+
+ /** Get the path for the destination directory */
+ public Path getDestDir() {
+ return destDir;
+ }
+
+ /** Get the path for the header directory (or null if no such path is set) */
+ public Path getHeaderDir() {
+ return headerDir;
+ }
+
+ /** Get all source locations for files to be compiled */
+ public List<SourceLocation> getSources() {
+ return sources;
+ }
+
+ /**
+ * Get all paths to search for classes in .java format. (Java-files in
+ * found here should not be compiled.
+ */
+ public List<SourceLocation> getSourceSearchPaths() {
+ return sourceSearchPaths;
+ }
+
+ /** Get all paths to search for classes in. */
+ public List<SourceLocation> getClassSearchPath() {
+ return classSearchPaths;
+ }
+
+ /** Get all paths to search for modules in. */
+ public List<SourceLocation> getModuleSearchPaths() {
+ return moduleSearchPaths;
+ }
+
+ /** Get the log level. */
+ public String getLogLevel() {
+ return logLevel;
+ }
+
+ /** Returns true iff artifacts in the output directories should be kept,
+ * even if they would not be generated in a clean build. */
+ public boolean isUnidentifiedArtifactPermitted() {
+ return permitUnidentifiedArtifact;
+ }
+
+ /** Returns true iff sources in the default package should be permitted. */
+ public boolean isDefaultPackagePermitted() {
+ return permitSourcesInDefaultPackage;
+ }
+
+ /** Get the path to the list of reference sources (or null if none is set) */
+ public Path getSourceReferenceList() {
+ return sourceReferenceList;
+ }
+
+ /** Get the number of cores to be used by sjavac */
+ public int getNumCores() {
+ return numCores;
+ }
+
+ /** Returns all arguments relevant to javac but irrelevant to sjavac. */
+ public List<String> getJavacArgs() {
+ return javacArgs;
+ }
+
+ /**
+ * Get a map which maps suffixes to transformers (for example
+ * ".java" -> CompileJavaPackages)
+ */
+ public Map<String, Transformer> getTranslationRules() {
+ return trRules;
+ }
+
+ /** Return true iff a new server should be started */
+ public boolean startServerFlag() {
+ return startServer;
+ }
+
+ /** Return the server configuration string. */
+ public String getServerConf() {
+ return serverConf;
+ }
+
+ /**
+ * Parses the given argument array and returns a corresponding Options
+ * instance.
+ */
+ public static Options parseArgs(String... args) {
+ Options options = new Options();
+ options.new ArgDecoderOptionHelper().traverse(args);
+ return options;
+ }
+
+ /** Returns true iff a .java file is among the javac arguments */
+ public boolean isJavaFilesAmongJavacArgs() {
+ for (String javacArg : javacArgs)
+ if (javacArg.endsWith(".java"))
+ return true;
+ return false;
+ }
+
+ /** Returns true iff an @-file is among the javac arguments */
+ public boolean isAtFilePresent() {
+ for (String javacArg : javacArgs)
+ if (javacArg.startsWith("@"))
+ return true;
+ return false;
+ }
+
+ /**
+ * Returns a string representation of the options that affect the result of
+ * the compilation. (Used for saving the state of the options used in a
+ * previous compile.)
+ */
+ public String getStateArgsString() {
+
+ // Local utility class for collecting the arguments
+ class StateArgs {
+
+ private List<String> args = new ArrayList<>();
+
+ void addArg(Option opt) {
+ args.add(opt.arg);
+ }
+
+ void addArg(Option opt, Object val) {
+ addArg(opt);
+ args.add(val.toString());
+ }
+
+ void addSourceLocations(Option opt, List<SourceLocation> locs) {
+ for (SourceLocation sl : locs) {
+ for (String pkg : sl.includes) addArg(Option.I, pkg);
+ for (String pkg : sl.excludes) addArg(Option.X, pkg);
+ for (String f : sl.excludedFiles) addArg(Option.XF, f);
+ for (String f : sl.includedFiles) addArg(Option.IF, f);
+ addArg(opt, sl.getPath());
+ }
+ }
+
+ String getResult() {
+ String result = "";
+ for (String s : args)
+ result += s + " ";
+ return result.trim();
+ }
+
+ public void addAll(Collection<String> toAdd) {
+ args.addAll(toAdd);
+ }
+ }
+
+ StateArgs args = new StateArgs();
+
+ // Directories
+ if (genSrcDir != null)
+ args.addArg(Option.S, genSrcDir.normalize());
+
+ if (headerDir != null)
+ args.addArg(Option.H, headerDir.normalize());
+
+ if (destDir != null)
+ args.addArg(Option.D, destDir.normalize());
+
+ // Source roots
+ args.addSourceLocations(Option.SRC, sources);
+ args.addSourceLocations(Option.SOURCEPATH, sourceSearchPaths);
+ args.addSourceLocations(Option.CLASSPATH, classSearchPaths);
+ args.addSourceLocations(Option.MODULEPATH, moduleSearchPaths);
+
+ // Boolean options
+ if (permitSourcesInDefaultPackage)
+ args.addArg(Option.PERMIT_SOURCES_WITHOUT_PACKAGE);
+
+ if (permitUnidentifiedArtifact)
+ args.addArg(Option.PERMIT_UNIDENTIFIED_ARTIFACTS);
+
+ // Translation rules
+ for (Map.Entry<String, Transformer> tr : trRules.entrySet()) {
+ String val = tr.getKey() + "=" + tr.getValue().getClass().getName();
+ args.addArg(Option.TR, val);
+ }
+
+ // Javac args
+ args.addAll(javacArgs);
+
+ return args.getResult();
+ }
+
+
+ /** Extract the arguments to be passed on to javac. */
+ public String[] prepJavacArgs() {
+ List<String> args = new ArrayList<>();
+
+ // Output directories
+ args.add("-d");
+ args.add(destDir.toString());
+
+ if (getGenSrcDir() != null) {
+ args.add("-s");
+ args.add(genSrcDir.toString());
+ }
+
+ if (headerDir != null) {
+ args.add("-h");
+ args.add(headerDir.toString());
+ }
+
+ // Prep sourcepath
+ List<SourceLocation> sourcepath = new ArrayList<>();
+ sourcepath.addAll(sources);
+ sourcepath.addAll(sourceSearchPaths);
+ if (sourcepath.size() > 0) {
+ args.add("-sourcepath");
+ args.add(concatenateSourceLocations(sourcepath));
+ }
+
+ // Prep classpath
+ if (classSearchPaths.size() > 0) {
+ args.add("-classpath");
+ args.add(concatenateSourceLocations(classSearchPaths));
+ }
+
+ // This can't be anything but 'none'. Enforced by sjavac main method.
+ args.add("-implicit:" + implicitPolicy);
+
+ // Append javac-options (i.e. pass through options not recognized by
+ // sjavac to javac.)
+ args.addAll(javacArgs);
+
+ return args.toArray(new String[args.size()]);
+ }
+
+ // Helper method to join a list of source locations separated by
+ // File.pathSeparator
+ private static String concatenateSourceLocations(List<SourceLocation> locs) {
+ String s = "";
+ for (SourceLocation loc : locs)
+ s += (s.isEmpty() ? "" : java.io.File.pathSeparator) + loc.getPath();
+ return s;
+ }
+
+ // OptionHelper that records the traversed options in this Options instance.
+ private class ArgDecoderOptionHelper extends OptionHelper {
+
+ List<String> includes, excludes, includeFiles, excludeFiles;
+ {
+ resetFilters();
+ }
+
+ boolean headerProvided = false;
+ boolean genSrcProvided = false;
+
+ @Override
+ public void reportError(String msg) {
+ throw new IllegalArgumentException(msg);
+ }
+
+ @Override
+ public void sourceRoots(List<Path> paths) {
+ sources.addAll(createSourceLocations(paths));
+ }
+
+ @Override
+ public void exclude(String exclPattern) {
+ excludes.add(exclPattern);
+ }
+
+ @Override
+ public void include(String inclPattern) {
+ includes.add(inclPattern);
+ }
+
+ @Override
+ public void excludeFile(String exclFilePattern) {
+ excludeFiles.add(exclFilePattern);
+ }
+
+ @Override
+ public void includeFile(String inclFilePattern) {
+ includeFiles.add(inclFilePattern);
+ }
+
+ @Override
+ public void addTransformer(String suffix, Transformer tr) {
+ if (trRules.containsKey(suffix)) {
+ reportError("More than one transformer specified for " +
+ "suffix " + suffix + ".");
+ return;
+ }
+ trRules.put(suffix, tr);
+ }
+
+ @Override
+ public void sourcepath(List<Path> paths) {
+ sourceSearchPaths.addAll(createSourceLocations(paths));
+ }
+
+ @Override
+ public void modulepath(List<Path> paths) {
+ moduleSearchPaths.addAll(createSourceLocations(paths));
+ }
+
+ @Override
+ public void classpath(List<Path> paths) {
+ classSearchPaths.addAll(createSourceLocations(paths));
+ }
+
+ @Override
+ public void numCores(int n) {
+ numCores = n;
+ }
+
+ @Override
+ public void logLevel(String level) {
+ logLevel = level;
+ }
+
+ @Override
+ public void compareFoundSources(Path referenceList) {
+ sourceReferenceList = referenceList;
+ }
+
+ @Override
+ public void permitUnidentifiedArtifacts() {
+ permitUnidentifiedArtifact = true;
+ }
+
+ @Override
+ public void permitDefaultPackage() {
+ permitSourcesInDefaultPackage = true;
+ }
+
+ @Override
+ public void serverConf(String conf) {
+ if (serverConf != null)
+ reportError("Can not specify more than one server configuration.");
+ else
+ serverConf = conf;
+ }
+
+ @Override
+ public void implicit(String policy) {
+ implicitPolicy = policy;
+ }
+
+ @Override
+ public void startServerConf(String conf) {
+ if (serverConf != null)
+ reportError("Can not specify more than one server configuration.");
+ else {
+ startServer = true;
+ serverConf = conf;
+ }
+ }
+
+ @Override
+ public void javacArg(String... arg) {
+ javacArgs.addAll(Arrays.asList(arg));
+ }
+
+ @Override
+ public void destDir(Path dir) {
+ if (destDir != null) {
+ reportError("Destination directory already specified.");
+ return;
+ }
+ destDir = dir.toAbsolutePath();
+ }
+
+ @Override
+ public void generatedSourcesDir(Path dir) {
+ if (genSrcProvided) {
+ reportError("Directory for generated sources already specified.");
+ return;
+ }
+ genSrcProvided = true;
+ genSrcDir = dir.toAbsolutePath();
+ }
+
+ @Override
+ public void headerDir(Path dir) {
+ if (headerProvided) {
+ reportError("Header directory already specified.");
+ return;
+ }
+ headerProvided = true;
+ headerDir = dir.toAbsolutePath();
+ }
+
+ private List<SourceLocation> createSourceLocations(List<Path> paths) {
+ List<SourceLocation> result = new ArrayList<>();
+ for (Path path : paths) {
+ result.add(new SourceLocation(
+ path,
+ includes,
+ excludes,
+ includeFiles,
+ excludeFiles));
+ }
+ resetFilters();
+ return result;
+ }
+
+ private void resetFilters() {
+ includes = new ArrayList<>();
+ excludes = new ArrayList<>();
+ includeFiles = new ArrayList<>();
+ excludeFiles = new ArrayList<>();
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/SourceLocation.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,115 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.sjavac.options;
+
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.sun.tools.sjavac.Module;
+import com.sun.tools.sjavac.ProblemException;
+import com.sun.tools.sjavac.Source;
+
+/**
+ * Represents a directory to be used for input to sjavac. (For instance a
+ * sourcepath or classpath.)
+ */
+public class SourceLocation {
+
+ // Path to the root directory
+ private Path path;
+
+ // Package include / exclude patterns and file includes / excludes.
+ List<String> includes, excludes, includedFiles, excludedFiles;
+
+ public SourceLocation(Path path,
+ List<String> includes,
+ List<String> excludes,
+ List<String> includedFiles,
+ List<String> excludedFiles) {
+ this.path = path;
+ this.includes = includes;
+ this.excludes = excludes;
+ this.includedFiles = includedFiles;
+ this.excludedFiles = excludedFiles;
+ }
+
+
+ /**
+ * Finds all files with the given suffix that pass the include / exclude
+ * filters in this source location.
+ *
+ * @param suffixes The set of suffixes to search for
+ * @param foundFiles The map in which to store the found files
+ * @param foundModules The map in which to store the found modules
+ * @param currentModule The current module
+ * @param permitSourcesInDefaultPackage true if sources in default package
+ * are to be permitted
+ * @param inLinksrc true if in link source
+ */
+ public void findSourceFiles(Set<String> suffixes,
+ Map<String, Source> foundFiles,
+ Map<String, Module> foundModules,
+ Module currentModule,
+ boolean permitSourcesInDefaultPackage,
+ boolean inLinksrc) {
+ try {
+ Source.scanRoot(path.toFile(), suffixes, excludes, includes,
+ excludedFiles, includedFiles, foundFiles, foundModules,
+ currentModule, permitSourcesInDefaultPackage, false,
+ inLinksrc);
+ } catch (ProblemException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /** Get the root directory of this source location */
+ public Path getPath() {
+ return path;
+ }
+
+ /** Get the package include patterns */
+ public List<String> getIncludes() {
+ return includes;
+ }
+
+ /** Get the package exclude patterns */
+ public List<String> getExcludes() {
+ return excludes;
+ }
+
+ /** Get the file include patterns */
+ public List<String> getIncludedFiles() {
+ return includedFiles;
+ }
+
+ /** Get the file exclude patterns */
+ public List<String> getExcludedFiles() {
+ return excludedFiles;
+ }
+
+}
--- a/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java Mon Apr 21 22:51:49 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/JavacServer.java Tue Apr 22 16:51:10 2014 +0200
@@ -104,6 +104,17 @@
allPortFiles = new HashMap<>();
}
PortFile pf = allPortFiles.get(filename);
+
+ // Port file known. Does it still exist?
+ if (pf != null) {
+ try {
+ if (!pf.exists())
+ pf = null;
+ } catch (IOException ioex) {
+ ioex.printStackTrace();
+ }
+ }
+
if (pf == null) {
pf = new PortFile(filename);
allPortFiles.put(filename, pf);
@@ -305,7 +316,7 @@
// We could not connect to the server. Try again.
attempts++;
try {
- Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS);
+ Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS * 1000);
} catch (InterruptedException e) {
}
}
--- a/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java Mon Apr 21 22:51:49 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/server/PortFile.java Tue Apr 22 16:51:10 2014 +0200
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/ExclPattern.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,85 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class ExclPattern {
+
+ public static void main(String[] ignore) throws IOException {
+
+ String toBeExcluded = "pkg/excl-dir/excluded.txt";
+ String toBeIncluded = "pkg/incl-dir/included.txt";
+
+ // Set up source directory with directory to be excluded
+ populate(Paths.get("srcdir"),
+ "pkg/SomeClass.java",
+ "package pkg; public class SomeClass { }",
+
+ toBeExcluded,
+ "This file should not end up in the dest directory.",
+
+ toBeIncluded,
+ "This file should end up in the dest directory.");
+
+ String[] args = {
+ "-x", "pkg/excl-dir/*",
+ "-src", "srcdir",
+ "-d", "dest",
+ "-j", "1",
+ "-copy", ".txt",
+ "--server:portfile=testserver,background=false",
+ "--log=debug"
+ };
+
+ int rc = new com.sun.tools.sjavac.Main().go(args, System.out, System.err);
+ if (rc != 0) throw new RuntimeException("Error during compile!");
+
+ if (!Files.exists(Paths.get("dest/" + toBeIncluded)))
+ throw new AssertionError("File missing: " + toBeIncluded);
+
+ if (Files.exists(Paths.get("dest/" + toBeExcluded)))
+ throw new AssertionError("File present: " + toBeExcluded);
+ }
+
+ static void populate(Path root, String... args) throws IOException {
+ if (!Files.exists(root))
+ Files.createDirectory(root);
+ for (int i = 0; i < args.length; i += 2) {
+ String filename = args[i];
+ String content = args[i+1];
+ Path p = root.resolve(filename);
+ Files.createDirectories(p.getParent());
+ try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(p,
+ Charset.defaultCharset()))) {
+ out.println(content);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/ExclPatternWrapper.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,34 @@
+/*
+ * 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 8037085
+ * @summary Ensures that sjavac can handle various exclusion patterns.
+ * @run main ExclPatternWrapper
+ */
+public class ExclPatternWrapper {
+ public static void main(String... args) throws Exception {
+ SJavacTestUtil.runSjavacTest("ExclPattern", args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/JavacOptionPrep.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,166 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Iterator;
+
+import com.sun.tools.sjavac.options.Options;
+
+
+public class JavacOptionPrep {
+
+ enum TestPath {
+ CP1, CP2, SRC1, SRC2, SOURCEPATH1, SOURCEPATH2;
+
+ public String toString() {
+ return name().toLowerCase();
+ }
+ }
+
+ private final static String SEP = File.pathSeparator;
+
+ public static void main(String[] unused) throws IOException {
+
+ for (TestPath p : TestPath.values())
+ Files.createDirectory(Paths.get(p.toString()));
+
+ // Test some various cases:
+ // - Paths combined with File.pathSeparator (CP1 / CP2)
+ // - Paths given as duplicate options (SOURCEPATH1 / SOURCEPATH2)
+ // - Sources provided by -src (SRC1)
+ // - Sources provided without preceding option (SRC2)
+ // - An unrecognized option which is to be passed on to javac
+ String sjavacArgs = "-cp " + TestPath.CP1 + SEP + TestPath.CP2 +
+ " -d dest " +
+ " -h header" +
+ " -sourcepath " + TestPath.SOURCEPATH1 +
+ " -src " + TestPath.SRC1 +
+ " -s gensrc" +
+ " -sourcepath " + TestPath.SOURCEPATH2 +
+ " " + TestPath.SRC2 +
+ " -unrecognized";
+
+ Options options = Options.parseArgs(sjavacArgs.split(" "));
+
+ // Extract javac-options
+ String[] javacArgs = options.prepJavacArgs();
+
+ // Check the result
+ boolean destDirFound = false;
+ boolean headerDirFound = false;
+ boolean gensrcDirFound = false;
+ boolean classPathFound = false;
+ boolean sourcePathFound = false;
+ boolean unrecognizedFound = false;
+ boolean implicitNoneFound = false;
+
+ Iterator<String> javacArgIter = Arrays.asList(javacArgs).iterator();
+ while (javacArgIter.hasNext()) {
+
+ String option = javacArgIter.next();
+
+ switch (option) {
+ case "-classpath":
+ case "-cp":
+ classPathFound = true;
+ assertEquals(TestPath.CP1 + SEP + TestPath.CP2,
+ javacArgIter.next());
+ break;
+
+ case "-d":
+ destDirFound = true;
+ assertEquals(Paths.get("dest").toAbsolutePath().toString(),
+ javacArgIter.next());
+ break;
+
+ case "-h":
+ headerDirFound = true;
+ assertEquals(Paths.get("header").toAbsolutePath().toString(),
+ javacArgIter.next());
+ break;
+
+ case "-s":
+ gensrcDirFound = true;
+ assertEquals(Paths.get("gensrc").toAbsolutePath().toString(),
+ javacArgIter.next());
+ break;
+
+ case "-sourcepath":
+ sourcePathFound = true;
+ assertEquals(TestPath.SRC1 + SEP +
+ TestPath.SRC2 + SEP +
+ TestPath.SOURCEPATH1 + SEP +
+ TestPath.SOURCEPATH2,
+ javacArgIter.next());
+ break;
+
+ case "-unrecognized":
+ unrecognizedFound = true;
+ break;
+
+ case "-implicit:none":
+ implicitNoneFound = true;
+ break;
+
+ // Note that *which* files to actually compile is not dealt
+ // with by prepJavacArgs.
+
+ default:
+ throw new AssertionError("Unexpected option found: " + option);
+ }
+ }
+
+ if (!destDirFound)
+ throw new AssertionError("Dest directory not found.");
+
+ if (!headerDirFound)
+ throw new AssertionError("Header directory not found.");
+
+ if (!gensrcDirFound)
+ throw new AssertionError("Generated source directory not found.");
+
+ if (!classPathFound)
+ throw new AssertionError("Class path not found.");
+
+ if (!sourcePathFound)
+ throw new AssertionError("Source path not found.");
+
+ if (!unrecognizedFound)
+ throw new AssertionError("\"-unrecognized\" not found.");
+
+ if (!implicitNoneFound)
+ throw new AssertionError("\"-implicit:none\" not found.");
+
+ }
+
+ static void assertEquals(Object expected, Object actual) {
+ if (!expected.equals(actual))
+ throw new AssertionError("Expected " + expected + " but got " + actual);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/JavacOptionPrepWrapper.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,34 @@
+/*
+ * 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 8035063
+ * @summary Tests the preparation of javac-arguments.
+ * @run main JavacOptionPrepWrapper
+ */
+public class JavacOptionPrepWrapper {
+ public static void main(String... args) throws Exception {
+ SJavacTestUtil.runSjavacTest("JavacOptionPrep", args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/OptionDecoding.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,240 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static util.OptionTestUtil.assertEquals;
+import static util.OptionTestUtil.checkFilesFound;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.tools.sjavac.CopyFile;
+import com.sun.tools.sjavac.Main;
+import com.sun.tools.sjavac.Module;
+import com.sun.tools.sjavac.Source;
+import com.sun.tools.sjavac.options.Options;
+import com.sun.tools.sjavac.options.SourceLocation;
+
+public class OptionDecoding {
+
+ public static void main(String[] args) throws IOException {
+
+ testPaths();
+ testDupPaths();
+ testSourceLocations();
+ testSimpleOptions();
+ testServerConf();
+ testSearchPaths();
+ testTranslationRules();
+
+ }
+
+ // Test decoding of output paths
+ static void testPaths() throws IOException {
+
+ final String H = "headers";
+ final String G = "gensrc";
+ final String D = "dest";
+ final String CMP = "srcRefList.txt";
+
+ Options options = Options.parseArgs("-h", H, "-s", G, "-d", D,
+ "--compare-found-sources", CMP);
+
+ assertEquals(Paths.get(H).toAbsolutePath(), options.getHeaderDir());
+ assertEquals(Paths.get(G).toAbsolutePath(), options.getGenSrcDir());
+ assertEquals(Paths.get(D).toAbsolutePath(), options.getDestDir());
+ assertEquals(Paths.get(CMP), options.getSourceReferenceList());
+
+ }
+
+ // Providing duplicate header / dest / gensrc paths should produce an error.
+ static void testDupPaths() throws IOException {
+
+ try {
+ Options.parseArgs("-h", "dir1", "-h", "dir2");
+ throw new RuntimeException("Duplicate header directories should fail.");
+ } catch (IllegalArgumentException iae) {
+ // Expected
+ }
+
+ try {
+ Options.parseArgs("-s", "dir1", "-s", "dir2");
+ throw new RuntimeException("Duplicate paths for generated sources should fail.");
+ } catch (IllegalArgumentException iae) {
+ // Expected
+ }
+
+ try {
+ Options.parseArgs("-d", "dir1", "-d", "dir2");
+ throw new RuntimeException("Duplicate destination directories should fail.");
+ } catch (IllegalArgumentException iae) {
+ // Expected
+ }
+
+ }
+
+ // Test source locations and -x, -i, -xf, -if filters
+ static void testSourceLocations() throws IOException {
+
+ Path a1 = Paths.get("root/pkg1/ClassA1.java");
+ Path a2 = Paths.get("root/pkg1/ClassA2.java");
+ Path b1 = Paths.get("root/pkg1/pkg2/ClassB1.java");
+ Path b2 = Paths.get("root/pkg1/pkg2/ClassB2.java");
+ Path c1 = Paths.get("root/pkg3/ClassC1.java");
+ Path c2 = Paths.get("root/pkg3/ClassC2.java");
+
+ for (Path p : Arrays.asList(a1, a2, b1, b2, c1, c2)) {
+ Files.createDirectories(p.getParent());
+ Files.createFile(p);
+ }
+
+ // Test -if
+ {
+ Options options = Options.parseArgs("-if", "root/pkg1/ClassA1.java", "root");
+
+ Map<String, Source> foundFiles = new HashMap<>();
+ Main.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
+ new HashMap<String, Module>(), new Module("", ""), false, true);
+
+ checkFilesFound(foundFiles.keySet(), a1);
+ }
+
+ // Test -i
+ System.out.println("--------------------------- CHECKING -i ----------------");
+ {
+ Options options = Options.parseArgs("-i", "pkg1/*", "root");
+
+ Map<String, Source> foundFiles = new HashMap<>();
+ Main.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
+ new HashMap<String, Module>(), new Module("", ""), false, true);
+
+ checkFilesFound(foundFiles.keySet(), a1, a2, b1, b2);
+ }
+ System.out.println("--------------------------------------------------------");
+
+ // Test -xf
+ {
+ Options options = Options.parseArgs("-xf", "root/pkg1/ClassA1.java", "root");
+
+ Map<String, Source> foundFiles = new HashMap<>();
+ Main.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
+ new HashMap<String, Module>(), new Module("", ""), false, true);
+
+ checkFilesFound(foundFiles.keySet(), a2, b1, b2, c1, c2);
+ }
+
+ // Test -x
+ {
+ Options options = Options.parseArgs("-i", "pkg1/*", "root");
+
+ Map<String, Source> foundFiles = new HashMap<>();
+ Main.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
+ new HashMap<String, Module>(), new Module("", ""), false, true);
+
+ checkFilesFound(foundFiles.keySet(), a1, a2, b1, b2);
+ }
+
+ // Test -x and -i
+ {
+ Options options = Options.parseArgs("-i", "pkg1/*", "-x", "pkg1/pkg2/*", "root");
+
+ Map<String, Source> foundFiles = new HashMap<>();
+ Main.findSourceFiles(options.getSources(), Collections.singleton(".java"), foundFiles,
+ new HashMap<String, Module>(), new Module("", ""), false, true);
+
+ checkFilesFound(foundFiles.keySet(), a1, a2);
+ }
+
+ }
+
+ // Test basic options
+ static void testSimpleOptions() {
+
+ Options options = Options.parseArgs("-j", "17", "--log=debug");
+ assertEquals(17, options.getNumCores());
+ assertEquals("debug", options.getLogLevel());
+ assertEquals(false, options.isDefaultPackagePermitted());
+ assertEquals(false, options.isUnidentifiedArtifactPermitted());
+
+ options = Options.parseArgs("--permit-unidentified-artifacts",
+ "--permit-sources-without-package");
+ assertEquals("info", options.getLogLevel());
+ assertEquals(true, options.isDefaultPackagePermitted());
+ assertEquals(true, options.isUnidentifiedArtifactPermitted());
+ }
+
+ // Test server configuration options
+ static void testServerConf() {
+ Options options = Options.parseArgs("--server:someServerConfiguration");
+ assertEquals("someServerConfiguration", options.getServerConf());
+ assertEquals(false, options.startServerFlag());
+
+ options = Options.parseArgs("--startserver:someServerConfiguration");
+ assertEquals("someServerConfiguration", options.getServerConf());
+ assertEquals(true, options.startServerFlag());
+ }
+
+ // Test input paths
+ static void testSearchPaths() {
+
+ List<String> i, x, iF, xF;
+ i = x = iF = xF = new ArrayList<>();
+
+ SourceLocation dir1 = new SourceLocation(Paths.get("dir1"), i, x, iF, xF);
+ SourceLocation dir2 = new SourceLocation(Paths.get("dir2"), i, x, iF, xF);
+
+ Options options = Options.parseArgs("-sourcepath", "dir1:dir2");
+ assertEquals(options.getSourceSearchPaths(), Arrays.asList(dir1, dir2));
+
+ options = Options.parseArgs("-modulepath", "dir1:dir2");
+ assertEquals(options.getModuleSearchPaths(), Arrays.asList(dir1, dir2));
+
+ options = Options.parseArgs("-classpath", "dir1:dir2");
+ assertEquals(options.getClassSearchPath(), Arrays.asList(dir1, dir2));
+ }
+
+ // Test -tr option
+ static void testTranslationRules() {
+
+ Class<?> cls = com.sun.tools.sjavac.CompileJavaPackages.class;
+
+ Options options = Options.parseArgs(
+ "-tr", ".exa=" + cls.getName(),
+ "-tr", ".exb=" + cls.getName(),
+ "-copy", ".html");
+
+ assertEquals(cls, options.getTranslationRules().get(".exa").getClass());
+ assertEquals(cls, options.getTranslationRules().get(".exb").getClass());
+ assertEquals(CopyFile.class, options.getTranslationRules().get(".html").getClass());
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/OptionDecodingWrapper.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,34 @@
+/*
+ * 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 8035063
+ * @summary Tests decoding of String[] into Options.
+ * @run main OptionDecodingWrapper
+ */
+public class OptionDecodingWrapper {
+ public static void main(String... args) throws Exception {
+ SJavacTestUtil.runSjavacTest("OptionDecoding", args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/SJavacTestUtil.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,64 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.lang.reflect.Method;
+
+
+public class SJavacTestUtil {
+
+ public static void runSjavacTest(String testClassName, String[] args)
+ throws Exception {
+
+ if (!isSJavacOnClassPath()) {
+ System.out.println("sjavac not available: pass by default");
+ return;
+ }
+
+ File srcDir = new File(System.getProperty("test.src"));
+ File clsDir = new File(System.getProperty("test.classes"));
+
+ File src = new File(srcDir, testClassName + ".java");
+ File cls = new File(clsDir, testClassName + ".class");
+
+ if (cls.lastModified() < src.lastModified()) {
+ System.err.println("Recompiling test class...");
+ String[] javacArgs = { "-d", clsDir.getPath(), src.getPath() };
+ int rc = com.sun.tools.javac.Main.compile(javacArgs);
+ if (rc != 0)
+ throw new Exception("compilation failed");
+ }
+
+ Class<?> sjavac = Class.forName(testClassName);
+ Method main = sjavac.getMethod("main", String[].class);
+ main.invoke(null, new Object[] { args });
+
+ }
+
+ private static boolean isSJavacOnClassPath() {
+ String cls = "com/sun/tools/sjavac/Main.class";
+ return SJavacTestUtil.class.getClassLoader().getResource(cls) != null;
+ }
+}
--- a/langtools/test/tools/sjavac/SJavacWrapper.java Mon Apr 21 22:51:49 2014 +0100
+++ b/langtools/test/tools/sjavac/SJavacWrapper.java Tue Apr 22 16:51:10 2014 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -31,37 +31,8 @@
* @run main SJavacWrapper
*/
-import java.io.*;
-import java.lang.reflect.Method;
-import java.net.*;
-
-
-public
-class SJavacWrapper {
-
+public class SJavacWrapper {
public static void main(String... args) throws Exception {
- URL url = SJavacWrapper.class.getClassLoader().getResource("com/sun/tools/sjavac/Main.class");
- if (url == null) {
- // No sjavac in the classpath.
- System.out.println("sjavac not available: pass by default");
- return;
- }
-
- File testSrc = new File(System.getProperty("test.src"));
- File sjavac_java = new File(testSrc, "SJavac.java");
- File testClasses = new File(System.getProperty("test.classes"));
- File sjavac_class = new File(testClasses, "SJavac.class");
- if (sjavac_class.lastModified() < sjavac_java.lastModified()) {
- String[] javac_args = { "-d", testClasses.getPath(), sjavac_java.getPath() };
- System.err.println("Recompiling SJavac.java");
- int rc = com.sun.tools.javac.Main.compile(javac_args);
- if (rc != 0)
- throw new Exception("compilation failed");
- }
-
- Class<?> sjavac = Class.forName("SJavac");
- Method sjavac_main = sjavac.getMethod("main", String[].class);
- sjavac_main.invoke(null, new Object[] { args });
+ SJavacTestUtil.runSjavacTest("SJavac", args);
}
-
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/Serialization.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+import static util.OptionTestUtil.assertEquals;
+
+import java.io.IOException;
+import java.util.Map;
+
+import com.sun.tools.sjavac.CompileJavaPackages;
+import com.sun.tools.sjavac.Transformer;
+import com.sun.tools.sjavac.options.Option;
+import com.sun.tools.sjavac.options.Options;
+import com.sun.tools.sjavac.options.SourceLocation;
+
+
+public class Serialization {
+
+ public static void main(String[] args) throws IOException {
+
+ // Create reference options
+ Options options1 = Options.parseArgs(
+ Option.H.arg, "headers",
+ Option.S.arg, "gensrc",
+ Option.D.arg, "dest",
+ Option.I.arg, "pkg/*",
+ Option.X.arg, "pkg/pkg/*",
+ Option.IF.arg, "root/pkg/MyClass1.java",
+ Option.XF.arg, "root/pkg/MyClass2.java",
+ Option.SRC.arg, "root",
+ Option.SOURCEPATH.arg, "sourcepath",
+ Option.CLASSPATH.arg, "classpath",
+ Option.MODULEPATH.arg, "modulepath",
+ Option.PERMIT_SOURCES_WITHOUT_PACKAGE.arg,
+ Option.PERMIT_UNIDENTIFIED_ARTIFACTS.arg,
+ Option.TR.arg, ".prop=" + CompileJavaPackages.class.getName(),
+ Option.J.arg, "999",
+ "-someJavacArg",
+ "-someOtherJavacArg");
+
+ // Serialize
+ String serialized = options1.getStateArgsString();
+
+ // Deserialize
+ Options options2 = Options.parseArgs(serialized.split(" "));
+
+ // Make sure we got the same result
+ assertEquals(options1.getHeaderDir(), options2.getHeaderDir());
+ assertEquals(options1.getGenSrcDir(), options2.getGenSrcDir());
+ assertEquals(options1.getDestDir(), options2.getDestDir());
+
+ SourceLocation sl1 = options1.getSources().get(0);
+ SourceLocation sl2 = options2.getSources().get(0);
+ assertEquals(sl1.getPath(), sl2.getPath());
+ assertEquals(sl1.getIncludes(), sl2.getIncludes());
+ assertEquals(sl1.getExcludes(), sl2.getExcludes());
+ assertEquals(sl1.getIncludedFiles(), sl2.getIncludedFiles());
+ assertEquals(sl1.getExcludedFiles(), sl2.getExcludedFiles());
+
+ assertEquals(options1.getClassSearchPath(), options2.getClassSearchPath());
+ assertEquals(options1.getSourceSearchPaths(), options2.getSourceSearchPaths());
+ assertEquals(options1.getModuleSearchPaths(), options2.getModuleSearchPaths());
+
+ Map<String, Transformer> trRules1 = options1.getTranslationRules();
+ Map<String, Transformer> trRules2 = options2.getTranslationRules();
+ assertEquals(trRules1.keySet(), trRules2.keySet());
+ assertEquals(trRules1.values().iterator().next().getClass(),
+ trRules2.values().iterator().next().getClass());
+ assertEquals(options1.getJavacArgs(), options2.getJavacArgs());
+
+ assertEquals(999, options1.getNumCores());
+ if (options2.getNumCores() == 999)
+ throw new AssertionError("Num cores should not be part of serialization");
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/SerializationWrapper.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,38 @@
+/*
+ * 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 8035063
+ *
+ * @summary Tests serialization of options. The options needs to be serialized
+ * and saved in the state file since the files need to be recompiled
+ * if new options are provided.
+ *
+ * @run main SerializationWrapper
+ */
+public class SerializationWrapper {
+ public static void main(String... args) throws Exception {
+ SJavacTestUtil.runSjavacTest("Serialization", args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/sjavac/util/OptionTestUtil.java Tue Apr 22 16:51:10 2014 +0200
@@ -0,0 +1,79 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package util;
+
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import com.sun.tools.sjavac.options.SourceLocation;
+
+
+public class OptionTestUtil {
+
+ public static void checkFilesFound(Collection<String> found, Path... expected) {
+
+ Collection<String> expectedStrs = new HashSet<String>();
+ for (Path p : expected)
+ expectedStrs.add(p.toString());
+
+ if (!expectedStrs.containsAll(found))
+ throw new AssertionError("Expected (" + expectedStrs + ") does not " +
+ "contain all actual (" + found + ")");
+
+ if (!found.containsAll(expectedStrs))
+ throw new AssertionError("Actual (" + found + ") does not " +
+ "contain all expected (" + expectedStrs + ")");
+ }
+
+ public static void assertEquals(List<SourceLocation> expected, List<SourceLocation> actual) {
+ if (expected.size() != actual.size())
+ throw new AssertionError("Expected locs of length " + expected.size() + " but got something of size " + actual.size());
+
+ Iterator<SourceLocation> iter1 = expected.iterator();
+ Iterator<SourceLocation> iter2 = actual.iterator();
+
+ while (iter1.hasNext()) {
+ SourceLocation sl1 = iter1.next();
+ SourceLocation sl2 = iter2.next();
+
+ if (!sl1.getPath().equals(sl2.getPath()) ||
+ !sl1.getIncludes().equals(sl2.getIncludes()) ||
+ !sl1.getExcludes().equals(sl2.getExcludes()) ||
+ !sl1.getIncludedFiles().equals(sl2.getIncludedFiles()) ||
+ !sl1.getExcludedFiles().equals(sl2.getExcludedFiles()))
+ throw new AssertionError("Expected " + sl1 + " but got " + sl2);
+ }
+ }
+
+ public static void assertEquals(Object expected, Object actual) {
+ if (!expected.equals(actual))
+ throw new AssertionError("Expected " + expected + " but got " + actual);
+ }
+
+}