diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/StackTrace.scala b/internal/util-logging/src/main/scala/sbt/internal/util/StackTrace.scala index 58888e8be..37cc42400 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/StackTrace.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/StackTrace.scala @@ -3,6 +3,9 @@ */ package sbt.internal.util +import sbt.io.IO +import scala.collection.mutable.ListBuffer + object StackTrace { def isSbtClass(name: String) = name.startsWith("sbt.") || name.startsWith("xsbt.") @@ -18,9 +21,9 @@ object StackTrace { * where the line for the Throwable is counted plus one line for each stack element. * Less lines will be included if there are not enough stack elements. */ - def trimmed(t: Throwable, d: Int): String = { + def trimmedLines(t: Throwable, d: Int): List[String] = { require(d >= 0) - val b = new StringBuilder() + val b = new ListBuffer[String]() def appendStackTrace(t: Throwable, first: Boolean): Unit = { @@ -33,16 +36,12 @@ object StackTrace { } def appendElement(e: StackTraceElement): Unit = { - b.append("\tat ") - b.append(e) - b.append('\n') + b.append("\tat " + e) () } - if (!first) - b.append("Caused by: ") - b.append(t) - b.append('\n') + if (!first) b.append("Caused by: " + t.toString) + else b.append(t.toString) val els = t.getStackTrace() var i = 0 @@ -59,7 +58,21 @@ object StackTrace { c = c.getCause() appendStackTrace(c, false) } - b.toString() + b.toList } + /** + * Return a printable representation of the stack trace associated + * with t. Information about t and its Throwable causes is included. + * The number of lines to be included for each Throwable is configured + * via d which should be greater than or equal to 0. + * + * - If d is 0, then all elements are included up to (but not including) + * the first element that comes from sbt. + * - If d is greater than 0, then up to that many lines are included, + * where the line for the Throwable is counted plus one line for each stack element. + * Less lines will be included if there are not enough stack elements. + */ + def trimmed(t: Throwable, d: Int): String = + trimmedLines(t, d).mkString(IO.Newline) }