summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/classpath/ClassPathFactory.scala55
-rw-r--r--src/compiler/scala/tools/nsc/classpath/FileUtils.scala3
-rw-r--r--src/compiler/scala/tools/nsc/classpath/FlatClassPathFactory.scala38
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala33
4 files changed, 103 insertions, 26 deletions
diff --git a/src/compiler/scala/tools/nsc/classpath/ClassPathFactory.scala b/src/compiler/scala/tools/nsc/classpath/ClassPathFactory.scala
new file mode 100644
index 0000000000..9bf4e3f779
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/classpath/ClassPathFactory.scala
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014 Contributor. All rights reserved.
+ */
+package scala.tools.nsc.classpath
+
+import scala.reflect.io.AbstractFile
+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.
+ */
+trait ClassPathFactory[T] {
+
+ /**
+ * Create a new classpath based on the abstract file.
+ */
+ def newClassPath(file: AbstractFile): T
+
+ /**
+ * Creators for sub classpaths which preserve this context.
+ */
+ def sourcesInPath(path: String): List[T]
+
+ def expandPath(path: String, expandStar: Boolean = true): List[String] = ClassPath.expandPath(path, expandStar)
+
+ def expandDir(extdir: String): List[String] = ClassPath.expandDir(extdir)
+
+ def contentsOfDirsInPath(path: String): List[T] =
+ for {
+ dir <- expandPath(path, expandStar = false)
+ name <- expandDir(dir)
+ entry <- Option(AbstractFile.getDirectory(name))
+ } yield newClassPath(entry)
+
+ def classesInExpandedPath(path: String): IndexedSeq[T] =
+ 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))
+ else Nil
+
+ // Internal
+ protected def classesInPathImpl(path: String, expand: Boolean) =
+ for {
+ file <- expandPath(path, expand)
+ dir <- Option(AbstractFile.getDirectory(file))
+ } yield newClassPath(dir)
+}
diff --git a/src/compiler/scala/tools/nsc/classpath/FileUtils.scala b/src/compiler/scala/tools/nsc/classpath/FileUtils.scala
index cce16957f1..ee2528e15c 100644
--- a/src/compiler/scala/tools/nsc/classpath/FileUtils.scala
+++ b/src/compiler/scala/tools/nsc/classpath/FileUtils.scala
@@ -19,6 +19,9 @@ object FileUtils {
def isScalaOrJavaSource: Boolean = !file.isDirectory && (file.hasExtension("scala") || file.hasExtension("java"))
+ // TODO do we need to check also other files using ZipMagicNumber like in scala.tools.nsc.io.Jar.isJarOrZip?
+ def isJarOrZip: Boolean = file.hasExtension("jar") || file.hasExtension("zip")
+
/**
* Safe method returning a sequence containing one URL representing this file, when underlying file exists,
* and returning given default value in other case
diff --git a/src/compiler/scala/tools/nsc/classpath/FlatClassPathFactory.scala b/src/compiler/scala/tools/nsc/classpath/FlatClassPathFactory.scala
new file mode 100644
index 0000000000..7f67381d4d
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/classpath/FlatClassPathFactory.scala
@@ -0,0 +1,38 @@
+/*
+ * 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/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala
index 431ad0adf0..8d4d07759f 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -12,7 +12,6 @@ import java.net.MalformedURLException
import java.net.URL
import java.util.regex.PatternSyntaxException
import scala.collection.{ mutable, immutable }
-import scala.collection.convert.WrapAsScala.enumerationAsScalaIterator
import scala.reflect.internal.util.StringOps.splitWhere
import scala.tools.nsc.classpath.FileUtils
@@ -92,7 +91,7 @@ object ClassPath {
/** A class modeling aspects of a ClassPath which should be
* propagated to any classpaths it creates.
*/
- abstract class ClassPathContext[T] {
+ abstract class ClassPathContext[T] extends classpath.ClassPathFactory[ClassPath[T]] {
/** A filter which can be used to exclude entities from the classpath
* based on their name.
*/
@@ -108,35 +107,17 @@ object ClassPath {
*/
def toBinaryName(rep: T): String
- /** Create a new classpath based on the abstract file.
- */
- def newClassPath(file: AbstractFile): ClassPath[T]
-
- /** Creators for sub classpaths which preserve this context.
- */
def sourcesInPath(path: String): List[ClassPath[T]] =
for (file <- expandPath(path, expandStar = false) ; dir <- Option(AbstractFile getDirectory file)) yield
new SourcePath[T](dir, this)
-
- def contentsOfDirsInPath(path: String): List[ClassPath[T]] =
- for (dir <- expandPath(path, expandStar = false) ; name <- expandDir(dir) ; entry <- Option(AbstractFile getDirectory name)) yield
- newClassPath(entry)
-
- def classesInExpandedPath(path: String): IndexedSeq[ClassPath[T]] =
- classesInPathImpl(path, expand = true).toIndexedSeq
-
- def classesInPath(path: String) = classesInPathImpl(path, expand = false)
-
- // Internal
- private def classesInPathImpl(path: String, expand: Boolean) =
- for (file <- expandPath(path, expand) ; dir <- Option(AbstractFile getDirectory file)) yield
- newClassPath(dir)
-
- def classesInManifest(used: Boolean) =
- if (used) for (url <- manifests) yield newClassPath(AbstractFile getResources url) else Nil
}
- def manifests = Thread.currentThread().getContextClassLoader().getResources("META-INF/MANIFEST.MF").filter(_.getProtocol() == "jar").toList
+ def manifests: List[java.net.URL] = {
+ import scala.collection.convert.WrapAsScala.enumerationAsScalaIterator
+ Thread.currentThread().getContextClassLoader()
+ .getResources("META-INF/MANIFEST.MF")
+ .filter(_.getProtocol == "jar").toList
+ }
class JavaContext extends ClassPathContext[AbstractFile] {
def toBinaryName(rep: AbstractFile) = {