summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/classpath
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/classpath')
-rw-r--r--src/compiler/scala/tools/nsc/classpath/AggregateClassPath.scala (renamed from src/compiler/scala/tools/nsc/classpath/AggregateFlatClassPath.scala)74
-rw-r--r--src/compiler/scala/tools/nsc/classpath/ClassPath.scala60
-rw-r--r--src/compiler/scala/tools/nsc/classpath/ClassPathFactory.scala69
-rw-r--r--src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala240
-rw-r--r--src/compiler/scala/tools/nsc/classpath/DirectoryFlatClassPath.scala162
-rw-r--r--src/compiler/scala/tools/nsc/classpath/FileUtils.scala8
-rw-r--r--src/compiler/scala/tools/nsc/classpath/FlatClassPath.scala101
-rw-r--r--src/compiler/scala/tools/nsc/classpath/FlatClassPathFactory.scala38
-rw-r--r--src/compiler/scala/tools/nsc/classpath/PackageNameUtils.scala2
-rw-r--r--src/compiler/scala/tools/nsc/classpath/VirtualDirectoryClassPath.scala40
-rw-r--r--src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala51
-rw-r--r--src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala11
12 files changed, 473 insertions, 383 deletions
diff --git a/src/compiler/scala/tools/nsc/classpath/AggregateFlatClassPath.scala b/src/compiler/scala/tools/nsc/classpath/AggregateClassPath.scala
index 3f06264e3c..a1af3413ea 100644
--- a/src/compiler/scala/tools/nsc/classpath/AggregateFlatClassPath.scala
+++ b/src/compiler/scala/tools/nsc/classpath/AggregateClassPath.scala
@@ -6,22 +6,23 @@ package scala.tools.nsc.classpath
import java.net.URL
import scala.annotation.tailrec
import scala.collection.mutable.ArrayBuffer
+import scala.reflect.internal.FatalError
import scala.reflect.io.AbstractFile
import scala.tools.nsc.util.ClassPath
import scala.tools.nsc.util.ClassRepresentation
/**
* A classpath unifying multiple class- and sourcepath entries.
- * Flat classpath can obtain entries for classes and sources independently
+ * The Classpath can obtain entries for classes and sources independently
* so it tries to do operations quite optimally - iterating only these collections
* which are needed in the given moment and only as far as it's necessary.
+ *
* @param aggregates classpath instances containing entries which this class processes
*/
-case class AggregateFlatClassPath(aggregates: Seq[FlatClassPath]) extends FlatClassPath {
-
+case class AggregateClassPath(aggregates: Seq[ClassPath]) extends ClassPath {
override def findClassFile(className: String): Option[AbstractFile] = {
@tailrec
- def find(aggregates: Seq[FlatClassPath]): Option[AbstractFile] =
+ def find(aggregates: Seq[ClassPath]): Option[AbstractFile] =
if (aggregates.nonEmpty) {
val classFile = aggregates.head.findClassFile(className)
if (classFile.isDefined) classFile
@@ -31,22 +32,27 @@ case class AggregateFlatClassPath(aggregates: Seq[FlatClassPath]) extends FlatCl
find(aggregates)
}
- override def findClass(className: String): Option[ClassRepresentation[AbstractFile]] = {
- val (pkg, simpleClassName) = PackageNameUtils.separatePkgAndClassNames(className)
-
+ override def findClass(className: String): Option[ClassRepresentation] = {
@tailrec
- def findEntry[T <: ClassRepClassPathEntry](aggregates: Seq[FlatClassPath], getEntries: FlatClassPath => Seq[T]): Option[T] =
+ def findEntry(aggregates: Seq[ClassPath], isSource: Boolean): Option[ClassRepresentation] =
if (aggregates.nonEmpty) {
- val entry = getEntries(aggregates.head)
- .find(_.name == simpleClassName)
+ val entry = aggregates.head.findClass(className) match {
+ case s @ Some(_: SourceFileEntry) if isSource => s
+ case s @ Some(_: ClassFileEntry) if !isSource => s
+ case _ => None
+ }
if (entry.isDefined) entry
- else findEntry(aggregates.tail, getEntries)
+ else findEntry(aggregates.tail, isSource)
} else None
- val classEntry = findEntry(aggregates, classesGetter(pkg))
- val sourceEntry = findEntry(aggregates, sourcesGetter(pkg))
+ val classEntry = findEntry(aggregates, isSource = false)
+ val sourceEntry = findEntry(aggregates, isSource = true)
- mergeClassesAndSources(classEntry.toList, sourceEntry.toList).headOption
+ (classEntry, sourceEntry) match {
+ case (Some(c: ClassFileEntry), Some(s: SourceFileEntry)) => Some(ClassAndSourceFilesEntry(c.file, s.file))
+ case (c @ Some(_), _) => c
+ case (_, s) => s
+ }
}
override def asURLs: Seq[URL] = aggregates.flatMap(_.asURLs)
@@ -61,16 +67,25 @@ case class AggregateFlatClassPath(aggregates: Seq[FlatClassPath]) extends FlatCl
}
override private[nsc] def classes(inPackage: String): Seq[ClassFileEntry] =
- getDistinctEntries(classesGetter(inPackage))
+ getDistinctEntries(_.classes(inPackage))
override private[nsc] def sources(inPackage: String): Seq[SourceFileEntry] =
- getDistinctEntries(sourcesGetter(inPackage))
-
- override private[nsc] def list(inPackage: String): FlatClassPathEntries = {
- val (packages, classesAndSources) = aggregates.map(_.list(inPackage)).unzip
+ getDistinctEntries(_.sources(inPackage))
+
+ override private[nsc] def list(inPackage: String): ClassPathEntries = {
+ val (packages, classesAndSources) = aggregates.map { cp =>
+ try {
+ cp.list(inPackage)
+ } catch {
+ case ex: java.io.IOException =>
+ val e = new FatalError(ex.getMessage)
+ e.initCause(ex)
+ throw e
+ }
+ }.unzip
val distinctPackages = packages.flatten.distinct
val distinctClassesAndSources = mergeClassesAndSources(classesAndSources: _*)
- FlatClassPathEntries(distinctPackages, distinctClassesAndSources)
+ ClassPathEntries(distinctPackages, distinctClassesAndSources)
}
/**
@@ -78,11 +93,11 @@ case class AggregateFlatClassPath(aggregates: Seq[FlatClassPath]) extends FlatCl
* creates an entry containing both of them. If there would be more than one class or source
* entries for the same class it always would use the first entry of each type found on a classpath.
*/
- private def mergeClassesAndSources(entries: Seq[ClassRepClassPathEntry]*): Seq[ClassRepClassPathEntry] = {
+ private def mergeClassesAndSources(entries: Seq[ClassRepresentation]*): Seq[ClassRepresentation] = {
// based on the implementation from MergedClassPath
var count = 0
val indices = collection.mutable.HashMap[String, Int]()
- val mergedEntries = new ArrayBuffer[ClassRepClassPathEntry](1024)
+ val mergedEntries = new ArrayBuffer[ClassRepresentation](1024)
for {
partOfEntries <- entries
@@ -107,7 +122,7 @@ case class AggregateFlatClassPath(aggregates: Seq[FlatClassPath]) extends FlatCl
mergedEntries.toIndexedSeq
}
- private def getDistinctEntries[EntryType <: ClassRepClassPathEntry](getEntries: FlatClassPath => Seq[EntryType]): Seq[EntryType] = {
+ private def getDistinctEntries[EntryType <: ClassRepresentation](getEntries: ClassPath => Seq[EntryType]): Seq[EntryType] = {
val seenNames = collection.mutable.HashSet[String]()
val entriesBuffer = new ArrayBuffer[EntryType](1024)
for {
@@ -119,7 +134,16 @@ case class AggregateFlatClassPath(aggregates: Seq[FlatClassPath]) extends FlatCl
}
entriesBuffer.toIndexedSeq
}
+}
- private def classesGetter(pkg: String) = (cp: FlatClassPath) => cp.classes(pkg)
- private def sourcesGetter(pkg: String) = (cp: FlatClassPath) => cp.sources(pkg)
+object AggregateClassPath {
+ def createAggregate(parts: ClassPath*): ClassPath = {
+ val elems = new ArrayBuffer[ClassPath]()
+ parts foreach {
+ case AggregateClassPath(ps) => elems ++= ps
+ case p => elems += p
+ }
+ if (elems.size == 1) elems.head
+ else AggregateClassPath(elems.toIndexedSeq)
+ }
}
diff --git a/src/compiler/scala/tools/nsc/classpath/ClassPath.scala b/src/compiler/scala/tools/nsc/classpath/ClassPath.scala
new file mode 100644
index 0000000000..08bd98b1d8
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/classpath/ClassPath.scala
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014 Contributor. All rights reserved.
+ */
+package scala.tools.nsc.classpath
+
+import scala.reflect.io.AbstractFile
+import scala.tools.nsc.util.ClassRepresentation
+
+case class ClassPathEntries(packages: Seq[PackageEntry], classesAndSources: Seq[ClassRepresentation])
+
+object ClassPathEntries {
+ import scala.language.implicitConversions
+ // to have working unzip method
+ implicit def entry2Tuple(entry: ClassPathEntries): (Seq[PackageEntry], Seq[ClassRepresentation]) = (entry.packages, entry.classesAndSources)
+}
+
+trait ClassFileEntry extends ClassRepresentation {
+ def file: AbstractFile
+}
+
+trait SourceFileEntry extends ClassRepresentation {
+ def file: AbstractFile
+}
+
+trait PackageEntry {
+ def name: String
+}
+
+private[nsc] case class ClassFileEntryImpl(file: AbstractFile) extends ClassFileEntry {
+ override def name = FileUtils.stripClassExtension(file.name) // class name
+
+ override def binary: Option[AbstractFile] = Some(file)
+ override def source: Option[AbstractFile] = None
+}
+
+private[nsc] case class SourceFileEntryImpl(file: AbstractFile) extends SourceFileEntry {
+ override def name = FileUtils.stripSourceExtension(file.name)
+
+ override def binary: Option[AbstractFile] = None
+ override def source: Option[AbstractFile] = Some(file)
+}
+
+private[nsc] case class ClassAndSourceFilesEntry(classFile: AbstractFile, srcFile: AbstractFile) extends ClassRepresentation {
+ override def name = FileUtils.stripClassExtension(classFile.name)
+
+ override def binary: Option[AbstractFile] = Some(classFile)
+ override def source: Option[AbstractFile] = Some(srcFile)
+}
+
+private[nsc] case class PackageEntryImpl(name: String) extends PackageEntry
+
+private[nsc] trait NoSourcePaths {
+ def asSourcePathString: String = ""
+ private[nsc] def sources(inPackage: String): Seq[SourceFileEntry] = Seq.empty
+}
+
+private[nsc] trait NoClassPaths {
+ def findClassFile(className: String): Option[AbstractFile] = None
+ private[nsc] def classes(inPackage: String): Seq[ClassFileEntry] = Seq.empty
+}
diff --git a/src/compiler/scala/tools/nsc/classpath/ClassPathFactory.scala b/src/compiler/scala/tools/nsc/classpath/ClassPathFactory.scala
index 9bf4e3f779..80c5ec8828 100644
--- a/src/compiler/scala/tools/nsc/classpath/ClassPathFactory.scala
+++ b/src/compiler/scala/tools/nsc/classpath/ClassPathFactory.scala
@@ -3,53 +3,80 @@
*/
package scala.tools.nsc.classpath
-import scala.reflect.io.AbstractFile
+import scala.reflect.io.{AbstractFile, VirtualDirectory}
+import scala.reflect.io.Path.string2path
+import scala.tools.nsc.Settings
+import FileUtils.AbstractFileOps
import scala.tools.nsc.util.ClassPath
/**
- * A trait that contains factory methods for classpath elements of type T.
- *
- * The logic has been abstracted from ClassPath#ClassPathContext so it's possible
- * to have common trait that supports both recursive and flat classpath representations.
- *
- * Therefore, we expect that T will be either ClassPath[U] or FlatClassPath.
+ * Provides factory methods for classpath. When creating classpath instances for a given path,
+ * it uses proper type of classpath depending on a types of particular files containing sources or classes.
*/
-trait ClassPathFactory[T] {
-
+class ClassPathFactory(settings: Settings) {
/**
- * Create a new classpath based on the abstract file.
- */
- def newClassPath(file: AbstractFile): T
+ * Create a new classpath based on the abstract file.
+ */
+ def newClassPath(file: AbstractFile): ClassPath = ClassPathFactory.newClassPath(file, settings)
/**
- * Creators for sub classpaths which preserve this context.
- */
- def sourcesInPath(path: String): List[T]
+ * Creators for sub classpaths which preserve this context.
+ */
+ def sourcesInPath(path: String): List[ClassPath] =
+ for {
+ file <- expandPath(path, expandStar = false)
+ dir <- Option(AbstractFile getDirectory file)
+ } yield createSourcePath(dir)
+
- def expandPath(path: String, expandStar: Boolean = true): List[String] = ClassPath.expandPath(path, expandStar)
+ def expandPath(path: String, expandStar: Boolean = true): List[String] = scala.tools.nsc.util.ClassPath.expandPath(path, expandStar)
- def expandDir(extdir: String): List[String] = ClassPath.expandDir(extdir)
+ def expandDir(extdir: String): List[String] = scala.tools.nsc.util.ClassPath.expandDir(extdir)
- def contentsOfDirsInPath(path: String): List[T] =
+ def contentsOfDirsInPath(path: String): List[ClassPath] =
for {
dir <- expandPath(path, expandStar = false)
name <- expandDir(dir)
entry <- Option(AbstractFile.getDirectory(name))
} yield newClassPath(entry)
- def classesInExpandedPath(path: String): IndexedSeq[T] =
+ def classesInExpandedPath(path: String): IndexedSeq[ClassPath] =
classesInPathImpl(path, expand = true).toIndexedSeq
def classesInPath(path: String) = classesInPathImpl(path, expand = false)
def classesInManifest(useManifestClassPath: Boolean) =
- if (useManifestClassPath) ClassPath.manifests.map(url => newClassPath(AbstractFile getResources url))
+ if (useManifestClassPath) scala.tools.nsc.util.ClassPath.manifests.map(url => newClassPath(AbstractFile getResources url))
else Nil
// Internal
protected def classesInPathImpl(path: String, expand: Boolean) =
for {
file <- expandPath(path, expand)
- dir <- Option(AbstractFile.getDirectory(file))
+ dir <- {
+ def asImage = if (file.endsWith(".jimage")) Some(AbstractFile.getFile(file)) else None
+ Option(AbstractFile.getDirectory(file)).orElse(asImage)
+ }
} yield newClassPath(dir)
+
+ private def createSourcePath(file: AbstractFile): ClassPath =
+ if (file.isJarOrZip)
+ ZipAndJarSourcePathFactory.create(file, settings)
+ else if (file.isDirectory)
+ new DirectorySourcePath(file.file)
+ else
+ sys.error(s"Unsupported sourcepath element: $file")
+}
+
+object ClassPathFactory {
+ def newClassPath(file: AbstractFile, settings: Settings): ClassPath = file match {
+ case vd: VirtualDirectory => VirtualDirectoryClassPath(vd)
+ case _ =>
+ if (file.isJarOrZip)
+ ZipAndJarClassPathFactory.create(file, settings)
+ else if (file.isDirectory)
+ new DirectoryClassPath(file.file)
+ else
+ sys.error(s"Unsupported classpath element: $file")
+ }
}
diff --git a/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
new file mode 100644
index 0000000000..fbd59eb04a
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2014 Contributor. All rights reserved.
+ */
+package scala.tools.nsc.classpath
+
+import java.io.File
+import java.net.{URI, URL}
+import java.nio.file.{FileSystems, Files, SimpleFileVisitor}
+import java.util.function.IntFunction
+import java.util
+import java.util.Comparator
+
+import scala.reflect.io.{AbstractFile, PlainFile, PlainNioFile}
+import scala.tools.nsc.util.{ClassPath, ClassRepresentation}
+import FileUtils._
+import scala.collection.JavaConverters._
+
+/**
+ * A trait allowing to look for classpath entries in directories. It provides common logic for
+ * classes handling class and source files.
+ * It makes use of the fact that in the case of nested directories it's easy to find a file
+ * when we have a name of a package.
+ * It abstracts over the file representation to work with both JFile and AbstractFile.
+ */
+trait DirectoryLookup[FileEntryType <: ClassRepresentation] extends ClassPath {
+ type F
+
+ val dir: F
+
+ protected def emptyFiles: Array[F] // avoids reifying ClassTag[F]
+ protected def getSubDir(dirName: String): Option[F]
+ protected def listChildren(dir: F, filter: Option[F => Boolean] = None): Array[F]
+ protected def getName(f: F): String
+ protected def toAbstractFile(f: F): AbstractFile
+ protected def isPackage(f: F): Boolean
+
+ protected def createFileEntry(file: AbstractFile): FileEntryType
+ protected def isMatchingFile(f: F): Boolean
+
+ private def getDirectory(forPackage: String): Option[F] = {
+ if (forPackage == ClassPath.RootPackage) {
+ Some(dir)
+ } else {
+ val packageDirName = FileUtils.dirPath(forPackage)
+ getSubDir(packageDirName)
+ }
+ }
+
+ private[nsc] def packages(inPackage: String): Seq[PackageEntry] = {
+ val dirForPackage = getDirectory(inPackage)
+ val nestedDirs: Array[F] = dirForPackage match {
+ case None => emptyFiles
+ case Some(directory) => listChildren(directory, Some(isPackage))
+ }
+ val prefix = PackageNameUtils.packagePrefix(inPackage)
+ nestedDirs.map(f => PackageEntryImpl(prefix + getName(f)))
+ }
+
+ protected def files(inPackage: String): Seq[FileEntryType] = {
+ val dirForPackage = getDirectory(inPackage)
+ val files: Array[F] = dirForPackage match {
+ case None => emptyFiles
+ case Some(directory) => listChildren(directory, Some(isMatchingFile))
+ }
+ files.map(f => createFileEntry(toAbstractFile(f)))
+ }
+
+ private[nsc] def list(inPackage: String): ClassPathEntries = {
+ val dirForPackage = getDirectory(inPackage)
+ val files: Array[F] = dirForPackage match {
+ case None => emptyFiles
+ case Some(directory) => listChildren(directory)
+ }
+ val packagePrefix = PackageNameUtils.packagePrefix(inPackage)
+ val packageBuf = collection.mutable.ArrayBuffer.empty[PackageEntry]
+ val fileBuf = collection.mutable.ArrayBuffer.empty[FileEntryType]
+ for (file <- files) {
+ if (isPackage(file))
+ packageBuf += PackageEntryImpl(packagePrefix + getName(file))
+ else if (isMatchingFile(file))
+ fileBuf += createFileEntry(toAbstractFile(file))
+ }
+ ClassPathEntries(packageBuf, fileBuf)
+ }
+}
+
+trait JFileDirectoryLookup[FileEntryType <: ClassRepresentation] extends DirectoryLookup[FileEntryType] {
+ type F = File
+
+ protected def emptyFiles: Array[File] = Array.empty
+ protected def getSubDir(packageDirName: String): Option[File] = {
+ val packageDir = new File(dir, packageDirName)
+ if (packageDir.exists && packageDir.isDirectory) Some(packageDir)
+ else None
+ }
+ protected def listChildren(dir: File, filter: Option[File => Boolean]): Array[File] = {
+ val listing = filter match {
+ case Some(f) => dir.listFiles(mkFileFilter(f))
+ case None => dir.listFiles()
+ }
+
+ // Sort by file name for stable order of directory .class entries in package scope.
+ // This gives stable results ordering of base type sequences for unrelated classes
+ // with the same base type depth.
+ //
+ // Notably, this will stably infer`Product with Serializable`
+ // as the type of `case class C(); case class D(); List(C(), D()).head`, rather than the opposite order.
+ // On Mac, the HFS performs this sorting transparently, but on Linux the order is unspecified.
+ //
+ // Note this behaviour can be enabled in javac with `javac -XDsortfiles`, but that's only
+ // intended to improve determinism of the compiler for compiler hackers.
+ util.Arrays.sort(listing, (o1: File, o2: File) => o1.getName.compareTo(o2.getName))
+ listing
+ }
+ protected def getName(f: File): String = f.getName
+ protected def toAbstractFile(f: File): AbstractFile = new PlainFile(new scala.reflect.io.File(f))
+ protected def isPackage(f: File): Boolean = f.isPackage
+
+ assert(dir != null, "Directory file in DirectoryFileLookup cannot be null")
+
+ def asURLs: Seq[URL] = Seq(dir.toURI.toURL)
+ def asClassPathStrings: Seq[String] = Seq(dir.getPath)
+}
+
+object JrtClassPath {
+ import java.nio.file._, java.net.URI
+ def apply(): Option[ClassPath] = {
+ try {
+ val fs = FileSystems.getFileSystem(URI.create("jrt:/"))
+ Some(new JrtClassPath(fs))
+ } catch {
+ case _: ProviderNotFoundException | _: FileSystemNotFoundException =>
+ None
+ }
+ }
+}
+
+/**
+ * Implementation `ClassPath` based on the JDK 9 encapsulated runtime modules (JEP-220)
+ *
+ * https://bugs.openjdk.java.net/browse/JDK-8066492 is the most up to date reference
+ * for the structure of the jrt:// filesystem.
+ *
+ * The implementation assumes that no classes exist in the empty package.
+ */
+final class JrtClassPath(fs: java.nio.file.FileSystem) extends ClassPath with NoSourcePaths {
+ import java.nio.file.Path, java.nio.file._
+ type F = Path
+ private val dir: Path = fs.getPath("/packages")
+
+ // e.g. "java.lang" -> Seq("/modules/java.base")
+ private val packageToModuleBases: Map[String, Seq[Path]] = {
+ val ps = Files.newDirectoryStream(dir).iterator().asScala
+ def lookup(pack: Path): Seq[Path] = {
+ Files.list(pack).iterator().asScala.map(l => if (Files.isSymbolicLink(l)) Files.readSymbolicLink(l) else l).toList
+ }
+ ps.map(p => (p.toString.stripPrefix("/packages/"), lookup(p))).toMap
+ }
+
+ override private[nsc] def packages(inPackage: String): Seq[PackageEntry] = {
+ def matches(packageDottedName: String) =
+ if (packageDottedName.contains("."))
+ packageOf(packageDottedName) == inPackage
+ else inPackage == ""
+ packageToModuleBases.keysIterator.filter(matches).map(PackageEntryImpl(_)).toVector
+ }
+ private[nsc] def classes(inPackage: String): Seq[ClassFileEntry] = {
+ if (inPackage == "") Nil
+ else {
+ packageToModuleBases.getOrElse(inPackage, Nil).flatMap(x =>
+ Files.list(x.resolve(inPackage.replace('.', '/'))).iterator().asScala.filter(_.getFileName.toString.endsWith(".class"))).map(x =>
+ ClassFileEntryImpl(new PlainNioFile(x))).toVector
+ }
+ }
+
+ override private[nsc] def list(inPackage: String): ClassPathEntries =
+ if (inPackage == "") ClassPathEntries(packages(inPackage), Nil)
+ else ClassPathEntries(packages(inPackage), classes(inPackage))
+
+ def asURLs: Seq[URL] = Seq(dir.toUri.toURL)
+ // We don't yet have a scheme to represent the JDK modules in our `-classpath`.
+ // java models them as entries in the new "module path", we'll probably need to follow this.
+ def asClassPathStrings: Seq[String] = Nil
+
+ def findClassFile(className: String): Option[AbstractFile] = {
+ if (!className.contains(".")) None
+ else {
+ val inPackage = packageOf(className)
+ packageToModuleBases.getOrElse(inPackage, Nil).iterator.flatMap{x =>
+ val file = x.resolve(className.replace('.', '/') + ".class")
+ if (Files.exists(file)) new scala.reflect.io.PlainNioFile(file) :: Nil else Nil
+ }.take(1).toList.headOption
+ }
+ }
+ private def packageOf(dottedClassName: String): String =
+ dottedClassName.substring(0, dottedClassName.lastIndexOf("."))
+}
+
+case class DirectoryClassPath(dir: File) extends JFileDirectoryLookup[ClassFileEntryImpl] with NoSourcePaths {
+ 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 File(s"$dir/$relativePath.class")
+ if (classFile.exists) {
+ val wrappedClassFile = new scala.reflect.io.File(classFile)
+ val abstractClassFile = new PlainFile(wrappedClassFile)
+ Some(abstractClassFile)
+ } else None
+ }
+
+ protected def createFileEntry(file: AbstractFile): ClassFileEntryImpl = ClassFileEntryImpl(file)
+ protected def isMatchingFile(f: File): Boolean = f.isClass
+
+ private[nsc] def classes(inPackage: String): Seq[ClassFileEntry] = files(inPackage)
+}
+
+case class DirectorySourcePath(dir: File) extends JFileDirectoryLookup[SourceFileEntryImpl] with NoClassPaths {
+ def asSourcePathString: String = asClassPathString
+
+ protected def createFileEntry(file: AbstractFile): SourceFileEntryImpl = SourceFileEntryImpl(file)
+ protected def isMatchingFile(f: File): Boolean = endsScalaOrJava(f.getName)
+
+ override def findClass(className: String): Option[ClassRepresentation] = findSourceFile(className) map SourceFileEntryImpl
+
+ private def findSourceFile(className: String): Option[AbstractFile] = {
+ val relativePath = FileUtils.dirPath(className)
+ val sourceFile = Stream("scala", "java")
+ .map(ext => new File(s"$dir/$relativePath.$ext"))
+ .collectFirst { case file if file.exists() => file }
+
+ sourceFile.map { file =>
+ val wrappedSourceFile = new scala.reflect.io.File(file)
+ val abstractSourceFile = new PlainFile(wrappedSourceFile)
+ abstractSourceFile
+ }
+ }
+
+ private[nsc] def sources(inPackage: String): Seq[SourceFileEntry] = files(inPackage)
+}
diff --git a/src/compiler/scala/tools/nsc/classpath/DirectoryFlatClassPath.scala b/src/compiler/scala/tools/nsc/classpath/DirectoryFlatClassPath.scala
deleted file mode 100644
index 81d2f7320f..0000000000
--- a/src/compiler/scala/tools/nsc/classpath/DirectoryFlatClassPath.scala
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2014 Contributor. All rights reserved.
- */
-package scala.tools.nsc.classpath
-
-import java.io.File
-import java.io.FileFilter
-import java.net.URL
-import scala.reflect.io.AbstractFile
-import scala.reflect.io.PlainFile
-import scala.tools.nsc.util.ClassRepresentation
-import FileUtils._
-
-/**
- * A trait allowing to look for classpath entries of given type in directories.
- * It provides common logic for classes handling class and source files.
- * It makes use of the fact that in the case of nested directories it's easy to find a file
- * when we have a name of a package.
- */
-trait DirectoryFileLookup[FileEntryType <: ClassRepClassPathEntry] extends FlatClassPath {
- val dir: File
- assert(dir != null, "Directory file in DirectoryFileLookup cannot be null")
-
- override def asURLs: Seq[URL] = Seq(dir.toURI.toURL)
- override def asClassPathStrings: Seq[String] = Seq(dir.getPath)
-
- import FlatClassPath.RootPackage
- private def getDirectory(forPackage: String): Option[File] = {
- if (forPackage == RootPackage) {
- Some(dir)
- } else {
- val packageDirName = FileUtils.dirPath(forPackage)
- val packageDir = new File(dir, packageDirName)
- if (packageDir.exists && packageDir.isDirectory) {
- Some(packageDir)
- } else None
- }
- }
-
- override private[nsc] def packages(inPackage: String): Seq[PackageEntry] = {
- val dirForPackage = getDirectory(inPackage)
- val nestedDirs: Array[File] = dirForPackage match {
- case None => Array.empty
- case Some(directory) => directory.listFiles(DirectoryFileLookup.packageDirectoryFileFilter)
- }
- val prefix = PackageNameUtils.packagePrefix(inPackage)
- val entries = nestedDirs map { file =>
- PackageEntryImpl(prefix + file.getName)
- }
- entries
- }
-
- protected def files(inPackage: String): Seq[FileEntryType] = {
- val dirForPackage = getDirectory(inPackage)
- val files: Array[File] = dirForPackage match {
- case None => Array.empty
- case Some(directory) => directory.listFiles(fileFilter)
- }
- val entries = files map { file =>
- val wrappedFile = new scala.reflect.io.File(file)
- createFileEntry(new PlainFile(wrappedFile))
- }
- entries
- }
-
- override private[nsc] def list(inPackage: String): FlatClassPathEntries = {
- val dirForPackage = getDirectory(inPackage)
- val files: Array[File] = dirForPackage match {
- case None => Array.empty
- case Some(directory) => directory.listFiles()
- }
- val packagePrefix = PackageNameUtils.packagePrefix(inPackage)
- val packageBuf = collection.mutable.ArrayBuffer.empty[PackageEntry]
- val fileBuf = collection.mutable.ArrayBuffer.empty[FileEntryType]
- for (file <- files) {
- if (file.isPackage) {
- val pkgEntry = PackageEntryImpl(packagePrefix + file.getName)
- packageBuf += pkgEntry
- } else if (fileFilter.accept(file)) {
- val wrappedFile = new scala.reflect.io.File(file)
- val abstractFile = new PlainFile(wrappedFile)
- fileBuf += createFileEntry(abstractFile)
- }
- }
- FlatClassPathEntries(packageBuf, fileBuf)
- }
-
- protected def createFileEntry(file: AbstractFile): FileEntryType
- protected def fileFilter: FileFilter
-}
-
-object DirectoryFileLookup {
-
- private[classpath] object packageDirectoryFileFilter extends FileFilter {
- override def accept(pathname: File): Boolean = pathname.isPackage
- }
-}
-
-case class DirectoryFlatClassPath(dir: File)
- extends DirectoryFileLookup[ClassFileEntryImpl]
- with NoSourcePaths {
-
- override def findClass(className: String): Option[ClassRepresentation[AbstractFile]] = findClassFile(className) map ClassFileEntryImpl
-
- override def findClassFile(className: String): Option[AbstractFile] = {
- val relativePath = FileUtils.dirPath(className)
- val classFile = new File(s"$dir/$relativePath.class")
- if (classFile.exists) {
- val wrappedClassFile = new scala.reflect.io.File(classFile)
- val abstractClassFile = new PlainFile(wrappedClassFile)
- Some(abstractClassFile)
- } else None
- }
-
- override protected def createFileEntry(file: AbstractFile): ClassFileEntryImpl = ClassFileEntryImpl(file)
- override protected def fileFilter: FileFilter = DirectoryFlatClassPath.classFileFilter
-
- override private[nsc] def classes(inPackage: String): Seq[ClassFileEntry] = files(inPackage)
-}
-
-object DirectoryFlatClassPath {
-
- private val classFileFilter = new FileFilter {
- override def accept(pathname: File): Boolean = pathname.isClass
- }
-}
-
-case class DirectoryFlatSourcePath(dir: File)
- extends DirectoryFileLookup[SourceFileEntryImpl]
- with NoClassPaths {
-
- override def asSourcePathString: String = asClassPathString
-
- override protected def createFileEntry(file: AbstractFile): SourceFileEntryImpl = SourceFileEntryImpl(file)
- override protected def fileFilter: FileFilter = DirectoryFlatSourcePath.sourceFileFilter
-
- override def findClass(className: String): Option[ClassRepresentation[AbstractFile]] = {
- findSourceFile(className) map SourceFileEntryImpl
- }
-
- private def findSourceFile(className: String): Option[AbstractFile] = {
- val relativePath = FileUtils.dirPath(className)
- val sourceFile = Stream("scala", "java")
- .map(ext => new File(s"$dir/$relativePath.$ext"))
- .collectFirst { case file if file.exists() => file }
-
- sourceFile.map { file =>
- val wrappedSourceFile = new scala.reflect.io.File(file)
- val abstractSourceFile = new PlainFile(wrappedSourceFile)
- abstractSourceFile
- }
- }
-
- override private[nsc] def sources(inPackage: String): Seq[SourceFileEntry] = files(inPackage)
-}
-
-object DirectoryFlatSourcePath {
-
- private val sourceFileFilter = new FileFilter {
- override def accept(pathname: File): Boolean = endsScalaOrJava(pathname.getName)
- }
-}
diff --git a/src/compiler/scala/tools/nsc/classpath/FileUtils.scala b/src/compiler/scala/tools/nsc/classpath/FileUtils.scala
index ee2528e15c..2ade83c6f9 100644
--- a/src/compiler/scala/tools/nsc/classpath/FileUtils.scala
+++ b/src/compiler/scala/tools/nsc/classpath/FileUtils.scala
@@ -3,7 +3,7 @@
*/
package scala.tools.nsc.classpath
-import java.io.{ File => JFile }
+import java.io.{File => JFile, FileFilter}
import java.net.URL
import scala.reflect.internal.FatalError
import scala.reflect.io.AbstractFile
@@ -63,6 +63,10 @@ object FileUtils {
// probably it should match a pattern like [a-z_]{1}[a-z0-9_]* but it cannot be changed
// because then some tests in partest don't pass
- private def mayBeValidPackage(dirName: String): Boolean =
+ def mayBeValidPackage(dirName: String): Boolean =
(dirName != "META-INF") && (dirName != "") && (dirName.charAt(0) != '.')
+
+ def mkFileFilter(f: JFile => Boolean) = new FileFilter {
+ def accept(pathname: JFile): Boolean = f(pathname)
+ }
}
diff --git a/src/compiler/scala/tools/nsc/classpath/FlatClassPath.scala b/src/compiler/scala/tools/nsc/classpath/FlatClassPath.scala
deleted file mode 100644
index cb201617d2..0000000000
--- a/src/compiler/scala/tools/nsc/classpath/FlatClassPath.scala
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2014 Contributor. All rights reserved.
- */
-package scala.tools.nsc.classpath
-
-import scala.reflect.io.AbstractFile
-import scala.tools.nsc.util.{ ClassFileLookup, ClassPath, ClassRepresentation }
-
-/**
- * A base trait for the particular flat classpath representation implementations.
- *
- * We call this variant of a classpath representation flat because it's possible to
- * query the whole classpath using just single instance extending this trait.
- *
- * This is an alternative design compared to scala.tools.nsc.util.ClassPath
- */
-trait FlatClassPath extends ClassFileLookup[AbstractFile] {
- /** Empty string represents root package */
- private[nsc] def packages(inPackage: String): Seq[PackageEntry]
- private[nsc] def classes(inPackage: String): Seq[ClassFileEntry]
- private[nsc] def sources(inPackage: String): Seq[SourceFileEntry]
-
- /** Allows to get entries for packages and classes merged with sources possibly in one pass. */
- private[nsc] def list(inPackage: String): FlatClassPathEntries
-
- // A default implementation which should be overridden, if we can create the more efficient
- // solution for a given type of FlatClassPath
- override def findClass(className: String): Option[ClassRepresentation[AbstractFile]] = {
- val (pkg, simpleClassName) = PackageNameUtils.separatePkgAndClassNames(className)
-
- val foundClassFromClassFiles = classes(pkg)
- .find(_.name == simpleClassName)
-
- def findClassInSources = sources(pkg)
- .find(_.name == simpleClassName)
-
- foundClassFromClassFiles orElse findClassInSources
- }
-
- override def asClassPathString: String = ClassPath.join(asClassPathStrings: _*)
- def asClassPathStrings: Seq[String]
-}
-
-object FlatClassPath {
- val RootPackage = ""
-}
-
-case class FlatClassPathEntries(packages: Seq[PackageEntry], classesAndSources: Seq[ClassRepClassPathEntry])
-
-object FlatClassPathEntries {
- import scala.language.implicitConversions
- // to have working unzip method
- implicit def entry2Tuple(entry: FlatClassPathEntries) = (entry.packages, entry.classesAndSources)
-}
-
-sealed trait ClassRepClassPathEntry extends ClassRepresentation[AbstractFile]
-
-trait ClassFileEntry extends ClassRepClassPathEntry {
- def file: AbstractFile
-}
-
-trait SourceFileEntry extends ClassRepClassPathEntry {
- def file: AbstractFile
-}
-
-trait PackageEntry {
- def name: String
-}
-
-private[nsc] case class ClassFileEntryImpl(file: AbstractFile) extends ClassFileEntry {
- override def name = FileUtils.stripClassExtension(file.name) // class name
-
- override def binary: Option[AbstractFile] = Some(file)
- override def source: Option[AbstractFile] = None
-}
-
-private[nsc] case class SourceFileEntryImpl(file: AbstractFile) extends SourceFileEntry {
- override def name = FileUtils.stripSourceExtension(file.name)
-
- override def binary: Option[AbstractFile] = None
- override def source: Option[AbstractFile] = Some(file)
-}
-
-private[nsc] case class ClassAndSourceFilesEntry(classFile: AbstractFile, srcFile: AbstractFile) extends ClassRepClassPathEntry {
- override def name = FileUtils.stripClassExtension(classFile.name)
-
- override def binary: Option[AbstractFile] = Some(classFile)
- override def source: Option[AbstractFile] = Some(srcFile)
-}
-
-private[nsc] case class PackageEntryImpl(name: String) extends PackageEntry
-
-private[nsc] trait NoSourcePaths {
- def asSourcePathString: String = ""
- private[nsc] def sources(inPackage: String): Seq[SourceFileEntry] = Seq.empty
-}
-
-private[nsc] trait NoClassPaths {
- def findClassFile(className: String): Option[AbstractFile] = None
- private[nsc] def classes(inPackage: String): Seq[ClassFileEntry] = Seq.empty
-}
diff --git a/src/compiler/scala/tools/nsc/classpath/FlatClassPathFactory.scala b/src/compiler/scala/tools/nsc/classpath/FlatClassPathFactory.scala
deleted file mode 100644
index 7f67381d4d..0000000000
--- a/src/compiler/scala/tools/nsc/classpath/FlatClassPathFactory.scala
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2014 Contributor. All rights reserved.
- */
-package scala.tools.nsc.classpath
-
-import scala.tools.nsc.Settings
-import scala.tools.nsc.io.AbstractFile
-import scala.tools.nsc.util.ClassPath
-import FileUtils.AbstractFileOps
-
-/**
- * Provides factory methods for flat classpath. When creating classpath instances for a given path,
- * it uses proper type of classpath depending on a types of particular files containing sources or classes.
- */
-class FlatClassPathFactory(settings: Settings) extends ClassPathFactory[FlatClassPath] {
-
- override def newClassPath(file: AbstractFile): FlatClassPath =
- if (file.isJarOrZip)
- ZipAndJarFlatClassPathFactory.create(file, settings)
- else if (file.isDirectory)
- new DirectoryFlatClassPath(file.file)
- else
- sys.error(s"Unsupported classpath element: $file")
-
- override def sourcesInPath(path: String): List[FlatClassPath] =
- for {
- file <- expandPath(path, expandStar = false)
- dir <- Option(AbstractFile getDirectory file)
- } yield createSourcePath(dir)
-
- private def createSourcePath(file: AbstractFile): FlatClassPath =
- if (file.isJarOrZip)
- ZipAndJarFlatSourcePathFactory.create(file, settings)
- else if (file.isDirectory)
- new DirectoryFlatSourcePath(file.file)
- else
- sys.error(s"Unsupported sourcepath element: $file")
-}
diff --git a/src/compiler/scala/tools/nsc/classpath/PackageNameUtils.scala b/src/compiler/scala/tools/nsc/classpath/PackageNameUtils.scala
index c907d565d2..39b0d78135 100644
--- a/src/compiler/scala/tools/nsc/classpath/PackageNameUtils.scala
+++ b/src/compiler/scala/tools/nsc/classpath/PackageNameUtils.scala
@@ -3,7 +3,7 @@
*/
package scala.tools.nsc.classpath
-import scala.tools.nsc.classpath.FlatClassPath.RootPackage
+import scala.tools.nsc.util.ClassPath.RootPackage
/**
* Common methods related to package names represented as String
diff --git a/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryClassPath.scala b/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryClassPath.scala
new file mode 100644
index 0000000000..6fefaf0da0
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/classpath/VirtualDirectoryClassPath.scala
@@ -0,0 +1,40 @@
+package scala.tools.nsc.classpath
+
+import scala.tools.nsc.util.ClassRepresentation
+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 {
+ type F = AbstractFile
+
+ protected def emptyFiles: Array[AbstractFile] = Array.empty
+ protected def getSubDir(packageDirName: String): Option[AbstractFile] =
+ 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
+ }
+ def getName(f: AbstractFile): String = f.name
+ def toAbstractFile(f: AbstractFile): AbstractFile = f
+ def isPackage(f: AbstractFile): Boolean = f.isPackage
+
+ // mimic the behavior of the old nsc.util.DirectoryClassPath
+ def asURLs: Seq[URL] = Seq(new URL(dir.name))
+ def asClassPathStrings: Seq[String] = Seq(dir.path)
+
+ override def findClass(className: String): Option[ClassRepresentation] = findClassFile(className) map ClassFileEntryImpl
+
+ def findClassFile(className: String): Option[AbstractFile] = {
+ val relativePath = FileUtils.dirPath(className) + ".class"
+ Option(AbstractFileClassLoader.lookupPath(dir)(relativePath split '/', directory = false))
+ }
+
+ private[nsc] def classes(inPackage: String): Seq[ClassFileEntry] = files(inPackage)
+
+ protected def createFileEntry(file: AbstractFile): ClassFileEntryImpl = ClassFileEntryImpl(file)
+ protected def isMatchingFile(f: AbstractFile): Boolean = f.isClass
+}
diff --git a/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala b/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala
index 85c7c3c843..fe74e5f874 100644
--- a/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala
+++ b/src/compiler/scala/tools/nsc/classpath/ZipAndJarFileLookupFactory.scala
@@ -6,7 +6,8 @@ package scala.tools.nsc.classpath
import java.io.File
import java.net.URL
import scala.annotation.tailrec
-import scala.reflect.io.{ AbstractFile, FileZipArchive, ManifestResources }
+import scala.reflect.io.{AbstractFile, FileZipArchive, ManifestResources}
+import scala.tools.nsc.util.ClassPath
import scala.tools.nsc.Settings
import FileUtils._
@@ -19,17 +20,16 @@ import FileUtils._
* when there are a lot of projects having a lot of common dependencies.
*/
sealed trait ZipAndJarFileLookupFactory {
+ private val cache = collection.mutable.Map.empty[AbstractFile, ClassPath]
- private val cache = collection.mutable.Map.empty[AbstractFile, FlatClassPath]
-
- def create(zipFile: AbstractFile, settings: Settings): FlatClassPath = {
+ def create(zipFile: AbstractFile, settings: Settings): ClassPath = {
if (settings.YdisableFlatCpCaching) createForZipFile(zipFile)
else createUsingCache(zipFile, settings)
}
- protected def createForZipFile(zipFile: AbstractFile): FlatClassPath
+ protected def createForZipFile(zipFile: AbstractFile): ClassPath
- private def createUsingCache(zipFile: AbstractFile, settings: Settings): FlatClassPath = cache.synchronized {
+ private def createUsingCache(zipFile: AbstractFile, settings: Settings): ClassPath = cache.synchronized {
def newClassPathInstance = {
if (settings.verbose || settings.Ylogcp)
println(s"$zipFile is not yet in the classpath cache")
@@ -40,12 +40,11 @@ sealed trait ZipAndJarFileLookupFactory {
}
/**
- * Manages creation of flat classpath for class files placed in zip and jar files.
+ * Manages creation of classpath for class files placed in zip and jar files.
* It should be the only way of creating them as it provides caching.
*/
-object ZipAndJarFlatClassPathFactory extends ZipAndJarFileLookupFactory {
-
- private case class ZipArchiveFlatClassPath(zipFile: File)
+object ZipAndJarClassPathFactory extends ZipAndJarFileLookupFactory {
+ private case class ZipArchiveClassPath(zipFile: File)
extends ZipArchiveFileLookup[ClassFileEntryImpl]
with NoSourcePaths {
@@ -67,10 +66,7 @@ object ZipAndJarFlatClassPathFactory extends ZipAndJarFileLookupFactory {
* with a particularly prepared scala-library.jar. It should have all classes listed in the manifest like e.g. this entry:
* Name: scala/Function2$mcFJD$sp.class
*/
- private case class ManifestResourcesFlatClassPath(file: ManifestResources)
- extends FlatClassPath
- with NoSourcePaths {
-
+ private case class ManifestResourcesClassPath(file: ManifestResources) extends ClassPath with NoSourcePaths {
override def findClassFile(className: String): Option[AbstractFile] = {
val (pkg, simpleClassName) = PackageNameUtils.separatePkgAndClassNames(className)
classes(pkg).find(_.name == simpleClassName).map(_.file)
@@ -80,8 +76,8 @@ object ZipAndJarFlatClassPathFactory extends ZipAndJarFileLookupFactory {
override def asURLs: Seq[URL] = file.toURLs()
- import ManifestResourcesFlatClassPath.PackageFileInfo
- import ManifestResourcesFlatClassPath.PackageInfo
+ import ManifestResourcesClassPath.PackageFileInfo
+ import ManifestResourcesClassPath.PackageInfo
/**
* A cache mapping package name to abstract file for package directory and subpackages of given package.
@@ -119,8 +115,8 @@ object ZipAndJarFlatClassPathFactory extends ZipAndJarFileLookupFactory {
}
val subpackages = getSubpackages(file)
- packages.put(FlatClassPath.RootPackage, PackageFileInfo(file, subpackages))
- traverse(FlatClassPath.RootPackage, subpackages, collection.mutable.Queue())
+ packages.put(ClassPath.RootPackage, PackageFileInfo(file, subpackages))
+ traverse(ClassPath.RootPackage, subpackages, collection.mutable.Queue())
packages
}
@@ -137,21 +133,21 @@ object ZipAndJarFlatClassPathFactory extends ZipAndJarFileLookupFactory {
(for (file <- pkg if file.isClass) yield ClassFileEntryImpl(file))(collection.breakOut)
}
- override private[nsc] def list(inPackage: String): FlatClassPathEntries = FlatClassPathEntries(packages(inPackage), classes(inPackage))
+ override private[nsc] def list(inPackage: String): ClassPathEntries = ClassPathEntries(packages(inPackage), classes(inPackage))
}
- private object ManifestResourcesFlatClassPath {
+ private object ManifestResourcesClassPath {
case class PackageFileInfo(packageFile: AbstractFile, subpackages: Seq[AbstractFile])
case class PackageInfo(packageName: String, subpackages: List[AbstractFile])
}
- override protected def createForZipFile(zipFile: AbstractFile): FlatClassPath =
+ override protected def createForZipFile(zipFile: AbstractFile): ClassPath =
if (zipFile.file == null) createWithoutUnderlyingFile(zipFile)
- else ZipArchiveFlatClassPath(zipFile.file)
+ else ZipArchiveClassPath(zipFile.file)
private def createWithoutUnderlyingFile(zipFile: AbstractFile) = zipFile match {
case manifestRes: ManifestResources =>
- ManifestResourcesFlatClassPath(manifestRes)
+ ManifestResourcesClassPath(manifestRes)
case _ =>
val errorMsg = s"Abstract files which don't have an underlying file and are not ManifestResources are not supported. There was $zipFile"
throw new IllegalArgumentException(errorMsg)
@@ -159,12 +155,11 @@ object ZipAndJarFlatClassPathFactory extends ZipAndJarFileLookupFactory {
}
/**
- * Manages creation of flat classpath for source files placed in zip and jar files.
+ * Manages creation of classpath for source files placed in zip and jar files.
* It should be the only way of creating them as it provides caching.
*/
-object ZipAndJarFlatSourcePathFactory extends ZipAndJarFileLookupFactory {
-
- private case class ZipArchiveFlatSourcePath(zipFile: File)
+object ZipAndJarSourcePathFactory extends ZipAndJarFileLookupFactory {
+ private case class ZipArchiveSourcePath(zipFile: File)
extends ZipArchiveFileLookup[SourceFileEntryImpl]
with NoClassPaths {
@@ -176,5 +171,5 @@ object ZipAndJarFlatSourcePathFactory extends ZipAndJarFileLookupFactory {
override protected def isRequiredFileType(file: AbstractFile): Boolean = file.isScalaOrJavaSource
}
- override protected def createForZipFile(zipFile: AbstractFile): FlatClassPath = ZipArchiveFlatSourcePath(zipFile.file)
+ override protected def createForZipFile(zipFile: AbstractFile): ClassPath = ZipArchiveSourcePath(zipFile.file)
}
diff --git a/src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala b/src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala
index 1d0de57779..9c147cf8cc 100644
--- a/src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala
+++ b/src/compiler/scala/tools/nsc/classpath/ZipArchiveFileLookup.scala
@@ -9,13 +9,14 @@ import scala.collection.Seq
import scala.reflect.io.AbstractFile
import scala.reflect.io.FileZipArchive
import FileUtils.AbstractFileOps
+import scala.tools.nsc.util.{ClassPath, ClassRepresentation}
/**
* A trait allowing to look for classpath entries of given type in zip and jar files.
* It provides common logic for classes handling class and source files.
* It's aware of things like e.g. META-INF directory which is correctly skipped.
*/
-trait ZipArchiveFileLookup[FileEntryType <: ClassRepClassPathEntry] extends FlatClassPath {
+trait ZipArchiveFileLookup[FileEntryType <: ClassRepresentation] extends ClassPath {
val zipFile: File
assert(zipFile != null, "Zip file in ZipArchiveFileLookup cannot be null")
@@ -39,7 +40,7 @@ trait ZipArchiveFileLookup[FileEntryType <: ClassRepClassPathEntry] extends Flat
entry <- dirEntry.iterator if isRequiredFileType(entry)
} yield createFileEntry(entry)
- override private[nsc] def list(inPackage: String): FlatClassPathEntries = {
+ override private[nsc] def list(inPackage: String): ClassPathEntries = {
val foundDirEntry = findDirEntry(inPackage)
foundDirEntry map { dirEntry =>
@@ -53,11 +54,11 @@ trait ZipArchiveFileLookup[FileEntryType <: ClassRepClassPathEntry] extends Flat
else if (isRequiredFileType(entry))
fileBuf += createFileEntry(entry)
}
- FlatClassPathEntries(pkgBuf, fileBuf)
- } getOrElse FlatClassPathEntries(Seq.empty, Seq.empty)
+ ClassPathEntries(pkgBuf, fileBuf)
+ } getOrElse ClassPathEntries(Seq.empty, Seq.empty)
}
- private def findDirEntry(pkg: String) = {
+ private def findDirEntry(pkg: String): Option[archive.DirEntry] = {
val dirName = s"${FileUtils.dirPath(pkg)}/"
archive.allDirs.get(dirName)
}