Skip to content

Commit 08e6c71

Browse files
committed
Change Node.child return type to immutable.Seq on 2.13+
Change the type of `Node.child` and `Node.nonEmptyChildren` from `collection.Seq` to `immutable.Seq` in 2.13+. A parent is added to `Node` which defines the old signatures for `child` / `nonEmptyChildren`. This (and the resulting bridge methods) ensures binary compatbility.
1 parent b4b0269 commit 08e6c71

File tree

5 files changed

+38
-18
lines changed

5 files changed

+38
-18
lines changed

build.sbt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType}
1+
import com.typesafe.tools.mima.core._
2+
import sbtcrossproject.CrossPlugin.autoImport.{CrossType, crossProject}
23

34
publish / skip := true // root project
45

@@ -68,6 +69,12 @@ lazy val xml = crossProject(JSPlatform, JVMPlatform, NativePlatform)
6869
//import com.typesafe.tools.mima.core.{}
6970
//import com.typesafe.tools.mima.core.ProblemFilters
7071
Seq( // exclusions for all Scala versions
72+
// new method in `Node` with return type `immutable.Seq`
73+
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.xml.Node.child"),
74+
// these used to be declared methods, but are now a bridges without generic signature
75+
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.Node.nonEmptyChildren"),
76+
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.Group.child"),
77+
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.SpecialNode.child"),
7178
) ++ (CrossVersion.partialVersion(scalaVersion.value) match {
7279
case Some((3, _)) => Seq( // Scala 3-specific exclusions
7380
)

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ private[xml] object ScalaVersionSpecific {
2323
override def apply(): mutable.Builder[Node, NodeSeq] = NodeSeq.newBuilder
2424
}
2525
type SeqNodeUnapplySeq = scala.collection.Seq[Node]
26+
27+
type ChildReturnType = scala.collection.Seq[Node]
2628
}
2729

2830
private[xml] trait ScalaVersionSpecificNodeSeq extends SeqLike[Node, NodeSeq] { self: NodeSeq =>
@@ -33,3 +35,5 @@ private[xml] trait ScalaVersionSpecificNodeSeq extends SeqLike[Node, NodeSeq] {
3335
private[xml] trait ScalaVersionSpecificNodeBuffer { self: NodeBuffer =>
3436
override def stringPrefix: String = "NodeBuffer"
3537
}
38+
39+
private[xml] trait ScalaVersionSpecificNode {self: Node => }

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ private[xml] object ScalaVersionSpecific {
2525
def fromSpecific(from: Coll)(it: IterableOnce[Node]): NodeSeq = (NodeSeq.newBuilder ++= from).result()
2626
}
2727
type SeqNodeUnapplySeq = scala.collection.immutable.Seq[Node]
28+
29+
type ChildReturnType = scala.collection.immutable.Seq[Node]
2830
}
2931

3032
private[xml] trait ScalaVersionSpecificNodeSeq
@@ -53,3 +55,10 @@ private[xml] trait ScalaVersionSpecificNodeSeq
5355
private[xml] trait ScalaVersionSpecificNodeBuffer { self: NodeBuffer =>
5456
override def className: String = "NodeBuffer"
5557
}
58+
59+
private[xml] trait ScalaVersionSpecificNode { self: Node =>
60+
// These methods are overridden in Node with return type `immutable.Seq`. The declarations here result
61+
// in a bridge method in `Node` with result type `collection.Seq` which is needed for binary compatibility.
62+
def child: scala.collection.Seq[Node]
63+
def nonEmptyChildren: scala.collection.Seq[Node]
64+
}

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

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,18 @@ package scala.xml
1919
What should have been specified explicitly is given in the comments;
2020
next time we break binary compatibility the types should be changed in the code and this class removed.
2121
*/
22-
private[xml] object ScalaVersionSpecificReturnTypes { // should be
23-
type ExternalIDAttribute = MetaData // Null.type
24-
type NoExternalIDId = String // scala.Null
25-
type NodeNoAttributes = MetaData // Null.type
26-
type NullFilter = MetaData // Null.type
27-
type NullGetNamespace = String // scala.Null
28-
type NullNext = MetaData // scala.Null
29-
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
33-
type NullRemove = MetaData // Null.type
34-
type SpecialNodeChild = scala.collection.Seq[Node] // Nil.type
35-
type GroupChild = scala.collection.Seq[Node] // Nothing
22+
private[xml] object ScalaVersionSpecificReturnTypes { // should be
23+
type ExternalIDAttribute = MetaData // Null.type
24+
type NoExternalIDId = String // scala.Null
25+
type NodeNoAttributes = MetaData // Null.type
26+
type NullFilter = MetaData // Null.type
27+
type NullGetNamespace = String // scala.Null
28+
type NullNext = MetaData // scala.Null
29+
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
33+
type NullRemove = MetaData // Null.type
34+
type SpecialNodeChild = scala.collection.immutable.Seq[Node] // Nil.type
35+
type GroupChild = scala.collection.immutable.Seq[Node] // Nothing
3636
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ object Node {
4545
*
4646
* @author Burak Emir and others
4747
*/
48-
abstract class Node extends NodeSeq {
48+
abstract class Node extends NodeSeq with ScalaVersionSpecificNode {
4949

5050
/** prefix of this node */
5151
def prefix: String = null
@@ -120,12 +120,12 @@ abstract class Node extends NodeSeq {
120120
*
121121
* @return all children of this node
122122
*/
123-
def child: Seq[Node]
123+
def child: ScalaVersionSpecific.ChildReturnType
124124

125125
/**
126126
* Children which do not stringify to "" (needed for equality)
127127
*/
128-
def nonEmptyChildren: Seq[Node] = child.filterNot(_.toString.isEmpty)
128+
def nonEmptyChildren: ScalaVersionSpecific.ChildReturnType = child.filterNot(_.toString.isEmpty)
129129

130130
/**
131131
* Descendant axis (all descendants of this node, not including node itself)

0 commit comments

Comments
 (0)