Skip to content

Commit 558ceb0

Browse files
committed
WIP PipelineMain
1 parent 7122d06 commit 558ceb0

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/* NSC -- new Scala compiler
2+
* Copyright 2005-2018 LAMP/EPFL
3+
* @author Martin Odersky
4+
*/
5+
package scala.tools.nsc
6+
7+
import java.nio.file.{Files, Path, Paths}
8+
9+
import scala.collection.mutable
10+
import scala.reflect.internal.util.FakePos
11+
import scala.tools.nsc.reporters.Reporter
12+
import scala.tools.nsc.util.ClassPath
13+
14+
15+
class PipelineMainClass {
16+
/** Forward errors to the (current) reporter. */
17+
protected def scalacError(msg: String): Unit = {
18+
reporter.error(FakePos("scalac"), msg + "\n scalac -help gives more information")
19+
}
20+
21+
private var reporter: Reporter = _
22+
def process(args: Array[String]): Boolean = {
23+
reporter = Reporter(new Settings(scalacError))
24+
25+
def commandFor(argFileArg: String): CompilerCommand = {
26+
val ss = new Settings(scalacError)
27+
new CompilerCommand(args.toList, ss)
28+
}
29+
val projects: List[CompilerCommand] = args.toList.map(commandFor)
30+
val produces = mutable.HashMap[Path, CompilerCommand]()
31+
for (p <- projects) {
32+
val outputDir = p.settings.outputDirs.getSingleOutput.get.file.toPath.toAbsolutePath.normalize()
33+
produces(outputDir) = p
34+
}
35+
val dependsOn = mutable.HashMap[CompilerCommand, List[CompilerCommand]]()
36+
for (p <- projects) {
37+
val value: Seq[String] = ClassPath.expandPath(p.settings.classpath.value, expandStar = true)
38+
dependsOn(p) = value.flatMap(s => produces.get(Paths.get(s).toAbsolutePath.normalize())).toList
39+
}
40+
var toProcess = projects.toList
41+
val done = mutable.HashSet[CompilerCommand]()
42+
while (toProcess.nonEmpty) {
43+
val (nextRound, blocked) = toProcess.partition(x => dependsOn.getOrElse(x, Nil).forall(done))
44+
toProcess = blocked
45+
for (p <- nextRound) {
46+
if (!compile(p)) return false
47+
done += p
48+
}
49+
}
50+
true
51+
}
52+
53+
def compile(command: CompilerCommand): Boolean = {
54+
val compiler = newCompiler(command.settings)
55+
reporter = compiler.reporter
56+
try {
57+
if (reporter.hasErrors)
58+
reporter.flush()
59+
else if (command.shouldStopWithInfo)
60+
reporter.echo(command.getInfoMessage(compiler))
61+
else
62+
doCompile(command, compiler)
63+
} catch {
64+
case ex: Throwable =>
65+
compiler.reportThrowable(ex)
66+
ex match {
67+
case FatalError(msg) => // signals that we should fail compilation.
68+
case _ => throw ex // unexpected error, tell the outside world.
69+
}
70+
}
71+
!reporter.hasErrors
72+
}
73+
74+
protected def newCompiler(settings: Settings): Global = Global(settings)
75+
76+
protected def doCompile(command: CompilerCommand, compiler: Global): Unit = {
77+
if (command.files.isEmpty) {
78+
reporter.echo(command.usageMsg)
79+
reporter.echo(compiler.pluginOptionsHelp)
80+
} else {
81+
val run = new compiler.Run()
82+
run compile command.files
83+
reporter.finish()
84+
}
85+
}
86+
87+
88+
def main(args: Array[String]): Unit = System.exit(if (process(args)) 0 else 1)
89+
}
90+
91+
object PipelineMain extends PipelineMainClass {}

0 commit comments

Comments
 (0)