diff options
| author | Andrew Waterman | 2015-08-05 17:40:37 -0700 |
|---|---|---|
| committer | Andrew Waterman | 2015-08-05 17:41:04 -0700 |
| commit | acbf32a806cf5e3e856ff094d08b4db805fb4a56 (patch) | |
| tree | d7ff42b178c71877a1696c333f793e5836e95a8e /src/main/scala/Chisel | |
| parent | 4db92750b4977a9d0fa9be7cb1b5c582c6b82491 (diff) | |
Clean up ChiselError implementation
Diffstat (limited to 'src/main/scala/Chisel')
| -rw-r--r-- | src/main/scala/Chisel/Error.scala | 168 |
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) } |
