Skip to content

Commit 68d383c

Browse files
committed
Support -d with .jar paths
1 parent 72fa00d commit 68d383c

File tree

5 files changed

+62
-10
lines changed

5 files changed

+62
-10
lines changed

compiler/src/dotty/tools/backend/jvm/GenBCode.scala

+28-4
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ import Denotations._
2626
import Phases._
2727
import java.lang.AssertionError
2828
import java.io.{DataOutputStream, File => JFile}
29+
import dotty.tools.io.{Jar, File, Directory}
2930

3031
import scala.tools.asm
3132
import scala.tools.asm.tree._
3233
import dotty.tools.dotc.util.{DotClass, Positions}
3334
import tpd._
3435
import StdNames._
3536

36-
import dotty.tools.io.{AbstractFile, Directory, PlainDirectory}
37+
import dotty.tools.io._
3738

3839
class GenBCode extends Phase {
3940
def phaseName: String = "genBCode"
@@ -46,14 +47,37 @@ class GenBCode extends Phase {
4647
superCallsMap.put(sym, old + calls)
4748
}
4849

49-
def outputDir(implicit ctx: Context): AbstractFile =
50-
new PlainDirectory(ctx.settings.outputDir.value)
50+
def outputDir(implicit ctx: Context): AbstractFile = {
51+
val path = ctx.settings.outputDir.value
52+
if (path.isDirectory) new PlainDirectory(Directory(path))
53+
else new PlainFile(path)
54+
}
55+
56+
private[this] var classOutput: AbstractFile = _
5157

5258
def run(implicit ctx: Context): Unit = {
5359
new GenBCodePipeline(entryPoints.toList,
54-
new DottyBackendInterface(outputDir, superCallsMap.toMap)(ctx))(ctx).run(ctx.compilationUnit.tpdTree)
60+
new DottyBackendInterface(classOutput, superCallsMap.toMap)(ctx))(ctx).run(ctx.compilationUnit.tpdTree)
5561
entryPoints.clear()
5662
}
63+
64+
override def runOn(units: List[CompilationUnit])(implicit ctx: Context) = {
65+
val output = outputDir
66+
if (output.isDirectory) {
67+
classOutput = output
68+
val res = super.runOn(units)
69+
classOutput = null
70+
res
71+
} else {
72+
assert(output.hasExtension("jar"))
73+
classOutput = new PlainDirectory(Path(Path(output.file).parent + "/tmp-jar-" + System.currentTimeMillis().toHexString).createDirectory())
74+
val res = super.runOn(units)
75+
Jar.create(new File(ctx.settings.outputDir.value.jfile), new Directory(classOutput.file), mainClass = "")
76+
classOutput.delete()
77+
classOutput = null
78+
res
79+
}
80+
}
5781
}
5882

5983
class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInterface)(implicit val ctx: Context) extends BCodeSyncAndTry{

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class ScalaSettings extends Settings.SettingGroup {
1818
val javaextdirs = PathSetting("-javaextdirs", "Override java extdirs classpath.", Defaults.javaExtDirs)
1919
val sourcepath = PathSetting("-sourcepath", "Specify location(s) of source files.", "") // Defaults.scalaSourcePath
2020
val classpath = PathSetting("-classpath", "Specify where to find user class files.", defaultClasspath) withAbbreviation "-cp"
21-
val outputDir = DirectorySetting("-d", "directory|jar", "destination for generated classfiles.", Directory(Path(".")))
21+
val outputDir = DirectoryJarSetting("-d", "directory|jar", "destination for generated classfiles.", Directory(Path(".")))
2222
val priorityclasspath = PathSetting("-priorityclasspath", "class path that takes precedence over all other paths (or testing only)", "")
2323

2424
/** Other settings */

compiler/src/dotty/tools/dotc/config/Settings.scala

+4-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ object Settings {
2222
val ListTag = ClassTag(classOf[List[_]])
2323
val VersionTag = ClassTag(classOf[ScalaVersion])
2424
val OptionTag = ClassTag(classOf[Option[_]])
25-
val DirectoryTag = ClassTag(classOf[Directory])
25+
val DirectoryJarTag = ClassTag(classOf[Path])
2626

2727
class SettingsState(initialValues: Seq[Any]) {
2828
private[this] var values = ArrayBuffer(initialValues: _*)
@@ -161,9 +161,10 @@ object Settings {
161161
case Success(v) => update(v, args)
162162
case Failure(ex) => fail(ex.getMessage, args)
163163
}
164-
case (DirectoryTag, arg :: args) =>
164+
case (DirectoryJarTag, arg :: args) =>
165165
val path = Path(arg)
166166
if (path.isDirectory) update(Directory(path), args)
167+
else if (path.extension == "jar") update(path, args)
167168
else fail(s"'$arg' does not exist or is not a directory", args)
168169
case (_, Nil) =>
169170
missingArg
@@ -286,7 +287,7 @@ object Settings {
286287
def OptionSetting[T: ClassTag](name: String, descr: String): Setting[Option[T]] =
287288
publish(Setting(name, descr, None, propertyClass = Some(implicitly[ClassTag[T]].runtimeClass)))
288289

289-
def DirectorySetting(name: String, helpArg: String, descr: String, default: Directory): Setting[Directory] =
290+
def DirectoryJarSetting(name: String, helpArg: String, descr: String, default: Directory): Setting[Path] =
290291
publish(Setting(name, descr, default, helpArg))
291292
}
292293
}

compiler/src/dotty/tools/repl/ReplDriver.scala

+5-2
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,11 @@ class ReplDriver(settings: Array[String],
108108
val outDir: AbstractFile = {
109109
if (rootCtx.settings.outputDir.isDefault(rootCtx))
110110
new VirtualDirectory("(memory)", None)
111-
else
112-
new PlainDirectory(rootCtx.settings.outputDir.value(rootCtx))
111+
else {
112+
val path = rootCtx.settings.outputDir.value(rootCtx)
113+
assert(path.isDirectory)
114+
new PlainDirectory(Directory(path))
115+
}
113116
}
114117
compiler = new ReplCompiler(outDir)
115118
rendering = new Rendering(compiler, classLoader)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package dotty
2+
package tools
3+
package dotc
4+
5+
import java.io.{File => JFile}
6+
7+
import org.junit.Assert._
8+
import org.junit.Test
9+
import vulpix.TestConfiguration.mkClassPath
10+
11+
class JarOutputTests {
12+
13+
@Test def jarOutput: Unit = {
14+
val classPath = mkClassPath(Jars.dottyTestDeps)
15+
val source = "../tests/neg/nolib/Foo.scala"
16+
val out = new JFile("../out/jaredFoo.jar")
17+
if (out.exists()) out.delete()
18+
val options = Array("-classpath", classPath, "-d", out.toString, source)
19+
val reporter = Main.process(options)
20+
assertEquals(0, reporter.errorCount)
21+
assertTrue(out.exists())
22+
}
23+
24+
}

0 commit comments

Comments
 (0)