summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala
diff options
context:
space:
mode:
authorSchuyler Eldridge2020-03-11 14:42:22 -0400
committerSchuyler Eldridge2020-03-19 12:41:04 -0400
commit73974725f09338e265733c93866fd15e76a2bdd0 (patch)
treeda6b766b43e11fa97eb5d8e9a8b3269279fce8fb /chiselFrontend/src/main/scala
parentd67c4100bd9e24cb9337ad932ba342fd5c49dee4 (diff)
Report trimmed stack trace of Builder cause
Changes the behavior of ChiselException stack trace trimming to use either the first exception that includes a method from the Builder or the outer exception. Signed-off-by: Schuyler Eldridge <schuyler.eldridge@ibm.com>
Diffstat (limited to 'chiselFrontend/src/main/scala')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/Error.scala53
1 files changed, 46 insertions, 7 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Error.scala b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala
index 91d9d7de..0108237a 100644
--- a/chiselFrontend/src/main/scala/chisel3/internal/Error.scala
+++ b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala
@@ -2,6 +2,7 @@
package chisel3.internal
+import scala.annotation.tailrec
import scala.collection.mutable.{ArrayBuffer, LinkedHashMap}
class ChiselException(message: String, cause: Throwable = null) extends Exception(message, cause) {
@@ -9,27 +10,65 @@ class ChiselException(message: String, cause: Throwable = null) extends Exceptio
val blacklistPackages = Set("chisel3", "scala", "java", "sun", "sbt")
val builderName = "chisel3.internal.Builder"
- /** trims the top of the stack of elements belonging to [[blacklistPackages]]
- * then trims the bottom elements until it reaches [[builderName]]
- * then continues trimming elements belonging to [[blacklistPackages]]
+ /** Examine a [[Throwable]], recursively searching it's causes, for the first [[Throwable]] that contains a stack
+ * trace including a specific class name.
+ * @param throwable the root exception
+ * @param className a class name string to search for
+ * @return [[Some]] exception if the class name was found, [[None]] otherwise
*/
- def trimmedStackTrace: Array[StackTraceElement] = {
+ @tailrec
+ private def findCause(throwable: Throwable, className: String): Option[Throwable] =
+ throwable.getStackTrace().collectFirst {
+ case ste if ste.getClassName().startsWith(className) => throwable
+ } match {
+ case a: Some[_] => a
+ case None => throwable.getCause() match {
+ case null => None
+ case cause: Throwable => findCause(cause, className)
+ }
+ }
+
+ private lazy val likelyCause: Throwable = findCause(this, builderName) match {
+ case Some(a) => a
+ case None => this
+ }
+
+ /** For an exception, return a stack trace trimmed to user code only
+ *
+ * This does the following actions:
+ *
+ * 1. Trims the top of the stack trace while elements match [[blacklistPackages]]
+ * 2. Trims the bottom of the stack trace until an element matches [[builderName]]
+ * 3. Trims from the [[builderName]] all [[blacklistPackages]]
+ *
+ * @param throwable the exception whose stack trace should be trimmed
+ * @return an array of stack trace elements
+ */
+ private def trimmedStackTrace(throwable: Throwable): Array[StackTraceElement] = {
def isBlacklisted(ste: StackTraceElement) = {
val packageName = ste.getClassName().takeWhile(_ != '.')
blacklistPackages.contains(packageName)
}
- val trimmedLeft = getStackTrace().view.dropWhile(isBlacklisted)
+ val trimmedLeft = throwable.getStackTrace().view.dropWhile(isBlacklisted)
val trimmedReverse = trimmedLeft.reverse
.dropWhile(ste => !ste.getClassName.startsWith(builderName))
.dropWhile(isBlacklisted)
trimmedReverse.reverse.toArray
}
+ /** trims the top of the stack of elements belonging to [[blacklistPackages]]
+ * then trims the bottom elements until it reaches [[builderName]]
+ * then continues trimming elements belonging to [[blacklistPackages]]
+ */
+ @deprecated("This method will be removed in 3.4", "3.3")
+ def trimmedStackTrace: Array[StackTraceElement] = trimmedStackTrace(this)
+
def chiselStackTrace: String = {
- val trimmed = trimmedStackTrace
+ val trimmed = trimmedStackTrace(likelyCause)
+
val sw = new java.io.StringWriter
- sw.write(toString + "\n")
+ sw.write(likelyCause.toString + "\n")
sw.write("\t...\n")
trimmed.foreach(ste => sw.write(s"\tat $ste\n"))
sw.write("\t... (Stack trace trimmed to user code only, rerun with --full-stacktrace if you wish to see the full stack trace)\n") // scalastyle:ignore line.size.limit