Skip to content

Commit

Permalink
fix(#16459): cannot parse text in xml literal with newline
Browse files Browse the repository at this point in the history
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.

[Cherry-picked 1fc27df]
  • Loading branch information
i10416 authored and WojciechMazur committed Jun 28, 2024
1 parent 6976d59 commit cb777e2
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,7 @@ object Parsers {
var braces = 0
while (true) {
val token = lookahead.token
if (token == XMLSTART) return false
if (braces == 0) {
if (token == query) return true
if (stopScanTokens.contains(token) || lookahead.isNestedEnd) return false
Expand Down
65 changes: 65 additions & 0 deletions tests/run/i16459.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
object Test {
import scala.xml.*
def main(args: Array[String]): Unit = {

val xml = if(true) {
<script type="text/javascript">
'location.reload()'
'foo bar'
</script>
} else <div>empty</div>

assert(
xml match
case elm: Elem if
elm.label == "script"
&& elm.child.length == 1
&& elm.child(0) == Atom(Text("\n 'location.reload()'\n 'foo bar'\n "))
=> true
case _ => false
,
xml
)
}
}

package scala.xml {
type MetaData = AnyRef

class UnprefixedAttribute(
val key: String,
val value: Text,
next1: MetaData
) extends MetaData

trait NamespaceBinding
object TopScope extends NamespaceBinding
object Null
abstract class Node {
def label: String
def child: Seq[Node]
override def toString = label + child.mkString
}
class Comment(commentText: String) extends Node{
def label = commentText
def child = Nil
}
class Elem(prefix: String, val label: String, attributes1: MetaData, scope: NamespaceBinding, minimizeEmpty: Boolean, val child: Node*) extends Node
class NodeBuffer extends Seq[Node] {
val nodes = scala.collection.mutable.ArrayBuffer.empty[Node]
def &+(o: Any): NodeBuffer = o match {
case n: Node => nodes.addOne(n) ; this
case t: Text => nodes.addOne(Atom(t)) ; this
}
// Members declared in scala.collection.IterableOnce
def iterator: Iterator[scala.xml.Node] = nodes.iterator
// Members declared in scala.collection.SeqOps
def apply(i: Int): scala.xml.Node = nodes(i)
def length: Int = nodes.length
}
case class Text(text: String)
case class Atom(t: Text) extends Node {
def label = t.text
def child = Nil
}
}

0 comments on commit cb777e2

Please sign in to comment.