added options '-windowtitle' and '-documenttitle' to command scaladoc

added attributes 'windowtitle' and 'documenttitle' to Ant task 'Scaladoc'
added option '-encoding iso-8859-1' in script test/scalatest
removed leading tabs in scala/xml/*.scala



git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@7124 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
michelou 2006-04-12 16:55:00 +00:00
parent 9304130292
commit 210b36f4aa
9 changed files with 240 additions and 193 deletions

View File

@ -925,6 +925,8 @@ DOCUMENTATION
srcdir="${src.dir}" srcdir="${src.dir}"
destdir="${api.lib.dir}" destdir="${api.lib.dir}"
sourcepath="" sourcepath=""
windowtitle="Scala Library Documentation"
documenttitle="<div>Scala 2<div>${version.number}</div></div>"
> >
<classpath> <classpath>
<pathelement location="${quick.dir}/${lib.dir.name}"/> <pathelement location="${quick.dir}/${lib.dir.name}"/>
@ -944,6 +946,8 @@ DOCUMENTATION
srcdir="${src.comp.dir}" srcdir="${src.comp.dir}"
destdir="${api.comp.dir}" destdir="${api.comp.dir}"
sourcepath="" sourcepath=""
windowtitle="Scala Compiler Documentation"
documenttitle="&lt;div&gt;Scala 2&lt;div&gt;${version.number}&lt;/div&gt;&lt;/div&gt;"
> >
<classpath> <classpath>
<pathelement location="${quick.lib.dir}"/> <pathelement location="${quick.lib.dir}"/>

View File

@ -2,10 +2,11 @@
** / |/ / ____/ ____/ ** ** / |/ / ____/ ____/ **
** / | | /___ / /___ ** ** / | | /___ / /___ **
** /_/|__/_____/_____/ Copyright 2005-2006 LAMP/EPFL ** ** /_/|__/_____/_____/ Copyright 2005-2006 LAMP/EPFL **
** ** **
** $Id$
\* */ \* */
// $Id$
package scala.tools.ant { package scala.tools.ant {
@ -38,7 +39,9 @@ package scala.tools.ant {
* <li>bootclasspathref,</li> * <li>bootclasspathref,</li>
* <li>extdirs,</li> * <li>extdirs,</li>
* <li>extdirsref,</li> * <li>extdirsref,</li>
* <li>encoding.</li> * <li>encoding,</li>
* <li>windowtitle,</li>
* <li>documenttitle.</li>
* </ul> * </ul>
* It also takes the following parameters as nested elements:<ul> * It also takes the following parameters as nested elements:<ul>
* <li>src (for srcdir),</li> * <li>src (for srcdir),</li>
@ -48,7 +51,8 @@ package scala.tools.ant {
* <li>extdirs.</li> * <li>extdirs.</li>
* </ul> * </ul>
* *
* @author Gilles Dubochet */ * @author Gilles Dubochet, Stephane Micheloud
*/
class Scaladoc extends MatchingTask { class Scaladoc extends MatchingTask {
/** The unique Ant file utilities instance to use in this task. */ /** The unique Ant file utilities instance to use in this task. */
@ -75,6 +79,11 @@ package scala.tools.ant {
/** The character encoding of the files to compile. */ /** The character encoding of the files to compile. */
private var encoding: Option[String] = None private var encoding: Option[String] = None
/** The window title of the generated HTML documentation. */
private var windowtitle: Option[String] = None
/** The document title of the generated HTML documentation. */
private var documenttitle: Option[String] = None
/******************************************************************************\ /******************************************************************************\
** Properties setters ** ** Properties setters **
\******************************************************************************/ \******************************************************************************/
@ -176,11 +185,21 @@ package scala.tools.ant {
def setExtdirsref(input: Reference) = def setExtdirsref(input: Reference) =
createExtdirs().setRefid(input) createExtdirs().setRefid(input)
/** Sets the encoding attribute. Used by Ant. /** Sets the <code>encoding</code> attribute. Used by Ant.
* @param input The value of <code>encoding</code>. */ * @param input The value of <code>encoding</code>. */
def setEncoding(input: String): Unit = def setEncoding(input: String): Unit =
encoding = Some(input) encoding = Some(input)
/** Sets the <code>windowtitle</code> attribute.
* @param input The value of <code>windowtitle</code>. */
def setWindowtitle(input: String): Unit =
windowtitle = Some(input)
/** Sets the <code>documenttitle</code> attribute.
* @param input The value of <code>documenttitle</code>. */
def setDocumenttitle(input: String): Unit =
documenttitle = Some(input)
/******************************************************************************\ /******************************************************************************\
** Properties getters ** ** Properties getters **
\******************************************************************************/ \******************************************************************************/
@ -189,8 +208,7 @@ package scala.tools.ant {
* @returns The class path as a list of files. */ * @returns The class path as a list of files. */
private def getClasspath: List[File] = private def getClasspath: List[File] =
if (classpath.isEmpty) error("Member 'classpath' is empty.") if (classpath.isEmpty) error("Member 'classpath' is empty.")
else else List.fromArray(classpath.get.list()).map(nameToFile)
List.fromArray(classpath.get.list()).map(nameToFile)
/** Gets the value of the origin attribute in a Scala-friendly form. /** Gets the value of the origin attribute in a Scala-friendly form.
* @returns The origin path as a list of files. */ * @returns The origin path as a list of files. */
@ -312,7 +330,6 @@ package scala.tools.ant {
/** Performs the compilation. */ /** Performs the compilation. */
override def execute() = { override def execute() = {
// Tests if all mandatory attributes are set and valid. // Tests if all mandatory attributes are set and valid.
if (origin.isEmpty) error("Attribute 'srcdir' is not set.") if (origin.isEmpty) error("Attribute 'srcdir' is not set.")
if (getOrigin.isEmpty) error("Attribute 'srcdir' is not set.") if (getOrigin.isEmpty) error("Attribute 'srcdir' is not set.")
@ -366,15 +383,19 @@ package scala.tools.ant {
settings.bootclasspath.value = asString(getBootclasspath) settings.bootclasspath.value = asString(getBootclasspath)
if (!extdirs.isEmpty) settings.extdirs.value = asString(getExtdirs) if (!extdirs.isEmpty) settings.extdirs.value = asString(getExtdirs)
if (!encoding.isEmpty) settings.encoding.value = encoding.get if (!encoding.isEmpty) settings.encoding.value = encoding.get
if (!windowtitle.isEmpty) settings.windowtitle.value = windowtitle.get
if (!documenttitle.isEmpty) settings.documenttitle.value = documenttitle.get
// Compiles the actual code // Compiles the actual code
object compiler extends Global(settings, reporter) object compiler extends Global(settings, reporter)
try { try {
val run = new compiler.Run val run = new compiler.Run
run.compile(sourceFiles.map(f:File=>f.toString())) run.compile(sourceFiles.map(f: File => f.toString()))
object generator extends DocGenerator { object generator extends DocGenerator {
val global = compiler val global = compiler
val outdir = settings.outdir.value val outdir = settings.outdir.value
val windowTitle = settings.windowtitle.value
val documentTitle = settings.documenttitle.value
} }
generator.process(run.units) generator.process(run.units)
if (reporter.errors > 0) if (reporter.errors > 0)

View File

@ -16,9 +16,9 @@ import scala.tools.nsc.doc.DocGenerator
object Main extends Object with EvalLoop { object Main extends Object with EvalLoop {
val PRODUCT: String = val PRODUCT: String =
System.getProperty("scala.product", "scalac") System.getProperty("scala.tool.name", "scalac")
val VERSION: String = val VERSION: String =
System.getProperty("scala.version", "unknown version") System.getProperty("scala.tool.version", "unknown version")
val COPYRIGHT: String = val COPYRIGHT: String =
System.getProperty("scala.copyright", "(c) 2002-2006 LAMP/EPFL") System.getProperty("scala.copyright", "(c) 2002-2006 LAMP/EPFL")
val versionMsg = PRODUCT + " " + VERSION + " -- " + COPYRIGHT val versionMsg = PRODUCT + " " + VERSION + " -- " + COPYRIGHT
@ -60,8 +60,10 @@ object Main extends Object with EvalLoop {
run compile command.files run compile command.files
if (command.settings.doc.value) { if (command.settings.doc.value) {
object generator extends DocGenerator { object generator extends DocGenerator {
val global : compiler.type = compiler; val global : compiler.type = compiler
val outdir = command.settings.outdir.value; val outdir = command.settings.outdir.value
val windowTitle = command.settings.windowtitle.value
val documentTitle = command.settings.documenttitle.value
}; };
generator.process(run.units) generator.process(run.units)
} }

View File

@ -24,7 +24,6 @@ class Settings(error: String => unit) {
".") ".")
else getProperty("java.class.path") else getProperty("java.class.path")
private val bootclasspathDefault = private val bootclasspathDefault =
alternatePath( alternatePath(
concatPath( concatPath(
@ -61,6 +60,9 @@ class Settings(error: String => unit) {
new java.io.OutputStreamWriter( new java.io.OutputStreamWriter(
new java.io.ByteArrayOutputStream()).getEncoding new java.io.ByteArrayOutputStream()).getEncoding
private val windowtitleDefault = "Scala Library Documentation"
private val documenttitleDefault = "Scala 2"
val doc = BooleanSetting("-doc", "Generate documentation"); val doc = BooleanSetting("-doc", "Generate documentation");
val debuginfo = BooleanSetting("-g", "Generate debugging info") val debuginfo = BooleanSetting("-g", "Generate debugging info")
val nowarnings = BooleanSetting("-nowarn", "Generate no warnings") val nowarnings = BooleanSetting("-nowarn", "Generate no warnings")
@ -74,6 +76,8 @@ class Settings(error: String => unit) {
val extdirs = StringSetting ("-extdirs", "dirs", "Override location of installed extensions", extdirsDefault) val extdirs = StringSetting ("-extdirs", "dirs", "Override location of installed extensions", extdirsDefault)
val outdir = StringSetting ("-d", "directory", "Specify where to place generated class files", ".") val outdir = StringSetting ("-d", "directory", "Specify where to place generated class files", ".")
val encoding = StringSetting ("-encoding", "encoding", "Specify character encoding used by source files", encodingDefault) val encoding = StringSetting ("-encoding", "encoding", "Specify character encoding used by source files", encodingDefault)
val windowtitle = StringSetting ("-windowtitle", "windowtitle", "Specify window title of generated HTML documentation", windowtitleDefault)
val documenttitle = StringSetting ("-documenttitle", "documenttitle", "Specify document title of generated HTML documentation", documenttitleDefault)
val target = ChoiceSetting ("-target", "Specify which backend to use", List("jvm", "msil"), "jvm") val target = ChoiceSetting ("-target", "Specify which backend to use", List("jvm", "msil"), "jvm")
val migrate = BooleanSetting("-migrate", "Assist in migrating from Scala version 1.0") val migrate = BooleanSetting("-migrate", "Assist in migrating from Scala version 1.0")
val debug = BooleanSetting("-debug", "Output debugging messages") val debug = BooleanSetting("-debug", "Output debugging messages")

View File

@ -17,24 +17,26 @@ abstract class DocGenerator extends Models {
import global._ import global._
import DocUtil._ import DocUtil._
def outdir: String def outdir: String
def windowTitle: String
def documentTitle: String
def contentFrame = "contentFrame" def contentFrame = "contentFrame"
def classesFrame = "classesFrame" def classesFrame = "classesFrame"
def modulesFrame = "modulesFrame" def modulesFrame = "modulesFrame"
def emptyMap = ListMap.Empty[Kind,TreeSet[HasTree]]; def emptyMap = ListMap.Empty[Kind,TreeSet[HasTree]]
override def acceptPrivate = false; override def acceptPrivate = false;
abstract class Frame extends UrlContext { abstract class Frame extends UrlContext {
def path: String; // relative to outdir def path: String; // relative to outdir
def relative: String = { def relative: String = {
assert(path != null); assert(path != null)
var idx = 0; var idx = 0
var ct = ""; var ct = ""
while (idx != -1) { while (idx != -1) {
idx = path.indexOf('/', idx); idx = path.indexOf('/', idx);
//System.err.println(path + " idx=" + idx); //System.err.println(path + " idx=" + idx);
ct = ct + (if (idx != -1) "../" else ""); ct = ct + (if (idx != -1) "../" else "");
idx = idx + (if (idx == -1) 0 else 1); idx = idx + (if (idx == -1) 0 else 1)
} }
ct ct
} }
@ -54,7 +56,7 @@ abstract class DocGenerator extends Models {
writer.close() writer.close()
} }
def urlFor(sym : Symbol, target : String) : NodeSeq = try { def urlFor(sym: Symbol, target: String): NodeSeq = try {
if (sym.sourceFile == null) Text(sym.fullNameString('.')); if (sym.sourceFile == null) Text(sym.fullNameString('.'));
else aref(urlFor(sym), target, sym.nameString); else aref(urlFor(sym), target, sym.nameString);
} catch { } catch {
@ -72,7 +74,7 @@ abstract class DocGenerator extends Models {
Text(tpe.symbol.toString()) Text(tpe.symbol.toString())
} }
def urlFor0(sym : Symbol, orig : Symbol) : String = { def urlFor0(sym: Symbol, orig: Symbol): String = {
(if (sym == NoSymbol) { (if (sym == NoSymbol) {
"XXX"; "XXX";
} else if (sym.owner.isPackageClass) sym.fullNameString('/'); } else if (sym.owner.isPackageClass) sym.fullNameString('/');
@ -104,12 +106,17 @@ abstract class DocGenerator extends Models {
save(page(title, body, hasBody)) save(page(title, body, hasBody))
} }
val doctitle: NodeSeq =
<div class="doctitle-larger">
{load(documentTitle)}
</div>;
abstract class ListModuleFrame extends Frame { abstract class ListModuleFrame extends Frame {
val path = "modules"; val path = "modules";
val title = "List of all packages"; val title = "List of all packages";
def modules : TreeMap[String,ModuleClassSymbol]; def modules : TreeMap[String,ModuleClassSymbol];
def body : NodeSeq = { def body : NodeSeq = {
val x = div0("Scala 2") concat val x = doctitle concat
aref("all-classes.html", classesFrame, "All objects and classes"); aref("all-classes.html", classesFrame, "All objects and classes");
val y = <p/><b>Packages</b> val y = <p/><b>Packages</b>
<table class="list"><tr><td style="white-space:nowrap;"> <table class="list"><tr><td style="white-space:nowrap;">
@ -150,15 +157,15 @@ abstract class DocGenerator extends Models {
} }
abstract class ListClassFrame extends Frame { abstract class ListClassFrame extends Frame {
def classes: ListMap[Kind,TreeSet[HasTree]]; def classes: ListMap[Kind,TreeSet[HasTree]]
def navLabel: String; def navLabel: String
private def path0 = { private def path0 = {
val p = path; val p = path
if (p.endsWith("$package")) if (p.endsWith("$package"))
p.substring(0, p.length() - ("$package").length()); p.substring(0, p.length() - ("$package").length())
else p; else p
} }
def body : NodeSeq = { def body : NodeSeq = {
@ -254,7 +261,7 @@ abstract class DocGenerator extends Models {
} } </span>; } } </span>;
} else NodeSeq.Empty; } else NodeSeq.Empty;
def shortHeader(mmbr : HasTree) : NodeSeq = { def shortHeader(mmbr: HasTree): NodeSeq = {
<tr> <tr>
<td valign="top" class="modifiers"> <td valign="top" class="modifiers">
{ { for (val str <- stringsFor(mmbr.mods)) yield <code>{(Text(str + " "))}</code>; } } { { for (val str <- stringsFor(mmbr.mods)) yield <code>{(Text(str + " "))}</code>; } }
@ -270,15 +277,15 @@ abstract class DocGenerator extends Models {
</tr>; </tr>;
} }
def fullComment(mmbr : HasTree) : NodeSeq = { def fullComment(mmbr: HasTree): NodeSeq = {
if (comments.contains(mmbr.tree.symbol)) if (comments.contains(mmbr.tree.symbol))
comment(comments(mmbr.tree.symbol), false) else NodeSeq.Empty; comment(comments(mmbr.tree.symbol), false) else NodeSeq.Empty;
}; };
def shortComment(mmbr : HasTree) : NodeSeq = { def shortComment(mmbr: HasTree): NodeSeq = {
if (comments.contains(mmbr.tree.symbol)) if (comments.contains(mmbr.tree.symbol))
comment(comments(mmbr.tree.symbol), true) else NodeSeq.Empty; comment(comments(mmbr.tree.symbol), true) else NodeSeq.Empty;
}; };
def ifT (cond : Boolean, nodes : NodeSeq) = if (cond) nodes else NodeSeq.Empty; def ifT (cond: Boolean, nodes: NodeSeq) = if (cond) nodes else NodeSeq.Empty;
def ifT (tree : Tree, nodes : NodeSeq, before : Boolean) = { def ifT (tree : Tree, nodes : NodeSeq, before : Boolean) = {
if (tree != EmptyTree && if (tree != EmptyTree &&
tree.tpe.symbol != definitions.AnyClass && tree.tpe.symbol != definitions.AnyClass &&
@ -295,7 +302,7 @@ abstract class DocGenerator extends Models {
def forType(tpe: Type): NodeSeq = def forType(tpe: Type): NodeSeq =
urlFor(tpe, contentFrame); urlFor(tpe, contentFrame);
def forTree(tree : Tree) : NodeSeq = tree match { def forTree(tree: Tree): NodeSeq = tree match {
case vdef : ValDef => case vdef : ValDef =>
Text(vdef.symbol.name.toString()).concat(Text(" : ")).concat(forTree(vdef.tpt)); Text(vdef.symbol.name.toString()).concat(Text(" : ")).concat(forTree(vdef.tpt));
case sel : Select => forTree(sel.qualifier).concat(Text(sel.symbol.nameString)); case sel : Select => forTree(sel.qualifier).concat(Text(sel.symbol.nameString));
@ -319,17 +326,17 @@ abstract class DocGenerator extends Models {
def surround(open: String, close: String, node: NodeSeq): NodeSeq = def surround(open: String, close: String, node: NodeSeq): NodeSeq =
Text(open).concat(node).concat(Text(close)); Text(open).concat(node).concat(Text(close));
def typesFor(ht : HasTree) : NodeSeq = { def typesFor(ht: HasTree): NodeSeq = {
val tparams = ht.tree match { val tparams = ht.tree match {
case cdef : ClassDef => cdef.tparams; case cdef: ClassDef => cdef.tparams
case ddef : DefDef => ddef.tparams; case ddef: DefDef => ddef.tparams
case adef : AliasTypeDef => adef.tparams; case adef: AliasTypeDef => adef.tparams
case _ => Nil; case _ => Nil
} }
if (tparams.isEmpty) Text(""); if (tparams.isEmpty) Text("");
else surround("[", "]", forTrees(tparams)); else surround("[", "]", forTrees(tparams));
} }
def argsFor(ht : HasTree) : NodeSeq = ht.tree match { def argsFor(ht: HasTree): NodeSeq = ht.tree match {
case ddef : DefDef => case ddef : DefDef =>
if (!ddef.vparamss.isEmpty && if (!ddef.vparamss.isEmpty &&
(!ddef.vparamss.tail.isEmpty || !ddef.vparamss.head.isEmpty)) { (!ddef.vparamss.tail.isEmpty || !ddef.vparamss.head.isEmpty)) {
@ -339,12 +346,13 @@ abstract class DocGenerator extends Models {
} else NodeSeq.Empty; } else NodeSeq.Empty;
case _ => NodeSeq.Empty; case _ => NodeSeq.Empty;
} }
def resultFor(ht : HasTree) : NodeSeq = ht.tree match { def resultFor(ht: HasTree): NodeSeq = ht.tree match {
case vdef : ValOrDefDef => case vdef : ValOrDefDef =>
if (!vdef.symbol.nameString.equals("this")) if (!vdef.symbol.nameString.equals("this"))
Text(" : ").concat(forTree(vdef.tpt)); Text(" : ").concat(forTree(vdef.tpt));
else NodeSeq.Empty; else NodeSeq.Empty;
case _ => NodeSeq.Empty; case _ =>
NodeSeq.Empty
} }
} }
@ -355,7 +363,7 @@ abstract class DocGenerator extends Models {
def path = module.fullNameString('/') + "$content"; def path = module.fullNameString('/') + "$content";
def title = "All Classes and Objects in " + module.fullNameString('.'); def title = "All Classes and Objects in " + module.fullNameString('.');
def body : NodeSeq = { def body: NodeSeq = {
<span><div class="page-title"> <span><div class="page-title">
Scala 2 Scala 2
<br/>API Specification <br/>API Specification
@ -378,8 +386,8 @@ abstract class DocGenerator extends Models {
} }
abstract class ContentFrame extends ContentFrame0 { abstract class ContentFrame extends ContentFrame0 {
def clazz: ImplMod; def clazz: ImplMod
def kind: Kind; def kind: Kind
def body: NodeSeq = <span>{navigation}{header0}{fullHeader(clazz)}</span>; def body: NodeSeq = <span>{navigation}{header0}{fullHeader(clazz)}</span>;
final def path = urlFor0(clazz.tree.symbol,clazz.tree.symbol); final def path = urlFor0(clazz.tree.symbol,clazz.tree.symbol);
@ -387,7 +395,7 @@ abstract class DocGenerator extends Models {
// <td class="navigation-enabled">{aref("help.html" , "_self", "Help" )}</td> // <td class="navigation-enabled">{aref("help.html" , "_self", "Help" )}</td>
// <td class="navigation-enabled">{aref("root-page.html", "_self", "Overview")}</td> // <td class="navigation-enabled">{aref("root-page.html", "_self", "Overview")}</td>
// <td class="navigation-enabled">{aref("index.html" , null, "Index" )}</td> // <td class="navigation-enabled">{aref("index.html" , null, "Index" )}</td>
def navigation : NodeSeq = def navigation: NodeSeq =
<table class="navigation"> <table class="navigation">
<tr> <tr>
<td valign="top" class="navigation-links"> <td valign="top" class="navigation-links">
@ -395,13 +403,13 @@ abstract class DocGenerator extends Models {
</tr></table> </tr></table>
</td> </td>
<td align="right" valign="top" style="white-space:nowrap;" rowspan="2"> <td align="right" valign="top" style="white-space:nowrap;" rowspan="2">
{div0("Scala 2")} {doctitle}
</td> </td>
</tr> </tr>
<tr><td></td></tr> <tr><td></td></tr>
</table>; </table>;
def header0 : NodeSeq = <span> def header0: NodeSeq = <span>
<hr/> in {aref(urlFor(clazz.tree.symbol.owner), "_self", clazz.tree.symbol.owner.fullNameString('.'))} <hr/> in {aref(urlFor(clazz.tree.symbol.owner), "_self", clazz.tree.symbol.owner.fullNameString('.'))}
<div class="entity"> <div class="entity">
{Text(codeFor(kind))} {Text(codeFor(kind))}
@ -454,8 +462,8 @@ abstract class DocGenerator extends Models {
// class from for each module. // class from for each module.
for (val top <- topLevel.elements) { for (val top <- topLevel.elements) {
val module = top._1; val module = top._1
val members = top._2; val members = top._2
new ListClassFrame { new ListClassFrame {
def title = "List of classes and objects in package " + module.fullNameString('.') def title = "List of classes and objects in package " + module.fullNameString('.')
@ -482,10 +490,10 @@ abstract class DocGenerator extends Models {
} }
new Frame { new Frame {
def title = "Scala Library Documentation"; def title = windowTitle
def body = index; def body = index
def path = "index"; def path = "index"
override def hasBody = false; override def hasBody = false
}; };
for (val base <- "style.css" :: "script.js" :: Nil) { for (val base <- "style.css" :: "script.js" :: Nil) {
val input = getClass().getClassLoader().getResourceAsStream("scala/tools/nsc/doc/" + base); val input = getClass().getClassLoader().getResourceAsStream("scala/tools/nsc/doc/" + base);
@ -503,7 +511,7 @@ abstract class DocGenerator extends Models {
} }
} }
input.close(); input.close();
output.close(); output.close()
} }
} }
} }
@ -528,10 +536,10 @@ abstract class DocGenerator extends Models {
def parse(str : String) : NodeSeq = { def parse(str : String) : NodeSeq = {
new SpecialNode { new SpecialNode {
def label = "#PCDATA"; def label = "#PCDATA"
def toString(sb:StringBuffer): StringBuffer = { def toString(sb: StringBuffer): StringBuffer = {
sb.append(str.trim()); sb.append(str.trim());
sb; sb
} }
} }

View File

@ -2,10 +2,13 @@
* Copyright 2005-2006 LAMP/EPFL * Copyright 2005-2006 LAMP/EPFL
* @author Sean McDirmid * @author Sean McDirmid
*/ */
// $Id: $ // $Id$
package scala.tools.nsc.doc package scala.tools.nsc.doc
import java.io.StringReader
import org.xml.sax.InputSource
import scala.collection.immutable._ import scala.collection.immutable._
import scala.xml._ import scala.xml._
@ -14,6 +17,13 @@ object DocUtil {
def dquote(str: String): NodeSeq = def dquote(str: String): NodeSeq =
DQUOTE :: Text(str) :: DQUOTE :: Nil DQUOTE :: Text(str) :: DQUOTE :: Nil
def load(str: String): NodeSeq = {
val xmlStr = str.replaceAll("&lt;", "<").replaceAll("&gt;",">")
.replaceAll("&amp;", "&").replaceAll("&quot;", "\"")
val xmlSrc = new InputSource(new StringReader(xmlStr))
XML.load(xmlSrc)
}
object DQUOTE extends SpecialNode { object DQUOTE extends SpecialNode {
def toString(sb: StringBuffer) = { def toString(sb: StringBuffer) = {
sb.append("\""); sb sb.append("\""); sb

View File

@ -9,7 +9,7 @@
// $Id$ // $Id$
package scala.xml; package scala.xml
/** an XML node for text (PCDATA). Used in both non-bound and bound XML /** an XML node for text (PCDATA). Used in both non-bound and bound XML
@ -17,19 +17,19 @@ package scala.xml;
* @author Burak Emir * @author Burak Emir
* @param text the text contained in this node, may not be null. * @param text the text contained in this node, may not be null.
*/ */
case class Text( _data: String ) extends Atom[String](_data) { case class Text(_data: String) extends Atom[String](_data) {
if(null == data) if (null == data)
throw new java.lang.NullPointerException("tried to construct Text with null"); throw new java.lang.NullPointerException("tried to construct Text with null")
final override def equals(x:Any) = x match { final override def equals(x: Any) = x match {
case s:String => s.equals( data.toString() ); case s:String => s.equals(data.toString())
case s:Text => data == s.data ; case s:Text => data == s.data
case _ => false; case _ => false
} }
/** returns text, with some characters escaped according to XML spec */ /** returns text, with some characters escaped according to XML spec */
override def toString(sb:StringBuffer) = override def toString(sb: StringBuffer) =
Utility.escape( data.toString(), sb ); Utility.escape(data.toString(), sb)
} }

View File

@ -9,33 +9,32 @@
// $Id$ // $Id$
package scala.xml; package scala.xml
import java.lang.StringBuffer; import java.lang.StringBuffer
import scala.collection.mutable; import scala.collection.mutable
/** /**
* Utility functions for processing instances of bound and not bound XML * Utility functions for processing instances of bound and
* classes, as well as escaping text nodes * not bound XML classes, as well as escaping text nodes.
*/ */
object Utility extends AnyRef with parsing.TokenTests { object Utility extends AnyRef with parsing.TokenTests {
def view(s: String): Text = Text(s); def view(s: String): Text = Text(s)
/* escapes the characters &lt; &gt; &amp; and &quot; from string */ /* escapes the characters &lt; &gt; &amp; and &quot; from string */
final def escape(text: String): String = final def escape(text: String): String =
escape(text, new StringBuffer()).toString(); escape(text, new StringBuffer()).toString()
/* appends escaped string to s */ /* appends escaped string to s */
final def escape(text: String, s: StringBuffer): StringBuffer = { final def escape(text: String, s: StringBuffer): StringBuffer = {
for (val c <- Iterator.fromString(text)) c match { for (val c <- Iterator.fromString(text)) c match {
case '<' => s.append("&lt;"); case '<' => s.append("&lt;")
case '>' => s.append("&gt;"); case '>' => s.append("&gt;")
case '&' => s.append("&amp;"); case '&' => s.append("&amp;")
case '"' => s.append("&quot;"); case '"' => s.append("&quot;")
case _ => s.append(c); case _ => s.append(c)
} }
s s
} }
@ -48,8 +47,8 @@ object Utility extends AnyRef with parsing.TokenTests {
*/ */
def collectNamespaces(nodes: Seq[Node]): mutable.Set[String] = { def collectNamespaces(nodes: Seq[Node]): mutable.Set[String] = {
var m = new mutable.HashSet[String](); var m = new mutable.HashSet[String]()
val it = nodes.elements; val it = nodes.elements
while (it.hasNext) while (it.hasNext)
collectNamespaces(it.next, m); collectNamespaces(it.next, m);
m m
@ -84,9 +83,9 @@ object Utility extends AnyRef with parsing.TokenTests {
* @todo define a way to escape literal characters to &amp;xx; references * @todo define a way to escape literal characters to &amp;xx; references
*/ */
def toXML(n: Node, stripComment: Boolean): String = { def toXML(n: Node, stripComment: Boolean): String = {
val sb = new StringBuffer(); val sb = new StringBuffer()
toXML(n, TopScope, sb, stripComment); toXML(n, TopScope, sb, stripComment)
sb.toString(); sb.toString()
} }
@ -108,27 +107,26 @@ object Utility extends AnyRef with parsing.TokenTests {
case _ => case _ =>
// print tag with namespace declarations // print tag with namespace declarations
sb.append('<'); sb.append('<')
x.nameToString(sb); x.nameToString(sb)
if (x.attributes != null) { if (x.attributes != null) {
x.attributes.toString(sb) x.attributes.toString(sb)
} }
x.scope.toString(sb, pscope); x.scope.toString(sb, pscope)
sb.append('>'); sb.append('>')
for (val c <- x.child.elements) { for (val c <- x.child.elements) {
toXML(c, x.scope, sb, stripComment); toXML(c, x.scope, sb, stripComment)
} }
sb.append("</"); sb.append("</")
x.nameToString(sb); x.nameToString(sb)
sb.append('>') sb.append('>')
} }
} }
/** returns prefix of qualified name if any */ /** returns prefix of qualified name if any */
final def prefix(name: String): Option[String] = { final def prefix(name: String): Option[String] = {
val i = name.indexOf(':'.asInstanceOf[Int]); val i = name.indexOf(':'.asInstanceOf[Int])
if( i != -1 ) Some( name.substring(0, i) ) else None if( i != -1 ) Some( name.substring(0, i) ) else None
} }
@ -161,20 +159,20 @@ object Utility extends AnyRef with parsing.TokenTests {
*/ */
def systemLiteralToString(s: String): String = { def systemLiteralToString(s: String): String = {
val sb = new StringBuffer(); val sb = new StringBuffer()
systemLiteralToString(sb, s); systemLiteralToString(sb, s)
sb.toString(); sb.toString()
} }
def systemLiteralToString(sb: StringBuffer, s: String): StringBuffer = { def systemLiteralToString(sb: StringBuffer, s: String): StringBuffer = {
sb.append("SYSTEM "); sb.append("SYSTEM ")
appendQuoted(s, sb); appendQuoted(s, sb)
} }
def publicLiteralToString(s: String): String = { def publicLiteralToString(s: String): String = {
val sb = new StringBuffer(); val sb = new StringBuffer()
systemLiteralToString(sb, s); systemLiteralToString(sb, s)
sb.toString(); sb.toString()
} }
def publicLiteralToString(sb: StringBuffer, s: String): StringBuffer = { def publicLiteralToString(sb: StringBuffer, s: String): StringBuffer = {
@ -200,11 +198,11 @@ object Utility extends AnyRef with parsing.TokenTests {
* @param sb * @param sb
*/ */
def appendEscapedQuoted(s: String, sb: StringBuffer) = { def appendEscapedQuoted(s: String, sb: StringBuffer) = {
sb.append('"'); sb.append('"')
val z:Seq[Char] = Predef.string2seq(s); val z:Seq[Char] = Predef.string2seq(s)
for( val c <- z ) c match { for( val c <- z ) c match {
case '"' => sb.append('\\'); sb.append('"'); case '"' => sb.append('\\'); sb.append('"')
case _ => sb.append( c ); case _ => sb.append(c)
} }
sb.append('"') sb.append('"')
} }
@ -212,36 +210,36 @@ object Utility extends AnyRef with parsing.TokenTests {
def getName(s: String, index: Int): String = { def getName(s: String, index: Int): String = {
var i = index; var i = index;
val sb = new StringBuffer(); val sb = new StringBuffer();
if(i < s.length()) { if (i < s.length()) {
var c = s.charAt(i); var c = s.charAt(i);
if(isNameStart(s.charAt(i))) if (isNameStart(s.charAt(i)))
while(i < s.length() && { c = s.charAt(i); isNameChar(c)}) { while (i < s.length() && { c = s.charAt(i); isNameChar(c)}) {
sb.append(c); sb.append(c);
i = i + 1; i = i + 1
} }
sb.toString(); sb.toString()
} else null } else null
} }
/** returns null if the value is a correct attribute value, error message if it isn't */ /** returns null if the value is a correct attribute value, error message if it isn't */
def checkAttributeValue(value: String): String = { def checkAttributeValue(value: String): String = {
var i = 0; var i = 0
while(i < value.length()) { while (i < value.length()) {
value.charAt(i) match { value.charAt(i) match {
case '<' => case '<' =>
return "< not allowed in attribute value"; return "< not allowed in attribute value";
case '&' => case '&' =>
val n = getName(value, i+1); val n = getName(value, i+1);
if(n== null) if (n== null)
return "malformed entity reference in attribute value ["+value+"]"; return "malformed entity reference in attribute value ["+value+"]";
i = i + n.length() + 1; i = i + n.length() + 1;
if(i >= value.length() || value.charAt(i) != ';') if (i >= value.length() || value.charAt(i) != ';')
return "malformed entity reference in attribute value ["+value+"]"; return "malformed entity reference in attribute value ["+value+"]";
case _ => case _ =>
} }
i = i + 1; i = i + 1
} }
return null; null
} }
} }

View File

@ -203,7 +203,7 @@ test_print_failure() {
test_run_pos() { test_run_pos() {
rm -rf "$dstbase".obj && rm -rf "$dstbase".obj &&
mkdir -p "$dstbase".obj && mkdir -p "$dstbase".obj &&
$SOCOS -d "$os_dstbase".obj "$@" "$os_srcbase".scala && $SCALAC -d "$os_dstbase".obj "$@" "$os_srcbase".scala &&
rm -rf "$dstbase".obj; rm -rf "$dstbase".obj;
} }
@ -211,7 +211,7 @@ test_run_pos() {
test_run_neg() { test_run_neg() {
rm -rf "$dstbase".obj && rm -rf "$dstbase".obj &&
mkdir -p "$dstbase".obj && mkdir -p "$dstbase".obj &&
( cd "$srcdir" && $SOCOS -d "$os_dstbase".obj "$@" "$testname".scala; ); ( cd "$srcdir" && $SCALAC -d "$os_dstbase".obj "$@" "$testname".scala; );
if [ "$?" = 0 ]; then status=1; else status=0; fi; if [ "$?" = 0 ]; then status=1; else status=0; fi;
rm -rf "$dstbase".obj; rm -rf "$dstbase".obj;
return $status; return $status;
@ -221,7 +221,7 @@ test_run_neg() {
test_run_jvm() { test_run_jvm() {
rm -rf "$dstbase".obj && rm -rf "$dstbase".obj &&
mkdir -p "$dstbase".obj && mkdir -p "$dstbase".obj &&
$SOCOS -d "$os_dstbase".obj "$@" "$os_srcbase".scala && $SCALAC -d "$os_dstbase".obj "$@" "$os_srcbase".scala &&
classpath=`get_os_pathlist "$os_dstbase".obj:$CLASSPATH` && classpath=`get_os_pathlist "$os_dstbase".obj:$CLASSPATH` &&
$SCALA -classpath $classpath Test "jvm" && $SCALA -classpath $classpath Test "jvm" &&
rm -rf "$dstbase".obj; rm -rf "$dstbase".obj;
@ -235,7 +235,7 @@ test_run_dis() {
fi; fi;
rm -rf "$dstbase".obj && rm -rf "$dstbase".obj &&
mkdir -p "$dstbase".obj && mkdir -p "$dstbase".obj &&
$SOCOS -d "$os_dstbase".obj "$@" "$os_srcbase".scala && $SCALAC -d "$os_dstbase".obj "$@" "$os_srcbase".scala &&
$SCALAP -classpath "$os_dstbase".obj `cat "$argsfile"` && $SCALAP -classpath "$os_dstbase".obj `cat "$argsfile"` &&
rm -rf "$dstbase".obj; rm -rf "$dstbase".obj;
} }
@ -245,7 +245,7 @@ test_run_msil() {
assemblies=`get_os_pathlist "/home/linuxsoft/apps/msil"`; assemblies=`get_os_pathlist "/home/linuxsoft/apps/msil"`;
rm -f "$dstbase".il && rm -f "$dstbase".il &&
rm -f "$dstbase".EXE && rm -f "$dstbase".EXE &&
$SOCOS -nowarn -target:msil -o "$os_dstbase" -r $assemblies "$@" \ $SCALAC -nowarn -target:msil -o "$os_dstbase" -r $assemblies "$@" \
"$os_srcbase".scala && "$os_srcbase".scala &&
case "$UNAME" in case "$UNAME" in
CYGWIN* ) CYGWIN* )
@ -558,7 +558,7 @@ if [ "$TEST_ALL" = "true" ]; then
fi; fi;
SCALA="${BIN_DIR}scala"; SCALA="${BIN_DIR}scala";
SOCOS="${BIN_DIR}scalac"; SCALAC="${BIN_DIR}scalac -encoding iso-8859-1";
SCALAP="${BIN_DIR}scalap"; SCALAP="${BIN_DIR}scalap";
SCALA_SCALA_ARGS="-Xmx512M $SCALA_SCALA_ARGS"; SCALA_SCALA_ARGS="-Xmx512M $SCALA_SCALA_ARGS";
@ -575,7 +575,7 @@ fi
printf_outline "Source directory is : $SRCDIR\\n"; printf_outline "Source directory is : $SRCDIR\\n";
bin_dir=$BIN_DIR bin_dir=$BIN_DIR
if [ -z "$bin_dir" ]; then if [ -z "$bin_dir" ]; then
bin_dir=`which "$SOCOS"` && bin_dir=`dirname "$bin_dir"`/; bin_dir=`which "$SCALAC"` && bin_dir=`dirname "$bin_dir"`/;
bin_dir=`test_get_location ${bin_dir}scalac`; bin_dir=`test_get_location ${bin_dir}scalac`;
fi; fi;
printf_outline "Scala binaries in : $bin_dir\\n"; printf_outline "Scala binaries in : $bin_dir\\n";