Skip to content

Commit b2bdff6

Browse files
committed
Use immtuable.Seq for attributes
1 parent 00bdef8 commit b2bdff6

13 files changed

+71
-28
lines changed

build.sbt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,40 @@ lazy val xml = crossProject(JSPlatform, JVMPlatform, NativePlatform)
7171
Seq( // exclusions for all Scala versions
7272
// new method in `Node` with return type `immutable.Seq`
7373
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.xml.Node.child"),
74+
7475
// these used to be declared methods, but are now bridges without generic signature
7576
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.Node.nonEmptyChildren"),
7677
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.Group.child"),
7778
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.SpecialNode.child"),
79+
80+
// new methods with return type immutable.Seq
81+
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.xml.Attribute.apply"),
82+
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.xml.Attribute.value"),
83+
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.xml.MetaData.apply"),
84+
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.xml.MetaData.value"),
85+
86+
// Synthetic static accessors (for Java interop) have a changed return type
87+
ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.xml.Null.apply"),
88+
ProblemFilters.exclude[IncompatibleResultTypeProblem]("scala.xml.Null.value"),
89+
90+
// used to be a declared method, now a bridge without generic signature
91+
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.MetaData.apply"),
92+
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.Null.apply"),
93+
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.Null.value"),
94+
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.PrefixedAttribute.apply"),
95+
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.PrefixedAttribute.value"),
96+
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.UnprefixedAttribute.apply"),
97+
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.UnprefixedAttribute.value"),
98+
99+
// Option[c.Seq] => Option[i.Seq] results in a changed generic signature
100+
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.MetaData.get"),
101+
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.Null.get"),
102+
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.Node.attribute"),
103+
104+
// trait Attribute now extends trait ScalaVersionSpecificMetaData to ensure the previous signatures
105+
// with return type `collection.Seq` remain valid.
106+
// (trait Attribute extends MetaData, but that parent is not present in bytecode because it's a class.)
107+
ProblemFilters.exclude[InheritedNewAbstractMethodProblem]("scala.xml.Attribute.apply"),
78108
) ++ (CrossVersion.partialVersion(scalaVersion.value) match {
79109
case Some((3, _)) => Seq( // Scala 3-specific exclusions
80110
)

shared/src/main/scala-2.12/scala/xml/ScalaVersionSpecific.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,6 @@ private[xml] trait ScalaVersionSpecificNodeBuffer { self: NodeBuffer =>
3434
override def stringPrefix: String = "NodeBuffer"
3535
}
3636

37-
private[xml] trait ScalaVersionSpecificNode {self: Node => }
37+
private[xml] trait ScalaVersionSpecificNode { self: Node => }
38+
39+
private[xml] trait ScalaVersionSpecificMetaData { self: MetaData => }

shared/src/main/scala-2.13+/scala/xml/ScalaVersionSpecific.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,11 @@ private[xml] trait ScalaVersionSpecificNode { self: Node =>
6060
def child: scala.collection.Seq[Node]
6161
def nonEmptyChildren: scala.collection.Seq[Node]
6262
}
63+
64+
private[xml] trait ScalaVersionSpecificMetaData { self: MetaData =>
65+
def apply(key: String): scala.collection.Seq[Node]
66+
def apply(namespace_uri: String, owner: Node, key: String): scala.collection.Seq[Node]
67+
def apply(namespace_uri: String, scp: NamespaceBinding, k: String): scala.collection.Seq[Node]
68+
69+
def value: scala.collection.Seq[Node]
70+
}

shared/src/main/scala-2/scala/xml/ScalaVersionSpecificReturnTypes.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ private[xml] object ScalaVersionSpecificReturnTypes { // should be
2828
type NullNext = scala.Null
2929
type NullKey = scala.Null
3030
type NullValue = scala.Null
31-
type NullApply1 = scala.collection.Seq[Node] // scala.Null
3231
type NullApply3 = scala.Null
3332
type NullRemove = Null.type
3433
type SpecialNodeChild = Nil.type

shared/src/main/scala-3/scala/xml/ScalaVersionSpecificReturnTypes.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,8 @@ private[xml] object ScalaVersionSpecificReturnTypes { // should be
2727
type NullGetNamespace = String // scala.Null
2828
type NullNext = MetaData // scala.Null
2929
type NullKey = String // scala.Null
30-
type NullValue = scala.collection.Seq[Node] // scala.Null
31-
type NullApply1 = scala.collection.Seq[Node] // scala.Null
32-
type NullApply3 = scala.collection.Seq[Node] // scala.Null
30+
type NullValue = scala.collection.immutable.Seq[Node] // scala.Null
31+
type NullApply3 = scala.collection.immutable.Seq[Node] // scala.Null
3332
type NullRemove = MetaData // Null.type
3433
type SpecialNodeChild = scala.collection.immutable.Seq[Node] // Nil.type
3534
type GroupChild = scala.collection.immutable.Seq[Node] // Nothing

shared/src/main/scala/scala/xml/Attribute.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,14 @@ object Attribute {
5353
*
5454
* @author Burak Emir
5555
*/
56-
trait Attribute extends MetaData {
56+
trait Attribute extends MetaData with ScalaVersionSpecificMetaData {
5757
def pre: String // will be null if unprefixed
5858
override val key: String
59-
override val value: Seq[Node]
59+
override val value: ScalaVersionSpecific.SeqOfNode
6060
override val next: MetaData
6161

62-
override def apply(key: String): Seq[Node]
63-
override def apply(namespace: String, scope: NamespaceBinding, key: String): Seq[Node]
62+
override def apply(key: String): ScalaVersionSpecific.SeqOfNode
63+
override def apply(namespace: String, scope: NamespaceBinding, key: String): ScalaVersionSpecific.SeqOfNode
6464
override def copy(next: MetaData): Attribute
6565

6666
override def remove(key: String): MetaData =

shared/src/main/scala/scala/xml/Elem.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ object Elem {
3030
def unapplySeq(n: Node): Option[(String, String, MetaData, NamespaceBinding, ScalaVersionSpecific.SeqOfNode)] =
3131
n match {
3232
case _: SpecialNode | _: Group => None
33-
case _ => Some((n.prefix, n.label, n.attributes, n.scope, n.child.toSeq))
33+
case _ => Some((n.prefix, n.label, n.attributes, n.scope, n.child))
3434
}
3535
}
3636

shared/src/main/scala/scala/xml/MetaData.scala

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ abstract class MetaData
8585
with Iterable[MetaData]
8686
with Equality
8787
with Serializable
88+
with ScalaVersionSpecificMetaData
8889
{
8990
private[xml] def isNull: Boolean = this.eq(Null)
9091

@@ -106,7 +107,7 @@ abstract class MetaData
106107
* @param key
107108
* @return value as Seq[Node] if key is found, null otherwise
108109
*/
109-
def apply(key: String): Seq[Node]
110+
def apply(key: String): ScalaVersionSpecific.SeqOfNode
110111

111112
/**
112113
* convenience method, same as `apply(namespace, owner.scope, key)`.
@@ -115,7 +116,7 @@ abstract class MetaData
115116
* @param owner the element owning this attribute list
116117
* @param key the attribute key
117118
*/
118-
final def apply(namespace_uri: String, owner: Node, key: String): Seq[Node] =
119+
final def apply(namespace_uri: String, owner: Node, key: String): ScalaVersionSpecific.SeqOfNode =
119120
apply(namespace_uri, owner.scope, key)
120121

121122
/**
@@ -126,7 +127,7 @@ abstract class MetaData
126127
* @param k to be looked for
127128
* @return value as Seq[Node] if key is found, null otherwise
128129
*/
129-
def apply(namespace_uri: String, scp: NamespaceBinding, k: String): Seq[Node]
130+
def apply(namespace_uri: String, scp: NamespaceBinding, k: String): ScalaVersionSpecific.SeqOfNode
130131

131132
/**
132133
* returns a copy of this MetaData item with next field set to argument.
@@ -168,7 +169,7 @@ abstract class MetaData
168169
def key: String
169170

170171
/** returns value of this MetaData item */
171-
def value: Seq[Node]
172+
def value: ScalaVersionSpecific.SeqOfNode
172173

173174
/**
174175
* Returns a String containing "prefix:key" if the first key is
@@ -194,10 +195,10 @@ abstract class MetaData
194195
* @param key
195196
* @return value in Some(Seq[Node]) if key is found, None otherwise
196197
*/
197-
final def get(key: String): Option[Seq[Node]] = Option(apply(key))
198+
final def get(key: String): Option[ScalaVersionSpecific.SeqOfNode] = Option(apply(key))
198199

199200
/** same as get(uri, owner.scope, key) */
200-
final def get(uri: String, owner: Node, key: String): Option[Seq[Node]] =
201+
final def get(uri: String, owner: Node, key: String): Option[ScalaVersionSpecific.SeqOfNode] =
201202
get(uri, owner.scope, key)
202203

203204
/**
@@ -208,7 +209,7 @@ abstract class MetaData
208209
* @param key to be looked fore
209210
* @return value as `Some[Seq[Node]]` if key is found, None otherwise
210211
*/
211-
final def get(uri: String, scope: NamespaceBinding, key: String): Option[Seq[Node]] =
212+
final def get(uri: String, scope: NamespaceBinding, key: String): Option[ScalaVersionSpecific.SeqOfNode] =
212213
Option(apply(uri, scope, key))
213214

214215
protected def toString1: String = sbToString(toString1)

shared/src/main/scala/scala/xml/Node.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ object Node {
2929
val EmptyNamespace: String = ""
3030

3131
def unapplySeq(n: Node): Some[(String, MetaData, ScalaVersionSpecific.SeqOfNode)] =
32-
Some((n.label, n.attributes, n.child.toSeq))
32+
Some((n.label, n.attributes, n.child))
3333
}
3434

3535
/**
@@ -92,7 +92,7 @@ abstract class Node extends NodeSeq with ScalaVersionSpecificNode {
9292
* @return value of `UnprefixedAttribute` with given key
9393
* in attributes, if it exists, otherwise `null`.
9494
*/
95-
final def attribute(key: String): Option[Seq[Node]] = attributes.get(key)
95+
final def attribute(key: String): Option[ScalaVersionSpecific.SeqOfNode] = attributes.get(key)
9696

9797
/**
9898
* Convenience method, looks up a prefixed attribute in attributes of this node.
@@ -103,7 +103,7 @@ abstract class Node extends NodeSeq with ScalaVersionSpecificNode {
103103
* @return value of `PrefixedAttribute` with given namespace
104104
* and given key, otherwise `'''null'''`.
105105
*/
106-
final def attribute(uri: String, key: String): Option[Seq[Node]] =
106+
final def attribute(uri: String, key: String): Option[ScalaVersionSpecific.SeqOfNode] =
107107
attributes.get(uri, this, key)
108108

109109
/**

shared/src/main/scala/scala/xml/Null.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ case object Null extends MetaData {
4949
override protected def basisForHashCode: Seq[Any] = Nil
5050

5151
override def apply(namespace: String, scope: NamespaceBinding, key: String): ScalaVersionSpecificReturnTypes.NullApply3 = null
52-
override def apply(key: String): ScalaVersionSpecificReturnTypes.NullApply1 =
52+
override def apply(key: String): ScalaVersionSpecific.SeqOfNode =
5353
if (Utility.isNameStart(key.head)) null
5454
else throw new IllegalArgumentException(s"not a valid attribute name '$key', so can never match !")
5555

shared/src/main/scala/scala/xml/PrefixedAttribute.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ import scala.collection.Seq
2727
class PrefixedAttribute(
2828
override val pre: String,
2929
override val key: String,
30-
override val value: Seq[Node],
30+
_value: Seq[Node],
3131
val next1: MetaData
3232
)
3333
extends Attribute
3434
{
35+
override val value: ScalaVersionSpecific.SeqOfNode = if (_value == null) null else _value.toSeq
36+
3537
override val next: MetaData = if (value != null) next1 else next1.remove(key)
3638

3739
/** same as this(pre, key, Text(value), next), or no attribute if value is null */
@@ -53,12 +55,12 @@ class PrefixedAttribute(
5355
owner.getNamespace(pre)
5456

5557
/** forwards the call to next (because caller looks for unprefixed attribute */
56-
override def apply(key: String): Seq[Node] = next(key)
58+
override def apply(key: String): ScalaVersionSpecific.SeqOfNode = next(key)
5759

5860
/**
5961
* gets attribute value of qualified (prefixed) attribute with given key
6062
*/
61-
override def apply(namespace: String, scope: NamespaceBinding, key: String): Seq[Node] =
63+
override def apply(namespace: String, scope: NamespaceBinding, key: String): ScalaVersionSpecific.SeqOfNode =
6264
if (key == this.key && scope.getURI(pre) == namespace)
6365
value
6466
else

shared/src/main/scala/scala/xml/QNode.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ package xml
2121
*/
2222
object QNode {
2323
def unapplySeq(n: Node): Some[(String, String, MetaData, ScalaVersionSpecific.SeqOfNode)] =
24-
Some((n.scope.getURI(n.prefix), n.label, n.attributes, n.child.toSeq))
24+
Some((n.scope.getURI(n.prefix), n.label, n.attributes, n.child))
2525
}

shared/src/main/scala/scala/xml/UnprefixedAttribute.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ import scala.collection.Seq
2323
// Note: used by the Scala compiler.
2424
class UnprefixedAttribute(
2525
override val key: String,
26-
override val value: Seq[Node],
26+
_value: Seq[Node],
2727
next1: MetaData
2828
)
2929
extends Attribute
3030
{
31+
override val value: ScalaVersionSpecific.SeqOfNode = if (_value == null) null else _value.toSeq
32+
3133
final override val pre: scala.Null = null
3234
override val next: MetaData = if (value != null) next1 else next1.remove(key)
3335

@@ -50,7 +52,7 @@ class UnprefixedAttribute(
5052
* @param key
5153
* @return value as Seq[Node] if key is found, null otherwise
5254
*/
53-
override def apply(key: String): Seq[Node] =
55+
override def apply(key: String): ScalaVersionSpecific.SeqOfNode =
5456
if (key == this.key) value else next(key)
5557

5658
/**
@@ -61,7 +63,7 @@ class UnprefixedAttribute(
6163
* @param key
6264
* @return ..
6365
*/
64-
override def apply(namespace: String, scope: NamespaceBinding, key: String): Seq[Node] =
66+
override def apply(namespace: String, scope: NamespaceBinding, key: String): ScalaVersionSpecific.SeqOfNode =
6567
next(namespace, scope, key)
6668
}
6769
object UnprefixedAttribute {

0 commit comments

Comments
 (0)