Skip to content

Commit f716ea6

Browse files
committed
Use toVector` for XML literal sequences
In `<a><b/><c/><a>`, a `NodeBuffer` (which extends `ArrayBuffer`) is used to accumulate the children. The buffer is passed to `new Elem($buf: _*)`, which only works thanks to the implicit `collection.Seq[Node] => NodeSeq` declared in scala-xml. With `-Vprint:typer`: ```scala scala> <a><b/></a> [[syntax trees at end of typer]] // rs$line$1 val res0: scala.xml.Elem ={new _root_.scala.xml.Elem(null, "a", _root_.scala.xml.Null, scala.xml.TopScope, false,{val $buf: scala.xml.NodeBuffer = new _root_.scala.xml.NodeBuffer() $buf.&+({{new _root_.scala.xml.Elem(null, "b", _root_.scala.xml.Null, scala.xml.TopScope, true, [ : scala.xml.Node]*) } } ) scala.xml.NodeSeq.seqToNodeSeq($buf) }* ) } ``` The implicit was not inserted in 2.12 because the varargs parameter of Elem accepted a `collection.Seq`.
1 parent d5ca220 commit f716ea6

File tree

2 files changed

+15
-7
lines changed

2 files changed

+15
-7
lines changed

‎compiler/src/dotty/tools/dotc/parsing/xml/SymbolicXMLBuilder.scala‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@ class SymbolicXMLBuilder(parser: Parser, preserveWS: Boolean)(using Context){
4242
val_Group:TypeName="Group"
4343
val_MetaData:TypeName="MetaData"
4444
val_NamespaceBinding:TypeName="NamespaceBinding"
45+
val_Node:TypeName="Node"
4546
val_NodeBuffer:TypeName="NodeBuffer"
4647
val_PrefixedAttribute:TypeName="PrefixedAttribute"
4748
val_ProcInstr:TypeName="ProcInstr"
4849
val_Text:TypeName="Text"
4950
val_Unparsed:TypeName="Unparsed"
5051
val_UnprefixedAttribute:TypeName="UnprefixedAttribute"
52+
val_Seq:TypeName="Seq"
5153
}
5254

5355
privateobjectxmltermsextendsScalaTermNames{
@@ -59,12 +61,13 @@ class SymbolicXMLBuilder(parser: Parser, preserveWS: Boolean)(using Context){
5961
val_plus:TermName="&+"
6062
val_tmpscope:TermName="$tmpscope"
6163
val_xml:TermName="xml"
64+
val_toVector:TermName="toVector"
6265
}
6366

64-
importxmltypes.{_Comment, _Elem, _EntityRef, _Group, _MetaData, _NamespaceBinding, _NodeBuffer,
65-
_PrefixedAttribute, _ProcInstr, _Text, _Unparsed, _UnprefixedAttribute}
67+
importxmltypes.{_Comment, _Elem, _EntityRef, _Group, _MetaData, _NamespaceBinding, _NodeBuffer,_Node,
68+
_PrefixedAttribute, _ProcInstr, _Text, _Unparsed, _UnprefixedAttribute, _Seq}
6669

67-
importxmlterms.{_Null, __Elem, __Text, _buf, _md, _plus, _scope, _tmpscope, _xml}
70+
importxmlterms.{_Null, __Elem, __Text, _buf, _md, _plus, _scope, _tmpscope, _xml, _toVector}
6871

6972
// convenience methods
7073
privatedefLL[A](x: A*):List[List[A]] =List(x.toList)
@@ -89,6 +92,7 @@ class SymbolicXMLBuilder(parser: Parser, preserveWS: Boolean)(using Context){
8992
privatedef_scala_xml_UnprefixedAttribute= _scala_xml(_UnprefixedAttribute)
9093
privatedef_scala_xml__Elem= _scala_xml(__Elem)
9194
privatedef_scala_xml__Text= _scala_xml(__Text)
95+
privatedef_scala_Seq_Node=AppliedTypeTree(_scala(_Seq), List(_scala_xml(_Node)))
9296

9397
/** Wildly wrong documentation deleted in favor of "self-documenting code." */
9498
protecteddefmkXML(
@@ -166,7 +170,7 @@ class SymbolicXMLBuilder(parser: Parser, preserveWS: Boolean)(using Context){
166170
valbuffer=ValDef(_buf, TypeTree(), New(_scala_xml_NodeBuffer, ListOfNil))
167171
valapplies= args filterNot isEmptyText map (t =>Apply(Select(Ident(_buf), _plus), List(t)))
168172

169-
atSpan(span)(newXMLBlock(buffer :: applies.toList, Ident(_buf)) )
173+
atSpan(span)(newXMLBlock(buffer :: applies.toList, Typed(Select(Ident(_buf), _toVector), _scala_Seq_Node)))
170174
}
171175

172176
/** Returns (Some(prefix) | None, rest) based on position of ':' */

‎tests/run/xml.scala‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11

22
objectTest{
3-
importscala.xml.NodeBuffer
3+
importscala.xml._
44

55
defmain(args: Array[String]):Unit={
66
valxml= <hello>world</hello>
77
assert(xml.toString =="helloworld")
8-
valnodeBuffer:NodeBuffer= <hello/><world/>
9-
assert(nodeBuffer.mkString =="helloworld")
8+
valsq:Seq[Node] = <hello/><world/>
9+
assert(sq.mkString =="helloworld")
10+
assert(sq.isInstanceOf[Vector[_]]) // implementation detail
11+
12+
valsubSq:Node= <a><b/><c/></a>
13+
assert(subSq.child.toString =="Vector(b, c)") // implementation detail
1014
}
1115
}
1216
packagescala.xml{

0 commit comments

Comments
(0)