summaryrefslogtreecommitdiff
path: root/src/compiler/scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-11-18 18:09:28 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-11-28 15:57:31 +1000
commit753e848f3d6ac453871450161292139902669695 (patch)
treee2401d5b2f734a5fd77015f8104382abf120503b /src/compiler/scala
parent690ba800ec04f05c0f5e5e369863ab5b9578d42f (diff)
downloadscala-753e848f3d6ac453871450161292139902669695.tar.gz
scala-753e848f3d6ac453871450161292139902669695.tar.bz2
scala-753e848f3d6ac453871450161292139902669695.zip
SI-8779 Enable inlining of code within a REPL session
The REPL has a long running instance of Global which outputs classfiles by default to a VirtualDirectory. The inliner did not find any of these class files when compiling calls to methods defined in previous runs (ie, previous lines of input.) This commit: - Adds a hook to augment the classpath that the optimizer searches, and uses this in the REPL to add the output directory - Fixes the implementation of `findClassFile` in VirtualDirectory, which doesn't seem to have been used in anger before. I've factored out some common code into a new method on `AbstractFile`. - Fixes a similar problem getSubDir reported by Li Haoyi - Adds missing unit test coverage. This also fixes a bug in REPL autocompletion for types defined in packages >= 2 level deep (with the `:paste -raw` command). I've added a test for this case.
Diffstat (limited to 'src/compiler/scala')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala3
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala2
-rw-r--r--src/compiler/scala/tools/nsc/classpath/VirtualDirectoryClassPath.scala12
3 files changed, 10 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index a7880c72d7..e58d2d3b43 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -95,6 +95,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
type ThisPlatform = JavaPlatform { val global: Global.this.type }
lazy val platform: ThisPlatform = new GlobalPlatform
+ /* A hook for the REPL to add a classpath entry containing products of previous runs to inliner's bytecode repository*/
+ // Fixes SI-8779
+ def optimizerClassPath(base: ClassPath): ClassPath = base
def classPath: ClassPath = platform.classPath
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
index edb75514e8..f7ee36c1ba 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
@@ -37,7 +37,7 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
val coreBTypes = new CoreBTypesProxy[this.type](this)
import coreBTypes._
- val byteCodeRepository: ByteCodeRepository[this.type] = new ByteCodeRepository(global.classPath, this)
+ val byteCodeRepository: ByteCodeRepository[this.type] = new ByteCodeRepository(global.optimizerClassPath(global.classPath), this)
val localOpt: LocalOpt[this.type] = new LocalOpt(this)
diff --git a/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryClassPath.scala b/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryClassPath.scala
index 8df0c3743d..6fefaf0da0 100644
--- a/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryClassPath.scala
+++ b/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryClassPath.scala
@@ -1,9 +1,11 @@
package scala.tools.nsc.classpath
import scala.tools.nsc.util.ClassRepresentation
-import scala.reflect.io.{Path, PlainFile, VirtualDirectory, AbstractFile}
+import scala.reflect.io.{AbstractFile, Path, PlainFile, VirtualDirectory}
import FileUtils._
import java.net.URL
+
+import scala.reflect.internal.util.AbstractFileClassLoader
import scala.tools.nsc.util.ClassPath
case class VirtualDirectoryClassPath(dir: VirtualDirectory) extends ClassPath with DirectoryLookup[ClassFileEntryImpl] with NoSourcePaths {
@@ -11,7 +13,7 @@ case class VirtualDirectoryClassPath(dir: VirtualDirectory) extends ClassPath wi
protected def emptyFiles: Array[AbstractFile] = Array.empty
protected def getSubDir(packageDirName: String): Option[AbstractFile] =
- Option(dir.lookupName(packageDirName, directory = true))
+ Option(AbstractFileClassLoader.lookupPath(dir)(packageDirName.split('/'), directory = true))
protected def listChildren(dir: AbstractFile, filter: Option[AbstractFile => Boolean] = None): Array[F] = filter match {
case Some(f) => dir.iterator.filter(f).toArray
case _ => dir.toArray
@@ -27,10 +29,8 @@ case class VirtualDirectoryClassPath(dir: VirtualDirectory) extends ClassPath wi
override def findClass(className: String): Option[ClassRepresentation] = findClassFile(className) map ClassFileEntryImpl
def findClassFile(className: String): Option[AbstractFile] = {
- val relativePath = FileUtils.dirPath(className)
- val classFile = new PlainFile(Path(s"$dir/$relativePath.class"))
- if (classFile.exists) Some(classFile)
- else None
+ val relativePath = FileUtils.dirPath(className) + ".class"
+ Option(AbstractFileClassLoader.lookupPath(dir)(relativePath split '/', directory = false))
}
private[nsc] def classes(inPackage: String): Seq[ClassFileEntry] = files(inPackage)