Skip to content

sbt-bridge: Handle missing source files #8897

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 1 commit into from
May 7, 2020
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
58 changes: 36 additions & 22 deletions sbt-bridge/src/xsbt/DelegatingReporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,45 +78,59 @@ public void doReport(dotty.tools.dotc.reporting.Diagnostic dia, Context ctx) {
SourcePosition pos = dia.pos();
SourceFile src = pos.source();
position = new Position() {
public Optional<java.io.File> sourceFile() {
if (!src.exists()) return Optional.empty();
else return Optional.ofNullable(src.file().file());
}
public Optional<String> sourcePath() {
if (!src.exists()) return Optional.empty();
else return Optional.ofNullable(src.file().path());
if (!src.exists())
return Optional.empty();

return Optional.ofNullable(src.file().path());
}
public Optional<java.io.File> sourceFile() {
if (!src.exists())
return Optional.empty();

return Optional.ofNullable(src.file().file());
}
public Optional<Integer> line() {
if (!src.file().exists())
return Optional.empty();

int line = pos.line() + 1;
if (line == -1) return Optional.empty();
else return Optional.of(line);
if (line == -1)
return Optional.empty();

return Optional.of(line);
}
public String lineContent() {
if (!src.file().exists())
return "";

String line = pos.lineContent();
if (line.endsWith("\r\n"))
return line.substring(0, line.length() - 2);
else if (line.endsWith("\n") || line.endsWith("\u000c"))
if (line.endsWith("\n") || line.endsWith("\u000c"))
return line.substring(0, line.length() - 1);
else
return line;

return line;
}
public Optional<Integer> offset() {
return Optional.of(pos.point());
}
public Optional<Integer> pointer() {
if (!src.exists()) return Optional.empty();
else return Optional.of(pos.point() - src.startOfLine(pos.point()));
if (!src.file().exists())
return Optional.empty();

return Optional.of(pos.point() - src.startOfLine(pos.point()));
}
public Optional<String> pointerSpace() {
if (!src.exists()) return Optional.empty();
else {
String lineContent = this.lineContent();
int pointer = this.pointer().get();
StringBuilder result = new StringBuilder();
for (int i = 0; i < pointer; i++)
result.append(lineContent.charAt(i) == '\t' ? '\t' : ' ');
return Optional.of(result.toString());
}
if (!src.file().exists())
return Optional.empty();

String lineContent = this.lineContent();
int pointer = this.pointer().get();
StringBuilder result = new StringBuilder();
for (int i = 0; i < pointer; i++)
result.append(lineContent.charAt(i) == '\t' ? '\t' : ' ');
return Optional.of(result.toString());
}
};
} else {
Expand Down
5 changes: 5 additions & 0 deletions sbt-dotty/sbt-test/compilerReporter/i7442/a/A.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
object A {
inline def a[T](x: T): T = inline x match {
case 1 => x
}
}
4 changes: 4 additions & 0 deletions sbt-dotty/sbt-test/compilerReporter/i7442/b/B.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
object B {
def b = A.a(2)
}

18 changes: 18 additions & 0 deletions sbt-dotty/sbt-test/compilerReporter/i7442/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
lazy val a = project.in(file("a"))
.settings(
scalaVersion := sys.props("plugin.scalaVersion")
)
lazy val b = project.in(file("b"))
.settings(Reporter.checkSettings)
.settings(
scalaVersion := sys.props("plugin.scalaVersion"),
// Manually depend on `a` so that we can:
// 1. Compile `a`
// 2. Remove a source file in `a`
// 3. Compile `b` without forcing a recompilation of `a`
Compile / unmanagedJars := {
val s = Seq(Attributed.blank((a / Compile / packageBin / artifactPath).value))
println("s: " + s)
s
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import sbt._
import Keys._

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

override val projectSettings = Seq(
scalaVersion := sys.props("plugin.scalaVersion"),
)
}
42 changes: 42 additions & 0 deletions sbt-dotty/sbt-test/compilerReporter/i7442/project/Reporter.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import sbt._
import Keys._
import KeyRanks.DTask

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

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

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

lazy val reporter =
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(problem: Problem): Unit = buffer.append(problem)
def comment(pos: xsbti.Position, msg: String): Unit = ()
}

lazy val checkSettings = Seq(
compilerReporter in (Compile, compile) := reporter,
check := (compile in Compile).failure.map(_ => {
println(reporter.problems.toList)
assert(reporter.problems.length == 1)
val problem = reporter.problems.head
// Check that all methods on position can ba called without crashing
val pos = problem.position
println(pos.sourceFile)
println(pos.sourcePath)
println(pos.line)
println(pos.lineContent)
println(pos.offset)
println(pos.pointer)
println(pos.pointerSpace)
}).value
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % sys.props("plugin.version"))
4 changes: 4 additions & 0 deletions sbt-dotty/sbt-test/compilerReporter/i7442/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
> a/packageBin
# Remove the source file to check if we later try to read it because it's in the @SourceFile annotation of the tasty file being inlined
$ delete a/A.scala
> b/check
4 changes: 3 additions & 1 deletion sbt-dotty/sbt-test/compilerReporter/simple/build.sbt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Reporter.checkSettings
scalaVersion := sys.props("plugin.scalaVersion")

Reporter.checkSettings