Skip to content

Commit 1fc27df

Browse files
committed
fix(#16459): cannot parse text in xml literal with newline
The parser could not parse `if expr` that contains single-quoted text(s) inside XML literal with newline(s) because `followedByToken`, which is used to detect `do` or `then` token after `if`, unintentionally consumed XMLSTART symbol, which prevented the parser from delegating parse to XML parser.
1 parent fff24b1 commit 1fc27df

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+1
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,7 @@ object Parsers {
906906
var braces = 0
907907
while (true) {
908908
val token = lookahead.token
909+
if (token == XMLSTART) return false
909910
if (braces == 0) {
910911
if (token == query) return true
911912
if (stopScanTokens.contains(token) || lookahead.isNestedEnd) return false

tests/run/i16459.scala

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
object Test {
2+
import scala.xml.*
3+
def main(args: Array[String]): Unit = {
4+
5+
val xml = if(true) {
6+
<script type="text/javascript">
7+
'location.reload()'
8+
'foo bar'
9+
</script>
10+
} else <div>empty</div>
11+
12+
assert(
13+
xml match
14+
case elm: Elem if
15+
elm.label == "script"
16+
&& elm.child.length == 1
17+
&& elm.child(0) == Atom(Text("\n 'location.reload()'\n 'foo bar'\n "))
18+
=> true
19+
case _ => false
20+
,
21+
xml
22+
)
23+
}
24+
}
25+
26+
package scala.xml {
27+
type MetaData = AnyRef
28+
29+
class UnprefixedAttribute(
30+
val key: String,
31+
val value: Text,
32+
next1: MetaData
33+
) extends MetaData
34+
35+
trait NamespaceBinding
36+
object TopScope extends NamespaceBinding
37+
object Null
38+
abstract class Node {
39+
def label: String
40+
def child: Seq[Node]
41+
override def toString = label + child.mkString
42+
}
43+
class Comment(commentText: String) extends Node{
44+
def label = commentText
45+
def child = Nil
46+
}
47+
class Elem(prefix: String, val label: String, attributes1: MetaData, scope: NamespaceBinding, minimizeEmpty: Boolean, val child: Node*) extends Node
48+
class NodeBuffer extends Seq[Node] {
49+
val nodes = scala.collection.mutable.ArrayBuffer.empty[Node]
50+
def &+(o: Any): NodeBuffer = o match {
51+
case n: Node => nodes.addOne(n) ; this
52+
case t: Text => nodes.addOne(Atom(t)) ; this
53+
}
54+
// Members declared in scala.collection.IterableOnce
55+
def iterator: Iterator[scala.xml.Node] = nodes.iterator
56+
// Members declared in scala.collection.SeqOps
57+
def apply(i: Int): scala.xml.Node = nodes(i)
58+
def length: Int = nodes.length
59+
}
60+
case class Text(text: String)
61+
case class Atom(t: Text) extends Node {
62+
def label = t.text
63+
def child = Nil
64+
}
65+
}

0 commit comments

Comments
 (0)