From 2b04d2a96100fad5fc88b78b6b4094ae6ae25a37 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Wed, 5 Apr 2017 00:10:30 +0200 Subject: Fix #2186: Synchronize classpath handling with Scala 2.12 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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`. --- .../tools/dotc/classpath/ClassPathFactory.scala | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 compiler/src/dotty/tools/dotc/classpath/ClassPathFactory.scala (limited to 'compiler/src/dotty/tools/dotc/classpath/ClassPathFactory.scala') diff --git a/compiler/src/dotty/tools/dotc/classpath/ClassPathFactory.scala b/compiler/src/dotty/tools/dotc/classpath/ClassPathFactory.scala new file mode 100644 index 000000000..ac8fc633f --- /dev/null +++ b/compiler/src/dotty/tools/dotc/classpath/ClassPathFactory.scala @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014 Contributor. All rights reserved. + */ +package dotty.tools.dotc.classpath + +import scala.reflect.io.{AbstractFile, VirtualDirectory} +import scala.reflect.io.Path.string2path +import dotty.tools.dotc.config.Settings +import FileUtils.AbstractFileOps +import dotty.tools.io.ClassPath +import dotty.tools.dotc.core.Contexts.Context + +/** + * 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. + */ +class ClassPathFactory { + /** + * Create a new classpath based on the abstract file. + */ + def newClassPath(file: AbstractFile)(implicit ctx: Context): ClassPath = ClassPathFactory.newClassPath(file) + + /** + * Creators for sub classpaths which preserve this context. + */ + def sourcesInPath(path: String)(implicit ctx: Context): 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] = dotty.tools.io.ClassPath.expandPath(path, expandStar) + + def expandDir(extdir: String): List[String] = dotty.tools.io.ClassPath.expandDir(extdir) + + def contentsOfDirsInPath(path: String)(implicit ctx: Context): List[ClassPath] = + for { + dir <- expandPath(path, expandStar = false) + name <- expandDir(dir) + entry <- Option(AbstractFile.getDirectory(name)) + } yield newClassPath(entry) + + def classesInExpandedPath(path: String)(implicit ctx: Context): IndexedSeq[ClassPath] = + classesInPathImpl(path, expand = true).toIndexedSeq + + def classesInPath(path: String)(implicit ctx: Context) = classesInPathImpl(path, expand = false) + + def classesInManifest(useManifestClassPath: Boolean)(implicit ctx: Context) = + if (useManifestClassPath) dotty.tools.io.ClassPath.manifests.map(url => newClassPath(AbstractFile getResources url)) + else Nil + + // Internal + protected def classesInPathImpl(path: String, expand: Boolean)(implicit ctx: Context) = + for { + file <- expandPath(path, expand) + 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)(implicit ctx: Context): ClassPath = + if (file.isJarOrZip) + ZipAndJarSourcePathFactory.create(file) + else if (file.isDirectory) + new DirectorySourcePath(file.file) + else + sys.error(s"Unsupported sourcepath element: $file") +} + +object ClassPathFactory { + def newClassPath(file: AbstractFile)(implicit ctx: Context): ClassPath = file match { + case vd: VirtualDirectory => VirtualDirectoryClassPath(vd) + case _ => + if (file.isJarOrZip) + ZipAndJarClassPathFactory.create(file) + else if (file.isDirectory) + new DirectoryClassPath(file.file) + else + sys.error(s"Unsupported classpath element: $file") + } +} -- cgit v1.2.3