From 9d26606e741c701dbc7f042037809fc6a0240f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Cant=C3=BA?= Date: Thu, 20 Aug 2020 01:56:14 -0700 Subject: [PATCH] Add nullability annotations to System.Private.Xml.Linq project (#40744) * Add nullability annotations to Xml.Linq project * Fix misplaced assertion * Address feedback * Add missing NotNullIfNotNull attributes to operators --- .../src/System.Private.Xml.Linq.csproj | 1 + .../src/System/Xml/Linq/Extensions.cs | 102 ++++---- .../src/System/Xml/Linq/XAttribute.cs | 51 ++-- .../src/System/Xml/Linq/XComment.cs | 2 +- .../src/System/Xml/Linq/XContainer.cs | 185 +++++++------- .../src/System/Xml/Linq/XDeclaration.cs | 14 +- .../src/System/Xml/Linq/XDocument.cs | 32 +-- .../src/System/Xml/Linq/XDocumentType.cs | 16 +- .../src/System/Xml/Linq/XElement.cs | 146 ++++++----- .../src/System/Xml/Linq/XHashtable.cs | 13 +- .../src/System/Xml/Linq/XHelper.cs | 2 +- .../src/System/Xml/Linq/XLinq.cs | 120 ++++----- .../src/System/Xml/Linq/XName.cs | 18 +- .../src/System/Xml/Linq/XNamespace.cs | 42 ++-- .../src/System/Xml/Linq/XNode.cs | 84 +++---- .../src/System/Xml/Linq/XNodeBuilder.cs | 46 ++-- .../Xml/Linq/XNodeDocumentOrderComparer.cs | 8 +- .../System/Xml/Linq/XNodeEqualityComparer.cs | 12 +- .../src/System/Xml/Linq/XNodeReader.cs | 231 +++++++++--------- .../src/System/Xml/Linq/XObject.cs | 85 +++---- .../Xml/Linq/XObjectChangeAnnotation.cs | 4 +- .../System/Xml/Linq/XProcessingInstruction.cs | 2 +- .../src/System/Xml/Linq/XStreamingElement.cs | 6 +- .../src/System/Xml/Schema/XNodeValidator.cs | 161 ++++++------ .../src/System/Xml/XPath/XNodeNavigator.cs | 156 ++++++------ .../src/System/Xml/XPath/XObjectExtensions.cs | 4 +- .../src/System/Xml/XPath/XPathNavigator.cs | 4 +- 27 files changed, 809 insertions(+), 738 deletions(-) diff --git a/src/libraries/System.Private.Xml.Linq/src/System.Private.Xml.Linq.csproj b/src/libraries/System.Private.Xml.Linq/src/System.Private.Xml.Linq.csproj index 4db38b8700d29d..a174b927459d72 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System.Private.Xml.Linq.csproj +++ b/src/libraries/System.Private.Xml.Linq/src/System.Private.Xml.Linq.csproj @@ -2,6 +2,7 @@ System.Xml $(NetCoreAppCurrent) + enable in the target /// of . /// - public static IEnumerable Attributes(this IEnumerable source) + public static IEnumerable Attributes(this IEnumerable source) { if (source == null) throw new ArgumentNullException(nameof(source)); return GetAttributes(source, null); @@ -37,7 +37,7 @@ public static IEnumerable Attributes(this IEnumerable sour /// Attributes with a matching for every in /// the target of . /// - public static IEnumerable Attributes(this IEnumerable source, XName name) + public static IEnumerable Attributes(this IEnumerable source, XName? name) { if (source == null) throw new ArgumentNullException(nameof(source)); return name != null ? GetAttributes(source, name) : XAttribute.EmptySequence; @@ -53,7 +53,7 @@ public static IEnumerable Attributes(this IEnumerable sour /// and it's parent up to the root) of each of the s in this /// of . /// - public static IEnumerable Ancestors(this IEnumerable source) where T : XNode + public static IEnumerable Ancestors(this IEnumerable source) where T : XNode { if (source == null) throw new ArgumentNullException(nameof(source)); return GetAncestors(source, null, false); @@ -69,7 +69,7 @@ public static IEnumerable Ancestors(this IEnumerable source) whe /// and it's parent up to the root) that have a matching . This is done for each /// in this of . /// - public static IEnumerable Ancestors(this IEnumerable source, XName name) where T : XNode + public static IEnumerable Ancestors(this IEnumerable source, XName? name) where T : XNode { if (source == null) throw new ArgumentNullException(nameof(source)); return name != null ? GetAncestors(source, name, false) : XElement.EmptySequence; @@ -87,7 +87,7 @@ public static IEnumerable Ancestors(this IEnumerable source, XNa /// This is done for each in this of /// . /// - public static IEnumerable AncestorsAndSelf(this IEnumerable source) + public static IEnumerable AncestorsAndSelf(this IEnumerable source) { if (source == null) throw new ArgumentNullException(nameof(source)); return GetAncestors(source, null, true); @@ -105,7 +105,7 @@ public static IEnumerable AncestorsAndSelf(this IEnumerable /// that match the passed in . This is done for each /// in this of . /// - public static IEnumerable AncestorsAndSelf(this IEnumerable source, XName name) + public static IEnumerable AncestorsAndSelf(this IEnumerable source, XName? name) { if (source == null) throw new ArgumentNullException(nameof(source)); return name != null ? GetAncestors(source, name, true) : XElement.EmptySequence; @@ -114,24 +114,24 @@ public static IEnumerable AncestorsAndSelf(this IEnumerable /// /// Returns an of over the content of a set of nodes /// - public static IEnumerable Nodes(this IEnumerable source) where T : XContainer + public static IEnumerable Nodes(this IEnumerable source) where T : XContainer { if (source == null) throw new ArgumentNullException(nameof(source)); return NodesIterator(source); } - private static IEnumerable NodesIterator(IEnumerable source) where T : XContainer + private static IEnumerable NodesIterator(IEnumerable source) where T : XContainer { - foreach (XContainer root in source) + foreach (XContainer? root in source) { if (root != null) { - XNode n = root.LastNode; + XNode? n = root.LastNode; if (n != null) { do { - n = n.next; + n = n.next!; yield return n; } while (n.parent == root && n != root.content); } @@ -142,7 +142,7 @@ private static IEnumerable NodesIterator(IEnumerable source) where /// /// Returns an of over the descendants of a set of nodes /// - public static IEnumerable DescendantNodes(this IEnumerable source) where T : XContainer + public static IEnumerable DescendantNodes(this IEnumerable source) where T : XContainer { if (source == null) throw new ArgumentNullException(nameof(source)); return GetDescendantNodes(source, false); @@ -158,7 +158,7 @@ public static IEnumerable DescendantNodes(this IEnumerable source) /// and their children down to the leaf level). This is done for each in /// this of . /// - public static IEnumerable Descendants(this IEnumerable source) where T : XContainer + public static IEnumerable Descendants(this IEnumerable source) where T : XContainer { if (source == null) throw new ArgumentNullException(nameof(source)); return GetDescendants(source, null, false); @@ -174,7 +174,7 @@ public static IEnumerable Descendants(this IEnumerable source) w /// and their children down to the leaf level) that have a matching . This is done /// for each in this of . /// - public static IEnumerable Descendants(this IEnumerable source, XName name) where T : XContainer + public static IEnumerable Descendants(this IEnumerable source, XName? name) where T : XContainer { if (source == null) throw new ArgumentNullException(nameof(source)); return name != null ? GetDescendants(source, name, false) : XElement.EmptySequence; @@ -192,7 +192,7 @@ public static IEnumerable Descendants(this IEnumerable source, X /// This is done for each /// in this of . /// - public static IEnumerable DescendantNodesAndSelf(this IEnumerable source) + public static IEnumerable DescendantNodesAndSelf(this IEnumerable source) { if (source == null) throw new ArgumentNullException(nameof(source)); return GetDescendantNodes(source, true); @@ -210,7 +210,7 @@ public static IEnumerable DescendantNodesAndSelf(this IEnumerable in this /// of . /// - public static IEnumerable DescendantsAndSelf(this IEnumerable source) + public static IEnumerable DescendantsAndSelf(this IEnumerable source) { if (source == null) throw new ArgumentNullException(nameof(source)); return GetDescendants(source, null, true); @@ -228,7 +228,7 @@ public static IEnumerable DescendantsAndSelf(this IEnumerable. This is done for /// each in this of . /// - public static IEnumerable DescendantsAndSelf(this IEnumerable source, XName name) + public static IEnumerable DescendantsAndSelf(this IEnumerable source, XName? name) { if (source == null) throw new ArgumentNullException(nameof(source)); return name != null ? GetDescendants(source, name, true) : XElement.EmptySequence; @@ -242,7 +242,7 @@ public static IEnumerable DescendantsAndSelf(this IEnumerable of containing the child elements /// for each in this of . /// - public static IEnumerable Elements(this IEnumerable source) where T : XContainer + public static IEnumerable Elements(this IEnumerable source) where T : XContainer { if (source == null) throw new ArgumentNullException(nameof(source)); return GetElements(source, null); @@ -256,7 +256,7 @@ public static IEnumerable Elements(this IEnumerable source) wher /// An of containing the child elements /// for each in this of . /// - public static IEnumerable Elements(this IEnumerable source, XName name) where T : XContainer + public static IEnumerable Elements(this IEnumerable source, XName? name) where T : XContainer { if (source == null) throw new ArgumentNullException(nameof(source)); return name != null ? GetElements(source, name) : XElement.EmptySequence; @@ -277,6 +277,8 @@ public static IEnumerable InDocumentOrder(this IEnumerable source) wher return DocumentOrderIterator(source); } + // TODO-NULLABLE: Consider changing to T? instead. + // If we do it, we will also need to change XNodeDocumentOrderComparer to implement IComparer instead. private static IEnumerable DocumentOrderIterator(IEnumerable source) where T : XNode { int count; @@ -293,15 +295,15 @@ private static IEnumerable DocumentOrderIterator(IEnumerable source) wh /// . Note that this method uses snapshot semantics (copies the /// attributes to an array before deleting each). /// - public static void Remove(this IEnumerable source) + public static void Remove(this IEnumerable source) { if (source == null) throw new ArgumentNullException(nameof(source)); int count; - XAttribute[] attributes = EnumerableHelpers.ToArray(source, out count); + XAttribute?[] attributes = EnumerableHelpers.ToArray(source, out count); for (int i = 0; i < count; i++) { - XAttribute a = attributes[i]; + XAttribute? a = attributes[i]; if (a != null) a.Remove(); } } @@ -311,31 +313,31 @@ public static void Remove(this IEnumerable source) /// T which must be a derived from . Note that this method uses snapshot semantics /// (copies the s to an array before deleting each). /// - public static void Remove(this IEnumerable source) where T : XNode + public static void Remove(this IEnumerable source) where T : XNode { if (source == null) throw new ArgumentNullException(nameof(source)); int count; - T[] nodes = EnumerableHelpers.ToArray(source, out count); + T?[] nodes = EnumerableHelpers.ToArray(source, out count); for (int i = 0; i < count; i++) { - T node = nodes[i]; + T? node = nodes[i]; if (node != null) node.Remove(); } } - private static IEnumerable GetAttributes(IEnumerable source, XName name) + private static IEnumerable GetAttributes(IEnumerable source, XName? name) { - foreach (XElement e in source) + foreach (XElement? e in source) { if (e != null) { - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (name == null || a.name == name) yield return a; } while (a.parent == e && a != e.lastAttr); } @@ -343,13 +345,13 @@ private static IEnumerable GetAttributes(IEnumerable sourc } } - private static IEnumerable GetAncestors(IEnumerable source, XName name, bool self) where T : XNode + private static IEnumerable GetAncestors(IEnumerable source, XName? name, bool self) where T : XNode { - foreach (XNode node in source) + foreach (XNode? node in source) { if (node != null) { - XElement e = (self ? node : node.parent) as XElement; + XElement? e = (self ? node : node.parent) as XElement; while (e != null) { if (name == null || e.name == name) yield return e; @@ -359,27 +361,27 @@ private static IEnumerable GetAncestors(IEnumerable source, XNam } } - private static IEnumerable GetDescendantNodes(IEnumerable source, bool self) where T : XContainer + private static IEnumerable GetDescendantNodes(IEnumerable source, bool self) where T : XContainer { - foreach (XContainer root in source) + foreach (XContainer? root in source) { if (root != null) { if (self) yield return root; - XNode n = root; + XNode? n = root; while (true) { - XContainer c = n as XContainer; - XNode first; + XContainer? c = n as XContainer; + XNode? first; if (c != null && (first = c.FirstNode) != null) { n = first; } else { - while (n != null && n != root && n == n.parent.content) n = n.parent; + while (n != null && n != root && n == n.parent!.content) n = n.parent; if (n == null || n == root) break; - n = n.next; + n = n.next!; } yield return n; } @@ -387,9 +389,9 @@ private static IEnumerable GetDescendantNodes(IEnumerable source, b } } - private static IEnumerable GetDescendants(IEnumerable source, XName name, bool self) where T : XContainer + private static IEnumerable GetDescendants(IEnumerable source, XName? name, bool self) where T : XContainer { - foreach (XContainer root in source) + foreach (XContainer? root in source) { if (root != null) { @@ -398,8 +400,8 @@ private static IEnumerable GetDescendants(IEnumerable source, XN XElement e = (XElement)root; if (name == null || e.name == name) yield return e; } - XNode n = root; - XContainer c = root; + XNode? n = root; + XContainer? c = root; while (true) { if (c != null && c.content is XNode) @@ -408,11 +410,11 @@ private static IEnumerable GetDescendants(IEnumerable source, XN } else { - while (n != null && n != root && n == n.parent.content) n = n.parent; + while (n != null && n != root && n == n.parent!.content) n = n.parent; if (n == null || n == root) break; n = n.next; } - XElement e = n as XElement; + XElement? e = n as XElement; if (e != null && (name == null || e.name == name)) yield return e; c = e; } @@ -420,19 +422,19 @@ private static IEnumerable GetDescendants(IEnumerable source, XN } } - private static IEnumerable GetElements(IEnumerable source, XName name) where T : XContainer + private static IEnumerable GetElements(IEnumerable source, XName? name) where T : XContainer { - foreach (XContainer root in source) + foreach (XContainer? root in source) { if (root != null) { - XNode n = root.content as XNode; + XNode? n = root.content as XNode; if (n != null) { do { - n = n.next; - XElement e = n as XElement; + n = n.next!; + XElement? e = n as XElement; if (e != null && (name == null || e.name == name)) yield return e; } while (n.parent == root && n != root.content); } diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XAttribute.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XAttribute.cs index 0fde359789c234..deb5138f07d7fc 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XAttribute.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XAttribute.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using CultureInfo = System.Globalization.CultureInfo; @@ -29,7 +31,7 @@ public static IEnumerable EmptySequence } } - internal XAttribute next; + internal XAttribute? next; internal XName name; internal string value; @@ -105,7 +107,7 @@ public XName Name /// If this attribute does not have a parent, or if there is no next attribute, /// then this property returns null. /// - public XAttribute NextAttribute + public XAttribute? NextAttribute { get { return parent != null && ((XElement)parent).lastAttr != this ? next : null; } } @@ -131,15 +133,15 @@ public override XmlNodeType NodeType /// If this attribute does not have a parent, or if there is no previous attribute, /// then this property returns null. /// - public XAttribute PreviousAttribute + public XAttribute? PreviousAttribute { get { if (parent == null) return null; - XAttribute a = ((XElement)parent).lastAttr; + XAttribute a = ((XElement)parent).lastAttr!; while (a.next != this) { - a = a.next; + a = a.next!; } return a != ((XElement)parent).lastAttr ? a : null; } @@ -226,7 +228,8 @@ public override string ToString() /// The content of this as a . /// [CLSCompliant(false)] - public static explicit operator string(XAttribute attribute) + [return: NotNullIfNotNull("attribute")] + public static explicit operator string?(XAttribute? attribute) { if (attribute == null) return null; return attribute.value; @@ -261,7 +264,8 @@ public static explicit operator bool(XAttribute attribute) /// The content of this as a ?. /// [CLSCompliant(false)] - public static explicit operator bool?(XAttribute attribute) + [return: NotNullIfNotNull("attribute")] + public static explicit operator bool?(XAttribute? attribute) { if (attribute == null) return null; return XmlConvert.ToBoolean(attribute.value.ToLowerInvariant()); @@ -296,6 +300,7 @@ public static explicit operator int(XAttribute attribute) /// The content of this as an ?. /// [CLSCompliant(false)] + [return: NotNullIfNotNull("attribute")] public static explicit operator int?(XAttribute attribute) { if (attribute == null) return null; @@ -331,7 +336,8 @@ public static explicit operator uint(XAttribute attribute) /// The content of this as an ?. /// [CLSCompliant(false)] - public static explicit operator uint?(XAttribute attribute) + [return: NotNullIfNotNull("attribute")] + public static explicit operator uint?(XAttribute? attribute) { if (attribute == null) return null; return XmlConvert.ToUInt32(attribute.value); @@ -366,7 +372,8 @@ public static explicit operator long(XAttribute attribute) /// The content of this as a ?. /// [CLSCompliant(false)] - public static explicit operator long?(XAttribute attribute) + [return: NotNullIfNotNull("attribute")] + public static explicit operator long?(XAttribute? attribute) { if (attribute == null) return null; return XmlConvert.ToInt64(attribute.value); @@ -401,7 +408,8 @@ public static explicit operator ulong(XAttribute attribute) /// The content of this as an ?. /// [CLSCompliant(false)] - public static explicit operator ulong?(XAttribute attribute) + [return: NotNullIfNotNull("attribute")] + public static explicit operator ulong?(XAttribute? attribute) { if (attribute == null) return null; return XmlConvert.ToUInt64(attribute.value); @@ -436,7 +444,8 @@ public static explicit operator float(XAttribute attribute) /// The content of this as a ?. /// [CLSCompliant(false)] - public static explicit operator float?(XAttribute attribute) + [return: NotNullIfNotNull("attribute")] + public static explicit operator float?(XAttribute? attribute) { if (attribute == null) return null; return XmlConvert.ToSingle(attribute.value); @@ -471,7 +480,8 @@ public static explicit operator double(XAttribute attribute) /// The content of this as a ?. /// [CLSCompliant(false)] - public static explicit operator double?(XAttribute attribute) + [return: NotNullIfNotNull("attribute")] + public static explicit operator double?(XAttribute? attribute) { if (attribute == null) return null; return XmlConvert.ToDouble(attribute.value); @@ -506,7 +516,8 @@ public static explicit operator decimal(XAttribute attribute) /// The content of this as a ?. /// [CLSCompliant(false)] - public static explicit operator decimal?(XAttribute attribute) + [return: NotNullIfNotNull("attribute")] + public static explicit operator decimal?(XAttribute? attribute) { if (attribute == null) return null; return XmlConvert.ToDecimal(attribute.value); @@ -541,7 +552,8 @@ public static explicit operator DateTime(XAttribute attribute) /// The content of this as a ?. /// [CLSCompliant(false)] - public static explicit operator DateTime?(XAttribute attribute) + [return: NotNullIfNotNull("attribute")] + public static explicit operator DateTime?(XAttribute? attribute) { if (attribute == null) return null; return DateTime.Parse(attribute.value, CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.RoundtripKind); @@ -576,7 +588,8 @@ public static explicit operator DateTimeOffset(XAttribute attribute) /// The content of this as a ?. /// [CLSCompliant(false)] - public static explicit operator DateTimeOffset?(XAttribute attribute) + [return: NotNullIfNotNull("attribute")] + public static explicit operator DateTimeOffset?(XAttribute? attribute) { if (attribute == null) return null; return XmlConvert.ToDateTimeOffset(attribute.value); @@ -611,7 +624,8 @@ public static explicit operator TimeSpan(XAttribute attribute) /// The content of this as a ?. /// [CLSCompliant(false)] - public static explicit operator TimeSpan?(XAttribute attribute) + [return: NotNullIfNotNull("attribute")] + public static explicit operator TimeSpan?(XAttribute? attribute) { if (attribute == null) return null; return XmlConvert.ToTimeSpan(attribute.value); @@ -646,7 +660,8 @@ public static explicit operator Guid(XAttribute attribute) /// The content of this as a ?. /// [CLSCompliant(false)] - public static explicit operator Guid?(XAttribute attribute) + [return: NotNullIfNotNull("attribute")] + public static explicit operator Guid?(XAttribute? attribute) { if (attribute == null) return null; return XmlConvert.ToGuid(attribute.value); @@ -657,7 +672,7 @@ internal int GetDeepHashCode() return name.GetHashCode() ^ value.GetHashCode(); } - internal string GetPrefixOfNamespace(XNamespace ns) + internal string? GetPrefixOfNamespace(XNamespace ns) { string namespaceName = ns.NamespaceName; if (namespaceName.Length == 0) return string.Empty; diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XComment.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XComment.cs index 9f566c756b603d..dbb8ba0f9108a1 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XComment.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XComment.cs @@ -118,7 +118,7 @@ internal override XNode CloneNode() internal override bool DeepEquals(XNode node) { - XComment other = node as XComment; + XComment? other = node as XComment; return other != null && value == other.value; } diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs index d1fed61e1e1640..325c00d90cfc91 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs @@ -9,6 +9,7 @@ using IEnumerable = System.Collections.IEnumerable; using StringBuilder = System.Text.StringBuilder; using Interlocked = System.Threading.Interlocked; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Linq { @@ -21,7 +22,7 @@ namespace System.Xml.Linq /// public abstract class XContainer : XNode { - internal object content; + internal object? content; internal XContainer() { } @@ -34,12 +35,12 @@ internal XContainer(XContainer other) } else { - XNode n = (XNode)other.content; + XNode? n = (XNode?)other.content; if (n != null) { do { - n = n.next; + n = n.next!; AppendNodeSkipNotify(n.CloneNode()); } while (n != other.content); } @@ -49,11 +50,11 @@ internal XContainer(XContainer other) /// /// Get the first child node of this node. /// - public XNode FirstNode + public XNode? FirstNode { get { - XNode last = LastNode; + XNode? last = LastNode; return last != null ? last.next : null; } } @@ -61,14 +62,14 @@ public XNode FirstNode /// /// Get the last child node of this node. /// - public XNode LastNode + public XNode? LastNode { get { if (content == null) return null; - XNode n = content as XNode; + XNode? n = content as XNode; if (n != null) return n; - string s = content as string; + string? s = content as string; if (s != null) { if (s.Length == 0) return null; @@ -132,7 +133,7 @@ public XNode LastNode /// An added attribute must have a unique name within the element to /// which it is being added. /// - public void Add(object content) + public void Add(object? content) { if (SkipNotify()) { @@ -140,37 +141,37 @@ public void Add(object content) return; } if (content == null) return; - XNode n = content as XNode; + XNode? n = content as XNode; if (n != null) { AddNode(n); return; } - string s = content as string; + string? s = content as string; if (s != null) { AddString(s); return; } - XAttribute a = content as XAttribute; + XAttribute? a = content as XAttribute; if (a != null) { AddAttribute(a); return; } - XStreamingElement x = content as XStreamingElement; + XStreamingElement? x = content as XStreamingElement; if (x != null) { AddNode(new XElement(x)); return; } - object[] o = content as object[]; + object[]? o = content as object[]; if (o != null) { foreach (object obj in o) Add(obj); return; } - IEnumerable e = content as IEnumerable; + IEnumerable? e = content as IEnumerable; if (e != null) { foreach (object obj in e) Add(obj); @@ -210,7 +211,7 @@ public void Add(params object[] content) /// See for details about the content that can be added /// using this method. /// - public void AddFirst(object content) + public void AddFirst(object? content) { new Inserter(this, null).Add(content); } @@ -275,7 +276,7 @@ public IEnumerable Descendants() /// /// The to match against descendant s. /// An of - public IEnumerable Descendants(XName name) + public IEnumerable Descendants(XName? name) { return name != null ? GetDescendants(name, false) : XElement.EmptySequence; } @@ -291,15 +292,15 @@ public IEnumerable Descendants(XName name) /// /// An child that matches the passed in, or null. /// - public XElement Element(XName name) + public XElement? Element(XName name) { - XNode n = content as XNode; + XNode? n = content as XNode; if (n != null) { do { - n = n.next; - XElement e = n as XElement; + n = n.next!; + XElement? e = n as XElement; if (e != null && e.name == name) return e; } while (n != content); } @@ -330,7 +331,7 @@ public IEnumerable Elements() /// An of children of this that have /// a matching . /// - public IEnumerable Elements(XName name) + public IEnumerable Elements(XName? name) { return name != null ? GetElements(name) : XElement.EmptySequence; } @@ -348,12 +349,12 @@ public IEnumerable Elements(XName name) /// The contents of this public IEnumerable Nodes() { - XNode n = LastNode; + XNode? n = LastNode; if (n != null) { do { - n = n.next; + n = n.next!; yield return n; } while (n.parent == this && n != content); } @@ -373,7 +374,7 @@ public void RemoveNodes() } while (content != null) { - string s = content as string; + string? s = content as string; if (s != null) { if (s.Length > 0) @@ -397,10 +398,10 @@ public void RemoveNodes() } } } - XNode last = content as XNode; + XNode? last = content as XNode; if (last != null) { - XNode n = last.next; + XNode n = last.next!; NotifyChanging(n, XObjectChangeEventArgs.Remove); if (last != content || n != last.next) throw new InvalidOperationException(SR.InvalidOperation_ExternalCode); if (n != last) @@ -434,7 +435,7 @@ public void RemoveNodes() /// See XContainer.Add(object content) for details about the content that can be added /// using this method. /// - public void ReplaceNodes(object content) + public void ReplaceNodes(object? content) { content = GetContentSnapshot(content); RemoveNodes(); @@ -464,40 +465,40 @@ internal virtual void AddAttributeSkipNotify(XAttribute a) { } - internal void AddContentSkipNotify(object content) + internal void AddContentSkipNotify(object? content) { if (content == null) return; - XNode n = content as XNode; + XNode? n = content as XNode; if (n != null) { AddNodeSkipNotify(n); return; } - string s = content as string; + string? s = content as string; if (s != null) { AddStringSkipNotify(s); return; } - XAttribute a = content as XAttribute; + XAttribute? a = content as XAttribute; if (a != null) { AddAttributeSkipNotify(a); return; } - XStreamingElement x = content as XStreamingElement; + XStreamingElement? x = content as XStreamingElement; if (x != null) { AddNodeSkipNotify(new XElement(x)); return; } - object[] o = content as object[]; + object[]? o = content as object[]; if (o != null) { foreach (object obj in o) AddContentSkipNotify(obj); return; } - IEnumerable e = content as IEnumerable; + IEnumerable? e = content as IEnumerable; if (e != null) { foreach (object obj in e) AddContentSkipNotify(obj); @@ -569,7 +570,7 @@ internal void AddString(string s) else if (s.Length > 0) { ConvertTextToNode(); - XText tn = content as XText; + XText? tn = content as XText; if (tn != null && !(tn is XCData)) { tn.Value += s; @@ -590,14 +591,14 @@ internal void AddStringSkipNotify(string s) } else if (s.Length > 0) { - string stringContent = content as string; + string? stringContent = content as string; if (stringContent != null) { content = stringContent + s; } else { - XText tn = content as XText; + XText? tn = content as XText; if (tn != null && !(tn is XCData)) { tn.text += s; @@ -636,35 +637,35 @@ internal void AppendNodeSkipNotify(XNode n) internal override void AppendText(StringBuilder sb) { - string s = content as string; + string? s = content as string; if (s != null) { sb.Append(s); } else { - XNode n = (XNode)content; + XNode? n = (XNode?)content; if (n != null) { do { - n = n.next; + n = n.next!; n.AppendText(sb); } while (n != content); } } } - private string GetTextOnly() + private string? GetTextOnly() { if (content == null) return null; - string s = content as string; + string? s = content as string; if (s == null) { XNode n = (XNode)content; do { - n = n.next; + n = n.next!; if (n.NodeType != XmlNodeType.Text) return null; s += ((XText)n).Value; } while (n != content); @@ -672,7 +673,7 @@ private string GetTextOnly() return s; } - private string CollectText(ref XNode n) + private string CollectText(ref XNode? n) { string s = ""; while (n != null && n.NodeType == XmlNodeType.Text) @@ -686,10 +687,10 @@ private string CollectText(ref XNode n) internal bool ContentsEqual(XContainer e) { if (content == e.content) return true; - string s = GetTextOnly(); + string? s = GetTextOnly(); if (s != null) return s == e.GetTextOnly(); - XNode n1 = content as XNode; - XNode n2 = e.content as XNode; + XNode? n1 = content as XNode; + XNode? n2 = e.content as XNode; if (n1 != null && n2 != null) { n1 = n1.next; @@ -708,10 +709,10 @@ internal bool ContentsEqual(XContainer e) internal int ContentsHashCode() { - string s = GetTextOnly(); + string? s = GetTextOnly(); if (s != null) return s.GetHashCode(); int h = 0; - XNode n = content as XNode; + XNode? n = content as XNode; if (n != null) { do @@ -731,7 +732,7 @@ internal int ContentsHashCode() internal void ConvertTextToNode() { - string s = content as string; + string? s = content as string; if (!string.IsNullOrEmpty(s)) { XText t = new XText(s); @@ -747,23 +748,23 @@ internal IEnumerable GetDescendantNodes(bool self) XNode n = this; while (true) { - XContainer c = n as XContainer; - XNode first; + XContainer? c = n as XContainer; + XNode? first; if (c != null && (first = c.FirstNode) != null) { n = first; } else { - while (n != null && n != this && n == n.parent.content) n = n.parent; + while (n != null && n != this && n == n.parent!.content) n = n.parent; if (n == null || n == this) break; - n = n.next; + n = n.next!; } yield return n; } } - internal IEnumerable GetDescendants(XName name, bool self) + internal IEnumerable GetDescendants(XName? name, bool self) { if (self) { @@ -771,34 +772,34 @@ internal IEnumerable GetDescendants(XName name, bool self) if (name == null || e.name == name) yield return e; } XNode n = this; - XContainer c = this; + XContainer? c = this; while (true) { if (c != null && c.content is XNode) { - n = ((XNode)c.content).next; + n = ((XNode)c.content).next!; } else { - while (n != this && n == n.parent.content) n = n.parent; + while (n != this && n == n.parent!.content) n = n.parent; if (n == this) break; - n = n.next; + n = n.next!; } - XElement e = n as XElement; + XElement? e = n as XElement; if (e != null && (name == null || e.name == name)) yield return e; c = e; } } - private IEnumerable GetElements(XName name) + private IEnumerable GetElements(XName? name) { - XNode n = content as XNode; + XNode? n = content as XNode; if (n != null) { do { - n = n.next; - XElement e = n as XElement; + n = n.next!; + XElement? e = n as XElement; if (e != null && (name == null || e.name == name)) yield return e; } while (n.parent == this && n != content); } @@ -806,7 +807,7 @@ private IEnumerable GetElements(XName name) internal static string GetStringValue(object value) { - string s = value as string; + string? s = value as string; if (s != null) { return s; @@ -905,9 +906,9 @@ private sealed class ContentReader { private readonly NamespaceCache _eCache; private readonly NamespaceCache _aCache; - private readonly IXmlLineInfo _lineInfo; + private readonly IXmlLineInfo? _lineInfo; private XContainer _currentContainer; - private string _baseUri; + private string? _baseUri; public ContentReader(XContainer rootContainer) { @@ -947,7 +948,7 @@ public bool ReadContentFrom(XContainer rootContainer, XmlReader r) _currentContainer.content = string.Empty; } if (_currentContainer == rootContainer) return false; - _currentContainer = _currentContainer.parent; + _currentContainer = _currentContainer.parent!; break; case XmlNodeType.Text: case XmlNodeType.SignificantWhitespace: @@ -1006,7 +1007,7 @@ public async ValueTask ReadContentFromAsync(XContainer rootContainer, XmlR _currentContainer.content = string.Empty; } if (_currentContainer == rootContainer) return false; - _currentContainer = _currentContainer.parent; + _currentContainer = _currentContainer.parent!; break; case XmlNodeType.Text: case XmlNodeType.SignificantWhitespace: @@ -1039,8 +1040,9 @@ public async ValueTask ReadContentFromAsync(XContainer rootContainer, XmlR public bool ReadContentFrom(XContainer rootContainer, XmlReader r, LoadOptions o) { - XNode newNode = null; - string baseUri = r.BaseURI; + XNode? newNode = null; + // TODO-NULLABLE: Consider changing XmlReader.BaseURI to non-nullable. + string baseUri = r.BaseURI!; switch (r.NodeType) { @@ -1087,7 +1089,7 @@ public bool ReadContentFrom(XContainer rootContainer, XmlReader r, LoadOptions o } // Store the line info of the end element tag. // Note that since we've got EndElement the current container must be an XElement - XElement e = _currentContainer as XElement; + XElement? e = _currentContainer as XElement; Debug.Assert(e != null, "EndElement received but the current container is not an element."); if (e != null && _lineInfo != null && _lineInfo.HasLineInfo()) { @@ -1096,9 +1098,9 @@ public bool ReadContentFrom(XContainer rootContainer, XmlReader r, LoadOptions o if (_currentContainer == rootContainer) return false; if (_baseUri != null && _currentContainer.HasBaseUri) { - _baseUri = _currentContainer.parent.BaseUri; + _baseUri = _currentContainer.parent!.BaseUri; } - _currentContainer = _currentContainer.parent; + _currentContainer = _currentContainer.parent!; break; } case XmlNodeType.Text: @@ -1157,8 +1159,8 @@ public bool ReadContentFrom(XContainer rootContainer, XmlReader r, LoadOptions o public async ValueTask ReadContentFromAsync(XContainer rootContainer, XmlReader r, LoadOptions o) { - XNode newNode = null; - string baseUri = r.BaseURI; + XNode? newNode = null; + string baseUri = r.BaseURI!; switch (r.NodeType) { @@ -1207,7 +1209,7 @@ public async ValueTask ReadContentFromAsync(XContainer rootContainer, XmlR } // Store the line info of the end element tag. // Note that since we've got EndElement the current container must be an XElement - XElement e = _currentContainer as XElement; + XElement? e = _currentContainer as XElement; Debug.Assert(e != null, "EndElement received but the current container is not an element."); if (e != null && _lineInfo != null && _lineInfo.HasLineInfo()) { @@ -1216,9 +1218,9 @@ public async ValueTask ReadContentFromAsync(XContainer rootContainer, XmlR if (_currentContainer == rootContainer) return false; if (_baseUri != null && _currentContainer.HasBaseUri) { - _baseUri = _currentContainer.parent.BaseUri; + _baseUri = _currentContainer.parent!.BaseUri; } - _currentContainer = _currentContainer.parent; + _currentContainer = _currentContainer.parent!; break; } case XmlNodeType.Text: @@ -1280,8 +1282,10 @@ internal void RemoveNode(XNode n) { bool notify = NotifyChanging(n, XObjectChangeEventArgs.Remove); if (n.parent != this) throw new InvalidOperationException(SR.InvalidOperation_ExternalCode); + + Debug.Assert(content != null); XNode p = (XNode)content; - while (p.next != n) p = p.next; + while (p.next != n) p = p.next!; if (p == n) { content = null; @@ -1298,12 +1302,12 @@ internal void RemoveNode(XNode n) private void RemoveNodesSkipNotify() { - XNode n = content as XNode; + XNode? n = content as XNode; if (n != null) { do { - XNode next = n.next; + XNode next = n.next!; n.parent = null; n.next = null; n = next; @@ -1314,7 +1318,7 @@ private void RemoveNodesSkipNotify() // Validate insertion of the given node. previous is the node after which insertion // will occur. previous == null means at beginning, previous == this means at end. - internal virtual void ValidateNode(XNode node, XNode previous) + internal virtual void ValidateNode(XNode node, XNode? previous) { } @@ -1326,7 +1330,7 @@ internal void WriteContentTo(XmlWriter writer) { if (content != null) { - string stringContent = content as string; + string? stringContent = content as string; if (stringContent != null) { if (this is XDocument) @@ -1343,7 +1347,7 @@ internal void WriteContentTo(XmlWriter writer) XNode n = (XNode)content; do { - n = n.next; + n = n.next!; n.WriteTo(writer); } while (n != content); } @@ -1354,7 +1358,7 @@ internal async Task WriteContentToAsync(XmlWriter writer, CancellationToken canc { if (content != null) { - string stringContent = content as string; + string? stringContent = content as string; if (stringContent != null) { @@ -1378,7 +1382,7 @@ internal async Task WriteContentToAsync(XmlWriter writer, CancellationToken canc XNode n = (XNode)content; do { - n = n.next; + n = n.next!; await n.WriteToAsync(writer, cancellationToken).ConfigureAwait(false); } while (n != content); } @@ -1387,7 +1391,7 @@ internal async Task WriteContentToAsync(XmlWriter writer, CancellationToken canc private static void AddContentToList(List list, object content) { - IEnumerable e = content is string ? null : content as IEnumerable; + IEnumerable? e = content is string ? null : content as IEnumerable; if (e == null) { list.Add(content); @@ -1401,7 +1405,8 @@ private static void AddContentToList(List list, object content) } } - internal static object GetContentSnapshot(object content) + [return: NotNullIfNotNull("content")] + internal static object? GetContentSnapshot(object? content) { if (content is string || !(content is IEnumerable)) return content; List list = new List(); diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDeclaration.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDeclaration.cs index 10b1139d0c5aae..8407f48b9ed198 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDeclaration.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDeclaration.cs @@ -16,9 +16,9 @@ namespace System.Xml.Linq /// public class XDeclaration { - private string _version; - private string _encoding; - private string _standalone; + private string? _version; + private string? _encoding; + private string? _standalone; /// /// Initializes a new instance of the class from the @@ -34,7 +34,7 @@ public class XDeclaration /// Specifies whether the XML is standalone or requires external entities /// to be resolved. /// - public XDeclaration(string version, string encoding, string standalone) + public XDeclaration(string? version, string? encoding, string? standalone) { _version = version; _encoding = encoding; @@ -67,7 +67,7 @@ internal XDeclaration(XmlReader r) /// /// Gets or sets the encoding for this document. /// - public string Encoding + public string? Encoding { get { return _encoding; } set { _encoding = value; } @@ -79,7 +79,7 @@ public string Encoding /// /// The valid values for standalone are "yes" or "no". /// - public string Standalone + public string? Standalone { get { return _standalone; } set { _standalone = value; } @@ -91,7 +91,7 @@ public string Standalone /// /// The value is usually "1.0". /// - public string Version + public string? Version { get { return _version; } set { _version = value; } diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDocument.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDocument.cs index 537cbc31088760..5ee37a8fe6ddc1 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDocument.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDocument.cs @@ -26,7 +26,7 @@ namespace System.Xml.Linq /// public class XDocument : XContainer { - private XDeclaration _declaration; + private XDeclaration? _declaration; /// /// Initializes a new instance of the class. @@ -87,7 +87,7 @@ public XDocument(params object[] content) /// See for details about the content that can be added /// using this method. /// - public XDocument(XDeclaration declaration, params object[] content) + public XDocument(XDeclaration? declaration, params object[] content) : this(content) { _declaration = declaration; @@ -112,7 +112,7 @@ public XDocument(XDocument other) /// /// Gets the XML declaration for this document. /// - public XDeclaration Declaration + public XDeclaration? Declaration { get { return _declaration; } set { _declaration = value; } @@ -121,7 +121,7 @@ public XDeclaration Declaration /// /// Gets the Document Type Definition (DTD) for this document. /// - public XDocumentType DocumentType + public XDocumentType? DocumentType { get { @@ -146,7 +146,7 @@ public override XmlNodeType NodeType /// /// Gets the root element of the XML Tree for this document. /// - public XElement Root + public XElement? Root { get { @@ -481,7 +481,7 @@ private static XDocument InitLoad(XmlReader reader, LoadOptions options) XDocument d = new XDocument(); if ((options & LoadOptions.SetBaseUri) != 0) { - string baseUri = reader.BaseURI; + string? baseUri = reader.BaseURI; if (!string.IsNullOrEmpty(baseUri)) { d.SetBaseUri(baseUri); @@ -489,7 +489,7 @@ private static XDocument InitLoad(XmlReader reader, LoadOptions options) } if ((options & LoadOptions.SetLineInfo) != 0) { - IXmlLineInfo li = reader as IXmlLineInfo; + IXmlLineInfo? li = reader as IXmlLineInfo; if (li != null && li.HasLineInfo()) { d.SetLineInfo(li.LineNumber, li.LinePosition); @@ -867,7 +867,7 @@ internal override XNode CloneNode() internal override bool DeepEquals(XNode node) { - XDocument other = node as XDocument; + XDocument? other = node as XDocument; return other != null && ContentsEqual(other); } @@ -876,15 +876,15 @@ internal override int GetDeepHashCode() return ContentsHashCode(); } - private T GetFirstNode() where T : XNode + private T? GetFirstNode() where T : XNode { - XNode n = content as XNode; + XNode? n = content as XNode; if (n != null) { do { - n = n.next; - T e = n as T; + n = n.next!; + T? e = n as T; if (e != null) return e; } while (n != content); } @@ -900,7 +900,7 @@ internal static bool IsWhitespace(string s) return true; } - internal override void ValidateNode(XNode node, XNode previous) + internal override void ValidateNode(XNode node, XNode? previous) { switch (node.NodeType) { @@ -920,15 +920,15 @@ internal override void ValidateNode(XNode node, XNode previous) } } - private void ValidateDocument(XNode previous, XmlNodeType allowBefore, XmlNodeType allowAfter) + private void ValidateDocument(XNode? previous, XmlNodeType allowBefore, XmlNodeType allowAfter) { - XNode n = content as XNode; + XNode? n = content as XNode; if (n != null) { if (previous == null) allowBefore = allowAfter; do { - n = n.next; + n = n.next!; XmlNodeType nt = n.NodeType; if (nt == XmlNodeType.Element || nt == XmlNodeType.DocumentType) { diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDocumentType.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDocumentType.cs index f31c09681c6e94..7ba36d110aa0dd 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDocumentType.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDocumentType.cs @@ -12,14 +12,14 @@ namespace System.Xml.Linq public class XDocumentType : XNode { private string _name; - private string _publicId; - private string _systemId; + private string? _publicId; + private string? _systemId; private string _internalSubset; /// /// Initializes an empty instance of the class. /// - public XDocumentType(string name, string publicId, string systemId, string internalSubset) + public XDocumentType(string name, string? publicId, string? systemId, string internalSubset) { _name = XmlConvert.VerifyName(name); _publicId = publicId; @@ -57,6 +57,10 @@ public string InternalSubset { get { + // TODO-NULLABLE: As per documentation, this should return string.Empty. + // Should we check for null here? + // This is also referenced by XNodeReader.Value which overrides XmlReader.Value, which is non-nullable. + // There is one case that passes a nullable parameter (XNodeBuilder.WriteDocType), currently we are just asserting that the nullable parameter does not receive null. return _internalSubset; } set @@ -102,7 +106,7 @@ public override XmlNodeType NodeType /// /// Gets or sets the public identifier for this Document Type Definition (DTD). /// - public string PublicId + public string? PublicId { get { @@ -119,7 +123,7 @@ public string PublicId /// /// Gets or sets the system identifier for this Document Type Definition (DTD). /// - public string SystemId + public string? SystemId { get { @@ -170,7 +174,7 @@ internal override XNode CloneNode() internal override bool DeepEquals(XNode node) { - XDocumentType other = node as XDocumentType; + XDocumentType? other = node as XDocumentType; return other != null && _name == other._name && _publicId == other._publicId && _systemId == other.SystemId && _internalSubset == other._internalSubset; } diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XElement.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XElement.cs index 5a019ea4edfbf9..8b595a34e5f967 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XElement.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XElement.cs @@ -13,6 +13,8 @@ using IEnumerable = System.Collections.IEnumerable; using SuppressMessageAttribute = System.Diagnostics.CodeAnalysis.SuppressMessageAttribute; using StringBuilder = System.Text.StringBuilder; +using System.Diagnostics.CodeAnalysis; +using System.Diagnostics; namespace System.Xml.Linq { @@ -45,8 +47,8 @@ public static IEnumerable EmptySequence } } - internal XName name; - internal XAttribute lastAttr; + internal XName name = null!; + internal XAttribute? lastAttr; /// /// Initializes a new instance of the XElement class with the specified name. @@ -71,7 +73,7 @@ public XElement(XName name) /// See XContainer.Add(object content) for details about the content that can be added /// using this method. /// - public XElement(XName name, object content) + public XElement(XName name, object? content) : this(name) { AddContentSkipNotify(content); @@ -105,12 +107,12 @@ public XElement(XElement other) : base(other) { this.name = other.name; - XAttribute a = other.lastAttr; + XAttribute? a = other.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; AppendAttributeSkipNotify(new XAttribute(a)); } while (a != other.lastAttr); } @@ -131,7 +133,7 @@ public XElement(XStreamingElement other) } internal XElement() - : this("default") + : this("default"!) { } @@ -209,7 +211,7 @@ public void Save(string fileName, SaveOptions options) /// /// Gets the first attribute of an element. /// - public XAttribute FirstAttribute + public XAttribute? FirstAttribute { get { return lastAttr != null ? lastAttr.next : null; } } @@ -229,13 +231,13 @@ public bool HasElements { get { - XNode n = content as XNode; + XNode? n = content as XNode; if (n != null) { do { if (n is XElement) return true; - n = n.next; + n = n.next!; } while (n != content); } return false; @@ -253,7 +255,7 @@ public bool IsEmpty /// /// Gets the last attribute of an element. /// - public XAttribute LastAttribute + public XAttribute? LastAttribute { get { return lastAttr; } } @@ -302,7 +304,7 @@ public string Value get { if (content == null) return string.Empty; - string s = content as string; + string? s = content as string; if (s != null) return s; StringBuilder sb = StringBuilderCache.Acquire(); AppendText(sb); @@ -351,7 +353,7 @@ public IEnumerable AncestorsAndSelf() /// An of containing the /// ancestors of this with a matching . /// - public IEnumerable AncestorsAndSelf(XName name) + public IEnumerable AncestorsAndSelf(XName? name) { return name != null ? GetAncestors(name, true) : XElement.EmptySequence; } @@ -367,14 +369,14 @@ public IEnumerable AncestorsAndSelf(XName name) /// The with the passed in. If there is no /// with this then null is returned. /// - public XAttribute Attribute(XName name) + public XAttribute? Attribute(XName name) { - XAttribute a = lastAttr; + XAttribute? a = lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (a.name == name) return a; } while (a != lastAttr); } @@ -409,7 +411,7 @@ public IEnumerable Attributes() /// /// The (s) with the matching /// - public IEnumerable Attributes(XName name) + public IEnumerable Attributes(XName? name) { return name != null ? GetAttributes(name) : XAttribute.EmptySequence; } @@ -454,7 +456,7 @@ public IEnumerable DescendantsAndSelf() /// An of containing all of the descendant /// s that have this . /// - public IEnumerable DescendantsAndSelf(XName name) + public IEnumerable DescendantsAndSelf(XName? name) { return name != null ? GetDescendants(name, true) : XElement.EmptySequence; } @@ -464,7 +466,7 @@ public IEnumerable DescendantsAndSelf(XName name) /// public XNamespace GetDefaultNamespace() { - string namespaceName = GetNamespaceOfPrefixInScope("xmlns", null); + string? namespaceName = GetNamespaceOfPrefixInScope("xmlns", null); return namespaceName != null ? XNamespace.Get(namespaceName) : XNamespace.None; } @@ -474,12 +476,12 @@ public XNamespace GetDefaultNamespace() /// /// The namespace prefix to look up /// An for the namespace bound to the prefix - public XNamespace GetNamespaceOfPrefix(string prefix) + public XNamespace? GetNamespaceOfPrefix(string prefix) { if (prefix == null) throw new ArgumentNullException(nameof(prefix)); if (prefix.Length == 0) throw new ArgumentException(SR.Format(SR.Argument_InvalidPrefix, prefix)); if (prefix == "xmlns") return XNamespace.Xmlns; - string namespaceName = GetNamespaceOfPrefixInScope(prefix, null); + string? namespaceName = GetNamespaceOfPrefixInScope(prefix, null); if (namespaceName != null) return XNamespace.Get(namespaceName); if (prefix == "xml") return XNamespace.Xml; return null; @@ -490,21 +492,21 @@ public XNamespace GetNamespaceOfPrefix(string prefix) /// /// The for which to get a prefix /// The namespace prefix string - public string GetPrefixOfNamespace(XNamespace ns) + public string? GetPrefixOfNamespace(XNamespace ns) { if (ns == null) throw new ArgumentNullException(nameof(ns)); string namespaceName = ns.NamespaceName; bool hasInScopeNamespace = false; - XElement e = this; + XElement? e = this; do { - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { bool hasLocalNamespace = false; do { - a = a.next; + a = a.next!; if (a.IsNamespaceDeclaration) { if (a.Value == namespaceName) @@ -932,7 +934,7 @@ public void RemoveAttributes() } while (lastAttr != null) { - XAttribute a = lastAttr.next; + XAttribute a = lastAttr.next!; NotifyChanging(a, XObjectChangeEventArgs.Remove); if (lastAttr == null || a != lastAttr.next) throw new InvalidOperationException(SR.InvalidOperation_ExternalCode); if (a != lastAttr) @@ -964,7 +966,7 @@ public void RemoveAttributes() /// See XContainer.Add(object content) for details about the content that can be added /// using this method. /// - public void ReplaceAll(object content) + public void ReplaceAll(object? content) { content = GetContentSnapshot(content); RemoveAll(); @@ -1001,7 +1003,7 @@ public void ReplaceAll(params object[] content) /// See XContainer.Add(object content) for details about the content that can be added /// using this method. /// - public void ReplaceAttributes(object content) + public void ReplaceAttributes(object? content) { content = GetContentSnapshot(content); RemoveAttributes(); @@ -1207,9 +1209,9 @@ private async Task SaveAsyncInternal(XmlWriter writer, CancellationToken cancell /// /// Thrown if the value is an instance of . /// - public void SetAttributeValue(XName name, object value) + public void SetAttributeValue(XName name, object? value) { - XAttribute a = Attribute(name); + XAttribute? a = Attribute(name); if (value == null) { if (a != null) RemoveAttribute(a); @@ -1247,9 +1249,9 @@ public void SetAttributeValue(XName name, object value) /// /// Thrown if the value is an instance of . /// - public void SetElementValue(XName name, object value) + public void SetElementValue(XName name, object? value) { - XElement e = Element(name); + XElement? e = Element(name); if (value == null) { if (e != null) RemoveNode(e); @@ -1330,7 +1332,8 @@ public override Task WriteToAsync(XmlWriter writer, CancellationToken cancellati /// The content of this as a . /// [CLSCompliant(false)] - public static explicit operator string(XElement element) + [return: NotNullIfNotNull("element")] + public static explicit operator string?(XElement? element) { if (element == null) return null; return element.Value; @@ -1371,7 +1374,8 @@ public static explicit operator bool(XElement element) /// Thrown if the element does not contain a valid boolean value. /// [CLSCompliant(false)] - public static explicit operator bool?(XElement element) + [return: NotNullIfNotNull("element")] + public static explicit operator bool?(XElement? element) { if (element == null) return null; return XmlConvert.ToBoolean(element.Value.ToLowerInvariant()); @@ -1412,7 +1416,8 @@ public static explicit operator int(XElement element) /// Thrown if the specified element does not contain a valid integer value. /// [CLSCompliant(false)] - public static explicit operator int?(XElement element) + [return: NotNullIfNotNull("element")] + public static explicit operator int?(XElement? element) { if (element == null) return null; return XmlConvert.ToInt32(element.Value); @@ -1453,7 +1458,8 @@ public static explicit operator uint(XElement element) /// Thrown if the specified element does not contain a valid unsigned integer value. /// [CLSCompliant(false)] - public static explicit operator uint?(XElement element) + [return: NotNullIfNotNull("element")] + public static explicit operator uint?(XElement? element) { if (element == null) return null; return XmlConvert.ToUInt32(element.Value); @@ -1494,7 +1500,8 @@ public static explicit operator long(XElement element) /// Thrown if the specified element does not contain a valid long integer value. /// [CLSCompliant(false)] - public static explicit operator long?(XElement element) + [return: NotNullIfNotNull("element")] + public static explicit operator long?(XElement? element) { if (element == null) return null; return XmlConvert.ToInt64(element.Value); @@ -1535,7 +1542,8 @@ public static explicit operator ulong(XElement element) /// Thrown if the specified element does not contain a valid unsigned long integer value. /// [CLSCompliant(false)] - public static explicit operator ulong?(XElement element) + [return: NotNullIfNotNull("element")] + public static explicit operator ulong?(XElement? element) { if (element == null) return null; return XmlConvert.ToUInt64(element.Value); @@ -1576,7 +1584,8 @@ public static explicit operator float(XElement element) /// Thrown if the specified element does not contain a valid float value. /// [CLSCompliant(false)] - public static explicit operator float?(XElement element) + [return: NotNullIfNotNull("element")] + public static explicit operator float?(XElement? element) { if (element == null) return null; return XmlConvert.ToSingle(element.Value); @@ -1617,7 +1626,8 @@ public static explicit operator double(XElement element) /// Thrown if the specified element does not contain a valid double value. /// [CLSCompliant(false)] - public static explicit operator double?(XElement element) + [return: NotNullIfNotNull("element")] + public static explicit operator double?(XElement? element) { if (element == null) return null; return XmlConvert.ToDouble(element.Value); @@ -1658,7 +1668,8 @@ public static explicit operator decimal(XElement element) /// Thrown if the specified element does not contain a valid decimal value. /// [CLSCompliant(false)] - public static explicit operator decimal?(XElement element) + [return: NotNullIfNotNull("element")] + public static explicit operator decimal?(XElement? element) { if (element == null) return null; return XmlConvert.ToDecimal(element.Value); @@ -1699,7 +1710,8 @@ public static explicit operator DateTime(XElement element) /// Thrown if the specified element does not contain a valid value. /// [CLSCompliant(false)] - public static explicit operator DateTime?(XElement element) + [return: NotNullIfNotNull("element")] + public static explicit operator DateTime?(XElement? element) { if (element == null) return null; return DateTime.Parse(element.Value, CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.RoundtripKind); @@ -1740,7 +1752,8 @@ public static explicit operator DateTimeOffset(XElement element) /// Thrown if the specified element does not contain a valid value. /// [CLSCompliant(false)] - public static explicit operator DateTimeOffset?(XElement element) + [return: NotNullIfNotNull("element")] + public static explicit operator DateTimeOffset?(XElement? element) { if (element == null) return null; return XmlConvert.ToDateTimeOffset(element.Value); @@ -1781,7 +1794,8 @@ public static explicit operator TimeSpan(XElement element) /// Thrown if the specified element does not contain a valid value. /// [CLSCompliant(false)] - public static explicit operator TimeSpan?(XElement element) + [return: NotNullIfNotNull("element")] + public static explicit operator TimeSpan?(XElement? element) { if (element == null) return null; return XmlConvert.ToTimeSpan(element.Value); @@ -1822,7 +1836,8 @@ public static explicit operator Guid(XElement element) /// Thrown if the specified element does not contain a valid guid. /// [CLSCompliant(false)] - public static explicit operator Guid?(XElement element) + [return: NotNullIfNotNull("element")] + public static explicit operator Guid?(XElement? element) { if (element == null) return null; return XmlConvert.ToGuid(element.Value); @@ -1831,7 +1846,7 @@ public static explicit operator Guid(XElement element) /// /// This method is obsolete for the IXmlSerializable contract. /// - XmlSchema IXmlSerializable.GetSchema() + XmlSchema? IXmlSerializable.GetSchema() { return null; } @@ -1902,14 +1917,14 @@ internal void AppendAttributeSkipNotify(XAttribute a) private bool AttributesEqual(XElement e) { - XAttribute a1 = lastAttr; - XAttribute a2 = e.lastAttr; + XAttribute? a1 = lastAttr; + XAttribute? a2 = e.lastAttr; if (a1 != null && a2 != null) { do { - a1 = a1.next; - a2 = a2.next; + a1 = a1.next!; + a2 = a2.next!; if (a1.name != a2.name || a1.value != a2.value) return false; } while (a1 != lastAttr); return a2 == e.lastAttr; @@ -1924,34 +1939,35 @@ internal override XNode CloneNode() internal override bool DeepEquals(XNode node) { - XElement e = node as XElement; + XElement? e = node as XElement; return e != null && name == e.name && ContentsEqual(e) && AttributesEqual(e); } - private IEnumerable GetAttributes(XName name) + private IEnumerable GetAttributes(XName? name) { - XAttribute a = lastAttr; + XAttribute? a = lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (name == null || a.name == name) yield return a; } while (a.parent == this && a != lastAttr); } } - private string GetNamespaceOfPrefixInScope(string prefix, XElement outOfScope) + private string? GetNamespaceOfPrefixInScope(string prefix, XElement? outOfScope) { - XElement e = this; + XElement? e = this; while (e != outOfScope) { - XAttribute a = e.lastAttr; + Debug.Assert(e != null); + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (a.IsNamespaceDeclaration && a.Name.LocalName == prefix) return a.Value; } while (a != e.lastAttr); @@ -1965,12 +1981,12 @@ internal override int GetDeepHashCode() { int h = name.GetHashCode(); h ^= ContentsHashCode(); - XAttribute a = lastAttr; + XAttribute? a = lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; h ^= a.GetDeepHashCode(); } while (a != lastAttr); } @@ -2015,13 +2031,13 @@ private void ReadElementFromImpl(XmlReader r, LoadOptions o) name = XNamespace.Get(r.NamespaceURI).GetName(r.LocalName); if ((o & LoadOptions.SetBaseUri) != 0) { - string baseUri = r.BaseURI; + string? baseUri = r.BaseURI; if (!string.IsNullOrEmpty(baseUri)) { SetBaseUri(baseUri); } } - IXmlLineInfo li = null; + IXmlLineInfo? li = null; if ((o & LoadOptions.SetLineInfo) != 0) { li = r as IXmlLineInfo; @@ -2049,8 +2065,8 @@ internal void RemoveAttribute(XAttribute a) { bool notify = NotifyChanging(a, XObjectChangeEventArgs.Remove); if (a.parent != this) throw new InvalidOperationException(SR.InvalidOperation_ExternalCode); - XAttribute p = lastAttr, n; - while ((n = p.next) != a) p = n; + XAttribute? p = lastAttr!, n; + while ((n = p.next!) != a) p = n; if (p == a) { lastAttr = null; @@ -2072,7 +2088,7 @@ private void RemoveAttributesSkipNotify() XAttribute a = lastAttr; do { - XAttribute next = a.next; + XAttribute next = a.next!; a.parent = null; a.next = null; a = next; @@ -2086,7 +2102,7 @@ internal void SetEndElementLineInfo(int lineNumber, int linePosition) AddAnnotation(new LineInfoEndElementAnnotation(lineNumber, linePosition)); } - internal override void ValidateNode(XNode node, XNode previous) + internal override void ValidateNode(XNode node, XNode? previous) { if (node is XDocument) throw new ArgumentException(SR.Format(SR.Argument_AddNode, XmlNodeType.Document)); if (node is XDocumentType) throw new ArgumentException(SR.Format(SR.Argument_AddNode, XmlNodeType.DocumentType)); diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XHashtable.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XHashtable.cs index 24ea8411a64517..58c536966a3593 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XHashtable.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XHashtable.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Threading; using Debug = System.Diagnostics.Debug; using Interlocked = System.Threading.Interlocked; @@ -66,7 +67,7 @@ internal sealed class XHashtable /// Prototype of function which is called to extract a string key value from a hashed value. /// Returns null if the hashed value is invalid (e.g. value has been released due to a WeakReference TValue being cleaned up). /// - public delegate string ExtractKeyDelegate(TValue value); + public delegate string? ExtractKeyDelegate(TValue value); /// /// Construct a new XHashtable with the specified starting capacity. @@ -79,7 +80,7 @@ public XHashtable(ExtractKeyDelegate extractKey, int capacity) /// /// Get an existing value from the hash table. Return false if no such value exists. /// - public bool TryGetValue(string key, int index, int count, out TValue value) + public bool TryGetValue(string key, int index, int count, [MaybeNullWhen(false)] out TValue value) { return _state.TryGetValue(key, index, count, out value); } @@ -238,7 +239,7 @@ public XHashtableState Resize() /// Attempt to find "key" in the table. If the key exists, return the associated value in "value" and /// return true. Otherwise return false. /// - public bool TryGetValue(string key, int index, int count, out TValue value) + public bool TryGetValue(string key, int index, int count, [MaybeNullWhen(false)] out TValue value) { int hashCode = ComputeHashCode(key, index, count); int entryIndex = 0; @@ -264,7 +265,7 @@ public bool TryGetValue(string key, int index, int count, out TValue value) public bool TryAdd(TValue value, out TValue newValue) { int newEntry, entryIndex; - string key; + string? key; int hashCode; // Assume "value" will be added and returned as "newValue" @@ -345,7 +346,7 @@ private bool FindEntry(int hashCode, string key, int index, int count, ref int e // Check for matching hash code, then matching key if (_entries[currentIndex].HashCode == hashCode) { - string keyCompare = _extractKey(_entries[currentIndex].Value); + string? keyCompare = _extractKey(_entries[currentIndex].Value); // If the key is invalid, then attempt to remove the current entry from the linked list. // This is thread-safe in the case where the Next field points to another entry, since once a Next field points @@ -356,7 +357,7 @@ private bool FindEntry(int hashCode, string key, int index, int count, ref int e { // PUBLISH (buckets slot or entries slot) // Entry is invalid, so modify previous entry to point to its next entry - _entries[currentIndex].Value = default(TValue); + _entries[currentIndex].Value = default(TValue)!; currentIndex = _entries[currentIndex].Next; if (previousIndex == 0) diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XHelper.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XHelper.cs index 9249cce442fe90..f127fe02fa4cb3 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XHelper.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XHelper.cs @@ -9,7 +9,7 @@ namespace System.Xml.Linq { internal static class XHelper { - internal static bool IsInstanceOfType(object o, Type type) + internal static bool IsInstanceOfType(object? o, Type type) { Debug.Assert(type != null); diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XLinq.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XLinq.cs index 85e563ca1ed56a..0d47b5596cdc4a 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XLinq.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XLinq.cs @@ -13,17 +13,17 @@ namespace System.Xml.Linq internal struct Inserter { private readonly XContainer _parent; - private XNode _previous; - private string _text; + private XNode? _previous; + private string? _text; - public Inserter(XContainer parent, XNode anchor) + public Inserter(XContainer parent, XNode? anchor) { _parent = parent; _previous = anchor; _text = null; } - public void Add(object content) + public void Add(object? content) { AddContent(content); if (_text != null) @@ -60,7 +60,7 @@ public void Add(object content) } else if (_text.Length > 0) { - XText prevXText = _previous as XText; + XText? prevXText = _previous as XText; if (prevXText != null && !(_previous is XCData)) { prevXText.Value += _text; @@ -74,34 +74,34 @@ public void Add(object content) } } - private void AddContent(object content) + private void AddContent(object? content) { if (content == null) return; - XNode n = content as XNode; + XNode? n = content as XNode; if (n != null) { AddNode(n); return; } - string s = content as string; + string? s = content as string; if (s != null) { AddString(s); return; } - XStreamingElement x = content as XStreamingElement; + XStreamingElement? x = content as XStreamingElement; if (x != null) { AddNode(new XElement(x)); return; } - object[] o = content as object[]; + object[]? o = content as object[]; if (o != null) { foreach (object obj in o) AddContent(obj); return; } - IEnumerable e = content as IEnumerable; + IEnumerable? e = content as IEnumerable; if (e != null) { foreach (object obj in e) AddContent(obj); @@ -129,7 +129,7 @@ private void AddNode(XNode n) { if (_text.Length > 0) { - XText prevXText = _previous as XText; + XText? prevXText = _previous as XText; if (prevXText != null && !(_previous is XCData)) { prevXText.Value += _text; @@ -210,17 +210,17 @@ public void WriteElement(XElement e) XNode n = e; while (true) { - e = n as XElement; - if (e != null) + XElement? current = n as XElement; + if (current != null) { - WriteStartElement(e); - if (e.content == null) + WriteStartElement(current); + if (current.content == null) { WriteEndElement(); } else { - string s = e.content as string; + string? s = current.content as string; if (s != null) { _writer.WriteString(s); @@ -228,7 +228,7 @@ public void WriteElement(XElement e) } else { - n = ((XNode)e.content).next; + n = ((XNode)current.content).next!; continue; } } @@ -237,13 +237,13 @@ public void WriteElement(XElement e) { n.WriteTo(_writer); } - while (n != root && n == n.parent.content) + while (n != root && n == n.parent!.content) { n = n.parent; WriteFullEndElement(); } if (n == root) break; - n = n.next; + n = n.next!; } } @@ -254,17 +254,17 @@ public async Task WriteElementAsync(XElement e, CancellationToken cancellationTo XNode n = e; while (true) { - e = n as XElement; - if (e != null) + XElement? current = n as XElement; + if (current != null) { - await WriteStartElementAsync(e, cancellationToken).ConfigureAwait(false); - if (e.content == null) + await WriteStartElementAsync(current, cancellationToken).ConfigureAwait(false); + if (current.content == null) { await WriteEndElementAsync(cancellationToken).ConfigureAwait(false); } else { - string s = e.content as string; + string? s = current.content as string; if (s != null) { cancellationToken.ThrowIfCancellationRequested(); @@ -273,7 +273,7 @@ public async Task WriteElementAsync(XElement e, CancellationToken cancellationTo } else { - n = ((XNode)e.content).next; + n = ((XNode)current.content).next!; continue; } } @@ -282,39 +282,39 @@ public async Task WriteElementAsync(XElement e, CancellationToken cancellationTo { await n.WriteToAsync(_writer, cancellationToken).ConfigureAwait(false); } - while (n != root && n == n.parent.content) + while (n != root && n == n.parent!.content) { n = n.parent; await WriteFullEndElementAsync(cancellationToken).ConfigureAwait(false); } if (n == root) break; - n = n.next; + n = n.next!; } } - private string GetPrefixOfNamespace(XNamespace ns, bool allowDefaultNamespace) + private string? GetPrefixOfNamespace(XNamespace ns, bool allowDefaultNamespace) { string namespaceName = ns.NamespaceName; if (namespaceName.Length == 0) return string.Empty; - string prefix = _resolver.GetPrefixOfNamespace(ns, allowDefaultNamespace); + string? prefix = _resolver.GetPrefixOfNamespace(ns, allowDefaultNamespace); if (prefix != null) return prefix; if ((object)namespaceName == (object)XNamespace.xmlPrefixNamespace) return "xml"; if ((object)namespaceName == (object)XNamespace.xmlnsPrefixNamespace) return "xmlns"; return null; } - private void PushAncestors(XElement e) + private void PushAncestors(XElement? e) { while (true) { - e = e.parent as XElement; + e = e!.parent as XElement; if (e == null) break; - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (a.IsNamespaceDeclaration) { _resolver.AddFirst(a.Name.NamespaceName.Length == 0 ? string.Empty : a.Name.LocalName, XNamespace.Get(a.Value)); @@ -327,12 +327,12 @@ private void PushAncestors(XElement e) private void PushElement(XElement e) { _resolver.PushScope(); - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (a.IsNamespaceDeclaration) { _resolver.Add(a.Name.NamespaceName.Length == 0 ? string.Empty : a.Name.LocalName, XNamespace.Get(a.Value)); @@ -372,12 +372,12 @@ private void WriteStartElement(XElement e) PushElement(e); XNamespace ns = e.Name.Namespace; _writer.WriteStartElement(GetPrefixOfNamespace(ns, true), e.Name.LocalName, ns.NamespaceName); - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; ns = a.Name.Namespace; string localName = a.Name.LocalName; string namespaceName = ns.NamespaceName; @@ -391,12 +391,12 @@ private async Task WriteStartElementAsync(XElement e, CancellationToken cancella PushElement(e); XNamespace ns = e.Name.Namespace; await _writer.WriteStartElementAsync(GetPrefixOfNamespace(ns, true), e.Name.LocalName, ns.NamespaceName).ConfigureAwait(false); - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; ns = a.Name.Namespace; string localName = a.Name.LocalName; string namespaceName = ns.NamespaceName; @@ -410,15 +410,15 @@ internal struct NamespaceResolver { private class NamespaceDeclaration { - public string prefix; - public XNamespace ns; + public string prefix = null!; + public XNamespace ns = null!; public int scope; - public NamespaceDeclaration prev; + public NamespaceDeclaration prev = null!; } private int _scope; - private NamespaceDeclaration _declaration; - private NamespaceDeclaration _rover; + private NamespaceDeclaration? _declaration; + private NamespaceDeclaration? _rover; public void PushScope() { @@ -427,7 +427,7 @@ public void PushScope() public void PopScope() { - NamespaceDeclaration d = _declaration; + NamespaceDeclaration? d = _declaration; if (d != null) { do @@ -440,7 +440,7 @@ public void PopScope() } else { - _declaration.prev = d.prev; + _declaration!.prev = d.prev; } _rover = null; } while (d != _declaration && _declaration != null); @@ -487,10 +487,10 @@ public void AddFirst(string prefix, XNamespace ns) // Only elements allow default namespace declarations. The rover // caches the last namespace declaration used by an element. - public string GetPrefixOfNamespace(XNamespace ns, bool allowDefaultNamespace) + public string? GetPrefixOfNamespace(XNamespace ns, bool allowDefaultNamespace) { if (_rover != null && _rover.ns == ns && (allowDefaultNamespace || _rover.prefix.Length > 0)) return _rover.prefix; - NamespaceDeclaration d = _declaration; + NamespaceDeclaration? d = _declaration; if (d != null) { do @@ -498,7 +498,7 @@ public string GetPrefixOfNamespace(XNamespace ns, bool allowDefaultNamespace) d = d.prev; if (d.ns == ns) { - NamespaceDeclaration x = _declaration.prev; + NamespaceDeclaration x = _declaration!.prev; while (x != d && x.prefix != d.prefix) { x = x.prev; @@ -525,7 +525,7 @@ public string GetPrefixOfNamespace(XNamespace ns, bool allowDefaultNamespace) internal struct StreamingElementWriter { private readonly XmlWriter _writer; - private XStreamingElement _element; + private XStreamingElement? _element; private readonly List _attributes; private NamespaceResolver _resolver; @@ -556,11 +556,11 @@ private void FlushElement() } } - private string GetPrefixOfNamespace(XNamespace ns, bool allowDefaultNamespace) + private string? GetPrefixOfNamespace(XNamespace ns, bool allowDefaultNamespace) { string namespaceName = ns.NamespaceName; if (namespaceName.Length == 0) return string.Empty; - string prefix = _resolver.GetPrefixOfNamespace(ns, allowDefaultNamespace); + string? prefix = _resolver.GetPrefixOfNamespace(ns, allowDefaultNamespace); if (prefix != null) return prefix; if ((object)namespaceName == (object)XNamespace.xmlPrefixNamespace) return "xml"; if ((object)namespaceName == (object)XNamespace.xmlnsPrefixNamespace) return "xmlns"; @@ -579,40 +579,40 @@ private void PushElement() } } - private void Write(object content) + private void Write(object? content) { if (content == null) return; - XNode n = content as XNode; + XNode? n = content as XNode; if (n != null) { WriteNode(n); return; } - string s = content as string; + string? s = content as string; if (s != null) { WriteString(s); return; } - XAttribute a = content as XAttribute; + XAttribute? a = content as XAttribute; if (a != null) { WriteAttribute(a); return; } - XStreamingElement x = content as XStreamingElement; + XStreamingElement? x = content as XStreamingElement; if (x != null) { WriteStreamingElement(x); return; } - object[] o = content as object[]; + object[]? o = content as object[]; if (o != null) { foreach (object obj in o) Write(obj); return; } - IEnumerable e = content as IEnumerable; + IEnumerable? e = content as IEnumerable; if (e != null) { foreach (object obj in e) Write(obj); diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XName.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XName.cs index 1b6c7fa99a1f55..66ab4828ffa09d 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XName.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XName.cs @@ -3,6 +3,7 @@ using SuppressMessageAttribute = System.Diagnostics.CodeAnalysis.SuppressMessageAttribute; using System.Runtime.Serialization; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Linq { @@ -101,7 +102,8 @@ public static XName Get(string localName, string namespaceName) /// A string containing an expanded XML name in the format: {namespace}localname. /// An XName object constructed from the expanded name. [CLSCompliant(false)] - public static implicit operator XName(string expandedName) + [return: NotNullIfNotNull("expandedName")] + public static implicit operator XName?(string? expandedName) { return expandedName != null ? Get(expandedName) : null; } @@ -116,7 +118,7 @@ public static implicit operator XName(string expandedName) /// /// For two objects to be equal, they must have the same expanded name. /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { return (object)this == obj; } @@ -146,9 +148,9 @@ public override int GetHashCode() /// This overload is included to enable the comparison between /// an instance of XName and string. /// - public static bool operator ==(XName left, XName right) + public static bool operator ==(XName? left, XName? right) { - return (object)left == (object)right; + return (object?)left == (object?)right; } /// @@ -161,9 +163,9 @@ public override int GetHashCode() /// This overload is included to enable the comparison between /// an instance of XName and string. /// - public static bool operator !=(XName left, XName right) + public static bool operator !=(XName? left, XName? right) { - return (object)left != (object)right; + return (object?)left != (object?)right; } /// @@ -176,9 +178,9 @@ public override int GetHashCode() /// Returns true if the current is equal to /// the specified . Returns false otherwise. /// - bool IEquatable.Equals(XName other) + bool IEquatable.Equals(XName? other) { - return (object)this == (object)other; + return (object)this == (object?)other; } /// diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNamespace.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNamespace.cs index 8b673a644fde9b..c3fa5a3d85ac13 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNamespace.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNamespace.cs @@ -4,6 +4,7 @@ using Debug = System.Diagnostics.Debug; using SuppressMessageAttribute = System.Diagnostics.CodeAnalysis.SuppressMessageAttribute; using Interlocked = System.Threading.Interlocked; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Linq { @@ -15,10 +16,10 @@ public sealed class XNamespace internal const string xmlPrefixNamespace = "http://www.w3.org/XML/1998/namespace"; internal const string xmlnsPrefixNamespace = "http://www.w3.org/2000/xmlns/"; - private static XHashtable s_namespaces; - private static WeakReference s_refNone; - private static WeakReference s_refXml; - private static WeakReference s_refXmlns; + private static XHashtable? s_namespaces; + private static WeakReference? s_refNone; + private static WeakReference? s_refXml; + private static WeakReference? s_refXmlns; private readonly string _namespaceName; private readonly int _hashCode; @@ -123,7 +124,8 @@ public static XNamespace Get(string namespaceName) /// A string containing the namespace name. /// An constructed from the namespace name string. [CLSCompliant(false)] - public static implicit operator XNamespace(string namespaceName) + [return: NotNullIfNotNull("namespaceName")] + public static implicit operator XNamespace?(string? namespaceName) { return namespaceName != null ? Get(namespaceName) : null; } @@ -151,7 +153,7 @@ public static implicit operator XNamespace(string namespaceName) /// For two objects to be equal they must have the same /// namespace name. /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { return (object)this == obj; } @@ -182,9 +184,9 @@ public override int GetHashCode() /// This overload is included to enable the comparison between /// an instance of and string. /// - public static bool operator ==(XNamespace left, XNamespace right) + public static bool operator ==(XNamespace? left, XNamespace? right) { - return (object)left == (object)right; + return (object?)left == (object?)right; } /// @@ -197,9 +199,9 @@ public override int GetHashCode() /// This overload is included to enable the comparison between /// an instance of and string. /// - public static bool operator !=(XNamespace left, XNamespace right) + public static bool operator !=(XNamespace? left, XNamespace? right) { - return (object)left != (object)right; + return (object?)left != (object?)right; } /// @@ -213,7 +215,7 @@ internal XName GetName(string localName, int index, int count) Debug.Assert(count >= 0 && index + count <= localName.Length, "Caller should have checked that count was in bounds"); // Attempt to get the local name from the hash table - XName name; + XName? name; if (_names.TryGetValue(localName, index, count, out name)) return name; @@ -236,8 +238,8 @@ internal static XNamespace Get(string namespaceName, int index, int count) if (s_namespaces == null) Interlocked.CompareExchange(ref s_namespaces, new XHashtable(ExtractNamespace, NamespacesCapacity), null); - WeakReference refNamespace; - XNamespace ns; + WeakReference? refNamespace; + XNamespace? ns; // Keep looping until a non-null namespace has been retrieved do @@ -253,7 +255,7 @@ internal static XNamespace Get(string namespaceName, int index, int count) refNamespace = s_namespaces.Add(new WeakReference(new XNamespace(namespaceName.Substring(index, count)))); } - ns = (refNamespace != null) ? (XNamespace)refNamespace.Target : null; + ns = (refNamespace != null) ? (XNamespace?)refNamespace.Target : null; } while (ns == null); @@ -274,11 +276,11 @@ private static string ExtractLocalName(XName n) /// This function is used by the to extract the XNamespace that the WeakReference is /// referencing. In cases where the XNamespace has been cleaned up, this function returns null. /// - private static string ExtractNamespace(WeakReference r) + private static string? ExtractNamespace(WeakReference? r) { - XNamespace ns; + XNamespace? ns; - if (r == null || (ns = (XNamespace)r.Target) == null) + if (r == null || (ns = (XNamespace?)r.Target) == null) return null; return ns.NamespaceName; @@ -290,9 +292,9 @@ private static string ExtractNamespace(WeakReference r) /// since other threads can be concurrently calling this method, and the target of a WeakReference can be cleaned up /// at any time by the GC. /// - private static XNamespace EnsureNamespace(ref WeakReference refNmsp, string namespaceName) + private static XNamespace EnsureNamespace(ref WeakReference? refNmsp, string namespaceName) { - WeakReference refOld; + WeakReference? refOld; // Keep looping until a non-null namespace has been retrieved while (true) @@ -303,7 +305,7 @@ private static XNamespace EnsureNamespace(ref WeakReference refNmsp, string name if (refOld != null) { // If the target of the WeakReference is non-null, then we're done--just return the value - XNamespace ns = (XNamespace)refOld.Target; + XNamespace? ns = (XNamespace?)refOld.Target; if (ns != null) return ns; } diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNode.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNode.cs index d8645161a48f45..aa34604d8a05bd 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNode.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNode.cs @@ -9,6 +9,7 @@ using CultureInfo = System.Globalization.CultureInfo; using SuppressMessageAttribute = System.Diagnostics.CodeAnalysis.SuppressMessageAttribute; using StringBuilder = System.Text.StringBuilder; +using System.Diagnostics; namespace System.Xml.Linq { @@ -28,10 +29,10 @@ namespace System.Xml.Linq /// public abstract class XNode : XObject { - private static XNodeDocumentOrderComparer s_documentOrderComparer; - private static XNodeEqualityComparer s_equalityComparer; + private static XNodeDocumentOrderComparer? s_documentOrderComparer; + private static XNodeEqualityComparer? s_equalityComparer; - internal XNode next; + internal XNode? next; internal XNode() { } @@ -42,7 +43,7 @@ internal XNode() { } /// If this property does not have a parent, or if there is no next node, /// then this property returns null. /// - public XNode NextNode + public XNode? NextNode { get { @@ -57,17 +58,18 @@ public XNode NextNode /// If this property does not have a parent, or if there is no previous node, /// then this property returns null. /// - public XNode PreviousNode + public XNode? PreviousNode { get { if (parent == null) return null; - XNode n = ((XNode)parent.content).next; - XNode p = null; + Debug.Assert(parent.content != null); + XNode n = ((XNode)parent.content!).next!; + XNode? p = null; while (n != this) { p = n; - n = n.next; + n = n.next!; } return p; } @@ -117,7 +119,7 @@ public static XNodeEqualityComparer EqualityComparer /// See XContainer.Add(object content) for details about the content that can be added /// using this method. /// - public void AddAfterSelf(object content) + public void AddAfterSelf(object? content) { if (parent == null) throw new InvalidOperationException(SR.InvalidOperation_MissingParent); new Inserter(parent, this).Add(content); @@ -161,11 +163,11 @@ public void AddAfterSelf(params object[] content) /// See XContainer.Add(object content) for details about the content that can be added /// using this method. /// - public void AddBeforeSelf(object content) + public void AddBeforeSelf(object? content) { if (parent == null) throw new InvalidOperationException(SR.InvalidOperation_MissingParent); - XNode p = (XNode)parent.content; - while (p.next != this) p = p.next; + XNode? p = (XNode)parent.content!; + while (p.next != this) p = p.next!; if (p == parent.content) p = null; new Inserter(parent, p).Add(content); } @@ -218,7 +220,7 @@ public IEnumerable Ancestors() /// /// This method will not return itself in the results. /// - public IEnumerable Ancestors(XName name) + public IEnumerable Ancestors(XName? name) { return name != null ? GetAncestors(name, false) : XElement.EmptySequence; } @@ -234,7 +236,7 @@ public IEnumerable Ancestors(XName name) /// /// Thrown if the two nodes do not share a common ancestor. /// - public static int CompareDocumentOrder(XNode n1, XNode n2) + public static int CompareDocumentOrder(XNode? n1, XNode? n2) { if (n1 == n2) return 0; if (n1 == null) return -1; @@ -259,7 +261,7 @@ public static int CompareDocumentOrder(XNode n1, XNode n2) { do { - n2 = n2.parent; + n2 = n2.parent!; height++; } while (height != 0); if (n1 == n2) return -1; @@ -268,25 +270,25 @@ public static int CompareDocumentOrder(XNode n1, XNode n2) { do { - n1 = n1.parent; + n1 = n1.parent!; height--; } while (height != 0); if (n1 == n2) return 1; } while (n1.parent != n2.parent) { - n1 = n1.parent; - n2 = n2.parent; + n1 = n1.parent!; + n2 = n2.parent!; } } else if (n1.parent == null) { throw new InvalidOperationException(SR.InvalidOperation_MissingAncestor); } - XNode n = (XNode)n1.parent.content; + XNode n = (XNode)n1.parent!.content!; while (true) { - n = n.next; + n = n.next!; if (n == n1) return -1; if (n == n2) return 1; } @@ -325,7 +327,7 @@ public IEnumerable NodesAfterSelf() XNode n = this; while (n.parent != null && n != n.parent.content) { - n = n.next; + n = n.next!; yield return n; } } @@ -341,10 +343,10 @@ public IEnumerable NodesBeforeSelf() { if (parent != null) { - XNode n = (XNode)parent.content; + XNode n = (XNode)parent.content!; do { - n = n.next; + n = n.next!; if (n == this) break; yield return n; } while (parent != null && parent == n.parent); @@ -372,7 +374,7 @@ public IEnumerable ElementsAfterSelf() /// /// The element nodes after this node with the specified name. /// The name of elements to enumerate. - public IEnumerable ElementsAfterSelf(XName name) + public IEnumerable ElementsAfterSelf(XName? name) { return name != null ? GetElementsAfterSelf(name) : XElement.EmptySequence; } @@ -398,7 +400,7 @@ public IEnumerable ElementsBeforeSelf() /// /// The element nodes before this node with the specified name. /// The name of elements to enumerate. - public IEnumerable ElementsBeforeSelf(XName name) + public IEnumerable ElementsBeforeSelf(XName? name) { return name != null ? GetElementsBeforeSelf(name) : XElement.EmptySequence; } @@ -409,7 +411,7 @@ public IEnumerable ElementsBeforeSelf(XName name) /// /// The node to compare for document order. /// True if this node appears after the specified node; false if not. - public bool IsAfter(XNode node) + public bool IsAfter(XNode? node) { return CompareDocumentOrder(this, node) > 0; } @@ -420,7 +422,7 @@ public bool IsAfter(XNode node) /// /// The node to compare for document order. /// True if this node appears before the specified node; false if not. - public bool IsBefore(XNode node) + public bool IsBefore(XNode? node) { return CompareDocumentOrder(this, node) < 0; } @@ -549,12 +551,12 @@ public void Remove() /// Replaces the content of this . /// /// Content that replaces this node. - public void ReplaceWith(object content) + public void ReplaceWith(object? content) { if (parent == null) throw new InvalidOperationException(SR.InvalidOperation_MissingParent); XContainer c = parent; - XNode p = (XNode)parent.content; - while (p.next != this) p = p.next; + XNode? p = (XNode)parent.content!; + while (p.next != this) p = p.next!; if (p == parent.content) p = null; parent.RemoveNode(this); if (p != null && p.parent != c) throw new InvalidOperationException(SR.InvalidOperation_ExternalCode); @@ -611,7 +613,7 @@ public string ToString(SaveOptions options) /// Two nodes are equal if they have the same /// target and data. Two nodes are equal if the have the /// same name, public id, system id, and internal subset. - public static bool DeepEquals(XNode n1, XNode n2) + public static bool DeepEquals(XNode? n1, XNode? n2) { if (n1 == n2) return true; if (n1 == null || n2 == null) return false; @@ -639,9 +641,9 @@ internal virtual void AppendText(StringBuilder sb) internal abstract bool DeepEquals(XNode node); - internal IEnumerable GetAncestors(XName name, bool self) + internal IEnumerable GetAncestors(XName? name, bool self) { - XElement e = (self ? this : parent) as XElement; + XElement? e = (self ? this : parent) as XElement; while (e != null) { if (name == null || e.name == name) yield return e; @@ -649,27 +651,27 @@ internal IEnumerable GetAncestors(XName name, bool self) } } - private IEnumerable GetElementsAfterSelf(XName name) + private IEnumerable GetElementsAfterSelf(XName? name) { XNode n = this; while (n.parent != null && n != n.parent.content) { - n = n.next; - XElement e = n as XElement; + n = n.next!; + XElement? e = n as XElement; if (e != null && (name == null || e.name == name)) yield return e; } } - private IEnumerable GetElementsBeforeSelf(XName name) + private IEnumerable GetElementsBeforeSelf(XName? name) { if (parent != null) { - XNode n = (XNode)parent.content; + XNode n = (XNode)parent.content!; do { - n = n.next; + n = n.next!; if (n == this) break; - XElement e = n as XElement; + XElement? e = n as XElement; if (e != null && (name == null || e.name == name)) yield return e; } while (parent != null && parent == n.parent); } @@ -712,7 +714,7 @@ private string GetXmlString(SaveOptions o) if (this is XText) ws.ConformanceLevel = ConformanceLevel.Fragment; using (XmlWriter w = XmlWriter.Create(sw, ws)) { - XDocument n = this as XDocument; + XDocument? n = this as XDocument; if (n != null) { n.WriteContentTo(w); diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeBuilder.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeBuilder.cs index 0c6f99cf18c299..5269b2fc077a3c 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeBuilder.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeBuilder.cs @@ -2,15 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics; namespace System.Xml.Linq { internal class XNodeBuilder : XmlWriter { - private List _content; - private XContainer _parent; - private XName _attrName; - private string _attrValue; + private List? _content; + private XContainer? _parent; + private XName? _attrName; + private string? _attrValue; private readonly XContainer _root; public XNodeBuilder(XContainer container) @@ -60,9 +61,9 @@ public override void WriteBase64(byte[] buffer, int index, int count) throw new NotSupportedException(SR.NotSupported_WriteBase64); } - public override void WriteCData(string text) + public override void WriteCData(string? text) { - AddNode(new XCData(text)); + AddNode(new XCData(text!)); } public override void WriteCharEntity(char ch) @@ -75,19 +76,20 @@ public override void WriteChars(char[] buffer, int index, int count) AddString(new string(buffer, index, count)); } - public override void WriteComment(string text) + public override void WriteComment(string? text) { - AddNode(new XComment(text)); + AddNode(new XComment(text!)); } - public override void WriteDocType(string name, string pubid, string sysid, string subset) + public override void WriteDocType(string name, string? pubid, string? sysid, string? subset) { + Debug.Assert(subset != null); AddNode(new XDocumentType(name, pubid, sysid, subset)); } public override void WriteEndAttribute() { - XAttribute a = new XAttribute(_attrName, _attrValue); + XAttribute a = new XAttribute(_attrName!, _attrValue!); _attrName = null; _attrValue = null; if (_parent != null) @@ -106,7 +108,7 @@ public override void WriteEndDocument() public override void WriteEndElement() { - _parent = ((XElement)_parent).parent; + _parent = ((XElement)_parent!).parent; } public override void WriteEntityRef(string name) @@ -135,7 +137,7 @@ public override void WriteEntityRef(string name) public override void WriteFullEndElement() { - XElement e = (XElement)_parent; + XElement e = (XElement)_parent!; if (e.IsEmpty) { e.Add(string.Empty); @@ -143,13 +145,13 @@ public override void WriteFullEndElement() _parent = e.parent; } - public override void WriteProcessingInstruction(string name, string text) + public override void WriteProcessingInstruction(string name, string? text) { if (name == "xml") { return; } - AddNode(new XProcessingInstruction(name, text)); + AddNode(new XProcessingInstruction(name, text!)); } public override void WriteRaw(char[] buffer, int index, int count) @@ -162,10 +164,10 @@ public override void WriteRaw(string data) AddString(data); } - public override void WriteStartAttribute(string prefix, string localName, string namespaceName) + public override void WriteStartAttribute(string? prefix, string localName, string? namespaceName) { if (prefix == null) throw new ArgumentNullException(nameof(prefix)); - _attrName = XNamespace.Get(prefix.Length == 0 ? string.Empty : namespaceName).GetName(localName); + _attrName = XNamespace.Get(prefix.Length == 0 ? string.Empty : namespaceName!).GetName(localName); _attrValue = string.Empty; } @@ -177,12 +179,12 @@ public override void WriteStartDocument(bool standalone) { } - public override void WriteStartElement(string prefix, string localName, string namespaceName) + public override void WriteStartElement(string? prefix, string localName, string? namespaceName) { - AddNode(new XElement(XNamespace.Get(namespaceName).GetName(localName))); + AddNode(new XElement(XNamespace.Get(namespaceName!).GetName(localName))); } - public override void WriteString(string text) + public override void WriteString(string? text) { AddString(text); } @@ -200,7 +202,7 @@ public override void WriteValue(DateTimeOffset value) WriteString(XmlConvert.ToString(value)); } - public override void WriteWhitespace(string ws) + public override void WriteWhitespace(string? ws) { AddString(ws); } @@ -224,14 +226,14 @@ private void AddNode(XNode n) { Add(n); } - XContainer c = n as XContainer; + XContainer? c = n as XContainer; if (c != null) { _parent = c; } } - private void AddString(string s) + private void AddString(string? s) { if (s == null) { diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeDocumentOrderComparer.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeDocumentOrderComparer.cs index c80448c404de71..6abc99f4dc025e 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeDocumentOrderComparer.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeDocumentOrderComparer.cs @@ -28,7 +28,7 @@ public sealed class XNodeDocumentOrderComparer : /// /// Thrown if the two nodes do not share a common ancestor. /// - public int Compare(XNode x, XNode y) + public int Compare(XNode? x, XNode? y) { return XNode.CompareDocumentOrder(x, y); } @@ -49,11 +49,11 @@ public int Compare(XNode x, XNode y) /// /// Thrown if either of the two nodes are not derived from XNode. /// - int IComparer.Compare(object x, object y) + int IComparer.Compare(object? x, object? y) { - XNode n1 = x as XNode; + XNode? n1 = x as XNode; if (n1 == null && x != null) throw new ArgumentException(SR.Format(SR.Argument_MustBeDerivedFrom, typeof(XNode)), nameof(x)); - XNode n2 = y as XNode; + XNode? n2 = y as XNode; if (n2 == null && y != null) throw new ArgumentException(SR.Format(SR.Argument_MustBeDerivedFrom, typeof(XNode)), nameof(y)); return Compare(n1, n2); } diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeEqualityComparer.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeEqualityComparer.cs index 93b40b1fd11ca0..0b3b2dd94ac18c 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeEqualityComparer.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeEqualityComparer.cs @@ -34,7 +34,7 @@ public sealed class XNodeEqualityComparer : /// target and data. Two nodes are equal if the have the /// same name, public id, system id, and internal subset. /// - public bool Equals(XNode x, XNode y) + public bool Equals(XNode? x, XNode? y) { return XNode.DeepEquals(x, y); } @@ -73,11 +73,11 @@ public int GetHashCode(XNode obj) /// target and data. Two nodes are equal if the have the /// same name, public id, system id, and internal subset. /// - bool IEqualityComparer.Equals(object x, object y) + bool IEqualityComparer.Equals(object? x, object? y) { - XNode n1 = x as XNode; + XNode? n1 = x as XNode; if (n1 == null && x != null) throw new ArgumentException(SR.Format(SR.Argument_MustBeDerivedFrom, typeof(XNode)), nameof(x)); - XNode n2 = y as XNode; + XNode? n2 = y as XNode; if (n2 == null && y != null) throw new ArgumentException(SR.Format(SR.Argument_MustBeDerivedFrom, typeof(XNode)), nameof(y)); return Equals(n1, n2); } @@ -94,9 +94,9 @@ bool IEqualityComparer.Equals(object x, object y) /// int IEqualityComparer.GetHashCode(object obj) { - XNode n = obj as XNode; + XNode? n = obj as XNode; if (n == null && obj != null) throw new ArgumentException(SR.Format(SR.Argument_MustBeDerivedFrom, typeof(XNode)), nameof(obj)); - return GetHashCode(n); + return GetHashCode(n!); } } } diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeReader.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeReader.cs index daa1a2e1022f21..96b9d9f5d68073 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeReader.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeReader.cs @@ -14,13 +14,13 @@ internal class XNodeReader : XmlReader, IXmlLineInfo // uses (instance, parent attribute). End element uses (instance, // instance). Common XObject uses (instance, null). private object _source; - private object _parent; + private object? _parent; private ReadState _state; private XNode _root; private readonly XmlNameTable _nameTable; private readonly bool _omitDuplicateNamespaces; - internal XNodeReader(XNode node, XmlNameTable nameTable, ReaderOptions options) + internal XNodeReader(XNode node, XmlNameTable? nameTable, ReaderOptions options) { _source = node; _root = node; @@ -28,7 +28,7 @@ internal XNodeReader(XNode node, XmlNameTable nameTable, ReaderOptions options) _omitDuplicateNamespaces = (options & ReaderOptions.OmitDuplicateNamespaces) != 0 ? true : false; } - internal XNodeReader(XNode node, XmlNameTable nameTable) + internal XNodeReader(XNode node, XmlNameTable? nameTable) : this(node, nameTable, (node.GetSaveOptionsFromAnnotations() & SaveOptions.OmitDuplicateNamespaces) != 0 ? ReaderOptions.OmitDuplicateNamespaces : ReaderOptions.None) @@ -44,15 +44,15 @@ public override int AttributeCount return 0; } int count = 0; - XElement e = GetElementInAttributeScope(); + XElement? e = GetElementInAttributeScope(); if (e != null) { - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (!_omitDuplicateNamespaces || !IsDuplicateNamespaceAttribute(a)) { count++; @@ -68,7 +68,7 @@ public override string BaseURI { get { - XObject o = _source as XObject; + XObject? o = _source as XObject; if (o != null) { return o.BaseUri; @@ -90,7 +90,7 @@ public override int Depth { return 0; } - XObject o = _source as XObject; + XObject? o = _source as XObject; if (o != null) { return GetDepth(o); @@ -132,12 +132,12 @@ public override bool HasAttributes { return false; } - XElement e = GetElementInAttributeScope(); + XElement? e = GetElementInAttributeScope(); if (e != null && e.lastAttr != null) { if (_omitDuplicateNamespaces) { - return GetFirstNonDuplicateNamespaceAttribute(e.lastAttr.next) != null; + return GetFirstNonDuplicateNamespaceAttribute(e.lastAttr.next!) != null; } else { @@ -159,7 +159,7 @@ public override bool HasValue { return false; } - XObject o = _source as XObject; + XObject? o = _source as XObject; if (o != null) { switch (o.NodeType) @@ -187,7 +187,7 @@ public override bool IsEmptyElement { return false; } - XElement e = _source as XElement; + XElement? e = _source as XElement; return e != null && e.IsEmpty; } } @@ -203,22 +203,22 @@ private string GetLocalName() { return string.Empty; } - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { return e.Name.LocalName; } - XAttribute a = _source as XAttribute; + XAttribute? a = _source as XAttribute; if (a != null) { return a.Name.LocalName; } - XProcessingInstruction p = _source as XProcessingInstruction; + XProcessingInstruction? p = _source as XProcessingInstruction; if (p != null) { return p.Target; } - XDocumentType n = _source as XDocumentType; + XDocumentType? n = _source as XDocumentType; if (n != null) { return n.Name; @@ -250,12 +250,12 @@ private string GetNamespaceURI() { return string.Empty; } - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { return e.Name.NamespaceName; } - XAttribute a = _source as XAttribute; + XAttribute? a = _source as XAttribute; if (a != null) { string namespaceName = a.Name.NamespaceName; @@ -281,7 +281,7 @@ public override XmlNodeType NodeType { return XmlNodeType.None; } - XObject o = _source as XObject; + XObject? o = _source as XObject; if (o != null) { if (IsEndElement) @@ -318,20 +318,20 @@ private string GetPrefix() { return string.Empty; } - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { - string prefix = e.GetPrefixOfNamespace(e.Name.Namespace); + string? prefix = e.GetPrefixOfNamespace(e.Name.Namespace); if (prefix != null) { return prefix; } return string.Empty; } - XAttribute a = _source as XAttribute; + XAttribute? a = _source as XAttribute; if (a != null) { - string prefix = a.GetPrefixOfNamespace(a.Name.Namespace); + string? prefix = a.GetPrefixOfNamespace(a.Name.Namespace); if (prefix != null) { return prefix; @@ -363,7 +363,7 @@ public override string Value { return string.Empty; } - XObject o = _source as XObject; + XObject? o = _source as XObject; if (o != null) { switch (o.NodeType) @@ -395,13 +395,13 @@ public override string XmlLang { return string.Empty; } - XElement e = GetElementInScope(); + XElement? e = GetElementInScope(); if (e != null) { XName name = XNamespace.Xml.GetName("lang"); do { - XAttribute a = e.Attribute(name); + XAttribute? a = e.Attribute(name); if (a != null) { return a.Value; @@ -421,13 +421,13 @@ public override XmlSpace XmlSpace { return XmlSpace.None; } - XElement e = GetElementInScope(); + XElement? e = GetElementInScope(); if (e != null) { XName name = XNamespace.Xml.GetName("space"); do { - XAttribute a = e.Attribute(name); + XAttribute? a = e.Attribute(name); if (a != null) { switch (a.Value.Trim(s_WhitespaceChars)) @@ -457,29 +457,29 @@ protected override void Dispose(bool disposing) public override void Close() { - _source = null; + _source = null!; _parent = null; - _root = null; + _root = null!; _state = ReadState.Closed; } - public override string GetAttribute(string name) + public override string? GetAttribute(string name) { if (!IsInteractive) { return null; } - XElement e = GetElementInAttributeScope(); + XElement? e = GetElementInAttributeScope(); if (e != null) { - string localName, namespaceName; + string? localName, namespaceName; GetNameInAttributeScope(name, e, out localName, out namespaceName); - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (a.Name.LocalName == localName && a.Name.NamespaceName == namespaceName) { if (_omitDuplicateNamespaces && IsDuplicateNamespaceAttribute(a)) @@ -495,7 +495,7 @@ public override string GetAttribute(string name) } return null; } - XDocumentType n = _source as XDocumentType; + XDocumentType? n = _source as XDocumentType; if (n != null) { switch (name) @@ -509,13 +509,13 @@ public override string GetAttribute(string name) return null; } - public override string GetAttribute(string localName, string namespaceName) + public override string? GetAttribute(string localName, string? namespaceName) { if (!IsInteractive) { return null; } - XElement e = GetElementInAttributeScope(); + XElement? e = GetElementInAttributeScope(); if (e != null) { if (localName == "xmlns") @@ -529,12 +529,12 @@ public override string GetAttribute(string localName, string namespaceName) namespaceName = string.Empty; } } - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (a.Name.LocalName == localName && a.Name.NamespaceName == namespaceName) { if (_omitDuplicateNamespaces && IsDuplicateNamespaceAttribute(a)) @@ -552,25 +552,26 @@ public override string GetAttribute(string localName, string namespaceName) return null; } + // TODO-NULLABLE: decide if base signature should be switched to return string? public override string GetAttribute(int index) { if (!IsInteractive) { - return null; + return null!; } if (index < 0) { - return null; + return null!; } - XElement e = GetElementInAttributeScope(); + XElement? e = GetElementInAttributeScope(); if (e != null) { - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (!_omitDuplicateNamespaces || !IsDuplicateNamespaceAttribute(a)) { if (index-- == 0) @@ -581,10 +582,10 @@ public override string GetAttribute(int index) } while (a != e.lastAttr); } } - return null; + return null!; } - public override string LookupNamespace(string prefix) + public override string? LookupNamespace(string prefix) { if (!IsInteractive) { @@ -594,10 +595,10 @@ public override string LookupNamespace(string prefix) { return null; } - XElement e = GetElementInScope(); + XElement? e = GetElementInScope(); if (e != null) { - XNamespace ns = prefix.Length == 0 ? e.GetDefaultNamespace() : e.GetNamespaceOfPrefix(prefix); + XNamespace? ns = prefix.Length == 0 ? e.GetDefaultNamespace() : e.GetNamespaceOfPrefix(prefix); if (ns != null) { return _nameTable.Add(ns.NamespaceName); @@ -612,17 +613,17 @@ public override bool MoveToAttribute(string name) { return false; } - XElement e = GetElementInAttributeScope(); + XElement? e = GetElementInAttributeScope(); if (e != null) { - string localName, namespaceName; + string? localName, namespaceName; GetNameInAttributeScope(name, e, out localName, out namespaceName); - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (a.Name.LocalName == localName && a.Name.NamespaceName == namespaceName) { @@ -644,13 +645,13 @@ public override bool MoveToAttribute(string name) return false; } - public override bool MoveToAttribute(string localName, string namespaceName) + public override bool MoveToAttribute(string localName, string? namespaceName) { if (!IsInteractive) { return false; } - XElement e = GetElementInAttributeScope(); + XElement? e = GetElementInAttributeScope(); if (e != null) { if (localName == "xmlns") @@ -664,12 +665,12 @@ public override bool MoveToAttribute(string localName, string namespaceName) namespaceName = string.Empty; } } - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (a.Name.LocalName == localName && a.Name.NamespaceName == namespaceName) { @@ -698,15 +699,15 @@ public override void MoveToAttribute(int index) return; } if (index < 0) throw new ArgumentOutOfRangeException(nameof(index)); - XElement e = GetElementInAttributeScope(); + XElement? e = GetElementInAttributeScope(); if (e != null) { - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (!_omitDuplicateNamespaces || !IsDuplicateNamespaceAttribute(a)) { // Only count those which are non-duplicates if we're asked to @@ -729,7 +730,7 @@ public override bool MoveToElement() { return false; } - XAttribute a = _source as XAttribute; + XAttribute? a = _source as XAttribute; if (a == null) { a = _parent as XAttribute; @@ -752,14 +753,14 @@ public override bool MoveToFirstAttribute() { return false; } - XElement e = GetElementInAttributeScope(); + XElement? e = GetElementInAttributeScope(); if (e != null) { if (e.lastAttr != null) { if (_omitDuplicateNamespaces) { - object na = GetFirstNonDuplicateNamespaceAttribute(e.lastAttr.next); + object? na = GetFirstNonDuplicateNamespaceAttribute(e.lastAttr.next!); if (na == null) { return false; @@ -768,7 +769,7 @@ public override bool MoveToFirstAttribute() } else { - _source = e.lastAttr.next; + _source = e.lastAttr.next!; } return true; } @@ -782,7 +783,7 @@ public override bool MoveToNextAttribute() { return false; } - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { if (IsEndElement) @@ -796,7 +797,7 @@ public override bool MoveToNextAttribute() // Skip duplicate namespace attributes // We must NOT modify the this.source until we find the one we're looking for // because if we don't find anything, we need to stay positioned where we're now - object na = GetFirstNonDuplicateNamespaceAttribute(e.lastAttr.next); + object? na = GetFirstNonDuplicateNamespaceAttribute(e.lastAttr.next!); if (na == null) { return false; @@ -805,13 +806,13 @@ public override bool MoveToNextAttribute() } else { - _source = e.lastAttr.next; + _source = e.lastAttr.next!; } return true; } return false; } - XAttribute a = _source as XAttribute; + XAttribute? a = _source as XAttribute; if (a == null) { a = _parent as XAttribute; @@ -825,7 +826,7 @@ public override bool MoveToNextAttribute() // Skip duplicate namespace attributes // We must NOT modify the this.source until we find the one we're looking for // because if we don't find anything, we need to stay positioned where we're now - object na = GetFirstNonDuplicateNamespaceAttribute(a.next); + object? na = GetFirstNonDuplicateNamespaceAttribute(a.next!); if (na == null) { return false; @@ -834,7 +835,7 @@ public override bool MoveToNextAttribute() } else { - _source = a.next; + _source = a.next!; } _parent = null; return true; @@ -849,7 +850,7 @@ public override bool Read() { case ReadState.Initial: _state = ReadState.Interactive; - XDocument d = _source as XDocument; + XDocument? d = _source as XDocument; if (d != null) { return ReadIntoDocument(d); @@ -868,7 +869,7 @@ public override bool ReadAttributeValue() { return false; } - XAttribute a = _source as XAttribute; + XAttribute? a = _source as XAttribute; if (a != null) { return ReadIntoAttribute(a); @@ -883,7 +884,7 @@ public override bool ReadToDescendant(string localName, string namespaceName) return false; } MoveToElement(); - XElement c = _source as XElement; + XElement? c = _source as XElement; if (c != null && !c.IsEmpty) { if (IsEndElement) @@ -908,7 +909,7 @@ public override bool ReadToFollowing(string localName, string namespaceName) { while (Read()) { - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { if (IsEndElement) continue; @@ -930,7 +931,7 @@ public override bool ReadToNextSibling(string localName, string namespaceName) MoveToElement(); if (_source != _root) { - XNode n = _source as XNode; + XNode? n = _source as XNode; if (n != null) { foreach (XElement e in n.ElementsAfterSelf()) @@ -983,7 +984,7 @@ bool IXmlLineInfo.HasLineInfo() { // Special case for EndElement - we store the line info differently in this case // we also know that the current node (source) is XElement - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { return e.Annotation() != null; @@ -991,7 +992,7 @@ bool IXmlLineInfo.HasLineInfo() } else { - IXmlLineInfo li = _source as IXmlLineInfo; + IXmlLineInfo? li = _source as IXmlLineInfo; if (li != null) { return li.HasLineInfo(); @@ -1008,10 +1009,10 @@ int IXmlLineInfo.LineNumber { // Special case for EndElement - we store the line info differently in this case // we also know that the current node (source) is XElement - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { - LineInfoEndElementAnnotation a = e.Annotation(); + LineInfoEndElementAnnotation? a = e.Annotation(); if (a != null) { return a.lineNumber; @@ -1020,7 +1021,7 @@ int IXmlLineInfo.LineNumber } else { - IXmlLineInfo li = _source as IXmlLineInfo; + IXmlLineInfo? li = _source as IXmlLineInfo; if (li != null) { return li.LineNumber; @@ -1038,10 +1039,10 @@ int IXmlLineInfo.LinePosition { // Special case for EndElement - we store the line info differently in this case // we also know that the current node (source) is XElement - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { - LineInfoEndElementAnnotation a = e.Annotation(); + LineInfoEndElementAnnotation? a = e.Annotation(); if (a != null) { return a.linePosition; @@ -1050,7 +1051,7 @@ int IXmlLineInfo.LinePosition } else { - IXmlLineInfo li = _source as IXmlLineInfo; + IXmlLineInfo? li = _source as IXmlLineInfo; if (li != null) { return li.LinePosition; @@ -1080,9 +1081,9 @@ private static XmlNameTable CreateNameTable() return nameTable; } - private XElement GetElementInAttributeScope() + private XElement? GetElementInAttributeScope() { - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { if (IsEndElement) @@ -1091,35 +1092,35 @@ private XElement GetElementInAttributeScope() } return e; } - XAttribute a = _source as XAttribute; + XAttribute? a = _source as XAttribute; if (a != null) { - return (XElement)a.parent; + return (XElement?)a.parent; } a = _parent as XAttribute; if (a != null) { - return (XElement)a.parent; + return (XElement?)a.parent; } return null; } - private XElement GetElementInScope() + private XElement? GetElementInScope() { - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { return e; } - XNode n = _source as XNode; + XNode? n = _source as XNode; if (n != null) { return n.parent as XElement; } - XAttribute a = _source as XAttribute; + XAttribute? a = _source as XAttribute; if (a != null) { - return (XElement)a.parent; + return (XElement?)a.parent; } e = _parent as XElement; if (e != null) @@ -1129,12 +1130,12 @@ private XElement GetElementInScope() a = _parent as XAttribute; if (a != null) { - return (XElement)a.parent; + return (XElement?)a.parent; } return null; } - private static void GetNameInAttributeScope(string qualifiedName, XElement e, out string localName, out string namespaceName) + private static void GetNameInAttributeScope(string? qualifiedName, XElement e, out string? localName, out string? namespaceName) { if (!string.IsNullOrEmpty(qualifiedName)) { @@ -1147,7 +1148,7 @@ private static void GetNameInAttributeScope(string qualifiedName, XElement e, ou namespaceName = string.Empty; return; } - XNamespace ns = e.GetNamespaceOfPrefix(qualifiedName.Substring(0, i)); + XNamespace? ns = e.GetNamespaceOfPrefix(qualifiedName.Substring(0, i)); if (ns != null) { localName = qualifiedName.Substring(i + 1, qualifiedName.Length - i - 1); @@ -1162,7 +1163,7 @@ private static void GetNameInAttributeScope(string qualifiedName, XElement e, ou private bool Read(bool skipContent) { - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { if (e.IsEmpty || IsEndElement || skipContent) @@ -1171,12 +1172,12 @@ private bool Read(bool skipContent) } return ReadIntoElement(e); } - XNode n = _source as XNode; + XNode? n = _source as XNode; if (n != null) { return ReadOverNode(n); } - XAttribute a = _source as XAttribute; + XAttribute? a = _source as XAttribute; if (a != null) { return ReadOverAttribute(a, skipContent); @@ -1186,13 +1187,13 @@ private bool Read(bool skipContent) private bool ReadIntoDocument(XDocument d) { - XNode n = d.content as XNode; + XNode? n = d.content as XNode; if (n != null) { - _source = n.next; + _source = n.next!; return true; } - string s = d.content as string; + string? s = d.content as string; if (s != null) { if (s.Length > 0) @@ -1207,13 +1208,13 @@ private bool ReadIntoDocument(XDocument d) private bool ReadIntoElement(XElement e) { - XNode n = e.content as XNode; + XNode? n = e.content as XNode; if (n != null) { - _source = n.next; + _source = n.next!; return true; } - string s = e.content as string; + string? s = e.content as string; if (s != null) { if (s.Length > 0) @@ -1240,7 +1241,7 @@ private bool ReadIntoAttribute(XAttribute a) private bool ReadOverAttribute(XAttribute a, bool skipContent) { - XElement e = (XElement)a.parent; + XElement? e = (XElement?)a.parent; if (e != null) { if (e.IsEmpty || skipContent) @@ -1258,8 +1259,8 @@ private bool ReadOverNode(XNode n) { return ReadToEnd(); } - XNode next = n.next; - if (null == next || next == n || n == n.parent.content) + XNode? next = n.next; + if (null == next || next == n || n == n.parent!.content) { if (n.parent == null || (n.parent.parent == null && n.parent is XDocument)) { @@ -1286,7 +1287,7 @@ private bool ReadOverText(bool skipContent) return true; } - XAttribute parent = _parent as XAttribute; + XAttribute? parent = _parent as XAttribute; if (parent != null) { _parent = null; @@ -1333,7 +1334,7 @@ private bool IsDuplicateNamespaceAttributeInner(XAttribute candidateAttribute) // and find the closest namespace declaration attribute which declares the same prefix // If it declares that prefix to the exact same URI as ours does then ours is a duplicate // Note that if we find a namespace declaration for the same prefix but with a different URI, then we don't have a dupe! - XElement element = candidateAttribute.parent as XElement; + XElement? element = candidateAttribute.parent as XElement; if (element == _root || element == null) { // If there's only the parent element of our attribute, there can be no duplicates @@ -1347,7 +1348,7 @@ private bool IsDuplicateNamespaceAttributeInner(XAttribute candidateAttribute) // (The default ns decl is represented by an XName "xmlns{}", even if you try to create // an attribute with XName "xmlns{http://www.w3.org/2000/xmlns/}" it will fail, // because it's treated as a declaration of prefix "xmlns" which is invalid) - XAttribute a = element.lastAttr; + XAttribute? a = element.lastAttr; if (a != null) { do @@ -1367,7 +1368,7 @@ private bool IsDuplicateNamespaceAttributeInner(XAttribute candidateAttribute) return false; } } - a = a.next; + a = a.next!; } while (a != element.lastAttr); } if (element == _root) @@ -1384,7 +1385,7 @@ private bool IsDuplicateNamespaceAttributeInner(XAttribute candidateAttribute) /// /// The attribute to start with /// The first attribute which is not a namespace attribute or null if the end of attributes has bean reached - private XAttribute GetFirstNonDuplicateNamespaceAttribute(XAttribute candidate) + private XAttribute? GetFirstNonDuplicateNamespaceAttribute(XAttribute candidate) { Debug.Assert(_omitDuplicateNamespaces, "This method should only be called if we're omitting duplicate namespace attribute." + "For perf reason it's better to test this flag in the caller method."); @@ -1393,12 +1394,12 @@ private XAttribute GetFirstNonDuplicateNamespaceAttribute(XAttribute candidate) return candidate; } - XElement e = candidate.parent as XElement; + XElement? e = candidate.parent as XElement; if (e != null && candidate != e.lastAttr) { do { - candidate = candidate.next; + candidate = candidate.next!; if (!IsDuplicateNamespaceAttribute(candidate)) { return candidate; diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XObject.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XObject.cs index 26af0ce9100dd0..1855419be7db42 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XObject.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XObject.cs @@ -13,8 +13,8 @@ namespace System.Xml.Linq /// public abstract class XObject : IXmlLineInfo { - internal XContainer parent; - internal object annotations; + internal XContainer? parent; + internal object? annotations; internal XObject() { } @@ -25,7 +25,7 @@ public string BaseUri { get { - XObject o = this; + XObject? o = this; while (true) { while (o != null && o.annotations == null) @@ -33,7 +33,7 @@ public string BaseUri o = o.parent; } if (o == null) break; - BaseUriAnnotation a = o.Annotation(); + BaseUriAnnotation? a = o.Annotation(); if (a != null) return a.baseUri; o = o.parent; } @@ -44,13 +44,16 @@ public string BaseUri /// /// Gets the XDocument object for this . /// - public XDocument Document + public XDocument? Document { get { XObject n = this; while (n.parent != null) n = n.parent; - return n as XDocument; + + XDocument? doc = n as XDocument; + + return doc; } } @@ -65,7 +68,7 @@ public XDocument Document /// /// If this has no parent , this property returns null. /// - public XElement Parent + public XElement? Parent { get { return parent as XElement; } } @@ -83,7 +86,7 @@ public void AddAnnotation(object annotation) } else { - object[] a = annotations as object[]; + object?[]? a = annotations as object[]; if (a == null) { annotations = new object[] { annotations, annotation }; @@ -111,12 +114,12 @@ public void AddAnnotation(object annotation) /// The first matching annotation object, or null /// if no annotation is the specified type. /// - public object Annotation(Type type) + public object? Annotation(Type type) { if (type == null) throw new ArgumentNullException(nameof(type)); if (annotations != null) { - object[] a = annotations as object[]; + object?[]? a = annotations as object[]; if (a == null) { if (XHelper.IsInstanceOfType(annotations, type)) return annotations; @@ -125,7 +128,7 @@ public object Annotation(Type type) { for (int i = 0; i < a.Length; i++) { - object obj = a[i]; + object? obj = a[i]; if (obj == null) break; if (XHelper.IsInstanceOfType(obj, type)) return obj; } @@ -134,13 +137,13 @@ public object Annotation(Type type) return null; } - private object AnnotationForSealedType(Type type) + private object? AnnotationForSealedType(Type type) { Debug.Assert(type != null); if (annotations != null) { - object[] a = annotations as object[]; + object?[]? a = annotations as object[]; if (a == null) { if (annotations.GetType() == type) return annotations; @@ -149,7 +152,7 @@ private object AnnotationForSealedType(Type type) { for (int i = 0; i < a.Length; i++) { - object obj = a[i]; + object? obj = a[i]; if (obj == null) break; if (obj.GetType() == type) return obj; } @@ -167,17 +170,17 @@ private object AnnotationForSealedType(Type type) /// The first matching annotation object, or null if no annotation /// is the specified type. /// - public T Annotation() where T : class + public T? Annotation() where T : class { if (annotations != null) { - object[] a = annotations as object[]; + object?[]? a = annotations as object[]; if (a == null) return annotations as T; for (int i = 0; i < a.Length; i++) { - object obj = a[i]; + object? obj = a[i]; if (obj == null) break; - T result = obj as T; + T? result = obj as T; if (result != null) return result; } } @@ -200,7 +203,7 @@ private IEnumerable AnnotationsIterator(Type type) { if (annotations != null) { - object[] a = annotations as object[]; + object?[]? a = annotations as object[]; if (a == null) { if (XHelper.IsInstanceOfType(annotations, type)) yield return annotations; @@ -209,7 +212,7 @@ private IEnumerable AnnotationsIterator(Type type) { for (int i = 0; i < a.Length; i++) { - object obj = a[i]; + object? obj = a[i]; if (obj == null) break; if (XHelper.IsInstanceOfType(obj, type)) yield return obj; } @@ -227,19 +230,19 @@ public IEnumerable Annotations() where T : class { if (annotations != null) { - object[] a = annotations as object[]; + object?[]? a = annotations as object[]; if (a == null) { - T result = annotations as T; + T? result = annotations as T; if (result != null) yield return result; } else { for (int i = 0; i < a.Length; i++) { - object obj = a[i]; + object? obj = a[i]; if (obj == null) break; - T result = obj as T; + T? result = obj as T; if (result != null) yield return result; } } @@ -255,7 +258,7 @@ public void RemoveAnnotations(Type type) if (type == null) throw new ArgumentNullException(nameof(type)); if (annotations != null) { - object[] a = annotations as object[]; + object?[]? a = annotations as object[]; if (a == null) { if (XHelper.IsInstanceOfType(annotations, type)) annotations = null; @@ -265,7 +268,7 @@ public void RemoveAnnotations(Type type) int i = 0, j = 0; while (i < a.Length) { - object obj = a[i]; + object? obj = a[i]; if (obj == null) break; if (!XHelper.IsInstanceOfType(obj, type)) a[j++] = obj; i++; @@ -290,7 +293,7 @@ public void RemoveAnnotations() where T : class { if (annotations != null) { - object[] a = annotations as object[]; + object?[]? a = annotations as object[]; if (a == null) { if (annotations is T) annotations = null; @@ -300,7 +303,7 @@ public void RemoveAnnotations() where T : class int i = 0, j = 0; while (i < a.Length) { - object obj = a[i]; + object? obj = a[i]; if (obj == null) break; if (!(obj is T)) a[j++] = obj; i++; @@ -325,7 +328,7 @@ public event EventHandler Changed add { if (value == null) return; - XObjectChangeAnnotation a = Annotation(); + XObjectChangeAnnotation? a = Annotation(); if (a == null) { a = new XObjectChangeAnnotation(); @@ -336,7 +339,7 @@ public event EventHandler Changed remove { if (value == null) return; - XObjectChangeAnnotation a = Annotation(); + XObjectChangeAnnotation? a = Annotation(); if (a == null) return; a.changed -= value; if (a.changing == null && a.changed == null) @@ -354,7 +357,7 @@ public event EventHandler Changing add { if (value == null) return; - XObjectChangeAnnotation a = Annotation(); + XObjectChangeAnnotation? a = Annotation(); if (a == null) { a = new XObjectChangeAnnotation(); @@ -365,7 +368,7 @@ public event EventHandler Changing remove { if (value == null) return; - XObjectChangeAnnotation a = Annotation(); + XObjectChangeAnnotation? a = Annotation(); if (a == null) return; a.changing -= value; if (a.changing == null && a.changed == null) @@ -384,7 +387,7 @@ int IXmlLineInfo.LineNumber { get { - LineInfoAnnotation a = Annotation(); + LineInfoAnnotation? a = Annotation(); if (a != null) return a.lineNumber; return 0; } @@ -394,7 +397,7 @@ int IXmlLineInfo.LinePosition { get { - LineInfoAnnotation a = Annotation(); + LineInfoAnnotation? a = Annotation(); if (a != null) return a.linePosition; return 0; } @@ -411,7 +414,7 @@ internal bool HasBaseUri internal bool NotifyChanged(object sender, XObjectChangeEventArgs e) { bool notify = false; - XObject o = this; + XObject? o = this; while (true) { while (o != null && o.annotations == null) @@ -419,7 +422,7 @@ internal bool NotifyChanged(object sender, XObjectChangeEventArgs e) o = o.parent; } if (o == null) break; - XObjectChangeAnnotation a = o.Annotation(); + XObjectChangeAnnotation? a = o.Annotation(); if (a != null) { notify = true; @@ -436,7 +439,7 @@ internal bool NotifyChanged(object sender, XObjectChangeEventArgs e) internal bool NotifyChanging(object sender, XObjectChangeEventArgs e) { bool notify = false; - XObject o = this; + XObject? o = this; while (true) { while (o != null && o.annotations == null) @@ -444,7 +447,7 @@ internal bool NotifyChanging(object sender, XObjectChangeEventArgs e) o = o.parent; } if (o == null) break; - XObjectChangeAnnotation a = o.Annotation(); + XObjectChangeAnnotation? a = o.Annotation(); if (a != null) { notify = true; @@ -470,7 +473,7 @@ internal void SetLineInfo(int lineNumber, int linePosition) internal bool SkipNotify() { - XObject o = this; + XObject? o = this; while (true) { while (o != null && o.annotations == null) @@ -490,7 +493,7 @@ internal bool SkipNotify() /// The effective for this internal SaveOptions GetSaveOptionsFromAnnotations() { - XObject o = this; + XObject? o = this; while (true) { while (o != null && o.annotations == null) @@ -501,7 +504,7 @@ internal SaveOptions GetSaveOptionsFromAnnotations() { return SaveOptions.None; } - object saveOptions = o.AnnotationForSealedType(typeof(SaveOptions)); + object? saveOptions = o.AnnotationForSealedType(typeof(SaveOptions)); if (saveOptions != null) { return (SaveOptions)saveOptions; diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XObjectChangeAnnotation.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XObjectChangeAnnotation.cs index 2b1d74da4b1c4f..54409b0e11a8a5 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XObjectChangeAnnotation.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XObjectChangeAnnotation.cs @@ -5,7 +5,7 @@ namespace System.Xml.Linq { internal class XObjectChangeAnnotation { - internal EventHandler changing; - internal EventHandler changed; + internal EventHandler? changing; + internal EventHandler? changed; } } diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XProcessingInstruction.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XProcessingInstruction.cs index 9cd39d6ac8a5f7..4218332977c11d 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XProcessingInstruction.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XProcessingInstruction.cs @@ -144,7 +144,7 @@ internal override XNode CloneNode() internal override bool DeepEquals(XNode node) { - XProcessingInstruction other = node as XProcessingInstruction; + XProcessingInstruction? other = node as XProcessingInstruction; return other != null && target == other.target && data == other.data; } diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XStreamingElement.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XStreamingElement.cs index eae330e4feffd8..d8a71a9c203f7f 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XStreamingElement.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XStreamingElement.cs @@ -15,7 +15,7 @@ namespace System.Xml.Linq public class XStreamingElement { internal XName name; - internal object content; + internal object? content; /// /// Creates a node with a given name @@ -69,11 +69,11 @@ public XName Name /// Add content to an /// /// Object containing content to add - public void Add(object content) + public void Add(object? content) { if (content != null) { - List list = this.content as List; + List? list = this.content as List; if (list == null) { list = new List(); diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Schema/XNodeValidator.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Schema/XNodeValidator.cs index 96cbfc6ad2f5a4..5d1f1208f4138b 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Schema/XNodeValidator.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Schema/XNodeValidator.cs @@ -8,25 +8,26 @@ using System.Xml; using System.Xml.Linq; using System.Runtime.Versioning; +using System.Diagnostics; namespace System.Xml.Schema { internal class XNodeValidator { private readonly XmlSchemaSet schemas; - private readonly ValidationEventHandler validationEventHandler; + private readonly ValidationEventHandler? validationEventHandler; - private XObject source; + private XObject? source; private bool addSchemaInfo; - private XmlNamespaceManager namespaceManager; - private XmlSchemaValidator validator; + private XmlNamespaceManager? namespaceManager; + private XmlSchemaValidator? validator; - private Dictionary schemaInfos; - private ArrayList defaultAttributes; + private Dictionary? schemaInfos; + private ArrayList? defaultAttributes; private readonly XName xsiTypeName; private readonly XName xsiNilName; - public XNodeValidator(XmlSchemaSet schemas, ValidationEventHandler validationEventHandler) + public XNodeValidator(XmlSchemaSet schemas, ValidationEventHandler? validationEventHandler) { this.schemas = schemas; this.validationEventHandler = validationEventHandler; @@ -36,7 +37,7 @@ public XNodeValidator(XmlSchemaSet schemas, ValidationEventHandler validationEve xsiNilName = xsi.GetName("nil"); } - public void Validate(XObject source, XmlSchemaObject partialValidationType, bool addSchemaInfo) + public void Validate(XObject source, XmlSchemaObject? partialValidationType, bool addSchemaInfo) { this.source = source; this.addSchemaInfo = addSchemaInfo; @@ -45,7 +46,7 @@ public void Validate(XObject source, XmlSchemaObject partialValidationType, bool switch (nt) { case XmlNodeType.Document: - source = ((XDocument)source).Root; + source = ((XDocument)source).Root!; if (source == null) throw new InvalidOperationException(SR.InvalidOperation_MissingRoot); validationFlags |= XmlSchemaValidationFlags.ProcessIdentityConstraints; break; @@ -91,16 +92,21 @@ private XmlSchemaInfo GetDefaultAttributeSchemaInfo(XmlSchemaAttribute sa) si.IsDefault = true; si.IsNil = false; si.SchemaAttribute = sa; + Debug.Assert(sa.AttributeSchemaType != null); XmlSchemaSimpleType st = sa.AttributeSchemaType; si.SchemaType = st; + Debug.Assert(st.Datatype != null); if (st.Datatype.Variety == XmlSchemaDatatypeVariety.Union) { - string value = GetDefaultValue(sa); - foreach (XmlSchemaSimpleType mt in ((XmlSchemaSimpleTypeUnion)st.Content).BaseMemberTypes) + string? value = GetDefaultValue(sa); + Debug.Assert(st.Content != null); + foreach (XmlSchemaSimpleType mt in ((XmlSchemaSimpleTypeUnion)st.Content).BaseMemberTypes!) { - object typedValue = null; + object? typedValue = null; try { + Debug.Assert(mt.Datatype != null); + Debug.Assert(value != null); typedValue = mt.Datatype.ParseValue(value, schemas.NameTable, namespaceManager); } catch (XmlSchemaException) @@ -117,30 +123,32 @@ private XmlSchemaInfo GetDefaultAttributeSchemaInfo(XmlSchemaAttribute sa) return si; } - private string GetDefaultValue(XmlSchemaAttribute sa) + private string? GetDefaultValue(XmlSchemaAttribute sa) { - XmlQualifiedName name = sa.RefName; + XmlSchemaAttribute? saCopy = sa; + XmlQualifiedName name = saCopy.RefName; if (!name.IsEmpty) { - sa = schemas.GlobalAttributes[name] as XmlSchemaAttribute; - if (sa == null) return null; + saCopy = schemas.GlobalAttributes[name] as XmlSchemaAttribute; + if (saCopy == null) return null; } - string s = sa.FixedValue; + string? s = saCopy.FixedValue; if (s != null) return s; - return sa.DefaultValue; + return saCopy.DefaultValue; } - private string GetDefaultValue(XmlSchemaElement se) + private string? GetDefaultValue(XmlSchemaElement se) { - XmlQualifiedName name = se.RefName; + XmlSchemaElement? seCopy = se; + XmlQualifiedName name = seCopy.RefName; if (!name.IsEmpty) { - se = schemas.GlobalElements[name] as XmlSchemaElement; - if (se == null) return null; + seCopy = schemas.GlobalElements[name] as XmlSchemaElement; + if (seCopy == null) return null; } - string s = se.FixedValue; + string? s = seCopy.FixedValue; if (s != null) return s; - return se.DefaultValue; + return seCopy.DefaultValue; } private void ReplaceSchemaInfo(XObject o, XmlSchemaInfo schemaInfo) @@ -149,7 +157,7 @@ private void ReplaceSchemaInfo(XObject o, XmlSchemaInfo schemaInfo) { schemaInfos = new Dictionary(new XmlSchemaInfoEqualityComparer()); } - XmlSchemaInfo si = o.Annotation(); + XmlSchemaInfo? si = o.Annotation(); if (si != null) { if (!schemaInfos.ContainsKey(si)) @@ -166,16 +174,16 @@ private void ReplaceSchemaInfo(XObject o, XmlSchemaInfo schemaInfo) o.AddAnnotation(si); } - private void PushAncestorsAndSelf(XElement e) + private void PushAncestorsAndSelf(XElement? e) { while (e != null) { - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (a.IsNamespaceDeclaration) { string localName = a.Name.LocalName; @@ -183,7 +191,7 @@ private void PushAncestorsAndSelf(XElement e) { localName = string.Empty; } - if (!namespaceManager.HasNamespace(localName)) + if (!namespaceManager!.HasNamespace(localName)) { namespaceManager.AddNamespace(localName, a.Value); } @@ -194,15 +202,15 @@ private void PushAncestorsAndSelf(XElement e) } } - private void PushElement(XElement e, ref string xsiType, ref string xsiNil) + private void PushElement(XElement e, ref string? xsiType, ref string? xsiNil) { - namespaceManager.PushScope(); - XAttribute a = e.lastAttr; + namespaceManager!.PushScope(); + XAttribute? a = e.lastAttr; if (a != null) { do { - a = a.next; + a = a.next!; if (a.IsNamespaceDeclaration) { string localName = a.Name.LocalName; @@ -228,41 +236,41 @@ private void PushElement(XElement e, ref string xsiType, ref string xsiNil) } } - private IXmlLineInfo SaveLineInfo(XObject source) + private IXmlLineInfo SaveLineInfo(XObject? source) { - IXmlLineInfo previousLineInfo = validator.LineInfoProvider; + IXmlLineInfo previousLineInfo = validator!.LineInfoProvider; validator.LineInfoProvider = source as IXmlLineInfo; return previousLineInfo; } private void RestoreLineInfo(IXmlLineInfo originalLineInfo) { - validator.LineInfoProvider = originalLineInfo; + validator!.LineInfoProvider = originalLineInfo; } private void ValidateAttribute(XAttribute a) { IXmlLineInfo original = SaveLineInfo(a); - XmlSchemaInfo si = addSchemaInfo ? new XmlSchemaInfo() : null; + XmlSchemaInfo? si = addSchemaInfo ? new XmlSchemaInfo() : null; source = a; - validator.ValidateAttribute(a.Name.LocalName, a.Name.NamespaceName, a.Value, si); + validator!.ValidateAttribute(a.Name.LocalName, a.Name.NamespaceName, a.Value, si); if (addSchemaInfo) { - ReplaceSchemaInfo(a, si); + ReplaceSchemaInfo(a, si!); } RestoreLineInfo(original); } private void ValidateAttributes(XElement e) { - XAttribute a = e.lastAttr; + XAttribute? a = e.lastAttr; IXmlLineInfo orginal = SaveLineInfo(a); if (a != null) { do { - a = a.next; + a = a.next!; if (!a.IsNamespaceDeclaration) { ValidateAttribute(a); @@ -280,10 +288,10 @@ private void ValidateAttributes(XElement e) { defaultAttributes.Clear(); } - validator.GetUnspecifiedDefaultAttributes(defaultAttributes); + validator!.GetUnspecifiedDefaultAttributes(defaultAttributes); foreach (XmlSchemaAttribute sa in defaultAttributes) { - a = new XAttribute(XNamespace.Get(sa.QualifiedName.Namespace).GetName(sa.QualifiedName.Name), GetDefaultValue(sa)); + a = new XAttribute(XNamespace.Get(sa.QualifiedName.Namespace).GetName(sa.QualifiedName.Name), GetDefaultValue(sa)!); ReplaceSchemaInfo(a, GetDefaultAttributeSchemaInfo(sa)); e.Add(a); } @@ -293,52 +301,53 @@ private void ValidateAttributes(XElement e) private void ValidateElement(XElement e) { - XmlSchemaInfo si = addSchemaInfo ? new XmlSchemaInfo() : null; - string xsiType = null; - string xsiNil = null; + XmlSchemaInfo? si = addSchemaInfo ? new XmlSchemaInfo() : null; + string? xsiType = null; + string? xsiNil = null; PushElement(e, ref xsiType, ref xsiNil); IXmlLineInfo original = SaveLineInfo(e); source = e; - validator.ValidateElement(e.Name.LocalName, e.Name.NamespaceName, si, xsiType, xsiNil, null, null); + validator!.ValidateElement(e.Name.LocalName, e.Name.NamespaceName, si, xsiType, xsiNil, null, null); ValidateAttributes(e); validator.ValidateEndOfAttributes(si); ValidateNodes(e); validator.ValidateEndElement(si); if (addSchemaInfo) { - if (si.Validity == XmlSchemaValidity.Valid && si.IsDefault) + if (si!.Validity == XmlSchemaValidity.Valid && si.IsDefault) { - e.Value = GetDefaultValue(si.SchemaElement); + Debug.Assert(si.SchemaElement != null); + e.Value = GetDefaultValue(si.SchemaElement)!; } ReplaceSchemaInfo(e, si); } RestoreLineInfo(original); - namespaceManager.PopScope(); + namespaceManager!.PopScope(); } private void ValidateNodes(XElement e) { - XNode n = e.content as XNode; + XNode? n = e.content as XNode; IXmlLineInfo orginal = SaveLineInfo(n); if (n != null) { do { - n = n.next; - XElement c = n as XElement; + n = n.next!; + XElement? c = n as XElement; if (c != null) { ValidateElement(c); } else { - XText t = n as XText; + XText? t = n as XText; if (t != null) { string s = t.Value; if (s.Length > 0) { - validator.LineInfoProvider = t as IXmlLineInfo; + validator!.LineInfoProvider = t as IXmlLineInfo; validator.ValidateText(s); } } @@ -348,16 +357,16 @@ private void ValidateNodes(XElement e) } else { - string s = e.content as string; + string? s = e.content as string; if (s != null && s.Length > 0) { - validator.ValidateText(s); + validator!.ValidateText(s); } } RestoreLineInfo(orginal); } - private void ValidationCallback(object sender, ValidationEventArgs e) + private void ValidationCallback(object? sender, ValidationEventArgs e) { if (validationEventHandler != null) { @@ -372,21 +381,21 @@ private void ValidationCallback(object sender, ValidationEventArgs e) internal class XmlSchemaInfoEqualityComparer : IEqualityComparer { - public bool Equals(XmlSchemaInfo si1, XmlSchemaInfo si2) + public bool Equals(XmlSchemaInfo? si1, XmlSchemaInfo? si2) { if (si1 == si2) return true; if (si1 == null || si2 == null) return false; return si1.ContentType == si2.ContentType && si1.IsDefault == si2.IsDefault && si1.IsNil == si2.IsNil && - (object)si1.MemberType == (object)si2.MemberType && - (object)si1.SchemaAttribute == (object)si2.SchemaAttribute && - (object)si1.SchemaElement == (object)si2.SchemaElement && - (object)si1.SchemaType == (object)si2.SchemaType && + (object?)si1.MemberType == (object?)si2.MemberType && + (object?)si1.SchemaAttribute == (object?)si2.SchemaAttribute && + (object?)si1.SchemaElement == (object?)si2.SchemaElement && + (object?)si1.SchemaType == (object?)si2.SchemaType && si1.Validity == si2.Validity; } - public int GetHashCode(XmlSchemaInfo si) + public int GetHashCode(XmlSchemaInfo? si) { if (si == null) return 0; int h = (int)si.ContentType; @@ -398,22 +407,22 @@ public int GetHashCode(XmlSchemaInfo si) { h ^= 1; } - XmlSchemaSimpleType memberType = si.MemberType; + XmlSchemaSimpleType? memberType = si.MemberType; if (memberType != null) { h ^= memberType.GetHashCode(); } - XmlSchemaAttribute schemaAttribute = si.SchemaAttribute; + XmlSchemaAttribute? schemaAttribute = si.SchemaAttribute; if (schemaAttribute != null) { h ^= schemaAttribute.GetHashCode(); } - XmlSchemaElement schemaElement = si.SchemaElement; + XmlSchemaElement? schemaElement = si.SchemaElement; if (schemaElement != null) { h ^= schemaElement.GetHashCode(); } - XmlSchemaType schemaType = si.SchemaType; + XmlSchemaType? schemaType = si.SchemaType; if (schemaType != null) { h ^= schemaType.GetHashCode(); @@ -432,7 +441,7 @@ public static class Extensions /// Gets the schema information that has been assigned to the as a result of schema validation. /// /// Extension point - public static IXmlSchemaInfo GetSchemaInfo(this XElement source) + public static IXmlSchemaInfo? GetSchemaInfo(this XElement source) { if (source == null) throw new ArgumentNullException(nameof(source)); return source.Annotation(); @@ -442,7 +451,7 @@ public static IXmlSchemaInfo GetSchemaInfo(this XElement source) /// Gets the schema information that has been assigned to the as a result of schema validation. /// /// Extension point - public static IXmlSchemaInfo GetSchemaInfo(this XAttribute source) + public static IXmlSchemaInfo? GetSchemaInfo(this XAttribute source) { if (source == null) throw new ArgumentNullException(nameof(source)); return source.Annotation(); @@ -456,7 +465,7 @@ public static IXmlSchemaInfo GetSchemaInfo(this XAttribute source) /// The /// that receives schema validation warnings and errors encountered during schema /// validation - public static void Validate(this XDocument source, XmlSchemaSet schemas, ValidationEventHandler validationEventHandler) + public static void Validate(this XDocument source, XmlSchemaSet schemas, ValidationEventHandler? validationEventHandler) { source.Validate(schemas, validationEventHandler, false); } @@ -472,7 +481,7 @@ public static void Validate(this XDocument source, XmlSchemaSet schemas, Validat /// If enabled the and the corresponding /// subtree is augmented with PSVI in the form of annotations, /// default attributes and default element values - public static void Validate(this XDocument source, XmlSchemaSet schemas, ValidationEventHandler validationEventHandler, bool addSchemaInfo) + public static void Validate(this XDocument source, XmlSchemaSet schemas, ValidationEventHandler? validationEventHandler, bool addSchemaInfo) { if (source == null) throw new ArgumentNullException(nameof(source)); if (schemas == null) throw new ArgumentNullException(nameof(schemas)); @@ -490,7 +499,7 @@ public static void Validate(this XDocument source, XmlSchemaSet schemas, Validat /// The that /// receives schema validation warnings and errors encountered during schema /// validation - public static void Validate(this XElement source, XmlSchemaObject partialValidationType, XmlSchemaSet schemas, ValidationEventHandler validationEventHandler) + public static void Validate(this XElement source, XmlSchemaObject partialValidationType, XmlSchemaSet schemas, ValidationEventHandler? validationEventHandler) { source.Validate(partialValidationType, schemas, validationEventHandler, false); } @@ -509,7 +518,7 @@ public static void Validate(this XElement source, XmlSchemaObject partialValidat /// If enabled the and the corresponding /// subtree is augmented with PSVI in the form of annotations, /// default attributes and default element values - public static void Validate(this XElement source, XmlSchemaObject partialValidationType, XmlSchemaSet schemas, ValidationEventHandler validationEventHandler, bool addSchemaInfo) + public static void Validate(this XElement source, XmlSchemaObject partialValidationType, XmlSchemaSet schemas, ValidationEventHandler? validationEventHandler, bool addSchemaInfo) { if (source == null) throw new ArgumentNullException(nameof(source)); if (partialValidationType == null) throw new ArgumentNullException(nameof(partialValidationType)); @@ -528,7 +537,7 @@ public static void Validate(this XElement source, XmlSchemaObject partialValidat /// The that /// receives schema validation warnings and errors encountered during schema /// validation - public static void Validate(this XAttribute source, XmlSchemaObject partialValidationType, XmlSchemaSet schemas, ValidationEventHandler validationEventHandler) + public static void Validate(this XAttribute source, XmlSchemaObject partialValidationType, XmlSchemaSet schemas, ValidationEventHandler? validationEventHandler) { source.Validate(partialValidationType, schemas, validationEventHandler, false); } @@ -547,7 +556,7 @@ public static void Validate(this XAttribute source, XmlSchemaObject partialValid /// If enabled the is augmented with PSVI /// in the form of annotations, default attributes and /// default element values - public static void Validate(this XAttribute source, XmlSchemaObject partialValidationType, XmlSchemaSet schemas, ValidationEventHandler validationEventHandler, bool addSchemaInfo) + public static void Validate(this XAttribute source, XmlSchemaObject partialValidationType, XmlSchemaSet schemas, ValidationEventHandler? validationEventHandler, bool addSchemaInfo) { if (source == null) throw new ArgumentNullException(nameof(source)); if (partialValidationType == null) throw new ArgumentNullException(nameof(partialValidationType)); diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/XPath/XNodeNavigator.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/XPath/XNodeNavigator.cs index 614769bb567122..c301348cda7cb7 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/XPath/XNodeNavigator.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/XPath/XNodeNavigator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Xml.Linq; @@ -36,17 +37,17 @@ internal class XNodeNavigator : XPathNavigator, IXmlLineInfo (1 << (int)XmlNodeType.CDATA) | (1 << (int)XmlNodeType.Text); - private static XAttribute s_XmlNamespaceDeclaration; + private static XAttribute? s_XmlNamespaceDeclaration; // The navigator position is encoded by the tuple (source, parent). // Namespace declaration uses (instance, parent element). // Common XObjects uses (instance, null). private XObject _source; - private XElement _parent; + private XElement? _parent; private readonly XmlNameTable _nameTable; - public XNodeNavigator(XNode node, XmlNameTable nameTable) + public XNodeNavigator(XNode node, XmlNameTable? nameTable) { _source = node; _nameTable = nameTable != null ? nameTable : CreateNameTable(); @@ -79,7 +80,7 @@ public override bool HasAttributes { get { - XElement element = _source as XElement; + XElement? element = _source as XElement; if (element != null) { foreach (XAttribute attribute in element.Attributes()) @@ -98,7 +99,7 @@ public override bool HasChildren { get { - XContainer container = _source as XContainer; + XContainer? container = _source as XContainer; if (container != null) { foreach (XNode node in container.Nodes()) @@ -117,7 +118,7 @@ public override bool IsEmptyElement { get { - XElement e = _source as XElement; + XElement? e = _source as XElement; return e != null && e.IsEmpty; } } @@ -129,12 +130,12 @@ public override string LocalName private string GetLocalName() { - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { return e.Name.LocalName; } - XAttribute a = _source as XAttribute; + XAttribute? a = _source as XAttribute; if (a != null) { if (_parent != null && a.Name.NamespaceName.Length == 0) @@ -143,7 +144,7 @@ private string GetLocalName() } return a.Name.LocalName; } - XProcessingInstruction p = _source as XProcessingInstruction; + XProcessingInstruction? p = _source as XProcessingInstruction; if (p != null) { return p.Target; @@ -171,12 +172,12 @@ public override string NamespaceURI private string GetNamespaceURI() { - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { return e.Name.NamespaceName; } - XAttribute a = _source as XAttribute; + XAttribute? a = _source as XAttribute; if (a != null) { if (_parent != null) @@ -227,24 +228,24 @@ public override string Prefix private string GetPrefix() { - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { - string prefix = e.GetPrefixOfNamespace(e.Name.Namespace); + string? prefix = e.GetPrefixOfNamespace(e.Name.Namespace); if (prefix != null) { return prefix; } return string.Empty; } - XAttribute a = _source as XAttribute; + XAttribute? a = _source as XAttribute; if (a != null) { if (_parent != null) { return string.Empty; // backcompat } - string prefix = a.GetPrefixOfNamespace(a.Name.Namespace); + string? prefix = a.GetPrefixOfNamespace(a.Name.Namespace); if (prefix != null) { return prefix; @@ -274,7 +275,7 @@ public override string Value case XmlNodeType.Attribute: return ((XAttribute)_source).Value; case XmlNodeType.Document: - XElement root = ((XDocument)_source).Root; + XElement? root = ((XDocument)_source).Root; return root != null ? root.Value : string.Empty; case XmlNodeType.Text: case XmlNodeType.CDATA: @@ -298,7 +299,7 @@ public override XPathNavigator Clone() public override bool IsSamePosition(XPathNavigator navigator) { - XNodeNavigator other = navigator as XNodeNavigator; + XNodeNavigator? other = navigator as XNodeNavigator; if (other == null) { return false; @@ -308,7 +309,7 @@ public override bool IsSamePosition(XPathNavigator navigator) public override bool MoveTo(XPathNavigator navigator) { - XNodeNavigator other = navigator as XNodeNavigator; + XNodeNavigator? other = navigator as XNodeNavigator; if (other != null) { _source = other._source; @@ -320,7 +321,7 @@ public override bool MoveTo(XPathNavigator navigator) public override bool MoveToAttribute(string localName, string namespaceName) { - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { foreach (XAttribute attribute in e.Attributes()) @@ -339,7 +340,7 @@ public override bool MoveToAttribute(string localName, string namespaceName) public override bool MoveToChild(string localName, string namespaceName) { - XContainer c = _source as XContainer; + XContainer? c = _source as XContainer; if (c != null) { foreach (XElement element in c.Elements()) @@ -357,7 +358,7 @@ public override bool MoveToChild(string localName, string namespaceName) public override bool MoveToChild(XPathNodeType type) { - XContainer c = _source as XContainer; + XContainer? c = _source as XContainer; if (c != null) { int mask = GetElementContentMask(type); @@ -379,7 +380,7 @@ public override bool MoveToChild(XPathNodeType type) public override bool MoveToFirstAttribute() { - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { foreach (XAttribute attribute in e.Attributes()) @@ -396,7 +397,7 @@ public override bool MoveToFirstAttribute() public override bool MoveToFirstChild() { - XContainer container = _source as XContainer; + XContainer? container = _source as XContainer; if (container != null) { foreach (XNode node in container.Nodes()) @@ -413,10 +414,10 @@ public override bool MoveToFirstChild() public override bool MoveToFirstNamespace(XPathNamespaceScope scope) { - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { - XAttribute a = null; + XAttribute? a = null; switch (scope) { case XPathNamespaceScope.Local: @@ -454,18 +455,19 @@ public override bool MoveToId(string id) public override bool MoveToNamespace(string localName) { - XElement e = _source as XElement; + XElement? e = _source as XElement; if (e != null) { if (localName == "xmlns") { return false; // backcompat } + // TODO-NULLABLE: Unnecessary null check? if (localName != null && localName.Length == 0) { localName = "xmlns"; // backcompat } - XAttribute a = GetFirstNamespaceDeclarationGlobal(e); + XAttribute? a = GetFirstNamespaceDeclarationGlobal(e); while (a != null) { if (a.Name.LocalName == localName) @@ -488,13 +490,13 @@ public override bool MoveToNamespace(string localName) public override bool MoveToNext() { - XNode currentNode = _source as XNode; + XNode? currentNode = _source as XNode; if (currentNode != null) { - XContainer container = currentNode.GetParent(); + XContainer? container = currentNode.GetParent(); if (container != null) { - XNode next = null; + XNode? next = null; for (XNode node = currentNode; node != null; node = next) { next = node.NextNode; @@ -515,7 +517,7 @@ public override bool MoveToNext() public override bool MoveToNext(string localName, string namespaceName) { - XNode currentNode = _source as XNode; + XNode? currentNode = _source as XNode; if (currentNode != null) { foreach (XElement element in currentNode.ElementsAfterSelf()) @@ -533,10 +535,10 @@ public override bool MoveToNext(string localName, string namespaceName) public override bool MoveToNext(XPathNodeType type) { - XNode currentNode = _source as XNode; + XNode? currentNode = _source as XNode; if (currentNode != null) { - XContainer container = currentNode.GetParent(); + XContainer? container = currentNode.GetParent(); if (container != null) { int mask = GetElementContentMask(type); @@ -544,7 +546,7 @@ public override bool MoveToNext(XPathNodeType type) { mask &= ~TextMask; } - XNode next = null; + XNode? next = null; for (XNode node = currentNode; ; node = next) { next = node.NextNode; @@ -565,13 +567,13 @@ public override bool MoveToNext(XPathNodeType type) public override bool MoveToNextAttribute() { - XAttribute currentAttribute = _source as XAttribute; + XAttribute? currentAttribute = _source as XAttribute; if (currentAttribute != null && _parent == null) { - XElement e = (XElement)currentAttribute.GetParent(); + XElement? e = (XElement?)currentAttribute.GetParent(); if (e != null) { - for (XAttribute attribute = currentAttribute.NextAttribute; attribute != null; attribute = attribute.NextAttribute) + for (XAttribute? attribute = currentAttribute.NextAttribute; attribute != null; attribute = attribute.NextAttribute) { if (!attribute.IsNamespaceDeclaration) { @@ -586,7 +588,7 @@ public override bool MoveToNextAttribute() public override bool MoveToNextNamespace(XPathNamespaceScope scope) { - XAttribute a = _source as XAttribute; + XAttribute? a = _source as XAttribute; if (a != null && _parent != null && !IsXmlNamespaceDeclaration(a)) { switch (scope) @@ -636,7 +638,7 @@ public override bool MoveToParent() _parent = null; return true; } - XNode parentNode = _source.GetParent(); + XNode? parentNode = _source.GetParent(); if (parentNode != null) { _source = parentNode; @@ -647,13 +649,13 @@ public override bool MoveToParent() public override bool MoveToPrevious() { - XNode currentNode = _source as XNode; + XNode? currentNode = _source as XNode; if (currentNode != null) { - XContainer container = currentNode.GetParent(); + XContainer? container = currentNode.GetParent(); if (container != null) { - XNode previous = null; + XNode? previous = null; foreach (XNode node in container.Nodes()) { if (node == currentNode) @@ -678,7 +680,7 @@ public override bool MoveToPrevious() public override XmlReader ReadSubtree() { - XContainer c = _source as XContainer; + XContainer? c = _source as XContainer; if (c == null) throw new InvalidOperationException(SR.Format(SR.InvalidOperation_BadNodeType, NodeType)); return c.CreateReader(); } @@ -726,7 +728,7 @@ private static string CollectText(XText n) { foreach (XNode node in n.NodesAfterSelf()) { - XText t = node as XText; + XText? t = node as XText; if (t == null) break; s += t.Value; } @@ -767,21 +769,22 @@ private static int GetElementContentMask(XPathNodeType type) return s_ElementContentMasks[(int)type]; } - private static XAttribute GetFirstNamespaceDeclarationGlobal(XElement e) + private static XAttribute? GetFirstNamespaceDeclarationGlobal(XElement e) { + XElement? ce = e; do { - XAttribute a = GetFirstNamespaceDeclarationLocal(e); + XAttribute? a = GetFirstNamespaceDeclarationLocal(ce); if (a != null) { return a; } - e = e.Parent; - } while (e != null); + ce = ce.Parent; + } while (ce != null); return null; } - private static XAttribute GetFirstNamespaceDeclarationLocal(XElement e) + private static XAttribute? GetFirstNamespaceDeclarationLocal(XElement e) { foreach (XAttribute attribute in e.Attributes()) { @@ -793,14 +796,14 @@ private static XAttribute GetFirstNamespaceDeclarationLocal(XElement e) return null; } - private static XAttribute GetNextNamespaceDeclarationGlobal(XAttribute a) + private static XAttribute? GetNextNamespaceDeclarationGlobal(XAttribute a) { - XElement e = (XElement)a.GetParent(); + XElement? e = (XElement?)a.GetParent(); if (e == null) { return null; } - XAttribute next = GetNextNamespaceDeclarationLocal(a); + XAttribute? next = GetNextNamespaceDeclarationLocal(a); if (next != null) { return next; @@ -813,21 +816,22 @@ private static XAttribute GetNextNamespaceDeclarationGlobal(XAttribute a) return GetFirstNamespaceDeclarationGlobal(e); } - private static XAttribute GetNextNamespaceDeclarationLocal(XAttribute a) + private static XAttribute? GetNextNamespaceDeclarationLocal(XAttribute a) { - XElement e = a.Parent; + XElement? e = a.Parent; if (e == null) { return null; } - a = a.NextAttribute; - while (a != null) + XAttribute? ca = a; + ca = ca.NextAttribute; + while (ca != null) { - if (a.IsNamespaceDeclaration) + if (ca.IsNamespaceDeclaration) { - return a; + return ca; } - a = a.NextAttribute; + ca = ca.NextAttribute; } return null; } @@ -844,13 +848,14 @@ private static XAttribute GetXmlNamespaceDeclaration() private static bool HasNamespaceDeclarationInScope(XAttribute a, XElement e) { XName name = a.Name; - while (e != null && e != a.GetParent()) + XElement? ce = e; + while (ce != null && ce != a.GetParent()) { - if (e.Attribute(name) != null) + if (ce.Attribute(name) != null) { return true; } - e = e.Parent; + ce = ce.Parent; } return false; } @@ -858,11 +863,11 @@ private static bool HasNamespaceDeclarationInScope(XAttribute a, XElement e) internal readonly struct XPathEvaluator { - public object Evaluate(XNode node, string expression, IXmlNamespaceResolver resolver) where T : class + public object Evaluate(XNode node, string expression, IXmlNamespaceResolver? resolver) where T : class { XPathNavigator navigator = node.CreateNavigator(); object result = navigator.Evaluate(expression, resolver); - XPathNodeIterator iterator = result as XPathNodeIterator; + XPathNodeIterator? iterator = result as XPathNodeIterator; if (iterator != null) { return EvaluateIterator(iterator); @@ -875,10 +880,11 @@ private IEnumerable EvaluateIterator(XPathNodeIterator result) { foreach (XPathNavigator navigator in result) { + Debug.Assert(navigator.UnderlyingObject != null); object r = navigator.UnderlyingObject; if (!(r is T)) throw new InvalidOperationException(SR.Format(SR.InvalidOperation_UnexpectedEvaluation, r.GetType())); yield return (T)r; - XText t = r as XText; + XText? t = r as XText; if (t != null && t.GetParent() != null) { do @@ -886,7 +892,7 @@ private IEnumerable EvaluateIterator(XPathNodeIterator result) t = t.NextNode as XText; if (t == null) break; yield return (T)(object)t; - } while (t != t.GetParent().LastNode); + } while (t != t.GetParent()!.LastNode); } } } @@ -914,11 +920,11 @@ public static XPathNavigator CreateNavigator(this XNode node) /// The to be used by /// the /// An - public static XPathNavigator CreateNavigator(this XNode node, XmlNameTable nameTable) + public static XPathNavigator CreateNavigator(this XNode node, XmlNameTable? nameTable) { if (node == null) throw new ArgumentNullException(nameof(node)); if (node is XDocumentType) throw new ArgumentException(SR.Format(SR.Argument_CreateNavigator, XmlNodeType.DocumentType)); - XText text = node as XText; + XText? text = node as XText; if (text != null) { if (text.GetParent() is XDocument) throw new ArgumentException(SR.Format(SR.Argument_CreateNavigator, XmlNodeType.Whitespace)); @@ -948,7 +954,7 @@ public static object XPathEvaluate(this XNode node, string expression) /// prefixes used in the XPath expression /// The result of evaluating the expression which can be typed as bool, double, string or /// IEnumerable - public static object XPathEvaluate(this XNode node, string expression, IXmlNamespaceResolver resolver) + public static object XPathEvaluate(this XNode node, string expression, IXmlNamespaceResolver? resolver) { if (node == null) throw new ArgumentNullException(nameof(node)); return default(XPathEvaluator).Evaluate(node, expression, resolver); @@ -960,7 +966,7 @@ public static object XPathEvaluate(this XNode node, string expression, IXmlNames /// Extension point /// The XPath expression /// An or null - public static XElement XPathSelectElement(this XNode node, string expression) + public static XElement? XPathSelectElement(this XNode node, string expression) { return node.XPathSelectElement(expression, null); } @@ -973,7 +979,7 @@ public static XElement XPathSelectElement(this XNode node, string expression) /// A for the namespace /// prefixes used in the XPath expression /// An or null - public static XElement XPathSelectElement(this XNode node, string expression, IXmlNamespaceResolver resolver) + public static XElement? XPathSelectElement(this XNode node, string expression, IXmlNamespaceResolver? resolver) { return node.XPathSelectElements(expression, resolver).FirstOrDefault(); } @@ -997,7 +1003,7 @@ public static IEnumerable XPathSelectElements(this XNode node, string /// A for the namespace /// prefixes used in the XPath expression /// An corresponding to the resulting set of elements - public static IEnumerable XPathSelectElements(this XNode node, string expression, IXmlNamespaceResolver resolver) + public static IEnumerable XPathSelectElements(this XNode node, string expression, IXmlNamespaceResolver? resolver) { if (node == null) throw new ArgumentNullException(nameof(node)); return (IEnumerable)default(XPathEvaluator).Evaluate(node, expression, resolver); @@ -1005,18 +1011,18 @@ public static IEnumerable XPathSelectElements(this XNode node, string private static XText CalibrateText(XText n) { - XContainer parentNode = n.GetParent(); + XContainer? parentNode = n.GetParent(); if (parentNode == null) { return n; } foreach (XNode node in parentNode.Nodes()) { - XText t = node as XText; + XText? t = node as XText; bool isTextNode = t != null; if (isTextNode && node == n) { - return t; + return t!; } } diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/XPath/XObjectExtensions.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/XPath/XObjectExtensions.cs index d32860ffd11943..829b2e34af5990 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/XPath/XObjectExtensions.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/XPath/XObjectExtensions.cs @@ -7,9 +7,9 @@ namespace System.Xml.XPath { internal static class XObjectExtensions { - public static XContainer GetParent(this XObject obj) + public static XContainer? GetParent(this XObject obj) { - XContainer ret = obj.Parent; + XContainer? ret = obj.Parent; if (ret == null) { ret = obj.Document; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigator.cs index 02baf072f2a2c0..288f8d5212386b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigator.cs @@ -1186,7 +1186,7 @@ public virtual XPathNodeIterator Select(string xpath) return this.Select(XPathExpression.Compile(xpath)); } - public virtual XPathNodeIterator Select(string xpath, IXmlNamespaceResolver resolver) + public virtual XPathNodeIterator Select(string xpath, IXmlNamespaceResolver? resolver) { return this.Select(XPathExpression.Compile(xpath, resolver)); } @@ -1206,7 +1206,7 @@ public virtual object Evaluate(string xpath) return Evaluate(XPathExpression.Compile(xpath), null); } - public virtual object Evaluate(string xpath, IXmlNamespaceResolver resolver) + public virtual object Evaluate(string xpath, IXmlNamespaceResolver? resolver) { return this.Evaluate(XPathExpression.Compile(xpath, resolver)); }