diff --git a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala index ad84bde680d1..0705839ea504 100644 --- a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala +++ b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala @@ -7,6 +7,7 @@ import dotty.tools.dotc.core.Phases.Phase import dotty.tools.dotc.core.Names.TypeName import scala.collection.mutable +import scala.collection.JavaConverters._ import scala.tools.asm.{ClassVisitor, CustomAttr, FieldVisitor, MethodVisitor} import scala.tools.nsc.backend.jvm._ import dotty.tools.dotc @@ -26,14 +27,16 @@ import Denotations._ import Phases._ import java.lang.AssertionError import java.io.{DataOutputStream, File => JFile} +import java.nio.file.{Files, FileSystem, FileSystems, Path => JPath} + +import dotty.tools.io.{Directory, File, Jar} import scala.tools.asm import scala.tools.asm.tree._ import dotty.tools.dotc.util.{DotClass, Positions} import tpd._ import StdNames._ - -import dotty.tools.io.{AbstractFile, Directory, PlainDirectory} +import dotty.tools.io._ class GenBCode extends Phase { def phaseName: String = "genBCode" @@ -46,17 +49,35 @@ class GenBCode extends Phase { superCallsMap.put(sym, old + calls) } - def outputDir(implicit ctx: Context): AbstractFile = - new PlainDirectory(ctx.settings.outputDir.value) + private[this] var myOutput: AbstractFile = _ + + protected def outputDir(implicit ctx: Context): AbstractFile = { + if (myOutput eq null) { + val path = Directory(ctx.settings.outputDir.value) + myOutput = + if (path.extension == "jar") JarArchive.create(path) + else new PlainDirectory(path) + } + myOutput + } def run(implicit ctx: Context): Unit = { new GenBCodePipeline(entryPoints.toList, new DottyBackendInterface(outputDir, superCallsMap.toMap)(ctx))(ctx).run(ctx.compilationUnit.tpdTree) entryPoints.clear() } + + override def runOn(units: List[CompilationUnit])(implicit ctx: Context) = { + try super.runOn(units) + finally myOutput match { + case jar: JarArchive => + jar.close() + case _ => + } + } } -class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInterface)(implicit val ctx: Context) extends BCodeSyncAndTry{ +class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInterface)(implicit val ctx: Context) extends BCodeSyncAndTry { var tree: Tree = _ diff --git a/compiler/src/dotty/tools/dotc/Run.scala b/compiler/src/dotty/tools/dotc/Run.scala index 3ebd3a408781..44dca7e1dd6b 100644 --- a/compiler/src/dotty/tools/dotc/Run.scala +++ b/compiler/src/dotty/tools/dotc/Run.scala @@ -60,7 +60,7 @@ class Run(comp: Compiler, ictx: Context) { assert(ctx.runId <= Periods.MaxPossibleRunId) def getSource(fileName: String): SourceFile = { - val f = new PlainFile(fileName) + val f = new PlainFile(io.Path(fileName)) if (f.isDirectory) { ctx.error(s"expected file, received directory '$fileName'") NoSource diff --git a/compiler/src/dotty/tools/dotc/classpath/ClassPathFactory.scala b/compiler/src/dotty/tools/dotc/classpath/ClassPathFactory.scala index 86dde8a23cd7..fffbeac83116 100644 --- a/compiler/src/dotty/tools/dotc/classpath/ClassPathFactory.scala +++ b/compiler/src/dotty/tools/dotc/classpath/ClassPathFactory.scala @@ -4,7 +4,6 @@ package dotty.tools.dotc.classpath import dotty.tools.io.{AbstractFile, VirtualDirectory} -import dotty.tools.io.Path.string2path import dotty.tools.dotc.config.Settings import FileUtils.AbstractFileOps import dotty.tools.io.ClassPath diff --git a/compiler/src/dotty/tools/dotc/config/OutputDirs.scala b/compiler/src/dotty/tools/dotc/config/OutputDirs.scala index 87ba6a7f8349..7f158b0e3230 100644 --- a/compiler/src/dotty/tools/dotc/config/OutputDirs.scala +++ b/compiler/src/dotty/tools/dotc/config/OutputDirs.scala @@ -31,7 +31,7 @@ class OutputDirs { if (dir != null && dir.isDirectory) dir // was: else if (allowJar && dir == null && Path.isJarOrZip(name, false)) - else if (allowJar && dir == null && Jar.isJarOrZip(name, false)) + else if (allowJar && dir == null && Jar.isJarOrZip(File(name), false)) new PlainFile(Path(name)) else throw new FatalError(name + " does not exist or is not a directory")) diff --git a/compiler/src/dotty/tools/dotc/config/PathResolver.scala b/compiler/src/dotty/tools/dotc/config/PathResolver.scala index 4320069c20e9..572161a06647 100644 --- a/compiler/src/dotty/tools/dotc/config/PathResolver.scala +++ b/compiler/src/dotty/tools/dotc/config/PathResolver.scala @@ -80,11 +80,11 @@ object PathResolver { def scalaHome = Environment.scalaHome def scalaHomeDir = Directory(scalaHome) def scalaHomeExists = scalaHomeDir.isDirectory - def scalaLibDir = Directory(scalaHomeDir / "lib") - def scalaClassesDir = Directory(scalaHomeDir / "classes") + def scalaLibDir = (scalaHomeDir / "lib").toDirectory + def scalaClassesDir = (scalaHomeDir / "classes").toDirectory - def scalaLibAsJar = File(scalaLibDir / "scala-library.jar") - def scalaLibAsDir = Directory(scalaClassesDir / "library") + def scalaLibAsJar = (scalaLibDir / "scala-library.jar").toFile + def scalaLibAsDir = (scalaClassesDir / "library").toDirectory def scalaLibDirFound: Option[Directory] = if (scalaLibAsJar.isFile) Some(scalaLibDir) diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index f921ce5041a9..3315086fb7a9 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -18,7 +18,7 @@ class ScalaSettings extends Settings.SettingGroup { val javaextdirs = PathSetting("-javaextdirs", "Override java extdirs classpath.", Defaults.javaExtDirs) val sourcepath = PathSetting("-sourcepath", "Specify location(s) of source files.", "") // Defaults.scalaSourcePath val classpath = PathSetting("-classpath", "Specify where to find user class files.", defaultClasspath) withAbbreviation "-cp" - val outputDir = DirectorySetting("-d", "directory|jar", "destination for generated classfiles.", Directory(Path("."))) + val outputDir = PathSetting("-d", "directory|jar", "destination for generated classfiles.", ".") val priorityclasspath = PathSetting("-priorityclasspath", "class path that takes precedence over all other paths (or testing only)", "") /** Other settings */ diff --git a/compiler/src/dotty/tools/dotc/config/Settings.scala b/compiler/src/dotty/tools/dotc/config/Settings.scala index f370dbb3f2d9..66695e14d984 100644 --- a/compiler/src/dotty/tools/dotc/config/Settings.scala +++ b/compiler/src/dotty/tools/dotc/config/Settings.scala @@ -6,7 +6,7 @@ import scala.util.{ Try, Success, Failure } import reflect.ClassTag import core.Contexts._ import scala.annotation.tailrec -import dotty.tools.io.{ Directory, Path } +import dotty.tools.io.{ Directory, File, Path } // import annotation.unchecked // Dotty deviation: Imports take precedence over definitions in enclosing package @@ -22,7 +22,6 @@ object Settings { val ListTag = ClassTag(classOf[List[_]]) val VersionTag = ClassTag(classOf[ScalaVersion]) val OptionTag = ClassTag(classOf[Option[_]]) - val DirectoryTag = ClassTag(classOf[Directory]) class SettingsState(initialValues: Seq[Any]) { private[this] var values = ArrayBuffer(initialValues: _*) @@ -141,6 +140,15 @@ object Settings { else if (!choices.contains(argRest)) fail(s"$arg is not a valid choice for $name", args) else update(argRest, args) + case (StringTag, arg :: args) if name == "-d" => + Path(arg) match { + case _: Directory => + update(arg, args) + case p if p.extension == "jar" => + update(arg, args) + case _ => + fail(s"'$arg' does not exist or is not a directory", args) + } case (StringTag, arg2 :: args2) => update(arg2, args2) case (IntTag, arg2 :: args2) => @@ -161,10 +169,6 @@ object Settings { case Success(v) => update(v, args) case Failure(ex) => fail(ex.getMessage, args) } - case (DirectoryTag, arg :: args) => - val path = Path(arg) - if (path.isDirectory) update(Directory(path), args) - else fail(s"'$arg' does not exist or is not a directory", args) case (_, Nil) => missingArg } @@ -274,6 +278,9 @@ object Settings { def PathSetting(name: String, descr: String, default: String): Setting[String] = publish(Setting(name, descr, default)) + def PathSetting(name: String, helpArg: String, descr: String, default: String): Setting[String] = + publish(Setting(name, descr, default, helpArg)) + def PhasesSetting(name: String, descr: String, default: String = ""): Setting[List[String]] = publish(Setting(name, descr, if (default.isEmpty) Nil else List(default))) @@ -285,8 +292,5 @@ object Settings { def OptionSetting[T: ClassTag](name: String, descr: String): Setting[Option[T]] = publish(Setting(name, descr, None, propertyClass = Some(implicitly[ClassTag[T]].runtimeClass))) - - def DirectorySetting(name: String, helpArg: String, descr: String, default: Directory): Setting[Directory] = - publish(Setting(name, descr, default, helpArg)) } } diff --git a/compiler/src/dotty/tools/io/AbstractFile.scala b/compiler/src/dotty/tools/io/AbstractFile.scala index 5c30f4eecf69..d0155ace3711 100644 --- a/compiler/src/dotty/tools/io/AbstractFile.scala +++ b/compiler/src/dotty/tools/io/AbstractFile.scala @@ -10,7 +10,7 @@ import java.io.{ ByteArrayOutputStream } import java.net.URL -import java.nio.file.{FileAlreadyExistsException, Files} +import java.nio.file.{FileAlreadyExistsException, Files, Paths} /** * An abstraction over files for use in the reflection/compiler libraries. @@ -21,28 +21,26 @@ import java.nio.file.{FileAlreadyExistsException, Files} * @version 1.0, 23/03/2004 */ object AbstractFile { - /** Returns "getFile(new File(path))". */ def getFile(path: String): AbstractFile = getFile(File(path)) - def getFile(path: Path): AbstractFile = getFile(path.toFile) + def getDirectory(path: String): AbstractFile = getDirectory(Directory(path)) + def getFile(path: JPath): AbstractFile = getFile(File(path)) + def getDirectory(path: JPath): AbstractFile = getDirectory(Directory(path)) /** * If the specified File exists and is a regular file, returns an * abstract regular file backed by it. Otherwise, returns `null`. */ - def getFile(file: File): AbstractFile = - if (file.isFile) new PlainFile(file) else null - - /** Returns "getDirectory(new File(path))". */ - def getDirectory(path: Path): AbstractFile = getDirectory(path.toFile) + def getFile(path: Path): AbstractFile = + if (path.isFile) new PlainFile(path) else null /** * If the specified File exists and is either a directory or a * readable zip or jar archive, returns an abstract directory * backed by it. Otherwise, returns `null`. */ - def getDirectory(file: File): AbstractFile = - if (file.isDirectory) new PlainFile(file) - else if (file.isFile && Path.isExtensionJarOrZip(file.jpath)) ZipArchive fromFile file + def getDirectory(path: Path): AbstractFile = + if (path.isDirectory) new PlainFile(path) + else if (path.isFile && Path.isExtensionJarOrZip(path.jpath)) ZipArchive fromFile path.toFile else null /** @@ -51,11 +49,8 @@ object AbstractFile { * Otherwise, returns `null`. */ def getURL(url: URL): AbstractFile = - if (url.getProtocol == "file") { - val f = new java.io.File(url.getPath) - if (f.isDirectory) getDirectory(f) - else getFile(f) - } else null + if (url.getProtocol != "file") null + else new PlainFile(new Path(Paths.get(url.toURI))) def getResources(url: URL): AbstractFile = ZipArchive fromManifestURL url } diff --git a/compiler/src/dotty/tools/io/Directory.scala b/compiler/src/dotty/tools/io/Directory.scala index facccada7277..b961e913bd44 100644 --- a/compiler/src/dotty/tools/io/Directory.scala +++ b/compiler/src/dotty/tools/io/Directory.scala @@ -8,7 +8,7 @@ package dotty.tools.io -import java.nio.file.Files +import java.nio.file.{Files, Paths} import java.util.stream.Collectors import scala.collection.JavaConverters._ @@ -19,18 +19,12 @@ import scala.collection.JavaConverters._ object Directory { import scala.util.Properties.userDir - private def normalizePath(s: String) = Some(apply(Path(s).normalize)) - def Current: Option[Directory] = if (userDir == "") None else normalizePath(userDir) + def Current: Option[Directory] = + if (userDir == "") None + else Some(apply(userDir).normalize) - def apply(path: Path): Directory = path.toDirectory - def apply(jpath: JPath): Directory = new Directory(jpath) - - // Like File.makeTemp but creates a directory instead - def makeTemp(prefix: String = Path.randomPrefix, suffix: String = null, dir: JFile = null): Directory = { - val path = File.makeTemp(prefix, suffix, dir) - path.delete() - path.createDirectory() - } + def apply(path: String): Directory = apply(Paths.get(path)) + def apply(path: JPath): Directory = new Directory(path) } /** An abstraction for directories. @@ -49,10 +43,13 @@ class Directory(jpath: JPath) extends Path(jpath) { /** An iterator over the contents of this directory. */ def list: Iterator[Path] = - jpath.toFile.listFiles match { - case null => Iterator.empty - case xs => xs.iterator.map(x => Path(x.toPath)) + if (isDirectory) { + val fileStream = Files.list(jpath) + val files = fileStream.toArray(size => new Array[JPath](size)) + fileStream.close() + files.iterator.map(Path.apply) } + else Iterator.empty def dirs: Iterator[Directory] = list collect { case x: Directory => x } def files: Iterator[File] = list collect { case x: File => x } diff --git a/compiler/src/dotty/tools/io/File.scala b/compiler/src/dotty/tools/io/File.scala index e41c954a9ea3..894a928044ce 100644 --- a/compiler/src/dotty/tools/io/File.scala +++ b/compiler/src/dotty/tools/io/File.scala @@ -12,7 +12,7 @@ import java.io.{ FileInputStream, FileOutputStream, BufferedWriter, OutputStreamWriter, BufferedOutputStream, IOException, PrintWriter } -import java.nio.file.Files +import java.nio.file.{Files, Paths} import java.nio.file.StandardOpenOption._ import scala.io.Codec @@ -22,14 +22,9 @@ import scala.io.Codec object File { def pathSeparator = java.io.File.pathSeparator def separator = java.io.File.separator - def apply(path: Path)(implicit codec: Codec) = new File(path.jpath)(codec) - // Create a temporary file, which will be deleted upon jvm exit. - def makeTemp(prefix: String = Path.randomPrefix, suffix: String = null, dir: JFile = null) = { - val jfile = java.io.File.createTempFile(prefix, suffix, dir) - jfile.deleteOnExit() - apply(jfile) - } + def apply(path: String)(implicit codec: Codec): File = apply(Paths.get(path)) + def apply(path: JPath)(implicit codec: Codec): File = new File(path) } /** An abstraction for files. For character data, a Codec @@ -59,9 +54,9 @@ class File(jpath: JPath)(implicit constructorCodec: Codec) extends Path(jpath) w def inputStream() = Files.newInputStream(jpath) /** Obtains a OutputStream. */ - def outputStream(append: Boolean = false) = - if (append) Files.newOutputStream(jpath, APPEND) - else Files.newOutputStream(jpath) + def outputStream(append: Boolean = false) = + if (append) Files.newOutputStream(jpath, CREATE, APPEND) + else Files.newOutputStream(jpath, CREATE, TRUNCATE_EXISTING) def bufferedOutput(append: Boolean = false) = new BufferedOutputStream(outputStream(append)) /** Obtains an OutputStreamWriter wrapped around a FileOutputStream. diff --git a/compiler/src/dotty/tools/io/Jar.scala b/compiler/src/dotty/tools/io/Jar.scala index 7c84916b55b9..64bcef22027b 100644 --- a/compiler/src/dotty/tools/io/Jar.scala +++ b/compiler/src/dotty/tools/io/Jar.scala @@ -35,7 +35,7 @@ import scala.annotation.tailrec // static Attributes.Name SPECIFICATION_VERSION class Jar(file: File) extends Iterable[JarEntry] { - def this(jfile: JFile) = this(File(jfile)) + def this(jfile: JFile) = this(File(jfile.toPath)) def this(path: String) = this(File(path)) protected def errorFn(msg: String): Unit = Console println msg diff --git a/compiler/src/dotty/tools/io/JarArchive.scala b/compiler/src/dotty/tools/io/JarArchive.scala new file mode 100644 index 000000000000..ba9818d1b689 --- /dev/null +++ b/compiler/src/dotty/tools/io/JarArchive.scala @@ -0,0 +1,31 @@ +package dotty.tools.io + +import java.nio.file.{Files, FileSystem, FileSystems} + +import scala.collection.JavaConverters._ + +/** + * This class implements an [[AbstractFile]] backed by a jar + * that be can used as the compiler's output directory. + */ +class JarArchive private (root: Directory) extends PlainDirectory(root) { + def close() = jpath.getFileSystem().close() +} + +object JarArchive { + /** Create a new jar file. Overwrite if file already exists */ + def create(path: Path): JarArchive = { + require(path.extension == "jar") + + path.delete() + + // creating a new zip file system by using the JAR URL syntax: + // https://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html + val env = Map("create" -> "true").asJava + val uri = java.net.URI.create("jar:file:" + path.toAbsolute.path) + val fs = FileSystems.newFileSystem(uri, env) + + val root = fs.getRootDirectories().iterator.next() + new JarArchive(Directory(root)) + } +} diff --git a/compiler/src/dotty/tools/io/Path.scala b/compiler/src/dotty/tools/io/Path.scala index a55d033f748d..fbd2a4ac92c7 100644 --- a/compiler/src/dotty/tools/io/Path.scala +++ b/compiler/src/dotty/tools/io/Path.scala @@ -47,10 +47,6 @@ object Path { else name.substring(i + 1).toLowerCase } - // not certain these won't be problematic, but looks good so far - implicit def string2path(s: String): Path = apply(s) - implicit def jfile2path(jfile: JFile): Path = apply(jfile.toPath) - def onlyDirs(xs: Iterator[Path]): Iterator[Directory] = xs filter (_.isDirectory) map (_.toDirectory) def onlyDirs(xs: List[Path]): List[Directory] = xs filter (_.isDirectory) map (_.toDirectory) def onlyFiles(xs: Iterator[Path]): Iterator[File] = xs filter (_.isFile) map (_.toFile) @@ -95,6 +91,7 @@ class Path private[io] (val jpath: JPath) { /** Creates a new Path with the specified path appended. Assumes * the type of the new component implies the type of the result. */ + def /(child: String): Path = new Path(jpath.resolve(child)) def /(child: Path): Path = resolve(child) def /(child: Directory): Directory = /(child: Path).toDirectory def /(child: File): File = /(child: Path).toFile @@ -117,31 +114,24 @@ class Path private[io] (val jpath: JPath) { def walk: Iterator[Path] = walkFilter(_ => true) // identity - def name: String = jpath.getFileName().toString + def name: String = jpath.getFileName() match { + case null => "" + case name => name.toString + } def path: String = jpath.toString - def normalize: Path = Path(jpath.normalize) + def normalize: Path = new Path(jpath.normalize) - def resolve(other: Path) = Path(jpath.resolve(other.jpath)) - def relativize(other: Path) = Path(jpath.relativize(other.jpath)) + def resolve(other: Path) = new Path(jpath.resolve(other.jpath)) + def relativize(other: Path) = new Path(jpath.relativize(other.jpath)) def segments: List[String] = (path split separator).toList filterNot (_.length == 0) /** * @return The path of the parent directory, or root if path is already root */ - def parent: Directory = path match { - case "" | "." => Directory("..") - case _ => - // the only solution <-- a comment which could have used elaboration - if (segments.nonEmpty && segments.last == "..") - (path / "..").toDirectory - else jpath.getParent match { - case null => - if (isAbsolute) toDirectory // it should be a root. BTW, don't need to worry about relative pathed root - else Directory(".") // a dir under pwd - case x => - Directory(x) - } + def parent: Directory = jpath.normalize.getParent match { + case null => Directory(jpath) + case parent => Directory(parent) } def parents: List[Directory] = { val p = parent @@ -164,12 +154,12 @@ class Path private[io] (val jpath: JPath) { // returns the filename without the extension. def stripExtension: String = name stripSuffix ("." + extension) // returns the Path with the extension. - def addExtension(ext: String): Path = Path(path + "." + ext) + def addExtension(ext: String): Path = new Path(jpath.resolveSibling(name + ext)) // changes the existing extension out for a new one, or adds it // if the current path has none. def changeExtension(ext: String): Path = if (extension == "") addExtension(ext) - else Path(path.stripSuffix(extension) + ext) + else new Path(jpath.resolveSibling(stripExtension + "." + ext)) // conditionally execute def ifFile[T](f: File => T): Option[T] = if (isFile) Some(f(toFile)) else None diff --git a/compiler/src/dotty/tools/io/PlainFile.scala b/compiler/src/dotty/tools/io/PlainFile.scala index 2a381cb5745a..9eb2705dd622 100644 --- a/compiler/src/dotty/tools/io/PlainFile.scala +++ b/compiler/src/dotty/tools/io/PlainFile.scala @@ -22,7 +22,7 @@ class PlainDirectory(givenPath: Directory) extends PlainFile(givenPath) { class PlainFile(val givenPath: Path) extends AbstractFile { assert(path ne null) - val jpath = givenPath.jpath + def jpath = givenPath.jpath override def underlyingSource = Some(this) private val fpath = givenPath.toAbsolute @@ -37,8 +37,8 @@ class PlainFile(val givenPath: Path) extends AbstractFile { def absolute = new PlainFile(givenPath.toAbsolute) override def container: AbstractFile = new PlainFile(givenPath.parent) - override def input = Files.newInputStream(jpath) - override def output = Files.newOutputStream(jpath) + override def input = givenPath.toFile.inputStream() + override def output = givenPath.toFile.outputStream() override def sizeOption = Some(givenPath.length.toInt) override def hashCode(): Int = fpath.hashCode() @@ -58,11 +58,10 @@ class PlainFile(val givenPath: Path) extends AbstractFile { // Optimization: Assume that the file was not deleted and did not have permissions changed // between the call to `list` and the iteration. This saves a call to `exists`. def existsFast(path: Path) = path match { - case (_: Directory | _: io.File) => true + case (_: Directory | _: File) => true case _ => path.exists } - if (!isDirectory) Iterator.empty - else givenPath.toDirectory.list filter existsFast map (new PlainFile(_)) + givenPath.toDirectory.list.filter(existsFast).map(new PlainFile(_)) } /** diff --git a/compiler/src/dotty/tools/repl/ReplDriver.scala b/compiler/src/dotty/tools/repl/ReplDriver.scala index 858e2338b9e0..4f5c01505c5f 100644 --- a/compiler/src/dotty/tools/repl/ReplDriver.scala +++ b/compiler/src/dotty/tools/repl/ReplDriver.scala @@ -108,8 +108,11 @@ class ReplDriver(settings: Array[String], val outDir: AbstractFile = { if (rootCtx.settings.outputDir.isDefault(rootCtx)) new VirtualDirectory("(memory)", None) - else - new PlainDirectory(rootCtx.settings.outputDir.value(rootCtx)) + else { + val path = Directory(rootCtx.settings.outputDir.value(rootCtx)) + assert(path.isDirectory) + new PlainDirectory(path) + } } compiler = new ReplCompiler(outDir) rendering = new Rendering(compiler, classLoader) diff --git a/compiler/test/dotty/tools/dotc/CompilerTest.scala b/compiler/test/dotty/tools/dotc/CompilerTest.scala index dd12bf2d148f..888b20f69efa 100644 --- a/compiler/test/dotty/tools/dotc/CompilerTest.scala +++ b/compiler/test/dotty/tools/dotc/CompilerTest.scala @@ -6,7 +6,7 @@ import reporting._ import diagnostic.MessageContainer import util.SourcePosition import config.CompilerCommand -import dotty.tools.io.PlainFile +import dotty.tools.io.{PlainFile, Path} import scala.collection.mutable.ListBuffer import dotty.tools.io.{ Path, Directory, File => SFile, AbstractFile } import scala.annotation.tailrec @@ -44,7 +44,7 @@ abstract class CompilerTest { if (runTest) log(s"WARNING: run tests can only be run by partest, JUnit just verifies compilation: $prefix$fileName$extension") if (args.contains("-rewrite")) { - val file = new PlainFile(filePath) + val file = new PlainFile(Path(filePath)) val data = file.toByteArray // compile with rewrite compileArgs((filePath :: args).toArray, expErrors) @@ -338,7 +338,7 @@ abstract class CompilerTest { @tailrec def copyfile(file: SFile, bytewise: Boolean): Unit = { if (bytewise) { val in = file.inputStream() - val out = SFile(dest).outputStream() + val out = dest.toFile.outputStream() val buffer = new Array[Byte](1024) @tailrec def loop(available: Int):Unit = { if (available < 0) {()} @@ -353,7 +353,7 @@ abstract class CompilerTest { out.close() } else { try { - SFile(dest)(scala.io.Codec.UTF8).writeAll((s"/* !!!!! WARNING: DO NOT MODIFY. Original is at: $file !!!!! */").replace("\\", "/"), file.slurp("UTF-8")) + SFile(dest.jpath)(scala.io.Codec.UTF8).writeAll((s"/* !!!!! WARNING: DO NOT MODIFY. Original is at: $file !!!!! */").replace("\\", "/"), file.slurp("UTF-8")) } catch { case unmappable: java.nio.charset.MalformedInputException => copyfile(file, true) //there are bytes that can't be mapped with UTF-8. Bail and just do a straight byte-wise copy without the warning header. @@ -390,7 +390,7 @@ abstract class CompilerTest { if (!genSrc.isDefined) { NotExists } else { - val source = processFileDir(sourceFile, { f => try Some(f.slurp("UTF8")) catch {case _: java.io.IOException => None} }, { d => Some("") }, + val source = processFileDir(Path(sourceFile.toPath), { f => try Some(f.slurp("UTF8")) catch {case _: java.io.IOException => None} }, { d => Some("") }, Some("DPCompilerTest sourceFile doesn't exist: " + sourceFile)).get if (source == genSrc) { nerr match { diff --git a/compiler/test/dotty/tools/dotc/SettingsTests.scala b/compiler/test/dotty/tools/dotc/SettingsTests.scala index 98603b39fb36..b1fffbabda44 100644 --- a/compiler/test/dotty/tools/dotc/SettingsTests.scala +++ b/compiler/test/dotty/tools/dotc/SettingsTests.scala @@ -3,6 +3,11 @@ package dotty.tools.dotc import org.junit.Test import org.junit.Assert._ +import java.nio.file._ + +import dotty.Jars +import dotty.tools.vulpix.TestConfiguration.mkClassPath + class SettingsTests { @Test def missingOutputDir: Unit = { @@ -11,4 +16,15 @@ class SettingsTests { assertEquals(1, reporter.errorCount) assertEquals("'not_here' does not exist or is not a directory", reporter.allErrors.head.message) } + + @Test def jarOutput: Unit = { + val classPath = mkClassPath(Jars.dottyTestDeps) + val source = "../tests/neg/nolib/Foo.scala" + val out = Paths.get("../out/jaredFoo.jar").normalize + if (Files.exists(out)) Files.delete(out) + val options = Array("-classpath", classPath, "-d", out.toString, source) + val reporter = Main.process(options) + assertEquals(0, reporter.errorCount) + assertTrue(Files.exists(out)) + } } diff --git a/compiler/test/dotty/tools/dotc/classpath/ZipAndJarFileLookupFactoryTest.scala b/compiler/test/dotty/tools/dotc/classpath/ZipAndJarFileLookupFactoryTest.scala index babbf97f20b2..f929df085fe4 100644 --- a/compiler/test/dotty/tools/dotc/classpath/ZipAndJarFileLookupFactoryTest.scala +++ b/compiler/test/dotty/tools/dotc/classpath/ZipAndJarFileLookupFactoryTest.scala @@ -19,7 +19,7 @@ class ZipAndJarFileLookupFactoryTest { implicit val ctx: Context = new ContextBase().initialCtx assert(!ctx.settings.YdisableFlatCpCaching.value) // we're testing with our JAR metadata caching enabled. - def createCp = ZipAndJarClassPathFactory.create(AbstractFile.getFile(f.toFile)) + def createCp = ZipAndJarClassPathFactory.create(AbstractFile.getFile(f)) try { createZip(f, Array(), "p1/C.class") createZip(f, Array(), "p2/X.class") diff --git a/compiler/test/dotty/tools/dotc/parsing/ParserTest.scala b/compiler/test/dotty/tools/dotc/parsing/ParserTest.scala index 64bd5a81d9ef..93357b9f2fa1 100644 --- a/compiler/test/dotty/tools/dotc/parsing/ParserTest.scala +++ b/compiler/test/dotty/tools/dotc/parsing/ParserTest.scala @@ -13,7 +13,7 @@ import scala.collection.mutable.ListBuffer class ParserTest extends DottyTest { - def parse(name: String): Tree = parse(new PlainFile(name)) + def parse(name: String): Tree = parse(new PlainFile(File(name))) var parsed = 0 val parsedTrees = new ListBuffer[Tree] diff --git a/compiler/test/dotty/tools/dotc/parsing/ScannerTest.scala b/compiler/test/dotty/tools/dotc/parsing/ScannerTest.scala index 20958e30126d..e3e51d905747 100644 --- a/compiler/test/dotty/tools/dotc/parsing/ScannerTest.scala +++ b/compiler/test/dotty/tools/dotc/parsing/ScannerTest.scala @@ -15,7 +15,7 @@ class ScannerTest extends DottyTest { "/scaladoc/scala/tools/nsc/doc/html/page/Template.scala" ) - def scan(name: String): Unit = scan(new PlainFile(name)) + def scan(name: String): Unit = scan(new PlainFile(File(name))) def scan(file: PlainFile): Unit = { //println("***** scanning " + file)