object Test { import java.io.{File, FileWriter} /** Tests the generation of the HTML documentation for some Scala * code samples (see value 'code' below) with different scaladoc * options (currently -access:). * * @author Stephane Micheloud */ def main(args: Array[String]) { // overwrites value of UrlContext.generator in file DocUtil.scala System.setProperty("doc.generator", "scaladoc") var dirname = System.getProperty("scalatest.output") if (dirname eq null) dirname = System.getProperty("java.io.tmpdir") val tmpDir = new File(dirname) tmpDir.mkdirs() test1(tmpDir) test2(tmpDir) } private def test1(tmpDir: File) { def testOptions(inFile: File, outDir: File, opts: String*) { val args = Array.concat(Array("-Ydoc", "-d", outDir.getPath, inFile.getPath), opts.toArray:Array[String]) if (MainDoc.main0(args)) { for (name <- List("all-classes.html", "index.html")) { val f = new File(outDir, name) println(name + ": " + generateMD5Sum(f)) } println } } val inFile = { val f = new File(tmpDir.getPath, "docgenerator1.scala") val writer = new FileWriter(f) writer.write(code1, 0, code1.length) writer.close f } testOptions(inFile, createDir(tmpDir, "test1"), "") // none (default is -access:protected) testOptions(inFile, createDir(tmpDir, "test2"), "-access:public") testOptions(inFile, createDir(tmpDir, "test3"), "-access:protected") testOptions(inFile, createDir(tmpDir, "test4"), "-access:private") } private def test2(tmpDir: File) { val code =""" package annots @deprecated object Foo { val x = 0 } @deprecated class Bar { val x = 1 } object Foo1 { @deprecated object Foo11 { val x = 3 } } class Bar1 { @deprecated object Foo11 { val x = 2 } } class Bar2 { def bar { @deprecated object Foo21 { val x = 4 } () } } object Foo2 { def foo { @deprecated object Foo21 { val x = 5 } () } } """ val inFile = { val f = new File(tmpDir.getPath, "docgenerator2.scala") val writer = new FileWriter(f) writer.write(code, 0, code.length) writer.close f } val outDir = createDir(tmpDir, "annots1") val args = Array.concat(Array("-Ydoc", "-d", outDir.getPath, inFile.getPath)) if (MainDoc.main0(args)) { for (name <- List("all-classes.html", "index.html")) { val f = new File(outDir, name) println(name + ": " + generateMD5Sum(f)) } println } } object MainDoc { import scala.tools.nsc._ import scala.tools.nsc.doc.DocDriver import scala.tools.nsc.reporters.ConsoleReporter def error(msg: String) { Console.err.println(msg) } var reporter: ConsoleReporter = _ def process(args: Array[String]) { val settings = new Settings(error) reporter = new ConsoleReporter(settings) val command = new CompilerCommand(List.fromArray(args), settings, error, false) try { object compiler extends Global(command.settings, reporter) if (reporter.hasErrors) { reporter.flush() return } val run = new compiler.Run run compile command.files object generator extends DocDriver { lazy val global: compiler.type = compiler def settings = command.settings } generator process run.units reporter.printSummary() } catch { case ex @ FatalError(msg) => if (command.settings.debug.value) ex.printStackTrace(); reporter.error(null, "fatal error: " + msg) } } def main(args: Array[String]) { process(args) exit(if (reporter.hasErrors) 1 else 0) } // main returning a status (no exit code) def main0(args: Array[String]): Boolean = { process(args) !reporter.hasErrors } } private def createDir(parent: File, dirname: String): File = { val outDir = new File(parent, dirname) outDir.mkdir outDir } private def generateMD5Sum(f: java.io.File): String = { import java.io._, java.security._ val digest = MessageDigest.getInstance("MD5") val is = new FileInputStream(f) val buffer = new Array[Byte](8192) try { var read = is.read(buffer) while (read > 0) { digest.update(buffer, 0, read) read = is.read(buffer) } val hash = digest.digest() val buf = new StringBuilder for (i <- hash.indices) buf.append((hash(i) & 0xFF).toHexString) buf.toString } catch { case e: IOException => throw new RuntimeException("Unable to process file for MD5", e) } finally { try { is.close(); } catch { case e: IOException => throw new RuntimeException("Unable to close input stream for MD5 calculation", e) } } } private val code1 = """ package examples abstract class C0 { def foo_public protected def foo_protected private def foo_private {} class C1_Public { val x_public = () protected val x_protected = () private val x_private = () } protected class C1_Protected { val x_public = () protected val x_protected = () private val x_private = () } private class C1_Private { val x_public = () protected val x_protected = () private val x_private = () } } protected abstract class C0_Protected { def foo_public protected def foo_protected private def foo_private {} class C1_Public { val x_public = () protected val x_protected = () private val x_private = () } protected class C1_Protected { val x_public = () protected val x_protected = () private val x_private = () } private class C1_Private { val x_public = () protected val x_protected = () private val x_private = () } } private abstract class C0_Private { def foo_public protected def foo_protected private def foo_private {} class C1_Public { val x_public = () protected val x_protected = () private val x_private = () } protected class C1_Protected { val x_public = () protected val x_protected = () private val x_private = () } private class C1_Private { val x_public = () protected val x_protected = () private val x_private = () } } object obj0 { def bar_public {} protected def bar_protected {} private def bar_private {} object obj1_Public { val x_public = () protected val x_protected = () private val x_private = () } protected object obj1_Protected { val x_public = () protected val x_protected = () private val x_private = () } private object obj1_Private { val x_public = () protected val x_protected = () private val x_private = () } } protected object obj0_Protected { def bar_public {} protected def bar_protected {} private def bar_private {} object obj1_Public { val x_public = () protected val x_protected = () private val x_private = () } protected object obj1_Protected { val x_public = () protected val x_protected = () private val x_private = () } private object obj1_Private { val x_public = () protected val x_protected = () private val x_private = () } } private object obj0_Private { def bar_public {} protected def bar_protected {} private def bar_private {} object obj1_Public { val x_public = () protected val x_protected = () private val x_private = () } protected object obj1_Protected { val x_public = () protected val x_protected = () private val x_private = () } private object obj1_Private { val x_public = () protected val x_protected = () private val x_private = () } } """ }