Skip to content

Commit a27ac72

Browse files
authored
Merge pull request #1530 from MasseGuillaume/feature/sbt-bridge-reporter
sbt bridge reporter
2 parents a83d436 + 1e2bbb2 commit a27ac72

File tree

8 files changed

+155
-2
lines changed

8 files changed

+155
-2
lines changed

bridge/src/main/scala/xsbt/CompilerInterface.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,14 @@ class CachedCompilerImpl(args: Array[String], output: Output, resident: Boolean)
5050
(outputArgs ++ args.toList ++ sources.map(_.getAbsolutePath).sortWith(_ < _)).toArray[String]
5151

5252
def run(sources: Array[File], changes: DependencyChanges, callback: AnalysisCallback, log: Logger, delegate: Reporter, progress: CompileProgress): Unit = synchronized {
53-
run(sources.toList, changes, callback, log, progress)
53+
run(sources.toList, changes, callback, log, delegate, progress)
5454
}
55-
private[this] def run(sources: List[File], changes: DependencyChanges, callback: AnalysisCallback, log: Logger, compileProgress: CompileProgress): Unit = {
55+
private[this] def run(sources: List[File], changes: DependencyChanges, callback: AnalysisCallback, log: Logger, delegate: Reporter, compileProgress: CompileProgress): Unit = {
5656
debug(log, args.mkString("Calling Dotty compiler with arguments (CompilerInterface):\n\t", "\n\t", ""))
5757
val ctx = (new ContextBase).initialCtx.fresh
5858
.setSbtCallback(callback)
59+
.setReporter(new DelegatingReporter(delegate))
60+
5961
val cl = getClass.getClassLoader.asInstanceOf[URLClassLoader]
6062

6163
val reporter = DottyMain.process(commandArguments(sources.toArray), ctx)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/* sbt -- Simple Build Tool
2+
* Copyright 2008, 2009 Mark Harrah
3+
*/
4+
package xsbt
5+
6+
import dotty.tools._
7+
import dotc._
8+
import reporting._
9+
import core.Contexts._
10+
11+
import xsbti.{Maybe, Position}
12+
13+
final class DelegatingReporter(delegate: xsbti.Reporter) extends Reporter
14+
with UniqueMessagePositions
15+
with HideNonSensicalMessages {
16+
17+
override def printSummary(implicit ctx: Context): Unit = delegate.printSummary()
18+
19+
def doReport(d: Diagnostic)(implicit ctx: Context): Unit = {
20+
val severity =
21+
d match {
22+
case _: Reporter.Error => xsbti.Severity.Error
23+
case _: Reporter.Warning => xsbti.Severity.Warn
24+
case _ => xsbti.Severity.Info
25+
}
26+
val pos =
27+
if (d.pos.exists) Some(d.pos)
28+
else None
29+
30+
val file =
31+
if (d.pos.source.file.exists) Option(d.pos.source.file.file)
32+
else None
33+
34+
val offset0 = pos.map(_.point)
35+
36+
val position = new Position {
37+
def line: Maybe[Integer] = maybe(pos.map(_.line))
38+
def lineContent: String = pos.map(_.lineContent).getOrElse("")
39+
def offset: Maybe[Integer] = maybeInt(offset0)
40+
def pointer: Maybe[Integer] = offset
41+
def pointerSpace: Maybe[String] = maybe(offset0.map(" " * _))
42+
def sourceFile: Maybe[java.io.File] = maybe(file)
43+
def sourcePath: Maybe[String] = maybe(file.map(_.getPath))
44+
}
45+
46+
delegate.log(position, d.message, severity)
47+
}
48+
49+
private[this] def maybe[T](opt: Option[T]): Maybe[T] = opt match {
50+
case None => Maybe.nothing[T]
51+
case Some(s) => Maybe.just[T](s)
52+
}
53+
import java.lang.{ Integer => I }
54+
private[this] def maybeInt(opt: Option[Int]): Maybe[I] = opt match {
55+
case None => Maybe.nothing[I]
56+
case Some(s) => Maybe.just[I](s)
57+
}
58+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
trait A
2+
trait B
3+
4+
trait Wr {
5+
val z: A with B
6+
}
7+
8+
object Er {
9+
val a = er1
10+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Reporter.checkSettings
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import sbt._
2+
import Keys._
3+
4+
object DottyInjectedPlugin extends AutoPlugin {
5+
override def requires = plugins.JvmPlugin
6+
override def trigger = allRequirements
7+
8+
override val projectSettings = Seq(
9+
scalaVersion := "0.1-SNAPSHOT",
10+
scalaOrganization := "ch.epfl.lamp",
11+
scalacOptions += "-language:Scala2",
12+
scalaBinaryVersion := "2.11",
13+
autoScalaLibrary := false,
14+
libraryDependencies ++= Seq("org.scala-lang" % "scala-library" % "2.11.5"),
15+
scalaCompilerBridgeSource := ("ch.epfl.lamp" % "dotty-bridge" % "0.1.1-SNAPSHOT" % "component").sources()
16+
)
17+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import sbt._
2+
import Keys._
3+
import KeyRanks.DTask
4+
5+
object Reporter {
6+
import xsbti.{Reporter, Problem, Position, Severity, Maybe}
7+
8+
lazy val check = TaskKey[Unit]("check", "make sure compilation info are forwared to sbt")
9+
10+
// compilerReporter is marked private in sbt
11+
lazy val compilerReporter = TaskKey[Option[xsbti.Reporter]]("compilerReporter", "Experimental hook to listen (or send) compilation failure messages.", DTask)
12+
13+
lazy val reporter =
14+
Some(new xsbti.Reporter {
15+
private val buffer = collection.mutable.ArrayBuffer.empty[Problem]
16+
def reset(): Unit = buffer.clear()
17+
def hasErrors: Boolean = buffer.exists(_.severity == Severity.Error)
18+
def hasWarnings: Boolean = buffer.exists(_.severity == Severity.Warn)
19+
def printSummary(): Unit = println(problems.mkString(System.lineSeparator))
20+
def problems: Array[Problem] = buffer.toArray
21+
def log(pos: Position, msg: String, sev: Severity): Unit = {
22+
object MyProblem extends Problem {
23+
def category: String = null
24+
def severity: Severity = sev
25+
def message: String = msg
26+
def position: Position = pos
27+
override def toString = s"custom: $position:$severity: $message"
28+
}
29+
buffer.append(MyProblem)
30+
}
31+
def comment(pos: xsbti.Position, msg: String): Unit = ()
32+
})
33+
34+
lazy val checkSettings = Seq(
35+
compilerReporter in (Compile, compile) := reporter,
36+
check <<= (compile in Compile).mapFailure( _ => {
37+
val problems = reporter.get.problems
38+
println(problems.toList)
39+
assert(problems.size == 2)
40+
assert(problems.count(_.severity == Severity.Error) == 1) // not found: er1,
41+
assert(problems.count(_.severity == Severity.Warn) == 1) // `with' as a type operator has been deprecated; use `&' instead,
42+
})
43+
)
44+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
> check

project/Build.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,31 @@ object DottyBuild extends Build {
207207
).
208208
settings(publishing)
209209

210+
// until sbt/sbt#2402 is fixed (https://github.com/sbt/sbt/issues/2402)
211+
lazy val cleanSbtBridge = TaskKey[Unit]("cleanSbtBridge", "delete dotty-sbt-bridge cache")
212+
210213
lazy val `dotty-bridge` = project.in(file("bridge")).
211214
dependsOn(dotty).
212215
settings(
213216
overrideScalaVersionSetting,
214217

218+
cleanSbtBridge := {
219+
val dottyBridgeVersion = version.value
220+
val dottyVersion = (version in dotty).value
221+
val classVersion = System.getProperty("java.class.version")
222+
223+
val sbtV = sbtVersion.value
224+
val sbtOrg = "org.scala-sbt"
225+
val sbtScalaVersion = "2.10.6"
226+
227+
val home = System.getProperty("user.home")
228+
val org = organization.value
229+
val artifact = moduleName.value
230+
231+
IO.delete(file(home) / ".ivy2" / "cache" / sbtOrg / s"$org-$artifact-$dottyBridgeVersion-bin_${dottyVersion}__$classVersion")
232+
IO.delete(file(home) / ".sbt" / "boot" / s"scala-$sbtScalaVersion" / sbtOrg / "sbt" / sbtV / s"$org-$artifact-$dottyBridgeVersion-bin_${dottyVersion}__$classVersion")
233+
},
234+
publishLocal := (publishLocal.dependsOn(cleanSbtBridge)).value,
215235
description := "sbt compiler bridge for Dotty",
216236
resolvers += Resolver.typesafeIvyRepo("releases"),
217237
libraryDependencies ++= Seq(

0 commit comments

Comments
 (0)