@@ -7,6 +7,7 @@ import java.nio.charset.StandardCharsets
77
88import dotty .tools .dotc .ast .Trees .*
99import dotty .tools .dotc .ast .{tpd , untpd }
10+ import dotty .tools .dotc .classpath .ClassPathFactory
1011import dotty .tools .dotc .config .CommandLineParser .tokenize
1112import dotty .tools .dotc .config .Properties .{javaVersion , javaVmName , simpleVersionString }
1213import dotty .tools .dotc .core .Contexts .*
@@ -21,6 +22,7 @@ import dotty.tools.dotc.core.NameOps.*
2122import dotty .tools .dotc .core .Names .Name
2223import dotty .tools .dotc .core .StdNames .*
2324import dotty .tools .dotc .core .Symbols .{Symbol , defn }
25+ import dotty .tools .dotc .core .SymbolLoaders
2426import dotty .tools .dotc .interfaces
2527import dotty .tools .dotc .interactive .Completion
2628import dotty .tools .dotc .printing .SyntaxHighlighting
@@ -39,6 +41,7 @@ import scala.annotation.tailrec
3941import scala .collection .mutable
4042import scala .compiletime .uninitialized
4143import scala .jdk .CollectionConverters .*
44+ import scala .tools .asm .ClassReader
4245import scala .util .control .NonFatal
4346import scala .util .Using
4447
@@ -512,10 +515,65 @@ class ReplDriver(settings: Array[String],
512515 state
513516 }
514517
518+ case Require (path) =>
519+ out.println(" :require is no longer supported, but has been replaced with :jar. Please use :jar" )
520+ state
521+
522+ case JarCmd (path) =>
523+ val jarFile = AbstractFile .getDirectory(path)
524+ if (jarFile == null )
525+ out.println(s """ Cannot add " $path" to classpath. """ )
526+ state
527+ else
528+ def flatten (f : AbstractFile ): Iterator [AbstractFile ] =
529+ if (f.isClassContainer) f.iterator.flatMap(flatten)
530+ else Iterator (f)
531+
532+ def tryClassLoad (classFile : AbstractFile ): Option [String ] = {
533+ val input = classFile.input
534+ try {
535+ val reader = new ClassReader (input)
536+ val clsName = reader.getClassName.replace('/' , '.' )
537+ rendering.myClassLoader.loadClass(clsName)
538+ Some (clsName)
539+ } catch
540+ case _ : ClassNotFoundException => None
541+ finally {
542+ input.close()
543+ }
544+ }
545+
546+ try {
547+ val entries = flatten(jarFile)
548+
549+ val existingClass = entries.filter(_.ext.isClass).find(tryClassLoad(_).isDefined)
550+ if (existingClass.nonEmpty)
551+ out.println(s " The path ' $path' cannot be loaded, it contains a classfile that already exists on the classpath: ${existingClass.get}" )
552+ else inContext(state.context):
553+ val jarClassPath = ClassPathFactory .newClassPath(jarFile)
554+ val prevOutputDir = ctx.settings.outputDir.value
555+
556+ // add to compiler class path
557+ ctx.platform.addToClassPath(jarClassPath)
558+ SymbolLoaders .mergeNewEntries(defn.RootClass , ClassPath .RootPackage , jarClassPath, ctx.platform.classPath)
559+
560+ // new class loader with previous output dir and specified jar
561+ val prevClassLoader = rendering.classLoader()
562+ val jarClassLoader = fromURLsParallelCapable(
563+ jarClassPath.asURLs, prevClassLoader)
564+ rendering.myClassLoader = new AbstractFileClassLoader (
565+ prevOutputDir, jarClassLoader)
566+
567+ out.println(s " Added ' $path' to classpath. " )
568+ } catch {
569+ case e : Throwable =>
570+ out.println(s " Failed to load ' $path' to classpath: ${e.getMessage}" )
571+ }
572+ state
573+
515574 case KindOf (expr) =>
516575 out.println(s """ The :kind command is not currently supported. """ )
517576 state
518-
519577 case TypeOf (expr) =>
520578 expr match {
521579 case " " => out.println(s " :type <expression> " )
0 commit comments