-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Provided a repl-embedded artifact which shades and isolates everything to avoid conflicts
#24494
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
lihaoyi
wants to merge
44
commits into
scala:main
Choose a base branch
from
lihaoyi:embedded-repl
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+421
−42
Open
Changes from all commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
22d77f1
.
lihaoyi 8ec198f
wip
lihaoyi 8b17db9
wip
lihaoyi 817e279
wip
lihaoyi a04c07a
cleanup
lihaoyi 04a8d16
cleanup
lihaoyi 1276bd0
cleanup
lihaoyi b7f7a50
cleanup
lihaoyi 0c3e845
.
lihaoyi 1d3b2f7
wip
lihaoyi 0a499d5
wip
lihaoyi 410d679
wip
lihaoyi 9b686ca
wip
lihaoyi 21539f8
wip
lihaoyi a5c0f83
wip
lihaoyi 94f34c1
wip
lihaoyi 0d91336
more-isolation
lihaoyi 312a5d2
.
lihaoyi 2d1adcd
.
lihaoyi 7965f9e
.
lihaoyi 0a2e8e9
.
lihaoyi a6be2bf
.
lihaoyi 4930d18
.
lihaoyi 66a1641
.
lihaoyi 0e292bc
.
lihaoyi 0caff87
merge
lihaoyi 108756f
Merge branch 'repl-bindings' into embedded-repl-bindings
lihaoyi 52a6891
.
lihaoyi d50f5b1
.
lihaoyi 4ad3f79
.
lihaoyi 4ea6918
.
lihaoyi 772185a
.
lihaoyi a9ac383
.
lihaoyi a01ae3e
.
lihaoyi c9467f2
.
lihaoyi 8f60a5c
.
lihaoyi b6b098c
.
lihaoyi e25b15a
.
lihaoyi d139dfb
.
lihaoyi ee4ed2b
.
lihaoyi 919f02c
.
lihaoyi bcae8fb
.
lihaoyi 1fbb3a5
.
lihaoyi 6748da0
.
lihaoyi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| package dotty.embedded | ||
|
|
||
| import java.net.{URL, URLClassLoader} | ||
| import java.io.InputStream | ||
|
|
||
| /** | ||
| * A classloader that remaps shaded classes back to their original package names. | ||
| */ | ||
| class UnshadingClassLoader(parent: ClassLoader) extends ClassLoader(parent) { | ||
|
|
||
| // dotty.isolated classes are loaded only within the REPL impl classloader. | ||
| // They exist in the enclosing classpath relocated within the dotty.isolated | ||
| // package, but are relocated to their proper package when the REPL impl | ||
| // classloader loads them | ||
| private val ISOLATED_PREFIX = "dotty.isolated." | ||
|
|
||
| override def loadClass(name: String, resolve: Boolean): Class[?] = { | ||
| val loaded = findLoadedClass(name) | ||
| if (loaded != null) return loaded | ||
|
|
||
| // dotty.shaded classes are loaded separately between the REPL line classloader | ||
| // and the REPL impl classloader, but at the same path because the REPL line | ||
| // classloader doesn't tolerate relocating classfiles | ||
| val shadedPath = (if (name.startsWith("dotty.shaded.")) name else ISOLATED_PREFIX + name) | ||
| .replace('.', '/') + ".class" | ||
|
|
||
| val is0 = scala.util.Try(Option(super.getResourceAsStream(shadedPath))).toOption.flatten | ||
|
|
||
| is0 match{ | ||
| case Some(is) => | ||
| try { | ||
| val bytes = is.readAllBytes() | ||
| val clazz = defineClass(name, bytes, 0, bytes.length) | ||
| if (resolve) resolveClass(clazz) | ||
| clazz | ||
| } finally is.close() | ||
| case None => | ||
| // These classes are loaded shared between all classloaders, because | ||
| // they misbehave if loaded multiple times in separate classloaders | ||
| if (name.startsWith("java.") || name.startsWith("org.jline.")) parent.loadClass(name) | ||
| // Other classes loaded by the `UnshadingClassLoader` *must* be found in the | ||
| // `dotty.isolated` package. If they're not there, throw an error rather than | ||
| // trying to look for them at their normal package path, to ensure we're not | ||
| // accidentally pulling stuff in from the enclosing classloader | ||
| else throw new ClassNotFoundException(name) | ||
| } | ||
| } | ||
|
|
||
| override def getResourceAsStream(name: String): InputStream | Null = { | ||
| super.getResourceAsStream(ISOLATED_PREFIX.replace('.', '/') + name) | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Main entry point for the embedded shaded REPL. | ||
| * | ||
| * This creates an isolated classloader that loads the shaded REPL classes | ||
| * as if they were unshaded, instantiates a ReplDriver, and runs it. | ||
| */ | ||
| object EmbeddedReplMain { | ||
| def main(args: Array[String]): Unit = { | ||
| val argsWithClasspath = | ||
| if (args.exists(arg => arg == "-classpath" || arg == "-cp")) args | ||
| else Array("-classpath", System.getProperty("java.class.path")) ++ args | ||
|
|
||
| val unshadingClassLoader = new UnshadingClassLoader(getClass.getClassLoader) | ||
| val replDriverClass = unshadingClassLoader.loadClass("dotty.tools.repl.ReplDriver") | ||
| val someCls = unshadingClassLoader.loadClass("scala.Some") | ||
| val pprintImport = replDriverClass.getMethod("pprintImport").invoke(null) | ||
|
|
||
| val replDriver = replDriverClass.getConstructors().head.newInstance( | ||
| /*settings*/ argsWithClasspath, | ||
| /*out*/ System.out, | ||
| /*classLoader*/ someCls.getConstructors().head.newInstance(getClass.getClassLoader), | ||
| /*extraPredef*/ pprintImport | ||
| ) | ||
|
|
||
| replDriverClass.getMethod("tryRunning").invoke(replDriver) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you consider using one of the shading plugins for sbt instead of doing it by hand?