Skip to content

Commit 115023f

Browse files
paulpadriaanm
authored andcommitted
Massive XML simplifications.
1 parent 3458610 commit 115023f

File tree

9 files changed

+66
-151
lines changed

9 files changed

+66
-151
lines changed

src/library/scala/xml/Atom.scala

+6-13
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,19 @@ package scala.xml
1818
* @param text the text contained in this node, may not be <code>null</code>.
1919
*/
2020
@serializable
21-
class Atom[+A](val data: A) extends SpecialNode {
21+
class Atom[+A](val data: A) extends SpecialNode
22+
{
23+
if (data.asInstanceOf[AnyRef] == null)
24+
throw new IllegalArgumentException("cannot construct Atom(null)")
2225

23-
data.asInstanceOf[AnyRef] match {
24-
case null => new IllegalArgumentException("cannot construct Atom(null)")
25-
case _ =>
26-
}
27-
final override def typeTag$: Int = -1
28-
29-
/** the constant "#PCDATA"
30-
*/
26+
final override def collectNamespacesAndDontTransform = false
3127
def label = "#PCDATA"
3228

3329
override def equals(x: Any) = x match {
3430
case s:Atom[_] => data == s.data
3531
case _ => false
3632
}
37-
38-
/** hashcode for this Text */
39-
override def hashCode() =
40-
data.hashCode()
33+
override def hashCode() = data.hashCode()
4134

4235
/** Returns text, with some characters escaped according to the XML
4336
* specification.

src/library/scala/xml/Comment.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package scala.xml
1818
*/
1919
case class Comment(commentText: String) extends SpecialNode {
2020

21-
final override def typeTag$: Int = -3
21+
final override def collectNamespacesAndDontTransform = false
2222

2323
if (commentText.indexOf("--") != -1)
2424
throw new IllegalArgumentException("text containts \"--\"")

src/library/scala/xml/Elem.scala

+15-21
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,15 @@ package scala.xml
1919
* Copyright 2008 Google Inc. All Rights Reserved.
2020
* @author Burak Emir <[email protected]>
2121
*/
22-
object Elem {
23-
22+
object Elem
23+
{
2424
def apply(prefix: String,label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*) =
2525
new Elem(prefix,label,attributes,scope,child:_*)
2626

2727
def unapplySeq(n:Node) = if (n.isInstanceOf[SpecialNode] || n.isInstanceOf[Group]) None else
28-
Some(Tuple5(n.prefix, n.label, n.attributes, n.scope, n.child))
29-
30-
28+
Some((n.prefix, n.label, n.attributes, n.scope, n.child))
3129
}
30+
3231
/** The case class <code>Elem</code> extends the <code>Node</code> class,
3332
* providing an immutable data object representing an XML element.
3433
*
@@ -41,13 +40,15 @@ object Elem {
4140
* Copyright 2008 Google Inc. All Rights Reserved.
4241
* @author Burak Emir <[email protected]>
4342
*/
44-
// "val" is redundant for non-overriding arguments
45-
@serializable class Elem(override val prefix: String,
46-
val label: String,
47-
override val attributes: MetaData,
48-
override val scope: NamespaceBinding,
49-
val child: Node*) extends Node {
50-
43+
@serializable
44+
class Elem(
45+
override val prefix: String,
46+
val label: String,
47+
override val attributes: MetaData,
48+
override val scope: NamespaceBinding,
49+
val child: Node*)
50+
extends Node
51+
{
5152
if ((null != prefix) && 0 == prefix.length())
5253
throw new IllegalArgumentException("prefix of zero length, use null instead")
5354

@@ -58,7 +59,7 @@ object Elem {
5859
// setting namespace scope if necessary
5960
// cleaning adjacent text nodes if necessary
6061

61-
final override def typeTag$: Int = 0
62+
final override def collectNamespacesAndDontTransform = true
6263

6364
override def hashCode(): Int =
6465
Utility.hashCode(prefix, label, attributes.hashCode(), scope.hashCode(), child)
@@ -78,12 +79,5 @@ object Elem {
7879
/** Returns concatenation of <code>text(n)</code> for each child
7980
* <code>n</code>.
8081
*/
81-
override def text = {
82-
val sb = new StringBuilder()
83-
val it = child.iterator
84-
while (it.hasNext)
85-
sb.append(it.next.text)
86-
sb.toString()
87-
}
88-
82+
override def text = child map (_.text) mkString
8983
}

src/library/scala/xml/EntityRef.scala

+1-15
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,9 @@ package scala.xml
1919
* @param text the text contained in this node.
2020
*/
2121
case class EntityRef(entityName: String) extends SpecialNode {
22-
23-
final override def typeTag$: Int = -5
24-
25-
/** structural equality */
26-
override def equals(x: Any): Boolean = x match {
27-
case EntityRef(x) => x.equals(entityName)
28-
case _ => false
29-
}
30-
31-
/** the constant "#ENTITY"
32-
*/
22+
final override def collectNamespacesAndDontTransform = false
3323
def label = "#ENTITY"
3424

35-
override def hashCode() = entityName.hashCode()
36-
37-
/** ...
38-
*/
3925
override def text = entityName match {
4026
case "lt" => "<"
4127
case "gt" => ">"

src/library/scala/xml/Node.scala

+6-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ object Node {
2525
/** the empty namespace */
2626
val EmptyNamespace = ""
2727

28-
def unapplySeq(n: Node) = Some(Tuple3(n.label, n.attributes, n.child))
28+
def unapplySeq(n: Node) = Some((n.label, n.attributes, n.child))
2929

3030
}
3131

@@ -46,7 +46,11 @@ abstract class Node extends NodeSeq {
4646

4747
/** used internally. Atom/Molecule = -1 PI = -2 Comment = -3 EntityRef = -5
4848
*/
49-
def typeTag$: Int = 0
49+
def isAtom = this.isInstanceOf[Atom[_]]
50+
51+
/** The logic formerly found in typeTag$, as best I could infer it.
52+
* XXX obviously this name is ludicrous. */
53+
def collectNamespacesAndDontTransform = true
5054

5155
/**
5256
* method returning the namespace bindings of this node. by default, this

src/library/scala/xml/NodeSeq.scala

+33-95
Original file line numberDiff line numberDiff line change
@@ -73,58 +73,35 @@ abstract class NodeSeq extends immutable.Sequence[Node] with SequenceTemplate[No
7373
* @param that ...
7474
* @return ...
7575
*/
76-
def \(that: String): NodeSeq = that match {
77-
case "_" =>
78-
var zs: List[Node] = Nil
79-
val it = this.iterator
80-
while (it.hasNext) {
81-
val x = it.next
82-
val jt = x.child.iterator
83-
while (jt.hasNext) {
84-
val y = jt.next
85-
if (y.typeTag$ != -1)
86-
zs = y::zs
76+
def \(that: String): NodeSeq = {
77+
def atResult = {
78+
def fail = throw new IllegalArgumentException(that)
79+
lazy val y = this(0)
80+
val attr =
81+
if (that.length == 1) fail
82+
else if (that(1) == '{') {
83+
val i = that indexOf '}'
84+
if (i == -1) fail
85+
val (uri, key) = (that.substring(2,i), that.substring(i+1, that.length()))
86+
if (uri == "" || key == "") fail
87+
else y.attribute(uri, key)
8788
}
88-
}
89-
NodeSeq.fromSeq(zs.reverse)
90-
91-
case _ if (that.charAt(0) == '@') && (this.length == 1) =>
92-
if (that.length() == 1)
93-
throw new IllegalArgumentException(that)
94-
if (that.charAt(1) == '{') {
95-
val i = that.indexOf('}')
96-
if (i == -1)
97-
throw new IllegalArgumentException(that)
98-
val (uri, key) = (that.substring(2,i), that.substring(i+1, that.length()))
99-
if (uri == "" || key == "")
100-
throw new IllegalArgumentException(that)
101-
val y = this(0)
102-
y.attribute(uri, key) match {
103-
case Some(x) => Group(x)
104-
case _ => NodeSeq.Empty
105-
}
106-
} else {
107-
val k = that.substring(1)
108-
val y = this(0)
109-
y.attribute(k) match {
110-
case Some(x) => Group(x)
111-
case _ => NodeSeq.Empty
112-
}
113-
}
89+
else y.attribute(that.substring(1))
11490

115-
case _ =>
116-
var zs: List[Node] = Nil
117-
val it = this.iterator
118-
while (it.hasNext) {
119-
val x = it.next
120-
val jt = x.child.iterator
121-
while (jt.hasNext) {
122-
val y = jt.next
123-
if (y.label == that)
124-
zs = y::zs
125-
}
91+
attr match {
92+
case Some(x) => Group(x)
93+
case _ => NodeSeq.Empty
12694
}
127-
NodeSeq.fromSeq(zs.reverse)
95+
}
96+
97+
def makeSeq(cond: (Node) => Boolean) =
98+
NodeSeq fromSeq (this flatMap (_.child) filter cond)
99+
100+
that match {
101+
case "_" => makeSeq(!_.isAtom)
102+
case _ if (that(0) == '@' && this.length == 1) => atResult
103+
case _ => makeSeq(_.label == that)
104+
}
128105
}
129106

130107
/** projection function. Similar to XPath, use <code>this \\ 'foo</code>
@@ -142,52 +119,13 @@ abstract class NodeSeq extends immutable.Sequence[Node] with SequenceTemplate[No
142119
* @param that ...
143120
* @return ...
144121
*/
145-
def \\ (that: String): NodeSeq = that match {
146-
case "_" =>
147-
var zs: List[Node] = Nil
148-
val it = this.iterator
149-
while (it.hasNext) {
150-
val x = it.next
151-
val jt = x.descendant_or_self.iterator
152-
while (jt.hasNext) {
153-
val y = jt.next
154-
if (y.typeTag$ != -1)
155-
zs = y::zs
156-
}
157-
}
158-
zs.reverse
159-
160-
case _ if that.charAt(0) == '@' =>
161-
var zs: List[Node] = Nil
162-
val it = this.iterator
163-
while (it.hasNext) {
164-
val x = it.next
165-
val jt = x.descendant_or_self.iterator
166-
while (jt.hasNext) {
167-
val y = jt.next
168-
if (y.typeTag$ != -1) {
169-
val kt = (y \ that).iterator
170-
while (kt.hasNext) {
171-
zs = (kt.next)::zs
172-
}
173-
}
174-
}
175-
}
176-
zs.reverse
177-
178-
case _ =>
179-
var zs: List[Node] = Nil
180-
val it = this.iterator
181-
while (it.hasNext) {
182-
val x = it.next
183-
val jt = x.descendant_or_self.iterator
184-
while (jt.hasNext) {
185-
val y = jt.next
186-
if (y.typeTag$ != -1 && y.label == that)
187-
zs = y::zs
188-
}
189-
}
190-
zs.reverse
122+
def \\ (that: String): NodeSeq = {
123+
def filt(cond: (Node) => Boolean) = this flatMap (_.descendant_or_self) filter cond
124+
that match {
125+
case "_" => filt(!_.isAtom)
126+
case _ if that(0) == '@' => filt(!_.isAtom) flatMap (_ \ that)
127+
case _ => filt(x => !x.isAtom && x.label == that)
128+
}
191129
}
192130

193131
override def toString(): String = theSeq.iterator.foldLeft ("") {

src/library/scala/xml/ProcInstr.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ case class ProcInstr(target:String, proctext:String) extends SpecialNode {
2424
else if (text.indexOf("?>") != -1)
2525
throw new IllegalArgumentException(proctext+" may not contain \"?>\"")
2626

27-
final override def typeTag$: Int = -2
27+
final override def collectNamespacesAndDontTransform = false
2828

2929
(target: Seq[Char]) match {
3030
case Seq('X'|'x','M'|'m','L'|'l') =>

src/library/scala/xml/Utility.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ object Utility extends AnyRef with parsing.TokenTests
2828
f(sb)
2929
sb.toString
3030
}
31-
private[xml] def isAtomAndNotText(x: Node) = x.isInstanceOf[Atom[_]] && !x.isInstanceOf[Text]
31+
private[xml] def isAtomAndNotText(x: Node) = x.isAtom && !x.isInstanceOf[Text]
3232

3333
// XXX this is very ham fisted at the moment
3434
class XMLOptions {
@@ -153,7 +153,7 @@ object Utility extends AnyRef with parsing.TokenTests
153153
* @param set ...
154154
*/
155155
def collectNamespaces(n: Node, set: Set[String]) {
156-
if (n.typeTag$ >= 0) {
156+
if (n.collectNamespacesAndDontTransform) {
157157
set += n.namespace
158158
for (a <- n.attributes) a match {
159159
case _:PrefixedAttribute =>

src/library/scala/xml/transform/BasicTransformer.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ abstract class BasicTransformer extends Function1[Node,Node] {
9898
}
9999

100100
def transform(n: Node): Seq[Node] = {
101-
if (n.typeTag$ < 0)
101+
if (!n.collectNamespacesAndDontTransform)
102102
n
103103
else {
104104
val ch = n.child

0 commit comments

Comments
 (0)