@@ -2,6 +2,7 @@ package dotty.tools.sbtplugin
22
33import sbt ._
44import sbt .Keys ._
5+ import sbt .inc .{ ClassfileManager , IncOptions }
56
67object DottyPlugin extends AutoPlugin {
78 object autoImport {
@@ -27,7 +28,8 @@ object DottyPlugin extends AutoPlugin {
2728
2829 implicit class DottyCompatModuleID (moduleID : ModuleID ) {
2930 /** If this ModuleID cross-version is a Dotty version, replace it
30- * by the Scala 2.x version that the Dotty version is retro-compatible with.
31+ * by the Scala 2.x version that the Dotty version is retro-compatible with,
32+ * otherwise do nothing.
3133 *
3234 * This setting is useful when your build contains dependencies that have only
3335 * been published with Scala 2.x, if you have:
@@ -46,10 +48,15 @@ object DottyPlugin extends AutoPlugin {
4648 * Dotty is released, you should not rely on it.
4749 */
4850 def withDottyCompat (): ModuleID =
49- moduleID.cross(CrossVersion .binaryMapped {
50- case version if version.startsWith(" 0." ) => " 2.11"
51- case version => version
52- })
51+ moduleID.crossVersion match {
52+ case _ : CrossVersion .Binary =>
53+ moduleID.cross(CrossVersion .binaryMapped {
54+ case version if version.startsWith(" 0." ) => " 2.11"
55+ case version => version
56+ })
57+ case _ =>
58+ moduleID
59+ }
5360 }
5461 }
5562
@@ -72,6 +79,37 @@ object DottyPlugin extends AutoPlugin {
7279 }
7380 }
7481
82+ /** Patches the IncOptions so that .tasty files are pruned as needed.
83+ *
84+ * This code is adapted from `scalaJSPatchIncOptions` in Scala.js, which needs
85+ * to do the exact same thing but for classfiles.
86+ *
87+ * This complicated logic patches the ClassfileManager factory of the given
88+ * IncOptions with one that is aware of .tasty files emitted by the Dotty
89+ * compiler. This makes sure that, when a .class file must be deleted, the
90+ * corresponding .tasty file is also deleted.
91+ */
92+ def dottyPatchIncOptions (incOptions : IncOptions ): IncOptions = {
93+ val inheritedNewClassfileManager = incOptions.newClassfileManager
94+ val newClassfileManager = () => new ClassfileManager {
95+ private [this ] val inherited = inheritedNewClassfileManager()
96+
97+ def delete (classes : Iterable [File ]): Unit = {
98+ inherited.delete(classes flatMap { classFile =>
99+ val dottyFiles = if (classFile.getPath endsWith " .class" ) {
100+ val f = new File (classFile.getAbsolutePath.stripSuffix(" .class" ) + " .tasty" )
101+ if (f.exists) List (f)
102+ else Nil
103+ } else Nil
104+ classFile :: dottyFiles
105+ })
106+ }
107+
108+ def generated (classes : Iterable [File ]): Unit = inherited.generated(classes)
109+ def complete (success : Boolean ): Unit = inherited.complete(success)
110+ }
111+ incOptions.withNewClassfileManager(newClassfileManager)
112+ }
75113
76114 override def projectSettings : Seq [Setting [_]] = {
77115 Seq (
@@ -93,9 +131,16 @@ object DottyPlugin extends AutoPlugin {
93131 scalaOrganization.value
94132 },
95133
134+ incOptions in Compile := {
135+ if (isDotty.value)
136+ dottyPatchIncOptions((incOptions in Compile ).value)
137+ else
138+ (incOptions in Compile ).value
139+ },
140+
96141 scalaBinaryVersion := {
97142 if (isDotty.value)
98- " 0.1 " // TODO: Fix sbt so that this isn't needed
143+ scalaVersion.value.split( " \\ . " ).take( 2 ).mkString( " . " ) // Not needed with sbt >= 0.13.16
99144 else
100145 scalaBinaryVersion.value
101146 }
0 commit comments