Skip to content

Commit b0059ff

Browse files
committed
chore: first draft of the stdlib
1 parent 4cb43b6 commit b0059ff

14 files changed

+3936
-80
lines changed

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ class TreePickler(pickler: TastyPickler, attributes: Attributes) {
861861
assert(isModifierTag(tag))
862862
writeByte(tag)
863863
}
864-
assert(!flags.is(Scala2x))
864+
//assert(!flags.is(Scala2x))
865865
if (flags.is(Private)) writeModTag(PRIVATE)
866866
if (flags.is(Protected)) writeModTag(PROTECTED)
867867
if (flags.is(Final, butNot = Module)) writeModTag(FINAL)

compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ class ExtensionMethods extends MiniPhase with DenotTransformer with FullParamete
7777
// Create extension methods, except if the class comes from Scala 2
7878
// because it adds extension methods before pickling.
7979
if !valueClass.is(Scala2x, butNot = Scala2Tasty) then
80-
for (decl <- valueClass.classInfo.decls)
81-
if isMethodWithExtension(decl) then
82-
enterInModuleClass(createExtensionMethod(decl, moduleClassSym.symbol))
80+
for (decl <- valueClass.classInfo.decls)
81+
if isMethodWithExtension(decl) then
82+
enterInModuleClass(createExtensionMethod(decl, moduleClassSym.symbol))
8383

8484
// Create synthetic methods to cast values between the underlying type
8585
// and the ErasedValueType. These methods are removed in ElimErasedValueType.

compiler/src/dotty/tools/dotc/typer/Namer.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,9 @@ class Namer { typer: Typer =>
246246

247247
tree match {
248248
case tree: TypeDef if tree.isClassDef =>
249-
val flags = checkFlags(tree.mods.flags)
249+
var flags = checkFlags(tree.mods.flags)
250+
if ctx.settings.YcompileScala2Library.value then
251+
flags |= Scala2x | Scala2Tasty
250252
val name = checkNoConflict(tree.name, flags.is(Private), tree.span).asTypeName
251253
val cls =
252254
createOrRefine[ClassSymbol](tree, name, flags, ctx.owner,

project/Build.scala

+5-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import sbt.Package.ManifestAttributes
2020
import sbt.PublishBinPlugin.autoImport._
2121
import dotty.tools.sbtplugin.RepublishPlugin
2222
import dotty.tools.sbtplugin.RepublishPlugin.autoImport._
23+
import dotty.tools.sbtplugin.ScalaLibraryPlugin
24+
2325
import sbt.plugins.SbtPlugin
2426
import sbt.ScriptedPlugin.autoImport._
2527
import xerial.sbt.Sonatype.autoImport._
@@ -32,6 +34,8 @@ import sbtbuildinfo.BuildInfoPlugin.autoImport._
3234
import sbttastymima.TastyMiMaPlugin
3335
import sbttastymima.TastyMiMaPlugin.autoImport._
3436

37+
import scala.jdk.CollectionConverters._
38+
3539
import scala.util.Properties.isJavaAtLeast
3640

3741
import org.portablescala.sbtplatformdeps.PlatformDepsPlugin.autoImport._
@@ -1207,9 +1211,9 @@ object Build {
12071211
* This version of the library is not (yet) TASTy/binary compatible with the Scala 2 compiled library.
12081212
*/
12091213
lazy val `scala2-library-bootstrapped` = project.in(file("scala2-library-bootstrapped")).
1214+
enablePlugins(ScalaLibraryPlugin).
12101215
withCommonSettings(Bootstrapped).
12111216
dependsOn(dottyCompiler(Bootstrapped) % "provided; compile->runtime; test->test").
1212-
settings(commonBootstrappedSettings).
12131217
settings(scala2LibraryBootstrappedSettings).
12141218
settings(moduleName := "scala2-library")
12151219
// -Ycheck:all is set in project/scripts/scala2-library-tasty-mima.sh
@@ -1221,7 +1225,6 @@ object Build {
12211225
lazy val `scala2-library-cc` = project.in(file("scala2-library-cc")).
12221226
withCommonSettings(Bootstrapped).
12231227
dependsOn(dottyCompiler(Bootstrapped) % "provided; compile->runtime; test->test").
1224-
settings(commonBootstrappedSettings).
12251228
settings(scala2LibraryBootstrappedSettings).
12261229
settings(
12271230
moduleName := "scala2-library-cc",

project/Scala2LibraryBootstrappedMiMaFilters.scala

+27-73
Original file line numberDiff line numberDiff line change
@@ -4,79 +4,33 @@ import com.typesafe.tools.mima.core._
44
object Scala2LibraryBootstrappedMiMaFilters {
55

66
val BackwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map(
7-
Build.stdlibBootstrappedVersion -> {
8-
Seq(
9-
// Files that are not compiled in the bootstrapped library
10-
ProblemFilters.exclude[MissingClassProblem]("scala.AnyVal"),
11-
12-
// Scala language features
13-
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.language.<clinit>"),
14-
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.language#experimental.<clinit>"),
15-
ProblemFilters.exclude[FinalClassProblem]("scala.language$experimental$"),
16-
ProblemFilters.exclude[FinalClassProblem]("scala.languageFeature$*$"),
17-
18-
// Value class extension methods
19-
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*$extension"),
20-
21-
// Companion module class
22-
ProblemFilters.exclude[FinalClassProblem]("scala.*$"),
23-
24-
// Scala 2 intrinsic macros
25-
ProblemFilters.exclude[FinalMethodProblem]("scala.StringContext.s"),
26-
27-
// Specialization?
28-
ProblemFilters.exclude[MissingFieldProblem]("scala.Tuple1._1"), // field _1 in class scala.Tuple1 does not have a correspondent in current version
29-
ProblemFilters.exclude[MissingFieldProblem]("scala.Tuple2._1"), // field _1 in class scala.Tuple2 does not have a correspondent in current version
30-
ProblemFilters.exclude[MissingFieldProblem]("scala.Tuple2._2"), // field _2 in class scala.Tuple2 does not have a correspondent in current version
31-
32-
// Scala 2 specialization
33-
ProblemFilters.exclude[MissingClassProblem]("scala.*$sp"),
34-
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*$sp"),
35-
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*#*#sp.$init$"),
36-
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.DoubleStepper"),
37-
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.DoubleVectorStepper"),
38-
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.IntVectorStepper"),
39-
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.immutable.LongVectorStepper"),
40-
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.IntStepper"),
41-
ProblemFilters.exclude[MissingTypesProblem]("scala.collection.LongStepper"),
42-
ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.DoubleAccumulator"),
43-
ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.FunctionWrappers$*"),
44-
ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.IntAccumulator"),
45-
ProblemFilters.exclude[MissingTypesProblem]("scala.jdk.LongAccumulator"),
46-
ProblemFilters.exclude[FinalClassProblem]("scala.collection.ArrayOps$ReverseIterator"),
47-
ProblemFilters.exclude[FinalClassProblem]("scala.Tuple1"),
48-
ProblemFilters.exclude[FinalClassProblem]("scala.Tuple2"),
49-
50-
// other
51-
ProblemFilters.exclude[FinalMethodProblem]("scala.Enumeration.ValueOrdering"),
52-
ProblemFilters.exclude[FinalMethodProblem]("scala.Enumeration.ValueSet"),
53-
ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.NoPositioner"),
54-
ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.RelaxedPosition"),
55-
ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.RelaxedPositioner"),
56-
ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.SortedMapOps.coll"),
57-
ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.TreeMap.empty"),
58-
ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.TreeMap.fromSpecific"),
59-
ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.mutable.ArrayBuilder#ofUnit.addAll"),
60-
ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.mutable.TreeMap.empty"),
61-
ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.mutable.TreeMap.fromSpecific"),
62-
ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.reflect.ManifestFactory#NothingManifest.newArray"),
63-
ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.reflect.ManifestFactory#NullManifest.newArray"),
64-
ProblemFilters.exclude[MissingFieldProblem]("scala.collection.ArrayOps#ReverseIterator.xs"),
65-
ProblemFilters.exclude[MissingFieldProblem]("scala.runtime.NonLocalReturnControl.value"),
66-
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.collection.immutable.SortedMapOps.coll"),
67-
) ++
68-
Seq( // DirectMissingMethodProblem
69-
"scala.collection.LinearSeqIterator#LazyCell.this",
70-
"scala.collection.mutable.PriorityQueue#ResizableArrayAccess.this",
71-
"scala.concurrent.BatchingExecutor#AbstractBatch.this",
72-
"scala.concurrent.Channel#LinkedList.this",
73-
"scala.Enumeration#ValueOrdering.this",
74-
"scala.io.Source#RelaxedPosition.this",
75-
"scala.collection.IterableOnceOps#Maximized.this", // New in 2.13.11: private inner class
76-
"scala.util.Properties.<clinit>",
77-
"scala.util.Sorting.scala$util$Sorting$$mergeSort$default$5",
78-
).map(ProblemFilters.exclude[DirectMissingMethodProblem])
79-
}
7+
Build.stdlibBootstrappedVersion -> Seq(
8+
// Scala language features (not really a problem)
9+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.language.<clinit>"),
10+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.language#experimental.<clinit>"),
11+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.util.Properties.<clinit>"),
12+
13+
// Companion module class (not really a problem)
14+
ProblemFilters.exclude[FinalClassProblem]("scala.*$"),
15+
ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.NoPositioner"),
16+
ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.RelaxedPosition"),
17+
ProblemFilters.exclude[FinalMethodProblem]("scala.io.Source.RelaxedPositioner"),
18+
ProblemFilters.exclude[FinalMethodProblem]("scala.Enumeration.ValueOrdering"),
19+
ProblemFilters.exclude[FinalMethodProblem]("scala.Enumeration.ValueSet"),
20+
ProblemFilters.exclude[FinalMethodProblem]("scala.StringContext.s"),
21+
22+
// Need to be fixed
23+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.*$extension"),
24+
//ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.SortedMapOps.coll"),
25+
//ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.TreeMap.empty"),
26+
//ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.immutable.TreeMap.fromSpecific"),
27+
//ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.mutable.ArrayBuilder#ofUnit.addAll"),
28+
//ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.mutable.TreeMap.empty"),
29+
//ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.collection.mutable.TreeMap.fromSpecific"),
30+
//ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.reflect.ManifestFactory#NothingManifest.newArray"),
31+
//ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.reflect.ManifestFactory#NullManifest.newArray"),
32+
//ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.collection.immutable.SortedMapOps.coll"),
33+
)
8034
)
8135

8236
val ForwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map(

project/ScalaLibraryPlugin.scala

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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

Comments
 (0)