1.1 --- a/cmdline/tool/nbproject/project.properties Sun Sep 20 10:49:35 2015 +0200
1.2 +++ b/cmdline/tool/nbproject/project.properties Sun Oct 11 22:02:22 2015 +0200
1.3 @@ -1,4 +1,4 @@
1.4 -javac.source=1.6
1.5 +javac.source=1.7
1.6 javac.compilerargs=-Xlint -Xlint:-serial
1.7 cp.extra=../../lib/jopt-simple/jopt-simple-3.2.jar
1.8 spec.version.base=1.16.0
2.1 --- a/cmdline/tool/src/org/netbeans/modules/jackpot30/cmdline/Main.java Sun Sep 20 10:49:35 2015 +0200
2.2 +++ b/cmdline/tool/src/org/netbeans/modules/jackpot30/cmdline/Main.java Sun Oct 11 22:02:22 2015 +0200
2.3 @@ -65,6 +65,7 @@
2.4 import java.util.concurrent.atomic.AtomicBoolean;
2.5 import java.util.logging.Level;
2.6 import java.util.logging.Logger;
2.7 +import java.util.prefs.AbstractPreferences;
2.8 import java.util.prefs.BackingStoreException;
2.9 import java.util.prefs.Preferences;
2.10 import java.util.regex.Pattern;
2.11 @@ -82,7 +83,6 @@
2.12 import org.netbeans.api.java.classpath.GlobalPathRegistry;
2.13 import org.netbeans.api.java.source.CompilationController;
2.14 import org.netbeans.api.java.source.ModificationResult;
2.15 -import org.netbeans.api.project.ui.*;
2.16 import org.netbeans.core.startup.MainLookup;
2.17 import org.netbeans.modules.jackpot30.cmdline.lib.Utils;
2.18 import org.netbeans.modules.jackpot30.ui.settings.XMLHintPreferences;
2.19 @@ -117,7 +117,6 @@
2.20 import org.openide.filesystems.FileUtil;
2.21 import org.openide.util.Exceptions;
2.22 import org.openide.util.Lookup;
2.23 -import org.openide.util.NbPreferences;
2.24 import org.openide.util.RequestProcessor;
2.25 import org.openide.util.lookup.Lookups;
2.26 import org.openide.util.lookup.ProxyLookup;
2.27 @@ -144,16 +143,14 @@
2.28
2.29 OptionParser parser = new OptionParser();
2.30 // ArgumentAcceptingOptionSpec<File> projects = parser.accepts("project", "project(s) to refactor").withRequiredArg().withValuesSeparatedBy(File.pathSeparatorChar).ofType(File.class);
2.31 - ArgumentAcceptingOptionSpec<File> classpath = parser.accepts("classpath", "classpath").withRequiredArg().withValuesSeparatedBy(File.pathSeparatorChar).ofType(File.class);
2.32 - ArgumentAcceptingOptionSpec<File> bootclasspath = parser.accepts("bootclasspath", "bootclasspath").withRequiredArg().withValuesSeparatedBy(File.pathSeparatorChar).ofType(File.class);
2.33 - ArgumentAcceptingOptionSpec<File> sourcepath = parser.accepts("sourcepath", "sourcepath").withRequiredArg().withValuesSeparatedBy(File.pathSeparatorChar).ofType(File.class);
2.34 + GroupOptions globalGroupOptions = setupGroupParser(parser);
2.35 ArgumentAcceptingOptionSpec<File> cache = parser.accepts("cache", "a cache directory to store working data").withRequiredArg().ofType(File.class);
2.36 ArgumentAcceptingOptionSpec<File> out = parser.accepts("out", "output diff").withRequiredArg().ofType(File.class);
2.37 ArgumentAcceptingOptionSpec<File> configFile = parser.accepts("config-file", "configuration file").withRequiredArg().ofType(File.class);
2.38 ArgumentAcceptingOptionSpec<String> hint = parser.accepts("hint", "hint name").withRequiredArg().ofType(String.class);
2.39 ArgumentAcceptingOptionSpec<String> config = parser.accepts("config", "configurations").withRequiredArg().ofType(String.class);
2.40 - ArgumentAcceptingOptionSpec<String> source = parser.accepts("source", "source level").withRequiredArg().ofType(String.class).defaultsTo(SOURCE_LEVEL_DEFAULT);
2.41 ArgumentAcceptingOptionSpec<File> hintFile = parser.accepts("hint-file", "file with rules that should be performed").withRequiredArg().ofType(File.class);
2.42 + ArgumentAcceptingOptionSpec<String> group = parser.accepts("group", "specify roots to process alongside with their classpath").withRequiredArg().ofType(String.class);
2.43
2.44 parser.accepts("list", "list all known hints");
2.45 parser.accepts("progress", "show progress");
2.46 @@ -196,10 +193,7 @@
2.47 }
2.48 }
2.49
2.50 - ClassPath bootCP = createClassPath(parsed.has(bootclasspath) ? parsed.valuesOf(bootclasspath) : null, createDefaultBootClassPath());
2.51 - ClassPath compileCP = createClassPath(parsed.has(classpath) ? parsed.valuesOf(classpath) : null, ClassPath.EMPTY);
2.52 - final ClassPath sourceCP = createClassPath(parsed.has(sourcepath) ? parsed.valuesOf(sourcepath) : null, ClassPathSupport.createClassPath(roots.toArray(new FileObject[0])));
2.53 - final ClassPath binaryCP = ClassPathSupport.createProxyClassPath(bootCP, compileCP);
2.54 + final RootConfiguration globalRootConfiguration = new RootConfiguration(parsed, globalGroupOptions);
2.55
2.56 if (parsed.has("show-gui")) {
2.57 if (parsed.has(configFile)) {
2.58 @@ -208,7 +202,7 @@
2.59 SwingUtilities.invokeAndWait(new Runnable() {
2.60 @Override public void run() {
2.61 try {
2.62 - showGUICustomizer(settingsFile, binaryCP, sourceCP);
2.63 + showGUICustomizer(settingsFile, globalRootConfiguration.binaryCP, globalRootConfiguration.sourceCP);
2.64 } catch (IOException ex) {
2.65 Exceptions.printStackTrace(ex);
2.66 } catch (BackingStoreException ex) {
2.67 @@ -261,52 +255,36 @@
2.68 org.netbeans.api.project.ui.OpenProjects.getDefault().getOpenProjects();
2.69 RepositoryUpdater.getDefault().start(false);
2.70
2.71 - if (roots.isEmpty() && !parsed.has("list")) {
2.72 - System.err.println("no source roots to work on");
2.73 - return 1;
2.74 - }
2.75 -
2.76 - Iterable<? extends HintDescription> hints;
2.77 -
2.78 if (parsed.has("list")) {
2.79 - printHints(sourceCP, binaryCP);
2.80 + printHints(globalRootConfiguration.sourceCP, globalRootConfiguration.binaryCP);
2.81 return 0;
2.82 }
2.83
2.84 - Preferences settingsFromConfigFile;
2.85 + int totalGroups = parsed.valuesOf(group).size() + (!globalRootConfiguration.rootFolders.isEmpty() ? 1 : 0);
2.86 +
2.87 + ProgressHandleWrapper progress = parsed.has("progress") ? new ProgressHandleWrapper(new ConsoleProgressHandleAbstraction(), ProgressHandleWrapper.prepareParts(totalGroups)) : new ProgressHandleWrapper(1);
2.88 +
2.89 Preferences hintSettingsPreferences;
2.90 - HintsSettings hintSettings;
2.91 boolean apply;
2.92 + boolean runDeclarative;
2.93
2.94 if (parsed.has(configFile)) {
2.95 + Preferences settingsFromConfigFile;
2.96 settingsFromConfigFile = XMLHintPreferences.from(parsed.valueOf(configFile));
2.97 - hintSettings = HintsSettings.createPreferencesBasedHintsSettings(hintSettingsPreferences = settingsFromConfigFile.node("settings"), false, null);
2.98 + hintSettingsPreferences = settingsFromConfigFile.node("settings");
2.99 apply = settingsFromConfigFile.getBoolean("apply", false);
2.100 - } else {
2.101 - settingsFromConfigFile = null;
2.102 - hintSettings = HintsSettings.createPreferencesBasedHintsSettings(hintSettingsPreferences = NbPreferences.root().node("tempSettings"), false, null);
2.103 - apply = false;
2.104 - }
2.105 -
2.106 - if (parsed.has(hint)) {
2.107 - if (settingsFromConfigFile != null) {
2.108 + runDeclarative = settingsFromConfigFile.getBoolean("runDeclarative", true);
2.109 + if (parsed.has(hint)) {
2.110 System.err.println("cannot specify --hint and --config-file together");
2.111 return 1;
2.112 - }
2.113 - hints = findHints(sourceCP, binaryCP, parsed.valueOf(hint), hintSettings);
2.114 - } else if (parsed.has(hintFile)) {
2.115 - if (settingsFromConfigFile != null) {
2.116 + } else if (parsed.has(hintFile)) {
2.117 System.err.println("cannot specify --hint-file and --config-file together");
2.118 return 1;
2.119 }
2.120 - FileObject hintFileFO = FileUtil.toFileObject(parsed.valueOf(hintFile));
2.121 - assert hintFileFO != null;
2.122 - hints = PatternConvertor.create(hintFileFO.asText());
2.123 - for (HintDescription hd : hints) {
2.124 - hintSettings.setEnabled(hd.getMetadata(), true);
2.125 - }
2.126 } else {
2.127 - hints = readHints(sourceCP, binaryCP, hintSettings, hintSettingsPreferences, settingsFromConfigFile != null ? settingsFromConfigFile.getBoolean("runDeclarative", true) : true);
2.128 + hintSettingsPreferences = null;
2.129 + apply = false;
2.130 + runDeclarative = true;
2.131 }
2.132
2.133 if (parsed.has(config) && !parsed.has(hint)) {
2.134 @@ -314,88 +292,35 @@
2.135 return 1;
2.136 }
2.137
2.138 - if (parsed.has(config)) {
2.139 - Iterator<? extends HintDescription> hit = hints.iterator();
2.140 - HintDescription hd = hit.next();
2.141 -
2.142 - if (hit.hasNext()) {
2.143 - System.err.println("--config cannot specified when more than one hint is specified");
2.144 -
2.145 - return 1;
2.146 - }
2.147 -
2.148 - Preferences prefs = hintSettings.getHintPreferences(hd.getMetadata());
2.149 -
2.150 - boolean stop = false;
2.151 -
2.152 - for (String c : parsed.valuesOf(config)) {
2.153 - int assign = c.indexOf('=');
2.154 -
2.155 - if (assign == (-1)) {
2.156 - System.err.println("configuration option is missing '=' (" + c + ")");
2.157 - stop = true;
2.158 - continue;
2.159 - }
2.160 -
2.161 - prefs.put(c.substring(0, assign), c.substring(assign + 1));
2.162 - }
2.163 -
2.164 - if (stop) {
2.165 - return 1;
2.166 - }
2.167 - }
2.168 -
2.169 - String sourceLevel = parsed.valueOf(source);
2.170 -
2.171 - if (!Pattern.compile(ACCEPTABLE_SOURCE_LEVEL_PATTERN).matcher(sourceLevel).matches()) {
2.172 - System.err.println("unrecognized source level specification: " + sourceLevel);
2.173 - return 1;
2.174 - }
2.175 -
2.176 if (parsed.has(OPTION_NO_APPLY)) {
2.177 apply = false;
2.178 } else if (parsed.has(OPTION_APPLY)) {
2.179 apply = true;
2.180 }
2.181 -
2.182 - if (apply && !hints.iterator().hasNext()) {
2.183 - System.err.println("no hints specified");
2.184 +
2.185 + GroupResult result = GroupResult.NOTHING_TO_DO;
2.186 +
2.187 + try (Writer outS = parsed.has(out) ? new BufferedWriter(new OutputStreamWriter(new FileOutputStream(parsed.valueOf(out)))) : null) {
2.188 + GlobalConfiguration globalConfig = new GlobalConfiguration(hintSettingsPreferences, apply, runDeclarative, parsed.valueOf(hint), parsed.valueOf(hintFile), outS, parsed.has(OPTION_FAIL_ON_WARNINGS));
2.189 +
2.190 + result = result.join(handleGroup(parsed, globalGroupOptions, progress, globalConfig, parsed.valuesOf(config)));
2.191 +
2.192 + for (String groupValue : parsed.valuesOf(group)) {
2.193 + OptionParser groupParser = new OptionParser();
2.194 + GroupOptions groupOptions = setupGroupParser(groupParser);
2.195 + OptionSet parsedGroup = groupParser.parse(splitGroupArg(groupValue));
2.196 + result = result.join(handleGroup(parsedGroup, groupOptions, progress, globalConfig, parsed.valuesOf(config)));
2.197 + }
2.198 + }
2.199 +
2.200 + progress.finish();
2.201 +
2.202 + if (result == GroupResult.NOTHING_TO_DO) {
2.203 + System.err.println("no source roots to work on");
2.204 return 1;
2.205 }
2.206
2.207 - Object[] register2Lookup = new Object[] {
2.208 - new ClassPathProviderImpl(bootCP, compileCP, sourceCP),
2.209 - new JavaPathRecognizer(),
2.210 - new SourceLevelQueryImpl(sourceCP, sourceLevel)
2.211 - };
2.212 -
2.213 - try {
2.214 - for (Object toRegister : register2Lookup) {
2.215 - MainLookup.register(toRegister);
2.216 - }
2.217 -
2.218 - ProgressHandleWrapper progress = parsed.has("progress") ? new ProgressHandleWrapper(new ConsoleProgressHandleAbstraction(), 1) : new ProgressHandleWrapper(1);
2.219 -
2.220 - if (apply) {
2.221 - apply(hints, rootFolders.toArray(new Folder[0]), progress, hintSettings, parsed.valueOf(out));
2.222 -
2.223 - return 0;
2.224 - } else {
2.225 - WarningsAndErrors wae = new WarningsAndErrors();
2.226 -
2.227 - findOccurrences(hints, rootFolders.toArray(new Folder[0]), progress, hintSettings, wae);
2.228 -
2.229 - if (wae.errors != 0 || (wae.warnings != 0 && parsed.has(OPTION_FAIL_ON_WARNINGS))) {
2.230 - return 1;
2.231 - } else {
2.232 - return 0;
2.233 - }
2.234 - }
2.235 - } finally {
2.236 - for (Object toUnRegister : register2Lookup) {
2.237 - MainLookup.unregister(toUnRegister);
2.238 - }
2.239 - }
2.240 + return result == GroupResult.SUCCESS ? 0 : 1;
2.241 } catch (Throwable e) {
2.242 e.printStackTrace();
2.243 throw new IllegalStateException(e);
2.244 @@ -411,6 +336,28 @@
2.245 }
2.246 }
2.247
2.248 + private static GroupOptions setupGroupParser(OptionParser parser) {
2.249 + return new GroupOptions(parser.accepts("classpath", "classpath").withRequiredArg().withValuesSeparatedBy(File.pathSeparatorChar).ofType(File.class),
2.250 + parser.accepts("bootclasspath", "bootclasspath").withRequiredArg().withValuesSeparatedBy(File.pathSeparatorChar).ofType(File.class),
2.251 + parser.accepts("sourcepath", "sourcepath").withRequiredArg().withValuesSeparatedBy(File.pathSeparatorChar).ofType(File.class),
2.252 + parser.accepts("source", "source level").withRequiredArg().ofType(String.class).defaultsTo(SOURCE_LEVEL_DEFAULT));
2.253 + }
2.254 +
2.255 + private static final class GroupOptions {
2.256 + private final ArgumentAcceptingOptionSpec<File> classpath;
2.257 + private final ArgumentAcceptingOptionSpec<File> bootclasspath;
2.258 + private final ArgumentAcceptingOptionSpec<File> sourcepath;
2.259 + private final ArgumentAcceptingOptionSpec<String> source;
2.260 +
2.261 + public GroupOptions(ArgumentAcceptingOptionSpec<File> classpath, ArgumentAcceptingOptionSpec<File> bootclasspath, ArgumentAcceptingOptionSpec<File> sourcepath, ArgumentAcceptingOptionSpec<String> source) {
2.262 + this.classpath = classpath;
2.263 + this.bootclasspath = bootclasspath;
2.264 + this.sourcepath = sourcepath;
2.265 + this.source = source;
2.266 + }
2.267 +
2.268 + }
2.269 +
2.270 private static Map<HintMetadata, Collection<? extends HintDescription>> listHints(ClassPath sourceFrom, ClassPath binaryFrom) {
2.271 Map<HintMetadata, Collection<? extends HintDescription>> result = new HashMap<HintMetadata, Collection<? extends HintDescription>>();
2.272
2.273 @@ -420,6 +367,194 @@
2.274
2.275 return result;
2.276 }
2.277 +
2.278 + private static GroupResult handleGroup(OptionSet parsed, GroupOptions groupOptions, ProgressHandleWrapper w, GlobalConfiguration globalConfig, List<String> config) throws IOException {
2.279 + ProgressHandleWrapper progress = w.startNextPartWithEmbedding(1);
2.280 + Iterable<? extends HintDescription> hints;
2.281 +
2.282 + RootConfiguration rootConfiguration = new RootConfiguration(parsed, groupOptions);
2.283 +
2.284 + if (rootConfiguration.rootFolders.isEmpty()) {
2.285 + return GroupResult.NOTHING_TO_DO;
2.286 + }
2.287 +
2.288 + Preferences settings = globalConfig.configurationPreferences != null ? globalConfig.configurationPreferences : new MemoryPreferences();
2.289 + HintsSettings hintSettings = HintsSettings.createPreferencesBasedHintsSettings(settings, false, null);
2.290 +
2.291 + if (globalConfig.hint != null) {
2.292 + hints = findHints(rootConfiguration.sourceCP, rootConfiguration.binaryCP, globalConfig.hint, hintSettings);
2.293 + } else if (globalConfig.hintFile != null) {
2.294 + FileObject hintFileFO = FileUtil.toFileObject(globalConfig.hintFile);
2.295 + assert hintFileFO != null;
2.296 + hints = PatternConvertor.create(hintFileFO.asText());
2.297 + for (HintDescription hd : hints) {
2.298 + hintSettings.setEnabled(hd.getMetadata(), true);
2.299 + }
2.300 + } else {
2.301 + hints = readHints(rootConfiguration.sourceCP, rootConfiguration.binaryCP, hintSettings, settings, globalConfig.runDeclarative);
2.302 + }
2.303 +
2.304 + if (config != null && !config.isEmpty()) {
2.305 + Iterator<? extends HintDescription> hit = hints.iterator();
2.306 + HintDescription hd = hit.next();
2.307 +
2.308 + if (hit.hasNext()) {
2.309 + System.err.println("--config cannot specified when more than one hint is specified");
2.310 +
2.311 + return GroupResult.FAILURE;
2.312 + }
2.313 +
2.314 + Preferences prefs = hintSettings.getHintPreferences(hd.getMetadata());
2.315 +
2.316 + boolean stop = false;
2.317 +
2.318 + for (String c : config) {
2.319 + int assign = c.indexOf('=');
2.320 +
2.321 + if (assign == (-1)) {
2.322 + System.err.println("configuration option is missing '=' (" + c + ")");
2.323 + stop = true;
2.324 + continue;
2.325 + }
2.326 +
2.327 + prefs.put(c.substring(0, assign), c.substring(assign + 1));
2.328 + }
2.329 +
2.330 + if (stop) {
2.331 + return GroupResult.FAILURE;
2.332 + }
2.333 + }
2.334 +
2.335 + String sourceLevel = parsed.valueOf(groupOptions.source);
2.336 +
2.337 + if (!Pattern.compile(ACCEPTABLE_SOURCE_LEVEL_PATTERN).matcher(sourceLevel).matches()) {
2.338 + System.err.println("unrecognized source level specification: " + sourceLevel);
2.339 + return GroupResult.FAILURE;
2.340 + }
2.341 +
2.342 + if (globalConfig.apply && !hints.iterator().hasNext()) {
2.343 + System.err.println("no hints specified");
2.344 + return GroupResult.FAILURE;
2.345 + }
2.346 +
2.347 + Object[] register2Lookup = new Object[] {
2.348 + new ClassPathProviderImpl(rootConfiguration.bootCP, rootConfiguration.compileCP, rootConfiguration.sourceCP),
2.349 + new JavaPathRecognizer(),
2.350 + new SourceLevelQueryImpl(rootConfiguration.sourceCP, sourceLevel)
2.351 + };
2.352 +
2.353 + try {
2.354 + for (Object toRegister : register2Lookup) {
2.355 + MainLookup.register(toRegister);
2.356 + }
2.357 +
2.358 + if (globalConfig.apply) {
2.359 + apply(hints, rootConfiguration.rootFolders.toArray(new Folder[0]), progress, hintSettings, globalConfig.out);
2.360 +
2.361 + return GroupResult.SUCCESS;
2.362 + } else {
2.363 + WarningsAndErrors wae = new WarningsAndErrors();
2.364 +
2.365 + findOccurrences(hints, rootConfiguration.rootFolders.toArray(new Folder[0]), progress, hintSettings, wae);
2.366 +
2.367 + if (wae.errors != 0 || (wae.warnings != 0 && globalConfig.failOnWarnings)) {
2.368 + return GroupResult.FAILURE;
2.369 + } else {
2.370 + return GroupResult.SUCCESS;
2.371 + }
2.372 + }
2.373 + } finally {
2.374 + for (Object toUnRegister : register2Lookup) {
2.375 + MainLookup.unregister(toUnRegister);
2.376 + }
2.377 + }
2.378 + }
2.379 +
2.380 + private static class MemoryPreferences extends AbstractPreferences {
2.381 +
2.382 + private final Map<String, String> values = new HashMap<>();
2.383 + private final Map<String, MemoryPreferences> nodes = new HashMap<>();
2.384 +
2.385 + public MemoryPreferences() {
2.386 + this(null, "");
2.387 + }
2.388 +
2.389 + public MemoryPreferences(MemoryPreferences parent, String name) {
2.390 + super(parent, name);
2.391 + }
2.392 + @Override
2.393 + protected void putSpi(String key, String value) {
2.394 + values.put(key, value);
2.395 + }
2.396 +
2.397 + @Override
2.398 + protected String getSpi(String key) {
2.399 + return values.get(key);
2.400 + }
2.401 +
2.402 + @Override
2.403 + protected void removeSpi(String key) {
2.404 + values.remove(key);
2.405 + }
2.406 +
2.407 + @Override
2.408 + protected void removeNodeSpi() throws BackingStoreException {
2.409 + ((MemoryPreferences) parent()).nodes.remove(name());
2.410 + }
2.411 +
2.412 + @Override
2.413 + protected String[] keysSpi() throws BackingStoreException {
2.414 + return values.keySet().toArray(new String[0]);
2.415 + }
2.416 +
2.417 + @Override
2.418 + protected String[] childrenNamesSpi() throws BackingStoreException {
2.419 + return nodes.keySet().toArray(new String[0]);
2.420 + }
2.421 +
2.422 + @Override
2.423 + protected AbstractPreferences childSpi(String name) {
2.424 + MemoryPreferences result = nodes.get(name);
2.425 +
2.426 + if (result == null) {
2.427 + nodes.put(name, result = new MemoryPreferences(this, name));
2.428 + }
2.429 +
2.430 + return result;
2.431 + }
2.432 +
2.433 + @Override
2.434 + protected void syncSpi() throws BackingStoreException {
2.435 + }
2.436 +
2.437 + @Override
2.438 + protected void flushSpi() throws BackingStoreException {
2.439 + }
2.440 + }
2.441 +
2.442 + private enum GroupResult {
2.443 + NOTHING_TO_DO {
2.444 + @Override
2.445 + public GroupResult join(GroupResult other) {
2.446 + return other;
2.447 + }
2.448 + },
2.449 + SUCCESS {
2.450 + @Override
2.451 + public GroupResult join(GroupResult other) {
2.452 + if (other == FAILURE) return other;
2.453 + return this;
2.454 + }
2.455 + },
2.456 + FAILURE {
2.457 + @Override
2.458 + public GroupResult join(GroupResult other) {
2.459 + return this;
2.460 + }
2.461 + };
2.462 +
2.463 + public abstract GroupResult join(GroupResult other);
2.464 + }
2.465
2.466 private static Iterable<? extends HintDescription> findHints(ClassPath sourceFrom, ClassPath binaryFrom, String name, HintsSettings toEnableIn) {
2.467 List<HintDescription> descs = new LinkedList<HintDescription>();
2.468 @@ -480,7 +615,7 @@
2.469 BatchResult occurrences = BatchSearch.findOccurrences(descs, Scopes.specifiedFoldersScope(sourceRoot), w, settings);
2.470
2.471 List<MessageImpl> problems = new LinkedList<MessageImpl>();
2.472 - BatchSearch.getVerifiedSpans(occurrences, progress, new VerifiedSpansCallBack() {
2.473 + BatchSearch.getVerifiedSpans(occurrences, w, new VerifiedSpansCallBack() {
2.474 @Override public void groupStarted() {}
2.475 @Override public boolean spansVerified(CompilationController wc, Resource r, Collection<? extends ErrorDescription> hints) throws Exception {
2.476 for (ErrorDescription ed : hints) {
2.477 @@ -525,7 +660,7 @@
2.478 System.out.println(b);
2.479 }
2.480
2.481 - private static void apply(Iterable<? extends HintDescription> descs, Folder[] sourceRoot, ProgressHandleWrapper progress, HintsSettings settings, File out) throws IOException {
2.482 + private static void apply(Iterable<? extends HintDescription> descs, Folder[] sourceRoot, ProgressHandleWrapper progress, HintsSettings settings, Writer out) throws IOException {
2.483 ProgressHandleWrapper w = progress.startNextPartWithEmbedding(1, 1);
2.484 BatchResult occurrences = BatchSearch.findOccurrences(descs, Scopes.specifiedFoldersScope(sourceRoot), w, settings);
2.485
2.486 @@ -533,20 +668,8 @@
2.487 Collection<ModificationResult> diffs = BatchUtilities.applyFixes(occurrences, w, new AtomicBoolean(), problems);
2.488
2.489 if (out != null) {
2.490 - Writer outS = null;
2.491 -
2.492 - try {
2.493 - outS = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(out)));
2.494 -
2.495 - for (ModificationResult mr : diffs) {
2.496 - org.netbeans.modules.jackpot30.indexing.batch.BatchUtilities.exportDiff(mr, null, outS);
2.497 - }
2.498 - } finally {
2.499 - try {
2.500 - outS.close();
2.501 - } catch (IOException ex) {
2.502 - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
2.503 - }
2.504 + for (ModificationResult mr : diffs) {
2.505 + org.netbeans.modules.jackpot30.indexing.batch.BatchUtilities.exportDiff(mr, null, out);
2.506 }
2.507 } else {
2.508 for (ModificationResult mr : diffs) {
2.509 @@ -642,11 +765,92 @@
2.510 }
2.511 }
2.512
2.513 + static String[] splitGroupArg(String arg) {
2.514 + List<String> result = new ArrayList<>();
2.515 + StringBuilder currentPart = new StringBuilder();
2.516 +
2.517 + for (int i = 0; i < arg.length(); i++) {
2.518 + switch (arg.charAt(i)) {
2.519 + case '\\':
2.520 + if (++i < arg.length()) {
2.521 + currentPart.append(arg.charAt(i));
2.522 + }
2.523 + break;
2.524 + case ' ':
2.525 + if (currentPart.length() > 0) {
2.526 + result.add(currentPart.toString());
2.527 + currentPart.delete(0, currentPart.length());
2.528 + }
2.529 + break;
2.530 + default:
2.531 + currentPart.append(arg.charAt(i));
2.532 + break;
2.533 + }
2.534 + }
2.535 +
2.536 + if (currentPart.length() > 0) {
2.537 + result.add(currentPart.toString());
2.538 + }
2.539 +
2.540 + return result.toArray(new String[0]);
2.541 + }
2.542 +
2.543 private static final class WarningsAndErrors {
2.544 private int warnings;
2.545 private int errors;
2.546 }
2.547
2.548 + private static final class RootConfiguration {
2.549 + private final List<Folder> rootFolders;
2.550 + private final ClassPath bootCP;
2.551 + private final ClassPath compileCP;
2.552 + private final ClassPath sourceCP;
2.553 + private final ClassPath binaryCP;
2.554 +
2.555 + public RootConfiguration(OptionSet parsed, GroupOptions groupOptions) throws IOException {
2.556 + this.rootFolders = new ArrayList<>();
2.557 +
2.558 + List<FileObject> roots = new ArrayList<>();
2.559 +
2.560 + for (String sr : parsed.nonOptionArguments()) {
2.561 + File r = new File(sr);
2.562 + FileObject root = FileUtil.toFileObject(r);
2.563 +
2.564 + if (root != null) {
2.565 + roots.add(root);
2.566 + rootFolders.add(new Folder(root));
2.567 + }
2.568 + }
2.569 +
2.570 + this.bootCP = createClassPath(parsed.has(groupOptions.bootclasspath) ? parsed.valuesOf(groupOptions.bootclasspath) : null, createDefaultBootClassPath());
2.571 + this.compileCP = createClassPath(parsed.has(groupOptions.classpath) ? parsed.valuesOf(groupOptions.classpath) : null, ClassPath.EMPTY);
2.572 + this.sourceCP = createClassPath(parsed.has(groupOptions.sourcepath) ? parsed.valuesOf(groupOptions.sourcepath) : null, ClassPathSupport.createClassPath(roots.toArray(new FileObject[0])));
2.573 + this.binaryCP = ClassPathSupport.createProxyClassPath(bootCP, compileCP);
2.574 + }
2.575 +
2.576 + }
2.577 +
2.578 + private static final class GlobalConfiguration {
2.579 + private final Preferences configurationPreferences;
2.580 + private final boolean apply;
2.581 + private final boolean runDeclarative;
2.582 + private final String hint;
2.583 + private final File hintFile;
2.584 + private final Writer out;
2.585 + private final boolean failOnWarnings;
2.586 +
2.587 + public GlobalConfiguration(Preferences configurationPreferences, boolean apply, boolean runDeclarative, String hint, File hintFile, Writer out, boolean failOnWarnings) {
2.588 + this.configurationPreferences = configurationPreferences;
2.589 + this.apply = apply;
2.590 + this.runDeclarative = runDeclarative;
2.591 + this.hint = hint;
2.592 + this.hintFile = hintFile;
2.593 + this.out = out;
2.594 + this.failOnWarnings = failOnWarnings;
2.595 + }
2.596 +
2.597 + }
2.598 +
2.599 @ServiceProvider(service=Lookup.class)
2.600 public static final class LookupProviderImpl extends ProxyLookup {
2.601
3.1 --- a/cmdline/tool/test/unit/src/org/netbeans/modules/jackpot30/cmdline/MainTest.java Sun Sep 20 10:49:35 2015 +0200
3.2 +++ b/cmdline/tool/test/unit/src/org/netbeans/modules/jackpot30/cmdline/MainTest.java Sun Oct 11 22:02:22 2015 +0200
3.3 @@ -427,6 +427,48 @@
3.4 "--fail-on-warnings");
3.5 }
3.6
3.7 + public void testGroups() throws Exception {
3.8 + doRunCompiler(null,
3.9 + "${workdir}/src1/test/Test.java:4: warning: [test] test\n" +
3.10 + " boolean b1 = c.size() == 0;\n" +
3.11 + " ^\n" +
3.12 + "${workdir}/src2/test/Test.java:5: warning: [test] test\n" +
3.13 + " boolean b2 = c.size() != 0;\n" +
3.14 + " ^\n",
3.15 + null,
3.16 + "cp1/META-INF/upgrade/test.hint",
3.17 + "$coll.size() == 0 :: $coll instanceof java.util.Collection;;",
3.18 + "src1/test/Test.java",
3.19 + "package test;\n" +
3.20 + "public class Test {\n" +
3.21 + " private void test(java.util.Collection c) {\n" +
3.22 + " boolean b1 = c.size() == 0;\n" +
3.23 + " boolean b2 = c.size() != 0;\n" +
3.24 + " }\n" +
3.25 + "}\n",
3.26 + "cp2/META-INF/upgrade/test.hint",
3.27 + "$coll.size() != 0 :: $coll instanceof java.util.Collection;;",
3.28 + "src2/test/Test.java",
3.29 + "package test;\n" +
3.30 + "public class Test {\n" +
3.31 + " private void test(java.util.Collection c) {\n" +
3.32 + " boolean b1 = c.size() == 0;\n" +
3.33 + " boolean b2 = c.size() != 0;\n" +
3.34 + " }\n" +
3.35 + "}\n",
3.36 + null,
3.37 + DONT_APPEND_PATH,
3.38 + "--group",
3.39 + "--classpath ${workdir}/cp1 ${workdir}/src1",
3.40 + "--group",
3.41 + "--classpath ${workdir}/cp2 ${workdir}/src2");
3.42 + }
3.43 +
3.44 + public void testGroupsParamEscape() throws Exception {
3.45 + assertEquals(Arrays.asList("a b", "a\\b"),
3.46 + Arrays.asList(Main.splitGroupArg("a\\ b a\\\\b")));
3.47 + }
3.48 +
3.49 private static final String DONT_APPEND_PATH = new String("DONT_APPEND_PATH");
3.50
3.51 private void doRunCompiler(String golden, String stdOut, String stdErr, String... fileContentAndExtraOptions) throws Exception {
3.52 @@ -482,7 +524,9 @@
3.53
3.54 reallyRunCompiler(wd, exitcode, output, options.toArray(new String[0]));
3.55
3.56 - assertEquals(golden, TestUtilities.copyFileToString(source));
3.57 + if (golden != null) {
3.58 + assertEquals(golden, TestUtilities.copyFileToString(source));
3.59 + }
3.60
3.61 if (stdOut != null) {
3.62 assertEquals(stdOut, output[0].replaceAll(Pattern.quote(wd.getAbsolutePath()), Matcher.quoteReplacement("${workdir}")));