Skip to content

Commit c05242b

Browse files
committed
chore: extract repl to be its own artifact
1 parent d254f06 commit c05242b

File tree

156 files changed

+272
-114
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

156 files changed

+272
-114
lines changed

build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ val `scala3-compiler` = Build.`scala3-compiler`
77
val `scala3-compiler-nonbootstrapped` = Build.`scala3-compiler-nonbootstrapped`
88
val `scala3-compiler-bootstrapped-new` = Build.`scala3-compiler-bootstrapped-new`
99
val `scala3-compiler-bootstrapped` = Build.`scala3-compiler-bootstrapped`
10+
val `scala3-repl` = Build.`scala3-repl`
1011
val `scala-library-sjs` = Build.`scala-library-sjs`
1112
val `scala3-library-sjs` = Build.`scala3-library-sjs`
1213
val `scala-library-nonbootstrapped` = Build.`scala-library-nonbootstrapped`

compiler/src/dotty/tools/dotc/quoted/Interpreter.scala

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import dotty.tools.dotc.quoted.*
2525
import dotty.tools.dotc.typer.ImportInfo.withRootImports
2626
import dotty.tools.dotc.util.SrcPos
2727
import dotty.tools.dotc.reporting.Message
28-
import dotty.tools.repl.AbstractFileClassLoader
28+
import dotty.tools.io.AbstractFileClassLoader
2929
import dotty.tools.dotc.core.CyclicReference
3030

3131
/** Tree interpreter for metaprogramming constructs */
@@ -35,7 +35,7 @@ class Interpreter(pos: SrcPos, classLoader0: ClassLoader)(using Context):
3535

3636
val classLoader =
3737
if ctx.owner.topLevelClass.name.startsWith(str.REPL_SESSION_LINE) then
38-
new AbstractFileClassLoader(ctx.settings.outputDir.value, classLoader0, "false")
38+
new AbstractFileClassLoader(ctx.settings.outputDir.value, classLoader0)
3939
else classLoader0
4040

4141
/** Local variable environment */
@@ -204,11 +204,7 @@ class Interpreter(pos: SrcPos, classLoader0: ClassLoader)(using Context):
204204
}
205205

206206
private def loadReplLineClass(moduleClass: Symbol): Class[?] = {
207-
val lineClassloader = new AbstractFileClassLoader(
208-
ctx.settings.outputDir.value,
209-
classLoader,
210-
"false"
211-
)
207+
val lineClassloader = new AbstractFileClassLoader(ctx.settings.outputDir.value, classLoader)
212208
lineClassloader.loadClass(moduleClass.name.firstPart.toString)
213209
}
214210

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import dotty.tools.dotc.quoted.Interpreter
2222

2323
import scala.util.control.NonFatal
2424
import dotty.tools.dotc.util.SrcPos
25-
import dotty.tools.repl.AbstractFileClassLoader
25+
import dotty.tools.io.AbstractFileClassLoader
2626

2727
import scala.reflect.ClassTag
2828

compiler/src/dotty/tools/dotc/util/ClasspathFromClassloader.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import scala.language.unsafeNulls
55
import java.net.URLClassLoader
66
import java.nio.file.Paths
77

8-
import dotty.tools.repl.AbstractFileClassLoader
8+
import dotty.tools.io.AbstractFileClassLoader
99

1010
object ClasspathFromClassloader {
1111

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Scala (https://www.scala-lang.org)
3+
*
4+
* Copyright EPFL and Lightbend, Inc.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (http://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package dotty.tools
14+
package io
15+
16+
import scala.language.unsafeNulls
17+
18+
import dotty.tools.io.AbstractFile
19+
20+
import java.net.{URL, URLConnection, URLStreamHandler}
21+
import java.util.Collections
22+
23+
class AbstractFileClassLoader(val root: AbstractFile, parent: ClassLoader) extends ClassLoader(parent):
24+
private def findAbstractFile(name: String) = root.lookupPath(name.split('/').toIndexedSeq, directory = false)
25+
26+
// on JDK 20 the URL constructor we're using is deprecated,
27+
// but the recommended replacement, URL.of, doesn't exist on JDK 8
28+
@annotation.nowarn("cat=deprecation")
29+
override protected def findResource(name: String): URL | Null =
30+
findAbstractFile(name) match
31+
case null => null
32+
case file => new URL(null, s"memory:${file.path}", new URLStreamHandler {
33+
override def openConnection(url: URL): URLConnection = new URLConnection(url) {
34+
override def connect() = ()
35+
override def getInputStream = file.input
36+
}
37+
})
38+
override protected def findResources(name: String): java.util.Enumeration[URL] =
39+
findResource(name) match
40+
case null => Collections.enumeration(Collections.emptyList[URL]) //Collections.emptyEnumeration[URL]
41+
case url => Collections.enumeration(Collections.singleton(url))
42+
43+
override def findClass(name: String): Class[?] = {
44+
var file: AbstractFile | Null = root
45+
val pathParts = name.split("[./]").toList
46+
for (dirPart <- pathParts.init) {
47+
file = file.lookupName(dirPart, true)
48+
if (file == null) {
49+
throw new ClassNotFoundException(name)
50+
}
51+
}
52+
file = file.lookupName(pathParts.last+".class", false)
53+
if (file == null) {
54+
throw new ClassNotFoundException(name)
55+
}
56+
val bytes = file.toByteArray
57+
defineClass(name, bytes, 0, bytes.length)
58+
}
59+
60+
override def loadClass(name: String): Class[?] = try findClass(name) catch case _: ClassNotFoundException => super.loadClass(name)
61+
end AbstractFileClassLoader

compiler/src/dotty/tools/repl/package.scala

Lines changed: 0 additions & 10 deletions
This file was deleted.

project/Build.scala

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -724,9 +724,6 @@ object Build {
724724
libraryDependencies ++= Seq(
725725
"org.scala-lang.modules" % "scala-asm" % "9.8.0-scala-1", // used by the backend
726726
Dependencies.compilerInterface,
727-
"org.jline" % "jline-reader" % "3.29.0", // used by the REPL
728-
"org.jline" % "jline-terminal" % "3.29.0",
729-
"org.jline" % "jline-terminal-jni" % "3.29.0", // needed for Windows
730727
("io.get-coursier" %% "coursier" % "2.0.16" % Test).cross(CrossVersion.for3Use2_13),
731728
),
732729

@@ -1479,7 +1476,8 @@ object Build {
14791476
.enablePlugins(ScriptedPlugin)
14801477
.aggregate(`scala3-interfaces`, `scala3-library-bootstrapped-new` , `scala-library-bootstrapped`,
14811478
`tasty-core-bootstrapped-new`, `scala3-compiler-bootstrapped-new`, `scala3-sbt-bridge-bootstrapped`,
1482-
`scala3-staging-new`, `scala3-tasty-inspector-new`, `scala-library-sjs`, `scala3-library-sjs`, `scaladoc-new`)
1479+
`scala3-staging-new`, `scala3-tasty-inspector-new`, `scala-library-sjs`, `scala3-library-sjs`,
1480+
`scaladoc-new`, `scala3-repl`)
14831481
.settings(
14841482
name := "scala3-bootstrapped",
14851483
moduleName := "scala3-bootstrapped",
@@ -1594,7 +1592,7 @@ object Build {
15941592

15951593
/* Configuration of the org.scala-lang:scala3-sbt-bridge:*.**.**-bootstrapped project */
15961594
lazy val `scala3-sbt-bridge-bootstrapped` = project.in(file("sbt-bridge"))
1597-
.dependsOn(`scala3-compiler-bootstrapped-new`) // TODO: Would this actually evict the reference compiler in scala-tool?
1595+
.dependsOn(`scala3-compiler-bootstrapped-new`, `scala3-repl`) // TODO: Would this actually evict the reference compiler in scala-tool?
15981596
.settings(publishSettings)
15991597
.settings(
16001598
name := "scala3-sbt-bridge-bootstrapped",
@@ -1607,6 +1605,7 @@ object Build {
16071605
// Add the source directories for the sbt-bridge (boostrapped)
16081606
Compile / unmanagedSourceDirectories := Seq(baseDirectory.value / "src"),
16091607
Test / unmanagedSourceDirectories := Seq(baseDirectory.value / "test"),
1608+
Compile / unmanagedSourceDirectories += baseDirectory.value / "src-bootstrapped",
16101609
Compile / resourceDirectory := baseDirectory.value / "resources",
16111610
// NOTE: The only difference here is that we drop `-Werror` and semanticDB for now
16121611
Compile / scalacOptions := Seq("-deprecation", "-feature", "-unchecked", "-encoding", "UTF8", "-language:implicitConversions"),
@@ -1773,6 +1772,90 @@ object Build {
17731772
},
17741773
)
17751774

1775+
lazy val `scala3-repl` = project.in(file("repl"))
1776+
.dependsOn(`scala3-compiler-bootstrapped-new` % "compile->compile;test->test")
1777+
.settings(publishSettings)
1778+
.settings(
1779+
name := "scala3-repl",
1780+
moduleName := "scala3-repl",
1781+
version := dottyVersion,
1782+
versionScheme := Some("semver-spec"),
1783+
scalaVersion := referenceVersion,
1784+
crossPaths := true, // org.scala-lang:scala3-tasty-inspector has a crosspath
1785+
autoScalaLibrary := false, // do not add a dependency to stdlib, we depend transitively on the stdlib from `scala3-compiler-bootstrapped`
1786+
// Add the source directories for the sbt-bridge (boostrapped)
1787+
Compile / unmanagedSourceDirectories := Seq(baseDirectory.value / "src"),
1788+
Test / unmanagedSourceDirectories := Seq(baseDirectory.value / "test"),
1789+
// NOTE: The only difference here is that we drop `-Werror` and semanticDB for now
1790+
Compile / scalacOptions := Seq("-deprecation", "-feature", "-unchecked", "-encoding", "UTF8", "-language:implicitConversions"),
1791+
// Make sure that the produced artifacts have the minimum JVM version in the bytecode
1792+
Compile / javacOptions ++= Seq("--release", Versions.minimumJVMVersion),
1793+
Compile / scalacOptions ++= Seq("--java-output-version", Versions.minimumJVMVersion),
1794+
// Packaging configuration of `scala3-staging`
1795+
Compile / packageBin / publishArtifact := true,
1796+
Compile / packageDoc / publishArtifact := false,
1797+
Compile / packageSrc / publishArtifact := true,
1798+
// Only publish compilation artifacts, no test artifacts
1799+
Test / publishArtifact := false,
1800+
publish / skip := false,
1801+
libraryDependencies ++= Seq(
1802+
"com.github.sbt" % "junit-interface" % "0.13.3" % Test,
1803+
),
1804+
// Configure to use the non-bootstrapped compiler
1805+
scalaInstance := {
1806+
val externalCompilerDeps = (`scala3-compiler-nonbootstrapped` / Compile / externalDependencyClasspath).value.map(_.data).toSet
1807+
1808+
// IMPORTANT: We need to use actual jars to form the ScalaInstance and not
1809+
// just directories containing classfiles because sbt maintains a cache of
1810+
// compiler instances. This cache is invalidated based on timestamps
1811+
// however this is only implemented on jars, directories are never
1812+
// invalidated.
1813+
val tastyCore = (`tasty-core-nonbootstrapped` / Compile / packageBin).value
1814+
val scalaLibrary = (`scala-library-nonbootstrapped` / Compile / packageBin).value
1815+
val scala3Interfaces = (`scala3-interfaces` / Compile / packageBin).value
1816+
val scala3Compiler = (`scala3-compiler-nonbootstrapped` / Compile / packageBin).value
1817+
1818+
Defaults.makeScalaInstance(
1819+
dottyNonBootstrappedVersion,
1820+
libraryJars = Array(scalaLibrary),
1821+
allCompilerJars = Seq(tastyCore, scala3Interfaces, scala3Compiler) ++ externalCompilerDeps,
1822+
allDocJars = Seq.empty,
1823+
state.value,
1824+
scalaInstanceTopLoader.value
1825+
)
1826+
},
1827+
scalaCompilerBridgeBinaryJar := {
1828+
Some((`scala3-sbt-bridge-nonbootstrapped` / Compile / packageBin).value)
1829+
},
1830+
Test / javaOptions ++= {
1831+
val log = streams.value.log
1832+
val managedSrcDir = {
1833+
// Populate the directory
1834+
(Compile / managedSources).value
1835+
1836+
(Compile / sourceManaged).value
1837+
}
1838+
val externalDeps = (ThisProject / Runtime / externalDependencyClasspath).value
1839+
Seq(
1840+
s"-Ddotty.tests.dottyCompilerManagedSources=${managedSrcDir}",
1841+
s"-Ddotty.tests.classes.dottyInterfaces=${(`scala3-interfaces` / Compile / packageBin).value}",
1842+
s"-Ddotty.tests.classes.dottyCompiler=${(ThisProject / Compile / packageBin).value}",
1843+
s"-Ddotty.tests.classes.tastyCore=${(`tasty-core-bootstrapped-new` / Compile / packageBin).value}",
1844+
s"-Ddotty.tests.classes.compilerInterface=${findArtifactPath(externalDeps, "compiler-interface")}",
1845+
s"-Ddotty.tests.classes.scalaLibrary=${(`scala-library-bootstrapped` / Compile / packageBin).value}",
1846+
s"-Ddotty.tests.classes.scalaJSScalalib=${(`scala-library-sjs` / Compile / packageBin).value}",
1847+
s"-Ddotty.tests.classes.scalaAsm=${findArtifactPath(externalDeps, "scala-asm")}",
1848+
s"-Ddotty.tests.classes.jlineTerminal=${findArtifactPath(externalDeps, "jline-terminal")}",
1849+
s"-Ddotty.tests.classes.jlineReader=${findArtifactPath(externalDeps, "jline-reader")}",
1850+
s"-Ddotty.tests.classes.dottyStaging=${(LocalProject("scala3-staging-new") / Compile / packageBin).value}",
1851+
s"-Ddotty.tests.classes.dottyTastyInspector=${(LocalProject("scala3-tasty-inspector-new") / Compile / packageBin).value}",
1852+
s"-Ddotty.tools.dotc.semanticdb.test=${(ThisBuild / baseDirectory).value/"tests"/"semanticdb"}",
1853+
)
1854+
},
1855+
Test / forkOptions :=
1856+
(Test / forkOptions).value.withWorkingDirectory((ThisBuild / baseDirectory).value),
1857+
)
1858+
17761859
// ==============================================================================================
17771860
// =================================== SCALA STANDARD LIBRARY ===================================
17781861
// ==============================================================================================
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
scala.tools.repl.ScriptEngine$Factory

compiler/src/dotty/tools/repl/AbstractFileClassLoader.scala renamed to repl/src/dotty/tools/repl/AbstractFileClassLoader.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package repl
1616
import scala.language.unsafeNulls
1717

1818
import io.AbstractFile
19-
import dotty.tools.repl.ReplBytecodeInstrumentation
2019

2120
import java.net.{URL, URLConnection, URLStreamHandler}
2221
import java.util.Collections

compiler/src/dotty/tools/repl/CollectTopLevelImports.scala renamed to repl/src/dotty/tools/repl/CollectTopLevelImports.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
package dotty.tools.repl
1+
package dotty.tools
2+
package repl
23

3-
import dotty.tools.dotc.ast.tpd
4-
import dotty.tools.dotc.core.Contexts.*
5-
import dotty.tools.dotc.core.Phases.Phase
4+
import dotc.ast.tpd
5+
import dotc.core.Contexts.*
6+
import dotc.core.Phases.Phase
67

78
import scala.compiletime.uninitialized
89

0 commit comments

Comments
 (0)