diff --git a/build.sbt b/build.sbt
index d1fd9a4f..c061bf75 100644
--- a/build.sbt
+++ b/build.sbt
@@ -110,6 +110,16 @@ lazy val xml = crossProject(JSPlatform, JVMPlatform, NativePlatform)
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.Null.get"),
ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.Node.attribute"),
+ // Nullable types result in a raw Seq, is fixed in 3.8
+ ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.Attribute.unapply"),
+ ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.Attribute.apply"),
+ ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.Attribute.value"),
+ ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.MetaData.value"),
+ ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.PrefixedAttribute.unapply"),
+ ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.PrefixedAttribute.this"),
+ ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.UnprefixedAttribute.unapply"),
+ ProblemFilters.exclude[IncompatibleSignatureProblem]("scala.xml.UnprefixedAttribute.this"),
+
// trait Attribute now extends trait ScalaVersionSpecificMetaData to ensure the previous signatures
// with return type `collection.Seq` remain valid.
// (trait Attribute extends MetaData, but that parent is not present in bytecode because it's a class.)
diff --git a/jvm/src/test/scala/scala/xml/XMLTest.scala b/jvm/src/test/scala/scala/xml/XMLTest.scala
index 4e5dba1a..41b0df5b 100644
--- a/jvm/src/test/scala/scala/xml/XMLTest.scala
+++ b/jvm/src/test/scala/scala/xml/XMLTest.scala
@@ -8,6 +8,7 @@ import java.net.URL
import scala.xml.dtd.{DocType, PublicID}
import scala.xml.parsing.ConstructingParser
import scala.xml.Utility.sort
+import xml.Nullables._
object XMLTestJVM {
val e: MetaData = Null //Node.NoAttributes
@@ -17,7 +18,7 @@ object XMLTestJVM {
class XMLTestJVM {
import XMLTestJVM.{e, sc}
- def Elem(prefix: String, label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*): Elem =
+ def Elem(prefix: Nullable[String], label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*): Elem =
scala.xml.Elem.apply(prefix, label, attributes, scope, minimizeEmpty = true, child: _*)
lazy val parsedxml1: Elem = XML.loadString("")
@@ -385,9 +386,9 @@ class XMLTestJVM {
@UnitTest
def t5052(): Unit = {
- assertTrue( xml_== )
+ assertTrue( xml_== )
assertTrue( xml_== )
- assertTrue( xml_== )
+ assertTrue( xml_== )
assertTrue( xml_== )
}
@@ -400,9 +401,9 @@ class XMLTestJVM {
assertHonorsIterableContract(.attributes)
assertHonorsIterableContract(.attributes)
assertHonorsIterableContract(.attributes)
- assertHonorsIterableContract(.attributes)
- assertHonorsIterableContract(.attributes)
- assertHonorsIterableContract(.attributes)
+ assertHonorsIterableContract(.attributes)
+ assertHonorsIterableContract(.attributes)
+ assertHonorsIterableContract(.attributes)
}
@UnitTest
@@ -459,9 +460,9 @@ class XMLTestJVM {
@UnitTest
def attributes(): Unit = {
val noAttr: Elem =
- val attrNull: Elem =
+ val attrNull: Elem =
val attrNone: Elem =
- val preAttrNull: Elem =
+ val preAttrNull: Elem =
val preAttrNone: Elem =
assertEquals(noAttr, attrNull)
assertEquals(noAttr, attrNone)
@@ -469,8 +470,8 @@ class XMLTestJVM {
assertEquals(noAttr, preAttrNone)
val xml1: Elem =
- val xml2: Elem =
- val xml3: Elem =
+ val xml2: Elem =
+ val xml3: Elem =
assertEquals(xml1, xml2)
assertEquals(xml1, xml3)
@@ -759,8 +760,8 @@ class XMLTestJVM {
def documentBaseURI(): Unit = {
val url: URL = resourceUrl("site")
// XMLLoader returns the document's baseURI:
- assert(XML.withSAXParser(xercesInternal.newSAXParser).loadDocument(url).baseURI.endsWith("/test-classes/scala/xml/site.xml"))
- assert(XML.withSAXParser(xercesExternal.newSAXParser).loadDocument(url).baseURI.endsWith("/test-classes/scala/xml/site.xml"))
+ assert(XML.withSAXParser(xercesInternal.newSAXParser).loadDocument(url).baseURI.nn.endsWith("/test-classes/scala/xml/site.xml"))
+ assert(XML.withSAXParser(xercesExternal.newSAXParser).loadDocument(url).baseURI.nn.endsWith("/test-classes/scala/xml/site.xml"))
// ConstructingParser does not return it of course: since it uses scala.io.Source it has no idea where is the XML coming from:
assertNull(ConstructingParser.fromSource(scala.io.Source.fromURI(url.toURI), preserveWS = false).document().baseURI)
}
diff --git a/shared/src/main/scala-2.13+/scala/xml/ScalaVersionSpecific.scala b/shared/src/main/scala-2.13+/scala/xml/ScalaVersionSpecific.scala
index 49da95b8..979ffb40 100644
--- a/shared/src/main/scala-2.13+/scala/xml/ScalaVersionSpecific.scala
+++ b/shared/src/main/scala-2.13+/scala/xml/ScalaVersionSpecific.scala
@@ -12,6 +12,8 @@
package scala.xml
+
+import xml.Nullables._
import scala.collection.immutable.StrictOptimizedSeqOps
import scala.collection.{View, SeqOps, IterableOnce, immutable, mutable}
import scala.collection.BuildFrom
@@ -65,11 +67,11 @@ private[xml] trait ScalaVersionSpecificNode { self: Node =>
}
private[xml] trait ScalaVersionSpecificMetaData { self: MetaData =>
- def apply(key: String): scala.collection.Seq[Node]
- def apply(namespace_uri: String, owner: Node, key: String): scala.collection.Seq[Node]
- def apply(namespace_uri: String, scp: NamespaceBinding, k: String): scala.collection.Seq[Node]
+ def apply(key: String): Nullable[scala.collection.Seq[Node]]
+ def apply(namespace_uri: String, owner: Node, key: Nullable[String]): Nullable[scala.collection.Seq[Node]]
+ def apply(namespace_uri: Nullable[String], scp: NamespaceBinding, k: Nullable[String]): Nullable[scala.collection.Seq[Node]]
- def value: scala.collection.Seq[Node]
+ def value: Nullable[scala.collection.Seq[Node]]
}
private[xml] trait ScalaVersionSpecificTextBuffer { self: TextBuffer =>
diff --git a/shared/src/main/scala-2/scala/xml/Nullables.scala b/shared/src/main/scala-2/scala/xml/Nullables.scala
new file mode 100644
index 00000000..707939c9
--- /dev/null
+++ b/shared/src/main/scala-2/scala/xml/Nullables.scala
@@ -0,0 +1,21 @@
+/*
+ * Scala (https://www.scala-lang.org)
+ *
+ * Copyright EPFL and Lightbend, Inc.
+ *
+ * Licensed under Apache License 2.0
+ * (http://www.apache.org/licenses/LICENSE-2.0).
+ *
+ * See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
+ */
+
+package scala.xml
+object Nullables {
+ type Nullable[T] = T
+ implicit class NonNullOps[T](private val x: T) extends AnyVal {
+ def nn: T = {
+ x
+ }
+ }
+}
diff --git a/shared/src/main/scala-3/scala/xml/Nullables.scala b/shared/src/main/scala-3/scala/xml/Nullables.scala
new file mode 100644
index 00000000..41417080
--- /dev/null
+++ b/shared/src/main/scala-3/scala/xml/Nullables.scala
@@ -0,0 +1,16 @@
+/*
+ * Scala (https://www.scala-lang.org)
+ *
+ * Copyright EPFL and Lightbend, Inc.
+ *
+ * Licensed under Apache License 2.0
+ * (http://www.apache.org/licenses/LICENSE-2.0).
+ *
+ * See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
+ */
+
+package scala.xml
+object Nullables {
+ type Nullable[T] = T | Null
+}
diff --git a/shared/src/main/scala/scala/xml/Attribute.scala b/shared/src/main/scala/scala/xml/Attribute.scala
index 1c7c3575..50078d07 100644
--- a/shared/src/main/scala/scala/xml/Attribute.scala
+++ b/shared/src/main/scala/scala/xml/Attribute.scala
@@ -13,6 +13,7 @@
package scala
package xml
+import xml.Nullables._
import scala.collection.Seq
/**
@@ -22,21 +23,21 @@ import scala.collection.Seq
* @author Burak Emir
*/
object Attribute {
- def unapply(x: Attribute): Option[(String, Seq[Node], MetaData)] = x match {
+ def unapply(x: Attribute): Option[(Nullable[String], Nullable[Seq[Node]], MetaData)] = x match {
case PrefixedAttribute(_, key, value, next) => Some((key, value, next))
case UnprefixedAttribute(key, value, next) => Some((key, value, next))
case _ => None
}
/** Convenience functions which choose Un/Prefixedness appropriately */
- def apply(key: String, value: Seq[Node], next: MetaData): Attribute =
+ def apply(key: Nullable[String], value: Seq[Node], next: MetaData): Attribute =
new UnprefixedAttribute(key, value, next)
- def apply(pre: String, key: String, value: String, next: MetaData): Attribute =
+ def apply(pre: Nullable[String], key: String, value: String, next: MetaData): Attribute =
if (pre == null || pre == "") new UnprefixedAttribute(key, value, next)
else new PrefixedAttribute(pre, key, value, next)
- def apply(pre: String, key: String, value: Seq[Node], next: MetaData): Attribute =
+ def apply(pre: Nullable[String], key: String, value: Seq[Node], next: MetaData): Attribute =
if (pre == null || pre == "") new UnprefixedAttribute(key, value, next)
else new PrefixedAttribute(pre, key, value, next)
@@ -54,29 +55,29 @@ object Attribute {
* @author Burak Emir
*/
trait Attribute extends MetaData with ScalaVersionSpecificMetaData {
- def pre: String // will be null if unprefixed
- override val key: String
- override val value: ScalaVersionSpecific.SeqOfNode
+ def pre: Nullable[String] // will be null if unprefixed
+ override val key: Nullable[String]
+ override val value: Nullable[ScalaVersionSpecific.SeqOfNode]
override val next: MetaData
- override def apply(key: String): ScalaVersionSpecific.SeqOfNode
- override def apply(namespace: String, scope: NamespaceBinding, key: String): ScalaVersionSpecific.SeqOfNode
+ override def apply(key: String): Nullable[ScalaVersionSpecific.SeqOfNode]
+ override def apply(namespace: Nullable[String], scope: NamespaceBinding, key: Nullable[String]): Nullable[ScalaVersionSpecific.SeqOfNode]
override def copy(next: MetaData): Attribute
- override def remove(key: String): MetaData =
+ override def remove(key: Nullable[String]): MetaData =
if (!isPrefixed && this.key == key) next
else copy(next.remove(key))
- override def remove(namespace: String, scope: NamespaceBinding, key: String): MetaData =
+ override def remove(namespace: Nullable[String], scope: NamespaceBinding, key: String): MetaData =
if (this.key == key && scope.getURI(pre) == namespace) next
else copy(next.remove(namespace, scope, key))
override def isPrefixed: Boolean = pre != null
- override def getNamespace(owner: Node): String
+ override def getNamespace(owner: Node): Nullable[String]
override def wellformed(scope: NamespaceBinding): Boolean = {
- val arg: String = if (isPrefixed) scope.getURI(pre) else null
+ val arg: Nullable[String] = if (isPrefixed) scope.getURI(pre) else null
(next(arg, scope, key) == null) && next.wellformed(scope)
}
diff --git a/shared/src/main/scala/scala/xml/Document.scala b/shared/src/main/scala/scala/xml/Document.scala
index 8fe1c6ae..650018aa 100644
--- a/shared/src/main/scala/scala/xml/Document.scala
+++ b/shared/src/main/scala/scala/xml/Document.scala
@@ -14,6 +14,7 @@ package scala
package xml
import scala.collection.Seq
+import xml.Nullables._
/**
* A document information item (according to InfoSet spec). The comments
@@ -42,7 +43,7 @@ class Document extends NodeSeq with Serializable {
var docElem: Node = _
/** The dtd that comes with the document, if any */
- var dtd: scala.xml.dtd.DTD = _
+ var dtd: Nullable[scala.xml.dtd.DTD] = _
/**
* An unordered set of notation information items, one for each notation
@@ -50,17 +51,17 @@ class Document extends NodeSeq with Serializable {
* has no value.
*/
def notations: Seq[scala.xml.dtd.NotationDecl] =
- dtd.notations
+ dtd.nn.notations
/**
* An unordered set of unparsed entity information items, one for each
* unparsed entity declared in the DTD.
*/
def unparsedEntities: Seq[scala.xml.dtd.EntityDecl] =
- dtd.unparsedEntities
+ dtd.nn.unparsedEntities
/** The base URI of the document entity. */
- var baseURI: String = _
+ var baseURI: Nullable[String] = _
/**
* The name of the character encoding scheme in which the document entity
diff --git a/shared/src/main/scala/scala/xml/Elem.scala b/shared/src/main/scala/scala/xml/Elem.scala
index 6b77f164..426052fe 100755
--- a/shared/src/main/scala/scala/xml/Elem.scala
+++ b/shared/src/main/scala/scala/xml/Elem.scala
@@ -14,6 +14,7 @@ package scala
package xml
import scala.collection.Seq
+import xml.Nullables._
/**
* This singleton object contains the `apply` and `unapplySeq` methods for
@@ -24,10 +25,10 @@ import scala.collection.Seq
// Note: used by the Scala compiler.
object Elem {
- def apply(prefix: String, label: String, attributes: MetaData, scope: NamespaceBinding, minimizeEmpty: Boolean, child: Node*): Elem =
+ def apply(prefix: Nullable[String], label: Nullable[String], attributes: MetaData, scope: NamespaceBinding, minimizeEmpty: Boolean, child: Node*): Elem =
new Elem(prefix, label, attributes, scope, minimizeEmpty, child: _*)
- def unapplySeq(n: Node): Option[(String, String, MetaData, NamespaceBinding, ScalaVersionSpecific.SeqOfNode)] =
+ def unapplySeq(n: Node): Option[(Nullable[String], Nullable[String], MetaData, NamespaceBinding, ScalaVersionSpecific.SeqOfNode)] =
n match {
case _: SpecialNode | _: Group => None
case _ => Some((n.prefix, n.label, n.attributes, n.scope, n.child))
@@ -55,8 +56,8 @@ object Elem {
*/
// Note: used by the Scala compiler.
class Elem(
- override val prefix: String,
- override val label: String,
+ override val prefix: Nullable[String],
+ override val label: Nullable[String],
attributes1: MetaData,
override val scope: NamespaceBinding,
val minimizeEmpty: Boolean,
@@ -98,8 +99,8 @@ class Elem(
* @return a new symbol with updated attributes
*/
def copy(
- prefix: String = this.prefix,
- label: String = this.label,
+ prefix: Nullable[String] = this.prefix,
+ label: Nullable[String] = this.label,
attributes: MetaData = this.attributes,
scope: NamespaceBinding = this.scope,
minimizeEmpty: Boolean = this.minimizeEmpty,
diff --git a/shared/src/main/scala/scala/xml/MetaData.scala b/shared/src/main/scala/scala/xml/MetaData.scala
index 6bdd080f..b9842478 100644
--- a/shared/src/main/scala/scala/xml/MetaData.scala
+++ b/shared/src/main/scala/scala/xml/MetaData.scala
@@ -17,6 +17,7 @@ import Utility.sbToString
import scala.annotation.tailrec
import scala.collection.AbstractIterable
import scala.collection.Seq
+import xml.Nullables._
object MetaData {
/**
@@ -37,13 +38,13 @@ object MetaData {
* namespace URIs via the given scope.
*/
def normalize(attribs: MetaData, scope: NamespaceBinding): MetaData = {
- def iterate(md: MetaData, normalized_attribs: MetaData, set: Set[String]): MetaData =
+ def iterate(md: MetaData, normalized_attribs: MetaData, set: Set[Nullable[String]]): MetaData =
if (md.isNull) {
normalized_attribs
} else if (md.value == null)
iterate(md.next, normalized_attribs, set)
else {
- val key: String = getUniversalKey(md, scope)
+ val key: Nullable[String] = getUniversalKey(md, scope)
if (set(key))
iterate(md.next, normalized_attribs, set)
else
@@ -56,8 +57,8 @@ object MetaData {
/**
* returns key if md is unprefixed, pre+key is md is prefixed
*/
- def getUniversalKey(attrib: MetaData, scope: NamespaceBinding): String = attrib match {
- case prefixed: PrefixedAttribute => scope.getURI(prefixed.pre) + prefixed.key
+ def getUniversalKey(attrib: MetaData, scope: NamespaceBinding): Nullable[String] = attrib match {
+ case prefixed: PrefixedAttribute => scope.getURI(prefixed.pre).asInstanceOf[String] + prefixed.key
case unprefixed: UnprefixedAttribute => unprefixed.key
}
@@ -107,7 +108,7 @@ abstract class MetaData
* @param key
* @return value as Seq[Node] if key is found, null otherwise
*/
- def apply(key: String): ScalaVersionSpecific.SeqOfNode
+ def apply(key: String): Nullable[ScalaVersionSpecific.SeqOfNode]
/**
* convenience method, same as `apply(namespace, owner.scope, key)`.
@@ -116,7 +117,7 @@ abstract class MetaData
* @param owner the element owning this attribute list
* @param key the attribute key
*/
- final def apply(namespace_uri: String, owner: Node, key: String): ScalaVersionSpecific.SeqOfNode =
+ final def apply(namespace_uri: String, owner: Node, key: Nullable[String]): Nullable[ScalaVersionSpecific.SeqOfNode] =
apply(namespace_uri, owner.scope, key)
/**
@@ -127,7 +128,7 @@ abstract class MetaData
* @param k to be looked for
* @return value as Seq[Node] if key is found, null otherwise
*/
- def apply(namespace_uri: String, scp: NamespaceBinding, k: String): ScalaVersionSpecific.SeqOfNode
+ def apply(namespace_uri: Nullable[String], scp: NamespaceBinding, k: Nullable[String]): Nullable[ScalaVersionSpecific.SeqOfNode]
/**
* returns a copy of this MetaData item with next field set to argument.
@@ -135,7 +136,7 @@ abstract class MetaData
def copy(next: MetaData): MetaData
/** if owner is the element of this metadata item, returns namespace */
- def getNamespace(owner: Node): String
+ def getNamespace(owner: Node): Nullable[String]
def hasNext: Boolean = Null != next
@@ -166,16 +167,16 @@ abstract class MetaData
}
/** returns key of this MetaData item */
- def key: String
+ def key: Nullable[String]
/** returns value of this MetaData item */
- def value: ScalaVersionSpecific.SeqOfNode
+ def value: Nullable[ScalaVersionSpecific.SeqOfNode]
/**
* Returns a String containing "prefix:key" if the first key is
* prefixed, and "key" otherwise.
*/
- def prefixedKey: String = this match {
+ def prefixedKey: Nullable[String] = this match {
case x: Attribute if x.isPrefixed => s"${x.pre}:$key"
case _ => key
}
@@ -183,8 +184,8 @@ abstract class MetaData
/**
* Returns a Map containing the attributes stored as key/value pairs.
*/
- def asAttrMap: Map[String, String] =
- iterator.map(x => (x.prefixedKey, NodeSeq.fromSeq(x.value).text)).toMap
+ def asAttrMap: Map[Nullable[String], String] =
+ iterator.map(x => (x.prefixedKey, NodeSeq.fromSeq(x.value.nn).text)).toMap
/** returns Null or the next MetaData item */
def next: MetaData
@@ -195,7 +196,7 @@ abstract class MetaData
* @param key
* @return value in Some(Seq[Node]) if key is found, None otherwise
*/
- final def get(key: String): Option[ScalaVersionSpecific.SeqOfNode] = Option(apply(key))
+ final def get(key: String): Option[ScalaVersionSpecific.SeqOfNode] = Option(apply(key).asInstanceOf[ScalaVersionSpecific.SeqOfNode])
/** same as get(uri, owner.scope, key) */
final def get(uri: String, owner: Node, key: String): Option[ScalaVersionSpecific.SeqOfNode] =
@@ -209,8 +210,8 @@ abstract class MetaData
* @param key to be looked fore
* @return value as `Some[Seq[Node]]` if key is found, None otherwise
*/
- final def get(uri: String, scope: NamespaceBinding, key: String): Option[ScalaVersionSpecific.SeqOfNode] =
- Option(apply(uri, scope, key))
+ final def get(uri: Nullable[String], scope: NamespaceBinding, key: String): Option[ScalaVersionSpecific.SeqOfNode] =
+ Option(apply(uri, scope, key).asInstanceOf[ScalaVersionSpecific.SeqOfNode])
protected def toString1: String = sbToString(toString1)
@@ -229,9 +230,9 @@ abstract class MetaData
*/
def wellformed(scope: NamespaceBinding): Boolean
- def remove(key: String): MetaData
+ def remove(key: Nullable[String]): MetaData
- def remove(namespace: String, scope: NamespaceBinding, key: String): MetaData
+ def remove(namespace: Nullable[String], scope: NamespaceBinding, key: String): MetaData
final def remove(namespace: String, owner: Node, key: String): MetaData =
remove(namespace, owner.scope, key)
diff --git a/shared/src/main/scala/scala/xml/NamespaceBinding.scala b/shared/src/main/scala/scala/xml/NamespaceBinding.scala
index 8efe27d7..c495931a 100644
--- a/shared/src/main/scala/scala/xml/NamespaceBinding.scala
+++ b/shared/src/main/scala/scala/xml/NamespaceBinding.scala
@@ -14,6 +14,7 @@ package scala
package xml
import scala.collection.Seq
+import xml.Nullables._
/**
* The class `NamespaceBinding` represents namespace bindings
@@ -25,12 +26,12 @@ import scala.collection.Seq
*/
// Note: used by the Scala compiler.
@SerialVersionUID(0 - 2518644165573446725L)
-case class NamespaceBinding(prefix: String, uri: String, parent: NamespaceBinding) extends AnyRef with Equality {
+case class NamespaceBinding(prefix: Nullable[String], uri: Nullable[String], parent: Nullable[NamespaceBinding]) extends AnyRef with Equality {
if (prefix == "")
throw new IllegalArgumentException("zero length prefix not allowed")
- def getURI(prefix: String): String =
- if (this.prefix == prefix) uri else parent.getURI(prefix)
+ def getURI(prefix: Nullable[String]): Nullable[String] =
+ if (this.prefix == prefix) uri else parent.nn.getURI(prefix)
/**
* Returns some prefix that is mapped to the URI.
@@ -39,21 +40,21 @@ case class NamespaceBinding(prefix: String, uri: String, parent: NamespaceBindin
* @return the prefix that is mapped to the input URI, or null
* if no prefix is mapped to the URI.
*/
- def getPrefix(uri: String): String =
- if (uri == this.uri) prefix else parent.getPrefix(uri)
+ def getPrefix(uri: String): Nullable[String] =
+ if (uri == this.uri) prefix else parent.nn.getPrefix(uri)
override def toString: String = Utility.sbToString(buildString(_, TopScope))
private def shadowRedefined(stop: NamespaceBinding): NamespaceBinding = {
- def prefixList(x: NamespaceBinding): List[String] =
+ def prefixList(x: Nullable[NamespaceBinding]): List[Nullable[String]] =
if ((x == null) || x.eq(stop)) Nil
else x.prefix :: prefixList(x.parent)
- def fromPrefixList(l: List[String]): NamespaceBinding = l match {
+ def fromPrefixList(l: List[Nullable[String]]): NamespaceBinding = l match {
case Nil => stop
case x :: xs => NamespaceBinding(x, this.getURI(x), fromPrefixList(xs))
}
- val ps0: List[String] = prefixList(this).reverse
- val ps: List[String] = ps0.distinct
+ val ps0: List[Nullable[String]] = prefixList(this).reverse
+ val ps: List[Nullable[String]] = ps0.distinct
if (ps.size == ps0.size) this
else fromPrefixList(ps)
}
@@ -80,6 +81,6 @@ case class NamespaceBinding(prefix: String, uri: String, parent: NamespaceBindin
val prefixStr: String = if (prefix != null) s":$prefix" else ""
val uriStr: String = if (uri != null) uri else ""
- parent.doBuildString(sb.append(s""" xmlns$prefixStr="$uriStr""""), stop) // copy(ignore)
+ parent.nn.doBuildString(sb.append(s""" xmlns$prefixStr="$uriStr""""), stop) // copy(ignore)
}
}
diff --git a/shared/src/main/scala/scala/xml/Node.scala b/shared/src/main/scala/scala/xml/Node.scala
index d9c41dd1..c2a76952 100755
--- a/shared/src/main/scala/scala/xml/Node.scala
+++ b/shared/src/main/scala/scala/xml/Node.scala
@@ -13,6 +13,7 @@
package scala
package xml
+import xml.Nullables._
import scala.collection.Seq
/**
@@ -28,7 +29,7 @@ object Node {
/** the empty namespace */
val EmptyNamespace: String = ""
- def unapplySeq(n: Node): Some[(String, MetaData, ScalaVersionSpecific.SeqOfNode)] =
+ def unapplySeq(n: Node): Some[(Nullable[String], MetaData, ScalaVersionSpecific.SeqOfNode)] =
Some((n.label, n.attributes, n.child))
}
@@ -48,10 +49,10 @@ object Node {
abstract class Node extends NodeSeq with ScalaVersionSpecificNode {
/** prefix of this node */
- def prefix: String = null
+ def prefix: Nullable[String] = null
/** label of this node. I.e. "foo" for <foo/>) */
- def label: String
+ def label: Nullable[String]
/**
* used internally. Atom/Molecule = -1 PI = -2 Comment = -3 EntityRef = -5
@@ -72,7 +73,7 @@ abstract class Node extends NodeSeq with ScalaVersionSpecificNode {
/**
* convenience, same as `getNamespace(this.prefix)`
*/
- def namespace: String = getNamespace(this.prefix)
+ def namespace: Nullable[String] = getNamespace(this.prefix)
/**
* Convenience method, same as `scope.getURI(pre)` but additionally
@@ -82,7 +83,7 @@ abstract class Node extends NodeSeq with ScalaVersionSpecificNode {
* @return the namespace if `scope != null` and prefix was
* found, else `null`
*/
- def getNamespace(pre: String): String = if (scope == null) null else scope.getURI(pre)
+ def getNamespace(pre: Nullable[String]): Nullable[String] = if (scope == null) null else scope.getURI(pre)
/**
* Convenience method, looks up an unprefixed attribute in attributes of this node.
@@ -190,7 +191,7 @@ abstract class Node extends NodeSeq with ScalaVersionSpecificNode {
/**
* Returns a type symbol (e.g. DTD, XSD), default `'''null'''`.
*/
- def xmlType: TypeSymbol = null
+ def xmlType: Nullable[TypeSymbol] = null
/**
* Returns a text representation of this node. Note that this is not equivalent to
diff --git a/shared/src/main/scala/scala/xml/Null.scala b/shared/src/main/scala/scala/xml/Null.scala
index c8e35640..6200e7f2 100644
--- a/shared/src/main/scala/scala/xml/Null.scala
+++ b/shared/src/main/scala/scala/xml/Null.scala
@@ -13,6 +13,7 @@
package scala
package xml
+import xml.Nullables._
import scala.collection.Iterator
import scala.collection.Seq
@@ -31,12 +32,12 @@ case object Null extends MetaData {
override def filter(f: MetaData => Boolean): ScalaVersionSpecificReturnTypes.NullFilter = this
override def copy(next: MetaData): MetaData = next
- override def getNamespace(owner: Node): ScalaVersionSpecificReturnTypes.NullGetNamespace = null
+ override def getNamespace(owner: Node): ScalaVersionSpecificReturnTypes.NullGetNamespace = null.asInstanceOf[ScalaVersionSpecificReturnTypes.NullGetNamespace]
override def hasNext: Boolean = false
- override def next: ScalaVersionSpecificReturnTypes.NullNext = null
- override def key: ScalaVersionSpecificReturnTypes.NullKey = null
- override def value: ScalaVersionSpecificReturnTypes.NullValue = null
+ override def next: ScalaVersionSpecificReturnTypes.NullNext = null.asInstanceOf[ScalaVersionSpecificReturnTypes.NullNext]
+ override def key: ScalaVersionSpecificReturnTypes.NullKey = null.asInstanceOf[ScalaVersionSpecificReturnTypes.NullKey]
+ override def value: ScalaVersionSpecificReturnTypes.NullValue = null.asInstanceOf[ScalaVersionSpecificReturnTypes.NullValue]
override def isPrefixed: Boolean = false
override def length: Int = 0
@@ -48,8 +49,8 @@ case object Null extends MetaData {
}
override protected def basisForHashCode: Seq[Any] = Nil
- override def apply(namespace: String, scope: NamespaceBinding, key: String): ScalaVersionSpecificReturnTypes.NullApply3 = null
- override def apply(key: String): ScalaVersionSpecific.SeqOfNode =
+ override def apply(namespace: Nullable[String], scope: NamespaceBinding, key: Nullable[String]): ScalaVersionSpecificReturnTypes.NullApply3 = null.asInstanceOf[ScalaVersionSpecificReturnTypes.NullApply3]
+ override def apply(key: String): Nullable[ScalaVersionSpecific.SeqOfNode] =
if (Utility.isNameStart(key.head)) null
else throw new IllegalArgumentException(s"not a valid attribute name '$key', so can never match !")
@@ -62,6 +63,6 @@ case object Null extends MetaData {
override def wellformed(scope: NamespaceBinding): Boolean = true
- override def remove(key: String): ScalaVersionSpecificReturnTypes.NullRemove = this
- override def remove(namespace: String, scope: NamespaceBinding, key: String): ScalaVersionSpecificReturnTypes.NullRemove = this
+ override def remove(key: Nullable[String]): ScalaVersionSpecificReturnTypes.NullRemove = this
+ override def remove(namespace: Nullable[String], scope: NamespaceBinding, key: String): ScalaVersionSpecificReturnTypes.NullRemove = this
}
diff --git a/shared/src/main/scala/scala/xml/PrefixedAttribute.scala b/shared/src/main/scala/scala/xml/PrefixedAttribute.scala
index 1dc6ba12..c6109cf3 100644
--- a/shared/src/main/scala/scala/xml/PrefixedAttribute.scala
+++ b/shared/src/main/scala/scala/xml/PrefixedAttribute.scala
@@ -13,6 +13,7 @@
package scala
package xml
+import xml.Nullables._
import scala.collection.Seq
/**
@@ -27,12 +28,12 @@ import scala.collection.Seq
class PrefixedAttribute(
override val pre: String,
override val key: String,
- _value: Seq[Node],
+ _value: Nullable[Seq[Node]],
val next1: MetaData
)
extends Attribute
{
- override val value: ScalaVersionSpecific.SeqOfNode = if (_value == null) null else _value match {
+ override val value: Nullable[ScalaVersionSpecific.SeqOfNode] = if (_value == null) null else _value match {
case ns: ScalaVersionSpecific.SeqOfNode => ns
case _ => _value.toVector
}
@@ -40,8 +41,8 @@ class PrefixedAttribute(
override val next: MetaData = if (value != null) next1 else next1.remove(key)
/** same as this(pre, key, Text(value), next), or no attribute if value is null */
- def this(pre: String, key: String, value: String, next: MetaData) =
- this(pre, key, if (value != null) Text(value) else null: NodeSeq, next)
+ def this(pre: String, key: String, value: Nullable[String], next: MetaData) =
+ this(pre, key, if (value != null) Text(value) else null: Nullable[NodeSeq], next)
/** same as this(pre, key, value.get, next), or no attribute if value is None */
def this(pre: String, key: String, value: Option[Seq[Node]], next: MetaData) =
@@ -54,16 +55,16 @@ class PrefixedAttribute(
override def copy(next: MetaData): PrefixedAttribute =
new PrefixedAttribute(pre, key, value, next)
- override def getNamespace(owner: Node): String =
+ override def getNamespace(owner: Node): Nullable[String] =
owner.getNamespace(pre)
/** forwards the call to next (because caller looks for unprefixed attribute */
- override def apply(key: String): ScalaVersionSpecific.SeqOfNode = next(key)
+ override def apply(key: String): Nullable[ScalaVersionSpecific.SeqOfNode] = next(key)
/**
* gets attribute value of qualified (prefixed) attribute with given key
*/
- override def apply(namespace: String, scope: NamespaceBinding, key: String): ScalaVersionSpecific.SeqOfNode =
+ override def apply(namespace: Nullable[String], scope: NamespaceBinding, key: Nullable[String]): Nullable[ScalaVersionSpecific.SeqOfNode] =
if (key == this.key && scope.getURI(pre) == namespace)
value
else
@@ -71,5 +72,5 @@ class PrefixedAttribute(
}
object PrefixedAttribute {
- def unapply(x: PrefixedAttribute): Some[(String, String, Seq[Node], MetaData)] = Some((x.pre, x.key, x.value, x.next))
+ def unapply(x: PrefixedAttribute): Some[(String, String, Nullable[Seq[Node]], MetaData)] = Some((x.pre, x.key, x.value, x.next))
}
diff --git a/shared/src/main/scala/scala/xml/QNode.scala b/shared/src/main/scala/scala/xml/QNode.scala
index ddf7818c..9d96eeec 100644
--- a/shared/src/main/scala/scala/xml/QNode.scala
+++ b/shared/src/main/scala/scala/xml/QNode.scala
@@ -13,6 +13,7 @@
package scala
package xml
+import xml.Nullables._
/**
* This object provides an extractor method to match a qualified node with
* its namespace URI
@@ -20,6 +21,6 @@ package xml
* @author Burak Emir
*/
object QNode {
- def unapplySeq(n: Node): Some[(String, String, MetaData, ScalaVersionSpecific.SeqOfNode)] =
+ def unapplySeq(n: Node): Some[(Nullable[String], Nullable[String], MetaData, ScalaVersionSpecific.SeqOfNode)] =
Some((n.scope.getURI(n.prefix), n.label, n.attributes, n.child))
}
diff --git a/shared/src/main/scala/scala/xml/TopScope.scala b/shared/src/main/scala/scala/xml/TopScope.scala
index 0b82e4b6..a9c03025 100644
--- a/shared/src/main/scala/scala/xml/TopScope.scala
+++ b/shared/src/main/scala/scala/xml/TopScope.scala
@@ -13,6 +13,7 @@
package scala
package xml
+import xml.Nullables._
/**
* top level namespace scope. only contains the predefined binding
* for the "xml" prefix which is bound to
@@ -20,10 +21,10 @@ package xml
*/
object TopScope extends NamespaceBinding(null, null, null) {
- override def getURI(prefix1: String): String =
+ override def getURI(prefix1: Nullable[String]): Nullable[String] =
if (prefix1 == XML.xml) XML.namespace else null
- override def getPrefix(uri1: String): String =
+ override def getPrefix(uri1: String): Nullable[String] =
if (uri1 == XML.namespace) XML.xml else null
override def toString: String = ""
diff --git a/shared/src/main/scala/scala/xml/UnprefixedAttribute.scala b/shared/src/main/scala/scala/xml/UnprefixedAttribute.scala
index 877a59b2..cdde2a9d 100644
--- a/shared/src/main/scala/scala/xml/UnprefixedAttribute.scala
+++ b/shared/src/main/scala/scala/xml/UnprefixedAttribute.scala
@@ -13,6 +13,7 @@
package scala
package xml
+import xml.Nullables._
import scala.collection.Seq
/**
@@ -22,13 +23,13 @@ import scala.collection.Seq
*/
// Note: used by the Scala compiler.
class UnprefixedAttribute(
- override val key: String,
- _value: Seq[Node],
+ override val key: Nullable[String],
+ _value: Nullable[Seq[Node]],
next1: MetaData
)
extends Attribute
{
- override val value: ScalaVersionSpecific.SeqOfNode = if (_value == null) null else _value match {
+ override val value: Nullable[ScalaVersionSpecific.SeqOfNode] = if (_value == null) null else _value match {
case ns: ScalaVersionSpecific.SeqOfNode => ns
case _ => _value.toVector
}
@@ -37,8 +38,8 @@ class UnprefixedAttribute(
override val next: MetaData = if (value != null) next1 else next1.remove(key)
/** same as this(key, Text(value), next), or no attribute if value is null */
- def this(key: String, value: String, next: MetaData) =
- this(key, if (value != null) Text(value) else null: NodeSeq, next)
+ def this(key: String, value: Nullable[String], next: MetaData) =
+ this(key, if (value != null) Text(value) else null: Nullable[NodeSeq], next)
/** same as this(key, value.get, next), or no attribute if value is None */
def this(key: String, value: Option[Seq[Node]], next: MetaData) =
@@ -47,7 +48,7 @@ class UnprefixedAttribute(
/** returns a copy of this unprefixed attribute with the given next field*/
override def copy(next: MetaData): UnprefixedAttribute = new UnprefixedAttribute(key, value, next)
- final override def getNamespace(owner: Node): String = null
+ final override def getNamespace(owner: Node): Nullable[String] = null
/**
* Gets value of unqualified (unprefixed) attribute with given key, null if not found
@@ -55,7 +56,7 @@ class UnprefixedAttribute(
* @param key
* @return value as Seq[Node] if key is found, null otherwise
*/
- override def apply(key: String): ScalaVersionSpecific.SeqOfNode =
+ override def apply(key: String): Nullable[ScalaVersionSpecific.SeqOfNode] =
if (key == this.key) value else next(key)
/**
@@ -66,9 +67,9 @@ class UnprefixedAttribute(
* @param key
* @return ..
*/
- override def apply(namespace: String, scope: NamespaceBinding, key: String): ScalaVersionSpecific.SeqOfNode =
+ override def apply(namespace: Nullable[String], scope: NamespaceBinding, key: Nullable[String]): Nullable[ScalaVersionSpecific.SeqOfNode] =
next(namespace, scope, key)
}
object UnprefixedAttribute {
- def unapply(x: UnprefixedAttribute): Some[(String, Seq[Node], MetaData)] = Some((x.key, x.value, x.next))
+ def unapply(x: UnprefixedAttribute): Some[(Nullable[String], Nullable[Seq[Node]], MetaData)] = Some((x.key, x.value, x.next))
}
diff --git a/shared/src/main/scala/scala/xml/Utility.scala b/shared/src/main/scala/scala/xml/Utility.scala
index cf85be14..68ed32cb 100755
--- a/shared/src/main/scala/scala/xml/Utility.scala
+++ b/shared/src/main/scala/scala/xml/Utility.scala
@@ -18,6 +18,7 @@ import scala.collection.mutable
import scala.language.implicitConversions
import scala.collection.Seq
import scala.collection.immutable.{Seq => ISeq}
+import xml.Nullables._
/**
* The `Utility` object provides utility functions for processing instances
@@ -78,9 +79,9 @@ object Utility extends AnyRef with parsing.TokenTests with ScalaVersionSpecificU
/** returns a sorted attribute list */
def sort(md: MetaData): MetaData = if (md.isNull || md.next.isNull) md else {
- val key: String = md.key
- val smaller: MetaData = sort(md.filter { m => m.key < key })
- val greater: MetaData = sort(md.filter { m => m.key > key })
+ val key: String = md.key.nn
+ val smaller: MetaData = sort(md.filter { m => m.key.nn < key })
+ val greater: MetaData = sort(md.filter { m => m.key.nn > key })
smaller.foldRight(md.copy(greater)) ((x, xs) => x.copy(xs))
}
@@ -137,20 +138,20 @@ object Utility extends AnyRef with parsing.TokenTests with ScalaVersionSpecificU
*
* @return `'''null'''` if `ref` was not a predefined entity.
*/
- final def unescape(ref: String, s: StringBuilder): StringBuilder =
+ final def unescape(ref: String, s: StringBuilder): Nullable[StringBuilder] =
unescMap.get(ref).map(s.append).orNull
/**
* Returns a set of all namespaces used in a sequence of nodes
* and all their descendants, including the empty namespaces.
*/
- def collectNamespaces(nodes: Seq[Node]): mutable.Set[String] =
- nodes.foldLeft(new mutable.HashSet[String]) { (set, x) => collectNamespaces(x, set); set }
+ def collectNamespaces(nodes: Seq[Node]): mutable.Set[Nullable[String]] =
+ nodes.foldLeft(new mutable.HashSet[Nullable[String]]) { (set, x) => collectNamespaces(x, set); set }
/**
* Adds all namespaces in node to set.
*/
- def collectNamespaces(n: Node, set: mutable.Set[String]): Unit =
+ def collectNamespaces(n: Node, set: mutable.Set[Nullable[String]]): Unit =
if (n.doCollectNamespaces) {
set += n.namespace
for (a <- n.attributes) a match {
@@ -222,12 +223,12 @@ object Utility extends AnyRef with parsing.TokenTests with ScalaVersionSpecificU
minimizeTags: MinimizeMode.Value,
sb: StringBuilder
): Unit = {
- @tailrec def ser(nss: List[List[Node]], pscopes: List[NamespaceBinding], spaced: List[Boolean], toClose: List[Node]): Unit = nss match {
+ @tailrec def ser(nss: List[List[Node]], pscopes: List[NamespaceBinding], spaced: List[Boolean], toClose: List[Nullable[Node]]): Unit = nss match {
case List(Nil) =>
case Nil :: rests =>
if (toClose.head != null) {
sb.append("")
- toClose.head.nameToString(sb)
+ toClose.head.nn.nameToString(sb)
sb.append('>')
}
ser(rests, pscopes.tail, spaced.tail, toClose.tail)
@@ -296,7 +297,7 @@ object Utility extends AnyRef with parsing.TokenTests with ScalaVersionSpecificU
/**
* Returns a hashcode for the given constituents of a node
*/
- def hashCode(pre: String, label: String, attribHashCode: Int, scpeHash: Int, children: Seq[Node]): Int =
+ def hashCode(pre: Nullable[String], label: Nullable[String], attribHashCode: Int, scpeHash: Int, children: Seq[Node]): Int =
scala.util.hashing.MurmurHash3.orderedHash(label +: attribHashCode +: scpeHash +: children, pre.##)
def appendQuoted(s: String): String = sbToString(appendQuoted(s, _))
@@ -323,7 +324,7 @@ object Utility extends AnyRef with parsing.TokenTests with ScalaVersionSpecificU
sb.append('"')
}
- def getName(s: String, index: Int): String =
+ def getName(s: String, index: Int): Nullable[String] =
if (index >= s.length) null else {
val xs: String = s.drop(index)
if (xs.nonEmpty && isNameStart(xs.head)) xs.takeWhile(isNameChar)
@@ -334,14 +335,14 @@ object Utility extends AnyRef with parsing.TokenTests with ScalaVersionSpecificU
* Returns `'''null'''` if the value is a correct attribute value,
* error message if it isn't.
*/
- def checkAttributeValue(value: String): String = {
+ def checkAttributeValue(value: String): Nullable[String] = {
var i: Int = 0
while (i < value.length) {
value.charAt(i) match {
case '<' =>
return "< not allowed in attribute value"
case '&' =>
- val n: String = getName(value, i + 1)
+ val n: Nullable[String] = getName(value, i + 1)
if (n == null)
return s"malformed entity reference in attribute value [$value]"
i = i + n.length + 1
@@ -357,7 +358,7 @@ object Utility extends AnyRef with parsing.TokenTests with ScalaVersionSpecificU
// unused, untested
def parseAttributeValue(value: String): ScalaVersionSpecific.SeqOfNode = {
val sb: StringBuilder = new StringBuilder
- var rfb: StringBuilder = null
+ var rfb: Nullable[StringBuilder] = null
val nb: NodeBuffer = new NodeBuffer()
val it: Iterator[Char] = value.iterator
diff --git a/shared/src/main/scala/scala/xml/XML.scala b/shared/src/main/scala/scala/xml/XML.scala
index 3dfe36b2..dff15145 100755
--- a/shared/src/main/scala/scala/xml/XML.scala
+++ b/shared/src/main/scala/scala/xml/XML.scala
@@ -17,6 +17,7 @@ import factory.XMLLoader
import java.io.{File, FileDescriptor, FileInputStream, FileOutputStream, InputStream, Reader, StringReader, Writer}
import java.nio.channels.Channels
import scala.util.control.Exception
+import xml.Nullables._
object Source {
def fromFile(name: String): InputSource = fromFile(new File(name))
@@ -96,7 +97,7 @@ object XML extends XMLLoader[Elem] {
node: Node,
enc: String = "UTF-8",
xmlDecl: Boolean = false,
- doctype: dtd.DocType = null
+ doctype: Nullable[dtd.DocType] = null
): Unit = {
val fos: FileOutputStream = new FileOutputStream(filename)
val w: Writer = Channels.newWriter(fos.getChannel, enc)
@@ -121,7 +122,7 @@ object XML extends XMLLoader[Elem] {
node: Node,
enc: String,
xmlDecl: Boolean,
- doctype: dtd.DocType,
+ doctype: Nullable[dtd.DocType],
minimizeTags: MinimizeMode.Value = MinimizeMode.Default
): Unit = {
/* TODO: optimize by giving writer parameter to toXML*/
diff --git a/shared/src/main/scala/scala/xml/dtd/DTD.scala b/shared/src/main/scala/scala/xml/dtd/DTD.scala
index 9b334a8d..fd9c22bd 100644
--- a/shared/src/main/scala/scala/xml/dtd/DTD.scala
+++ b/shared/src/main/scala/scala/xml/dtd/DTD.scala
@@ -14,6 +14,7 @@ package scala
package xml
package dtd
+import xml.Nullables._
import scala.collection.mutable
import scala.collection.Seq
@@ -23,7 +24,7 @@ import scala.collection.Seq
* @author Burak Emir
*/
abstract class DTD {
- var externalID: ExternalID = _
+ var externalID: Nullable[ExternalID] = _
var decls: List[Decl] = Nil
def notations: Seq[NotationDecl] = Nil
def unparsedEntities: Seq[EntityDecl] = Nil
diff --git a/shared/src/main/scala/scala/xml/dtd/Decl.scala b/shared/src/main/scala/scala/xml/dtd/Decl.scala
index c2cf53e1..1965c4e9 100644
--- a/shared/src/main/scala/scala/xml/dtd/Decl.scala
+++ b/shared/src/main/scala/scala/xml/dtd/Decl.scala
@@ -15,6 +15,7 @@ package xml
package dtd
import Utility.sbToString
+import xml.Nullables._
/**
* XML declarations
@@ -55,12 +56,12 @@ case class AttListDecl(name: String, attrs: List[AttrDecl]) extends MarkupDecl {
* versions might provide a way to access the attribute types more
* directly.
*/
-case class AttrDecl(name: String, tpe: String, default: DefaultDecl) {
+case class AttrDecl(name: String, tpe: String, default: Nullable[DefaultDecl]) {
override def toString: String = sbToString(buildString)
def buildString(sb: StringBuilder): StringBuilder = {
sb.append(s" $name $tpe ")
- default.buildString(sb)
+ default.nn.buildString(sb)
}
}
diff --git a/shared/src/main/scala/scala/xml/dtd/ExternalID.scala b/shared/src/main/scala/scala/xml/dtd/ExternalID.scala
index 80b9da86..5913558f 100644
--- a/shared/src/main/scala/scala/xml/dtd/ExternalID.scala
+++ b/shared/src/main/scala/scala/xml/dtd/ExternalID.scala
@@ -13,6 +13,7 @@
package scala
package xml
package dtd
+import xml.Nullables._
/**
* an ExternalIDs - either PublicID or SystemID
@@ -20,8 +21,8 @@ package dtd
* @author Burak Emir
*/
sealed abstract class ExternalID extends parsing.TokenTests {
- def quoted(s: String): String = {
- val c: Char = if (s.contains('"')) '\'' else '"'
+ def quoted(s: Nullable[String]): String = {
+ val c: Char = if (s.nn.contains('"')) '\'' else '"'
s"$c$s$c"
}
@@ -35,8 +36,8 @@ sealed abstract class ExternalID extends parsing.TokenTests {
def buildString(sb: StringBuilder): StringBuilder =
sb.append(this.toString)
- def systemId: String
- def publicId: String
+ def systemId: Nullable[String]
+ def publicId: Nullable[String]
}
/**
@@ -59,7 +60,7 @@ case class SystemID(override val systemId: String) extends ExternalID {
* @param publicId the public identifier literal
* @param systemId (can be null for notation pubIDs) the system identifier literal
*/
-case class PublicID(override val publicId: String, override val systemId: String) extends ExternalID {
+case class PublicID(override val publicId: String, override val systemId: Nullable[String]) extends ExternalID {
if (!checkPubID(publicId))
throw new IllegalArgumentException("publicId must consist of PubidChars")
@@ -82,8 +83,8 @@ case class PublicID(override val publicId: String, override val systemId: String
* @author Michael Bayne
*/
object NoExternalID extends ExternalID {
- override val publicId: ScalaVersionSpecificReturnTypes.NoExternalIDId = null
- override val systemId: ScalaVersionSpecificReturnTypes.NoExternalIDId = null
+ override val publicId: Nullable[ScalaVersionSpecificReturnTypes.NoExternalIDId] = null
+ override val systemId: Nullable[ScalaVersionSpecificReturnTypes.NoExternalIDId] = null
override def toString: String = ""
}
diff --git a/shared/src/main/scala/scala/xml/include/CircularIncludeException.scala b/shared/src/main/scala/scala/xml/include/CircularIncludeException.scala
index ecff559d..0039a447 100644
--- a/shared/src/main/scala/scala/xml/include/CircularIncludeException.scala
+++ b/shared/src/main/scala/scala/xml/include/CircularIncludeException.scala
@@ -14,11 +14,13 @@ package scala
package xml
package include
+import xml.Nullables._
+
/**
* A `CircularIncludeException` is thrown when an included document attempts
* to include itself or one of its ancestor documents.
*/
-class CircularIncludeException(message: String) extends XIncludeException {
+class CircularIncludeException(message: Nullable[String]) extends XIncludeException {
/**
* Constructs a `CircularIncludeException` with `'''null'''`.
diff --git a/shared/src/main/scala/scala/xml/include/UnavailableResourceException.scala b/shared/src/main/scala/scala/xml/include/UnavailableResourceException.scala
index 7499a3f1..883ee816 100644
--- a/shared/src/main/scala/scala/xml/include/UnavailableResourceException.scala
+++ b/shared/src/main/scala/scala/xml/include/UnavailableResourceException.scala
@@ -14,11 +14,13 @@ package scala
package xml
package include
+import xml.Nullables._
+
/**
* An `UnavailableResourceException` is thrown when an included document
* cannot be found or loaded.
*/
-class UnavailableResourceException(message: String)
+class UnavailableResourceException(message: Nullable[String])
extends XIncludeException(message) {
def this() = this(null)
}
diff --git a/shared/src/main/scala/scala/xml/include/XIncludeException.scala b/shared/src/main/scala/scala/xml/include/XIncludeException.scala
index 4d2a809c..a8d4fe21 100644
--- a/shared/src/main/scala/scala/xml/include/XIncludeException.scala
+++ b/shared/src/main/scala/scala/xml/include/XIncludeException.scala
@@ -14,6 +14,8 @@ package scala
package xml
package include
+import xml.Nullables._
+
/**
* `XIncludeException` is the generic superclass for all checked exceptions
* that may be thrown as a result of a violation of XInclude's rules.
@@ -25,14 +27,14 @@ package include
*
* @param message the detail message.
*/
-class XIncludeException(message: String) extends Exception(message) {
+class XIncludeException(message: Nullable[String]) extends Exception(message) {
/**
* uses `'''null'''` as its error detail message.
*/
def this() = this(null)
- private var rootCause: Throwable = _
+ private var rootCause: Nullable[Throwable] = _
/**
* When an `IOException`, `MalformedURLException` or other generic
@@ -57,5 +59,5 @@ class XIncludeException(message: String) extends Exception(message) {
* @return Throwable the underlying exception which caused the
* `XIncludeException` to be thrown
*/
- def getRootCause: Throwable = this.rootCause
+ def getRootCause: Nullable[Throwable] = this.rootCause
}
diff --git a/shared/src/main/scala/scala/xml/include/sax/EncodingHeuristics.scala b/shared/src/main/scala/scala/xml/include/sax/EncodingHeuristics.scala
index fe8b0e32..63f89b06 100644
--- a/shared/src/main/scala/scala/xml/include/sax/EncodingHeuristics.scala
+++ b/shared/src/main/scala/scala/xml/include/sax/EncodingHeuristics.scala
@@ -16,6 +16,7 @@ package include.sax
import java.io.InputStream
import scala.util.matching.Regex
+import xml.Nullables._
/**
* `EncodingHeuristics` reads from a stream
@@ -50,9 +51,9 @@ object EncodingHeuristics {
* @return the name of the encoding.
*/
def readEncodingFromStream(in: InputStream): String = {
- var ret: String = null
+ var ret: Nullable[String] = null
val bytesToRead: Int = 1024 // enough to read most XML encoding declarations
- def resetAndRet: String = { in.reset(); ret }
+ def resetAndRet: Nullable[String] = { in.reset(); ret }
// This may fail if there are a lot of space characters before the end
// of the encoding declaration
@@ -71,7 +72,7 @@ object EncodingHeuristics {
case _ => null
}
if (ret != null)
- return resetAndRet
+ return resetAndRet.nn
def readASCIIEncoding: String = {
val data: Array[Byte] = new Array[Byte](bytesToRead - 4)
@@ -98,6 +99,6 @@ object EncodingHeuristics {
case (0x4C, 0x6F, 0xA7, 0x94) => utf8 // XXX EBCDIC
case _ => utf8 // no XML or text declaration present
}
- resetAndRet
+ resetAndRet.nn
}
}
diff --git a/shared/src/main/scala/scala/xml/include/sax/XIncludeFilter.scala b/shared/src/main/scala/scala/xml/include/sax/XIncludeFilter.scala
index b82414d6..71c4df8b 100644
--- a/shared/src/main/scala/scala/xml/include/sax/XIncludeFilter.scala
+++ b/shared/src/main/scala/scala/xml/include/sax/XIncludeFilter.scala
@@ -15,6 +15,7 @@ package xml
package include.sax
import scala.xml.include._
+import xml.Nullables._
import org.xml.sax.{Attributes, Locator, XMLReader}
import org.xml.sax.helpers.{AttributesImpl, NamespaceSupport, XMLFilterImpl, XMLReaderFactory}
@@ -250,7 +251,7 @@ class XIncludeFilter extends XMLFilterImpl {
private def includeTextDocument(url: String, encoding1: String): Unit = {
var encoding: String = encoding1
if (encoding == null || encoding.trim.isEmpty) encoding = "UTF-8"
- var source: URL = null
+ var source: Nullable[URL] = null
try {
val base: URL = bases.peek
source = new URL(base, url)
@@ -262,7 +263,7 @@ class XIncludeFilter extends XMLFilterImpl {
}
try {
- val uc: URLConnection = source.openConnection
+ val uc: URLConnection = source.nn.openConnection
val in: BufferedInputStream = new BufferedInputStream(uc.getInputStream)
val encodingFromHeader: String = uc.getContentEncoding
var contentType: String = uc.getContentType
@@ -293,7 +294,7 @@ class XIncludeFilter extends XMLFilterImpl {
case e: UnsupportedEncodingException =>
throw new SAXException(s"Unsupported encoding: $encoding$getLocation", e)
case e: IOException =>
- throw new SAXException(s"Document not found: ${source.toExternalForm}$getLocation", e)
+ throw new SAXException(s"Document not found: ${source.nn.toExternalForm}$getLocation", e)
}
}
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 ec94be79..7b9809bd 100644
--- a/shared/src/main/scala/scala/xml/include/sax/XIncluder.scala
+++ b/shared/src/main/scala/scala/xml/include/sax/XIncluder.scala
@@ -14,6 +14,7 @@ package scala
package xml
package include.sax
+import xml.Nullables._
import org.xml.sax.{ ContentHandler, Locator, Attributes }
import org.xml.sax.ext.LexicalHandler
import java.io.{ OutputStream, OutputStreamWriter, IOException }
@@ -159,14 +160,14 @@ class XIncluder(outs: OutputStream, encoding: String) extends ContentHandler wit
// Just need this reference so we can ask if a comment is
// inside an include element or not
- private var filter: XIncludeFilter = _
+ private var filter: Nullable[XIncludeFilter] = _
def setFilter(filter: XIncludeFilter): Unit = {
this.filter = filter
}
override def comment(ch: Array[Char], start: Int, length: Int): Unit = {
- if (!inDTD && !filter.insideIncludeElement) {
+ if (!inDTD && !filter.nn.insideIncludeElement) {
try {
out.write("