All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ammonite.interp.PredefInitialization.scala Maven / Gradle / Ivy

There is a newer version: 3.0.0-M0-67-83057fea
Show newest version
package ammonite.interp


import ammonite.interp.api.InterpAPI
import ammonite.runtime.{SpecialClassLoader, Storage}
import ammonite.util.ScriptOutput.Metadata
import ammonite.util.{ImportData, Imports, Name, PredefInfo, Res}
import ammonite.util.Util.CodeSource

/**
  * The logic around executing an [[Interpreter]]'s predef during
  * initialization
  */
object PredefInitialization {
  def initBridge[T >: Null <: AnyRef](classloader: SpecialClassLoader,
                    name: String,
                    t: T) = {
    classloader.findClassPublic(name + "$")
    classloader.findClassPublic(name)
      .getDeclaredMethods
      .find(_.getName == "value0_$eq")
      .get
      .invoke(null, t)
  }
  def initBridges(bridges: Seq[(String, String)]): Imports = {

    val allImports =
      for ((name, shortName) <- bridges)
        yield Imports(
          Seq(ImportData(
            Name("value"),
            Name(shortName),
            // FIXME Not sure special chars / backticked things in name are fine here
            Name("_root_") +: name.stripPrefix("_root_.").split('.').map(Name(_)).toSeq,
            ImportData.Term
          ))
        )

    allImports.foldLeft(Imports())(_ ++ _)
  }
  def initBridges(bridges: Seq[(String, String, AnyRef)],
                  evalClassloader: SpecialClassLoader): Imports = {

    for ((name, shortName, bridge) <- bridges)
      initBridge(evalClassloader, name, bridge)

    initBridges(bridges.map { case (name, shortName, _) => (name, shortName) })
  }
  def apply(interpApi: InterpAPI,
            storage: Storage,
            basePredefs: Seq[PredefInfo],
            customPredefs: Seq[PredefInfo],
            processModule: (String, CodeSource, Boolean) => Res[Metadata],
            addImports: Imports => Unit,
            watch: os.Path => Unit): Res[_] = {

    val predefs = {
      basePredefs ++
      storage.loadPredef.map{
        case (code, path) =>
          PredefInfo(Name(path.last.stripSuffix(".sc")), code, false, Some(path))
      } ++
      customPredefs
    }


    Res.fold((), predefs){(_, predefInfo) =>
      predefInfo.path.foreach(watch)
      if (predefInfo.code.isEmpty) Res.Success(())
      else {
        processModule(
          predefInfo.code,
          CodeSource(
            predefInfo.name,
            Seq(),
            Seq(Name("ammonite"), Name("predef")),
            predefInfo.path
          ),
          predefInfo.hardcoded
        ) match{
          case Res.Skip => Res.Success(())
          case Res.Success(processed) =>
            addImports(processed.blockInfo.last.hookInfo.imports)
            addImports(processed.blockInfo.last.finalImports)
            Res.Success(())

          case x => x.map(_ => ())
        }

      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy