From 7c41f18b8c7ce18313dac11d693cb9532a766d44 Mon Sep 17 00:00:00 2001 From: Aleksander Boruch-Gruszecki Date: Mon, 7 Dec 2020 14:58:40 +0100 Subject: [PATCH 1/2] Always use forward slash as path element separator in TASTy --- compiler/src/dotty/tools/dotc/util/SourceFile.scala | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/util/SourceFile.scala b/compiler/src/dotty/tools/dotc/util/SourceFile.scala index 1afda8d33c5f..fcd8b2d55d06 100644 --- a/compiler/src/dotty/tools/dotc/util/SourceFile.scala +++ b/compiler/src/dotty/tools/dotc/util/SourceFile.scala @@ -233,7 +233,15 @@ object SourceFile { // As we already check that the prefix matches, the special handling for // Windows is not needed. - refPath.relativize(sourcePath).toString + // We also consistently use forward slashes as path element separators + // for relative paths. If we didn't do that, it'd be impossible to parse + // them back, as one would need to know whether they were created on Windows + // and use both slashes as separators, or on other OS and use forward slash + // as separator, backslash as file name character. + + import scala.jdk.CollectionConverters._ + val path = refPath.relativize(sourcePath) + path.iterator.asScala.mkString("/") else sourcePath.toString } From 0c17ff47c1a49d4d9b81bdbd96f22843529c08e5 Mon Sep 17 00:00:00 2001 From: Aleksander Boruch-Gruszecki Date: Tue, 8 Dec 2020 19:16:34 +0100 Subject: [PATCH 2/2] Test pickling paths with a JUnit test --- .../dotc/core/tasty/PathPicklingTest.scala | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 compiler/test/dotty/tools/dotc/core/tasty/PathPicklingTest.scala diff --git a/compiler/test/dotty/tools/dotc/core/tasty/PathPicklingTest.scala b/compiler/test/dotty/tools/dotc/core/tasty/PathPicklingTest.scala new file mode 100644 index 000000000000..2a44c681e8f1 --- /dev/null +++ b/compiler/test/dotty/tools/dotc/core/tasty/PathPicklingTest.scala @@ -0,0 +1,76 @@ +package dotty.tools.dotc.core.tasty + +import java.io.{File => JFile, ByteArrayOutputStream, IOException} +import java.nio.file.{Files, NoSuchFileException, Path, Paths} + +import scala.sys.process._ + +import org.junit.Test +import org.junit.Assert.{assertEquals, assertTrue, assertFalse, fail} + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.ast.tpd.TreeOps +import dotty.tools.dotc.{Driver, Main} +import dotty.tools.dotc.decompiler +import dotty.tools.dotc.core.Comments.CommentsContext +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Decorators.{toTermName, toTypeName} +import dotty.tools.dotc.core.Mode +import dotty.tools.dotc.core.Names.Name +import dotty.tools.dotc.interfaces.Diagnostic.ERROR +import dotty.tools.dotc.reporting.TestReporter +import dotty.tools.io.{Directory, File, Path} + +import dotty.tools.vulpix.TestConfiguration + +class PathPicklingTest { + + @Test def test(): Unit = { + val out = JFile("out/testPathPickling") + val cwd = JFile("").getAbsolutePath() + delete(out) + out.mkdir() + + locally { + val ignorantProcessLogger = ProcessLogger(_ => ()) + val options = TestConfiguration.defaultOptions + .and("-d", s"$out/out.jar") + .and("-sourceroot", "tests/pos") + .and(s"$cwd/tests/pos/i10430/lib.scala", s"$cwd/tests/pos/i10430/app.scala") + val reporter = TestReporter.reporter(System.out, logLevel = ERROR) + val rep = Main.process(options.all, reporter) + assertFalse("Compilation failed.", rep.hasErrors) + } + + val decompiled = + val outstream = new ByteArrayOutputStream() + val options = TestConfiguration.defaultOptions + .and("-print-tasty") + .and("-color:never") + .and(s"$out/out.jar") + val reporter = TestReporter.reporter(System.out, logLevel = ERROR) + val rep = Console.withOut(outstream) { + decompiler.Main.process(options.all, reporter) + } + assertFalse("Decompilation failed.", rep.hasErrors) + new String(outstream.toByteArray(), "UTF-8") + + assertTrue(decompiled.contains(": i10430/lib.scala")) + assertTrue(decompiled.contains(": i10430/app.scala")) + assertTrue(decompiled.contains("[i10430/lib.scala]")) + assertTrue(decompiled.contains("[i10430/app.scala]")) + + assertFalse(decompiled.contains(": i10430\\lib.scala")) + assertFalse(decompiled.contains(": i10430\\app.scala")) + assertFalse(decompiled.contains("[i10430\\lib.scala]")) + assertFalse(decompiled.contains("[i10430\\app.scala]")) + } + + private def delete(file: JFile): Unit = { + if (file.isDirectory) file.listFiles.foreach(delete) + try Files.delete(file.toPath) + catch { + case _: NoSuchFileException => // already deleted, everything's fine + } + } +}