diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-02-08 15:43:08 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-11-10 10:18:03 +1000 |
commit | 8d175b907d41323333a5613e419303f10beddc76 (patch) | |
tree | 3dff29c42d7ac22b0ef7a2cb7517bec99a94ee7c | |
parent | b431a4bd83d3bfb2b95d0426d2905b34ce1265ad (diff) | |
download | scala-8d175b907d41323333a5613e419303f10beddc76.tar.gz scala-8d175b907d41323333a5613e419303f10beddc76.tar.bz2 scala-8d175b907d41323333a5613e419303f10beddc76.zip |
SI-8253 Fix incorrect parsing of <elem xmlns={f("a")}/>
The spliced application was placed in the `attrMap` in
`SymbolicXMLBuilder` and later incorrectly matched by a pattern
intended only to match:
xml.Text(s)
That attribute value is generated by parsing:
<elem xmlns='a'/>
So the net effect was that the two fragments of XML were identical!
This commit sharpens up the match to really look for a syntactic
`_root_.scala.xml.Text("...")`.
The test just prints the parse trees of a variety of cases, as we
we should not test the modularized XML library in scala/scala.
-rwxr-xr-x | src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala | 3 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/StdNames.scala | 2 | ||||
-rw-r--r-- | test/files/run/t8253.check | 40 | ||||
-rw-r--r-- | test/files/run/t8253.scala | 14 |
4 files changed, 58 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala index 1abc0c860c..8cd915bf22 100755 --- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala @@ -184,7 +184,8 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) { ) val uri1 = attrMap(z) match { - case Apply(_, List(uri @ Literal(Constant(_)))) => mkAssign(uri) + case Apply(Select(New(Select(Select(Select(Ident(nme.ROOTPKG), nme.scala_), nme.xml), tpnme.Text)), nme.CONSTRUCTOR), List(uri @ Literal(Constant(_)))) => + mkAssign(uri) case Select(_, nme.Nil) => mkAssign(const(null)) // allow for xmlns="" -- bug #1626 case x => mkAssign(x) } diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index f2517fff54..667ff7c4b4 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -248,6 +248,7 @@ trait StdNames { final val Unliftable: NameType = "Unliftable" final val Name: NameType = "Name" final val Tree: NameType = "Tree" + final val Text: NameType = "Text" final val TermName: NameType = "TermName" final val Type : NameType = "Type" final val TypeName: NameType = "TypeName" @@ -778,6 +779,7 @@ trait StdNames { val values : NameType = "values" val wait_ : NameType = "wait" val withFilter: NameType = "withFilter" + val xml: NameType = "xml" val zero: NameType = "zero" // quasiquote interpolators: diff --git a/test/files/run/t8253.check b/test/files/run/t8253.check new file mode 100644 index 0000000000..0b4cb2d1f7 --- /dev/null +++ b/test/files/run/t8253.check @@ -0,0 +1,40 @@ + +<sample xmlns='ns1'/> +{ + var $tmpscope: _root_.scala.xml.NamespaceBinding = $scope; + $tmpscope = new _root_.scala.xml.NamespaceBinding(null, "ns1", $tmpscope); + { + val $scope: _root_.scala.xml.NamespaceBinding = $tmpscope; + new _root_.scala.xml.Elem(null, "sample", _root_.scala.xml.Null, $scope, true) + } +} + +<sample xmlns={identity(ns1)}/> +{ + var $tmpscope: _root_.scala.xml.NamespaceBinding = $scope; + $tmpscope = new _root_.scala.xml.NamespaceBinding(null, ns1, $tmpscope); + { + val $scope: _root_.scala.xml.NamespaceBinding = $tmpscope; + new _root_.scala.xml.Elem(null, "sample", _root_.scala.xml.Null, $scope, true) + } +} + +<sample xmlns:foo='ns1'/> +{ + var $tmpscope: _root_.scala.xml.NamespaceBinding = $scope; + $tmpscope = new _root_.scala.xml.NamespaceBinding("foo", "ns1", $tmpscope); + { + val $scope: _root_.scala.xml.NamespaceBinding = $tmpscope; + new _root_.scala.xml.Elem(null, "sample", _root_.scala.xml.Null, $scope, true) + } +} + +<sample xmlns:foo={identity(ns1)}/> +{ + var $tmpscope: _root_.scala.xml.NamespaceBinding = $scope; + $tmpscope = new _root_.scala.xml.NamespaceBinding("foo", ns1, $tmpscope); + { + val $scope: _root_.scala.xml.NamespaceBinding = $tmpscope; + new _root_.scala.xml.Elem(null, "sample", _root_.scala.xml.Null, $scope, true) + } +} diff --git a/test/files/run/t8253.scala b/test/files/run/t8253.scala new file mode 100644 index 0000000000..c4800b4491 --- /dev/null +++ b/test/files/run/t8253.scala @@ -0,0 +1,14 @@ +object Test extends App { + import reflect.runtime.universe._ // not using the XML library in compiler tests + + def show(code: String, t: Tree) = println(s"\n$code\n$t") + + val ns1 = "ns1" + show("<sample xmlns='ns1'/>", q"<sample xmlns='ns1'/>") + show("<sample xmlns={identity(ns1)}/>", q"<sample xmlns={ns1}/>") + show("<sample xmlns:foo='ns1'/>", q"<sample xmlns:foo='ns1'/>") + show("<sample xmlns:foo={identity(ns1)}/>", q"<sample xmlns:foo={ns1}/>") + + // `identity(foo)` used to match the overly permissive match in SymbolXMLBuilder + // which was intented to more specifically match `_root_.scala.xml.Text(...)` +} |