summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/io/PlainFile.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-04-24 17:23:20 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-12-02 11:30:47 +1000
commit159480f2504cc08f9cc35660cc33090a49e0228e (patch)
tree741982f0327fd013d6f218b5582adea5d7d93fd4 /src/reflect/scala/reflect/io/PlainFile.scala
parentbfa7ade0db6d36efc721e36dc41627dbd76b0176 (diff)
downloadscala-159480f2504cc08f9cc35660cc33090a49e0228e.tar.gz
scala-159480f2504cc08f9cc35660cc33090a49e0228e.tar.bz2
scala-159480f2504cc08f9cc35660cc33090a49e0228e.zip
Support Java 9 modular runtime images
http://openjdk.java.net/jeps/220 changes the layout of the JDK to encapsulate the provided libraries with the new module system. This commit modifies the compiler's classpath implementation to scan the new location of these, the `jrt://` virtual filesystem. This might need to be adjusted once we provide a means for users to specify the subset of modules that they want to depend on, but for now reclaims the ground we lost. ``` ⚡ (java_use 9-ea; qscala) Welcome to Scala 2.12.0-20160908-223617-7e4ebda (Java HotSpot(TM) 64-Bit Server VM, Java 9-ea). Type in expressions for evaluation. Or try :help. scala> import StackWalker._, java.util.stream._, scala.collection.JavaConverters._ import StackWalker._ import java.util.stream._ import scala.collection.JavaConverters._ scala> (() => StackWalker.getInstance(java.util.EnumSet.of(Option.RETAIN_CLASS_REFERENCE)).walk[Seq[String]]((s: java.util.stream.Stream[StackFrame]) => s.iterator.asScala.take(3).map(_.toString).toList)).apply().mkString("\n") res0: String = .$anonfun$res0$1(<console>:21) .<init>(<console>:21) .<clinit>(<console>) scala> ``` I've marked the new class, `NioFile` as `private[scala]` to justify the forward compatibility whitelist entry. In principle we could use NioFile more widely rather than `PlainFile` I tried this out in https://github.com/retronym/scala/commit/b2d0a17a which passed CI. But to be conservative, I'm not submitting that change at this point.
Diffstat (limited to 'src/reflect/scala/reflect/io/PlainFile.scala')
-rw-r--r--src/reflect/scala/reflect/io/PlainFile.scala80
1 files changed, 79 insertions, 1 deletions
diff --git a/src/reflect/scala/reflect/io/PlainFile.scala b/src/reflect/scala/reflect/io/PlainFile.scala
index eb0940e703..989081ebe0 100644
--- a/src/reflect/scala/reflect/io/PlainFile.scala
+++ b/src/reflect/scala/reflect/io/PlainFile.scala
@@ -40,7 +40,6 @@ class PlainFile(val givenPath: Path) extends AbstractFile {
override def output = givenPath.toFile.outputStream()
override def sizeOption = Some(givenPath.length.toInt)
- override def toString = path
override def hashCode(): Int = fpath.hashCode()
override def equals(that: Any): Boolean = that match {
case x: PlainFile => fpath == x.fpath
@@ -91,3 +90,82 @@ class PlainFile(val givenPath: Path) extends AbstractFile {
def lookupNameUnchecked(name: String, directory: Boolean): AbstractFile =
new PlainFile(givenPath / name)
}
+
+private[scala] class PlainNioFile(nioPath: java.nio.file.Path) extends AbstractFile {
+ import java.nio.file._
+
+ assert(nioPath ne null)
+
+ /** Returns the underlying File if any and null otherwise. */
+ override def file: java.io.File = try {
+ nioPath.toFile
+ } catch {
+ case _: UnsupportedOperationException => null
+ }
+
+ override def underlyingSource = Some(this)
+
+ private val fpath = nioPath.toAbsolutePath.toString
+
+ /** Returns the name of this abstract file. */
+ def name = nioPath.getFileName.toString
+
+ /** Returns the path of this abstract file. */
+ def path = nioPath.toString
+
+ /** The absolute file. */
+ def absolute = new PlainNioFile(nioPath.toAbsolutePath)
+
+ override def container: AbstractFile = new PlainNioFile(nioPath.getParent)
+ override def input = Files.newInputStream(nioPath)
+ override def output = Files.newOutputStream(nioPath)
+ override def sizeOption = Some(Files.size(nioPath).toInt)
+ override def hashCode(): Int = fpath.hashCode()
+ override def equals(that: Any): Boolean = that match {
+ case x: PlainNioFile => fpath == x.fpath
+ case _ => false
+ }
+
+ /** Is this abstract file a directory? */
+ def isDirectory: Boolean = Files.isDirectory(nioPath)
+
+ /** Returns the time that this abstract file was last modified. */
+ def lastModified: Long = Files.getLastModifiedTime(nioPath).toMillis
+
+ /** Returns all abstract subfiles of this abstract directory. */
+ def iterator: Iterator[AbstractFile] = {
+ try {
+ import scala.collection.JavaConverters._
+ val it = Files.newDirectoryStream(nioPath).iterator()
+ it.asScala.map(new PlainNioFile(_))
+ } catch {
+ case _: NotDirectoryException => Iterator.empty
+ }
+ }
+
+ /**
+ * Returns the abstract file in this abstract directory with the
+ * specified name. If there is no such file, returns null. The
+ * argument "directory" tells whether to look for a directory or
+ * or a regular file.
+ */
+ def lookupName(name: String, directory: Boolean): AbstractFile = {
+ val child = nioPath.resolve(name)
+ if ((Files.isDirectory(child) && directory) || (Files.isRegularFile(child) && !directory)) new PlainNioFile(child)
+ else null
+ }
+
+ /** Does this abstract file denote an existing file? */
+ def create(): Unit = if (!exists) Files.createFile(nioPath)
+
+ /** Delete the underlying file or directory (recursively). */
+ def delete(): Unit =
+ if (Files.isRegularFile(nioPath)) Files.deleteIfExists(nioPath)
+ else if (Files.isDirectory(nioPath)) new Directory(nioPath.toFile).deleteRecursively()
+
+ /** Returns a plain file with the given name. It does not
+ * check that it exists.
+ */
+ def lookupNameUnchecked(name: String, directory: Boolean): AbstractFile =
+ new PlainNioFile(nioPath.resolve(name))
+}