|
| 1 | +package dotty.tools.sbtplugin |
| 2 | + |
| 3 | +import sbt.* |
| 4 | +import sbt.Keys.* |
| 5 | +import scala.jdk.CollectionConverters.* |
| 6 | +import java.nio.file.Files |
| 7 | + |
| 8 | +object ScalaLibraryPlugin extends AutoPlugin { |
| 9 | + |
| 10 | + override def trigger = noTrigger |
| 11 | + |
| 12 | + val fetchScala2ClassFiles = taskKey[(Set[File], File)]("Fetch the files to use that were compiled with Scala 2") |
| 13 | + //val scala2LibraryVersion = settingKey[String]("Version of the Scala 2 Standard Library") |
| 14 | + |
| 15 | + override def projectSettings = Seq ( |
| 16 | + fetchScala2ClassFiles := { |
| 17 | + val stream = streams.value |
| 18 | + val cache = stream.cacheDirectory |
| 19 | + val target = cache / "scala-library-classes" |
| 20 | + val report = update.value |
| 21 | + |
| 22 | + val scalaLibraryBinaryJar = report.select( |
| 23 | + configuration = configurationFilter(), |
| 24 | + module = (_: ModuleID).name == "scala-library", |
| 25 | + artifact = artifactFilter(`type` = "jar")).headOption.getOrElse { |
| 26 | + sys.error(s"Could not fetch scala-library binary JAR") |
| 27 | + } |
| 28 | + |
| 29 | + if (!target.exists()) { |
| 30 | + IO.createDirectory(target) |
| 31 | + } |
| 32 | + |
| 33 | + (FileFunction.cached(cache / "fetch-scala-library-classes", FilesInfo.lastModified, FilesInfo.exists) { _ => |
| 34 | + stream.log.info(s"Unpacking scala-library binaries to persistent directory: ${target.getAbsolutePath}") |
| 35 | + IO.unzip(scalaLibraryBinaryJar, target) |
| 36 | + (target ** "*.class").get.toSet |
| 37 | + } (Set(scalaLibraryBinaryJar)), target) |
| 38 | + |
| 39 | + }, |
| 40 | + (Compile / compile) := { |
| 41 | + val stream = streams.value |
| 42 | + val target = (Compile / classDirectory).value |
| 43 | + val (files, reference) = fetchScala2ClassFiles.value; |
| 44 | + val analysis = (Compile / compile).value |
| 45 | + stream.log.info(s"Copying files from Scala 2 Standard Library to $target") |
| 46 | + for (file <- files; id <- file.relativeTo(reference).map(_.toString())) { |
| 47 | + if (filesToCopy(id)) { |
| 48 | + stream.log.debug(s"Copying file '${id}' to ${target / id}") |
| 49 | + IO.copyFile(file, target / id) |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + val overwrittenBinaries = Files.walk((Compile / classDirectory).value.toPath()) |
| 54 | + .iterator() |
| 55 | + .asScala |
| 56 | + .map(_.toFile) |
| 57 | + .map(_.relativeTo((Compile / classDirectory).value).get) |
| 58 | + .toSet |
| 59 | + val diff = files.filterNot(_.relativeTo(reference).exists(overwrittenBinaries)) |
| 60 | + |
| 61 | + IO.copy(diff.map { file => |
| 62 | + file -> (Compile / classDirectory).value / file.relativeTo(reference).get.getPath |
| 63 | + }) |
| 64 | + |
| 65 | + analysis |
| 66 | + } |
| 67 | + ) |
| 68 | + |
| 69 | + private lazy val filesToCopy = Set( |
| 70 | + "scala/Tuple1.class", |
| 71 | + "scala/Tuple2.class", |
| 72 | + "scala/collection/DoubleStepper.class", |
| 73 | + "scala/collection/IntStepper.class", |
| 74 | + "scala/collection/LongStepper.class", |
| 75 | + "scala/collection/immutable/DoubleVectorStepper.class", |
| 76 | + "scala/collection/immutable/IntVectorStepper.class", |
| 77 | + "scala/collection/immutable/LongVectorStepper.class", |
| 78 | + "scala/jdk/DoubleAccumulator.class", |
| 79 | + "scala/jdk/IntAccumulator.class", |
| 80 | + "scala/jdk/LongAccumulator.class", |
| 81 | + "scala/jdk/FunctionWrappers$FromJavaDoubleBinaryOperator.class", |
| 82 | + "scala/jdk/FunctionWrappers$FromJavaBooleanSupplier.class", |
| 83 | + "scala/jdk/FunctionWrappers$FromJavaDoubleConsumer.class", |
| 84 | + "scala/jdk/FunctionWrappers$FromJavaDoublePredicate.class", |
| 85 | + "scala/jdk/FunctionWrappers$FromJavaDoubleSupplier.class", |
| 86 | + "scala/jdk/FunctionWrappers$FromJavaDoubleToIntFunction.class", |
| 87 | + "scala/jdk/FunctionWrappers$FromJavaDoubleToLongFunction.class", |
| 88 | + "scala/jdk/FunctionWrappers$FromJavaIntBinaryOperator.class", |
| 89 | + "scala/jdk/FunctionWrappers$FromJavaDoubleUnaryOperator.class", |
| 90 | + "scala/jdk/FunctionWrappers$FromJavaIntPredicate.class", |
| 91 | + "scala/jdk/FunctionWrappers$FromJavaIntConsumer.class", |
| 92 | + "scala/jdk/FunctionWrappers$FromJavaIntSupplier.class", |
| 93 | + "scala/jdk/FunctionWrappers$FromJavaIntToDoubleFunction.class", |
| 94 | + "scala/jdk/FunctionWrappers$FromJavaIntToLongFunction.class", |
| 95 | + "scala/jdk/FunctionWrappers$FromJavaIntUnaryOperator.class", |
| 96 | + "scala/jdk/FunctionWrappers$FromJavaLongBinaryOperator.class", |
| 97 | + "scala/jdk/FunctionWrappers$FromJavaLongConsumer.class", |
| 98 | + "scala/jdk/FunctionWrappers$FromJavaLongPredicate.class", |
| 99 | + "scala/jdk/FunctionWrappers$FromJavaLongSupplier.class", |
| 100 | + "scala/jdk/FunctionWrappers$FromJavaLongToDoubleFunction.class", |
| 101 | + "scala/jdk/FunctionWrappers$FromJavaLongToIntFunction.class", |
| 102 | + "scala/jdk/FunctionWrappers$FromJavaLongUnaryOperator.class", |
| 103 | + "scala/collection/ArrayOps$ReverseIterator.class", |
| 104 | + "scala/runtime/NonLocalReturnControl.class", |
| 105 | + "scala/util/Sorting.class", "scala/util/Sorting$.class", // Contains @specialized annotation |
| 106 | + ) |
| 107 | + |
| 108 | +} |
0 commit comments