diff options
-rw-r--r-- | config/list/library.lst | 1 | ||||
-rw-r--r-- | sources/scala/tools/scalac/ast/parser/MarkupParser.scala | 81 | ||||
-rw-r--r-- | sources/scala/xml/NodeBuffer.scala | 21 | ||||
-rw-r--r-- | test/files/jvm/xmlLiterals.scala | 6 | ||||
-rw-r--r-- | test/files/jvm/xmlstuff.check | 1 | ||||
-rw-r--r-- | test/files/jvm/xmlstuff.scala | 8 |
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 + ); + } |