summaryrefslogtreecommitdiff
path: root/src/main/scala/Chisel/Error.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/Chisel/Error.scala')
-rw-r--r--src/main/scala/Chisel/Error.scala168
1 files changed, 55 insertions, 113 deletions
diff --git a/src/main/scala/Chisel/Error.scala b/src/main/scala/Chisel/Error.scala
index 578dd1de..34544f12 100644
--- a/src/main/scala/Chisel/Error.scala
+++ b/src/main/scala/Chisel/Error.scala
@@ -34,11 +34,8 @@ import scala.collection.mutable.ArrayBuffer
class ChiselException(message: String, cause: Throwable) extends Exception(message, cause)
object throwException {
- def apply(s: String, t: Throwable = null) = {
- val xcpt = new ChiselException(s, t)
- ChiselError.findFirstUserLine(xcpt.getStackTrace) foreach { u => xcpt.setStackTrace(Array(u)) }
- throw xcpt
- }
+ def apply(s: String, t: Throwable = null) =
+ throw new ChiselException(s, t)
}
/** This Singleton implements a log4j compatible interface.
@@ -49,131 +46,76 @@ object ChiselError {
val startTime = System.currentTimeMillis
def elapsedTime: Long = System.currentTimeMillis - startTime
- var hasErrors: Boolean = false;
- val ChiselErrors = new ArrayBuffer[ChiselError];
- def clear() {
- ChiselErrors.clear()
- hasErrors = false
- }
+ def hasErrors = errors.exists(_.isFatal)
- /** emit an error message */
- def error(mf: => String, line: StackTraceElement) {
- hasErrors = true
- ChiselErrors += new ChiselError(() => mf, line)
- }
+ def clear(): Unit = errors.clear
- def error(m: String) {
- val stack = Thread.currentThread().getStackTrace
- error(m, findFirstUserLine(stack) getOrElse stack(0))
- }
+ /** Log an error message */
+ def error(m: => String): Unit =
+ errors += new Error(m, getUserLineNumber)
- /** Emit an informational message
- (useful to track long running passes) */
- def info(m: String): Unit =
- println(tag("info", Console.MAGENTA) + " [%2.3f] ".format(elapsedTime/1e3) + m)
+ /** Log a warning message */
+ def warning(m: => String): Unit =
+ errors += new Warning(m, getUserLineNumber)
- /** emit a warning message */
- def warning(m: => String) {
- val stack = Thread.currentThread().getStackTrace
- ChiselErrors += new ChiselError(() => m,
- findFirstUserLine(stack) getOrElse stack(0), 1)
- }
+ /** Emit an informational message */
+ def info(m: String): Unit =
+ println(new Info(" [%2.3f] %s".format(elapsedTime/1e3, m), None))
- def findFirstUserLine(stack: Array[StackTraceElement]): Option[StackTraceElement] = {
- findFirstUserInd(stack) map { stack(_) }
+ /** Prints error messages generated by Chisel at runtime. */
+ def report(): Unit = errors foreach println
+
+ /** Throw an exception if any errors have yet occurred. */
+ def checkpoint(): Unit = if(hasErrors) {
+ import Console._
+ throw new IllegalStateException(
+ UNDERLINED + "CODE HAS " + errors.filter(_.isFatal).length + RESET +
+ UNDERLINED + " " + RED + "ERRORS" + RESET +
+ UNDERLINED + " and " + errors.filterNot(_.isFatal).length + RESET +
+ UNDERLINED + " " + YELLOW + "WARNINGS" + RESET)
}
- def findFirstUserInd(stack: Array[StackTraceElement]): Option[Int] = {
+ private def findFirstUserFrame(stack: Array[StackTraceElement]): Option[StackTraceElement] = {
def isUserCode(ste: StackTraceElement): Boolean = {
- val className = ste.getClassName()
- try {
- val cls = Class.forName(className)
- if( cls.getSuperclass() == classOf[Module] ) {
- true
- } else {
- /* XXX Do it the old way until we figure if it is safe
- to remove from Node.scala
- var line: StackTraceElement = findFirstUserLine(Thread.currentThread().getStackTrace)
- */
- val dotPos = className.lastIndexOf('.')
- if( dotPos > 0 ) {
- (className.subSequence(0, dotPos) != "Chisel") && !className.contains("scala") &&
- !className.contains("java") && !className.contains("$$")
- } else {
- false
- }
- }
- } catch {
- case e: java.lang.ClassNotFoundException => false
- }
- }
- val idx = stack.indexWhere(isUserCode)
- if(idx < 0) {
- println("COULDN'T FIND LINE NUMBER (" + stack(1) + ")")
- None
- } else {
- Some(idx)
+ def isUserModule(c: Class[_]): Boolean =
+ c != null && (c == classOf[Module] || isUserModule(c.getSuperclass))
+ isUserModule(Class.forName(ste.getClassName))
}
- }
- // Print stack frames up to and including the "user" stack frame.
- def printChiselStackTrace() {
- val stack = Thread.currentThread().getStackTrace
- val idx = ChiselError.findFirstUserInd(stack)
- idx match {
- case None => {}
- case Some(x) => for (i <- 0 to x) println(stack(i))
+ stack.indexWhere(isUserCode) match {
+ case x if x < 0 => None
+ case x => Some(stack(x))
}
}
- /** Prints error messages generated by Chisel at runtime. */
- def report() {
- if (!ChiselErrors.isEmpty) {
- for(err <- ChiselErrors) err.print;
- }
- }
+ private def getUserLineNumber =
+ findFirstUserFrame(Thread.currentThread().getStackTrace)
- /** Throws an exception if there has been any error recorded
- before this point. */
- def checkpoint() {
- if(hasErrors) {
- throw new IllegalStateException(
- Console.UNDERLINED + "CODE HAS " +
- Console.UNDERLINED + Console.BOLD + ChiselErrors.filter(_.isError).length + Console.RESET +
- Console.UNDERLINED + " " +
- Console.UNDERLINED + Console.RED + "ERRORS" + Console.RESET +
- Console.UNDERLINED + " and " +
- Console.UNDERLINED + Console.BOLD + ChiselErrors.filter(_.isWarning).length + Console.RESET +
- Console.UNDERLINED + " " +
- Console.UNDERLINED + Console.YELLOW + "WARNINGS" + Console.RESET)
- }
+ private val errors = ArrayBuffer[LogEntry]()
+}
+
+abstract class LogEntry(msg: => String, line: Option[StackTraceElement]) {
+ def isFatal: Boolean = false
+ def format: String
+
+ override def toString: String = line match {
+ case Some(l) => s"${format} ${l.getFileName}:${l.getLineNumber}: ${msg} in class ${l.getClassName}"
+ case None => s"${format}: ${msg}"
}
- def tag(name: String, color: String): String =
+ protected def tag(name: String, color: String): String =
s"[${color}${name}${Console.RESET}]"
}
-class ChiselError(val errmsgFun: () => String, val errline: StackTraceElement,
-val errlevel: Int = 0) {
-
- val level = errlevel
- val line = errline
- val msgFun = errmsgFun
-
- def isError = (level == 0)
- def isWarning = (level == 1)
-
- def print() {
- /* Following conventions for error formatting */
- val levelstr =
- if (isError) ChiselError.tag("error", Console.RED)
- else ChiselError.tag("warn", Console.YELLOW)
- if( line != null ) {
- println(levelstr + " " + line.getFileName + ":" +
- line.getLineNumber + ": " + msgFun() +
- " in class " + line.getClassName)
- } else {
- println(levelstr + ": " + msgFun())
- }
- }
+class Error(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) {
+ override def isFatal = true
+ def format = tag("error", Console.RED)
+}
+
+class Warning(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) {
+ def format = tag("warn", Console.YELLOW)
+}
+
+class Info(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) {
+ def format = tag("info", Console.MAGENTA)
}