First cut at unifying new JavaTool interface with Doc usage.

This commit is contained in:
Josh Suereth 2015-02-27 19:11:30 -05:00
parent 127081b3c5
commit b753b150d9
5 changed files with 45 additions and 6 deletions

View File

@ -18,6 +18,8 @@ import xsbti.{ Severity, Reporter }
sealed trait JavaTools { sealed trait JavaTools {
/** The raw interface of the java compiler for direct access. */ /** The raw interface of the java compiler for direct access. */
def compiler: JavaTool def compiler: JavaTool
/** The raw interface for javadoc for direct access. */
def javadoc: JavaTool
/** /**
* This will run a java compiler. * This will run a java compiler.
* *
@ -49,6 +51,8 @@ sealed trait JavaTools {
sealed trait IncrementalCompilerJavaTools extends JavaTools { sealed trait IncrementalCompilerJavaTools extends JavaTools {
/** An instance of the java Compiler for use with incremental compilation. */ /** An instance of the java Compiler for use with incremental compilation. */
def xsbtiCompiler: xsbti.compile.JavaCompiler def xsbtiCompiler: xsbti.compile.JavaCompiler
/** An instance of javadoc for use with incremental compilation or other tasks. */
def xsbtiJavadoc: xsbti.compile.JavaCompiler
} }
/** Factory methods for getting a java toolchain. */ /** Factory methods for getting a java toolchain. */
object JavaTools { object JavaTools {
@ -56,8 +60,10 @@ object JavaTools {
def apply(c: JavaCompiler, docgen: Javadoc): JavaTools = def apply(c: JavaCompiler, docgen: Javadoc): JavaTools =
new JavaTools { new JavaTools {
override def compiler = c override def compiler = c
override def javadoc = docgen
def compile(sources: Seq[File], options: Seq[String])(implicit log: Logger, reporter: Reporter): Boolean = def compile(sources: Seq[File], options: Seq[String])(implicit log: Logger, reporter: Reporter): Boolean =
c.run(sources, options) c.run(sources, options)
def doc(sources: Seq[File], options: Seq[String])(implicit log: Logger, reporter: Reporter): Boolean = def doc(sources: Seq[File], options: Seq[String])(implicit log: Logger, reporter: Reporter): Boolean =
docgen.run(sources, options) docgen.run(sources, options)
} }
@ -86,7 +92,9 @@ object JavaTools {
val delegate = apply(compiler, doc) val delegate = apply(compiler, doc)
new IncrementalCompilerJavaTools { new IncrementalCompilerJavaTools {
val xsbtiCompiler = new JavaCompilerAdapter(delegate.compiler, instance, cpOptions) val xsbtiCompiler = new JavaCompilerAdapter(delegate.compiler, instance, cpOptions)
val xsbtiJavadoc = new JavaCompilerAdapter(delegate.javadoc, instance, cpOptions)
def compiler = delegate.compiler def compiler = delegate.compiler
def javadoc = delegate.javadoc
def compile(sources: Seq[File], options: Seq[String])(implicit log: Logger, reporter: Reporter): Boolean = def compile(sources: Seq[File], options: Seq[String])(implicit log: Logger, reporter: Reporter): Boolean =
delegate.compile(sources, options) delegate.compile(sources, options)
def doc(sources: Seq[File], options: Seq[String])(implicit log: Logger, reporter: Reporter): Boolean = def doc(sources: Seq[File], options: Seq[String])(implicit log: Logger, reporter: Reporter): Boolean =
@ -117,7 +125,9 @@ sealed trait JavaTool {
} }
/** Interface we use to compile java code. This is mostly a tag over the raw JavaTool interface. */ /** Interface we use to compile java code. This is mostly a tag over the raw JavaTool interface. */
trait JavaCompiler extends JavaTool {} trait JavaCompiler extends JavaTool {
override def toString = "javac"
}
/** Factory methods for constructing a java compiler. */ /** Factory methods for constructing a java compiler. */
object JavaCompiler { object JavaCompiler {
/** Returns a local compiler, if the current runtime supports it. */ /** Returns a local compiler, if the current runtime supports it. */
@ -133,7 +143,9 @@ object JavaCompiler {
} }
/** Interface we use to document java code. This is a tag over the raw JavaTool interface. */ /** Interface we use to document java code. This is a tag over the raw JavaTool interface. */
trait Javadoc extends JavaTool {} trait Javadoc extends JavaTool {
override def toString = "javadoc"
}
/** Factory methods for constructing a javadoc. */ /** Factory methods for constructing a javadoc. */
object Javadoc { object Javadoc {
/** Returns a local compiler, if the current runtime supports it. */ /** Returns a local compiler, if the current runtime supports it. */

View File

@ -24,7 +24,7 @@ class JavaCompilerAdapter(delegate: JavaTool, scalaInstance: xsbti.compile.Scala
override final def compileWithReporter(sources: Array[File], classpath: Array[File], output: Output, options: Array[String], reporter: Reporter, log: xsbti.Logger): Unit = { override final def compileWithReporter(sources: Array[File], classpath: Array[File], output: Output, options: Array[String], reporter: Reporter, log: xsbti.Logger): Unit = {
val target = output match { val target = output match {
case so: SingleOutput => so.outputDirectory case so: SingleOutput => so.outputDirectory
case mo: MultipleOutput => throw new RuntimeException("Javac doesn't support multiple output directories") case mo: MultipleOutput => throw new RuntimeException(delegate + " doesn't support multiple output directories")
} }
val args = commandArguments(Seq(), classpath, target, options, log) val args = commandArguments(Seq(), classpath, target, options, log)
// We sort the sources for deterministic results. // We sort the sources for deterministic results.
@ -32,7 +32,7 @@ class JavaCompilerAdapter(delegate: JavaTool, scalaInstance: xsbti.compile.Scala
if (!success) { if (!success) {
// TODO - Will the reporter have problems from Scalac? It appears like it does not, only from the most recent run. // TODO - Will the reporter have problems from Scalac? It appears like it does not, only from the most recent run.
// This is because the incremental compiler will not run javac if scalac fails. // This is because the incremental compiler will not run javac if scalac fails.
throw new CompileFailed(args.toArray, "javac returned nonzero exit code", reporter.problems()) throw new CompileFailed(args.toArray, delegate + " returned nonzero exit code", reporter.problems())
} }
} }
private[this] def commandArguments(sources: Seq[File], classpath: Seq[File], outputDirectory: File, options: Seq[String], log: Logger): Seq[String] = private[this] def commandArguments(sources: Seq[File], classpath: Seq[File], outputDirectory: File, options: Seq[String], log: Logger): Seq[String] =

View File

@ -31,6 +31,7 @@ object Compiler {
case x: JavaToolWithNewInterface => Some(x.newJavac) case x: JavaToolWithNewInterface => Some(x.newJavac)
case _ => None case _ => None
} }
} }
/** The previous source dependency analysis result from compilation. */ /** The previous source dependency analysis result from compilation. */
final case class PreviousAnalysis(analysis: Analysis, setup: Option[CompileSetup]) final case class PreviousAnalysis(analysis: Analysis, setup: Option[CompileSetup])

View File

@ -14,6 +14,7 @@ import sbinary.DefaultProtocol.FileFormat
import Cache.{ defaultEquiv, hConsCache, hNilCache, seqCache, seqFormat, streamFormat, StringFormat, UnitFormat, wrapIn } import Cache.{ defaultEquiv, hConsCache, hNilCache, seqCache, seqFormat, streamFormat, StringFormat, UnitFormat, wrapIn }
import Tracked.{ inputChanged, outputChanged } import Tracked.{ inputChanged, outputChanged }
import FilesInfo.{ exists, hash, lastModified } import FilesInfo.{ exists, hash, lastModified }
import xsbti.compile.SingleOutput
object Doc { object Doc {
import RawCompileLike._ import RawCompileLike._
@ -21,11 +22,31 @@ object Doc {
scaladoc(label, cache, compiler, Seq()) scaladoc(label, cache, compiler, Seq())
def scaladoc(label: String, cache: File, compiler: AnalyzingCompiler, fileInputOptions: Seq[String]): Gen = def scaladoc(label: String, cache: File, compiler: AnalyzingCompiler, fileInputOptions: Seq[String]): Gen =
cached(cache, fileInputOptions, prepare(label + " Scala API documentation", compiler.doc)) cached(cache, fileInputOptions, prepare(label + " Scala API documentation", compiler.doc))
@deprecated("Use new sbt.compiler.javac.* interfaces", "0.13.8")
def javadoc(label: String, cache: File, doc: sbt.compiler.Javadoc): Gen = def javadoc(label: String, cache: File, doc: sbt.compiler.Javadoc): Gen =
javadoc(label, cache, doc, Seq()) javadoc(label, cache, doc, Seq())
@deprecated("Use new sbt.compiler.javac.* interfaces", "0.13.8")
def javadoc(label: String, cache: File, doc: sbt.compiler.Javadoc, fileInputOptions: Seq[String]): Gen = def javadoc(label: String, cache: File, doc: sbt.compiler.Javadoc, fileInputOptions: Seq[String]): Gen =
cached(cache, fileInputOptions, prepare(label + " Java API documentation", filterSources(javaSourcesOnly, doc.doc))) cached(cache, fileInputOptions, prepare(label + " Java API documentation", filterSources(javaSourcesOnly, doc.doc)))
// TODO - These new javadoc methods are somewhat gross, like their predecessors. We should directly use the Javadoc interface.
def javadocWithIncrementalConfig(label: String, cache: File, doc: xsbti.compile.JavaCompiler, fileInputOptions: Seq[String]): Gen = {
def gen(sources: Seq[File], classpath: Seq[File], outputDir: File, options: Seq[String], maximumErrors: Int, log: Logger): Unit = {
//doc.run(sources, args)
// TODO - Construct logger reporter
object output extends SingleOutput {
def outputDirectory: File = outputDir
override def toString = s"SingleOutput($outputDirectory)"
}
val reporter = new LoggerReporter(maximumErrors, log)
doc.compileWithReporter(sources.toArray, classpath.toArray, output, options.toArray, reporter, log)
reporter.printSummary()
}
cached(cache, fileInputOptions, prepare(label + " Java API documentation", filterSources(javaSourcesOnly, gen)))
}
val javaSourcesOnly: File => Boolean = _.getName.endsWith(".java") val javaSourcesOnly: File => Boolean = _.getName.endsWith(".java")
@deprecated("Use `scaladoc`", "0.13.0") @deprecated("Use `scaladoc`", "0.13.0")

View File

@ -750,8 +750,13 @@ object Defaults extends BuildCommon {
(sOpts ++ Opts.doc.externalAPI(xapis), // can't put the .value calls directly here until 2.10.2 (sOpts ++ Opts.doc.externalAPI(xapis), // can't put the .value calls directly here until 2.10.2
Doc.scaladoc(label, s.cacheDirectory / "scala", cs.scalac.onArgs(exported(s, "scaladoc")), fiOpts)) Doc.scaladoc(label, s.cacheDirectory / "scala", cs.scalac.onArgs(exported(s, "scaladoc")), fiOpts))
else if (hasJava) else if (hasJava)
(jOpts, cs.newJavac match {
Doc.javadoc(label, s.cacheDirectory / "java", cs.javac.onArgs(exported(s, "javadoc")), fiOpts)) case Some(jc) =>
(jOpts,
Doc.javadocWithIncrementalConfig(label, s.cacheDirectory / "java", jc.xsbtiJavadoc, fiOpts))
case _ =>
(jOpts, Doc.javadoc(label, s.cacheDirectory / "java", cs.javac.onArgs(exported(s, "javadoc")), fiOpts))
}
else else
(Nil, RawCompileLike.nop) (Nil, RawCompileLike.nop)
runDoc(srcs, cp, out, options, maxErrors.value, s.log) runDoc(srcs, cp, out, options, maxErrors.value, s.log)