diff options
author | Som Snytt <som.snytt@gmail.com> | 2014-12-20 02:28:44 -0800 |
---|---|---|
committer | Som Snytt <som.snytt@gmail.com> | 2015-04-08 09:20:24 -0700 |
commit | 4df81aab315e587d9c7e319c7a2ece0f0f6fbaf3 (patch) | |
tree | d83454b666d54549d88f52bd800cddb66bd46041 /src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala | |
parent | 476eef82dfed90278de45739ca72819b1b4be5a4 (diff) | |
download | scala-4df81aab315e587d9c7e319c7a2ece0f0f6fbaf3.tar.gz scala-4df81aab315e587d9c7e319c7a2ece0f0f6fbaf3.tar.bz2 scala-4df81aab315e587d9c7e319c7a2ece0f0f6fbaf3.zip |
SI-3368 CDATA gets a Node
XML Parser uses `scala.xml.PCData`.
A compiler flag `-Yxml:coalescing`, analogous to
`DocumentBuilderFactory.setCoalescing`, turns `PCData`
nodes into `Text` nodes and coalesces sibling text nodes.
This change also fixes parse errors such as rejecting a
sequence of CDATA sections.
A sequence of "top level" nodes are not coalesced.
```
scala> <a><b/>start<![CDATA[hi & bye]]><c/>world<d/>stuff<![CDATA[red & black]]></a>
res0: scala.xml.Elem = <a><b/>start<![CDATA[hi & bye]]><c/>world<d/>stuff<![CDATA[red & black]]></a>
scala> :replay -Yxml:coalescing
Replaying: <a><b/>start<![CDATA[hi & bye]]><c/>world<d/>stuff<![CDATA[red & black]]></a>
res0: scala.xml.Elem = <a><b/>starthi & bye<c/>world<d/>stuffred & black</a>
```
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala')
-rwxr-xr-x | src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala index d2a999cdec..90610ab2e6 100755 --- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala @@ -36,6 +36,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { val _MetaData: NameType = "MetaData" val _NamespaceBinding: NameType = "NamespaceBinding" val _NodeBuffer: NameType = "NodeBuffer" + val _PCData: NameType = "PCData" val _PrefixedAttribute: NameType = "PrefixedAttribute" val _ProcInstr: NameType = "ProcInstr" val _Text: NameType = "Text" @@ -46,6 +47,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { private object xmlterms extends TermNames { val _Null: NameType = "Null" val __Elem: NameType = "Elem" + val _PCData: NameType = "PCData" val __Text: NameType = "Text" val _buf: NameType = "$buf" val _md: NameType = "$md" @@ -55,10 +57,15 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { val _xml: NameType = "xml" } - import xmltypes.{_Comment, _Elem, _EntityRef, _Group, _MetaData, _NamespaceBinding, _NodeBuffer, - _PrefixedAttribute, _ProcInstr, _Text, _Unparsed, _UnprefixedAttribute} + import xmltypes.{ + _Comment, _Elem, _EntityRef, _Group, _MetaData, _NamespaceBinding, _NodeBuffer, + _PCData, _PrefixedAttribute, _ProcInstr, _Text, _Unparsed, _UnprefixedAttribute + } + + import xmlterms.{ _Null, __Elem, __Text, _buf, _md, _plus, _scope, _tmpscope, _xml } - import xmlterms.{_Null, __Elem, __Text, _buf, _md, _plus, _scope, _tmpscope, _xml} + /** Attachment for trees deriving from text nodes (Text, CData, entities). Used for coalescing. */ + case class TextAttache(pos: Position, text: String) // convenience methods private def LL[A](x: A*): List[List[A]] = List(List(x:_*)) @@ -108,16 +115,22 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { final def entityRef(pos: Position, n: String) = atPos(pos)( New(_scala_xml_EntityRef, LL(const(n))) ) + private def coalescing = settings.YxmlSettings.isCoalescing + // create scala.xml.Text here <: scala.xml.Node final def text(pos: Position, txt: String): Tree = atPos(pos) { - if (isPattern) makeTextPat(const(txt)) - else makeText1(const(txt)) + val t = if (isPattern) makeTextPat(const(txt)) else makeText1(const(txt)) + if (coalescing) t updateAttachment TextAttache(pos, txt) else t } def makeTextPat(txt: Tree) = Apply(_scala_xml__Text, List(txt)) def makeText1(txt: Tree) = New(_scala_xml_Text, LL(txt)) def comment(pos: Position, text: String) = atPos(pos)( Comment(const(text)) ) - def charData(pos: Position, txt: String) = atPos(pos)( makeText1(const(txt)) ) + def charData(pos: Position, txt: String) = atPos(pos) { + val t = if (isPattern) Apply(_scala_xml(xmlterms._PCData), List(const(txt))) + else New(_scala_xml(_PCData), LL(const(txt))) + if (coalescing) t updateAttachment TextAttache(pos, txt) else t + } def procInstr(pos: Position, target: String, txt: String) = atPos(pos)( ProcInstr(const(target), const(txt)) ) |