Skip to content

Commit 0e5f9dd

Browse files
authored
Merge pull request #8897 from dotty-staging/srcfile-exists
sbt-bridge: Handle missing source files
2 parents ef255d3 + 40eece4 commit 0e5f9dd

File tree

9 files changed

+124
-23
lines changed

9 files changed

+124
-23
lines changed

sbt-bridge/src/xsbt/DelegatingReporter.java

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -78,45 +78,59 @@ public void doReport(dotty.tools.dotc.reporting.Diagnostic dia, Context ctx) {
7878
SourcePosition pos = dia.pos();
7979
SourceFile src = pos.source();
8080
position = new Position() {
81-
public Optional<java.io.File> sourceFile() {
82-
if (!src.exists()) return Optional.empty();
83-
else return Optional.ofNullable(src.file().file());
84-
}
8581
public Optional<String> sourcePath() {
86-
if (!src.exists()) return Optional.empty();
87-
else return Optional.ofNullable(src.file().path());
82+
if (!src.exists())
83+
return Optional.empty();
84+
85+
return Optional.ofNullable(src.file().path());
86+
}
87+
public Optional<java.io.File> sourceFile() {
88+
if (!src.exists())
89+
return Optional.empty();
90+
91+
return Optional.ofNullable(src.file().file());
8892
}
8993
public Optional<Integer> line() {
94+
if (!src.file().exists())
95+
return Optional.empty();
96+
9097
int line = pos.line() + 1;
91-
if (line == -1) return Optional.empty();
92-
else return Optional.of(line);
98+
if (line == -1)
99+
return Optional.empty();
100+
101+
return Optional.of(line);
93102
}
94103
public String lineContent() {
104+
if (!src.file().exists())
105+
return "";
106+
95107
String line = pos.lineContent();
96108
if (line.endsWith("\r\n"))
97109
return line.substring(0, line.length() - 2);
98-
else if (line.endsWith("\n") || line.endsWith("\u000c"))
110+
if (line.endsWith("\n") || line.endsWith("\u000c"))
99111
return line.substring(0, line.length() - 1);
100-
else
101-
return line;
112+
113+
return line;
102114
}
103115
public Optional<Integer> offset() {
104116
return Optional.of(pos.point());
105117
}
106118
public Optional<Integer> pointer() {
107-
if (!src.exists()) return Optional.empty();
108-
else return Optional.of(pos.point() - src.startOfLine(pos.point()));
119+
if (!src.file().exists())
120+
return Optional.empty();
121+
122+
return Optional.of(pos.point() - src.startOfLine(pos.point()));
109123
}
110124
public Optional<String> pointerSpace() {
111-
if (!src.exists()) return Optional.empty();
112-
else {
113-
String lineContent = this.lineContent();
114-
int pointer = this.pointer().get();
115-
StringBuilder result = new StringBuilder();
116-
for (int i = 0; i < pointer; i++)
117-
result.append(lineContent.charAt(i) == '\t' ? '\t' : ' ');
118-
return Optional.of(result.toString());
119-
}
125+
if (!src.file().exists())
126+
return Optional.empty();
127+
128+
String lineContent = this.lineContent();
129+
int pointer = this.pointer().get();
130+
StringBuilder result = new StringBuilder();
131+
for (int i = 0; i < pointer; i++)
132+
result.append(lineContent.charAt(i) == '\t' ? '\t' : ' ');
133+
return Optional.of(result.toString());
120134
}
121135
};
122136
} else {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object A {
2+
inline def a[T](x: T): T = inline x match {
3+
case 1 => x
4+
}
5+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
object B {
2+
def b = A.a(2)
3+
}
4+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
lazy val a = project.in(file("a"))
2+
.settings(
3+
scalaVersion := sys.props("plugin.scalaVersion")
4+
)
5+
lazy val b = project.in(file("b"))
6+
.settings(Reporter.checkSettings)
7+
.settings(
8+
scalaVersion := sys.props("plugin.scalaVersion"),
9+
// Manually depend on `a` so that we can:
10+
// 1. Compile `a`
11+
// 2. Remove a source file in `a`
12+
// 3. Compile `b` without forcing a recompilation of `a`
13+
Compile / unmanagedJars := {
14+
val s = Seq(Attributed.blank((a / Compile / packageBin / artifactPath).value))
15+
println("s: " + s)
16+
s
17+
}
18+
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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 := sys.props("plugin.scalaVersion"),
10+
)
11+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import sbt._
2+
import Keys._
3+
import KeyRanks.DTask
4+
5+
object Reporter {
6+
import xsbti.{Reporter, Problem, Position, Severity}
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[xsbti.Reporter]("compilerReporter", "Experimental hook to listen (or send) compilation failure messages.", DTask)
12+
13+
lazy val reporter =
14+
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(problem: Problem): Unit = buffer.append(problem)
22+
def comment(pos: xsbti.Position, msg: String): Unit = ()
23+
}
24+
25+
lazy val checkSettings = Seq(
26+
compilerReporter in (Compile, compile) := reporter,
27+
check := (compile in Compile).failure.map(_ => {
28+
println(reporter.problems.toList)
29+
assert(reporter.problems.length == 1)
30+
val problem = reporter.problems.head
31+
// Check that all methods on position can ba called without crashing
32+
val pos = problem.position
33+
println(pos.sourceFile)
34+
println(pos.sourcePath)
35+
println(pos.line)
36+
println(pos.lineContent)
37+
println(pos.offset)
38+
println(pos.pointer)
39+
println(pos.pointerSpace)
40+
}).value
41+
)
42+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % sys.props("plugin.version"))
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
> a/packageBin
2+
# 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
3+
$ delete a/A.scala
4+
> b/check
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
Reporter.checkSettings
1+
scalaVersion := sys.props("plugin.scalaVersion")
2+
3+
Reporter.checkSettings

0 commit comments

Comments
 (0)