Skip to content

sbt bridge reporter #1530

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions bridge/src/main/scala/xsbt/CompilerInterface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ class CachedCompilerImpl(args: Array[String], output: Output, resident: Boolean)
(outputArgs ++ args.toList ++ sources.map(_.getAbsolutePath).sortWith(_ < _)).toArray[String]

def run(sources: Array[File], changes: DependencyChanges, callback: AnalysisCallback, log: Logger, delegate: Reporter, progress: CompileProgress): Unit = synchronized {
run(sources.toList, changes, callback, log, progress)
run(sources.toList, changes, callback, log, delegate, progress)
}
private[this] def run(sources: List[File], changes: DependencyChanges, callback: AnalysisCallback, log: Logger, compileProgress: CompileProgress): Unit = {
private[this] def run(sources: List[File], changes: DependencyChanges, callback: AnalysisCallback, log: Logger, delegate: Reporter, compileProgress: CompileProgress): Unit = {
debug(log, args.mkString("Calling Dotty compiler with arguments (CompilerInterface):\n\t", "\n\t", ""))
val ctx = (new ContextBase).initialCtx.fresh
.setSbtCallback(callback)
.setReporter(new DelegatingReporter(delegate))

val cl = getClass.getClassLoader.asInstanceOf[URLClassLoader]

val reporter = DottyMain.process(commandArguments(sources.toArray), ctx)
Expand Down
58 changes: 58 additions & 0 deletions bridge/src/main/scala/xsbt/DelegatingReporter.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* sbt -- Simple Build Tool
* Copyright 2008, 2009 Mark Harrah
*/
package xsbt

import dotty.tools._
import dotc._
import reporting._
import core.Contexts._

import xsbti.{Maybe, Position}

final class DelegatingReporter(delegate: xsbti.Reporter) extends Reporter
with UniqueMessagePositions
with HideNonSensicalMessages {

override def printSummary(implicit ctx: Context): Unit = delegate.printSummary()

def doReport(d: Diagnostic)(implicit ctx: Context): Unit = {
val severity =
d match {
case _: Reporter.Error => xsbti.Severity.Error
case _: Reporter.Warning => xsbti.Severity.Warn
case _ => xsbti.Severity.Info
}
val pos =
if (d.pos.exists) Some(d.pos)
else None

val file =
if (d.pos.source.file.exists) Option(d.pos.source.file.file)
else None

val offset0 = pos.map(_.point)

val position = new Position {
def line: Maybe[Integer] = maybe(pos.map(_.line))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe[Int] and Maybe[Integer] are the same thing so just use Maybe[Int]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

def lineContent: String = pos.map(_.lineContent).getOrElse("")
def offset: Maybe[Integer] = maybeInt(offset0)
def pointer: Maybe[Integer] = offset
def pointerSpace: Maybe[String] = maybe(offset0.map(" " * _))
def sourceFile: Maybe[java.io.File] = maybe(file)
def sourcePath: Maybe[String] = maybe(file.map(_.getPath))
}

delegate.log(position, d.message, severity)
}

private[this] def maybe[T](opt: Option[T]): Maybe[T] = opt match {
case None => Maybe.nothing[T]
case Some(s) => Maybe.just[T](s)
}
import java.lang.{ Integer => I }
private[this] def maybeInt(opt: Option[Int]): Maybe[I] = opt match {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is unnecessary, just use maybe above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the compiler fails to infer with only maybe

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then write maybe[Int], please open an issue for this too if this is an issue specific to dotty

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scalac:

trait Position {
  def offset(): Integer  
}

object A {
  val p = new Position {
    def offset(): Int = 1
  }
}

overriding method offset in trait Position of type ()Integer;
method offset has incompatible type

case None => Maybe.nothing[I]
case Some(s) => Maybe.just[I](s)
}
}
10 changes: 10 additions & 0 deletions bridge/src/sbt-test/compilerReporter/simple/Source.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
trait A
trait B

trait Wr {
val z: A with B
}

object Er {
val a = er1
}
1 change: 1 addition & 0 deletions bridge/src/sbt-test/compilerReporter/simple/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reporter.checkSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import sbt._
import Keys._

object DottyInjectedPlugin extends AutoPlugin {
override def requires = plugins.JvmPlugin
override def trigger = allRequirements

override val projectSettings = Seq(
scalaVersion := "0.1-SNAPSHOT",
scalaOrganization := "ch.epfl.lamp",
scalacOptions += "-language:Scala2",
scalaBinaryVersion := "2.11",
autoScalaLibrary := false,
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
)
}
44 changes: 44 additions & 0 deletions bridge/src/sbt-test/compilerReporter/simple/project/Reporter.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import sbt._
import Keys._
import KeyRanks.DTask

object Reporter {
import xsbti.{Reporter, Problem, Position, Severity, Maybe}

lazy val check = TaskKey[Unit]("check", "make sure compilation info are forwared to sbt")

// compilerReporter is marked private in sbt
lazy val compilerReporter = TaskKey[Option[xsbti.Reporter]]("compilerReporter", "Experimental hook to listen (or send) compilation failure messages.", DTask)

lazy val reporter =
Some(new xsbti.Reporter {
private val buffer = collection.mutable.ArrayBuffer.empty[Problem]
def reset(): Unit = buffer.clear()
def hasErrors: Boolean = buffer.exists(_.severity == Severity.Error)
def hasWarnings: Boolean = buffer.exists(_.severity == Severity.Warn)
def printSummary(): Unit = println(problems.mkString(System.lineSeparator))
def problems: Array[Problem] = buffer.toArray
def log(pos: Position, msg: String, sev: Severity): Unit = {
object MyProblem extends Problem {
def category: String = null
def severity: Severity = sev
def message: String = msg
def position: Position = pos
override def toString = s"custom: $position:$severity: $message"
}
buffer.append(MyProblem)
}
def comment(pos: xsbti.Position, msg: String): Unit = ()
})

lazy val checkSettings = Seq(
compilerReporter in (Compile, compile) := reporter,
check <<= (compile in Compile).mapFailure( _ => {
val problems = reporter.get.problems
println(problems.toList)
assert(problems.size == 2)
assert(problems.count(_.severity == Severity.Error) == 1) // not found: er1,
assert(problems.count(_.severity == Severity.Warn) == 1) // `with' as a type operator has been deprecated; use `&' instead,
})
)
}
1 change: 1 addition & 0 deletions bridge/src/sbt-test/compilerReporter/simple/test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
> check
20 changes: 20 additions & 0 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,31 @@ object DottyBuild extends Build {
).
settings(publishing)

// until sbt/sbt#2402 is fixed (https://github.com/sbt/sbt/issues/2402)
lazy val cleanSbtBridge = TaskKey[Unit]("cleanSbtBridge", "delete dotty-sbt-bridge cache")

lazy val `dotty-bridge` = project.in(file("bridge")).
dependsOn(dotty).
settings(
overrideScalaVersionSetting,

cleanSbtBridge := {
val dottyBridgeVersion = version.value
val dottyVersion = (version in dotty).value
val classVersion = System.getProperty("java.class.version")

val sbtV = sbtVersion.value
val sbtOrg = "org.scala-sbt"
val sbtScalaVersion = "2.10.6"

val home = System.getProperty("user.home")
val org = organization.value
val artifact = moduleName.value

IO.delete(file(home) / ".ivy2" / "cache" / sbtOrg / s"$org-$artifact-$dottyBridgeVersion-bin_${dottyVersion}__$classVersion")
IO.delete(file(home) / ".sbt" / "boot" / s"scala-$sbtScalaVersion" / sbtOrg / "sbt" / sbtV / s"$org-$artifact-$dottyBridgeVersion-bin_${dottyVersion}__$classVersion")
},
publishLocal := (publishLocal.dependsOn(cleanSbtBridge)).value,
description := "sbt compiler bridge for Dotty",
resolvers += Resolver.typesafeIvyRepo("releases"),
libraryDependencies ++= Seq(
Expand Down