diff options
author | Guillaume Martres <smarter@ubuntu.com> | 2017-04-05 00:10:30 +0200 |
---|---|---|
committer | Guillaume Martres <smarter@ubuntu.com> | 2017-04-11 16:04:31 +0200 |
commit | 2b04d2a96100fad5fc88b78b6b4094ae6ae25a37 (patch) | |
tree | ba9741bab0d92d9bf92853385d5d0c207e01f16e /compiler/src/dotty/tools/dotc/classpath/FileUtils.scala | |
parent | 92a9d05fd64ac97140aa0f01214c4738526383c3 (diff) | |
download | dotty-2b04d2a96100fad5fc88b78b6b4094ae6ae25a37.tar.gz dotty-2b04d2a96100fad5fc88b78b6b4094ae6ae25a37.tar.bz2 dotty-2b04d2a96100fad5fc88b78b6b4094ae6ae25a37.zip |
Fix #2186: Synchronize classpath handling with Scala 2.12
This commit is a very crude port of the classpath handling as it exists
in the 2.12.x branch of scalac (hash: 232d95a198c94da0c6c8393624e83e9b9ac84e81),
this replaces the existing Classpath code that was adapted from scalac
years ago.
This code was written by Grzegorz Kossakowski, MichaĆ Pociecha, Lukas
Rytz, Jason Zaugg and other scalac contributors, many thanks to them!
For more information on this implementation, see the description of the
PR that originally added it to scalac: https://github.com/scala/scala/pull/4060
Changes made to the copied code to get it to compile with dotty:
- Rename scala.tools.nsc.util.ClassPath to dotty.tools.io.ClassPath
- Rename scala.tools.nsc.classpath.* to dotty.tools.dotc.classpath.*
- Replace "private[nsc]" by "private[dotty]"
- Changed `isClass` methods in FileUtils to skip Scala 2.11
implementation classes (needed until we stop being retro-compatible with
Scala 2.11)
I also copied PlainFile.scala from scalac to get access to
`PlainNioFile`.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/classpath/FileUtils.scala')
-rw-r--r-- | compiler/src/dotty/tools/dotc/classpath/FileUtils.scala | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/compiler/src/dotty/tools/dotc/classpath/FileUtils.scala b/compiler/src/dotty/tools/dotc/classpath/FileUtils.scala new file mode 100644 index 000000000..823efbb9d --- /dev/null +++ b/compiler/src/dotty/tools/dotc/classpath/FileUtils.scala @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014 Contributor. All rights reserved. + */ +package dotty.tools.dotc.classpath + +import java.io.{File => JFile, FileFilter} +import java.net.URL +import scala.reflect.internal.FatalError +import scala.reflect.io.AbstractFile + +/** + * Common methods related to Java files and abstract files used in the context of classpath + */ +object FileUtils { + implicit class AbstractFileOps(val file: AbstractFile) extends AnyVal { + def isPackage: Boolean = file.isDirectory && mayBeValidPackage(file.name) + + def isClass: Boolean = !file.isDirectory && file.hasExtension("class") && !file.name.endsWith("$class.class") + // FIXME: drop last condition when we stop being compatible with Scala 2.11 + + 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 + */ + def toURLs(default: => Seq[URL] = Seq.empty): Seq[URL] = if (file.file == null) default else Seq(file.toURL) + } + + implicit class FileOps(val file: JFile) extends AnyVal { + def isPackage: Boolean = file.isDirectory && mayBeValidPackage(file.getName) + + def isClass: Boolean = file.isFile && file.getName.endsWith(".class") && !file.getName.endsWith("$class.class") + // FIXME: drop last condition when we stop being compatible with Scala 2.11 + } + + def stripSourceExtension(fileName: String): String = { + if (endsScala(fileName)) stripClassExtension(fileName) + else if (endsJava(fileName)) stripJavaExtension(fileName) + else throw new FatalError("Unexpected source file ending: " + fileName) + } + + def dirPath(forPackage: String) = forPackage.replace('.', '/') + + def endsClass(fileName: String): Boolean = + fileName.length > 6 && fileName.substring(fileName.length - 6) == ".class" + + def endsScalaOrJava(fileName: String): Boolean = + endsScala(fileName) || endsJava(fileName) + + def endsJava(fileName: String): Boolean = + fileName.length > 5 && fileName.substring(fileName.length - 5) == ".java" + + def endsScala(fileName: String): Boolean = + fileName.length > 6 && fileName.substring(fileName.length - 6) == ".scala" + + def stripClassExtension(fileName: String): String = + fileName.substring(0, fileName.length - 6) // equivalent of fileName.length - ".class".length + + def stripJavaExtension(fileName: String): String = + fileName.substring(0, fileName.length - 5) + + // 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 + 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) + } +} |