diff --git a/build.sbt b/build.sbt index 65b248329..4ecf29d24 100644 --- a/build.sbt +++ b/build.sbt @@ -31,21 +31,8 @@ lazy val xml = crossProject.in(file(".")) // http://stackoverflow.com/questions/16934488 file(System.getProperty("sun.boot.class.path").split(java.io.File.pathSeparator).filter(_.endsWith(java.io.File.separator + "rt.jar")).head) -> url("http://docs.oracle.com/javase/8/docs/api") - ), - - mimaBinaryIssueFilters ++= { - import com.typesafe.tools.mima.core._ - import com.typesafe.tools.mima.core.ProblemFilters._ - Seq( - // Scala 2.12 deprecated mutable.Stack, so we broke - // binary compatibility for 1.1.0 in the following way: - exclude[IncompatibleMethTypeProblem]("scala.xml.parsing.FactoryAdapter.scopeStack_="), - exclude[IncompatibleResultTypeProblem]("scala.xml.parsing.FactoryAdapter.hStack"), - exclude[IncompatibleResultTypeProblem]("scala.xml.parsing.FactoryAdapter.scopeStack"), - exclude[IncompatibleResultTypeProblem]("scala.xml.parsing.FactoryAdapter.attribStack"), - exclude[IncompatibleResultTypeProblem]("scala.xml.parsing.FactoryAdapter.tagStack") - ) - }) + ) + ) .jvmSettings( OsgiKeys.exportPackage := Seq(s"scala.xml.*;version=${version.value}"), diff --git a/jvm/src/test/scala/scala/xml/XMLTest.scala b/jvm/src/test/scala/scala/xml/XMLTest.scala index 43dd182e2..ed35b8aaf 100644 --- a/jvm/src/test/scala/scala/xml/XMLTest.scala +++ b/jvm/src/test/scala/scala/xml/XMLTest.scala @@ -40,8 +40,8 @@ class XMLTestJVM { override def text = "" } - assertEquals(c, parsedxml11) - assertEquals(parsedxml1, parsedxml11) + assertTrue(c == parsedxml11) + assertTrue(parsedxml1 == parsedxml11) assertTrue(List(parsedxml1) sameElements List(parsedxml11)) assertTrue(Array(parsedxml1).toList sameElements List(parsedxml11)) @@ -50,10 +50,10 @@ class XMLTestJVM { val i = new InputSource(new StringReader(x2)) val x2p = scala.xml.XML.load(i) - assertEquals(Elem(null, "book", e, sc, + assertTrue(x2p == Elem(null, "book", e, sc, Elem(null, "author", e, sc, Text("Peter Buneman")), Elem(null, "author", e, sc, Text("Dan Suciu")), - Elem(null, "title", e, sc, Text("Data on ze web"))), x2p) + Elem(null, "title", e, sc, Text("Data on ze web")))) } @@ -454,16 +454,16 @@ class XMLTestJVM { @UnitTest def t6939 = { val foo = - assertEquals(foo.child.head.scope.toString, """ xmlns:x="http://bar.com/"""") + assertTrue(foo.child.head.scope.toString == """ xmlns:x="http://bar.com/"""") val fooDefault = - assertEquals(fooDefault.child.head.scope.toString, """ xmlns="http://bar.com/"""") + assertTrue(fooDefault.child.head.scope.toString == """ xmlns="http://bar.com/"""") val foo2 = scala.xml.XML.loadString("""""") - assertEquals(foo2.child.head.scope.toString, """ xmlns:x="http://bar.com/"""") + assertTrue(foo2.child.head.scope.toString == """ xmlns:x="http://bar.com/"""") val foo2Default = scala.xml.XML.loadString("""""") - assertEquals(foo2Default.child.head.scope.toString, """ xmlns="http://bar.com/"""") + assertTrue(foo2Default.child.head.scope.toString == """ xmlns="http://bar.com/"""") } @UnitTest diff --git a/shared/src/main/scala/scala/xml/dtd/impl/SubsetConstruction.scala b/shared/src/main/scala/scala/xml/dtd/impl/SubsetConstruction.scala index b046a34e3..93ca0cfcd 100644 --- a/shared/src/main/scala/scala/xml/dtd/impl/SubsetConstruction.scala +++ b/shared/src/main/scala/scala/xml/dtd/impl/SubsetConstruction.scala @@ -32,9 +32,9 @@ private[dtd] class SubsetConstruction[T <: AnyRef](val nfa: NondetWordAutom[T]) val delta = new mutable.HashMap[immutable.BitSet, mutable.HashMap[T, immutable.BitSet]] var deftrans = mutable.Map(q0 -> sink, sink -> sink) // initial transitions var finals: mutable.Map[immutable.BitSet, Int] = mutable.Map() - var rest = immutable.List.empty[immutable.BitSet] + val rest = new mutable.Stack[immutable.BitSet] - rest = q0 :: sink :: rest + rest.push(sink, q0) def addFinal(q: immutable.BitSet) { if (nfa containsFinal q) @@ -43,7 +43,7 @@ private[dtd] class SubsetConstruction[T <: AnyRef](val nfa: NondetWordAutom[T]) def add(Q: immutable.BitSet) { if (!states(Q)) { states += Q - rest = Q :: rest + rest push Q addFinal(Q) } } @@ -51,8 +51,7 @@ private[dtd] class SubsetConstruction[T <: AnyRef](val nfa: NondetWordAutom[T]) addFinal(q0) // initial state may also be a final state while (!rest.isEmpty) { - val P = rest.head - rest = rest.tail + val P = rest.pop() // assign a number to this bitset indexMap = indexMap.updated(P, ix) invIndexMap = invIndexMap.updated(ix, P) diff --git a/shared/src/main/scala/scala/xml/factory/XMLLoader.scala b/shared/src/main/scala/scala/xml/factory/XMLLoader.scala index e08b41e94..0604282ea 100644 --- a/shared/src/main/scala/scala/xml/factory/XMLLoader.scala +++ b/shared/src/main/scala/scala/xml/factory/XMLLoader.scala @@ -37,9 +37,9 @@ trait XMLLoader[T <: Node] { def loadXML(source: InputSource, parser: SAXParser): T = { val newAdapter = adapter - newAdapter.scopeStack = TopScope :: newAdapter.scopeStack + newAdapter.scopeStack push TopScope parser.parse(source, newAdapter) - newAdapter.scopeStack = newAdapter.scopeStack.tail + newAdapter.scopeStack.pop() newAdapter.rootElem.asInstanceOf[T] } diff --git a/shared/src/main/scala/scala/xml/include/sax/XIncluder.scala b/shared/src/main/scala/scala/xml/include/sax/XIncluder.scala index ec5da7618..ae1cd9dd0 100644 --- a/shared/src/main/scala/scala/xml/include/sax/XIncluder.scala +++ b/shared/src/main/scala/scala/xml/include/sax/XIncluder.scala @@ -10,6 +10,7 @@ package scala package xml package include.sax +import scala.collection.mutable import org.xml.sax.{ ContentHandler, Locator, Attributes } import org.xml.sax.ext.LexicalHandler import java.io.{ OutputStream, OutputStreamWriter, IOException } @@ -125,7 +126,7 @@ class XIncluder(outs: OutputStream, encoding: String) extends ContentHandler wit // LexicalHandler methods private var inDTD: Boolean = false - private var entities = List.empty[String] + private val entities = new mutable.Stack[String]() def startDTD(name: String, publicID: String, systemID: String) { inDTD = true @@ -144,12 +145,12 @@ class XIncluder(outs: OutputStream, encoding: String) extends ContentHandler wit } def endDTD() {} - def startEntity(name: String): Unit = { - entities = name :: entities + def startEntity(name: String) { + entities push name } - def endEntity(name: String): Unit = { - entities = entities.tail + def endEntity(name: String) { + entities.pop() } def startCDATA() {} diff --git a/shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala b/shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala index a099c78d3..a8b5c887f 100644 --- a/shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala +++ b/shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala @@ -10,6 +10,7 @@ package scala package xml package parsing +import scala.collection.{ mutable, Iterator } import org.xml.sax.Attributes import org.xml.sax.helpers.DefaultHandler @@ -38,34 +39,10 @@ abstract class FactoryAdapter extends DefaultHandler with factory.XMLLoader[Node var rootElem: Node = null val buffer = new StringBuilder() - /** List of attributes - * - * Previously was a mutable [[scala.collection.mutable.Stack Stack]], but is now a mutable reference to an immutable [[scala.collection.immutable.List List]]. - * - * @since 1.1.0 - */ - var attribStack = List.empty[MetaData] - /** List of elements - * - * Previously was a mutable [[scala.collection.mutable.Stack Stack]], but is now a mutable reference to an immutable [[scala.collection.immutable.List List]]. - * - * @since 1.1.0 - */ - var hStack = List.empty[Node] // [ element ] contains siblings - /** List of element names - * - * Previously was a mutable [[scala.collection.mutable.Stack Stack]], but is now a mutable reference to an immutable [[scala.collection.immutable.List List]]. - * - * @since 1.1.0 - */ - var tagStack = List.empty[String] - /** List of namespaces - * - * Previously was a mutable [[scala.collection.mutable.Stack Stack]], but is now a mutable reference to an immutable [[scala.collection.immutable.List List]]. - * - * @since 1.1.0 - */ - var scopeStack = List.empty[NamespaceBinding] + val attribStack = new mutable.Stack[MetaData] + val hStack = new mutable.Stack[Node] // [ element ] contains siblings + val tagStack = new mutable.Stack[String] + var scopeStack = new mutable.Stack[NamespaceBinding] var curTag: String = null var capture: Boolean = false @@ -145,17 +122,17 @@ abstract class FactoryAdapter extends DefaultHandler with factory.XMLLoader[Node attributes: Attributes): Unit = { captureText() - tagStack = curTag :: tagStack + tagStack push curTag curTag = qname val localName = splitName(qname)._2 capture = nodeContainsText(localName) - hStack = null :: hStack + hStack push null var m: MetaData = Null var scpe: NamespaceBinding = if (scopeStack.isEmpty) TopScope - else scopeStack.head + else scopeStack.top for (i <- 0 until attributes.getLength()) { val qname = attributes getQName i @@ -170,8 +147,8 @@ abstract class FactoryAdapter extends DefaultHandler with factory.XMLLoader[Node m = Attribute(Option(pre), key, Text(value), m) } - scopeStack = scpe :: scopeStack - attribStack = m :: attribStack + scopeStack push scpe + attribStack push m } /** @@ -179,7 +156,7 @@ abstract class FactoryAdapter extends DefaultHandler with factory.XMLLoader[Node */ def captureText(): Unit = { if (capture && buffer.length > 0) - hStack = createText(buffer.toString) :: hStack + hStack push createText(buffer.toString) buffer.clear() } @@ -193,24 +170,17 @@ abstract class FactoryAdapter extends DefaultHandler with factory.XMLLoader[Node */ override def endElement(uri: String, _localName: String, qname: String): Unit = { captureText() - val metaData = attribStack.head - attribStack = attribStack.tail + val metaData = attribStack.pop() // reverse order to get it right - val v = hStack.takeWhile(_ != null).reverse - hStack = hStack.dropWhile(_ != null) match { - case null :: hs => hs - case hs => hs - } + val v = (Iterator continually hStack.pop takeWhile (_ != null)).toList.reverse val (pre, localName) = splitName(qname) - val scp = scopeStack.head - scopeStack = scopeStack.tail + val scp = scopeStack.pop() // create element rootElem = createNode(pre, localName, metaData, scp, v) - hStack = rootElem :: hStack - curTag = tagStack.head - tagStack = tagStack.tail + hStack push rootElem + curTag = tagStack.pop() capture = curTag != null && nodeContainsText(curTag) // root level } @@ -219,6 +189,6 @@ abstract class FactoryAdapter extends DefaultHandler with factory.XMLLoader[Node */ override def processingInstruction(target: String, data: String) { captureText() - hStack = hStack.reverse_:::(createProcInstr(target, data).toList) + hStack pushAll createProcInstr(target, data) } }