From 222a970080f99fbefc45e2c707bdbf112339a976 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 5 Jul 2016 13:35:18 +0100 Subject: [PATCH 1/8] Kill some vars --- .../src/main/scala/sbt/compiler/Eval.scala | 13 +++++------ .../scala/sbt/TrapExitSecurityException.scala | 23 +++++-------------- .../main/scala/sbt/test/ScriptedTests.scala | 1 - tasks/src/main/scala/sbt/Incomplete.scala | 8 ++++--- 4 files changed, 17 insertions(+), 28 deletions(-) diff --git a/main-actions/src/main/scala/sbt/compiler/Eval.scala b/main-actions/src/main/scala/sbt/compiler/Eval.scala index a54d0807b..025dc2810 100644 --- a/main-actions/src/main/scala/sbt/compiler/Eval.scala +++ b/main-actions/src/main/scala/sbt/compiler/Eval.scala @@ -1,6 +1,7 @@ package sbt package compiler +import scala.collection.mutable.ListBuffer import scala.reflect.Manifest import scala.tools.nsc.{ ast, interpreter, io, reporters, util, CompilerCommand, Global, Phase, Settings } import io.{ AbstractFile, PlainFile, VirtualDirectory } @@ -337,14 +338,12 @@ final class Eval(optionsNoncp: Seq[String], classpath: Seq[File], mkReporter: Se /** Parses one or more definitions (defs, vals, lazy vals, classes, traits, modules). */ private[this] def parseDefinitions(parser: syntaxAnalyzer.UnitParser): Seq[Tree] = { - var defs = parser.nonLocalDefOrDcl - parser.acceptStatSepOpt() - while (!parser.isStatSeqEnd) { - val next = parser.nonLocalDefOrDcl - defs ++= next + val defs = ListBuffer[Tree]() + do { + defs ++= parser.nonLocalDefOrDcl parser.acceptStatSepOpt() - } - defs + } while (!parser.isStatSeqEnd) + defs.toList } private[this] trait EvalType[T] { diff --git a/run/src/main/scala/sbt/TrapExitSecurityException.scala b/run/src/main/scala/sbt/TrapExitSecurityException.scala index 50bdab303..dc5792e66 100644 --- a/run/src/main/scala/sbt/TrapExitSecurityException.scala +++ b/run/src/main/scala/sbt/TrapExitSecurityException.scala @@ -6,21 +6,10 @@ package sbt * terminating the thread's execution. */ private final class TrapExitSecurityException(val exitCode: Int) extends SecurityException { - private var accessAllowed = false - def allowAccess(): Unit = { - accessAllowed = true - } - override def printStackTrace = ifAccessAllowed(super.printStackTrace) - override def toString = ifAccessAllowed(super.toString) - override def getCause = ifAccessAllowed(super.getCause) - override def getMessage = ifAccessAllowed(super.getMessage) - override def fillInStackTrace = ifAccessAllowed(super.fillInStackTrace) - override def getLocalizedMessage = ifAccessAllowed(super.getLocalizedMessage) - private def ifAccessAllowed[T](f: => T): T = - { - if (accessAllowed) - f - else - throw this - } + override def printStackTrace = throw this + override def toString = throw this + override def getCause = throw this + override def getMessage = throw this + override def fillInStackTrace = throw this + override def getLocalizedMessage = throw this } diff --git a/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala b/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala index 0778f9ba7..f341a4925 100644 --- a/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala +++ b/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala @@ -31,7 +31,6 @@ final class ScriptedTests(resourceBaseDirectory: File, bufferLog: Boolean, launc def scriptedTest(group: String, name: String, prescripted: File => Unit, log: Logger): Seq[() => Option[String]] = { import sbt.io.syntax._ import GlobFilter._ - var failed = false for (groupDir <- (resourceBaseDirectory * group).get; nme <- (groupDir * name).get) yield { val g = groupDir.getName val n = nme.getName diff --git a/tasks/src/main/scala/sbt/Incomplete.scala b/tasks/src/main/scala/sbt/Incomplete.scala index 5f40193de..a83e33e36 100644 --- a/tasks/src/main/scala/sbt/Incomplete.scala +++ b/tasks/src/main/scala/sbt/Incomplete.scala @@ -3,6 +3,8 @@ */ package sbt +import scala.collection.mutable.ListBuffer + import sbt.internal.util.IDSet import Incomplete.{ Error, Value => IValue } @@ -47,9 +49,9 @@ object Incomplete extends Enumeration { } def linearize(i: Incomplete): Seq[Incomplete] = { - var ordered = List[Incomplete]() - visitAll(i) { ordered ::= _ } - ordered + val ordered = ListBuffer[Incomplete]() + visitAll(i) { ordered += _ } + ordered.toList } def allExceptions(is: Seq[Incomplete]): Iterable[Throwable] = allExceptions(new Incomplete(None, causes = is)) From d77e7696352faf0618335282bacdcc6ea42541e2 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 6 Jul 2016 13:33:55 +0100 Subject: [PATCH 2/8] Cleanup testAgentProj --- .../src/main/java/sbt/ForkConfiguration.java | 6 +- testing/agent/src/main/java/sbt/ForkMain.java | 164 +++++++++--------- testing/agent/src/main/java/sbt/ForkTags.java | 1 - .../src/main/java/sbt/FrameworkWrapper.java | 124 ++++++------- 4 files changed, 147 insertions(+), 148 deletions(-) mode change 100755 => 100644 testing/agent/src/main/java/sbt/ForkMain.java diff --git a/testing/agent/src/main/java/sbt/ForkConfiguration.java b/testing/agent/src/main/java/sbt/ForkConfiguration.java index 397d1aaa9..9f51e9c69 100644 --- a/testing/agent/src/main/java/sbt/ForkConfiguration.java +++ b/testing/agent/src/main/java/sbt/ForkConfiguration.java @@ -3,10 +3,10 @@ package sbt; import java.io.Serializable; public final class ForkConfiguration implements Serializable { - private boolean ansiCodesSupported; - private boolean parallel; + private final boolean ansiCodesSupported; + private final boolean parallel; - public ForkConfiguration(boolean ansiCodesSupported, boolean parallel) { + public ForkConfiguration(final boolean ansiCodesSupported, final boolean parallel) { this.ansiCodesSupported = ansiCodesSupported; this.parallel = parallel; } diff --git a/testing/agent/src/main/java/sbt/ForkMain.java b/testing/agent/src/main/java/sbt/ForkMain.java old mode 100755 new mode 100644 index 142bc6aa1..b7871ecde --- a/testing/agent/src/main/java/sbt/ForkMain.java +++ b/testing/agent/src/main/java/sbt/ForkMain.java @@ -16,16 +16,16 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.*; -public class ForkMain { +final public class ForkMain { // serializables // ----------------------------------------------------------------------------- - static class SubclassFingerscan implements SubclassFingerprint, Serializable { - private boolean isModule; - private String superclassName; - private boolean requireNoArgConstructor; - SubclassFingerscan(SubclassFingerprint print) { + final static class SubclassFingerscan implements SubclassFingerprint, Serializable { + private final boolean isModule; + private final String superclassName; + private final boolean requireNoArgConstructor; + SubclassFingerscan(final SubclassFingerprint print) { isModule = print.isModule(); superclassName = print.superclassName(); requireNoArgConstructor = print.requireNoArgConstructor(); @@ -35,10 +35,10 @@ public class ForkMain { public boolean requireNoArgConstructor() { return requireNoArgConstructor; } } - static class AnnotatedFingerscan implements AnnotatedFingerprint, Serializable { - private boolean isModule; - private String annotationName; - AnnotatedFingerscan(AnnotatedFingerprint print) { + final static class AnnotatedFingerscan implements AnnotatedFingerprint, Serializable { + private final boolean isModule; + private final String annotationName; + AnnotatedFingerscan(final AnnotatedFingerprint print) { isModule = print.isModule(); annotationName = print.annotationName(); } @@ -46,34 +46,34 @@ public class ForkMain { public String annotationName() { return annotationName; } } - static class ForkEvent implements Event, Serializable { - private String fullyQualifiedName; - private Fingerprint fingerprint; - private Selector selector; - private Status status; - private OptionalThrowable throwable; - private long duration; + final static class ForkEvent implements Event, Serializable { + private final String fullyQualifiedName; + private final Fingerprint fingerprint; + private final Selector selector; + private final Status status; + private final OptionalThrowable throwable; + private final long duration; - ForkEvent(Event e) { + ForkEvent(final Event e) { fullyQualifiedName = e.fullyQualifiedName(); - Fingerprint rawFingerprint = e.fingerprint(); + final Fingerprint rawFingerprint = e.fingerprint(); if (rawFingerprint instanceof SubclassFingerprint) - this.fingerprint = new SubclassFingerscan((SubclassFingerprint) rawFingerprint); + fingerprint = new SubclassFingerscan((SubclassFingerprint) rawFingerprint); else - this.fingerprint = new AnnotatedFingerscan((AnnotatedFingerprint) rawFingerprint); + fingerprint = new AnnotatedFingerscan((AnnotatedFingerprint) rawFingerprint); selector = e.selector(); checkSerializableSelector(selector); status = e.status(); - OptionalThrowable originalThrowable = e.throwable(); + final OptionalThrowable originalThrowable = e.throwable(); if (originalThrowable.isDefined()) - this.throwable = new OptionalThrowable(new ForkError(originalThrowable.get())); + throwable = new OptionalThrowable(new ForkError(originalThrowable.get())); else - this.throwable = originalThrowable; + throwable = originalThrowable; - this.duration = e.duration(); + duration = e.duration(); } public String fullyQualifiedName() { return fullyQualifiedName; } @@ -83,7 +83,7 @@ public class ForkMain { public OptionalThrowable throwable() { return throwable; } public long duration() { return duration; } - static void checkSerializableSelector(Selector selector) { + private static void checkSerializableSelector(final Selector selector) { if (! (selector instanceof Serializable)) { throw new UnsupportedOperationException("Selector implementation must be Serializable, but " + selector.getClass().getName() + " is not."); } @@ -93,11 +93,11 @@ public class ForkMain { // ----------------------------------------------------------------------------- - static class ForkError extends Exception { - private String originalMessage; - private String originalName; + final static class ForkError extends Exception { + private final String originalMessage; + private final String originalName; private ForkError cause; - ForkError(Throwable t) { + ForkError(final Throwable t) { originalMessage = t.getMessage(); originalName = t.getClass().getName(); setStackTrace(t.getStackTrace()); @@ -111,8 +111,8 @@ public class ForkMain { // main // ---------------------------------------------------------------------------------------------------------------- - public static void main(String[] args) throws Exception { - Socket socket = new Socket(InetAddress.getByName(null), Integer.valueOf(args[0])); + public static void main(final String[] args) throws Exception { + final Socket socket = new Socket(InetAddress.getByName(null), Integer.valueOf(args[0])); final ObjectInputStream is = new ObjectInputStream(socket.getInputStream()); final ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream()); // Must flush the header that the constructor writes, otherwise the ObjectInputStream on the other end may block indefinitely @@ -132,76 +132,76 @@ public class ForkMain { // ---------------------------------------------------------------------------------------------------------------- - private static class Run { + final private static class Run { - void run(ObjectInputStream is, ObjectOutputStream os) { + private void run(final ObjectInputStream is, final ObjectOutputStream os) { try { runTests(is, os); - } catch (RunAborted e) { + } catch (final RunAborted e) { internalError(e); - } catch (Throwable t) { + } catch (final Throwable t) { try { logError(os, "Uncaught exception when running tests: " + t.toString()); write(os, new ForkError(t)); - } catch (Throwable t2) { + } catch (final Throwable t2) { internalError(t2); } } } - boolean matches(Fingerprint f1, Fingerprint f2) { + private boolean matches(final Fingerprint f1, final Fingerprint f2) { if (f1 instanceof SubclassFingerprint && f2 instanceof SubclassFingerprint) { final SubclassFingerprint sf1 = (SubclassFingerprint) f1; final SubclassFingerprint sf2 = (SubclassFingerprint) f2; return sf1.isModule() == sf2.isModule() && sf1.superclassName().equals(sf2.superclassName()); } else if (f1 instanceof AnnotatedFingerprint && f2 instanceof AnnotatedFingerprint) { - AnnotatedFingerprint af1 = (AnnotatedFingerprint) f1; - AnnotatedFingerprint af2 = (AnnotatedFingerprint) f2; + final AnnotatedFingerprint af1 = (AnnotatedFingerprint) f1; + final AnnotatedFingerprint af2 = (AnnotatedFingerprint) f2; return af1.isModule() == af2.isModule() && af1.annotationName().equals(af2.annotationName()); } return false; } class RunAborted extends RuntimeException { - RunAborted(Exception e) { super(e); } + RunAborted(final Exception e) { super(e); } } - synchronized void write(ObjectOutputStream os, Object obj) { + private synchronized void write(final ObjectOutputStream os, final Object obj) { try { os.writeObject(obj); os.flush(); - } catch (IOException e) { + } catch (final IOException e) { throw new RunAborted(e); } } - void log(ObjectOutputStream os, String message, ForkTags level) { + private void log(final ObjectOutputStream os, final String message, final ForkTags level) { write(os, new Object[]{level, message}); } - void logDebug(ObjectOutputStream os, String message) { log(os, message, ForkTags.Debug); } - void logInfo(ObjectOutputStream os, String message) { log(os, message, ForkTags.Info); } - void logWarn(ObjectOutputStream os, String message) { log(os, message, ForkTags.Warn); } - void logError(ObjectOutputStream os, String message) { log(os, message, ForkTags.Error); } + private void logDebug(final ObjectOutputStream os, final String message) { log(os, message, ForkTags.Debug); } + private void logInfo(final ObjectOutputStream os, final String message) { log(os, message, ForkTags.Info); } + private void logWarn(final ObjectOutputStream os, final String message) { log(os, message, ForkTags.Warn); } + private void logError(final ObjectOutputStream os, final String message) { log(os, message, ForkTags.Error); } - Logger remoteLogger(final boolean ansiCodesSupported, final ObjectOutputStream os) { + private Logger remoteLogger(final boolean ansiCodesSupported, final ObjectOutputStream os) { return new Logger() { public boolean ansiCodesSupported() { return ansiCodesSupported; } - public void error(String s) { logError(os, s); } - public void warn(String s) { logWarn(os, s); } - public void info(String s) { logInfo(os, s); } - public void debug(String s) { logDebug(os, s); } - public void trace(Throwable t) { write(os, new ForkError(t)); } + public void error(final String s) { logError(os, s); } + public void warn(final String s) { logWarn(os, s); } + public void info(final String s) { logInfo(os, s); } + public void debug(final String s) { logDebug(os, s); } + public void trace(final Throwable t) { write(os, new ForkError(t)); } }; } - void writeEvents(ObjectOutputStream os, TaskDef taskDef, ForkEvent[] events) { + private void writeEvents(final ObjectOutputStream os, final TaskDef taskDef, final ForkEvent[] events) { write(os, new Object[]{taskDef.fullyQualifiedName(), events}); } - ExecutorService executorService(ForkConfiguration config, ObjectOutputStream os) { + private ExecutorService executorService(final ForkConfiguration config, final ObjectOutputStream os) { if(config.isParallel()) { - int nbThreads = Runtime.getRuntime().availableProcessors(); + final int nbThreads = Runtime.getRuntime().availableProcessors(); logDebug(os, "Create a test executor with a thread pool of " + nbThreads + " threads."); // more options later... // TODO we might want to configure the blocking queue with size #proc @@ -212,12 +212,12 @@ public class ForkMain { } } - void runTests(ObjectInputStream is, final ObjectOutputStream os) throws Exception { + private void runTests(final ObjectInputStream is, final ObjectOutputStream os) throws Exception { final ForkConfiguration config = (ForkConfiguration) is.readObject(); - ExecutorService executor = executorService(config, os); + final ExecutorService executor = executorService(config, os); final TaskDef[] tests = (TaskDef[]) is.readObject(); - int nFrameworks = is.readInt(); - Logger[] loggers = { remoteLogger(config.isAnsiCodesSupported(), os) }; + final int nFrameworks = is.readInt(); + final Logger[] loggers = { remoteLogger(config.isAnsiCodesSupported(), os) }; for (int i = 0; i < nFrameworks; i++) { final String[] implClassNames = (String[]) is.readObject(); @@ -225,15 +225,15 @@ public class ForkMain { final String[] remoteFrameworkArgs = (String[]) is.readObject(); Framework framework = null; - for (String implClassName : implClassNames) { + for (final String implClassName : implClassNames) { try { - Object rawFramework = Class.forName(implClassName).newInstance(); + final Object rawFramework = Class.forName(implClassName).newInstance(); if (rawFramework instanceof Framework) framework = (Framework) rawFramework; else framework = new FrameworkWrapper((org.scalatools.testing.Framework) rawFramework); break; - } catch (ClassNotFoundException e) { + } catch (final ClassNotFoundException e) { logDebug(os, "Framework implementation '" + implClassName + "' not present."); } } @@ -241,16 +241,16 @@ public class ForkMain { if (framework == null) continue; - ArrayList filteredTests = new ArrayList(); - for (Fingerprint testFingerprint : framework.fingerprints()) { - for (TaskDef test : tests) { + final ArrayList filteredTests = new ArrayList(); + for (final Fingerprint testFingerprint : framework.fingerprints()) { + for (final TaskDef test : tests) { // TODO: To pass in correct explicitlySpecified and selectors if (matches(testFingerprint, test.fingerprint())) filteredTests.add(new TaskDef(test.fullyQualifiedName(), test.fingerprint(), test.explicitlySpecified(), test.selectors())); } } final Runner runner = framework.runner(frameworkArgs, remoteFrameworkArgs, getClass().getClassLoader()); - Task[] tasks = runner.tasks(filteredTests.toArray(new TaskDef[filteredTests.size()])); + final Task[] tasks = runner.tasks(filteredTests.toArray(new TaskDef[filteredTests.size()])); logDebug(os, "Runner for " + framework.getClass().getName() + " produced " + tasks.length + " initial tasks for " + filteredTests.size() + " tests."); runTestTasks(executor, tasks, loggers, os); @@ -261,20 +261,20 @@ public class ForkMain { is.readObject(); } - void runTestTasks(ExecutorService executor, Task[] tasks, Logger[] loggers, ObjectOutputStream os) { + private void runTestTasks(final ExecutorService executor, final Task[] tasks, final Logger[] loggers, final ObjectOutputStream os) { if( tasks.length > 0 ) { - List> futureNestedTasks = new ArrayList>(); - for( Task task : tasks ) { + final List> futureNestedTasks = new ArrayList>(); + for( final Task task : tasks ) { futureNestedTasks.add(runTest(executor, task, loggers, os)); } // Note: this could be optimized further, we could have a callback once a test finishes that executes immediately the nested tasks // At the moment, I'm especially interested in JUnit, which doesn't have nested tasks. - List nestedTasks = new ArrayList(); - for( Future futureNestedTask : futureNestedTasks ) { + final List nestedTasks = new ArrayList(); + for( final Future futureNestedTask : futureNestedTasks ) { try { nestedTasks.addAll( Arrays.asList(futureNestedTask.get())); - } catch (Exception e) { + } catch (final Exception e) { logError(os, "Failed to execute task " + futureNestedTask); } } @@ -282,23 +282,23 @@ public class ForkMain { } } - Future runTest(ExecutorService executor, final Task task, final Logger[] loggers, final ObjectOutputStream os) { + private Future runTest(final ExecutorService executor, final Task task, final Logger[] loggers, final ObjectOutputStream os) { return executor.submit(new Callable() { @Override public Task[] call() { ForkEvent[] events; Task[] nestedTasks; - TaskDef taskDef = task.taskDef(); + final TaskDef taskDef = task.taskDef(); try { final List eventList = new ArrayList(); - EventHandler handler = new EventHandler() { public void handle(Event e){ eventList.add(new ForkEvent(e)); } }; + final EventHandler handler = new EventHandler() { public void handle(final Event e){ eventList.add(new ForkEvent(e)); } }; logDebug(os, " Running " + taskDef); nestedTasks = task.execute(handler, loggers); if(nestedTasks.length > 0 || eventList.size() > 0) logDebug(os, " Produced " + nestedTasks.length + " nested tasks and " + eventList.size() + " events."); events = eventList.toArray(new ForkEvent[eventList.size()]); } - catch (Throwable t) { + catch (final Throwable t) { nestedTasks = new Task[0]; events = new ForkEvent[] { testError(os, taskDef, "Uncaught exception when running " + taskDef.fullyQualifiedName() + ": " + t.toString(), t) }; } @@ -308,11 +308,11 @@ public class ForkMain { }); } - void internalError(Throwable t) { + private void internalError(final Throwable t) { System.err.println("Internal error when running tests: " + t.toString()); } - ForkEvent testEvent(final String fullyQualifiedName, final Fingerprint fingerprint, final Selector selector, final Status r, final ForkError err, final long duration) { + private ForkEvent testEvent(final String fullyQualifiedName, final Fingerprint fingerprint, final Selector selector, final Status r, final ForkError err, final long duration) { final OptionalThrowable throwable; if (err == null) throwable = new OptionalThrowable(); @@ -332,9 +332,9 @@ public class ForkMain { }); } - ForkEvent testError(ObjectOutputStream os, TaskDef taskDef, String message, Throwable t) { + private ForkEvent testError(final ObjectOutputStream os, final TaskDef taskDef, final String message, final Throwable t) { logError(os, message); - ForkError fe = new ForkError(t); + final ForkError fe = new ForkError(t); write(os, fe); return testEvent(taskDef.fullyQualifiedName(), taskDef.fingerprint(), new SuiteSelector(), Status.Error, fe, 0); } diff --git a/testing/agent/src/main/java/sbt/ForkTags.java b/testing/agent/src/main/java/sbt/ForkTags.java index 7fe3f365b..4318555ee 100644 --- a/testing/agent/src/main/java/sbt/ForkTags.java +++ b/testing/agent/src/main/java/sbt/ForkTags.java @@ -6,4 +6,3 @@ package sbt; public enum ForkTags { Error, Warn, Info, Debug, Done } - diff --git a/testing/agent/src/main/java/sbt/FrameworkWrapper.java b/testing/agent/src/main/java/sbt/FrameworkWrapper.java index 1ad5d0e1f..dd606ab54 100644 --- a/testing/agent/src/main/java/sbt/FrameworkWrapper.java +++ b/testing/agent/src/main/java/sbt/FrameworkWrapper.java @@ -8,9 +8,9 @@ import sbt.testing.*; */ final class FrameworkWrapper implements Framework { - private org.scalatools.testing.Framework oldFramework; + private final org.scalatools.testing.Framework oldFramework; - public FrameworkWrapper(org.scalatools.testing.Framework oldFramework) { + FrameworkWrapper(final org.scalatools.testing.Framework oldFramework) { this.oldFramework = oldFramework; } @@ -19,11 +19,11 @@ final class FrameworkWrapper implements Framework { } public Fingerprint[] fingerprints() { - org.scalatools.testing.Fingerprint[] oldFingerprints = oldFramework.tests(); - int length = oldFingerprints.length; - Fingerprint[] fingerprints = new Fingerprint[length]; + final org.scalatools.testing.Fingerprint[] oldFingerprints = oldFramework.tests(); + final int length = oldFingerprints.length; + final Fingerprint[] fingerprints = new Fingerprint[length]; for (int i=0; i < length; i++) { - org.scalatools.testing.Fingerprint oldFingerprint = oldFingerprints[i]; + final org.scalatools.testing.Fingerprint oldFingerprint = oldFingerprints[i]; if (oldFingerprint instanceof org.scalatools.testing.TestFingerprint) fingerprints[i] = new SubclassFingerprintWrapper((org.scalatools.testing.TestFingerprint) oldFingerprint); else if (oldFingerprint instanceof org.scalatools.testing.SubclassFingerprint) @@ -34,20 +34,20 @@ final class FrameworkWrapper implements Framework { return fingerprints; } - public Runner runner(String[] args, String[] remoteArgs, ClassLoader testClassLoader) { + public Runner runner(final String[] args, final String[] remoteArgs, final ClassLoader testClassLoader) { return new RunnerWrapper(oldFramework, testClassLoader, args); } } final class SubclassFingerprintWrapper implements SubclassFingerprint { - private String superclassName; - private boolean isModule; - private boolean requireNoArgConstructor; + private final String superclassName; + private final boolean isModule; + private final boolean requireNoArgConstructor; - public SubclassFingerprintWrapper(org.scalatools.testing.SubclassFingerprint oldFingerprint) { - this.superclassName = oldFingerprint.superClassName(); - this.isModule = oldFingerprint.isModule(); - this.requireNoArgConstructor = false; // Old framework SubclassFingerprint does not require no arg constructor + SubclassFingerprintWrapper(final org.scalatools.testing.SubclassFingerprint oldFingerprint) { + superclassName = oldFingerprint.superClassName(); + isModule = oldFingerprint.isModule(); + requireNoArgConstructor = false; // Old framework SubclassFingerprint does not require no arg constructor } public boolean isModule() { @@ -57,19 +57,19 @@ final class SubclassFingerprintWrapper implements SubclassFingerprint { public String superclassName() { return superclassName; } - + public boolean requireNoArgConstructor() { return requireNoArgConstructor; } } final class AnnotatedFingerprintWrapper implements AnnotatedFingerprint { - private String annotationName; - private boolean isModule; + private final String annotationName; + private final boolean isModule; - public AnnotatedFingerprintWrapper(org.scalatools.testing.AnnotatedFingerprint oldFingerprint) { - this.annotationName = oldFingerprint.annotationName(); - this.isModule = oldFingerprint.isModule(); + AnnotatedFingerprintWrapper(final org.scalatools.testing.AnnotatedFingerprint oldFingerprint) { + annotationName = oldFingerprint.annotationName(); + isModule = oldFingerprint.isModule(); } public boolean isModule() { @@ -83,33 +83,33 @@ final class AnnotatedFingerprintWrapper implements AnnotatedFingerprint { final class EventHandlerWrapper implements org.scalatools.testing.EventHandler { - private EventHandler newEventHandler; - private String fullyQualifiedName; - private Fingerprint fingerprint; + private final EventHandler newEventHandler; + private final String fullyQualifiedName; + private final Fingerprint fingerprint; - public EventHandlerWrapper(EventHandler newEventHandler, String fullyQualifiedName, Fingerprint fingerprint) { + EventHandlerWrapper(final EventHandler newEventHandler, final String fullyQualifiedName, final Fingerprint fingerprint) { this.newEventHandler = newEventHandler; this.fullyQualifiedName = fullyQualifiedName; this.fingerprint = fingerprint; } - public void handle(org.scalatools.testing.Event oldEvent) { + public void handle(final org.scalatools.testing.Event oldEvent) { newEventHandler.handle(new EventWrapper(oldEvent, fullyQualifiedName, fingerprint)); } } final class EventWrapper implements Event { - private org.scalatools.testing.Event oldEvent; - private String className; - private Fingerprint fingerprint; - private OptionalThrowable throwable; + private final org.scalatools.testing.Event oldEvent; + private final String className; + private final Fingerprint fingerprint; + private final OptionalThrowable throwable; - public EventWrapper(org.scalatools.testing.Event oldEvent, String className, Fingerprint fingerprint) { + EventWrapper(final org.scalatools.testing.Event oldEvent, final String className, final Fingerprint fingerprint) { this.oldEvent = oldEvent; this.className = className; this.fingerprint = fingerprint; - Throwable oldThrowable = oldEvent.error(); + final Throwable oldThrowable = oldEvent.error(); if (oldThrowable == null) throwable = new OptionalThrowable(); else @@ -121,7 +121,7 @@ final class EventWrapper implements Event { } public Fingerprint fingerprint() { - return fingerprint; + return fingerprint; } public Selector selector() { @@ -130,9 +130,9 @@ final class EventWrapper implements Event { public Status status() { switch (oldEvent.result()) { - case Success: + case Success: return Status.Success; - case Error: + case Error: return Status.Error; case Failure: return Status.Failure; @@ -154,47 +154,47 @@ final class EventWrapper implements Event { final class RunnerWrapper implements Runner { - private org.scalatools.testing.Framework oldFramework; - private ClassLoader testClassLoader; - private String[] args; + private final org.scalatools.testing.Framework oldFramework; + private final ClassLoader testClassLoader; + private final String[] args; - public RunnerWrapper(org.scalatools.testing.Framework oldFramework, ClassLoader testClassLoader, String[] args) { + RunnerWrapper(final org.scalatools.testing.Framework oldFramework, final ClassLoader testClassLoader, final String[] args) { this.oldFramework = oldFramework; this.testClassLoader = testClassLoader; this.args = args; } - - public Task[] tasks(TaskDef[] taskDefs) { - int length = taskDefs.length; - Task[] tasks = new Task[length]; + + public Task[] tasks(final TaskDef[] taskDefs) { + final int length = taskDefs.length; + final Task[] tasks = new Task[length]; for (int i = 0; i < length; i++) { - TaskDef taskDef = taskDefs[i]; + final TaskDef taskDef = taskDefs[i]; tasks[i] = createTask(taskDef); } return tasks; } - public Task createTask(final TaskDef taskDef) { + private Task createTask(final TaskDef taskDef) { return new Task() { public String[] tags() { return new String[0]; // Old framework does not support tags } - + private org.scalatools.testing.Logger createOldLogger(final Logger logger) { return new org.scalatools.testing.Logger() { - public boolean ansiCodesSupported() { return logger.ansiCodesSupported(); } - public void error(String msg) { logger.error(msg); } - public void warn(String msg) { logger.warn(msg); } - public void info(String msg) { logger.info(msg); } - public void debug(String msg) { logger.debug(msg); } - public void trace(Throwable t) { logger.trace(t); } + public boolean ansiCodesSupported() { return logger.ansiCodesSupported(); } + public void error(final String msg) { logger.error(msg); } + public void warn(final String msg) { logger.warn(msg); } + public void info(final String msg) { logger.info(msg); } + public void debug(final String msg) { logger.debug(msg); } + public void trace(final Throwable t) { logger.trace(t); } }; } - - private void runRunner(org.scalatools.testing.Runner runner, Fingerprint fingerprint, EventHandler eventHandler) { + + private void runRunner(final org.scalatools.testing.Runner runner, final Fingerprint fingerprint, final EventHandler eventHandler) { // Old runner only support subclass fingerprint. final SubclassFingerprint subclassFingerprint = (SubclassFingerprint) fingerprint; - org.scalatools.testing.TestFingerprint oldFingerprint = + final org.scalatools.testing.TestFingerprint oldFingerprint = new org.scalatools.testing.TestFingerprint() { public boolean isModule() { return subclassFingerprint.isModule(); } public String superClassName() { return subclassFingerprint.superclassName(); } @@ -202,9 +202,9 @@ final class RunnerWrapper implements Runner { final String name = taskDef.fullyQualifiedName(); runner.run(name, oldFingerprint, new EventHandlerWrapper(eventHandler, name, subclassFingerprint), args); } - - private void runRunner2(org.scalatools.testing.Runner2 runner, Fingerprint fingerprint, EventHandler eventHandler) { - org.scalatools.testing.Fingerprint oldFingerprint = null; + + private void runRunner2(final org.scalatools.testing.Runner2 runner, final Fingerprint fingerprint, final EventHandler eventHandler) { + final org.scalatools.testing.Fingerprint oldFingerprint; if (fingerprint instanceof SubclassFingerprint) { final SubclassFingerprint subclassFingerprint = (SubclassFingerprint) fingerprint; oldFingerprint = new org.scalatools.testing.SubclassFingerprint() { @@ -222,10 +222,10 @@ final class RunnerWrapper implements Runner { final String name = taskDef.fullyQualifiedName(); runner.run(name, oldFingerprint, new EventHandlerWrapper(eventHandler, name, fingerprint), args); } - - public Task[] execute(EventHandler eventHandler, Logger[] loggers) { - int length = loggers.length; - org.scalatools.testing.Logger[] oldLoggers = new org.scalatools.testing.Logger[length]; + + public Task[] execute(final EventHandler eventHandler, final Logger[] loggers) { + final int length = loggers.length; + final org.scalatools.testing.Logger[] oldLoggers = new org.scalatools.testing.Logger[length]; for (int i=0; i Date: Wed, 6 Jul 2016 13:45:57 +0100 Subject: [PATCH 3/8] Remove some heads and tails --- main-command/src/main/scala/sbt/State.scala | 2 +- .../main/scala/sbt/internal/BuildStructure.scala | 6 ++++-- main/src/main/scala/sbt/internal/Load.scala | 7 +++++-- .../main/scala/sbt/internal/SettingGraph.scala | 16 +++++++++------- main/src/test/scala/sbt/internal/TestBuild.scala | 2 +- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/main-command/src/main/scala/sbt/State.scala b/main-command/src/main/scala/sbt/State.scala index 50aa80831..f4b4041cf 100644 --- a/main-command/src/main/scala/sbt/State.scala +++ b/main-command/src/main/scala/sbt/State.scala @@ -166,7 +166,7 @@ object State { /** Changes the maximum number of commands kept, adjusting the current history if necessary.*/ def setMaxSize(size: Int): History = new History(if (size <= 0) executed else executed.take(size), size) - def current: String = executed.head + def currentOption: Option[String] = executed.headOption def previous: Option[String] = executed.drop(1).headOption } /** Constructs an empty command History with a default, finite command limit.*/ diff --git a/main/src/main/scala/sbt/internal/BuildStructure.scala b/main/src/main/scala/sbt/internal/BuildStructure.scala index 1e83322fa..31f89725f 100644 --- a/main/src/main/scala/sbt/internal/BuildStructure.scala +++ b/main/src/main/scala/sbt/internal/BuildStructure.scala @@ -41,12 +41,14 @@ final class StructureIndex( * The first root project is used as the default in several situations where a project is not otherwise selected. */ final class LoadedBuildUnit(val unit: BuildUnit, val defined: Map[String, ResolvedProject], val rootProjects: Seq[String], val buildSettings: Seq[Setting[_]]) extends BuildUnitBase { - assert(rootProjects.nonEmpty, "No root projects defined for build unit " + unit) /** * The project to use as the default when one is not otherwise selected. * [[LocalRootProject]] resolves to this from within the same build. */ - val root = rootProjects.head + val root = rootProjects match { + case Nil => throw new java.lang.AssertionError("assertion failed: No root projects defined for build unit " + unit) + case Seq(root, _*) => root + } /** The base directory of the build unit (not the build definition).*/ def localBase = unit.localBase diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index 99e14e78f..cce1dbf31 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -312,7 +312,10 @@ private[sbt] object Load { def loaded(unit: BuildUnit): (PartBuildUnit, List[ProjectReference]) = { val defined = projects(unit) - if (defined.isEmpty) sys.error("No projects defined in build unit " + unit) + val firstDefined = defined match { + case Nil => sys.error("No projects defined in build unit " + unit) + case Seq(first, _*) => first + } // since base directories are resolved at this point (after 'projects'), // we can compare Files instead of converting to URIs @@ -321,7 +324,7 @@ private[sbt] object Load { val externals = referenced(defined).toList val explicitRoots = unit.definitions.builds.flatMap(_.rootProject) val projectsInRoot = if (explicitRoots.isEmpty) defined.filter(isRoot) else explicitRoots - val rootProjects = if (projectsInRoot.isEmpty) defined.head :: Nil else projectsInRoot + val rootProjects = if (projectsInRoot.isEmpty) firstDefined :: Nil else projectsInRoot (new PartBuildUnit(unit, defined.map(d => (d.id, d)).toMap, rootProjects.map(_.id), buildSettings(unit)), externals) } def buildSettings(unit: BuildUnit): Seq[Setting[_]] = diff --git a/main/src/main/scala/sbt/internal/SettingGraph.scala b/main/src/main/scala/sbt/internal/SettingGraph.scala index bdce207a5..561e60150 100644 --- a/main/src/main/scala/sbt/internal/SettingGraph.scala +++ b/main/src/main/scala/sbt/internal/SettingGraph.scala @@ -77,19 +77,21 @@ object Graph { }) + s.slice(at + 1, s.length) else s - def toAsciiLines(node: A, level: Int): Vector[String] = { + def toAsciiLines(node: A, level: Int): (String, Vector[String]) = { val line = limitLine((twoSpaces * level) + (if (level == 0) "" else "+-") + display(node)) val cs = Vector(children(node): _*) val childLines = cs map { toAsciiLines(_, level + 1) } val withBar = childLines.zipWithIndex flatMap { - case (lines, pos) if pos < (cs.size - 1) => lines map { insertBar(_, 2 * (level + 1)) } - case (lines, pos) => - if (lines.last.trim != "") lines ++ Vector(twoSpaces * (level + 1)) - else lines + case ((line, withBar), pos) if pos < (cs.size - 1) => + (line +: withBar) map { insertBar(_, 2 * (level + 1)) } + case ((line, withBar), pos) if withBar.lastOption.getOrElse(line).trim != "" => + (line +: withBar) ++ Vector(twoSpaces * (level + 1)) + case ((line, withBar), _) => line +: withBar } - line +: withBar + (line, withBar) } - toAsciiLines(top, 0).mkString("\n") + val (line, withBar) = toAsciiLines(top, 0) + (line +: withBar).mkString("\n") } } diff --git a/main/src/test/scala/sbt/internal/TestBuild.scala b/main/src/test/scala/sbt/internal/TestBuild.scala index f7720f873..059a2ad88 100644 --- a/main/src/test/scala/sbt/internal/TestBuild.scala +++ b/main/src/test/scala/sbt/internal/TestBuild.scala @@ -99,7 +99,7 @@ object TestBuild { def inheritConfig(ref: ResolvedReference, config: ConfigKey) = projectFor(ref).confMap(config.name).extended map toConfigKey def inheritTask(task: AttributeKey[_]) = taskMap.get(task) match { case None => Nil; case Some(t) => t.delegates map getKey } def inheritProject(ref: ProjectRef) = project(ref).delegates - def resolve(ref: Reference) = Scope.resolveReference(builds.head.uri, rootProject, ref) + def resolve(ref: Reference) = Scope.resolveReference(root.uri, rootProject, ref) lazy val delegates: Scope => Seq[Scope] = Scope.delegates( allProjects, From 32760bed55fc58a57040599a6dbc917d5e66a4c3 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 6 Jul 2016 23:56:31 +0100 Subject: [PATCH 4/8] Remove some fatal exception catching --- main-command/src/main/scala/sbt/MainLoop.scala | 3 ++- main-command/src/main/scala/xsbt/IPC.scala | 4 +++- main-settings/src/main/scala/sbt/Previous.scala | 7 +++++-- main/src/main/scala/sbt/Defaults.scala | 3 ++- main/src/main/scala/sbt/Main.scala | 2 +- main/src/main/scala/sbt/Resolvers.scala | 3 ++- main/src/main/scala/sbt/SessionVar.scala | 4 +++- main/src/main/scala/sbt/internal/PluginDiscovery.scala | 1 + main/src/test/scala/ProjectMacro.scala | 3 ++- project/Util.scala | 3 ++- scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala | 4 +++- tasks-standard/src/test/scala/checkResult.scala | 6 ++++-- testing/src/main/scala/sbt/TestFramework.scala | 5 +++-- 13 files changed, 33 insertions(+), 15 deletions(-) diff --git a/main-command/src/main/scala/sbt/MainLoop.scala b/main-command/src/main/scala/sbt/MainLoop.scala index 7aaaf0c4f..9452f6454 100644 --- a/main-command/src/main/scala/sbt/MainLoop.scala +++ b/main-command/src/main/scala/sbt/MainLoop.scala @@ -4,6 +4,7 @@ package sbt import scala.annotation.tailrec +import scala.util.control.NonFatal import java.io.{ File, PrintWriter } import jline.TerminalFactory @@ -52,7 +53,7 @@ object MainLoop { case e: xsbti.FullReload => deleteLastLog(logBacking) throw e // pass along a reboot request - case e: Throwable => + case NonFatal(e) => System.err.println("sbt appears to be exiting abnormally.\n The log file for this session is at " + logBacking.file) deleteLastLog(logBacking) throw e diff --git a/main-command/src/main/scala/xsbt/IPC.scala b/main-command/src/main/scala/xsbt/IPC.scala index fc5943598..ec1563561 100644 --- a/main-command/src/main/scala/xsbt/IPC.scala +++ b/main-command/src/main/scala/xsbt/IPC.scala @@ -6,6 +6,8 @@ package xsbt import java.io.{ BufferedReader, BufferedWriter, InputStream, InputStreamReader, OutputStreamWriter, OutputStream } import java.net.{ InetAddress, ServerSocket, Socket } +import scala.util.control.NonFatal + object IPC { private val portMin = 1025 private val portMax = 65536 @@ -28,7 +30,7 @@ object IPC { def createServer(attempts: Int): ServerSocket = if (attempts > 0) try { new ServerSocket(nextPort, 1, loopback) } - catch { case _: Exception => createServer(attempts - 1) } + catch { case NonFatal(e) => createServer(attempts - 1) } else sys.error("Could not connect to socket: maximum attempts exceeded") createServer(10) diff --git a/main-settings/src/main/scala/sbt/Previous.scala b/main-settings/src/main/scala/sbt/Previous.scala index 565fa1394..af026fee2 100644 --- a/main-settings/src/main/scala/sbt/Previous.scala +++ b/main-settings/src/main/scala/sbt/Previous.scala @@ -6,6 +6,9 @@ import sbt.internal.util.{ ~>, AttributeKey, IMap, RMap } import sbt.internal.util.Types._ import java.io.{ InputStream, OutputStream } + +import scala.util.control.NonFatal + import sbinary.{ DefaultProtocol, Format } import DefaultProtocol.{ StringFormat, withStamp } @@ -76,11 +79,11 @@ object Previous { private def read[T](stream: InputStream, format: Format[T]): Option[T] = try Some(format.reads(stream)) - catch { case e: Exception => None } + catch { case NonFatal(e) => None } private def write[T](stream: OutputStream, format: Format[T], value: T): Unit = try format.writes(stream, value) - catch { case e: Exception => () } + catch { case NonFatal(e) => () } /** Public as a macro implementation detail. Do not call directly. */ def runtime[T](skey: TaskKey[T])(implicit format: Format[T]): Initialize[Task[Option[T]]] = diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 7d5e028ed..fae766bf2 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -28,6 +28,7 @@ import sbt.util.Level import sys.error import scala.xml.NodeSeq +import scala.util.control.NonFatal import org.apache.ivy.core.module.{ descriptor, id } import descriptor.ModuleDescriptor, id.ModuleRevisionId import java.io.{ File, PrintWriter } @@ -1572,7 +1573,7 @@ object Classpaths { s.init.evaluate(empty) map { _ -> s.pos } }: _*) } catch { - case _: Throwable => Map() + case NonFatal(e) => Map() } val outCacheFile = cacheFile / "output_dsp" diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index ff2a5139b..bd5537b30 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -333,7 +333,7 @@ object BuiltinCommands { } yield () => { def export0(s: State): State = lastImpl(s, kvs, Some(ExportStream)) val newS = try f() catch { - case e: Exception => + case NonFatal(e) => try export0(s) finally { throw e } } diff --git a/main/src/main/scala/sbt/Resolvers.scala b/main/src/main/scala/sbt/Resolvers.scala index 4d24fdb19..0b9058527 100644 --- a/main/src/main/scala/sbt/Resolvers.scala +++ b/main/src/main/scala/sbt/Resolvers.scala @@ -17,6 +17,7 @@ import RichURI.fromURI import java.util.Locale import scala.sys.process.Process +import scala.util.control.NonFatal object Resolvers { type Resolver = BuildLoader.Resolver @@ -147,7 +148,7 @@ object Resolvers { try { f } catch { - case e: Throwable => + case NonFatal(e) => IO.delete(file) throw e } diff --git a/main/src/main/scala/sbt/SessionVar.scala b/main/src/main/scala/sbt/SessionVar.scala index e7858c8eb..078b947d2 100644 --- a/main/src/main/scala/sbt/SessionVar.scala +++ b/main/src/main/scala/sbt/SessionVar.scala @@ -1,5 +1,7 @@ package sbt +import scala.util.control.NonFatal + import sbt.internal.util.{ AttributeMap, IMap, Types } import Def.ScopedKey @@ -53,7 +55,7 @@ object SessionVar { def read[T](key: ScopedKey[Task[T]], state: State)(implicit f: Format[T]): Option[T] = Project.structure(state).streams(state).use(key) { s => try { Some(Operations.read(s.readBinary(key, DefaultDataID))) } - catch { case e: Exception => None } + catch { case NonFatal(e) => None } } def load[T](key: ScopedKey[Task[T]], state: State)(implicit f: Format[T]): Option[T] = diff --git a/main/src/main/scala/sbt/internal/PluginDiscovery.scala b/main/src/main/scala/sbt/internal/PluginDiscovery.scala index 1a62c0242..a3dc15c5b 100644 --- a/main/src/main/scala/sbt/internal/PluginDiscovery.scala +++ b/main/src/main/scala/sbt/internal/PluginDiscovery.scala @@ -5,6 +5,7 @@ import sbt.internal.util.Attributed // import sbt.internal.{ BuildDef, IncompatiblePluginsException, OldPlugin } import java.io.File import java.net.URL +import scala.util.control.NonFatal import Attributed.data import sbt.internal.BuildDef.analyzed import xsbt.api.{ Discovered, Discovery } diff --git a/main/src/test/scala/ProjectMacro.scala b/main/src/test/scala/ProjectMacro.scala index 7d96b0a64..55575e630 100644 --- a/main/src/test/scala/ProjectMacro.scala +++ b/main/src/test/scala/ProjectMacro.scala @@ -1,5 +1,6 @@ package sbt +import scala.util.control.NonFatal import org.scalacheck._ import Prop._ import Project.project @@ -27,7 +28,7 @@ object ProjectMacro extends Properties("ProjectMacro") { def secure(f: => Prop): Prop = try { Prop.secure(f) } catch { - case e: Throwable => + case NonFatal(e) => e.printStackTrace throw e } diff --git a/project/Util.scala b/project/Util.scala index 5fa0ad216..0bf378ef9 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -1,3 +1,4 @@ +import scala.util.control.NonFatal import sbt._ import Keys._ import StringUtilities.normalize @@ -164,5 +165,5 @@ object Licensed { def extractLicenses0(base: File, note: File, s: TaskStreams): Seq[File] = if (!note.exists) Nil else try { seePaths(base, IO.read(note)) } - catch { case e: Exception => s.log.warn("Could not read NOTICE"); Nil } + catch { case NonFatal(e) => s.log.warn("Could not read NOTICE"); Nil } } diff --git a/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala b/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala index f341a4925..758abdb56 100644 --- a/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala +++ b/scripted/sbt/src/main/scala/sbt/test/ScriptedTests.scala @@ -8,6 +8,8 @@ package test import java.io.File import java.nio.charset.Charset +import scala.util.control.NonFatal + import xsbt.IPC import sbt.internal.scripted.{ CommentHandler, FileCommands, ScriptRunner, TestScriptParser, TestException } import sbt.io.{ DirectoryFilter, GlobFilter, HiddenFileFilter, Path } @@ -98,7 +100,7 @@ final class ScriptedTests(resourceBaseDirectory: File, bufferLog: Boolean, launc testFailed() buffered.error(" Mark as passing to remove this failure.") throw e - case e: Exception => + case NonFatal(e) => testFailed() if (!pending) throw e } finally { buffered.clear() } diff --git a/tasks-standard/src/test/scala/checkResult.scala b/tasks-standard/src/test/scala/checkResult.scala index 14c992c57..b8c4fe701 100644 --- a/tasks-standard/src/test/scala/checkResult.scala +++ b/tasks-standard/src/test/scala/checkResult.scala @@ -3,6 +3,8 @@ */ package sbt +import scala.util.control.NonFatal + import org.scalacheck.Prop._ object checkResult { @@ -16,9 +18,9 @@ object checkResult { case i: Incomplete => println(i) "One or more tasks failed" |: false - case e: Throwable => + case NonFatal(e) => e.printStackTrace() "Error in framework" |: false }) } -} \ No newline at end of file +} diff --git a/testing/src/main/scala/sbt/TestFramework.scala b/testing/src/main/scala/sbt/TestFramework.scala index b2ff1c4d6..e151d90ec 100644 --- a/testing/src/main/scala/sbt/TestFramework.scala +++ b/testing/src/main/scala/sbt/TestFramework.scala @@ -5,6 +5,7 @@ package sbt import java.io.File import java.net.URLClassLoader +import scala.util.control.NonFatal import testing.{ Logger => TLogger, Task => TestTask, _ } import org.scalatools.testing.{ Framework => OldFramework } import sbt.internal.inc.classpath.{ ClasspathUtilities, DualLoader, FilteredLoader } @@ -89,7 +90,7 @@ final class TestRunner(delegate: Runner, listeners: Seq[TestReportListener], log safeListenersCall(_.endGroup(name, suiteResult.result)) (suiteResult, nestedTasks) } catch { - case e: Throwable => + case NonFatal(e) => safeListenersCall(_.endGroup(name, e)) (SuiteResult.Error, Seq.empty[TestTask]) } @@ -107,7 +108,7 @@ object TestFramework { } private[sbt] def safeForeach[T](it: Iterable[T], log: Logger)(f: T => Unit): Unit = - it.foreach(i => try f(i) catch { case e: Exception => log.trace(e); log.error(e.toString) }) + it.foreach(i => try f(i) catch { case NonFatal(e) => log.trace(e); log.error(e.toString) }) private[sbt] def hashCode(f: Fingerprint): Int = f match { case s: SubclassFingerprint => (s.isModule, s.superclassName).hashCode From 4c75d778b9e44c20767f1a01a00903c6e71a8538 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 7 Jul 2016 00:11:41 +0100 Subject: [PATCH 5/8] Group imports --- main-settings/src/main/scala/sbt/Def.scala | 1 - main-settings/src/test/scala/UsageTest.scala | 3 +-- main/src/main/scala/sbt/Defaults.scala | 14 ++++++-------- main/src/main/scala/sbt/EvaluateTask.scala | 7 +++---- main/src/main/scala/sbt/Keys.scala | 7 +++---- main/src/main/scala/sbt/LogManager.scala | 3 +-- main/src/main/scala/sbt/Main.scala | 5 +++-- main/src/main/scala/sbt/Project.scala | 4 +--- main/src/main/scala/sbt/internal/KeyIndex.scala | 4 +--- main/src/main/scala/sbt/internal/Load.scala | 8 ++++---- .../src/main/scala/sbt/std/Streams.scala | 6 +++--- 11 files changed, 26 insertions(+), 36 deletions(-) diff --git a/main-settings/src/main/scala/sbt/Def.scala b/main-settings/src/main/scala/sbt/Def.scala index 8800843da..7f08e50bb 100644 --- a/main-settings/src/main/scala/sbt/Def.scala +++ b/main-settings/src/main/scala/sbt/Def.scala @@ -95,7 +95,6 @@ object Def extends Init[Scope] with TaskMacroExtra { implicit def parserInitToInput[T](p: Initialize[Parser[T]]): ParserInput[T] = ??? implicit def parserInitStateToInput[T](p: Initialize[State => Parser[T]]): ParserInput[T] = ??? - import language.experimental.macros def settingKey[T](description: String): SettingKey[T] = macro std.KeyMacro.settingKeyImpl[T] def taskKey[T](description: String): TaskKey[T] = macro std.KeyMacro.taskKeyImpl[T] def inputKey[T](description: String): InputKey[T] = macro std.KeyMacro.inputKeyImpl[T] diff --git a/main-settings/src/test/scala/UsageTest.scala b/main-settings/src/test/scala/UsageTest.scala index c62ec9205..88c894e2a 100644 --- a/main-settings/src/test/scala/UsageTest.scala +++ b/main-settings/src/test/scala/UsageTest.scala @@ -20,8 +20,7 @@ import sbt.internal.util.complete.{ DefaultParsers, Parsers } }*/ object Assign { import java.io.File - import Def.{ inputKey, settingKey, taskKey } - import Def.{ Initialize, macroValueT, parserToInput } + import Def.{ Initialize, inputKey, macroValueT, parserToInput, settingKey, taskKey } // import UseTask.{x,y,z,a,set,plain} val ak = taskKey[Int]("a") diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index fae766bf2..f1d129a45 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -5,15 +5,12 @@ package sbt import scala.concurrent.duration.{ FiniteDuration, Duration } import sbt.internal._ -import sbt.internal.util.Attributed import sbt.internal.util.Attributed.data import Scope.{ fillTaskAxis, GlobalScope, ThisScope } import sbt.internal.librarymanagement.mavenint.{ PomExtraDependencyAttributes, SbtPomExtraProperties } import Project.{ inConfig, inScope, inTask, richInitialize, richInitializeTask, richTaskSessionVar } import Def.{ Initialize, ScopedKey, Setting, SettingsDefinition } -import sbt.internal.librarymanagement.{ CustomPomParser, DependencyFilter } import sbt.librarymanagement.Artifact.{ DocClassifier, SourceClassifier } -import sbt.librarymanagement.{ Configuration, Configurations, ConflictManager, CrossVersion, MavenRepository, Resolver, ScalaArtifacts, UpdateOptions } import sbt.librarymanagement.Configurations.{ Compile, CompilerPlugin, IntegrationTest, names, Provided, Runtime, Test } import sbt.librarymanagement.CrossVersion.{ binarySbtVersion, binaryScalaVersion, partialVersion } import sbt.internal.util.complete._ @@ -24,7 +21,7 @@ import sbt.librarymanagement.{ `package` => _, _ } import sbt.internal.librarymanagement._ import sbt.internal.librarymanagement.syntax._ import sbt.internal.util._ -import sbt.util.Level +import sbt.util.{ Level, Logger } import sys.error import scala.xml.NodeSeq @@ -36,7 +33,6 @@ import java.net.{ URI, URL, MalformedURLException } import java.util.concurrent.{ TimeUnit, Callable } import sbinary.DefaultProtocol.StringFormat import sbt.internal.util.Cache.seqFormat -import sbt.util.Logger import sbt.internal.CommandStrings.ExportStream import xsbti.{ CrossValue, Maybe } @@ -53,9 +49,11 @@ import Keys._ // incremental compiler import xsbt.api.Discovery -import xsbti.compile.{ Compilers, ClasspathOptions, CompileAnalysis, CompileOptions, CompileOrder, CompileResult, DefinesClass, IncOptions, IncOptionsUtil, Inputs, MiniSetup, PreviousResult, Setup, TransactionalManagerType } -import xsbti.compile.PerClasspathEntryLookup -import sbt.internal.inc.{ AnalyzingCompiler, Analysis, ClassfileManager, CompilerCache, FileValueCache, IncrementalCompilerImpl, Locate, LoggerReporter, MixedAnalyzingCompiler, ScalaInstance, ClasspathOptionsUtil } +import xsbti.compile.{ Compilers, ClasspathOptions, CompileAnalysis, CompileOptions, CompileOrder, + CompileResult, DefinesClass, IncOptions, IncOptionsUtil, Inputs, MiniSetup, PerClasspathEntryLookup, + PreviousResult, Setup, TransactionalManagerType } +import sbt.internal.inc.{ AnalyzingCompiler, Analysis, ClassfileManager, CompilerCache, FileValueCache, + IncrementalCompilerImpl, Locate, LoggerReporter, MixedAnalyzingCompiler, ScalaInstance, ClasspathOptionsUtil } object Defaults extends BuildCommon { final val CacheDirectoryName = "cache" diff --git a/main/src/main/scala/sbt/EvaluateTask.scala b/main/src/main/scala/sbt/EvaluateTask.scala index 871d6e919..59fd27dd9 100644 --- a/main/src/main/scala/sbt/EvaluateTask.scala +++ b/main/src/main/scala/sbt/EvaluateTask.scala @@ -4,19 +4,18 @@ package sbt import sbt.internal.{ Load, BuildStructure, TaskTimings, TaskName, GCUtil } -import sbt.internal.util.{ ErrorHandling, RMap, Show, Signals, Types } +import sbt.internal.util.{ Attributed, ErrorHandling, HList, RMap, Show, Signals, Types } import sbt.util.Logger import sbt.librarymanagement.{ Resolver, UpdateReport } import scala.concurrent.duration.Duration import java.io.File import Def.{ displayFull, dummyState, ScopedKey, Setting } -import Keys.{ streams, Streams, TaskStreams } -import Keys.{ dummyRoots, dummyStreamsManager, executionRoots, pluginData, streamsManager, taskDefinitionKey, transformState } +import Keys.{ Streams, TaskStreams, dummyRoots, dummyStreamsManager, executionRoots, pluginData, streams, + streamsManager, taskDefinitionKey, transformState } import Project.richInitializeTask import Scope.{ GlobalScope, ThisScope } import sbt.internal.util.Types.const -import sbt.internal.util.{ Attributed, HList } import scala.Console.RED import std.Transform.{ DummyTaskMap, TaskAndValue } import TaskName._ diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index d3e828085..ba97bf029 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -8,10 +8,10 @@ import java.net.URL import scala.concurrent.duration.{ FiniteDuration, Duration } import Def.ScopedKey import sbt.internal.util.complete._ -import xsbti.compile.DefinesClass import sbt.internal.inc.{ MixedAnalyzingCompiler, ScalaInstance } import std.TaskExtra._ -import xsbti.compile.{ ClasspathOptions, CompileAnalysis, CompileOptions, CompileOrder, Compilers, CompileResult, GlobalsCache, IncOptions, Inputs, PreviousResult, Setup } +import xsbti.compile.{ DefinesClass, ClasspathOptions, CompileAnalysis, CompileOptions, CompileOrder, + Compilers, CompileResult, GlobalsCache, IncOptions, Inputs, PreviousResult, Setup } import scala.xml.{ Node => XNode, NodeSeq } import org.apache.ivy.core.module.{ descriptor, id } import descriptor.ModuleDescriptor, id.ModuleRevisionId @@ -22,7 +22,7 @@ import KeyRanks._ import sbt.internal.{ BuildStructure, LoadedBuild, PluginDiscovery, BuildDependencies, SessionSettings } import sbt.io.FileFilter import sbt.internal.io.WatchState -import sbt.internal.util.AttributeKey +import sbt.internal.util.{ AttributeKey, SourcePosition } import sbt.librarymanagement.Configurations.CompilerPlugin import sbt.librarymanagement.{ @@ -64,7 +64,6 @@ import sbt.internal.librarymanagement.{ UpdateLogging } import sbt.util.{ AbstractLogger, Level, Logger } -import sbt.internal.util.SourcePosition object Keys { val TraceValues = "-1 to disable, 0 for up to the first sbt frame, or a positive number to set the maximum number of frames shown." diff --git a/main/src/main/scala/sbt/LogManager.scala b/main/src/main/scala/sbt/LogManager.scala index baf260f2e..96e47538a 100644 --- a/main/src/main/scala/sbt/LogManager.scala +++ b/main/src/main/scala/sbt/LogManager.scala @@ -3,8 +3,7 @@ */ package sbt -import java.io.PrintWriter -import java.io.File +import java.io.{ File, PrintWriter } import LogManager._ import std.Transform import Def.ScopedKey diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index bd5537b30..3abaeef3a 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -3,8 +3,9 @@ */ package sbt -import sbt.internal.{ Load, EvaluateConfigurations, LoadedBuildUnit, Aggregation, BuildStructure, Act, Inspect, BuildUnit, Output, PluginsDebug } -import sbt.internal.{ SettingCompletions, CommandStrings, IvyConsole, ProjectNavigation, Script, SessionSettings } +import sbt.internal.{ Act, Aggregation, BuildStructure, BuildUnit, CommandStrings, EvaluateConfigurations, + Inspect, IvyConsole, Load, LoadedBuildUnit, Output, PluginsDebug, ProjectNavigation, Script, SessionSettings, + SettingCompletions } import sbt.internal.util.{ AttributeKey, AttributeMap, complete, ConsoleOut, GlobalLogging, LineRange, MainLogging, SimpleReader, Types } import sbt.util.{ Level, Logger } diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index 456f8d407..e32ff9e72 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -11,13 +11,11 @@ import Keys.{ appConfiguration, stateBuildStructure, commands, configuration, hi import Scope.{ GlobalScope, ThisScope } import Def.{ Flattened, Initialize, ScopedKey, Setting } import sbt.internal.{ Load, BuildStructure, LoadedBuild, LoadedBuildUnit, SettingGraph, SettingCompletions, AddSettings, SessionSettings } -import sbt.internal.util.Eval +import sbt.internal.util.{ AttributeKey, AttributeMap, Dag, Eval, Relation, Settings, Show, ~> } import sbt.internal.util.Types.{ const, idFun } import sbt.internal.util.complete.DefaultParsers import sbt.librarymanagement.Configuration -import sbt.internal.util.{ AttributeKey, AttributeMap, Dag, Relation, Settings, Show, ~> } - import language.experimental.macros sealed trait ProjectDefinition[PR <: ProjectReference] { diff --git a/main/src/main/scala/sbt/internal/KeyIndex.scala b/main/src/main/scala/sbt/internal/KeyIndex.scala index 3a24ae49d..f9778d52e 100644 --- a/main/src/main/scala/sbt/internal/KeyIndex.scala +++ b/main/src/main/scala/sbt/internal/KeyIndex.scala @@ -4,13 +4,11 @@ package sbt package internal -import sbt.internal.util.Relation - import java.net.URI import Def.ScopedKey import sbt.internal.util.complete.DefaultParsers.validID import sbt.internal.util.Types.{ idFun, some } -import sbt.internal.util.AttributeKey +import sbt.internal.util.{ AttributeKey, Relation } object KeyIndex { def empty: ExtendableKeyIndex = new KeyIndex0(emptyBuildIndex) diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index cce1dbf31..1dc910ca3 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -4,7 +4,6 @@ package sbt package internal -import sbt.internal.util.{ Settings, Show, ~> } import sbt.librarymanagement.{ Configuration, Configurations, Resolver, UpdateOptions } import sbt.internal.librarymanagement.{ InlineIvyConfiguration, IvyPaths } @@ -17,10 +16,11 @@ import sbt.internal.inc.{ Analysis, ClasspathOptionsUtil, FileValueCache, Locate import sbt.internal.inc.classpath.ClasspathUtilities import Project.inScope import Def.{ isDummy, ScopedKey, ScopeLocal, Setting } -import Keys.{ appConfiguration, baseDirectory, configuration, fullResolvers, fullClasspath, pluginData, streams, thisProject, thisProjectRef, update } -import Keys.{ exportedProducts, loadedBuild, onLoadMessage, resolvedScoped, sbtPlugin, scalacOptions, taskDefinitionKey } +import Keys.{ appConfiguration, baseDirectory, configuration, exportedProducts, fullClasspath, fullResolvers, + loadedBuild, onLoadMessage, pluginData, resolvedScoped, sbtPlugin, scalacOptions, streams, taskDefinitionKey, + thisProject, thisProjectRef, update } import tools.nsc.reporters.ConsoleReporter -import sbt.internal.util.{ Attributed, Eval => Ev } +import sbt.internal.util.{ Attributed, Eval => Ev, Settings, Show, ~> } import sbt.internal.util.Attributed.data import Scope.{ GlobalScope, ThisScope } import sbt.internal.util.Types.const diff --git a/tasks-standard/src/main/scala/sbt/std/Streams.scala b/tasks-standard/src/main/scala/sbt/std/Streams.scala index 3246be73a..ff1feb096 100644 --- a/tasks-standard/src/main/scala/sbt/std/Streams.scala +++ b/tasks-standard/src/main/scala/sbt/std/Streams.scala @@ -4,9 +4,9 @@ package sbt package std -import java.io.{ InputStream, IOException, OutputStream, Reader, Writer } -import java.io.{ BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter, PrintWriter } -import java.io.{ Closeable, File, FileInputStream, FileOutputStream, InputStreamReader, OutputStreamWriter } +import java.io.{ BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter, Closeable, File, + FileInputStream, FileOutputStream, IOException, InputStream, InputStreamReader, OutputStream, + OutputStreamWriter, PrintWriter, Reader, Writer } import sbt.internal.io.DeferredWriter import sbt.io.IO From 12c2734052a2e15f1830eb21cd9fa68209270116 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 7 Jul 2016 01:39:05 +0100 Subject: [PATCH 6/8] Pattern match some if/else's --- .../src/main/scala/sbt/std/InputConvert.scala | 81 +++++++++-------- .../src/main/scala/sbt/std/InputWrapper.scala | 89 ++++++++++--------- .../src/main/scala/sbt/std/SettingMacro.scala | 22 +++-- .../src/main/scala/sbt/std/TaskMacro.scala | 18 ++-- main/src/main/scala/sbt/Defaults.scala | 17 ++-- main/src/main/scala/sbt/Main.scala | 22 ++--- main/src/main/scala/sbt/ScopedKeyData.scala | 11 ++- .../main/scala/sbt/internal/IvyConsole.scala | 11 ++- .../sbt/internal/SettingCompletions.scala | 11 ++- .../test/scala/sbt/internal/TestBuild.scala | 9 +- .../main/scala/sbt/TestReportListener.scala | 11 ++- 11 files changed, 167 insertions(+), 135 deletions(-) diff --git a/main-settings/src/main/scala/sbt/std/InputConvert.scala b/main-settings/src/main/scala/sbt/std/InputConvert.scala index 97b5794ac..69008c4ff 100644 --- a/main-settings/src/main/scala/sbt/std/InputConvert.scala +++ b/main-settings/src/main/scala/sbt/std/InputConvert.scala @@ -11,52 +11,56 @@ import sbt.internal.util.appmacro.{ Convert, Converted } object InputInitConvert extends Convert { def apply[T: c.WeakTypeTag](c: Context)(nme: String, in: c.Tree): Converted[c.type] = - if (nme == InputWrapper.WrapInitName) - Converted.Success(in) - else if (nme == InputWrapper.WrapInitTaskName) - Converted.Failure(in.pos, "Internal sbt error: initialize+task wrapper not split") - else - Converted.NotApplicable + nme match { + case InputWrapper.WrapInitName => Converted.Success(in) + case InputWrapper.WrapInitTaskName => Converted.Failure(in.pos, initTaskErrorMessage) + case _ => Converted.NotApplicable + } + + private def initTaskErrorMessage = "Internal sbt error: initialize+task wrapper not split" } /** Converts an input `Tree` of type `Parser[T]` or `State => Parser[T]` into a `Tree` of type `State => Parser[T]`.*/ object ParserConvert extends Convert { def apply[T: c.WeakTypeTag](c: Context)(nme: String, in: c.Tree): Converted[c.type] = - { - if (nme == ParserInput.WrapName) - Converted.Success(in) - else if (nme == ParserInput.WrapInitName) - Converted.Failure(in.pos, "Internal sbt error: initialize+parser wrapper not split") - else - Converted.NotApplicable + nme match { + case ParserInput.WrapName => Converted.Success(in) + case ParserInput.WrapInitName => Converted.Failure(in.pos, initParserErrorMessage) + case _ => Converted.NotApplicable } + + private def initParserErrorMessage = "Internal sbt error: initialize+parser wrapper not split" } /** Convert instance for plain `Task`s not within the settings system. */ object TaskConvert extends Convert { def apply[T: c.WeakTypeTag](c: Context)(nme: String, in: c.Tree): Converted[c.type] = - if (nme == InputWrapper.WrapTaskName) - Converted.Success(in) - else - Converted.NotApplicable + if (nme == InputWrapper.WrapTaskName) Converted.Success(in) else Converted.NotApplicable } /** Converts an input `Tree` of type `Initialize[T]`, `Initialize[Task[T]]`, or `Task[T]` into a `Tree` of type `Initialize[Task[T]]`.*/ object FullConvert extends Convert { import InputWrapper._ def apply[T: c.WeakTypeTag](c: Context)(nme: String, in: c.Tree): Converted[c.type] = - if (nme == WrapInitTaskName || nme == WrapPreviousName) - Converted.Success(in) - else if (nme == WrapInitName) { - val i = c.Expr[Initialize[T]](in) - val t = c.universe.reify(Def.toITask(i.splice)).tree - Converted.Success(t) - } else if (nme == WrapTaskName) { - val i = c.Expr[Task[T]](in) - val t = c.universe.reify(Def.valueStrict[Task[T]](i.splice)).tree - Converted.Success(t) - } else - Converted.NotApplicable + nme match { + case WrapInitTaskName => Converted.Success(in) + case WrapPreviousName => Converted.Success(in) + case WrapInitName => wrapInit[T](c)(in) + case WrapTaskName => wrapTask[T](c)(in) + case _ => Converted.NotApplicable + } + + private def wrapInit[T](c: Context)(tree: c.Tree): Converted[c.type] = { + val i = c.Expr[Initialize[T]](tree) + val t = c.universe.reify(Def.toITask(i.splice)).tree + Converted.Success(t) + } + + private def wrapTask[T](c: Context)(tree: c.Tree): Converted[c.type] = { + val i = c.Expr[Task[T]](tree) + val t = c.universe.reify(Def.valueStrict[Task[T]](i.splice)).tree + Converted.Success(t) + } } /** @@ -65,12 +69,15 @@ object FullConvert extends Convert { */ object InitParserConvert extends Convert { def apply[T: c.WeakTypeTag](c: Context)(nme: String, in: c.Tree): Converted[c.type] = - if (nme == ParserInput.WrapName) { - val e = c.Expr[State => Parser[T]](in) - val t = c.universe.reify { Def.valueStrict[State => Parser[T]](e.splice) } - Converted.Success(t.tree) - } else if (nme == ParserInput.WrapInitName) - Converted.Success(in) - else - Converted.NotApplicable + nme match { + case ParserInput.WrapName => wrap[T](c)(in) + case ParserInput.WrapInitName => Converted.Success(in) + case _ => Converted.NotApplicable + } + + private def wrap[T](c: Context)(tree: c.Tree): Converted[c.type] = { + val e = c.Expr[State => Parser[T]](tree) + val t = c.universe.reify { Def.valueStrict[State => Parser[T]](e.splice) } + Converted.Success(t.tree) + } } diff --git a/main-settings/src/main/scala/sbt/std/InputWrapper.scala b/main-settings/src/main/scala/sbt/std/InputWrapper.scala index 0ec3d121d..62384a3e4 100644 --- a/main-settings/src/main/scala/sbt/std/InputWrapper.scala +++ b/main-settings/src/main/scala/sbt/std/InputWrapper.scala @@ -90,19 +90,14 @@ object InputWrapper { def valueMacroImpl[T: c.WeakTypeTag](c: Context): c.Expr[T] = ContextUtil.selectMacroImpl[T](c) { (ts, pos) => - val tpe = ts.tree.tpe - if (tpe <:< c.weakTypeOf[Initialize[Task[T]]]) - InputWrapper.wrapInitTask[T](c)(ts, pos) - else if (tpe <:< c.weakTypeOf[Initialize[T]]) - InputWrapper.wrapInit[T](c)(ts, pos) - else if (tpe <:< c.weakTypeOf[Task[T]]) - InputWrapper.wrapTask[T](c)(ts, pos) - else if (tpe <:< c.weakTypeOf[InputTask[T]]) - InputWrapper.wrapInputTask[T](c)(ts, pos) - else if (tpe <:< c.weakTypeOf[Initialize[InputTask[T]]]) - InputWrapper.wrapInitInputTask[T](c)(ts, pos) - else - c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.widen}") + ts.tree.tpe match { + case tpe if tpe <:< c.weakTypeOf[Initialize[Task[T]]] => InputWrapper.wrapInitTask[T](c)(ts, pos) + case tpe if tpe <:< c.weakTypeOf[Initialize[T]] => InputWrapper.wrapInit[T](c)(ts, pos) + case tpe if tpe <:< c.weakTypeOf[Task[T]] => InputWrapper.wrapTask[T](c)(ts, pos) + case tpe if tpe <:< c.weakTypeOf[InputTask[T]] => InputWrapper.wrapInputTask[T](c)(ts, pos) + case tpe if tpe <:< c.weakTypeOf[Initialize[InputTask[T]]] => InputWrapper.wrapInitInputTask[T](c)(ts, pos) + case tpe => unexpectedType(c)(pos, tpe) + } } def taskValueMacroImpl[T: c.WeakTypeTag](c: Context): c.Expr[Task[T]] = ContextUtil.selectMacroImpl[Task[T]](c) { (ts, pos) => @@ -110,7 +105,7 @@ object InputWrapper { if (tpe <:< c.weakTypeOf[Initialize[Task[T]]]) InputWrapper.wrapInit[Task[T]](c)(ts, pos) else - c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.widen}") + unexpectedType(c)(pos, tpe) } /** Translates .previous(format) to Previous.runtime()(format).value*/ def previousMacroImpl[T: c.WeakTypeTag](c: Context)(format: c.Expr[sbinary.Format[T]]): c.Expr[Option[T]] = @@ -123,10 +118,13 @@ object InputWrapper { val newTree = c.universe.reify { Previous.runtime[T](tsTyped.splice)(format.splice) } wrapPrevious[T](c)(newTree, a.pos) } else - c.abort(a.pos, s"Internal sbt error. Unexpected type ${t.tpe.widen}") + unexpectedType(c)(a.pos, t.tpe) case x => ContextUtil.unexpectedTree(x) } } + + private def unexpectedType(c: Context)(pos: c.Position, tpe: c.Type) = + c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.widen}") } sealed abstract class MacroTaskValue[T] { @@ -177,35 +175,46 @@ object ParserInput { def parsedInputMacroImpl[T: c.WeakTypeTag](c: Context): c.Expr[Task[T]] = ContextUtil.selectMacroImpl[Task[T]](c) { (p, pos) => - import c.universe.reify - val tpe = p.tree.tpe - if (tpe <:< c.weakTypeOf[InputTask[T]]) { - val e = c.Expr[InputTask[T]](p.tree) - wrap[Task[T]](c)(inputParser(c)(e), pos) - } else if (tpe <:< c.weakTypeOf[Initialize[InputTask[T]]]) { - val e = c.Expr[Initialize[InputTask[T]]](p.tree) - wrapInit[Task[T]](c)(reify { Def.toIParser(e.splice) }, pos) - } else - c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.dealias} in parsedInputMacroImpl.") + p.tree.tpe match { + case tpe if tpe <:< c.weakTypeOf[InputTask[T]] => wrapInputTask[T](c)(p.tree, pos) + case tpe if tpe <:< c.weakTypeOf[Initialize[InputTask[T]]] => wrapInitInputTask[T](c)(p.tree, pos) + case tpe => unexpectedType(c)(pos, tpe, "parsedInputMacroImpl") + } } + private def wrapInputTask[T: c.WeakTypeTag](c: Context)(tree: c.Tree, pos: c.Position) = { + val e = c.Expr[InputTask[T]](tree) + wrap[Task[T]](c)(inputParser(c)(e), pos) + } + + private def wrapInitInputTask[T: c.WeakTypeTag](c: Context)(tree: c.Tree, pos: c.Position) = { + val e = c.Expr[Initialize[InputTask[T]]](tree) + wrapInit[Task[T]](c)(c.universe.reify {Def.toIParser(e.splice)}, pos) + } + /** Implements `Parser[T].parsed` by wrapping the Parser with the ParserInput wrapper.*/ def parsedMacroImpl[T: c.WeakTypeTag](c: Context): c.Expr[T] = ContextUtil.selectMacroImpl[T](c) { (p, pos) => - import c.universe.reify - val tpe = p.tree.tpe - if (tpe <:< c.weakTypeOf[Parser[T]]) { - val e = c.Expr[Parser[T]](p.tree) - wrap[T](c)(reify { Def.toSParser(e.splice) }, pos) - } else if (tpe <:< c.weakTypeOf[State => Parser[T]]) - wrap[T](c)(p, pos) - else if (tpe <:< c.weakTypeOf[Initialize[Parser[T]]]) { - val e = c.Expr[Initialize[Parser[T]]](p.tree) - val es = reify { Def.toISParser(e.splice) } - wrapInit[T](c)(es, pos) - } else if (tpe <:< c.weakTypeOf[Initialize[State => Parser[T]]]) - wrapInit[T](c)(p, pos) - else - c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.dealias} in parsedMacroImpl") + p.tree.tpe match { + case tpe if tpe <:< c.weakTypeOf[Parser[T]] => wrapParser[T](c)(p.tree, pos) + case tpe if tpe <:< c.weakTypeOf[State => Parser[T]] => wrap[T](c)(p, pos) + case tpe if tpe <:< c.weakTypeOf[Initialize[Parser[T]]] => wrapInitParser[T](c)(p.tree, pos) + case tpe if tpe <:< c.weakTypeOf[Initialize[State => Parser[T]]] => wrapInit[T](c)(p, pos) + case tpe => unexpectedType(c)(pos, tpe, "parsedMacroImpl") + } } + + private def wrapParser[T: c.WeakTypeTag](c: Context)(tree: c.Tree, pos: c.Position) = { + val e = c.Expr[Parser[T]](tree) + wrap[T](c)(c.universe.reify {Def.toSParser(e.splice)}, pos) + } + + private def wrapInitParser[T: c.WeakTypeTag](c: Context)(tree: c.Tree, pos: c.Position) = { + val e = c.Expr[Initialize[Parser[T]]](tree) + val es = c.universe.reify {Def.toISParser(e.splice)} + wrapInit[T](c)(es, pos) + } + + private def unexpectedType(c: Context)(pos: c.Position, tpe: c.Type, label: String) = + c.abort(pos, s"Internal sbt error. Unexpected type ${tpe.dealias} in $label.") } diff --git a/main-settings/src/main/scala/sbt/std/SettingMacro.scala b/main-settings/src/main/scala/sbt/std/SettingMacro.scala index 5f2ae6d85..3c05c9a8a 100644 --- a/main-settings/src/main/scala/sbt/std/SettingMacro.scala +++ b/main-settings/src/main/scala/sbt/std/SettingMacro.scala @@ -20,16 +20,24 @@ import reflect.macros._ object InitializeConvert extends Convert { def apply[T: c.WeakTypeTag](c: Context)(nme: String, in: c.Tree): Converted[c.type] = - if (nme == InputWrapper.WrapInitName) { + nme match { + case InputWrapper.WrapInitName => convert[T](c)(in) + case InputWrapper.WrapTaskName | InputWrapper.WrapInitTaskName => failTask[c.type](c)(in.pos) + case InputWrapper.WrapPreviousName => failPrevious[c.type](c)(in.pos) + case _ => Converted.NotApplicable + } + + private def convert[T](c: Context)(in: c.Tree): Converted[c.type] = + { val i = c.Expr[Initialize[T]](in) val t = c.universe.reify(i.splice).tree Converted.Success(t) - } else if (nme == InputWrapper.WrapTaskName || nme == InputWrapper.WrapInitTaskName) - Converted.Failure(in.pos, "A setting cannot depend on a task") - else if (nme == InputWrapper.WrapPreviousName) - Converted.Failure(in.pos, "A setting cannot depend on a task's previous value.") - else - Converted.NotApplicable + } + + private def failTask[C <: Context with Singleton](c: C)(pos: c.Position): Converted[c.type] = + Converted.Failure(pos, "A setting cannot depend on a task") + private def failPrevious[C <: Context with Singleton](c: C)(pos: c.Position): Converted[c.type] = + Converted.Failure(pos, "A setting cannot depend on a task's previous value.") } object SettingMacro { diff --git a/main-settings/src/main/scala/sbt/std/TaskMacro.scala b/main-settings/src/main/scala/sbt/std/TaskMacro.scala index 987c7e16b..9679b00d6 100644 --- a/main-settings/src/main/scala/sbt/std/TaskMacro.scala +++ b/main-settings/src/main/scala/sbt/std/TaskMacro.scala @@ -10,6 +10,7 @@ import sbt.internal.util.complete.{ DefaultParsers, Parser } import sbt.internal.util.{ AList, LinePosition, NoPosition, SourcePosition } import language.experimental.macros +import scala.annotation.tailrec import scala.reflect._ import reflect.macros._ import reflect.internal.annotations.compileTimeOnly @@ -236,15 +237,14 @@ object TaskMacro { } private[this] def settingSource(c: Context, path: String, name: String): String = { - val ec = c.enclosingClass.symbol - def inEmptyPackage(s: c.Symbol): Boolean = - s != c.universe.NoSymbol && (s.owner == c.mirror.EmptyPackage || s.owner == c.mirror.EmptyPackageClass || inEmptyPackage(s.owner)) - if (!ec.isStatic) - name - else if (inEmptyPackage(ec)) - path - else - s"(${ec.fullName}) $name" + @tailrec def inEmptyPackage(s: c.Symbol): Boolean = s != c.universe.NoSymbol && ( + s.owner == c.mirror.EmptyPackage || s.owner == c.mirror.EmptyPackageClass || inEmptyPackage(s.owner) + ) + c.enclosingClass.symbol match { + case ec if !ec.isStatic => name + case ec if inEmptyPackage(ec) => path + case ec => s"(${ec.fullName}) $name" + } } private[this] def constant[T: c.TypeTag](c: Context, t: T): c.Expr[T] = { diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index f1d129a45..4025238a9 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -621,12 +621,10 @@ object Defaults extends BuildCommon { val includeFilters = includeArgs map GlobFilter.apply val excludeFilters = excludeArgs.map(_.substring(1)).map(GlobFilter.apply) - if (includeFilters.isEmpty && excludeArgs.isEmpty) { - Seq(const(true)) - } else if (includeFilters.isEmpty) { - Seq({ (s: String) => !matches(excludeFilters, s) }) - } else { - includeFilters.map { f => (s: String) => (f.accept(s) && !matches(excludeFilters, s)) } + (includeFilters, excludeArgs) match { + case (Nil, Nil) => Seq(const(true)) + case (Nil, _) => Seq((s: String) => !matches(excludeFilters, s)) + case _ => includeFilters.map(f => (s: String) => (f.accept(s) && !matches(excludeFilters, s))) } } def detectTests: Initialize[Task[Seq[TestDefinition]]] = (loadedTestFrameworks, compile, streams) map { (frameworkMap, analysis, s) => @@ -1786,8 +1784,11 @@ object Classpaths { a => (Seq[B]() /: maps) { _ ++ _(a) } distinct; def parseList(s: String, allConfs: Seq[String]): Seq[String] = (trim(s split ",") flatMap replaceWildcard(allConfs)).distinct - def replaceWildcard(allConfs: Seq[String])(conf: String): Seq[String] = - if (conf == "") Nil else if (conf == "*") allConfs else conf :: Nil + def replaceWildcard(allConfs: Seq[String])(conf: String): Seq[String] = conf match { + case "" => Nil + case "*" => allConfs + case _ => conf :: Nil + } private def trim(a: Array[String]): List[String] = a.toList.map(_.trim) def missingConfiguration(in: String, conf: String) = diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 3abaeef3a..2963df038 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -461,20 +461,16 @@ object BuiltinCommands { { val result = (SimpleReader.readLine("Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? ") getOrElse Quit).toLowerCase(Locale.ENGLISH) def matches(s: String) = !result.isEmpty && (s startsWith result) + def retry = loadProjectCommand(LoadProject, loadArg) :: s.clearGlobalLog + def ignoreMsg = if (Project.isProjectLoaded(s)) "using previously loaded project" else "no project loaded" - if (result.isEmpty || matches("retry")) - loadProjectCommand(LoadProject, loadArg) :: s.clearGlobalLog - else if (matches(Quit)) - s.exit(ok = false) - else if (matches("ignore")) { - val hadPrevious = Project.isProjectLoaded(s) - s.log.warn("Ignoring load failure: " + (if (hadPrevious) "using previously loaded project." else "no project loaded.")) - s - } else if (matches("last")) - LastCommand :: loadProjectCommand(LoadFailed, loadArg) :: s - else { - println("Invalid response.") - doLoadFailed(s, loadArg) + result match { + case "" => retry + case _ if matches("retry") => retry + case _ if matches(Quit) => s.exit(ok = false) + case _ if matches("ignore") => s.log.warn(s"Ignoring load failure: $ignoreMsg.") ; s + case _ if matches("last") => LastCommand :: loadProjectCommand(LoadFailed, loadArg) :: s + case _ => println("Invalid response."); doLoadFailed(s, loadArg) } } diff --git a/main/src/main/scala/sbt/ScopedKeyData.scala b/main/src/main/scala/sbt/ScopedKeyData.scala index ae5d57b76..0fcc0ebc8 100644 --- a/main/src/main/scala/sbt/ScopedKeyData.scala +++ b/main/src/main/scala/sbt/ScopedKeyData.scala @@ -11,8 +11,13 @@ final case class ScopedKeyData[A](scoped: ScopedKey[A], value: Any) { def description: String = fold(fmtMf("Task: %s"), fmtMf("Input task: %s"), "Setting: %s = %s" format (key.manifest.toString, value.toString)) def fold[T](targ: OptManifest[_] => T, itarg: OptManifest[_] => T, s: => T): T = - if (key.manifest.runtimeClass == classOf[Task[_]]) targ(key.manifest.typeArguments.head) - else if (key.manifest.runtimeClass == classOf[InputTask[_]]) itarg(key.manifest.typeArguments.head) - else s + key.manifest.runtimeClass match { + case TaskClass => targ(key.manifest.typeArguments.head) + case InputTaskClass => itarg(key.manifest.typeArguments.head) + case _ => s + } def fmtMf(s: String): OptManifest[_] => String = s format _ + + private val TaskClass = classOf[Task[_]] + private val InputTaskClass = classOf[InputTask[_]] } diff --git a/main/src/main/scala/sbt/internal/IvyConsole.scala b/main/src/main/scala/sbt/internal/IvyConsole.scala index 3db965653..66e5e0f17 100644 --- a/main/src/main/scala/sbt/internal/IvyConsole.scala +++ b/main/src/main/scala/sbt/internal/IvyConsole.scala @@ -47,12 +47,11 @@ object IvyConsole { final case class Dependencies(managed: Seq[ModuleID], resolvers: Seq[Resolver], unmanaged: Seq[File]) def parseDependencies(args: Seq[String], log: Logger): Dependencies = (Dependencies(Nil, Nil, Nil) /: args)(parseArgument(log)) def parseArgument(log: Logger)(acc: Dependencies, arg: String): Dependencies = - if (arg contains " at ") - acc.copy(resolvers = parseResolver(arg) +: acc.resolvers) - else if (arg endsWith ".jar") - acc.copy(unmanaged = new File(arg) +: acc.unmanaged) - else - acc.copy(managed = parseManaged(arg, log) ++ acc.managed) + arg match { + case _ if arg contains " at " => acc.copy(resolvers = parseResolver(arg) +: acc.resolvers) + case _ if arg endsWith ".jar" => acc.copy(unmanaged = new File(arg) +: acc.unmanaged) + case _ => acc.copy(managed = parseManaged(arg, log) ++ acc.managed) + } private[this] def parseResolver(arg: String): MavenRepository = { diff --git a/main/src/main/scala/sbt/internal/SettingCompletions.scala b/main/src/main/scala/sbt/internal/SettingCompletions.scala index 9f95d6033..4069066eb 100644 --- a/main/src/main/scala/sbt/internal/SettingCompletions.scala +++ b/main/src/main/scala/sbt/internal/SettingCompletions.scala @@ -286,10 +286,13 @@ private[sbt] object SettingCompletions { def keyType[S](key: AttributeKey[_])(onSetting: Manifest[_] => S, onTask: Manifest[_] => S, onInput: Manifest[_] => S)(implicit tm: Manifest[Task[_]], im: Manifest[InputTask[_]]): S = { def argTpe = key.manifest.typeArguments.head - val e = key.manifest.runtimeClass - if (e == tm.runtimeClass) onTask(argTpe) - else if (e == im.runtimeClass) onInput(argTpe) - else onSetting(key.manifest) + val TaskClass = tm.runtimeClass + val InputTaskClass = im.runtimeClass + key.manifest.runtimeClass match { + case TaskClass => onTask(argTpe) + case InputTaskClass => onInput(argTpe) + case _ => onSetting(key.manifest) + } } /** For a Task[T], InputTask[T], or Setting[T], this returns the manifest for T. */ diff --git a/main/src/test/scala/sbt/internal/TestBuild.scala b/main/src/test/scala/sbt/internal/TestBuild.scala index 059a2ad88..72fd594c6 100644 --- a/main/src/test/scala/sbt/internal/TestBuild.scala +++ b/main/src/test/scala/sbt/internal/TestBuild.scala @@ -77,10 +77,11 @@ object TestBuild { global += skey else { val keys = tasks map makeKey - if (keys.size == 1) - single ++= keys - else if (keys.size > 1) - multi ++= keys + keys.size match { + case 0 => + case 1 => single ++= keys + case _ => multi ++= keys + } } } (taskAxes, global.toSet, single.toSet, multi.toSet) diff --git a/testing/src/main/scala/sbt/TestReportListener.scala b/testing/src/main/scala/sbt/TestReportListener.scala index 056e57c47..298a3329b 100644 --- a/testing/src/main/scala/sbt/TestReportListener.scala +++ b/testing/src/main/scala/sbt/TestReportListener.scala @@ -76,10 +76,13 @@ object TestEvent { private[sbt] def overallResult(events: Seq[TEvent]): TestResult.Value = (TestResult.Passed /: events) { (sum, event) => - val status = event.status - if (sum == TestResult.Error || status == TStatus.Error) TestResult.Error - else if (sum == TestResult.Failed || status == TStatus.Failure) TestResult.Failed - else TestResult.Passed + (sum, event.status) match { + case (TestResult.Error, _) => TestResult.Error + case (_, TStatus.Error) => TestResult.Error + case (TestResult.Failed, _) => TestResult.Failed + case (_, TStatus.Failure) => TestResult.Failed + case _ => TestResult.Passed + } } } From f02485b54bbc0e40c9587ce4088175c92514d83c Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 7 Jul 2016 09:35:30 +0100 Subject: [PATCH 7/8] Configure Travis for fast finishing See https://blog.travis-ci.com/2013-11-27-fast-finishing-builds/ --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index c7f69cbfc..06f20523e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,9 @@ jdk: - openjdk7 - oraclejdk7 +matrix: + fast_finish: true + env: matrix: - SBT_CMD="mima-report-binary-issues" From 650f080bacb6a00599c4f0d2878dad8a88c952bb Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 7 Jul 2016 09:47:20 +0100 Subject: [PATCH 8/8] Update mima usage in Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 06f20523e..f81880fd4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ matrix: env: matrix: - - SBT_CMD="mima-report-binary-issues" + - SBT_CMD="mimaReportBinaryIssues" - SBT_CMD="safeUnitTests" - SBT_CMD="otherUnitTests" - SBT_CMD="scripted actions/*"