summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-09-25 14:50:45 +0000
committerPaul Phillips <paulp@improving.org>2009-09-25 14:50:45 +0000
commit22c91bc256a30df03db359ab7de5616683a30b17 (patch)
tree7c9e29c4dae2f825145ca3727131317519b59b64
parentd7796af940ac9a0431184115c6c0478856c7ee54 (diff)
downloadscala-22c91bc256a30df03db359ab7de5616683a30b17.tar.gz
scala-22c91bc256a30df03db359ab7de5616683a30b17.tar.bz2
scala-22c91bc256a30df03db359ab7de5616683a30b17.zip
Some more XML work as I prepare to deal with th...
Some more XML work as I prepare to deal with the almost unfixable XML equality situation (sure, I can be equal to four different classes and their four different hashcodes, why do you ask?)
-rw-r--r--src/dotnet-library/scala/xml/path/Expression.scala1
-rw-r--r--src/library/scala/xml/MetaData.scala38
-rw-r--r--src/library/scala/xml/PrettyPrinter.scala9
-rw-r--r--src/library/scala/xml/ProcInstr.scala41
-rw-r--r--src/library/scala/xml/Text.scala11
-rw-r--r--src/library/scala/xml/TextBuffer.scala34
-rw-r--r--src/library/scala/xml/Unparsed.scala3
-rw-r--r--src/library/scala/xml/UnprefixedAttribute.scala14
-rw-r--r--src/library/scala/xml/path/Expression.scala49
-rw-r--r--src/library/scala/xml/pull/XMLEvent.scala1
-rw-r--r--src/library/scala/xml/transform/BasicTransformer.scala2
11 files changed, 46 insertions, 157 deletions
diff --git a/src/dotnet-library/scala/xml/path/Expression.scala b/src/dotnet-library/scala/xml/path/Expression.scala
deleted file mode 100644
index 00e8ca63f5..0000000000
--- a/src/dotnet-library/scala/xml/path/Expression.scala
+++ /dev/null
@@ -1 +0,0 @@
-/* Expression.scala does not exist for the dotnet target */
diff --git a/src/library/scala/xml/MetaData.scala b/src/library/scala/xml/MetaData.scala
index 95a1bbbf69..280f2b7871 100644
--- a/src/library/scala/xml/MetaData.scala
+++ b/src/library/scala/xml/MetaData.scala
@@ -29,28 +29,20 @@ object MetaData {
@tailrec
def concatenate(attribs: MetaData, new_tail: MetaData): MetaData =
if (attribs eq Null) new_tail
- else concatenate(attribs.next, attribs.copy(new_tail))
+ else concatenate(attribs.next, attribs copy new_tail)
/**
* returns normalized MetaData, with all duplicates removed and namespace prefixes resolved to
* namespace URIs via the given scope.
*/
def normalize(attribs: MetaData, scope: NamespaceBinding): MetaData = {
- import collection.mutable.HashSet
- def iterate(md: MetaData, normalized_attribs: MetaData, map: HashSet[String]): MetaData = {
- if (md eq Null)
- normalized_attribs
- else {
- val universal_key = getUniversalKey(md, scope)
- if (map.contains(universal_key))
- iterate(md.next, normalized_attribs, map)
- else {
- map += universal_key
- iterate(md.next, md.copy(normalized_attribs), map)
- }
- }
+ def iterate(md: MetaData, normalized_attribs: MetaData, set: Set[String]): MetaData = {
+ lazy val key = getUniversalKey(md, scope)
+ if (md eq Null) normalized_attribs
+ else if (set(key)) iterate(md.next, normalized_attribs, set)
+ else iterate(md.next, md copy normalized_attribs, set + key)
}
- iterate(attribs, Null, new HashSet[String])
+ iterate(attribs, Null, Set())
}
/**
@@ -156,19 +148,9 @@ abstract class MetaData extends Iterable[MetaData]
case _ => false
}
- /** returns an iterator on attributes */
- def iterator: Iterator[MetaData] = new Iterator[MetaData] {
- var x: MetaData = MetaData.this
- def hasNext = Null != x
- def next = {
- val y = x
- x = x.next
- y
- }
- }
- override def size : Int = 1 + {
- if (Null == next) 0 else next.size
- }
+ /** Returns an iterator on attributes */
+ def iterator: Iterator[MetaData] = Iterator.iterate(this)(_.next) takeWhile (_ != Null)
+ override def size: Int = 1 + iterator.length
/** shallow equals method */
def equals1(that: MetaData): Boolean
diff --git a/src/library/scala/xml/PrettyPrinter.scala b/src/library/scala/xml/PrettyPrinter.scala
index e97a2e0f59..1753860f50 100644
--- a/src/library/scala/xml/PrettyPrinter.scala
+++ b/src/library/scala/xml/PrettyPrinter.scala
@@ -25,7 +25,7 @@ import Utility.sbToString
* @param width the width to fit the output into
* @step indentation
*/
-class PrettyPrinter( width:Int, step:Int ) {
+class PrettyPrinter(width: Int, step: Int) {
class BrokenException() extends java.lang.Exception
@@ -174,7 +174,7 @@ class PrettyPrinter( width:Int, step:Int ) {
val sb = new StringBuilder()
Utility.toXML(node, pscope, sb, false)
if (doPreserve(node)) sb.toString
- else TextBuffer.fromString(sb.toString()).toText(0)._data
+ else TextBuffer.fromString(sb.toString()).toText(0).data
}
if (childrenAreLeaves(node) && fits(test)) {
makeBox(ind, test)
@@ -300,8 +300,5 @@ class PrettyPrinter( width:Int, step:Int ) {
* @param sb the string buffer to which to append to
*/
def formatNodes(nodes: Seq[Node], pscope: NamespaceBinding, sb: StringBuilder): Unit =
- for (n <- nodes.iterator) {
- sb.append(format(n, pscope))
- }
-
+ nodes foreach (n => sb append format(n, pscope))
}
diff --git a/src/library/scala/xml/ProcInstr.scala b/src/library/scala/xml/ProcInstr.scala
index a4bff34271..c59e89e9a8 100644
--- a/src/library/scala/xml/ProcInstr.scala
+++ b/src/library/scala/xml/ProcInstr.scala
@@ -8,7 +8,6 @@
// $Id$
-
package scala.xml
/** an XML node for processing instructions (PI)
@@ -17,50 +16,24 @@ package scala.xml
* @param target target name of this PI
* @param text text contained in this node, may not contain "?>"
*/
-case class ProcInstr(target:String, proctext:String) extends SpecialNode
+case class ProcInstr(target: String, proctext: String) extends SpecialNode
{
-
if (!Utility.isName(target))
throw new IllegalArgumentException(target+" must be an XML Name")
- if (text.indexOf("?>") != -1)
+ if (proctext contains "?>")
throw new IllegalArgumentException(proctext+" may not contain \"?>\"")
+ if (target.toLowerCase == "xml")
+ throw new IllegalArgumentException(target+" is reserved")
final override def doCollectNamespaces = false
final override def doTransform = false
- (target: Seq[Char]) match {
- case Seq('X'|'x','M'|'m','L'|'l') =>
- throw new IllegalArgumentException(target+" is reserved")
- case _ =>
- }
-
- /** structural equality */
- override def equals(x: Any): Boolean = x match {
- case ProcInstr(x, y) => x.equals(target) && y.equals(proctext)
- case _ => false
- }
-
- /** the constant "#PI" */
- final def label = "#PI"
-
- /** hashcode for this PI */
- override def hashCode() = target.hashCode() * 7 + proctext.hashCode()
-
-
+ final def label = "#PI"
override def text = ""
/** appends &quot;&lt;?&quot; target (&quot; &quot;+text)?+&quot;?&gt;&quot;
* to this stringbuffer.
*/
- override def buildString(sb: StringBuilder) = {
- sb
- .append("<?")
- .append(target);
- if (proctext.length() > 0) {
- sb
- .append(' ')
- .append(proctext);
- }
- sb.append("?>")
- }
+ override def buildString(sb: StringBuilder) =
+ sb append "<?%s%s?>".format(target, (if (proctext.isEmpty) "" else " " + proctext))
}
diff --git a/src/library/scala/xml/Text.scala b/src/library/scala/xml/Text.scala
index f434d10acf..34001bba70 100644
--- a/src/library/scala/xml/Text.scala
+++ b/src/library/scala/xml/Text.scala
@@ -11,6 +11,10 @@
package scala.xml
+object Text {
+ def apply(data: String) = new Text(data)
+ def unapply(other: Any) = other match { case x: Text => Some(x.data) ; case _ => None }
+}
/** The class <code>Text</code> implements an XML node for text (PCDATA).
* It is used in both non-bound and bound XML representations.
@@ -19,14 +23,14 @@ package scala.xml
*
* @param text the text contained in this node, may not be null.
*/
-case class Text(_data: String) extends Atom[String](_data)
+class Text(data: String) extends Atom[String](data)
{
- if (null == data)
+ if (data == null)
throw new IllegalArgumentException("tried to construct Text with null")
+ /** XXX More hashCode flailing. */
final override def equals(x: Any) = x match {
case s:String => s == data
- case s:Text => data == s.data
case s:Atom[_] => data == s.data
case _ => false
}
@@ -39,5 +43,4 @@ case class Text(_data: String) extends Atom[String](_data)
*/
override def buildString(sb: StringBuilder) =
Utility.escape(data, sb)
-
}
diff --git a/src/library/scala/xml/TextBuffer.scala b/src/library/scala/xml/TextBuffer.scala
index 70635b6135..20c23a6a06 100644
--- a/src/library/scala/xml/TextBuffer.scala
+++ b/src/library/scala/xml/TextBuffer.scala
@@ -11,9 +11,10 @@
package scala.xml
+import Utility.isSpace
object TextBuffer {
- def fromString(str: String): TextBuffer = new TextBuffer().append(str)
+ def fromString(str: String): TextBuffer = new TextBuffer() append str
}
/** The class <code>TextBuffer</code> is for creating text nodes without
@@ -21,22 +22,20 @@ object TextBuffer {
* appended with the <code>append</code> method will be replaced by a single
* space character, and leading and trailing space will be removed completely.
*/
-class TextBuffer {
-
+class TextBuffer
+{
val sb = new StringBuilder()
- var ws = true
-
- def appendSpace = if(!ws) { ws = true; sb.append(' ') } else {}
- def appendChar(c: Char) = { ws = false; sb.append( c ) }
/** Appends this string to the text buffer, trimming whitespaces as needed.
*
* @param cs ...
* @return ...
*/
- def append(cs: Seq[Char]): TextBuffer = {
- for (c <- cs)
- if (Utility.isSpace(c)) appendSpace else appendChar(c)
+ def append(cs: Seq[Char]): this.type = {
+ cs foreach { c =>
+ if (!isSpace(c)) sb append c
+ else if (sb.isEmpty || !isSpace(sb.last)) sb append ' '
+ }
this
}
@@ -44,17 +43,8 @@ class TextBuffer {
*
* @return the text without whitespaces.
*/
- def toText: Seq[Text] = {
- var len = sb.length /* invariant */
- if (len == 0) return Nil
-
- if (Utility.isSpace(sb.charAt(len - 1))) {
- len -= 1
- sb.length = len
- }
- if (len == 0) return Nil
-
- List(Text(sb.toString()))
+ def toText: Seq[Text] = sb.toString.trim match {
+ case "" => Nil
+ case s => Seq(Text(s))
}
-
}
diff --git a/src/library/scala/xml/Unparsed.scala b/src/library/scala/xml/Unparsed.scala
index 7ee616f495..08e7f373e9 100644
--- a/src/library/scala/xml/Unparsed.scala
+++ b/src/library/scala/xml/Unparsed.scala
@@ -22,10 +22,9 @@ class Unparsed(data: String) extends Atom[String](data)
if (null == data)
throw new IllegalArgumentException("tried to construct Unparsed with null")
+ /** XXX another hashCode fail */
final override def equals(x: Any) = x match {
case s:String => s == data
- case s:Text => data == s.data
- case s:Unparsed => data == s.data
case s:Atom[_] => data == s.data
case _ => false
}
diff --git a/src/library/scala/xml/UnprefixedAttribute.scala b/src/library/scala/xml/UnprefixedAttribute.scala
index f82b5698dd..dcc10cd646 100644
--- a/src/library/scala/xml/UnprefixedAttribute.scala
+++ b/src/library/scala/xml/UnprefixedAttribute.scala
@@ -25,22 +25,19 @@ extends Attribute
/** same as this(key, Text(value), next) */
def this(key: String, value: String, next: MetaData) =
- this(key, if (value ne null) Text(value) else {val z:NodeSeq=null;z}, next)
+ this(key, if (value ne null) Text(value) else null: NodeSeq, next)
/** same as this(key, value.get, next), or no attribute if value is None */
def this(key: String, value: Option[Seq[Node]], next: MetaData) =
- this(key, if (!value.isEmpty) value.get else {val z:NodeSeq=null;z}, next)
+ this(key, value.orNull, next)
/** returns a copy of this unprefixed attribute with the given next field*/
- def copy(next: MetaData) =
- new UnprefixedAttribute(key, value, next)
+ def copy(next: MetaData) = new UnprefixedAttribute(key, value, next)
def equals1(m: MetaData) =
!m.isPrefixed && (m.key == key) && (m.value sameElements value)
- /** returns null */
- final def getNamespace(owner: Node): String =
- null
+ final def getNamespace(owner: Node): String = null
/**
* Gets value of unqualified (unprefixed) attribute with given key, null if not found
@@ -62,12 +59,9 @@ extends Attribute
def apply(namespace: String, scope: NamespaceBinding, key: String): Seq[Node] =
next(namespace, scope, key)
- /** returns the hashcode.
- */
override def hashCode() =
key.hashCode() * 7 + { if(value ne null) value.hashCode() * 53 else 0 } + next.hashCode()
- /** returns false */
final def isPrefixed = false
/** appends string representation of only this attribute to stringbuffer.
diff --git a/src/library/scala/xml/path/Expression.scala b/src/library/scala/xml/path/Expression.scala
deleted file mode 100644
index dce0cd94c2..0000000000
--- a/src/library/scala/xml/path/Expression.scala
+++ /dev/null
@@ -1,49 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-// $Id$
-
-
-package scala.xml
-package path
-
-object Expression
-{
- final def testFromString(x: String): Test = if (x == "*") WildcardTest else NameTest(x)
- private def emptyNodeSeq = new NodeSeq { val theSeq = Nil }
-
- case class FExp(e:Expr, c:Cond) {
- def eval(n: Node): NodeSeq = emptyNodeSeq // @todo
- }
-
- abstract class GenExp
- case class Attrib(test: NameTest, e: Expr) extends GenExp
-
- abstract class Expr extends GenExp {
- def \ (x: String) = Child(testFromString(x), this)
- def \\ (x: String) = DescOrSelf(testFromString(x), this)
-
- def apply(c: Cond) = FExp(this, c)
- def eval(n: Node): NodeSeq = emptyNodeSeq // @todo
- }
-
- case object Root extends Expr;
-
- case class Child(test: Test, e: Expr) extends Expr;
- case class DescOrSelf(test: Test, e: Expr) extends Expr;
-
- abstract class Test;
-
- case object WildcardTest extends Test; // "x \ * "
- case class NameTest(label: String) extends Test; // "x \ bar"
-
- abstract class Cond;
-
- case class Exists(p: GenExp) extends Cond ; // "p [ p ]"
- case class Equals(p: Expr, c:String) extends Cond ; // "p [ @p == bla ]"
-}
diff --git a/src/library/scala/xml/pull/XMLEvent.scala b/src/library/scala/xml/pull/XMLEvent.scala
index a2177d61c9..0f6edfad52 100644
--- a/src/library/scala/xml/pull/XMLEvent.scala
+++ b/src/library/scala/xml/pull/XMLEvent.scala
@@ -24,6 +24,7 @@ case class EvElemStart(pre: String, label: String, attrs: MetaData, scope: Names
/** An element is encountered the last time */
case class EvElemEnd(pre: String, label: String) extends XMLEvent
+
/** A text node is encountered */
case class EvText(text: String) extends XMLEvent
diff --git a/src/library/scala/xml/transform/BasicTransformer.scala b/src/library/scala/xml/transform/BasicTransformer.scala
index 6b01871397..f3a4d10a33 100644
--- a/src/library/scala/xml/transform/BasicTransformer.scala
+++ b/src/library/scala/xml/transform/BasicTransformer.scala
@@ -51,7 +51,7 @@ abstract class BasicTransformer extends Function1[Node,Node]
val nch = transform(ch)
if (ch eq nch) n
- else Elem(n.prefix, n.label, n.attributes, n.scope, nch:_*)
+ else Elem(n.prefix, n.label, n.attributes, n.scope, nch: _*)
}
else n
}