Skip to content

Commit 919f02c

Browse files
committed
.
1 parent ee4ed2b commit 919f02c

File tree

2 files changed

+26
-18
lines changed

2 files changed

+26
-18
lines changed

project/Build.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ object Build {
12651265
}
12661266
)
12671267

1268-
lazy val `scala3-repl-embedded` = project.in(file("repl-shaded"))
1268+
lazy val `scala3-repl-embedded` = project.in(file("repl-embedded"))
12691269
.dependsOn(`scala-library-bootstrapped`)
12701270
.enablePlugins(sbtassembly.AssemblyPlugin)
12711271
.settings(publishSettings)
@@ -1320,8 +1320,8 @@ object Build {
13201320
val relativePath = file.relativeTo(tmpDir).get.getPath
13211321

13221322
val shouldKeepInPlace =
1323-
relativePath.startsWith("scala/tools/repl/")||
1324-
// These are manually shaded so leave them alone
1323+
relativePath.startsWith("dotty/embedded/")||
1324+
// These are manually shaded when vendored/patched so leave them alone
13251325
relativePath.startsWith("dotty/shaded/") ||
13261326
// This needs to be inside scala/collection so cannot be moved
13271327
relativePath.startsWith("scala/collection/internal/pprint/")

repl-shaded/src/scala/tools/repl/EmbeddedReplMain.scala renamed to repl-embedded/src/dotty/embedded/EmbeddedReplMain.scala

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
1-
package scala.tools.repl
1+
package dotty.embedded
22

33
import java.net.{URL, URLClassLoader}
44
import java.io.InputStream
55

66
/**
77
* A classloader that remaps shaded classes back to their original package names.
8-
*
9-
* This classloader intercepts class loading requests and remaps them from
10-
* dotty.tools.repl.shaded.* back to their original package names, allowing the
11-
* shaded classes to be loaded as if they were in their original packages.
12-
*
13-
* The scala.* packages are not shaded, so they pass through normally.
148
*/
159
class UnshadingClassLoader(parent: ClassLoader) extends ClassLoader(parent) {
1610

17-
private val SHADED_PREFIX = "dotty.isolated."
11+
// dotty.isolated classes are loaded only within the REPL impl classloader.
12+
// They exist in the enclosing classpath relocated within the dotty.isolated
13+
// package, but are relocated to their proper package when the REPL impl
14+
// classloader loads them
15+
private val ISOLATED_PREFIX = "dotty.isolated."
1816

1917
override def loadClass(name: String, resolve: Boolean): Class[?] = {
2018
val loaded = findLoadedClass(name)
2119
if (loaded != null) return loaded
2220

23-
val shadedPath = (SHADED_PREFIX + name).replace('.', '/') + ".class"
21+
// dotty.shaded classes are loaded separately between the REPL line classloader
22+
// and the REPL impl classloader, but at the same path because the REPL line
23+
// classloader doesn't tolerate relocating classfiles
24+
val shadedPath = (if (name.startsWith("dotty.shaded.")) name else ISOLATED_PREFIX + name)
25+
.replace('.', '/') + ".class"
26+
2427
val is0 = scala.util.Try(Option(super.getResourceAsStream(shadedPath))).toOption.flatten
2528

2629
is0 match{
@@ -29,17 +32,22 @@ class UnshadingClassLoader(parent: ClassLoader) extends ClassLoader(parent) {
2932
val bytes = is.readAllBytes()
3033
val clazz = defineClass(name, bytes, 0, bytes.length)
3134
if (resolve) resolveClass(clazz)
32-
return clazz
35+
clazz
3336
} finally is.close()
34-
case None => super.loadClass(name, resolve)
37+
case None =>
38+
// These classes are loaded shared between all classloaders, because
39+
// they misbehave if loaded multiple times in separate classloaders
40+
if (name.startsWith("java.") || name.startsWith("org.jline.")) parent.loadClass(name)
41+
// Other classes loaded by the `UnshadingClassLoader` *must* be found in the
42+
// `dotty.isolated` package. If they're not there, throw an error rather than
43+
// trying to look for them at their normal package path, to ensure we're not
44+
// accidentally pulling stuff in from the enclosing classloader
45+
else throw new ClassNotFoundException(name)
3546
}
3647
}
3748

3849
override def getResourceAsStream(name: String): InputStream | Null = {
39-
val shadedPath = SHADED_PREFIX.replace('.', '/') + name
40-
val shadedStream = super.getResourceAsStream(shadedPath)
41-
if (shadedStream != null) return shadedStream
42-
else super.getResourceAsStream(name)
50+
super.getResourceAsStream(ISOLATED_PREFIX.replace('.', '/') + name)
4351
}
4452
}
4553

0 commit comments

Comments
 (0)