Skip to content

Commit 2458b8f

Browse files
committed
remain compatible with Zinc 1.3
1 parent 34a5e45 commit 2458b8f

18 files changed

+279
-93
lines changed

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import scala.tools.asm
3030
import scala.tools.asm.tree._
3131
import tpd._
3232
import dotty.tools.io.AbstractFile
33-
import dotty.tools.dotc.util.{NoSourcePosition, SourceFile}
33+
import dotty.tools.dotc.util.NoSourcePosition
3434

3535

3636
class CodeGen(val int: DottyBackendInterface, val primitives: DottyPrimitives)( val bTypes: BTypesFromSymbols[int.type]) { self =>
@@ -106,7 +106,7 @@ class CodeGen(val int: DottyBackendInterface, val primitives: DottyPrimitives)(
106106
}
107107

108108
// Creates a callback that will be evaluated in PostProcessor after creating a file
109-
private def onFileCreated(cls: ClassNode, claszSymbol: Symbol, sourceFile: SourceFile): AbstractFile => Unit = clsFile => {
109+
private def onFileCreated(cls: ClassNode, claszSymbol: Symbol, sourceFile: interfaces.SourceFile): AbstractFile => Unit = clsFile => {
110110
val (fullClassName, isLocal) = atPhase(sbtExtractDependenciesPhase) {
111111
(ExtractDependencies.classNameAsString(claszSymbol), claszSymbol.isLocal)
112112
}
@@ -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/config/ScalaSettings.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,6 @@ private sealed trait YSettings:
325325
val YdebugTypeError: Setting[Boolean] = BooleanSetting("-Ydebug-type-error", "Print the stack trace when a TypeError is caught", false)
326326
val YdebugError: Setting[Boolean] = BooleanSetting("-Ydebug-error", "Print the stack trace when any error is caught.", false)
327327
val YdebugUnpickling: Setting[Boolean] = BooleanSetting("-Ydebug-unpickling", "Print the stack trace when an error occurs when reading Tasty.", false)
328-
val YdebugVirtualFiles: Setting[Boolean] = BooleanSetting("-Ydebug-virtual-files", "Debug usage of virtual files, e.g. remote cache in sbt", false)
329328
val YtermConflict: Setting[String] = ChoiceSetting("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", List("package", "object", "error"), "error")
330329
val Ylog: Setting[List[String]] = PhasesSetting("-Ylog", "Log operations during")
331330
val YlogClasspath: Setting[Boolean] = BooleanSetting("-Ylog-classpath", "Output information about what classpath is being applied.")

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

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,17 @@ 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

45-
4644
object Contexts {
4745

4846
private val (compilerCallbackLoc, store1) = Store.empty.newLocation[CompilerCallback]()
49-
private val (sbtCallbackLoc, store2) = store1.newLocation[AnalysisCallback]()
47+
private val (incCallbackLoc, store2) = store1.newLocation[IncrementalCallback | Null]()
5048
private val (printerFnLoc, store3) = store2.newLocation[Context => Printer](new RefinedPrinter(_))
5149
private val (settingsStateLoc, store4) = store3.newLocation[SettingsState]()
5250
private val (compilationUnitLoc, store5) = store4.newLocation[CompilationUnit]()
@@ -55,7 +53,7 @@ object Contexts {
5553
private val (notNullInfosLoc, store8) = store7.newLocation[List[NotNullInfo]]()
5654
private val (importInfoLoc, store9) = store8.newLocation[ImportInfo | Null]()
5755
private val (typeAssignerLoc, store10) = store9.newLocation[TypeAssigner](TypeAssigner)
58-
private val (zincVirtualFilesLoc, store11) = store10.newLocation[JMap[String, xsbti.VirtualFile] | Null]()
56+
private val (zincInitialFilesLoc, store11) = store10.newLocation[util.ReadOnlySet[AbstractFile] | Null]()
5957

6058
private val initialStore = store11
6159

@@ -168,10 +166,18 @@ 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)
170+
def zincInitialFiles: util.ReadOnlySet[AbstractFile] | Null = store(zincInitialFilesLoc)
171+
172+
/** Run `op` if there exists an incremental callback */
173+
inline def withIncCallback(inline op: IncrementalCallback => Unit): Unit =
174+
val local = incCallback
175+
if local != null then op(local)
172176

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)
177+
def incrementalEnabled: Boolean =
178+
val local = incCallback
179+
if local != null then local.enabled
180+
else false
175181

176182
/** The current plain printer */
177183
def printerFn: Context => Printer = store(printerFnLoc)
@@ -240,7 +246,16 @@ object Contexts {
240246
/** Sourcefile corresponding to given abstract file, memoized */
241247
def getSource(file: AbstractFile, codec: => Codec = Codec(settings.encoding.value)) = {
242248
util.Stats.record("Context.getSource")
243-
base.sources.getOrElseUpdate(file, SourceFile(file, codec))
249+
base.sources.getOrElseUpdate(file, {
250+
val zincSources = zincInitialFiles
251+
val cachedFile =
252+
if zincSources != null then zincSources.lookup(file) match
253+
case null => file
254+
case cached => cached
255+
else
256+
file
257+
SourceFile(cachedFile, codec)
258+
})
244259
}
245260

246261
/** SourceFile with given path name, memoized */
@@ -670,9 +685,8 @@ object Contexts {
670685
}
671686

672687
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)
688+
def setIncCallback(callback: IncrementalCallback): this.type = updateStore(incCallbackLoc, callback)
689+
def setZincInitialFiles(zincInitialFiles: util.ReadOnlySet[AbstractFile]): this.type = updateStore(zincInitialFilesLoc, zincInitialFiles)
676690
def setPrinterFn(printer: Context => Printer): this.type = updateStore(printerFnLoc, printer)
677691
def setSettings(settingsState: SettingsState): this.type = updateStore(settingsStateLoc, settingsState)
678692
def setRun(run: Run | Null): this.type = updateStore(runLoc, run)

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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 7 additions & 8 deletions
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

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import dotty.tools.dotc.core.Denotations.StaleSymbol
2020
import dotty.tools.dotc.core.Types._
2121
import dotty.tools.dotc.transform.SymUtils._
2222
import dotty.tools.dotc.util.{SrcPos, NoSourcePosition}
23-
import dotty.tools.uncheckedNN
2423
import dotty.tools.io
2524
import dotty.tools.io.{AbstractFile, PlainFile, ZipArchive}
2625
import xsbti.UseScope
@@ -58,7 +57,7 @@ class ExtractDependencies extends Phase {
5857

5958
override def isRunnable(using Context): Boolean = {
6059
def forceRun = ctx.settings.YdumpSbtInc.value || ctx.settings.YforceSbtPhases.value
61-
super.isRunnable && (ctx.sbtCallback != null && ctx.sbtCallback.enabled() || forceRun)
60+
super.isRunnable && (ctx.incrementalEnabled || forceRun)
6261
}
6362

6463
// Check no needed. Does not transform trees
@@ -93,15 +92,16 @@ class ExtractDependencies extends Phase {
9392
} finally pw.close()
9493
}
9594

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-
}
95+
if (ctx.incrementalEnabled) {
96+
ctx.withIncCallback: cb =>
97+
collector.usedNames.foreach {
98+
case (clazz, usedNames) =>
99+
val className = classNameAsString(clazz)
100+
usedNames.names.foreach {
101+
case (usedName, scopes) =>
102+
cb.usedName(className, usedName.toString, scopes)
103+
}
104+
}
105105

106106
collector.dependencies.foreach(recordDependency)
107107
}
@@ -114,10 +114,10 @@ class ExtractDependencies extends Phase {
114114
*/
115115
def recordDependency(dep: ClassDependency)(using Context): Unit = {
116116
val fromClassName = classNameAsString(dep.from)
117-
val zincSourceFile = ctx.compilationUnit.source.underlyingZincFile
117+
val sourceFile = ctx.compilationUnit.source
118118

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

122122
def processExternalDependency(depFile: AbstractFile, binaryClassName: String) = {
123123
depFile match {
@@ -143,8 +143,7 @@ class ExtractDependencies extends Phase {
143143
val depFile = dep.to.associatedFile
144144
if (depFile != null) {
145145
def depIsSameSource =
146-
val depVF: xsbti.VirtualFile | Null = ctx.zincVirtualFiles.uncheckedNN.get(depFile.absolutePath)
147-
depVF != null && depVF.id() == zincSourceFile.id()
146+
depFile.absolutePath == sourceFile.file.absolutePath
148147

149148
// Cannot ignore inheritance relationship coming from the same source (see sbt/zinc#417)
150149
def allowLocal = dep.context == DependencyByInheritance || dep.context == LocalDependencyByInheritance
@@ -158,7 +157,7 @@ class ExtractDependencies extends Phase {
158157
// We cannot ignore dependencies coming from the same source file because
159158
// the dependency info needs to propagate. See source-dependencies/trait-trait-211.
160159
val toClassName = classNameAsString(dep.to)
161-
ctx.sbtCallback.classDependency(toClassName, fromClassName, dep.context)
160+
ctx.withIncCallback(_.classDependency(toClassName, fromClassName, dep.context))
162161
}
163162
}
164163
}
Lines changed: 39 additions & 0 deletions
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

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -64,33 +64,6 @@ class SourceFile(val file: AbstractFile, computeContent: => Array[Char]) extends
6464
import SourceFile._
6565

6666
private var myContent: Array[Char] | Null = null
67-
private var myUnderlyingZincFile: xsbti.VirtualFile | Null = null
68-
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
9467

9568
/** The contents of the original source file. Note that this can be empty, for example when
9669
* the source is read from Tasty. */

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

Lines changed: 0 additions & 3 deletions
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

Lines changed: 7 additions & 0 deletions
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+
}

0 commit comments

Comments
 (0)