diff --git a/build.xml b/build.xml
index 9ad3252cd..f5d7953d4 100644
--- a/build.xml
+++ b/build.xml
@@ -334,6 +334,10 @@ LOCAL REFERENCE BUILD (LOCKER)
@@ -40,9 +40,7 @@ import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
*
- Class
- Type
- Class
- Type
- Class
- The default implementations of this method is an equivalence
- relation:
- windowtitle
attribute.
- *
- * @param input The value of windowtitle
.
- */
- def setWindowtitle(input: String) {
- windowtitle = Some(input)
- }
-
/** Sets the doctitle
attribute.
*
* @param input The value of doctitle
.
@@ -291,46 +269,6 @@ class Scaladoc extends MatchingTask {
doctitle = Some(input)
}
- /** Sets the stylesheetfile
attribute.
- *
- * @param input The value of stylesheetfile
.
- */
- def setStylesheetfile(input: String) {
- stylesheetfile = Some(input)
- }
-
- /** Sets the header
attribute.
- *
- * @param input The value of header
.
- */
- def setHeader(input: String) {
- pageheader = Some(input)
- }
-
- /** Sets the footer
attribute.
- *
- * @param input The value of footer
.
- */
- def setFooter(input: String) {
- pagefooter = Some(input)
- }
-
- /** Sets the top
attribute.
- *
- * @param input The value of top
.
- */
- def setTop(input: String) {
- pagetop = Some(input)
- }
-
- /** Sets the bottom
attribute.
- *
- * @param input The value of bottom
.
- */
- def setBottom(input: String) {
- pagebottom = Some(input)
- }
-
/** Set the addparams
info attribute.
*
* @param input The value for addparams
.
@@ -492,7 +430,7 @@ class Scaladoc extends MatchingTask {
\*============================================================================*/
/** Initializes settings and source files */
- protected def initialize: Pair[scala.tools.nsc.doc.Settings, List[File]] = {
+ protected def initialize: Pair[Settings, List[File]] = {
// Tests if all mandatory attributes are set and valid.
if (origin.isEmpty) error("Attribute 'srcdir' is not set.")
if (getOrigin.isEmpty) error("Attribute 'srcdir' is not set.")
@@ -542,7 +480,7 @@ class Scaladoc extends MatchingTask {
// Builds-up the compilation settings for Scalac with the existing Ant
// parameters.
- val docSettings = new scala.tools.nsc.doc.Settings(error)
+ val docSettings = new Settings(error)
docSettings.outdir.value = asString(destination.get)
if (!classpath.isEmpty)
docSettings.classpath.value = asString(getClasspath)
@@ -554,13 +492,7 @@ class Scaladoc extends MatchingTask {
docSettings.bootclasspath.value = asString(getBootclasspath)
if (!extdirs.isEmpty) docSettings.extdirs.value = asString(getExtdirs)
if (!encoding.isEmpty) docSettings.encoding.value = encoding.get
- if (!windowtitle.isEmpty) docSettings.windowtitle.value = windowtitle.get
if (!doctitle.isEmpty) docSettings.doctitle.value = decodeEscapes(doctitle.get)
- if (!stylesheetfile.isEmpty) docSettings.stylesheetfile.value = stylesheetfile.get
- if (!pageheader.isEmpty) docSettings.pageheader.value = decodeEscapes(pageheader.get)
- if (!pagefooter.isEmpty) docSettings.pagefooter.value = decodeEscapes(pagefooter.get)
- if (!pagetop.isEmpty) docSettings.pagetop.value = decodeEscapes(pagetop.get)
- if (!pagebottom.isEmpty) docSettings.pagebottom.value = decodeEscapes(pagebottom.get)
docSettings.deprecation.value = deprecation
docSettings.unchecked.value = unchecked
log("Scaladoc params = '" + addParams + "'", Project.MSG_DEBUG)
@@ -583,26 +515,11 @@ class Scaladoc extends MatchingTask {
/** Performs the compilation. */
override def execute() = {
- val Pair(commandSettings, sourceFiles) = initialize
- val reporter = new ConsoleReporter(commandSettings)
-
- // Compiles the actual code
- val compiler = new Global(commandSettings, reporter) {
- override protected def computeInternalPhases() {
- phasesSet += syntaxAnalyzer
- phasesSet += analyzer.namerFactory
- phasesSet += analyzer.typerFactory
- }
- override def onlyPresentation = true
- }
+ val Pair(docSettings, sourceFiles) = initialize
+ val reporter = new ConsoleReporter(docSettings)
try {
- val run = new compiler.Run
- run.compile(sourceFiles.map (_.toString))
- object generator extends DefaultDocDriver {
- lazy val global: compiler.type = compiler
- lazy val settings = commandSettings
- }
- generator.process(run.units)
+ val docProcessor = new scala.tools.nsc.doc.Processor(reporter, docSettings)
+ docProcessor.document(sourceFiles.map (_.toString))
if (reporter.ERROR.count > 0)
error(
"Document failed with " +
diff --git a/src/compiler/scala/tools/nsc/ScalaDoc.scala b/src/compiler/scala/tools/nsc/ScalaDoc.scala
index db9f8acdb..598127a30 100644
--- a/src/compiler/scala/tools/nsc/ScalaDoc.scala
+++ b/src/compiler/scala/tools/nsc/ScalaDoc.scala
@@ -9,7 +9,6 @@ package scala.tools.nsc
import java.io.File
-import scala.tools.nsc.doc.DefaultDocDriver
import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
import scala.tools.nsc.util.FakePos //{Position}
@@ -19,78 +18,69 @@ import scala.tools.nsc.util.FakePos //{Position}
*/
object ScalaDoc {
- val versionMsg = "Scala documentation generator " +
+ val versionMsg: String =
+ "Scaladoc " +
Properties.versionString + " -- " +
Properties.copyrightString
var reporter: ConsoleReporter = _
-
- def error(msg: String) {
- reporter.error(/*new Position */FakePos("scalac"),
- msg + "\n scalac -help gives more information")
+
+ def error(msg: String): Unit = {
+ reporter.error(FakePos("scalac"), msg + "\n scalac -help gives more information")
}
- def process(args: Array[String]) {
- val docSettings : doc.Settings = new doc.Settings(error)
+ def process(args: Array[String]): Unit = {
+
+ val docSettings: doc.Settings =
+ new doc.Settings(error)
+
reporter = new ConsoleReporter(docSettings)
- val command = new CompilerCommand(args.toList, docSettings, error, false)
- if (command.settings.version.value)
- reporter.info(null, versionMsg, true)
- else {
- if (command.settings.target.value == "msil") {
- val libpath = System.getProperty("msil.libpath")
- if (libpath != null)
- command.settings.assemrefs.value =
- command.settings.assemrefs.value + File.pathSeparator + libpath
+
+ val command =
+ new CompilerCommand(args.toList, docSettings, error, false)
+
+ if (!reporter.hasErrors) { // No need to continue if reading the command generated errors
+
+ if (docSettings.version.value)
+ reporter.info(null, versionMsg, true)
+ else if (docSettings.help.value) {
+ reporter.info(null, command.usageMsg, true)
}
- try {
- object compiler extends Global(command.settings, reporter) {
- override protected def computeInternalPhases() {
- phasesSet += syntaxAnalyzer
- phasesSet += analyzer.namerFactory
- phasesSet += analyzer.typerFactory
- }
- override def onlyPresentation = true
+ else if (docSettings.Xhelp.value)
+ reporter.info(null, command.xusageMsg, true)
+ else if (docSettings.Yhelp.value)
+ reporter.info(null, command.yusageMsg, true)
+ else if (docSettings.showPlugins.value)
+ reporter.warning(null, "Plugins are not available when using Scaladoc")
+ else if (docSettings.showPhases.value)
+ reporter.warning(null, "Phases are restricted when using Scaladoc")
+ else try {
+
+ if (docSettings.target.value == "msil") {
+ val libpath = System.getProperty("msil.libpath")
+ if (libpath != null)
+ docSettings.assemrefs.value = docSettings.assemrefs.value + File.pathSeparator + libpath
}
- if (reporter.hasErrors) {
- reporter.flush()
- return
- }
-
- if (command.settings.help.value || command.settings.Xhelp.value || command.settings.Yhelp.value) {
- if (command.settings.help.value) {
- reporter.info(null, command.usageMsg, true)
- reporter.info(null, compiler.pluginOptionsHelp, true)
- }
- if (command.settings.Xhelp.value)
- reporter.info(null, command.xusageMsg, true)
- if (command.settings.Yhelp.value)
- reporter.info(null, command.yusageMsg, true)
- } else if (command.settings.showPlugins.value)
- reporter.info(null, compiler.pluginDescriptions, true)
- else if (command.settings.showPhases.value)
- reporter.info(null, compiler.phaseDescriptions, true)
- else {
- val run = new compiler.Run()
- run compile command.files
- val generator = new DefaultDocDriver {
- lazy val global: compiler.type = compiler
- lazy val settings = docSettings
- }
- generator.process(run.units)
- reporter.printSummary()
- }
- } catch {
+
+ val docProcessor = new scala.tools.nsc.doc.Processor(reporter, docSettings)
+ docProcessor.document(command.files)
+
+ }
+ catch {
case ex @ FatalError(msg) =>
- if (command.settings.debug.value)
- ex.printStackTrace();
- reporter.error(null, "fatal error: " + msg)
+ if (docSettings.debug.value) ex.printStackTrace();
+ reporter.error(null, "fatal error: " + msg)
+ }
+ finally {
+ reporter.printSummary()
}
}
+
}
- def main(args: Array[String]) {
+ def main(args: Array[String]): Unit = {
process(args)
exit(if (reporter.hasErrors) 1 else 0)
}
+
}
diff --git a/src/compiler/scala/tools/nsc/doc/DefaultDocDriver.scala b/src/compiler/scala/tools/nsc/doc/DefaultDocDriver.scala
deleted file mode 100644
index 66d13350e..000000000
--- a/src/compiler/scala/tools/nsc/doc/DefaultDocDriver.scala
+++ /dev/null
@@ -1,307 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2007-2009 LAMP/EPFL
- * @author Sean McDirmid
- */
-// $Id$
-
-package scala.tools.nsc
-package doc
-
-import scala.collection.mutable
-import java.util.zip.ZipFile
-
-import symtab.Flags._
-import scala.xml._
-
-/**
- * @author Sean McDirmid
- */
-abstract class DefaultDocDriver extends DocDriver with ModelFrames with ModelToXML {
- import global._
- import definitions.{AnyClass, AnyRefClass}
-
- lazy val additions = new mutable.LinkedHashSet[Symbol]
- lazy val additions0 = new ModelAdditions(global) {
- override def addition(sym: global.Symbol) = {
- super.addition(sym)
- sym match {
- case sym : global.ClassSymbol => additions += sym.asInstanceOf[Symbol]
- case sym : global.ModuleSymbol => additions += sym.asInstanceOf[Symbol]
- case sym : global.TypeSymbol => additions += sym.asInstanceOf[Symbol]
- case _ =>
- }
- }
- def init {}
- }
-
- /** Add all top-level entities in ModelAdditions to allClasses */
- def addAdditionsToClasses() {
- additions0.init
- for (sym <- additions) {
- val packSym = sym.enclosingPackage
- if (packSym != NoSymbol) {
- val pack = Package(packSym)
- if (!(allClasses contains pack)) {
- // don't emit an addition unless its package
- // is already being scaladoced
- } else {
- val addition: Option[ClassOrObject] =
- if (sym.isClass)
- Some(new TopLevelClass(sym))
- else if (sym.isModule)
- Some(new TopLevelObject(sym))
- else if (sym == definitions.AnyRefClass) {
- // AnyRef is the only top-level type alias, so handle
- // it specially instead of introducing general support for
- // top-level aliases
- Some(new TopLevelClass(sym))
- }
- else
- None
-
- addition match {
- case None =>
- //println("skipping: " + sym) //DEBUG
- case Some(addition) =>
- allClasses(pack) += addition
- }
- }
- } else {
- //println("no package found for: "+sym) //DEBUG
- }
- }
- }
-
- def process(units: Iterator[CompilationUnit]) {
-
- assert(global.definitions != null)
-
- def g(pkg: Package, clazz: ClassOrObject) {
- if (isAccessible(clazz.sym)) {
- allClasses(pkg) += clazz
- clazz.decls.map(_._2).foreach {
- case clazz : ClassOrObject => g(pkg, clazz)
- case _ =>
- }
- }
- }
- def f(pkg: Package, tree: Tree) {
- if (tree != EmptyTree && tree.hasSymbol) {
- val sym = tree.symbol
- if (sym != NoSymbol && !sym.hasFlag(symtab.Flags.PRIVATE)) tree match {
- case tree : PackageDef =>
- val pkg1 = new Package(sym.asInstanceOf[ModuleSymbol])
- tree.stats.foreach(stat => f(pkg1, stat))
- case tree : ClassDef =>
- assert(pkg != null)
- g(pkg, new TopLevelClass(sym.asInstanceOf[ClassSymbol]))
- case tree : ModuleDef =>
- assert(pkg != null)
- g(pkg, new TopLevelObject(sym.asInstanceOf[ModuleSymbol]))
- case _ =>
- }
- }
- }
- units.foreach(unit => f(null, unit.body))
- addAdditionsToClasses()
-
- for (p <- allClasses; d <- p._2) {
- symbols += d.sym
- for (pp <- d.sym.tpe.parents) subClasses(pp.typeSymbol) += d
- }
- copyResources
- lazy val packages0 = sort(allClasses.keySet)
- new AllPackagesFrame with Frame { def packages = packages0 }
- new PackagesContentFrame with Frame { def packages = packages0 }
- new NavigationFrame with Frame { }
- new ListClassFrame with Frame {
- def classes = for (p <- allClasses; d <- p._2) yield d
- object organized extends mutable.LinkedHashMap[(List[String],Boolean),List[ClassOrObject]] {
- override def default(key : (List[String],Boolean)) = Nil;
- classes.foreach(cls => {
- val path = cls.path.map(_.name);
- this((path,cls.isInstanceOf[Clazz])) = cls :: this((path,cls.isInstanceOf[Clazz]));
- });
- }
-
- def title = "List of all classes and objects"
- def path = "all-classes"
- def navLabel = null // "root-page"
- // override protected def navSuffix = ".html";
- override def optional(cls: ClassOrObject): NodeSeq = {
- val path = cls.path.map(_.name)
- val key = (cls.path.map(_.name), cls.isInstanceOf[Clazz])
- assert(!organized(key).isEmpty);
-
- ((if (!organized(key).tail.isEmpty) Text(" (" +{
- //Console.println("CONFLICT: " + path + " " + organized(key));
- val str = cls.path(0).sym.owner.fullNameString('.');
- val idx = str.lastIndexOf('.');
- if (idx == -1) str;
- else str.substring(idx + 1);
- }+ ")");
- else NodeSeq.Empty) ++ super.optional(cls))//(NodeSeq.builderFactory)
- }
-
- }
- for ((pkg0, classes0) <- allClasses) {
- new ListClassFrame with Frame {
- def title =
- "List of classes and objects in package " + pkg0.fullName('.')
- def classes = classes0
- def path = pkgPath(pkg0.sym) + NAME_SUFFIX_PACKAGE
- def navLabel = pkg0.fullName('.')
- }
- new PackageContentFrame with Frame {
- def classes = classes0
- def pkg = pkg0
- }
- for (clazz0 <- classes0) {
- new ClassContentFrame with Frame {
- def clazz = clazz0
- def title =
- clazz0.kind + " " + clazz0.name + " in " + (clazz0.sym.owner.fullNameString('.'));
- }
- }
- }
- new RootFrame with Frame
- }
- override def longList(entity: ClassOrObject, category: Category)(implicit from: Frame) : NodeSeq = category match {
- case Classes | Objects => NodeSeq.Empty
- case _ => super.longList(entity, category)
- }
-
- trait Frame extends super.Frame {
- def longHeader(entity : Entity) = DefaultDocDriver.this.longHeader(entity)(this)
- def shortHeader(entity : Entity) = DefaultDocDriver.this.shortHeader(entity)(this)
- }
-
- import DocUtil._
- override def classBody(entity: ClassOrObject)(implicit from: Frame): NodeSeq =
- (((subClasses.get(entity.sym) match {
- case Some(symbols) =>
- (
-
);
- case None =>
- NodeSeq.Empty
- }): NodeSeq)++super.classBody(entity))//(NodeSeq.builderFactory)
-
- protected def urlFor(sym: Symbol)(implicit frame: Frame) = frame.urlFor(sym)
-
- override protected def decodeTag(tag: String): String = tag match {
- case "exception" => "Throws"
- case "ex" => "Examples"
- case "param" => "Parameters"
- case "pre" => "Precondition"
- case "return" => "Returns"
- case "note" => "Notes"
- case "see" => "See Also"
- case tag => super.decodeTag(tag)
- }
-
- override protected def decodeOption(tag: String, option: String): NodeSeq = tag match {
- case "throws" if additions0.exceptions.contains(option) =>
- val (sym, s) = additions0.exceptions(option)
- val path = "../" //todo: fix path
- val href = path + sym.fullNameString('/') +
- (if (sym.isModule || sym.isModuleClass) NAME_SUFFIX_OBJECT else "") +
- "#" + s
- ({option}) ++ {Text(" - ")};
- case _ =>
- super.decodeOption(tag,option)
- }
-
- object roots extends mutable.LinkedHashMap[String,String];
- roots("classes") = "http://java.sun.com/j2se/1.5.0/docs/api";
- roots("rt") = roots("classes");
- private val SCALA_API_ROOT = "http://www.scala-lang.org/docu/files/api/";
- roots("scala-library") = SCALA_API_ROOT;
-
- private def keyFor(file: ZipFile): String = {
- var name = file.getName
- var idx = name.lastIndexOf(java.io.File.pathSeparator)
- if (idx == -1) idx = name.lastIndexOf('/')
- if (idx != -1) name = name.substring(idx + 1)
- if (name endsWith ".jar") name.substring(0, name.length - (".jar").length)
- else null
- }
-
- // {Text(string + " - ")}
;
- override def hasLink0(sym: Symbol): Boolean = {
- if (sym == NoSymbol) return false;
- if (sym == AnyRefClass) {
- // AnyRefClass is a type alias, so the following logic
- // does not work. AnyClass should have a link in
- // the same cases as AnyRefClass, so test it instead.
- return hasLink(AnyClass)
- }
- if (super.hasLink0(sym) && symbols.contains(sym))
- return true;
- if (SyntheticClasses contains sym)
- return true;
- if (sym.toplevelClass == NoSymbol) return false;
- val clazz = sym.toplevelClass.asInstanceOf[ClassSymbol];
- import scala.tools.nsc.io._;
- clazz.classFile match {
- case file : ZipArchive#FileEntry =>
- val key = keyFor(file.archive);
- if (key != null && roots.contains(key)) return true;
- case null =>
- case _ =>
- }
- false
- }
-
- def aref(href: String, label: String)(implicit frame: Frame) =
- frame.aref(href, "_self", label)
-
- protected def anchor(entity: Symbol)(implicit frame: Frame): NodeSeq =
- ()
-
- object symbols extends mutable.LinkedHashSet[Symbol]
-
- object allClasses extends mutable.LinkedHashMap[Package, mutable.LinkedHashSet[ClassOrObject]] {
- override def default(pkg: Package): mutable.LinkedHashSet[ClassOrObject] = {
- object ret extends mutable.LinkedHashSet[ClassOrObject]
- this(pkg) = ret
- ret
- }
- }
-
- object subClasses extends mutable.LinkedHashMap[Symbol, mutable.LinkedHashSet[ClassOrObject]] {
- override def default(key: Symbol) = {
- val ret = new mutable.LinkedHashSet[ClassOrObject]
- this(key) = ret
- ret
- }
- }
-
- override def rootFor(sym: Symbol): String = {
- assert(sym != NoSymbol)
- if (sym == definitions.AnyRefClass) {
- // AnyRefClass is a type alias, so the following logic
- // does not work. AnyClass should have the same root,
- // so use it instead.
- return rootFor(definitions.AnyClass)
- }
- if (sym.toplevelClass == NoSymbol) return super.rootFor(sym)
- if (symbols.contains(sym.toplevelClass)) return super.rootFor(sym)
- if (SyntheticClasses contains sym)
- return SCALA_API_ROOT
- val clazz = sym.toplevelClass.asInstanceOf[ClassSymbol]
- import scala.tools.nsc.io._;
- clazz.classFile match {
- case file : ZipArchive#FileEntry =>
- val key = keyFor(file.archive)
- if (key != null && roots.contains(key)) {
- return roots(key) + '/'
- }
- case _ =>
- }
- super.rootFor(sym)
- }
-}
diff --git a/src/compiler/scala/tools/nsc/doc/DocDriver.scala b/src/compiler/scala/tools/nsc/doc/DocDriver.scala
deleted file mode 100644
index 3593775e3..000000000
--- a/src/compiler/scala/tools/nsc/doc/DocDriver.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2007-2009 LAMP/EPFL
- * @author Sean McDirmid
- */
-// $Id$
-
-package scala.tools.nsc
-package doc
-
-/**
- * This is an abstract class for documentation plugins.
- *
- * @author Geoffrey Washburn
- */
-abstract class DocDriver {
- val global: Global
- import global._
- def settings: doc.Settings
-
- def process(units: Iterator[CompilationUnit]): Unit
-}
diff --git a/src/compiler/scala/tools/nsc/doc/DocUtil.scala b/src/compiler/scala/tools/nsc/doc/DocUtil.scala
deleted file mode 100644
index f869feff7..000000000
--- a/src/compiler/scala/tools/nsc/doc/DocUtil.scala
+++ /dev/null
@@ -1,104 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2005-2009 LAMP/EPFL
- * @author Sean McDirmid
- */
-// $Id$
-
-package scala.tools.nsc
-package doc
-
-import java.io.StringReader
-import org.xml.sax.InputSource
-
-import scala.collection.immutable.{ListMap, TreeSet}
-import scala.xml._
-
-object DocUtil
-{
- def load(str: String): NodeSeq =
- if ((str == null) || (str.length == 0))
- NodeSeq.Empty
- else {
- val xmlSrc =
- if (str.matches("^()*<[^>]+>.*<[^>]+>()*$")) str
- else "
)
- def hr(nodes: NodeSeq): NodeSeq = nodes ++ (
)
-
- trait UrlContext {
- def relative: String
-
- def aref(href0: String, target: String, text: String): NodeSeq = {
- if (href0 == null) return Text(text);
-
- val href = {
- if (href0.startsWith("http:") || href0.startsWith("file:")) "";
- else relative
- } + Utility.escape(href0)
- if ((target ne null) && target.indexOf('<') != -1) throw new Error(target)
-
- val t0 = Text(text)
- if (target ne null)
- ({t0});
- else
- ({t0});
- }
-
- // can't use platform default here or the generated XML may end up all MacRoman
- val encoding = Properties.sourceEncoding
- val generator = System.getProperty("doc.generator", "scaladoc (" + Properties.versionString + ")")
- val header =
- (
-
- );
-
- def body0(hasBody: Boolean, nodes: NodeSeq): NodeSeq =
- if (!hasBody) nodes else ({nodes});
-
- val dtype = ""
-
- def page(title: String, body: NodeSeq, hasBody: Boolean): NodeSeq =
- (
- Nothing
is - together with class
- Null
- at the bottom of the
- Scala type
- hierarchy.
- Nothing
is a subtype of every other type
- (including Null
); there
- exist no instances of this type. Even though type
- Nothing
is empty, it is nevertheless useful as a
- type parameter. For instance, the Scala library defines a value
- Nil
of type
- List[Nothing]
. Because lists
- are covariant in Scala,
- this makes Nil
an
- instance of List[T]
, for
- any element type T
.
- Null
is - together with class
- Nothing
- at the bottom of the
- Scala type
- hierarchy.
- Null
is a subtype of all reference types; its
- only instance is the null
reference.
- Since Null
is not a subtype of value types,
- null
is not a member of any such type. For instance,
- it is not possible to assign null
to a variable of
- type Int
.
- Any
is the root of the Scala class hierarchy. Every class in a
- Scala execution
- environment inherits directly or indirectly from this class.
- Class Any
has two direct subclasses:
- AnyRef
and
- AnyVal
.
- this
)
- with the argument object (arg0
) for equivalence.
-
-
-
- x
of type Any
,
- x.equals(x)
should return true
.x
and y
of type
- Any
, x.equals(y)
should return true
if and only
- if y.equals(x)
returns true
.x
, y
, and z
of type AnyRef
- if x.equals(y)
returns true
and
- y.equals(z)
returns
- true
, then x.equals(z)
should return true
.
- If you override this method, you should verify that
- your implementation remains an equivalence relation.
- Additionally, when overriding this method it is often necessary to
- override hashCode
to ensure that objects that are
- "equal" (o1.equals(o2)
returns true
)
- hash to the same Int
- (o1.hashCode.equals(o2.hashCode)
).
-
- @param arg0 the object to compare against this object for equality.
- @return true
if the receiver object is equivalent to the argument; false
otherwise.
-
o == arg0
is the same as o.equals(arg0)
.
-
- @param arg0 the object to compare against this object for equality.
- @return true
if the receiver object is equivalent to the argument; false
otherwise.
-
o != arg0
is the same as !(o == (arg0))
.
-
- @param arg0 the object to compare against this object for dis-equality.
- @return false
if the receiver object is equivalent to the argument; true
otherwise.
-
- The default representation is platform dependent. - - @return a string representation of the object. -
- """ - - addition(Any_asInstanceOf); - comments(Any_asInstanceOf) = """ - This method is used to cast the receiver object to be of typeT0
.
-
- Note that the success of a cast at runtime is modulo Scala's
- erasure semantics. Therefore the expression
- 1.asInstanceOf[String]
will throw a
- ClassCastException
at runtime, while the expression
- List(1).asInstanceOf[List[String]]
will not. In the
- latter example, because the type argument is erased as part of
- compilation it is not possible to check whether the contents of
- the list are of the requested typed.
-
- @throws ClassCastException if the receiver object is not an
- instance of erasure of type T0
.
- @return the receiver object.
-
T0
.
-
- Note that the test result of the test is modulo Scala's erasure
- semantics. Therefore the expression
- 1.isInstanceOf[String]
will return
- false
, while the expression
- List(1).isInstanceOf[List[String]]
will return
- true
. In the latter example, because the type
- argument is erased as part of compilation it is not possible to
- check whether the contents of the list are of the requested typed.
-
- @return true
if the receiver object is an
- instance of erasure of type T0
; false
otherwise.
- """
-
- addition(Any_hashCode);
- comments(Any_hashCode) = """
- Returns a hash code value for the object.
-
-
- The default hashing algorithm is platform dependent.
-
- Note that it is allowed for two objects to have identical hash
- codes (o1.hashCode.equals(o2.hashCode)
) yet not be
- equal (o1.equals(o2)
returns false
). A
- degenerate implementation could always return 0
.
- However, it is required that if two objects are equal
- (o1.equals(o2)
returns true
) that they
- have identical hash codes
- (o1.hashCode.equals(o2.hashCode)
). Therefore, when
- overriding this method, be sure to verify that the behavior is
- consistent with the equals
method.
-
- @return the hash code value for the object. -
""" - - /*******************************************************************/ - /* Documentation for AnyRef */ - - addition(AnyRefClass); - comments(AnyRefClass) = """ -
- Class AnyRef
is the root class of all
- reference types.
-
o == arg0
is the same as if (o eq null) arg0 eq null else o.equals(arg0)
.
-
- @param arg0 the object to compare against this object for equality.
- @return true
if the receiver object is equivalent to the argument; false
otherwise.
-
o.ne(arg0)
is the same as !(o.eq(arg0))
.
-
- @param arg0 the object to compare against this object for reference dis-equality.
- @return false
if the argument is not a reference to the receiver object; true
otherwise.
-
- The details of when and if the finalize
method are
- invoked, as well as the interaction between finalize
- and non-local returns and exceptions, are all platform dependent.
-
- The default implementation of the clone
method is platform dependent.
-
- @return a copy of the receiver object.
-
- The nature of the representation is platform dependent. - - @return a representation that corresponds to the dynamic class of the receiver object. -
- """ - - addition(Object_notify); - comments(Object_notify) = """ - Wakes up a single thread that is waiting on the receiver object's monitor. - """ - - addition(Object_notifyAll); - comments(Object_notifyAll) = """ - Wakes up all threads that are waiting on the receiver object's monitor. - """ - - addition(Object_eq); - comments(Object_eq) = """ - This method is used to test whether the argument (arg0
) is a reference to the
- receiver object (this
).
-
-
- The eq
method implements an
- equivalence relation on non-null instances of
- AnyRef
:
-
x
of type AnyRef
,
- x.eq(x)
returns true
.x
and y
of type
- AnyRef
, x.eq(y)
returns true
if and only
- if y.eq(x)
returns true
.x
, y
, and z
of type AnyRef
- if x.eq(y)
returns true
and
- y.eq(z)
returns
- true
, then x.eq(z)
returns true
.eq
method has three other properties.
- x
and y
of type AnyRef
,
- multiple invocations of x.eq(y)
consistently returns true
- or consistently returns false
.x
of type AnyRef
,
- x.eq(null)
and null.eq(x)
returns false
.null.eq(null)
returns true
. When overriding the equals
or
- hashCode
methods, it is important to ensure that
- their behavior is consistent with reference equality. Therefore,
- if two objects are references to each other (o1 eq
- o2
), they should be equal to each other (o1 ==
- o2
) and they should hash to the same value
- (o1.hashCode == o2.hashCode
).
true
if the argument is a reference to the receiver object; false
otherwise.
-
- """
-
- /*******************************************************************/
-
- addition(AnyValClass);
- comments(AnyValClass) = """
-
- Class AnyVal
is the root class of all
- value types.
-
- AnyVal
has a fixed number subclasses, which
- describe values which are not implemented as objects in the
- underlying host system.
-
- Classes Double
,
- Float
,
- Long
,
- Int
,
- Char
,
- Short
, and
- Byte
are together called
- numeric value types.
- Classes Byte
,
- Short
, or
- Char
- are called subrange types. Subrange types, as well as
- Int
and
- Long
are called
- integer types, whereas
- Float
and
- Double
are called
- floating point types.
-
- Class Boolean
has only two values: true
- and false
.
-
- Class """ + sym.name + """
belongs to the value
- classes whose instances are not represented as objects by the
- underlying host system. There is an implicit conversion from
- instances of """ + sym.name + """
to instances of
- runtime.Rich""" + sym.name + """
which
- provides useful non-primitive operations. All value classes inherit
- from class AnyVal
.
-
- Values """ + maxValue + """
and """ + minValue + """
- are in defined in object scala.Math.
-
- Class Unit
has only one value: ()
.
-
- Class """ + sym.name + """
implements the
- boxing/unboxing from/to value types.
-
- Boxing and unboxing enable value types to be treated as objects; - they provide a unified view of the type system wherein a value - of any type can ultimately be treated as an object. -
""" - }; - //("Float" :: "Long" :: "Number" :: "Integer" :: Nil).foreach(boxedValDescr); -*/ - object exceptions extends collection.JavaConversions.JMapWrapper[String,(Symbol,String)]( - new java.util.TreeMap()) { - def f(name: String) { - this("Predef." + name) = (definitions.PredefModule, name) - } - f("IndexOutOfBoundsException") - f("NoSuchElementException") - f("NullPointerException") - f("UnsupportedOperationException") - } -} diff --git a/src/compiler/scala/tools/nsc/doc/ModelExtractor.scala b/src/compiler/scala/tools/nsc/doc/ModelExtractor.scala deleted file mode 100644 index e6c44c7cf..000000000 --- a/src/compiler/scala/tools/nsc/doc/ModelExtractor.scala +++ /dev/null @@ -1,453 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2007-2009 LAMP/EPFL - * @author Sean McDirmid - */ -// $Id$ - -package scala.tools.nsc -package doc - -import scala.collection.mutable -import compat.Platform.{EOL => LINE_SEPARATOR} - - -/** This class attempts to reverse engineer source code intent from compiler - * symbol objects. - * - * @author Sean McDirmid - */ -trait ModelExtractor { - val global: Global - import global._ - def settings: doc.Settings - - def assert(b: Boolean) { - if (!b) throw new Error - } - - def assert(b: Boolean, message: Any) { - if (!b) throw new Error(message.toString) - } - - case class Tag(tag: String, option: String, body: String) - - case class Comment(body: String, attributes: List[Tag]) { - def decodeAttributes = { - val map = new mutable.LinkedHashMap[String, List[(String, String)]] { - override def default(key: String) = Nil - } - attributes.foreach(a => { - map(a.tag) = map(a.tag) ::: List((a.option, a.body)) - }); - map - } - } - protected def decode(sym: Symbol) = - if (sym == definitions.ScalaObjectClass || sym == definitions.ObjectClass) - definitions.AnyRefClass - else sym match { - case sym: ModuleClassSymbol => sym.sourceModule - case sym => sym - } - - protected def decodeComment(comment0: String): Comment = { - val comment = { // discard outmost comment delimiters if present - val begin = if (comment0 startsWith "/**") 3 else 0 - val end = comment0.length - (if (comment0 endsWith "*/") 2 else 0) - comment0.substring(begin, end) - } - val tok = new java.util.StringTokenizer(comment, LINE_SEPARATOR) - val buf = new StringBuilder - type AttrDescr = (String, String, StringBuilder) - val attributes = new collection.mutable.ListBuffer[AttrDescr] - var attr: AttrDescr = null - while (tok.hasMoreTokens) { - val s = tok.nextToken.replaceFirst("\\p{Space}?\\*", "") - val mat1 = pat1.matcher(s) - if (mat1.matches) { - attr = (mat1.group(1), null, new StringBuilder(mat1.group(2))) - //if (kind != CONSTRUCTOR) - attributes += attr - } else { - val mat2 = pat2.matcher(s) - if (mat2.matches) { - attr = (mat2.group(1), mat2.group(2), new StringBuilder(mat2.group(3))) - //if (kind != CLASS) - attributes += attr - } else if (attr ne null) - attr._3.append(s + LINE_SEPARATOR) - else - buf.append(s + LINE_SEPARATOR) - } - } - Comment(buf.toString, attributes.toList.map({x => Tag(x._1,x._2,x._3.toString)})) - } - - sealed abstract class Entity(val sym: Symbol) { - private[ModelExtractor] def sym0 = sym - - override def toString = sym.toString - def comment: Option[String] = global.comments.get(sym) - // comments decoded, now what? - def attributes = sym.annotations - def decodeComment: Option[Comment] = { - val comment0 = this.comment - if (comment0.isEmpty) None - else Some(ModelExtractor.this.decodeComment(comment0.get.trim)) - } - protected def accessQualified(core: String, qual: String) = core match { - case "public" => "" // assert(qual == null); ""; - case core => core + (if (qual == null) "" else "[" + qual + "]") - } - - def flagsString = { - import symtab.Flags - //val isLocal = sym.hasFlag(Flags.LOCAL) - val x = - if (sym hasFlag Flags.PRIVATE) "private" - else if (sym hasFlag Flags.PROTECTED) "protected" - else "public" - var string = accessQualified(x, - if (sym hasFlag Flags.LOCAL) "this" - else if (sym.privateWithin != null && sym.privateWithin != NoSymbol) - sym.privateWithin.nameString - else null - ) - def f(flag: Int, str: String) { - if (sym hasFlag flag) string = string + " " + str - } - f(Flags.IMPLICIT, "implicit") - f(Flags.SEALED, "sealed") - f(Flags.OVERRIDE, "override") - f(Flags.CASE, "case") - if (!sym.isTrait) f(Flags.ABSTRACT, "abstract") - if (!sym.isModule) f(Flags.FINAL, "final") - if (!sym.isTrait) f(Flags.DEFERRED, "abstract") - string.trim - } - def listName = name - def name = sym.nameString - def fullName(sep: Char) = sym.fullNameString(sep) - def kind: String - def header { } - def typeParams: List[TypeParam] = Nil - def valueParams: List[List[ValueParam]] = Nil - def resultType: Option[Type] = None - def parents: Iterable[Type] = Nil - def lo: Option[Type] = sym.info match { - case TypeBounds(lo, hi) if decode(lo.typeSymbol) != definitions.NothingClass => Some(lo) - case _ => None - } - def hi: Option[Type] = sym.info match { - case TypeBounds(lo, hi) if decode(hi.typeSymbol) != definitions.AnyClass => Some(hi) - case _ => None - } - def variance = { - import symtab.Flags._ - if (sym hasFlag COVARIANT) "+" - else if (sym hasFlag CONTRAVARIANT) "-" - else "" - } - def overridden: Iterable[Symbol] = Nil - } - - class ValueParam(sym: Symbol) extends Entity(sym) { - override def resultType = Some(sym.tpe) - //def kind = if (sym.isPublic) "val" else ""; - def kind = "" - } - - class ConstructorParam(sym: Symbol) extends ValueParam(sym) { - override protected def accessQualified(core: String, qual: String) = core match { - case "public" => "val" - case "protected" => super.accessQualified(core,qual) + " val" - case "private" if qual == "this" => "" - case core => super.accessQualified(core, qual) - } - } - - def ValueParam(sym: Symbol) = new ValueParam(sym) - class TypeParam(sym: Symbol) extends Entity(sym) { - def kind = "" - } - def TypeParam(sym: Symbol) = new TypeParam(sym) - - trait Clazz extends ClassOrObject { - private def csym = sym.asInstanceOf[TypeSymbol] - override def typeParams = csym.typeParams.map(TypeParam) - override def valueParams = { - if (constructorArgs.isEmpty) Nil - else constructorArgs.valuesIterator.toList :: Nil - } - def isTrait = csym.isTrait - override def kind = if (sym.isTrait) "trait" else "class" - } - - trait Object extends ClassOrObject { - override def kind = "object" - } - - case class Package(override val sym: Symbol) extends Entity(sym) { - override def kind = "package" - override def name = fullName('.') - } - - trait TopLevel extends ClassOrObject - class TopLevelClass (sym: Symbol) extends Entity(sym) with TopLevel with Clazz - class TopLevelObject(sym: Symbol) extends Entity(sym) with TopLevel with Object { - override def attributes = sym.moduleClass.annotations - } - - def compare(pathA: List[ClassOrObject], pathB: List[ClassOrObject]): Int = { - var pA = pathA - var pB = pathB - while (true) { - if (pA.isEmpty) return -1 - if (pB.isEmpty) return +1 - val diff = pA.head.name compare pB.head.name - if (diff != 0) return diff - pA = pA.tail - pB = pB.tail - } - 0 - } - - def isAccessible(sym: Symbol): Boolean = { - import symtab.Flags._ - settings.memberaccess.value match { - case "private" => sym.isPublic || (sym hasFlag PROTECTED) || (sym hasFlag PRIVATE) - case "protected" => sym.isPublic || (sym hasFlag PROTECTED) - case "public" => sym.isPublic - case _ => false - } - } - - trait ClassOrObject extends Entity { - def path: List[ClassOrObject] = this :: Nil - override def listName = path map (_.name) mkString "." - - object freshParents extends mutable.LinkedHashSet[Type] { - this ++= sym.tpe.parents - this.toList foreach (this --= _.parents) - } - object constructorArgs extends mutable.LinkedHashMap[Symbol, ValueParam] { - import symtab.Flags._ - sym.constrParamAccessors.filter(arg => ! (arg hasFlag SYNTHETIC)).foreach(arg => { - val str = flagsToString(arg.flags) - assert((arg hasFlag PRIVATE) && (arg hasFlag LOCAL), arg) - val argName = arg.name.toString.trim - val actual = sym.tpe.decls.iterator.find(e => { - val eName = e.name.toString.trim; - argName == eName && { - val str = flagsToString(e.flags); - !e.hasFlag(LOCAL); - } - }); - val param = actual getOrElse arg - this(param) = new ConstructorParam(param) - }); - } - object decls extends mutable.LinkedHashMap[Symbol, Member] { - sym.tpe.decls.iterator.foreach(e => { - if (!constructorArgs.contains(e)) { - val m = Member(e) - if (!m.isEmpty && !this.contains(e)) this.put(e, m.get) - } - }); - } - def members0(f: Symbol => Boolean) = decls.filterKeys(f).valuesIterator.toList - def members(c: Category): Iterable[Member] = members0(c.f) - object inherited extends mutable.LinkedHashMap[Symbol, List[Member]]() { - override def default(tpe: Symbol) = Nil - for (m <- sym.tpe.members if !sym.tpe.decls.iterator.contains(m) && - (Values.f(m) || Methods.f(m))) { - val o = m.overridingSymbol(sym) - if (o == NoSymbol) { - val parent = decode(m.enclClass) - val mo = Member(m) - if (!mo.isEmpty) { - this(parent) = mo.get :: this(parent) - } - } - } - } - override def parents = freshParents - abstract class Member(sym: Symbol) extends Entity(sym) { - private def overriding = sym.allOverriddenSymbols - override def comment = super.comment match { - case ret @ Some(comment) => - ret - case None => - val o = overriding.find(comments.contains) - o.map(comments.apply) - } - } - abstract class ValDef(sym: Symbol) extends Member(sym) { - override def resultType = Some(resultType0) - protected def resultType0: Type - override def overridden: Iterable[Symbol] = { - var ret: mutable.LinkedHashSet[Symbol] = null - for (parent <- ClassOrObject.this.parents) { - val sym0 = sym.overriddenSymbol(parent.typeSymbol) - if (sym0 != NoSymbol) { - if (ret == null) ret = new mutable.LinkedHashSet[Symbol]; - ret += sym0 - } - } - if (ret == null) Nil else ret - } - } - case class Def(override val sym : TermSymbol) extends ValDef(sym) { - override def resultType0 = sym.tpe.finalResultType - override def typeParams = sym.tpe.typeParams.map(TypeParam) - override def valueParams = methodArgumentNames.get(sym) match { - case Some(argss) if argss.length > 1 || (!argss.isEmpty && !argss(0).isEmpty) => - argss map (_.map(ValueParam)) - case _ => - var i = 0 - val ret = for (tpe <- sym.tpe.paramTypes) yield { - val ret = sym.newValueParameter(sym.pos, newTermName("arg" + i)); - ret setInfo tpe - i += 1 - ValueParam(ret) - } - if (ret.isEmpty) Nil - else ret :: Nil - } - override def kind = "def" - } - case class Val(override val sym: TermSymbol) extends ValDef(sym) { - import symtab.Flags._ - def resultType0: Type = sym.tpe - override def kind: String = - if (sym hasFlag ACCESSOR) { - val setterName = nme.getterToSetter(sym.name) - val setter = sym.owner.info.decl(setterName) - val lazyMod = if (sym hasFlag LAZY) "lazy " else "" - lazyMod + (if (setter == NoSymbol) "val" else "var") - } else { - assert(sym hasFlag JAVA) - if (sym hasFlag FINAL) "val" else "var" - } - } - - case class AbstractType(override val sym: Symbol) extends Member(sym) { - override def kind = "type" - } - - abstract class NestedClassOrObject(override val sym: Symbol) extends Member(sym) with ClassOrObject { - override def path: List[ClassOrObject] = ClassOrObject.this.path ::: super.path - } - - case class NestedClass(override val sym: ClassSymbol) extends NestedClassOrObject(sym) with Clazz - - case class NestedObject(override val sym: ModuleSymbol) extends NestedClassOrObject(sym) with Object { - override def attributes = sym.moduleClass.annotations - } - - def isVisible(sym: Symbol): Boolean = { - import symtab.Flags._ - if (sym.isLocalClass) return false - if (sym.isLocal) return false - if (sym.isPrivateLocal) return false - // the next line used to return !inIDE - now it returns true. The underlying - // logic being applied here is somewhat mysterious (if PRIVATE return isVisible == true?) - // but changing it causes the docgenerator.scala test case to break, so I leave as-is. - if (sym hasFlag PRIVATE) return true - if (sym hasFlag SYNTHETIC) return false - if (sym hasFlag BRIDGE) return false - if ((sym.nameString indexOf "$") != -1) return false - if ((sym hasFlag CASE) && sym.isMethod) return false - true - } - - def Member(sym: Symbol): Option[Member] = { - import global._ - import symtab.Flags - if (!isVisible(sym)) - None - else if (!isAccessible(sym)) - None - else if (sym hasFlag Flags.ACCESSOR) { - if (sym.isSetter) return None; - assert(sym.isGetter); - Some[Member](new Val(sym.asInstanceOf[TermSymbol])) - } - else if (sym.isValue && !sym.isMethod && !sym.isModule) { - if (!sym.hasFlag(Flags.JAVA)) { - Console.println("SYM: " + sym + " " + sym.fullNameString('.')) - Console.println("FLA: " + Flags.flagsToString(sym.flags)) - } - assert(sym hasFlag Flags.JAVA) - Some[Member](new Val(sym.asInstanceOf[TermSymbol])) - } - else if (sym.isValue && !sym.isModule) { - val str = Flags.flagsToString(sym.flags) - assert(sym.isMethod) - Some[Member](new Def(sym.asInstanceOf[TermSymbol])) - } - else if (sym.isAliasType || sym.isAbstractType) - Some(new AbstractType(sym)) - else if (sym.isClass) - Some(new NestedClass(sym.asInstanceOf[ClassSymbol])) - else if (sym.isModule) - Some(new NestedObject(sym.asInstanceOf[ModuleSymbol])) - else - None - } - - } - case class Category(label: String)(g: Symbol => Boolean) { - val f = g - def plural = label + "s" - } - val Constructors = new Category("Additional Constructor")(e => e.isConstructor && !e.isPrimaryConstructor) { - // override def plural = "Additional Constructors"; - } - val Objects = Category("Object")(_.isModule); - val Classes = new Category("Class")(sym => sym.isClass || (sym == definitions.AnyRefClass)) { - override def plural = "Classes" - } - val Values = new Category("Value")(e => e.isValue && e.hasFlag(symtab.Flags.ACCESSOR)) { - override def plural = "Values and Variables" - } - val Methods = Category("Method")(e => e.isValue && e.isMethod && !e.isConstructor && !e.hasFlag(symtab.Flags.ACCESSOR)); - val Types = Category("Type")(e => e.isAliasType || e.isAbstractType); - - val categories = Constructors :: Types :: Values :: Methods :: Classes :: Objects :: Nil; - - - import java.util.regex.Pattern - // patterns for standard tags with 1 and 2 arguments - private val pat1 = Pattern.compile( - "[ \t]*@(author|deprecated|owner|pre|return|see|since|todo|version|ex|note)[ \t]*(.*)") - private val pat2 = Pattern.compile( - "[ \t]*@(exception|param|throws)[ \t]+(\\p{Graph}*)[ \t]*(.*)") - - def sort[E <: Entity](entities: Iterable[E]): Iterable[E] = { - val set = new collection.immutable.TreeSet[E]()(new Ordering[E] { - def compare(eA : E, eB: E): Int = { - if (eA eq eB) return 0; - (eA, eB) match { - case (eA: ClassOrObject, eB: ClassOrObject) => - val diff = ModelExtractor.this.compare(eA.path, eB.path) - if (diff!= 0) return diff - case _ => - } - if (eA.getClass != eB.getClass) { - val diff = eA.getClass.getName.compare(eB.getClass.getName) - assert(diff != 0) - return diff - } - if (!eA.sym0.isPackage) { - val diff = eA.sym0.nameString compare eB.sym0.nameString - if (diff != 0) return diff - } - val diff0 = eA.sym0.fullNameString compare eB.sym0.fullNameString - assert(diff0 != 0) - diff0 - } - }) - set ++ entities - } -} diff --git a/src/compiler/scala/tools/nsc/doc/ModelFrames.scala b/src/compiler/scala/tools/nsc/doc/ModelFrames.scala deleted file mode 100644 index 6a412b3a1..000000000 --- a/src/compiler/scala/tools/nsc/doc/ModelFrames.scala +++ /dev/null @@ -1,396 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2009 LAMP/EPFL - * @author Sean McDirmid - */ -// $Id$ - -package scala.tools.nsc -package doc - -import java.io.{File, FileWriter} -import scala.util.NameTransformer -import scala.collection.mutable -import scala.compat.Platform.{EOL => LINE_SEPARATOR} -import scala.xml.{NodeSeq, Text, Unparsed, Utility} - -/** This class provides HTML document framing functionality. - * - * @author Sean McDirmid, Stephane Micheloud - */ -trait ModelFrames extends ModelExtractor { - import DocUtil._ - def settings: doc.Settings - import global.definitions.{AnyClass, AnyRefClass} - - val SyntheticClasses = new scala.collection.mutable.HashSet[global.Symbol]; - { - import global.definitions._ - global.definitions.init - SyntheticClasses ++= List( - NothingClass, NullClass, AnyClass, AnyRefClass, AnyValClass, - //value classes - BooleanClass, ByteClass, CharClass, IntClass, LongClass, ShortClass, - FloatClass, DoubleClass, UnitClass) - } - - val outdir = settings.outdir.value - val windowTitle = settings.windowtitle.value - val docTitle = load(settings.doctitle.value) - - val stylesheetSetting = settings.stylesheetfile - - def pageHeader = load(settings.pageheader.value) - def pageFooter = load(settings.pagefooter.value) - def pageTop = load(settings.pagetop.value) - def pageBottom = load(settings.pagebottom.value) - - def contentFrame = "contentFrame" - def classesFrame = "classesFrame" - def modulesFrame = "modulesFrame" - - protected val FILE_EXTENSION_HTML = ".html" - protected val NAME_SUFFIX_OBJECT = "$object" - protected val NAME_SUFFIX_PACKAGE = "$package" - - def rootTitle = ({load("This document is the API specification for " + windowTitle)}
); - - final def hasLink(sym: global.Symbol): Boolean = - if (sym == global.NoSymbol) false - else if (hasLink0(sym)) true - else hasLink(decode(sym.owner)) - - def hasLink0(sym: global.Symbol): Boolean = true - - abstract class Frame extends UrlContext { - { // just save. - save(page(title, body, hasBody)); - } - def path: String // relative to outdir - def relative: String = { - if (path eq null) return "foo" - assert(path ne null) - var idx = 0 - var ct = new StringBuilder - while (idx != -1) { - idx = path.indexOf('/', idx) - //System.err.println(path + " idx=" + idx) - ct.append(if (idx != -1) "../" else "") - idx += (if (idx == -1) 0 else 1) - } - ct.toString - } - def save(nodes: NodeSeq) = { - val path = this.path - if (path.startsWith("http://")) throw new Error("frame: " + this) - val path0 = outdir + File.separator + path + FILE_EXTENSION_HTML - //if (settings.debug.value) inform("Writing XML nodes to " + path0) - val file = new File(path0) - val parent = file.getParentFile() - if (!parent.exists()) parent.mkdirs() - val writer = new FileWriter(file) - val str = dtype + LINE_SEPARATOR + nodes.toString() - writer.write(str, 0, str.length()) - writer.close() - } - protected def body: NodeSeq - protected def title: String - protected def hasBody = true - - //def urlFor(entity: Entity, target: String): NodeSeq - def urlFor(entity: Entity): String = { - val ret = this.urlFor(entity.sym) - assert(ret != null); - ret - } - def link(entity: Entity, target: String) = aref(urlFor(entity), target, entity.name) - protected def shortHeader(entity: Entity): NodeSeq - protected def longHeader(entity: Entity): NodeSeq - import global._ - import symtab.Flags - - def urlFor(sym: Symbol): String = sym match { - case psym : ModuleSymbol if psym.isPackage => - urlFor0(sym, sym) + FILE_EXTENSION_HTML - case sym if !hasLink(sym) => - null - case sym if sym == AnyRefClass => - urlFor0(sym, sym) + FILE_EXTENSION_HTML - case msym: ModuleSymbol => - urlFor0(sym, sym) + FILE_EXTENSION_HTML - case csym: ClassSymbol => - urlFor0(sym, sym) + FILE_EXTENSION_HTML - case _ => - val cnt = urlFor(decode(sym.owner)) - if (cnt == null) null else cnt + "#" + docName(sym) - } - - def docName(sym: Symbol): String = { - def javaParams(paramTypes: List[Type]): String = { - def javaName(pt: Type): String = { - val s = pt.toString - val matVal = patVal.matcher(s) - if (matVal.matches) matVal.group(1).toLowerCase - else s.replaceAll("\\$", ".") - } - paramTypes.map(pt => javaName(pt)).mkString("(", ",", ")") - } - def scalaParams(paramTypes: List[Type]): String = { - def scalaName(pt: Type): String = pt.toString.replaceAll(" ", "") - paramTypes.map(pt => scalaName(pt)).mkString("(", ",", ")") - } - java.net.URLEncoder.encode(sym.nameString + - (sym.tpe match { - case MethodType(params, _) => - val paramTypes = params map (_.tpe) - if (sym hasFlag Flags.JAVA) javaParams(paramTypes) - else scalaParams(paramTypes) - case PolyType(_, MethodType(params, _)) => - val paramTypes = params map (_.tpe) - if (sym hasFlag Flags.JAVA) javaParams(paramTypes) - else scalaParams(paramTypes) - case _ => "" - }), encoding) - } - - def urlFor0(sym: Symbol, orig: Symbol): String = - (if (sym == NoSymbol) "XXX" - else if (sym.owner.isPackageClass) rootFor(sym) + pkgPath(sym) - else urlFor0(decode(sym.owner), orig) + "." + NameTransformer.encode(Utility.escape(sym.nameString)) - ) + - (sym match { - case msym: ModuleSymbol => - if (msym hasFlag Flags.PACKAGE) NAME_SUFFIX_PACKAGE - else NAME_SUFFIX_OBJECT - case csym: ClassSymbol if csym.isModuleClass => - if (csym hasFlag Flags.PACKAGE) NAME_SUFFIX_PACKAGE - else NAME_SUFFIX_OBJECT - case _ => - "" - }) - } - def pkgPath(sym : global.Symbol) = sym.fullNameString('/') match { - case "Package Summary | |
- package
- {aref(pkgPath(pkg.sym) + "$content.html", "_self", pkg.fullName('.'))}
-
- |
- {aref(navPath, contentFrame, navLabel)} - |
{kind.label} Summary |
- - | -
- {windowTitle}
- |
-
{name + ".scala"}
) ++
- Text("]")
- }
- }
- with
, Text(""))(link);
- case _ =>
- if (tpe.typeSymbol == NoSymbol) {
- throw new Error(tpe + " has no type class " + tpe.getClass)
- }
- link(decode(tpe.typeSymbol))
- }
- }
-
- private def printIf[T](what: Option[T], before: String, after: String)(f: T => NodeSeq): NodeSeq =
- if (what.isEmpty) Text("")
- else Text(before) ++ f(what.get) ++ Text(after)
-
- def bodyFor(entity: Entity)(implicit frame: Frame): NodeSeq = try {
- var seq = {entity.typeParams.surround("[", "]")(e => {
- Text(e.variance) ++ {e.name} ++
- {printIf(e.hi, " <: ", "")(link)} ++
- {printIf(e.lo, " >: ", "")(link)}
- })} ++ printIf(entity.hi, " <: ", "")(link) ++
- printIf(entity.lo, " >: ", "")(link);
- {entity.valueParams.foreach(xs => {
- seq = seq ++ xs.mkXML("(", ", ", ")")(arg =>
- {
- val str = arg.flagsString.trim
- if (str.length == 0) NodeSeq.Empty
- else {Text(str)}
- } ++
- {arg.name} ++ (try {
-
- Text(" : ") ++ link(arg.resultType.get)
- } catch {
- case e : Throwable => System.err.println("ARG " + arg + " in " + entity); throw e
- })
- );
- seq
- })};
- seq ++ {printIf(entity.resultType, " : ", "")(tpe => link(tpe))}
- } catch {
- case e => System.err.println("generating for " + entity); throw e
- }
-
- def extendsFor(entity: Entity)(implicit frame: Frame): NodeSeq = {
- if (entity.parents.isEmpty) NodeSeq.Empty
- else extends
++
- entity.parents.mkXML(Text(""), with
, Text(""))(link);
- }
-
- def parse(str: String): NodeSeq = {
- new SpecialNode {
- def label = "#PCDATA"
- def buildString(sb: StringBuilder): StringBuilder = {
- sb.append(str.trim)
- sb
- }
- }
- }
-
- def longHeader(entity: Entity)(implicit frame: Frame): NodeSeq = Group({
- anchor(entity.sym) ++ {Text(entity.flagsString)}
- {Text(entity.kind)}
- {entity.sym.nameString}{bodyFor(entity)}
- {Text(category.label)} Details |
{Text(category.label + " Summary")} |
- {Text(category.plural + " inherited from ") ++ link(tpe)} - | |
- {members0.mkXML((""), (", "), (""))(m => { - link(decode(m.sym)) ++ - (if (m.sym.hasFlag(symtab.Flags.ABSTRACT) || m.sym.hasFlag(symtab.Flags.DEFERRED)) { - Text(" (abstract)"); - } else NodeSeq.Empty); - })} - |
{Text(string + " - ")}
;
-
- protected def decodeTag(tag: String): String = tag.capitalize
-
- def shortHeader(entity: Entity)(implicit from: Frame): NodeSeq =
- {Text(entity.flagsString)} {Text(entity.kind)}
- " - val first = - if (lines.length < 2) - lines(0) - else { - val line0 = lines(0) - val mat = pat matcher line0 - if (mat.matches()) line0 + lines(1) - else line0 - } -
+ * Class Nothing
is - together with class
+ * Null
- at the bottom of the
+ * Scala type
+ * hierarchy.
+ *
+ * Type Nothing
is a subtype of every other type
+ * (including Null
); there
+ * exist no instances of this type. Even though type
+ * Nothing
is empty, it is nevertheless useful as a
+ * type parameter. For instance, the Scala library defines a value
+ * Nil
of type
+ * List[Nothing]
. Because lists
+ * are covariant in Scala,
+ * this makes Nil
an
+ * instance of List[T]
, for
+ * any element type T
.
+ *
+ * Class Null
is - together with class
+ * Nothing
- at the bottom of the
+ * Scala type
+ * hierarchy.
+ *
+ * Type Null
is a subtype of all reference types; its
+ * only instance is the null
reference.
+ * Since Null
is not a subtype of value types,
+ * null
is not a member of any such type. For instance,
+ * it is not possible to assign null
to a variable of
+ * type Int
.
+ *
+ * Class Any
is the root of the Scala class hierarchy. Every class in a
+ * Scala execution
+ * environment inherits directly or indirectly from this class.
+ * Class Any
has two direct subclasses:
+ * AnyRef
and
+ * AnyVal
.
+ *
this
)
+ * with the argument object (arg0
) for equivalence.
+ *
+ * + * The default implementations of this method is an equivalence + * relation: + *
x
of type Any
,
+ * x.equals(x)
should return true
.x
and y
of type
+ * Any
, x.equals(y)
should return true
if and only
+ * if y.equals(x)
returns true
.x
, y
, and z
of type AnyRef
+ * if x.equals(y)
returns true
and
+ * y.equals(z)
returns
+ * true
, then x.equals(z)
should return true
.
+ * If you override this method, you should verify that
+ * your implementation remains an equivalence relation.
+ * Additionally, when overriding this method it is often necessary to
+ * override hashCode
to ensure that objects that are
+ * "equal" (o1.equals(o2)
returns true
)
+ * hash to the same Int
+ * (o1.hashCode.equals(o2.hashCode)
).
+ *
+ * @param arg0 the object to compare against this object for equality.
+ * @return true
if the receiver object is equivalent to the argument; false
otherwise.
+ *
+ * @param arg0 the object to compare against this object for equality. + * @return `true` if the receiver object is equivalent to the argument; `false` otherwise. + *
*/ + """ + + comment(Any_!=) = """ + /** `o != arg0` is the same as `!(o == (arg0))`. + *+ * @param arg0 the object to compare against this object for dis-equality. + * @return `false` if the receiver object is equivalent to the argument; `true` otherwise. + *
*/ + """ + + comment(Any_toString) = """ + /** Returns a string representation of the object. + *+ * The default representation is platform dependent. + * + * @return a string representation of the object. + *
*/ + """ + + comment(Any_asInstanceOf) = """ + /**This method is used to cast the receiver object to be of typeT0
.
+ *
+ * Note that the success of a cast at runtime is modulo Scala's
+ * erasure semantics. Therefore the expression
+ * 1.asInstanceOf[String]
will throw a
+ * ClassCastException
at runtime, while the expression
+ * List(1).asInstanceOf[List[String]]
will not. In the
+ * latter example, because the type argument is erased as part of
+ * compilation it is not possible to check whether the contents of
+ * the list are of the requested typed.
+ *
+ * @throws ClassCastException if the receiver object is not an
+ * instance of erasure of type T0
.
+ * @return the receiver object.
+ *
T0
.
+ *
+ * Note that the test result of the test is modulo Scala's erasure
+ * semantics. Therefore the expression
+ * 1.isInstanceOf[String]
will return
+ * false
, while the expression
+ * List(1).isInstanceOf[List[String]]
will return
+ * true
. In the latter example, because the type
+ * argument is erased as part of compilation it is not possible to
+ * check whether the contents of the list are of the requested typed.
+ *
+ * @return true
if the receiver object is an
+ * instance of erasure of type T0
; false
otherwise. */
+ """
+
+ comment(Any_hashCode) = """
+ /** Returns a hash code value for the object.
+ *
+ *
+ * The default hashing algorithm is platform dependent.
+ *
+ * Note that it is allowed for two objects to have identical hash
+ * codes (o1.hashCode.equals(o2.hashCode)
) yet not be
+ * equal (o1.equals(o2)
returns false
). A
+ * degenerate implementation could always return 0
.
+ * However, it is required that if two objects are equal
+ * (o1.equals(o2)
returns true
) that they
+ * have identical hash codes
+ * (o1.hashCode.equals(o2.hashCode)
). Therefore, when
+ * overriding this method, be sure to verify that the behavior is
+ * consistent with the equals
method.
+ *
+ * @return the hash code value for the object. + *
*/ + """ + + /*******************************************************************/ + /* Documentation for AnyRef */ + + comment(AnyRefClass) = """ + /**
+ * Class AnyRef
is the root class of all
+ * reference types.
+ *
o == arg0
is the same as if (o eq null) arg0 eq null else o.equals(arg0)
.
+ *
+ * @param arg0 the object to compare against this object for equality.
+ * @return true
if the receiver object is equivalent to the argument; false
otherwise.
+ *
o.ne(arg0)
is the same as !(o.eq(arg0))
.
+ *
+ * @param arg0 the object to compare against this object for reference dis-equality.
+ * @return false
if the argument is not a reference to the receiver object; true
otherwise.
+ *
+ * The details of when and if the finalize
method are
+ * invoked, as well as the interaction between finalize
+ * and non-local returns and exceptions, are all platform dependent.
+ *
+ * The default implementation of the clone
method is platform dependent.
+ *
+ * @return a copy of the receiver object.
+ *
+ * The nature of the representation is platform dependent. + * + * @return a representation that corresponds to the dynamic class of the receiver object. + *
*/ + """ + + comment(Object_notify) = """ + /** Wakes up a single thread that is waiting on the receiver object's monitor. */ + """ + + comment(Object_notifyAll) = """ + /** Wakes up all threads that are waiting on the receiver object's monitor. */ + """ + + comment(Object_eq) = """ + /** This method is used to test whether the argument (arg0
) is a reference to the
+ * receiver object (this
).
+ *
+ *
+ * The eq
method implements an
+ * equivalence relation on non-null instances of
+ * AnyRef
:
+ *
x
of type AnyRef
,
+ * x.eq(x)
returns true
.x
and y
of type
+ * AnyRef
, x.eq(y)
returns true
if and only
+ * if y.eq(x)
returns true
.x
, y
, and z
of type AnyRef
+ * if x.eq(y)
returns true
and
+ * y.eq(z)
returns
+ * true
, then x.eq(z)
returns true
.eq
method has three other properties.
+ * x
and y
of type AnyRef
,
+ * multiple invocations of x.eq(y)
consistently returns true
+ * or consistently returns false
.x
of type AnyRef
,
+ * x.eq(null)
and null.eq(x)
returns false
.null.eq(null)
returns true
. When overriding the equals
or
+ * hashCode
methods, it is important to ensure that
+ * their behavior is consistent with reference equality. Therefore,
+ * if two objects are references to each other (o1 eq
+ * o2
), they should be equal to each other (o1 ==
+ * o2
) and they should hash to the same value
+ * (o1.hashCode == o2.hashCode
).
true
if the argument is a reference to the receiver object; false
otherwise.
+ * */
+ """
+
+ /*******************************************************************/
+
+ comment(AnyValClass) = """
+ /**
+ * Class AnyVal
is the root class of all
+ * value types.
+ *
+ * AnyVal
has a fixed number subclasses, which
+ * describe values which are not implemented as objects in the
+ * underlying host system.
+ *
+ * Classes Double
,
+ * Float
,
+ * Long
,
+ * Int
,
+ * Char
,
+ * Short
, and
+ * Byte
are together called
+ * numeric value types.
+ * Classes Byte
,
+ * Short
, or
+ * Char
+ * are called subrange types. Subrange types, as well as
+ * Int
and
+ * Long
are called
+ * integer types, whereas
+ * Float
and
+ * Double
are called
+ * floating point types.
+ *
+ * Class Boolean
has only two values: true
+ * and false
.
+ *
+ * Class Unit
has only one value: ()
.
+ *
+ * Class """ + sym.name + """
belongs to the value
+ * classes whose instances are not represented as objects by the
+ * underlying host system. There is an implicit conversion from
+ * instances of """ + sym.name + """
to instances of
+ * runtime.Rich""" + sym.name + """
which
+ * provides useful non-primitive operations. All value classes inherit
+ * from class AnyVal
.
+ *
+ * Values """ + maxValue + """
and """ + minValue + """
+ * are in defined in object scala.Math.
+ *
{ inlineToHtml(in) }
+ case Code(data) =>{ Unparsed(data) }
{ Unparsed(text) }
+ case Text(text) => Unparsed(text)
+ }
+
+ def typeToHtml(tpe: model.TypeEntity): NodeSeq = {
+
+ // TODO: Generate links using tpe's refEntity map
+
+ xml.Text(tpe.name)
+
+ }
+
+}
diff --git a/src/compiler/scala/tools/nsc/doc/html/SiteFactory.scala b/src/compiler/scala/tools/nsc/doc/html/SiteFactory.scala
new file mode 100644
index 000000000..afbcd6613
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/doc/html/SiteFactory.scala
@@ -0,0 +1,79 @@
+/* NSC -- new Scala compiler
+ * Copyright 2007-2009 LAMP/EPFL
+ * @author David Bernard, Manohar Jonnalagedda
+ */
+
+package scala.tools.nsc
+package doc
+package html
+
+import reporters.Reporter
+import model._
+
+import java.io.{FileOutputStream, File}
+import scala.collection._
+
+/** A class that can generate Scaladoc sites to some fixed root folder.
+ * @author David Bernard
+ * @author Gilles Dubochet */
+class SiteFactory(val reporter: Reporter, val settings: Settings) {
+
+ /** The character encoding to be used for generated Scaladoc sites. This value is currently always UTF-8. */
+ def encoding: String = "UTF-8"
+
+ /** The character encoding to be used for generated Scaladoc sites. This value is defined by the generator's
+ * settings. */
+ def siteRoot: File = new File(settings.outdir.value)
+
+ /** Generates the Scaladoc site for a model into the site toot. A scaladoc site is a set of HTML and related files
+ * that document a model extracted from a compiler run.
+ * @param model The model to generate in the form of a sequence of packages. */
+ def generate(modelRoot: Package): Unit = {
+
+ def copyResource(subPath: String) {
+ val buf = new Array[Byte](1024)
+ val in = getClass.getResourceAsStream("/scala/tools/nsc/doc/html/resource/" + subPath)
+ assert(in != null)
+ val dest = new File(siteRoot, subPath)
+ dest.getParentFile.mkdirs()
+ val out = new FileOutputStream(dest)
+ try {
+ var len = 0
+ while ({len = in.read(buf); len != -1})
+ out.write(buf, 0, len)
+ }
+ finally {
+ in.close()
+ out.close()
+ }
+ }
+
+ copyResource("lib/jquery.js")
+ copyResource("lib/index.css")
+ copyResource("lib/index.js")
+ copyResource("lib/template.css")
+ copyResource("lib/template.js")
+ copyResource("lib/class.png")
+ copyResource("lib/class_big.png")
+ copyResource("lib/object.png")
+ copyResource("lib/object_big.png")
+ copyResource("lib/trait.png")
+ copyResource("lib/trait_big.png")
+ copyResource("lib/package.png")
+ copyResource("lib/package_big.png")
+
+ new page.Index(modelRoot) writeFor this
+
+ val written = mutable.HashSet.empty[DocTemplateEntity]
+
+ def writeTemplate(tpl: DocTemplateEntity): Unit = {
+ new page.Template(tpl) writeFor this
+ written += tpl
+ tpl.templates filter { t => !(written contains t) } map (writeTemplate(_))
+ }
+
+ writeTemplate(modelRoot)
+
+ }
+
+}
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Index.scala b/src/compiler/scala/tools/nsc/doc/html/page/Index.scala
new file mode 100644
index 000000000..ec408f363
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Index.scala
@@ -0,0 +1,77 @@
+/* NSC -- new Scala compiler
+ * Copyright 2007-2009 LAMP/EPFL
+ * @author David Bernard, Manohar Jonnalagedda
+ */
+
+package scala.tools.nsc
+package doc
+package html
+package page
+
+import model._
+
+import scala.collection._
+import scala.xml._
+
+class Index(modelRoot: Package) extends HtmlPage {
+
+ def path = List("index.html")
+
+ def title = "Scaladoc: all classes and objects"
+
+ def headers =
+ + """) + + def footer(dest: URI) = Some("""+ + + + """) + + //TODO: escape the source code + def scalaToHtml(src :File) = { + val dest = new File(outDir, fileHelper.relativePathUnderDir(src, inDir) + ".html") + if (!dest.exists || dest.lastModified < src.lastModified) { + + //we need to verify whether the directory we are trying to write to has already been created or not + if(!dest.getParentFile.exists) dest.getParentFile.mkdirs + + val uri = linkHelper.uriFor(dest).get + var txt = fileHelper.readTextFromFile(src).getOrElse("") + txt = txt.replace("<", "<") + fileHelper.writeTextToFile(dest, txt, header(uri), footer(uri)) + } + Some(dest) + } + + def copyResources() { + val loader = this.getClass().getClassLoader() + val buf = new Array[Byte](1024) + def copyResource(name: String) = fileHelper.copyResource("/scala/tools/nsc/doc/html/resource/", name, outDir, loader, buf) + copyResource("_highlighter/clipboard.swf") + copyResource("_highlighter/shAll.js") + copyResource("_highlighter/SyntaxHighlighter.css") + } + + copyResources() + } + } else { + new SourceHtmlizer { + def scalaToHtml(src :File) = None + } + } + } + */ + +} diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala new file mode 100644 index 000000000..6c9670530 --- /dev/null +++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala @@ -0,0 +1,214 @@ +/* NSC -- new Scala compiler + * Copyright 2007-2009 LAMP/EPFL + * @author David Bernard, Manohar Jonnalagedda + */ + +package scala.tools.nsc +package doc +package html +package page + +import model._ + +import scala.xml.{NodeSeq, Text} +import scala.collection.mutable.HashSet + +class Template(tpl: DocTemplateEntity) extends HtmlPage { + + val path = + templateToPath(tpl) + + val title = "Scaladoc for " + tpl.qualifiedName + + val headers = +
{ tpl.inTemplate.qualifiedName }
+ } + +scala.collection.mutable
+This class can be used as an adaptor to create mutable maps from immutable map implementations. Only method empty has to be redefined if the immutable map on which this mutable map is originally based is not empty. empty is supposed to return the representation of an empty map.
+A subtrait of collection.IndexedSeq which represents sequences that can be mutated.
+The canonical builder for collections that are addable, i.e. that support an efficient + method which adds an element to the collection. Collections are built from their empty element using this + method.
+T an empty map.
+U can be used as an adaptor to create mutable maps.
+f can be used as an adaptor to create mutable maps from immutable map implementations. Only method empty has to be redefined.
+b the immutable map on which this mutable map is originally based is not empty. empty is supposed to return the representation of an empty map.
+A subtrait of collection.IndexedSeq which represents sequences that can be mutated.
+The canonical builder for collections that are addable, i.e. that support an efficient + method which adds an element to the collection. Collections are built from their empty element using this + method.
+A subtrait of collection.IndexedSeq which represents sequences that can be mutated.
+The canonical builder for collections that are addable, i.e. that support an efficient + method which adds an element to the collection. Collections are built from their empty element using this + method.
+A subtrait of collection.IndexedSeq which represents sequences that can be mutated.
+The canonical builder for collections that are addable, i.e. that support an efficient + method which adds an element to the collection. Collections are built from their empty element using this + method.
+A subtrait of collection.IndexedSeq which represents sequences that can be mutated.
+Some inner class
+Some type parameter
+A subtrait of collection.IndexedSeq which represents sequences that can be mutated.
+A subtrait of collection.IndexedSeq which represents sequences that can be mutated.
+A subtrait of collection.IndexedSeq which represents sequences that can be mutated.
+