Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

146 lines (131 sloc) 3.74 kb
/* 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) 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 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 =
{
allProblems += problem("", pos, msg, severity)
severity match
{
case Warn | Error =>
{
if(!testAndLog(pos, severity))
display(pos, msg, severity)
}
case _ => display(pos, 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
}
}
}
}
Jump to Line
Something went wrong with that request. Please try again.