Skip to content

Commit

Permalink
Logger reporter uses event logging
Browse files Browse the repository at this point in the history
  • Loading branch information
eed3si9n committed Feb 17, 2017
1 parent 0dee711 commit 8fef6c8
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,48 @@ package xsbt

import xsbti.{ F0, Logger, Maybe }
import java.io.File
import sbt.util.InterfaceUtil.o2jo
import java.util.Optional

private object DelegatingReporter {
def apply(settings: scala.tools.nsc.Settings, delegate: xsbti.Reporter): DelegatingReporter =
new DelegatingReporter(Command.getWarnFatal(settings), Command.getNoWarn(settings), delegate)

class PositionImpl(sourcePath0: Option[String], sourceFile0: Option[File],
line0: Option[Int], lineContent0: String, offset0: Option[Int], pointer0: Option[Int], pointerSpace0: Option[String]) extends xsbti.Position {
val line = o2oi(line0)
val lineContent = lineContent0
val offset = o2oi(offset0)
val sourcePath = o2jo(sourcePath0)
val sourceFile = o2jo(sourceFile0)
val pointer = o2oi(pointer0)
val pointerSpace = o2jo(pointerSpace0)
override def toString =
(sourcePath0, line0) match {
case (Some(s), Some(l)) => s + ":" + l
case (Some(s), _) => s + ":"
case _ => ""
}
}

import java.lang.{ Integer => I }
private[xsbt] def o2oi(opt: Option[Int]): Optional[I] =
opt match {
case Some(s) => Optional.ofNullable[I](s: I)
case None => Optional.empty[I]
}
private[xsbt] def o2jo[A](o: Option[A]): Optional[A] =
o match {
case Some(v) => Optional.ofNullable(v)
case None => Optional.empty[A]()
}
}

// The following code is based on scala.tools.nsc.reporters.{AbstractReporter, ConsoleReporter}
// Copyright 2002-2009 LAMP/EPFL
// Original author: Martin Odersky
private final class DelegatingReporter(warnFatal: Boolean, noWarn: Boolean, private[this] var delegate: xsbti.Reporter) extends scala.tools.nsc.reporters.Reporter {
import scala.tools.nsc.util.{ FakePos, NoPosition, Position }

import DelegatingReporter._
def dropDelegate(): Unit = { delegate = null }
def error(msg: String): Unit = error(FakePos("scalac"), msg)

Expand All @@ -42,16 +70,15 @@ private final class DelegatingReporter(warnFatal: Boolean, noWarn: Boolean, priv
}
def convert(posIn: Position): xsbti.Position =
{
val pos =
posIn match {
case null | NoPosition => NoPosition
case x: FakePos => x
case x =>
posIn.inUltimateSource(posIn.source)
val posOpt =
Option(posIn) match {
case None | Some(NoPosition) => None
case Some(x: FakePos) => None
case x => Option(posIn.finalPosition)
}
pos match {
case NoPosition | FakePos(_) => position(None, None, None, "", None, None, None)
case _ => makePosition(pos)
posOpt match {
case None => position(None, None, None, "", None, None, None)
case Some(pos) => makePosition(pos)
}
}
private[this] def makePosition(pos: Position): xsbti.Position =
Expand All @@ -64,7 +91,7 @@ private final class DelegatingReporter(warnFatal: Boolean, noWarn: Boolean, priv
val offset = getOffset(pos)
val pointer = offset - src.lineToOffset(src.offsetToLine(offset))
val pointerSpace = ((lineContent: Seq[Char]).take(pointer).map { case '\t' => '\t'; case x => ' ' }).mkString
position(Some(sourcePath), Some(sourceFile), Some(line), lineContent, Some(offset), Some(pointer), Some(pointerSpace))
position(Option(sourcePath), Option(sourceFile), Option(line), lineContent, Option(offset), Option(pointer), Option(pointerSpace))
}
private[this] def getOffset(pos: Position): Int =
{
Expand All @@ -74,21 +101,7 @@ private final class DelegatingReporter(warnFatal: Boolean, noWarn: Boolean, priv
pos.point
}
private[this] def position(sourcePath0: Option[String], sourceFile0: Option[File], line0: Option[Int], lineContent0: String, offset0: Option[Int], pointer0: Option[Int], pointerSpace0: Option[String]) =
new xsbti.Position {
val line = o2oi(line0)
val lineContent = lineContent0
val offset = o2oi(offset0)
val sourcePath = o2jo(sourcePath0)
val sourceFile = o2jo(sourceFile0)
val pointer = o2oi(pointer0)
val pointerSpace = o2jo(pointerSpace0)
override def toString =
(sourcePath0, line0) match {
case (Some(s), Some(l)) => s + ":" + l
case (Some(s), _) => s + ":"
case _ => ""
}
}
new PositionImpl(sourcePath0, sourceFile0, line0, lineContent0, offset0, pointer0, pointerSpace0)

import xsbti.Severity.{ Info, Warn, Error }
private[this] def convert(sev: Severity): xsbti.Severity =
Expand All @@ -97,7 +110,4 @@ private final class DelegatingReporter(warnFatal: Boolean, noWarn: Boolean, priv
case WARNING => Warn
case ERROR => Error
}

import java.lang.{ Integer => I }
private[this] def o2oi(opt: Option[Int]): Optional[I] = opt match { case None => Optional.empty[I]; case Some(s) => Optional.ofNullable[I](s) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,48 @@
package xsbt

import java.io.File
import sbt.util.InterfaceUtil.o2jo
import java.util.Optional

private object DelegatingReporter {
def apply(settings: scala.tools.nsc.Settings, delegate: xsbti.Reporter): DelegatingReporter =
new DelegatingReporter(Command.getWarnFatal(settings), Command.getNoWarn(settings), delegate)

class PositionImpl(sourcePath0: Option[String], sourceFile0: Option[File],
line0: Option[Int], lineContent0: String, offset0: Option[Int], pointer0: Option[Int], pointerSpace0: Option[String]) extends xsbti.Position {
val line = o2oi(line0)
val lineContent = lineContent0
val offset = o2oi(offset0)
val sourcePath = o2jo(sourcePath0)
val sourceFile = o2jo(sourceFile0)
val pointer = o2oi(pointer0)
val pointerSpace = o2jo(pointerSpace0)
override def toString =
(sourcePath0, line0) match {
case (Some(s), Some(l)) => s + ":" + l
case (Some(s), _) => s + ":"
case _ => ""
}
}

import java.lang.{ Integer => I }
private[xsbt] def o2oi(opt: Option[Int]): Optional[I] =
opt match {
case Some(s) => Optional.ofNullable[I](s: I)
case None => Optional.empty[I]
}
private[xsbt] def o2jo[A](o: Option[A]): Optional[A] =
o match {
case Some(v) => Optional.ofNullable(v)
case None => Optional.empty[A]()
}
}

// The following code is based on scala.tools.nsc.reporters.{AbstractReporter, ConsoleReporter}
// Copyright 2002-2009 LAMP/EPFL
// Original author: Martin Odersky
private final class DelegatingReporter(warnFatal: Boolean, noWarn: Boolean, private[this] var delegate: xsbti.Reporter) extends scala.tools.nsc.reporters.Reporter {
import scala.reflect.internal.util.{ FakePos, NoPosition, Position }

import DelegatingReporter._
def dropDelegate(): Unit = { delegate = null }
def error(msg: String): Unit = error(FakePos("scalac"), msg)

Expand All @@ -45,16 +73,15 @@ private final class DelegatingReporter(warnFatal: Boolean, noWarn: Boolean, priv
}
def convert(posIn: Position): xsbti.Position =
{
val pos =
posIn match {
case null | NoPosition => NoPosition
case x: FakePos => x
case x =>
posIn.finalPosition
val posOpt =
Option(posIn) match {
case None | Some(NoPosition) => None
case Some(x: FakePos) => None
case x => Option(posIn.finalPosition)
}
pos match {
case NoPosition | FakePos(_) => position(None, None, None, "", None, None, None)
case _ => makePosition(pos)
posOpt match {
case None => new PositionImpl(None, None, None, "", None, None, None)
case Some(pos) => makePosition(pos)
}
}
private[this] def makePosition(pos: Position): xsbti.Position =
Expand All @@ -67,23 +94,7 @@ private final class DelegatingReporter(warnFatal: Boolean, noWarn: Boolean, priv
val offset = pos.point
val pointer = offset - src.lineToOffset(src.offsetToLine(offset))
val pointerSpace = ((lineContent: Seq[Char]).take(pointer).map { case '\t' => '\t'; case x => ' ' }).mkString
position(Option(sourcePath), Option(sourceFile), Some(line), lineContent, Some(offset), Some(pointer), Some(pointerSpace))
}
private[this] def position(sourcePath0: Option[String], sourceFile0: Option[File], line0: Option[Int], lineContent0: String, offset0: Option[Int], pointer0: Option[Int], pointerSpace0: Option[String]) =
new xsbti.Position {
val line = o2oi(line0)
val lineContent = lineContent0
val offset = o2oi(offset0)
val sourcePath = o2jo(sourcePath0)
val sourceFile = o2jo(sourceFile0)
val pointer = o2oi(pointer0)
val pointerSpace = o2jo(pointerSpace0)
override def toString =
(sourcePath0, line0) match {
case (Some(s), Some(l)) => s + ":" + l
case (Some(s), _) => s + ":"
case _ => ""
}
new PositionImpl(Option(sourcePath), Option(sourceFile), Option(line), lineContent, Option(offset), Option(pointer), Option(pointerSpace))
}

import xsbti.Severity.{ Info, Warn, Error }
Expand All @@ -93,7 +104,4 @@ private final class DelegatingReporter(warnFatal: Boolean, noWarn: Boolean, priv
case WARNING => Warn
case ERROR => Error
}

import java.lang.{ Integer => I }
private[this] def o2oi(opt: Option[Int]): Optional[I] = opt match { case None => Optional.empty[I]; case Some(s) => Optional.ofNullable[I](s) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import java.util.EnumMap
import scala.collection.mutable
import LoggerReporter._
import sbt.internal.util.ManagedLogger
import sbt.internal.util.codec._
import sbt.util.InterfaceUtil.{ jo2o, problem }
import Severity.{ Error, Info => SInfo, Warn }

Expand Down Expand Up @@ -47,13 +48,18 @@ object LoggerReporter {
case 4 => "four " + elements + "s"
case _ => "" + n + " " + elements + "s"
}

lazy val problemFormats: ProblemFormats = new ProblemFormats with SeverityFormats with PositionFormats with sjsonnew.BasicJsonProtocol {}
lazy val problemStringFormats: ProblemStringFormats = new ProblemStringFormats {}
}

class LoggerReporter(maximumErrors: Int, log: ManagedLogger, sourcePositionMapper: Position => Position = { p => p }) extends xsbti.Reporter {
class LoggerReporter(maximumErrors: Int, logger: ManagedLogger, 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]

import problemStringFormats._
logger.registerStringCodec[Problem]
reset()

def reset(): Unit = {
Expand All @@ -68,69 +74,48 @@ class LoggerReporter(maximumErrors: Int, log: ManagedLogger, sourcePositionMappe
def problems: Array[Problem] = allProblems.toArray
def comment(pos: Position, msg: String): Unit = ()

override def log(pos: Position, msg: String, severity: Severity): Unit =
{
val mappedPos: Position = sourcePositionMapper(pos)
val p = problem("", mappedPos, msg, severity)
allProblems += p
severity match {
case Warn | Error =>
{
if (!testAndLog(mappedPos, severity))
display(p)
}
case _ => display(p)
}
}

def printSummary(): Unit = {
val warnings = count.get(Severity.Warn)
if (warnings > 0)
log.warn(countElementsAsString(warnings, "warning") + " found")
logger.warn(countElementsAsString(warnings, "warning") + " found")
val errors = count.get(Severity.Error)
if (errors > 0)
log.error(countElementsAsString(errors, "error") + " found")
logger.error(countElementsAsString(errors, "error") + " found")
}

def inc(sev: Severity) = count.put(sev, count.get(sev) + 1)
private def inc(sev: Severity) = count.put(sev, count.get(sev) + 1)

def display(pos: Position, msg: String, severity: Severity): Unit =
private def display(p: Problem): Unit =
{
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): Unit = {
if (!pos.sourcePath.isPresent && !pos.line.isPresent)
log(msg)
else {
val sourcePrefix = jo2o(pos.sourcePath).getOrElse("")
val columnNumber = jo2o(pos.pointer).map(_.toInt + 1).getOrElse(1)
val lineNumberString = jo2o(pos.line).map(":" + _ + ":" + columnNumber + ":").getOrElse(":") + " "
log(sourcePrefix + lineNumberString + msg)
val lineContent = pos.lineContent
if (!lineContent.isEmpty) {
log(lineContent)
for (space <- jo2o(pos.pointerSpace))
log(space + "^") // pointer to the column position of the error/warning
}
}
}

override 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)
import problemFormats._
inc(p.severity)
if (p.severity != Error || maximumErrors <= 0 || count.get(p.severity) <= maximumErrors) {
p.severity match {
case Error => logger.errorEvent(p)
case Warn => logger.warnEvent(p)
case SInfo => logger.infoEvent(p)
}
}
}

def testAndLog(pos: Position, severity: Severity): Boolean =
private def testAndLog(pos: Position, severity: Severity): Boolean =
{
if (!pos.offset.isPresent || !pos.sourceFile.isPresent)
false
if (!pos.offset.isPresent || !pos.sourceFile.isPresent) false
else {
val key = new PositionKey(pos)
if (positions.get(key).exists(_.ordinal >= severity.ordinal))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package sbt
package internal
package inc

import xsbti.Problem
import sbt.util.ShowLines
import sbt.util.InterfaceUtil.jo2o

/**
* The string representation of compiler warnings and error messages,
* used by LoggerReporter and the logging system.
*/
trait ProblemStringFormats {
implicit lazy val ProblemStringFormat: ShowLines[Problem] = new ShowLines[Problem] {
def showLines(p: Problem): Seq[String] =
p match {
case p if !p.position.sourcePath.isPresent && !p.position.line.isPresent => Vector(p.message)
case _ =>
val pos = p.position
val sourcePrefix = jo2o(pos.sourcePath).getOrElse("")
val columnNumber = jo2o(pos.pointer).map(_.toInt + 1).getOrElse(1)
val lineNumberString = jo2o(pos.line).map(":" + _ + ":" + columnNumber + ":").getOrElse(":") + " "
val line1 = sourcePrefix + lineNumberString + p.message
val lineContent = pos.lineContent
if (!lineContent.isEmpty) {
Vector(line1, lineContent) ++
(for { space <- jo2o(pos.pointerSpace) }
yield (space + "^")).toVector // pointer to the column position of the error/warning
} else Vector(line1)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* This code is generated using sbt-datatype.
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
*/

// DO NOT EDIT MANUALLY
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* This code is generated using sbt-datatype.
* This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]].
*/

// DO NOT EDIT MANUALLY
Expand Down
Loading

0 comments on commit 8fef6c8

Please sign in to comment.