@@ -2,6 +2,7 @@ package dotty.tools.sbtplugin
2
2
3
3
import sbt ._
4
4
import sbt .Keys ._
5
+ import sbt .inc .{ ClassfileManager , IncOptions }
5
6
6
7
object DottyPlugin extends AutoPlugin {
7
8
object autoImport {
@@ -27,7 +28,8 @@ object DottyPlugin extends AutoPlugin {
27
28
28
29
implicit class DottyCompatModuleID (moduleID : ModuleID ) {
29
30
/** 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.
31
33
*
32
34
* This setting is useful when your build contains dependencies that have only
33
35
* been published with Scala 2.x, if you have:
@@ -46,10 +48,15 @@ object DottyPlugin extends AutoPlugin {
46
48
* Dotty is released, you should not rely on it.
47
49
*/
48
50
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
+ }
53
60
}
54
61
}
55
62
@@ -72,6 +79,37 @@ object DottyPlugin extends AutoPlugin {
72
79
}
73
80
}
74
81
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
+ }
75
113
76
114
override def projectSettings : Seq [Setting [_]] = {
77
115
Seq (
@@ -93,9 +131,16 @@ object DottyPlugin extends AutoPlugin {
93
131
scalaOrganization.value
94
132
},
95
133
134
+ incOptions in Compile := {
135
+ if (isDotty.value)
136
+ dottyPatchIncOptions((incOptions in Compile ).value)
137
+ else
138
+ (incOptions in Compile ).value
139
+ },
140
+
96
141
scalaBinaryVersion := {
97
142
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
99
144
else
100
145
scalaBinaryVersion.value
101
146
}
0 commit comments