Skip to content

Commit 8c22ff5

Browse files
committed
remain compatible with Zinc 1.3
1 parent 16b91ba commit 8c22ff5

17 files changed

+260
-83
lines changed

compiler/src/dotty/tools/backend/jvm/CodeGen.scala

+3-6
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,9 @@ class CodeGen(val int: DottyBackendInterface, val primitives: DottyPrimitives)(
115115
if (ctx.compilerCallback != null)
116116
ctx.compilerCallback.onClassGenerated(sourceFile, convertAbstractFile(clsFile), className)
117117

118-
if (ctx.sbtCallback != null) {
119-
val jSourceFile = sourceFile.underlyingZincFile
120-
val cb = ctx.sbtCallback
121-
if (isLocal) cb.generatedLocalClass(jSourceFile, clsFile.jpath)
122-
else cb.generatedNonLocalClass(jSourceFile, clsFile.jpath, className, fullClassName)
123-
}
118+
ctx.withIncCallback: cb =>
119+
if (isLocal) cb.generatedLocalClass(sourceFile, clsFile.jpath)
120+
else cb.generatedNonLocalClass(sourceFile, clsFile.jpath, className, fullClassName)
124121
}
125122

126123
/** Convert a `dotty.tools.io.AbstractFile` into a

compiler/src/dotty/tools/dotc/core/Contexts.scala

+14-11
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,18 @@ import scala.annotation.internal.sharable
3434

3535
import DenotTransformers.DenotTransformer
3636
import dotty.tools.dotc.profile.Profiler
37+
import dotty.tools.dotc.sbt.interfaces.IncrementalCallback
3738
import util.Property.Key
3839
import util.Store
39-
import xsbti.AnalysisCallback
4040
import plugins._
4141
import java.util.concurrent.atomic.AtomicInteger
42-
import java.util.Map as JMap
4342
import java.nio.file.InvalidPathException
4443

4544

4645
object Contexts {
4746

4847
private val (compilerCallbackLoc, store1) = Store.empty.newLocation[CompilerCallback]()
49-
private val (sbtCallbackLoc, store2) = store1.newLocation[AnalysisCallback]()
48+
private val (incCallbackLoc, store2) = store1.newLocation[IncrementalCallback | Null]()
5049
private val (printerFnLoc, store3) = store2.newLocation[Context => Printer](new RefinedPrinter(_))
5150
private val (settingsStateLoc, store4) = store3.newLocation[SettingsState]()
5251
private val (compilationUnitLoc, store5) = store4.newLocation[CompilationUnit]()
@@ -55,9 +54,8 @@ object Contexts {
5554
private val (notNullInfosLoc, store8) = store7.newLocation[List[NotNullInfo]]()
5655
private val (importInfoLoc, store9) = store8.newLocation[ImportInfo | Null]()
5756
private val (typeAssignerLoc, store10) = store9.newLocation[TypeAssigner](TypeAssigner)
58-
private val (zincVirtualFilesLoc, store11) = store10.newLocation[JMap[String, xsbti.VirtualFile] | Null]()
5957

60-
private val initialStore = store11
58+
private val initialStore = store10
6159

6260
/** The current context */
6361
inline def ctx(using ctx: Context): Context = ctx
@@ -168,10 +166,17 @@ object Contexts {
168166
def compilerCallback: CompilerCallback = store(compilerCallbackLoc)
169167

170168
/** The Zinc callback implementation if we are run from Zinc, null otherwise */
171-
def sbtCallback: AnalysisCallback = store(sbtCallbackLoc)
169+
def incCallback: IncrementalCallback | Null = store(incCallbackLoc)
172170

173-
/** A map from absolute path to VirtualFile if we are run from Zinc, null otherwise */
174-
def zincVirtualFiles: JMap[String, xsbti.VirtualFile] | Null = store(zincVirtualFilesLoc)
171+
/** Run `op` if there exists an incremental callback */
172+
inline def withIncCallback(inline op: IncrementalCallback => Unit): Unit =
173+
val local = incCallback
174+
if local != null then op(local)
175+
176+
def incrementalEnabled: Boolean =
177+
val local = incCallback
178+
if local != null then local.enabled
179+
else false
175180

176181
/** The current plain printer */
177182
def printerFn: Context => Printer = store(printerFnLoc)
@@ -670,9 +675,7 @@ object Contexts {
670675
}
671676

672677
def setCompilerCallback(callback: CompilerCallback): this.type = updateStore(compilerCallbackLoc, callback)
673-
def setSbtCallback(callback: AnalysisCallback): this.type = updateStore(sbtCallbackLoc, callback)
674-
def setZincVirtualFiles(map: JMap[String, xsbti.VirtualFile]): this.type =
675-
updateStore(zincVirtualFilesLoc, map)
678+
def setIncCallback(callback: IncrementalCallback): this.type = updateStore(incCallbackLoc, callback)
676679
def setPrinterFn(printer: Context => Printer): this.type = updateStore(printerFnLoc, printer)
677680
def setSettings(settingsState: SettingsState): this.type = updateStore(settingsStateLoc, settingsState)
678681
def setRun(run: Run | Null): this.type = updateStore(runLoc, run)

compiler/src/dotty/tools/dotc/sbt/APIUtils.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ object APIUtils {
3535
* a dummy empty class can be registered instead, using this method.
3636
*/
3737
def registerDummyClass(classSym: ClassSymbol)(using Context): Unit = {
38-
if (ctx.sbtCallback != null) {
38+
ctx.withIncCallback { cb =>
3939
val classLike = emptyClassLike(classSym)
40-
ctx.sbtCallback.api(ctx.compilationUnit.source.underlyingZincFile, classLike)
40+
cb.api(ctx.compilationUnit.source, classLike)
4141
}
4242
}
4343

compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala

+7-8
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class ExtractAPI extends Phase {
5050

5151
override def isRunnable(using Context): Boolean = {
5252
def forceRun = ctx.settings.YdumpSbtInc.value || ctx.settings.YforceSbtPhases.value
53-
super.isRunnable && (ctx.sbtCallback != null || forceRun)
53+
super.isRunnable && (ctx.incrementalEnabled || forceRun)
5454
}
5555

5656
// Check no needed. Does not transform trees
@@ -66,8 +66,8 @@ class ExtractAPI extends Phase {
6666
override def run(using Context): Unit = {
6767
val unit = ctx.compilationUnit
6868
val sourceFile = unit.source
69-
if (ctx.sbtCallback != null)
70-
ctx.sbtCallback.startSource(sourceFile.underlyingZincFile)
69+
ctx.withIncCallback: cb =>
70+
cb.startSource(sourceFile)
7171

7272
val apiTraverser = new ExtractAPICollector
7373
val classes = apiTraverser.apiSource(unit.tpdTree)
@@ -82,11 +82,10 @@ class ExtractAPI extends Phase {
8282
} finally pw.close()
8383
}
8484

85-
if ctx.sbtCallback != null &&
86-
!ctx.compilationUnit.suspendedAtInliningPhase // already registered before this unit was suspended
87-
then
88-
classes.foreach(ctx.sbtCallback.api(sourceFile.underlyingZincFile, _))
89-
mainClasses.foreach(ctx.sbtCallback.mainClass(sourceFile.underlyingZincFile, _))
85+
ctx.withIncCallback: cb =>
86+
if !ctx.compilationUnit.suspendedAtInliningPhase then // already registered before this unit was suspended
87+
classes.foreach(cb.api(sourceFile, _))
88+
mainClasses.foreach(cb.mainClass(sourceFile, _))
9089
}
9190
}
9291

compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala

+15-15
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class ExtractDependencies extends Phase {
5858

5959
override def isRunnable(using Context): Boolean = {
6060
def forceRun = ctx.settings.YdumpSbtInc.value || ctx.settings.YforceSbtPhases.value
61-
super.isRunnable && (ctx.sbtCallback != null && ctx.sbtCallback.enabled() || forceRun)
61+
super.isRunnable && (ctx.incrementalEnabled || forceRun)
6262
}
6363

6464
// Check no needed. Does not transform trees
@@ -93,15 +93,16 @@ class ExtractDependencies extends Phase {
9393
} finally pw.close()
9494
}
9595

96-
if (ctx.sbtCallback != null && ctx.sbtCallback.enabled()) {
97-
collector.usedNames.foreach {
98-
case (clazz, usedNames) =>
99-
val className = classNameAsString(clazz)
100-
usedNames.names.foreach {
101-
case (usedName, scopes) =>
102-
ctx.sbtCallback.usedName(className, usedName.toString, scopes)
103-
}
104-
}
96+
if (ctx.incrementalEnabled) {
97+
ctx.withIncCallback: cb =>
98+
collector.usedNames.foreach {
99+
case (clazz, usedNames) =>
100+
val className = classNameAsString(clazz)
101+
usedNames.names.foreach {
102+
case (usedName, scopes) =>
103+
cb.usedName(className, usedName.toString, scopes)
104+
}
105+
}
105106

106107
collector.dependencies.foreach(recordDependency)
107108
}
@@ -114,10 +115,10 @@ class ExtractDependencies extends Phase {
114115
*/
115116
def recordDependency(dep: ClassDependency)(using Context): Unit = {
116117
val fromClassName = classNameAsString(dep.from)
117-
val zincSourceFile = ctx.compilationUnit.source.underlyingZincFile
118+
val sourceFile = ctx.compilationUnit.source
118119

119120
def binaryDependency(file: Path, binaryClassName: String) =
120-
ctx.sbtCallback.binaryDependency(file, binaryClassName, fromClassName, zincSourceFile, dep.context)
121+
ctx.withIncCallback(_.binaryDependency(file, binaryClassName, fromClassName, sourceFile, dep.context))
121122

122123
def processExternalDependency(depFile: AbstractFile, binaryClassName: String) = {
123124
depFile match {
@@ -143,8 +144,7 @@ class ExtractDependencies extends Phase {
143144
val depFile = dep.to.associatedFile
144145
if (depFile != null) {
145146
def depIsSameSource =
146-
val depVF: xsbti.VirtualFile | Null = ctx.zincVirtualFiles.uncheckedNN.get(depFile.absolutePath)
147-
depVF != null && depVF.id() == zincSourceFile.id()
147+
depFile.absolutePath == sourceFile.file.absolutePath
148148

149149
// Cannot ignore inheritance relationship coming from the same source (see sbt/zinc#417)
150150
def allowLocal = dep.context == DependencyByInheritance || dep.context == LocalDependencyByInheritance
@@ -158,7 +158,7 @@ class ExtractDependencies extends Phase {
158158
// We cannot ignore dependencies coming from the same source file because
159159
// the dependency info needs to propagate. See source-dependencies/trait-trait-211.
160160
val toClassName = classNameAsString(dep.to)
161-
ctx.sbtCallback.classDependency(toClassName, fromClassName, dep.context)
161+
ctx.withIncCallback(_.classDependency(toClassName, fromClassName, dep.context))
162162
}
163163
}
164164
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package dotty.tools.dotc.sbt.interfaces;
2+
3+
import dotty.tools.dotc.interfaces.SourceFile;
4+
5+
import java.util.EnumSet;
6+
import java.nio.file.Path;
7+
8+
/* User code should not implement this interface, it is intended to be a wrapper around xsbti.AnalysisCallback. */
9+
public interface IncrementalCallback {
10+
default void api(SourceFile sourceFile, xsbti.api.ClassLike classApi) {
11+
}
12+
13+
default void startSource(SourceFile sourceFile) {
14+
}
15+
16+
default void mainClass(SourceFile sourceFile, String className) {
17+
}
18+
19+
default boolean enabled() {
20+
return false;
21+
}
22+
23+
default void usedName(String className, String name, EnumSet<xsbti.UseScope> useScopes) {
24+
}
25+
26+
default void binaryDependency(Path onBinaryEntry, String onBinaryClassName, String fromClassName,
27+
SourceFile fromSourceFile, xsbti.api.DependencyContext context) {
28+
}
29+
30+
default void classDependency(String onClassName, String sourceClassName, xsbti.api.DependencyContext context) {
31+
}
32+
33+
default void generatedLocalClass(SourceFile source, Path classFile) {
34+
}
35+
36+
default void generatedNonLocalClass(SourceFile source, Path classFile, String binaryClassName,
37+
String srcClassName) {
38+
}
39+
}

compiler/src/dotty/tools/dotc/util/SourceFile.scala

-26
Original file line numberDiff line numberDiff line change
@@ -66,32 +66,6 @@ class SourceFile(val file: AbstractFile, computeContent: => Array[Char]) extends
6666
private var myContent: Array[Char] | Null = null
6767
private var myUnderlyingZincFile: xsbti.VirtualFile | Null = null
6868

69-
def underlyingZincFile(using Context): xsbti.VirtualFile =
70-
val local = myUnderlyingZincFile
71-
if local == null then
72-
// usually without -sourcepath then the `underlying` will be set by Zinc.
73-
val maybeUnderlying = file.underlying
74-
val underlying0 =
75-
if maybeUnderlying == null then
76-
// When we have `-sourcepath` set then the file could come from the filesystem,
77-
// rather than a zinc managed file, so then we need to check if we have a virtual file for it.
78-
// TODO: we should consider in the future if there is a use case for sourcepath to possibly be
79-
// made of virtual files.
80-
val fromLookup = ctx.zincVirtualFiles.uncheckedNN.get(file.absolutePath)
81-
if fromLookup != null then
82-
fromLookup
83-
else
84-
sys.error(s"no underlying file for ${file.absolutePath}, possible paths = ${ctx.zincVirtualFiles.keySet}")
85-
else maybeUnderlying
86-
if ctx.settings.YdebugVirtualFiles.value then
87-
val isVirtual = !underlying0.isInstanceOf[xsbti.PathBasedFile]
88-
println(s"found underlying zinc file ${underlying0.id} for ${file.absolutePath} [virtual = $isVirtual]")
89-
90-
myUnderlyingZincFile = underlying0
91-
underlying0
92-
else
93-
local
94-
9569
/** The contents of the original source file. Note that this can be empty, for example when
9670
* the source is read from Tasty. */
9771
def content(): Array[Char] = {

compiler/src/dotty/tools/io/AbstractFile.scala

-3
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,6 @@ abstract class AbstractFile extends Iterable[AbstractFile] {
118118
/** Returns the underlying Path if any and null otherwise. */
119119
def jpath: JPath
120120

121-
/** Overridden in sbt-bridge ZincPlainFile and ZincVirtualFile */
122-
def underlying: xsbti.VirtualFile | Null = null
123-
124121
/** An underlying source, if known. Mostly, a zip/jar file. */
125122
def underlyingSource: Option[AbstractFile] = None
126123

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package dotty.tools.xsbt;
2+
3+
import xsbti.VirtualFile;
4+
5+
interface AbstractZincFile {
6+
VirtualFile underlying();
7+
}

sbt-bridge/src/dotty/tools/xsbt/CompilerBridgeDriver.java

+29-8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import dotty.tools.dotc.ScalacCommand;
1111
import dotty.tools.dotc.config.Properties;
1212
import dotty.tools.dotc.core.Contexts;
13+
import dotty.tools.dotc.util.SourceFile;
1314
import dotty.tools.io.AbstractFile;
1415
import scala.collection.mutable.ListBuffer;
1516
import scala.io.Codec;
@@ -20,6 +21,7 @@
2021
import java.io.IOException;
2122
import java.util.Comparator;
2223
import java.util.HashMap;
24+
import java.util.Map;
2325
import java.util.Arrays;
2426

2527
public class CompilerBridgeDriver extends Driver {
@@ -51,6 +53,15 @@ public boolean sourcesRequired() {
5153
return false;
5254
}
5355

56+
private static VirtualFile asVirtualFileOrNull(SourceFile sourceFile, Map<String, VirtualFile> sourcesMap) {
57+
if (sourceFile.file() instanceof AbstractZincFile) {
58+
return ((AbstractZincFile) sourceFile.file()).underlying();
59+
} else {
60+
String pathId = sourceFile.file().absolutePath();
61+
return sourcesMap.get(pathId);
62+
}
63+
}
64+
5465
synchronized public void run(VirtualFile[] sources, AnalysisCallback callback, Logger log, Reporter delegate) {
5566
// convert sources to a HashMap from this.id to itself
5667
HashMap<String, VirtualFile> sourcesMap = new HashMap<>();
@@ -69,13 +80,24 @@ synchronized public void run(VirtualFile[] sources, AnalysisCallback callback, L
6980
}
7081

7182
DelegatingReporter reporter = new DelegatingReporter(delegate, sourceFile -> {
72-
String pathId = sourceFile.file().absolutePath();
73-
VirtualFile source = sourcesMap.get(pathId);
74-
75-
if (source != null)
76-
return source.id();
83+
VirtualFile virtualFile = asVirtualFileOrNull(sourceFile, sourcesMap);
84+
if (virtualFile != null)
85+
return virtualFile.id();
7786
else
78-
return pathId;
87+
return sourceFile.file().absolutePath();
88+
});
89+
90+
IncrementalCallback incCallback = new IncrementalCallback(callback, sourceFile -> {
91+
if (sourceFile instanceof SourceFile) {
92+
SourceFile sf = (SourceFile) sourceFile;
93+
VirtualFile virtualFile = asVirtualFileOrNull(sf, sourcesMap);
94+
if (virtualFile != null)
95+
return virtualFile;
96+
else
97+
throw new IllegalStateException("Unknown source file: " + sourceFile.path());
98+
} else {
99+
throw new IllegalStateException("Unknown source file: " + sourceFile.path());
100+
}
79101
});
80102

81103
try {
@@ -84,8 +106,7 @@ synchronized public void run(VirtualFile[] sources, AnalysisCallback callback, L
84106
Contexts.Context initialCtx = initCtx()
85107
.fresh()
86108
.setReporter(reporter)
87-
.setSbtCallback(callback)
88-
.setZincVirtualFiles(sourcesMap);
109+
.setIncCallback(incCallback);
89110

90111
Contexts.Context context = setup(args, initialCtx).map(t -> t._2).getOrElse(() -> initialCtx);
91112

0 commit comments

Comments
 (0)