summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/list/library.lst1
-rw-r--r--sources/scala/tools/scalac/ast/parser/MarkupParser.scala81
-rw-r--r--sources/scala/xml/NodeBuffer.scala21
-rw-r--r--test/files/jvm/xmlLiterals.scala6
-rw-r--r--test/files/jvm/xmlstuff.check1
-rw-r--r--test/files/jvm/xmlstuff.scala8
6 files changed, 88 insertions, 30 deletions
diff --git a/config/list/library.lst b/config/list/library.lst
index f4688e0397..363632672e 100644
--- a/config/list/library.lst
+++ b/config/list/library.lst
@@ -163,6 +163,7 @@ xml/ExternalID.scala
xml/EntityRef.scala
xml/FactoryAdapter.scala
xml/Node.scala
+xml/NodeBuffer.scala
xml/NodeSeq.scala
xml/PrettyPrinter.scala
xml/ProcInstr.scala
diff --git a/sources/scala/tools/scalac/ast/parser/MarkupParser.scala b/sources/scala/tools/scalac/ast/parser/MarkupParser.scala
index a33e7fc810..9505475552 100644
--- a/sources/scala/tools/scalac/ast/parser/MarkupParser.scala
+++ b/sources/scala/tools/scalac/ast/parser/MarkupParser.scala
@@ -25,6 +25,7 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
import scala.tools.scalac.ast.{TreeList => myTreeList}
val _ArrayBuffer = Name.fromString("ArrayBuffer");
+ val _NodeBuffer = Name.fromString("NodeBuffer");
val _TreeMap = Name.fromString("TreeMap");
val _Elem = Name.fromString("Elem");
val _Seq = Name.fromString("Seq");
@@ -32,6 +33,7 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
val _immutable = Name.fromString("immutable");
val _mutable = Name.fromString("mutable");
val _append = Name.fromString("append");
+ val _plus = Name.fromString("$plus");
val _collection = Name.fromString("collection");
val _xml = Name.fromString("xml");
val _Comment = Name.fromString("Comment");
@@ -75,6 +77,8 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
private def _scala_xml_Node( pos: int ) =
_scala_xml( pos, _Node );
+ private def _scala_xml_NodeBuffer( pos: int ) =
+ p.convertToConstr( _scala_xml( pos, _NodeBuffer ));
private def _scala_xml_EntityRef( pos: int ) =
p.convertToConstr( _scala_xml( pos, _EntityRef ));
@@ -89,7 +93,7 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
p.convertToConstr( _scala_xml( pos, _ProcInstr ));
private def _scala_xml_Text( pos: int ) =
- p.convertToConstr( _scala_xml( pos, _Text ));
+ _scala_xml( pos, _Text );
private def _scala_collection( pos: int, name: Name ) =
@@ -151,7 +155,7 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
val ts = new myTreeList();
ts.append( t );
ts.append( new Tree$Ident( Names.PATTERN_WILDCARD ) );
- ts.append( convertToText( args ) );
+ ts.append( convertToText( true, args ) );
make.Apply(pos,
convertToTypeId( _scala_xml_Elem( pos ) ),
ts.toArray())
@@ -174,9 +178,33 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
make.New( pos, constr );
};
// create scala.xml.Text here <: scala.xml.Node
- def makeText( pos: int, txt:String ):Tree = {
- makeText( pos, gen.mkStringLit( pos, txt ));
+ def makeText( pos: int, isPattern:Boolean, txt:String ):Tree = {
+ makeText( pos, isPattern, gen.mkStringLit( pos, txt ));
}
+
+ // create scala.xml.Text here <: scala.xml.Node
+ def makeText( pos: int, isPattern:Boolean, txt:Tree ):Tree = {
+ if( isPattern )
+ makeTextPat( pos, txt );
+ else
+ makeText1( pos, txt );
+ }
+
+ // create scala.xml.Text here <: scala.xml.Node
+ def makeTextPat( pos: int, txt:Tree ):Tree = {
+ return make.Apply(pos,
+ p.convertToConstr( _scala_xml_Text( pos ) ),
+ Predef.Array[Tree]( txt ));
+ }
+
+ def makeText1( pos: int, txt:Tree ):Tree = {
+ val constr = make.Apply(pos,
+ p.convertToConstr( _scala_xml_Text( pos )),
+ Predef.Array[Tree]( txt ));
+ make.New( pos, constr );
+ }
+
+
// create
def makeComment( pos: int, comment:scala.xml.Comment ):Tree =
makeComment( pos, gen.mkStringLit( pos, comment.text ));
@@ -207,11 +235,10 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
make.New( pos, constr );
}
-
- def makeText( pos: int, txt:Tree ):Tree = {
+ def makeNodeBuffer( pos: int ):Tree = {
val constr = make.Apply( pos,
- _scala_xml_Text( pos ),
- Predef.Array[Tree] ( txt ));
+ _scala_xml_NodeBuffer( pos ),
+ Tree.EMPTY_ARRAY);
make.New( pos, constr );
}
@@ -243,24 +270,24 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
def makeXML(pos:int, n:Name, args:Array[Tree]):Tree =
mkXML(pos, false, gen.mkStringLit( pos, n.toString() ), args);
- def convertToText( t:Tree ) = t match {
- case _:Tree$Literal => makeText( t.pos, t );
+ def convertToText(isPattern:Boolean, t:Tree):Tree = t match {
+ case _:Tree$Literal => makeText(t.pos, isPattern, t);
case _ => t
}
- def convertToText( ts:Array[Tree] ) = {
+ def convertToText( isPattern:Boolean, ts:Array[Tree] ):Array[Tree] = {
var res:Array[Tree] = null;
var i = 0; while( i < ts.length ) {
- ts( i ) match {
- case _:Tree$Literal =>
+ val t1 = ts( i );
+ val t2 = convertToText( isPattern, t1 );
+ if (!t1.eq(t2)) {
if( null == res ) { // lazy copy
res = new Array[Tree]( ts.length );
System.arraycopy( ts, 0, res, 0, i );
}
- res( i ) = makeText( ts( i ).pos, ts( i ) );
- case _ =>
- }
- i = i + 1
+ res( i ) = t2;
+ }
+ i = i + 1;
}
if( null == res ) ts else res;
}
@@ -272,20 +299,22 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
def makeXMLseq( pos:int, args:Array[Tree] ) = {
val ts = new TreeList();
//val blocArr = new Array[Tree] ( 1 + args.length );
- val constr = _scala_collection_mutable_ArrayBuffer( pos );
+ //val constr = _scala_collection_mutable_ArrayBuffer( pos );
+ val _buffer = makeNodeBuffer( pos );
val n = p.fresh();
val nIdent = make.Ident(pos, n);
//blocArr( 0 )
- ts.append( make.ValDef(pos, Modifiers.MUTABLE, n, Tree.Empty,
- make.New( pos, constr )));
+ ts.append( make.ValDef(pos,
+ 0, n, Tree.Empty,
+ _buffer));
var i = 0; while( i < args.length ) {
val ipos = args(i).pos;
if( !isEmptyText( args( i ))) {
ts.append(
make.Apply( ipos,
- make.Select( ipos, nIdent, _append ),
- Predef.Array[Tree]( convertToText( args( i ) )))
+ make.Select( ipos, nIdent, _plus /*_append*/ ),
+ Predef.Array[Tree]( convertToText(false, args( i ) )))
)
}
i = i + 1;
@@ -470,7 +499,7 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
var text = s.xText;
if( !preserveWS ) text = trimWS( text );
str.append( text );
- ts.append( makeText( s.pos, str.toString() ));
+ ts.append( makeText( s.pos, false, str.toString() ));
}
// postcond: s.xScalaBlock == false!
case '&' => // EntityRef or CharRef
@@ -478,7 +507,7 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
s.ch match {
case '#' => // CharacterRef
s.xNext;
- val theChar = makeText( s.pos, s.xCharRef );
+ val theChar = makeText( s.pos, false, s.xCharRef );
s.xToken(';');
ts.append( theChar);
case _ => // EntityRef
@@ -491,7 +520,7 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
var text = s.xText;
if( !preserveWS ) text = trimWS( text );
if( text.length() > 0 )
- ts.append( makeText( s.pos, text ));
+ ts.append( makeText( s.pos, false, text ));
// here s.xScalaBlock might be true
}
@@ -578,7 +607,7 @@ class MarkupParser( unit:Unit, s:Scanner, p:Parser, preserveWS:boolean ) {
var text = s.xText;
if( !preserveWS ) text = trimWS( text );
if( text.length() > 0 )
- ts.append( makeText( pos1, text ));
+ ts.append( makeText( pos1, true, text ));
// here s.xScalaBlock might be true;
//if( s.xScalaBlock ) throw new ApplicationError("after:"+text); // assert
}
diff --git a/sources/scala/xml/NodeBuffer.scala b/sources/scala/xml/NodeBuffer.scala
new file mode 100644
index 0000000000..732cc36b8c
--- /dev/null
+++ b/sources/scala/xml/NodeBuffer.scala
@@ -0,0 +1,21 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2004, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+** $Id$
+\* */
+
+package scala.xml ;
+
+/** this class acts as a Buffer for nodes. If it is used as a sequence
+ * of nodes Seq[Node], it must be ensured that no updates occur after
+ * that point, because scala.xml.Node is assumed to be immutable.
+ */
+class NodeBuffer extends scala.collection.mutable.ArrayBuffer[Node] {
+
+ override def +(n:Node):NodeBuffer = { super.+( n ); this }
+ def +(ns:Seq[Node]):NodeBuffer = { super.++( ns ); this }
+
+}
diff --git a/test/files/jvm/xmlLiterals.scala b/test/files/jvm/xmlLiterals.scala
index f3ee124d33..c751a5c8a7 100644
--- a/test/files/jvm/xmlLiterals.scala
+++ b/test/files/jvm/xmlLiterals.scala
@@ -160,7 +160,7 @@ object Test03Servlet {
{headerMsg }
</p>
<p>
- { ns:_* }
+ { ns }
</p>
<hr/>
<p>
@@ -179,10 +179,10 @@ object Test03Servlet {
*/
def beautify( n:Node ):Node = n match {
case <td>{xs @ _* }</td> =>
- <td bgcolor="#AAAAFF" color="#222255">{ xs:_* }</td>
+ <td bgcolor="#AAAAFF" color="#222255">{ xs }</td>
case <table>{ xs @ _* }</table> =>
- <table align="center">{ beautify( xs ):_*}</table>
+ <table align="center">{ beautify( xs )}</table>
case Elem( label, _, xs @ _* ) =>
new Elem( label, beautify( xs ):_*)
diff --git a/test/files/jvm/xmlstuff.check b/test/files/jvm/xmlstuff.check
index 9429214ffe..f8bab77aac 100644
--- a/test/files/jvm/xmlstuff.check
+++ b/test/files/jvm/xmlstuff.check
@@ -30,3 +30,4 @@ passed ok
<title>Blubabla</title>
<remarks>rem 2</remarks>
</result>
+List(<book><title>Blabla</title></book>)
diff --git a/test/files/jvm/xmlstuff.scala b/test/files/jvm/xmlstuff.scala
index 3e482e62b1..95295838af 100644
--- a/test/files/jvm/xmlstuff.scala
+++ b/test/files/jvm/xmlstuff.scala
@@ -226,8 +226,14 @@ object Test with Application {
r \ "title" == t) yield
<result>
{ t }
- { (r \ "remarks"):_* }
+ { r \ "remarks" }
</result>
));
+ // example
+ Console.println(
+ for( val t @ <book><title>Blabla</title></book> <- new NodeSeq( books.child ).asList)
+ yield t
+ );
+
}