@@ -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