sbt.LoggerReporter.scala Maven / Gradle / Ivy
/* sbt -- Simple Build Tool
* Copyright 2008, 2009, 2010 Mark Harrah
*/
package sbt
// The following code is based on scala.tools.nsc.reporters.{AbstractReporter, ConsoleReporter, Reporter}
// Copyright 2002-2009 LAMP/EPFL
// see licenses/LICENSE_Scala
// Original author: Martin Odersky
import xsbti.{Maybe,Position,Problem,Reporter,Severity}
import java.io.File
import java.util.EnumMap
import scala.collection.mutable
import LoggerReporter._
import Logger.{m2o,o2m,position,problem}
import Severity.{Error,Info => SInfo,Warn}
object LoggerReporter
{
final class PositionKey(pos: Position)
{
def offset = pos.offset
def sourceFile = pos.sourceFile
override def equals(o: Any) =
o match { case pk: PositionKey => equalsKey(pk); case _ => false }
def equalsKey(o: PositionKey) =
m2o(pos.offset) == m2o(o.offset) &&
m2o(pos.sourceFile) == m2o(o.sourceFile)
override def hashCode =
m2o(pos.offset).hashCode * 31
m2o(pos.sourceFile).hashCode
}
def countElementsAsString(n: Int, elements: String): String =
n match {
case 0 => "no " + elements + "s"
case 1 => "one " + elements
case 2 => "two " + elements + "s"
case 3 => "three " + elements + "s"
case 4 => "four " + elements + "s"
case _ => "" + n + " " + elements + "s"
}
}
class LoggerReporter(maximumErrors: Int, log: Logger, sourcePositionMapper: Position => Position = {p => p}) extends xsbti.Reporter
{
val positions = new mutable.HashMap[PositionKey, Severity]
val count = new EnumMap[Severity, Int](classOf[Severity])
private[this] val allProblems = new mutable.ListBuffer[Problem]
reset()
def reset()
{
count.put(Warn, 0)
count.put(SInfo, 0)
count.put(Error, 0)
positions.clear()
allProblems.clear()
}
def hasWarnings = count.get(Warn) > 0
def hasErrors = count.get(Error) > 0
def problems: Array[Problem] = allProblems.toArray
def comment(pos: Position, msg: String) {}
def printSummary()
{
val warnings = count.get(Severity.Warn)
if(warnings > 0)
log.warn(countElementsAsString(warnings, "warning") + " found")
val errors = count.get(Severity.Error)
if(errors > 0)
log.error(countElementsAsString(errors, "error") + " found")
}
def inc(sev: Severity) = count.put(sev, count.get(sev) + 1)
def display(pos: Position, msg: String, severity: Severity)
{
inc(severity)
if(severity != Error || maximumErrors <= 0 || count.get(severity) <= maximumErrors)
print(severityLogger(severity), pos, msg)
}
def severityLogger(severity: Severity): (=> String) => Unit =
m =>
{
(severity match
{
case Error => log.error(m)
case Warn => log.warn(m)
case SInfo => log.info(m)
})
}
def print(log: (=> String) => Unit, pos: Position, msg: String)
{
if(pos.sourcePath.isEmpty && pos.line.isEmpty)
log(msg)
else
{
val sourcePrefix = m2o(pos.sourcePath).getOrElse("")
val lineNumberString = m2o(pos.line).map(":" + _ + ":").getOrElse(":") + " "
log(sourcePrefix + lineNumberString + msg)
val lineContent = pos.lineContent
if(!lineContent.isEmpty)
{
log(lineContent)
for(space <- m2o(pos.pointerSpace))
log(space + "^") // pointer to the column position of the error/warning
}
}
}
def log(pos: Position, msg: String, severity: Severity): Unit =
{
val mappedPos = sourcePositionMapper(pos)
allProblems += problem("", mappedPos, msg, severity)
severity match
{
case Warn | Error =>
{
if(!testAndLog(mappedPos, severity))
display(mappedPos, msg, severity)
}
case _ => display(mappedPos, msg, severity)
}
}
def testAndLog(pos: Position, severity: Severity): Boolean =
{
if(pos.offset.isEmpty || pos.sourceFile.isEmpty)
false
else
{
val key = new PositionKey(pos)
if(positions.get(key).map(_.ordinal >= severity.ordinal).getOrElse(false))
true
else
{
positions(key) = severity
false
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy