Add nullability annotations for *XPath* files in Xml/Dom and Xml/Xsl (#40295)
authorDavid Cantu <dacantu@microsoft.com>
Fri, 7 Aug 2020 00:00:09 +0000 (17:00 -0700)
committerGitHub <noreply@github.com>
Fri, 7 Aug 2020 00:00:09 +0000 (17:00 -0700)
* Add nullability annotations for *XPath* files in Xml/Dom and Xml/Xsl

* Fix build issues

* Address feedback

* Add TODO for replacing MaybeNull attributes

17 files changed:
src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXPathNavigator.cs
src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentXmlWriter.cs
src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElement.cs
src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNode.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXPathEnvironment.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/IXpathBuilder.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathAxis.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathBuilder.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathCompileException.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathContext.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathOperator.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathParser.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathQilFactory.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathScanner.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPathConvert.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternBuilder.cs
src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/XPathPatternParser.cs

index 2b9f90a..c9c16dd 100644 (file)
@@ -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.
 
+#nullable enable
 using System;
 using System.Collections;
 using System.Collections.Generic;
@@ -8,6 +9,7 @@ using System.Text;
 using System.Xml.Schema;
 using System.Xml.XPath;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 
 namespace System.Xml
 {
@@ -16,7 +18,7 @@ namespace System.Xml
         private readonly XmlDocument _document; // owner document
         private XmlNode _source; // navigator position
         private int _attributeIndex; // index in attribute collection for attribute
-        private XmlElement _namespaceParent; // parent for namespace
+        private XmlElement? _namespaceParent; // parent for namespace
 
         public DocumentXPathNavigator(XmlDocument document, XmlNode node)
         {
@@ -70,7 +72,7 @@ namespace System.Xml
                         {
                             throw new InvalidOperationException(SR.Xdom_Node_Modify_ReadOnly);
                         }
-                        DeleteToFollowingSibling(node.NextSibling, end);
+                        DeleteToFollowingSibling(node.NextSibling!, end);
                     }
                     goto case XmlNodeType.Element;
                 case XmlNodeType.Element:
@@ -113,8 +115,7 @@ namespace System.Xml
         {
             get
             {
-                XmlAttribute attribute = _source as XmlAttribute;
-                if (attribute != null
+                if (_source is XmlAttribute attribute
                     && attribute.IsNamespace)
                 {
                     return string.Empty;
@@ -153,8 +154,7 @@ namespace System.Xml
         {
             get
             {
-                XmlAttribute attribute = _source as XmlAttribute;
-                if (attribute != null
+                if (_source is XmlAttribute attribute
                     && attribute.IsNamespace)
                 {
                     return string.Empty;
@@ -180,6 +180,11 @@ namespace System.Xml
                     case XmlNodeType.SignificantWhitespace:
                         return ValueText;
                     default:
+                        Debug.Assert(_source.Value != null);
+                        // TODO-NULLABLE: Consider switching this.Value to nullable even if that implies switching it in the base type.
+                        // Also consider the following:
+                        //   * this.SetValue() does not accept null.
+                        //   * _source.Value is nullable.
                         return _source.Value;
                 }
             }
@@ -189,7 +194,7 @@ namespace System.Xml
         {
             get
             {
-                XmlElement element = _document.DocumentElement;
+                XmlElement? element = _document.DocumentElement;
                 if (element != null)
                 {
                     return element.InnerText;
@@ -204,8 +209,8 @@ namespace System.Xml
             {
                 CalibrateText();
 
-                string value = _source.Value;
-                XmlNode nextSibling = NextSibling(_source);
+                string? value = _source.Value;
+                XmlNode? nextSibling = NextSibling(_source);
                 if (nextSibling != null
                     && nextSibling.IsText)
                 {
@@ -219,6 +224,9 @@ namespace System.Xml
                            && nextSibling.IsText);
                     value = builder.ToString();
                 }
+                // TODO-NULLABLE: Consider making this nullable given that _source.Value is nullable,
+                // OR we could change this getter to return string.Empty if _source.Value == null.
+                Debug.Assert(value != null);
                 return value;
             }
         }
@@ -235,8 +243,7 @@ namespace System.Xml
         {
             get
             {
-                XmlElement element = _source as XmlElement;
-                if (element != null)
+                if (_source is XmlElement element)
                 {
                     return element.IsEmpty;
                 }
@@ -266,8 +273,7 @@ namespace System.Xml
         {
             get
             {
-                XmlElement element = _source as XmlElement;
-                if (element != null
+                if (_source is XmlElement element
                     && element.HasAttributes)
                 {
                     XmlAttributeCollection attributes = element.Attributes;
@@ -291,8 +297,7 @@ namespace System.Xml
 
         public override bool MoveToAttribute(string localName, string namespaceURI)
         {
-            XmlElement element = _source as XmlElement;
-            if (element != null
+            if (_source is XmlElement element
                 && element.HasAttributes)
             {
                 XmlAttributeCollection attributes = element.Attributes;
@@ -320,8 +325,7 @@ namespace System.Xml
 
         public override bool MoveToFirstAttribute()
         {
-            XmlElement element = _source as XmlElement;
-            if (element != null
+            if (_source is XmlElement element
                 && element.HasAttributes)
             {
                 XmlAttributeCollection attributes = element.Attributes;
@@ -341,13 +345,12 @@ namespace System.Xml
 
         public override bool MoveToNextAttribute()
         {
-            XmlAttribute attribute = _source as XmlAttribute;
-            if (attribute == null
+            if (!(_source is XmlAttribute attribute)
                 || attribute.IsNamespace)
             {
                 return false;
             }
-            XmlAttributeCollection attributes;
+            XmlAttributeCollection? attributes;
             if (!CheckAttributePosition(attribute, out attributes, _attributeIndex)
                 && !ResetAttributePosition(attribute, attributes, out _attributeIndex))
             {
@@ -368,12 +371,11 @@ namespace System.Xml
 
         public override string GetNamespace(string name)
         {
-            XmlNode node = _source;
+            XmlNode? node = _source;
             while (node != null
                    && node.NodeType != XmlNodeType.Element)
             {
-                XmlAttribute attribute = node as XmlAttribute;
-                if (attribute != null)
+                if (node is XmlAttribute attribute)
                 {
                     node = attribute.OwnerElement;
                 }
@@ -383,7 +385,7 @@ namespace System.Xml
                 }
             }
 
-            XmlElement element = node as XmlElement;
+            XmlElement? element = node as XmlElement;
             if (element != null)
             {
                 string localName;
@@ -400,7 +402,7 @@ namespace System.Xml
 
                 do
                 {
-                    XmlAttribute attribute = element.GetAttributeNode(localName, namespaceUri);
+                    XmlAttribute? attribute = element.GetAttributeNode(localName, namespaceUri);
                     if (attribute != null)
                     {
                         return attribute.Value;
@@ -427,7 +429,7 @@ namespace System.Xml
             {
                 return false;
             }
-            XmlElement element = _source as XmlElement;
+            XmlElement? element = _source as XmlElement;
             if (element != null)
             {
                 string localName;
@@ -444,7 +446,7 @@ namespace System.Xml
 
                 do
                 {
-                    XmlAttribute attribute = element.GetAttributeNode(localName, namespaceUri);
+                    XmlAttribute? attribute = element.GetAttributeNode(localName, namespaceUri);
                     if (attribute != null)
                     {
                         _namespaceParent = (XmlElement)_source;
@@ -467,8 +469,7 @@ namespace System.Xml
 
         public override bool MoveToFirstNamespace(XPathNamespaceScope scope)
         {
-            XmlElement element = _source as XmlElement;
-            if (element == null)
+            if (!(_source is XmlElement element))
             {
                 return false;
             }
@@ -553,7 +554,7 @@ namespace System.Xml
             }
 
             Debug.Assert(attributes != null && attributes.parent != null);
-            XmlElement element = attributes.parent.ParentNode as XmlElement;
+            XmlElement? element = attributes.parent.ParentNode as XmlElement;
             while (element != null)
             {
                 if (element.HasAttributes)
@@ -571,13 +572,12 @@ namespace System.Xml
 
         public override bool MoveToNextNamespace(XPathNamespaceScope scope)
         {
-            XmlAttribute attribute = _source as XmlAttribute;
-            if (attribute == null
+            if (!(_source is XmlAttribute attribute)
                 || !attribute.IsNamespace)
             {
                 return false;
             }
-            XmlAttributeCollection attributes;
+            XmlAttributeCollection? attributes;
             int index = _attributeIndex;
             if (!CheckAttributePosition(attribute, out attributes, index)
                 && !ResetAttributePosition(attribute, attributes, out index))
@@ -668,7 +668,7 @@ namespace System.Xml
             }
 
             Debug.Assert(attributes != null && attributes.parent != null);
-            XmlElement element = attributes.parent.ParentNode as XmlElement;
+            XmlElement? element = attributes.parent.ParentNode as XmlElement;
             while (element != null)
             {
                 if (element.HasAttributes)
@@ -684,25 +684,26 @@ namespace System.Xml
             return false;
         }
 
-        private bool PathHasDuplicateNamespace(XmlElement top, XmlElement bottom, string localName)
+        private bool PathHasDuplicateNamespace(XmlElement? top, XmlElement bottom, string localName)
         {
+            XmlElement? current = bottom;
             string namespaceUri = _document.strReservedXmlns;
-            while (bottom != null
-                   && bottom != top)
+            while (current != null
+                   && current != top)
             {
-                XmlAttribute attribute = bottom.GetAttributeNode(localName, namespaceUri);
+                XmlAttribute? attribute = current.GetAttributeNode(localName, namespaceUri);
                 if (attribute != null)
                 {
                     return true;
                 }
-                bottom = bottom.ParentNode as XmlElement;
+                current = current.ParentNode as XmlElement;
             }
             return false;
         }
 
-        public override string LookupNamespace(string prefix)
+        public override string? LookupNamespace(string prefix)
         {
-            string ns = base.LookupNamespace(prefix);
+            string? ns = base.LookupNamespace(prefix);
             if (ns != null)
             {
                 ns = this.NameTable.Add(ns);
@@ -712,7 +713,7 @@ namespace System.Xml
 
         public override bool MoveToNext()
         {
-            XmlNode sibling = NextSibling(_source);
+            XmlNode? sibling = NextSibling(_source);
             if (sibling == null)
             {
                 return false;
@@ -728,7 +729,7 @@ namespace System.Xml
                     }
                 }
             }
-            XmlNode parent = ParentNode(sibling);
+            XmlNode? parent = ParentNode(sibling);
             Debug.Assert(parent != null);
             while (!IsValidChild(parent, sibling))
             {
@@ -744,7 +745,7 @@ namespace System.Xml
 
         public override bool MoveToPrevious()
         {
-            XmlNode sibling = PreviousSibling(_source);
+            XmlNode? sibling = PreviousSibling(_source);
             if (sibling == null)
             {
                 return false;
@@ -764,7 +765,7 @@ namespace System.Xml
                     sibling = TextStart(sibling);
                 }
             }
-            XmlNode parent = ParentNode(sibling);
+            XmlNode? parent = ParentNode(sibling);
             Debug.Assert(parent != null);
             while (!IsValidChild(parent, sibling))
             {
@@ -787,12 +788,12 @@ namespace System.Xml
             {
                 return false;
             }
-            XmlNode parent = ParentNode(_source);
+            XmlNode? parent = ParentNode(_source);
             if (parent == null)
             {
                 return false;
             }
-            XmlNode sibling = FirstChild(parent);
+            XmlNode? sibling = FirstChild(parent);
             Debug.Assert(sibling != null);
             while (!IsValidChild(parent, sibling))
             {
@@ -808,7 +809,7 @@ namespace System.Xml
 
         public override bool MoveToFirstChild()
         {
-            XmlNode child;
+            XmlNode? child;
             switch (_source.NodeType)
             {
                 case XmlNodeType.Element:
@@ -843,14 +844,13 @@ namespace System.Xml
 
         public override bool MoveToParent()
         {
-            XmlNode parent = ParentNode(_source);
+            XmlNode? parent = ParentNode(_source);
             if (parent != null)
             {
                 _source = parent;
                 return true;
             }
-            XmlAttribute attribute = _source as XmlAttribute;
-            if (attribute != null)
+            if (_source is XmlAttribute attribute)
             {
                 parent = attribute.IsNamespace ? _namespaceParent : attribute.OwnerElement;
                 if (parent != null)
@@ -867,11 +867,10 @@ namespace System.Xml
         {
             while (true)
             {
-                XmlNode parent = _source.ParentNode;
+                XmlNode? parent = _source.ParentNode;
                 if (parent == null)
                 {
-                    XmlAttribute attribute = _source as XmlAttribute;
-                    if (attribute == null)
+                    if (!(_source is XmlAttribute attribute))
                     {
                         break;
                     }
@@ -888,8 +887,7 @@ namespace System.Xml
 
         public override bool MoveTo(XPathNavigator other)
         {
-            DocumentXPathNavigator that = other as DocumentXPathNavigator;
-            if (that != null
+            if (other is DocumentXPathNavigator that
                 && _document == that._document)
             {
                 _source = that._source;
@@ -902,7 +900,7 @@ namespace System.Xml
 
         public override bool MoveToId(string id)
         {
-            XmlElement element = _document.GetElementById(id);
+            XmlElement? element = _document.GetElementById(id);
             if (element != null)
             {
                 _source = element;
@@ -919,7 +917,7 @@ namespace System.Xml
                 return false;
             }
 
-            XmlNode child = FirstChild(_source);
+            XmlNode? child = FirstChild(_source);
             if (child != null)
             {
                 do
@@ -945,7 +943,7 @@ namespace System.Xml
                 return false;
             }
 
-            XmlNode child = FirstChild(_source);
+            XmlNode? child = FirstChild(_source);
             if (child != null)
             {
                 int mask = GetContentKindMask(type);
@@ -967,11 +965,10 @@ namespace System.Xml
             return false;
         }
 
-        public override bool MoveToFollowing(string localName, string namespaceUri, XPathNavigator end)
+        public override bool MoveToFollowing(string localName, string namespaceUri, XPathNavigator? end)
         {
-            XmlNode pastFollowing = null;
-            DocumentXPathNavigator that = end as DocumentXPathNavigator;
-            if (that != null)
+            XmlNode? pastFollowing = null;
+            if (end is DocumentXPathNavigator that)
             {
                 if (_document != that._document)
                 {
@@ -990,7 +987,7 @@ namespace System.Xml
                 pastFollowing = that._source;
             }
 
-            XmlNode following = _source;
+            XmlNode? following = _source;
             if (following.NodeType == XmlNodeType.Attribute)
             {
                 following = ((XmlAttribute)following).OwnerElement;
@@ -1001,7 +998,7 @@ namespace System.Xml
             }
             do
             {
-                XmlNode firstChild = following.FirstChild;
+                XmlNode? firstChild = following.FirstChild;
                 if (firstChild != null)
                 {
                     following = firstChild;
@@ -1010,7 +1007,7 @@ namespace System.Xml
                 {
                     while (true)
                     {
-                        XmlNode nextSibling = following.NextSibling;
+                        XmlNode? nextSibling = following.NextSibling;
                         if (nextSibling != null)
                         {
                             following = nextSibling;
@@ -1018,7 +1015,7 @@ namespace System.Xml
                         }
                         else
                         {
-                            XmlNode parent = following.ParentNode;
+                            XmlNode? parent = following.ParentNode;
                             if (parent != null)
                             {
                                 following = parent;
@@ -1043,11 +1040,10 @@ namespace System.Xml
             return true;
         }
 
-        public override bool MoveToFollowing(XPathNodeType type, XPathNavigator end)
+        public override bool MoveToFollowing(XPathNodeType type, XPathNavigator? end)
         {
-            XmlNode pastFollowing = null;
-            DocumentXPathNavigator that = end as DocumentXPathNavigator;
-            if (that != null)
+            XmlNode? pastFollowing = null;
+            if (end is DocumentXPathNavigator that)
             {
                 if (_document != that._document)
                 {
@@ -1071,7 +1067,7 @@ namespace System.Xml
             {
                 return false;
             }
-            XmlNode following = _source;
+            XmlNode? following = _source;
             switch (following.NodeType)
             {
                 case XmlNodeType.Attribute:
@@ -1090,7 +1086,7 @@ namespace System.Xml
             }
             do
             {
-                XmlNode firstChild = following.FirstChild;
+                XmlNode? firstChild = following.FirstChild;
                 if (firstChild != null)
                 {
                     following = firstChild;
@@ -1099,7 +1095,7 @@ namespace System.Xml
                 {
                     while (true)
                     {
-                        XmlNode nextSibling = following.NextSibling;
+                        XmlNode? nextSibling = following.NextSibling;
                         if (nextSibling != null)
                         {
                             following = nextSibling;
@@ -1107,7 +1103,7 @@ namespace System.Xml
                         }
                         else
                         {
-                            XmlNode parent = following.ParentNode;
+                            XmlNode? parent = following.ParentNode;
                             if (parent != null)
                             {
                                 following = parent;
@@ -1132,7 +1128,7 @@ namespace System.Xml
 
         public override bool MoveToNext(string localName, string namespaceUri)
         {
-            XmlNode sibling = NextSibling(_source);
+            XmlNode? sibling = NextSibling(_source);
             if (sibling == null)
             {
                 return false;
@@ -1154,7 +1150,7 @@ namespace System.Xml
 
         public override bool MoveToNext(XPathNodeType type)
         {
-            XmlNode sibling = NextSibling(_source);
+            XmlNode? sibling = NextSibling(_source);
             if (sibling == null)
             {
                 return false;
@@ -1191,7 +1187,7 @@ namespace System.Xml
         {
             get
             {
-                XmlNode child;
+                XmlNode? child;
                 switch (_source.NodeType)
                 {
                     case XmlNodeType.Element:
@@ -1225,8 +1221,7 @@ namespace System.Xml
 
         public override bool IsSamePosition(XPathNavigator other)
         {
-            DocumentXPathNavigator that = other as DocumentXPathNavigator;
-            if (that != null)
+            if (other is DocumentXPathNavigator that)
             {
                 this.CalibrateText();
                 that.CalibrateText();
@@ -1237,10 +1232,9 @@ namespace System.Xml
             return false;
         }
 
-        public override bool IsDescendant(XPathNavigator other)
+        public override bool IsDescendant(XPathNavigator? other)
         {
-            DocumentXPathNavigator that = other as DocumentXPathNavigator;
-            if (that != null)
+            if (other is DocumentXPathNavigator that)
             {
                 return IsDescendant(_source, that._source);
             }
@@ -1257,7 +1251,7 @@ namespace System.Xml
 
         public override bool CheckValidity(XmlSchemaSet schemas, ValidationEventHandler validationEventHandler)
         {
-            XmlDocument ownerDocument;
+            XmlDocument? ownerDocument;
 
             if (_source.NodeType == XmlNodeType.Document)
             {
@@ -1282,20 +1276,21 @@ namespace System.Xml
                 throw new InvalidOperationException(SR.XmlDocument_NoSchemaInfo);
             }
 
+            // DocumentSchemaValidator assumes that ownedDocument can never be null.
+            Debug.Assert(ownerDocument != null);
             DocumentSchemaValidator validator = new DocumentSchemaValidator(ownerDocument, schemas, validationEventHandler);
             validator.PsviAugmentation = false;
             return validator.Validate(_source);
         }
 
-        private static XmlNode OwnerNode(XmlNode node)
+        private static XmlNode? OwnerNode(XmlNode node)
         {
-            XmlNode parent = node.ParentNode;
+            XmlNode? parent = node.ParentNode;
             if (parent != null)
             {
                 return parent;
             }
-            XmlAttribute attribute = node as XmlAttribute;
-            if (attribute != null)
+            if (node is XmlAttribute attribute)
             {
                 return attribute.OwnerElement;
             }
@@ -1305,7 +1300,7 @@ namespace System.Xml
         private static int GetDepth(XmlNode node)
         {
             int depth = 0;
-            XmlNode owner = OwnerNode(node);
+            XmlNode? owner = OwnerNode(node);
             while (owner != null)
             {
                 depth++;
@@ -1327,7 +1322,8 @@ namespace System.Xml
             {
                 if (node2.XPNodeType == XPathNodeType.Attribute)
                 {
-                    XmlElement element = ((XmlAttribute)node1).OwnerElement;
+                    XmlElement? element = ((XmlAttribute)node1).OwnerElement;
+                    Debug.Assert(element != null);
                     if (element.HasAttributes)
                     {
                         XmlAttributeCollection attributes = element.Attributes;
@@ -1357,7 +1353,7 @@ namespace System.Xml
             }
 
             //neither of the node is Namespace node or Attribute node
-            XmlNode nextNode = node1.NextSibling;
+            XmlNode? nextNode = node1.NextSibling;
             while (nextNode != null && nextNode != node2)
                 nextNode = nextNode.NextSibling;
             if (nextNode == null)
@@ -1368,10 +1364,9 @@ namespace System.Xml
                 return XmlNodeOrder.Before;
         }
 
-        public override XmlNodeOrder ComparePosition(XPathNavigator other)
+        public override XmlNodeOrder ComparePosition(XPathNavigator? other)
         {
-            DocumentXPathNavigator that = other as DocumentXPathNavigator;
-            if (that == null)
+            if (!(other is DocumentXPathNavigator that))
             {
                 return XmlNodeOrder.Unknown;
             }
@@ -1391,11 +1386,11 @@ namespace System.Xml
                 return base.ComparePosition(other);
             }
 
-            XmlNode node1 = _source;
-            XmlNode node2 = that._source;
+            XmlNode? node1 = _source;
+            XmlNode? node2 = that._source;
 
-            XmlNode parent1 = OwnerNode(node1);
-            XmlNode parent2 = OwnerNode(node2);
+            XmlNode? parent1 = OwnerNode(node1);
+            XmlNode? parent2 = OwnerNode(node2);
             if (parent1 == parent2)
             {
                 if (parent1 == null)
@@ -1423,6 +1418,7 @@ namespace System.Xml
                 {
                     return XmlNodeOrder.Before;
                 }
+                Debug.Assert(node2 != null);
                 parent2 = OwnerNode(node2);
             }
             else if (depth1 > depth2)
@@ -1437,6 +1433,7 @@ namespace System.Xml
                 {
                     return XmlNodeOrder.After;
                 }
+                Debug.Assert(node1 != null);
                 parent1 = OwnerNode(node1);
             }
 
@@ -1461,13 +1458,13 @@ namespace System.Xml
 
         public override XPathNodeIterator SelectDescendants(string localName, string namespaceURI, bool matchSelf)
         {
-            string nsAtom = _document.NameTable.Get(namespaceURI);
+            string? nsAtom = _document.NameTable.Get(namespaceURI);
             if (nsAtom == null || _source.NodeType == XmlNodeType.Attribute)
                 return new DocumentXPathNodeIterator_Empty(this);
 
             Debug.Assert(this.NodeType != XPathNodeType.Attribute && this.NodeType != XPathNodeType.Namespace && this.NodeType != XPathNodeType.All);
 
-            string localNameAtom = _document.NameTable.Get(localName);
+            string? localNameAtom = _document.NameTable.Get(localName);
             if (localNameAtom == null)
                 return new DocumentXPathNodeIterator_Empty(this);
 
@@ -1606,8 +1603,7 @@ namespace System.Xml
 
         public override XmlWriter ReplaceRange(XPathNavigator lastSiblingToReplace)
         {
-            DocumentXPathNavigator that = lastSiblingToReplace as DocumentXPathNavigator;
-            if (that == null)
+            if (!(lastSiblingToReplace is DocumentXPathNavigator that))
             {
                 if (lastSiblingToReplace == null)
                 {
@@ -1664,8 +1660,7 @@ namespace System.Xml
 
         public override void DeleteRange(XPathNavigator lastSiblingToDelete)
         {
-            DocumentXPathNavigator that = lastSiblingToDelete as DocumentXPathNavigator;
-            if (that == null)
+            if (!(lastSiblingToDelete is DocumentXPathNavigator that))
             {
                 if (lastSiblingToDelete == null)
                 {
@@ -1693,7 +1688,7 @@ namespace System.Xml
                         {
                             goto default;
                         }
-                        XmlNode parent = OwnerNode(attribute);
+                        XmlNode? parent = OwnerNode(attribute);
                         DeleteAttribute(attribute, _attributeIndex);
                         if (parent != null)
                         {
@@ -1730,7 +1725,7 @@ namespace System.Xml
                 {
                     throw new InvalidOperationException(SR.Xpn_BadPosition);
                 }
-                XmlNode parent = OwnerNode(node);
+                XmlNode? parent = OwnerNode(node);
                 DeleteToFollowingSibling(node, end);
                 if (parent != null)
                 {
@@ -1752,7 +1747,7 @@ namespace System.Xml
                     {
                         goto default;
                     }
-                    XmlNode parent = OwnerNode(attribute);
+                    XmlNode? parent = OwnerNode(attribute);
                     DeleteAttribute(attribute, _attributeIndex);
                     if (parent != null)
                     {
@@ -1785,7 +1780,7 @@ namespace System.Xml
 
         private static void DeleteAttribute(XmlAttribute attribute, int index)
         {
-            XmlAttributeCollection attributes;
+            XmlAttributeCollection? attributes;
 
             if (!CheckAttributePosition(attribute, out attributes, index)
                 && !ResetAttributePosition(attribute, attributes, out index))
@@ -1801,7 +1796,7 @@ namespace System.Xml
 
         internal static void DeleteToFollowingSibling(XmlNode node, XmlNode end)
         {
-            XmlNode parent = node.ParentNode;
+            XmlNode? parent = node.ParentNode;
 
             if (parent == null)
             {
@@ -1814,22 +1809,22 @@ namespace System.Xml
             }
             while (node != end)
             {
+                Debug.Assert(node != null, "This method needs to be called with the beforehand check of NextSibling being not null from node to end");
                 XmlNode temp = node;
-                node = node.NextSibling;
+                node = node.NextSibling!;
                 parent.RemoveChild(temp);
             }
             parent.RemoveChild(node);
         }
 
-        private static XmlNamespaceManager GetNamespaceManager(XmlNode node, XmlDocument document)
+        private static XmlNamespaceManager GetNamespaceManager(XmlNode? node, XmlDocument document)
         {
             XmlNamespaceManager namespaceManager = new XmlNamespaceManager(document.NameTable);
             List<XmlElement> elements = new List<XmlElement>();
 
             while (node != null)
             {
-                XmlElement element = node as XmlElement;
-                if (element != null
+                if (node is XmlElement element
                     && element.HasAttributes)
                 {
                     elements.Add(element);
@@ -1853,15 +1848,15 @@ namespace System.Xml
             return namespaceManager;
         }
 
+        [MemberNotNull(nameof(_source))]
         internal void ResetPosition(XmlNode node)
         {
             Debug.Assert(node != null, "Undefined navigator position");
             Debug.Assert(node == _document || node.OwnerDocument == _document, "Navigator switched documents");
             _source = node;
-            XmlAttribute attribute = node as XmlAttribute;
-            if (attribute != null)
+            if (node is XmlAttribute attribute)
             {
-                XmlElement element = attribute.OwnerElement;
+                XmlElement? element = attribute.OwnerElement;
                 if (element != null)
                 {
                     ResetAttributePosition(attribute, element.Attributes, out _attributeIndex);
@@ -1873,7 +1868,7 @@ namespace System.Xml
             }
         }
 
-        private static bool ResetAttributePosition(XmlAttribute attribute, XmlAttributeCollection attributes, out int index)
+        private static bool ResetAttributePosition(XmlAttribute attribute, [NotNullWhen(true)] XmlAttributeCollection? attributes, out int index)
         {
             if (attributes != null)
             {
@@ -1890,9 +1885,9 @@ namespace System.Xml
             return false;
         }
 
-        private static bool CheckAttributePosition(XmlAttribute attribute, out XmlAttributeCollection attributes, int index)
+        private static bool CheckAttributePosition(XmlAttribute attribute, [NotNullWhen(true)] out XmlAttributeCollection? attributes, int index)
         {
-            XmlElement element = attribute.OwnerElement;
+            XmlElement? element = attribute.OwnerElement;
             if (element != null)
             {
                 attributes = element.Attributes;
@@ -1912,7 +1907,7 @@ namespace System.Xml
 
         private void CalibrateText()
         {
-            XmlNode text = PreviousText(_source);
+            XmlNode? text = PreviousText(_source);
             while (text != null)
             {
                 ResetPosition(text);
@@ -1920,9 +1915,9 @@ namespace System.Xml
             }
         }
 
-        private XmlNode ParentNode(XmlNode node)
+        private XmlNode? ParentNode(XmlNode node)
         {
-            XmlNode parent = node.ParentNode;
+            XmlNode? parent = node.ParentNode;
 
             if (!_document.HasEntityReferences)
             {
@@ -1931,7 +1926,7 @@ namespace System.Xml
             return ParentNodeTail(parent);
         }
 
-        private XmlNode ParentNodeTail(XmlNode parent)
+        private XmlNode? ParentNodeTail(XmlNode? parent)
         {
             while (parent != null
                    && parent.NodeType == XmlNodeType.EntityReference)
@@ -1941,9 +1936,9 @@ namespace System.Xml
             return parent;
         }
 
-        private XmlNode FirstChild(XmlNode node)
+        private XmlNode? FirstChild(XmlNode node)
         {
-            XmlNode child = node.FirstChild;
+            XmlNode? child = node.FirstChild;
 
             if (!_document.HasEntityReferences)
             {
@@ -1952,7 +1947,7 @@ namespace System.Xml
             return FirstChildTail(child);
         }
 
-        private XmlNode FirstChildTail(XmlNode child)
+        private XmlNode? FirstChildTail(XmlNode? child)
         {
             while (child != null
                    && child.NodeType == XmlNodeType.EntityReference)
@@ -1962,9 +1957,9 @@ namespace System.Xml
             return child;
         }
 
-        private XmlNode NextSibling(XmlNode node)
+        private XmlNode? NextSibling(XmlNode node)
         {
-            XmlNode sibling = node.NextSibling;
+            XmlNode? sibling = node.NextSibling;
 
             if (!_document.HasEntityReferences)
             {
@@ -1973,17 +1968,18 @@ namespace System.Xml
             return NextSiblingTail(node, sibling);
         }
 
-        private XmlNode NextSiblingTail(XmlNode node, XmlNode sibling)
+        private XmlNode? NextSiblingTail(XmlNode node, XmlNode? sibling)
         {
+            XmlNode? current = node;
             while (sibling == null)
             {
-                node = node.ParentNode;
-                if (node == null
-                    || node.NodeType != XmlNodeType.EntityReference)
+                current = current.ParentNode;
+                if (current == null
+                    || current.NodeType != XmlNodeType.EntityReference)
                 {
                     return null;
                 }
-                sibling = node.NextSibling;
+                sibling = current.NextSibling;
             }
             while (sibling != null
                    && sibling.NodeType == XmlNodeType.EntityReference)
@@ -1993,9 +1989,9 @@ namespace System.Xml
             return sibling;
         }
 
-        private XmlNode PreviousSibling(XmlNode node)
+        private XmlNode? PreviousSibling(XmlNode node)
         {
-            XmlNode sibling = node.PreviousSibling;
+            XmlNode? sibling = node.PreviousSibling;
 
             if (!_document.HasEntityReferences)
             {
@@ -2004,17 +2000,18 @@ namespace System.Xml
             return PreviousSiblingTail(node, sibling);
         }
 
-        private XmlNode PreviousSiblingTail(XmlNode node, XmlNode sibling)
+        private XmlNode? PreviousSiblingTail(XmlNode node, XmlNode? sibling)
         {
+            XmlNode? current = node;
             while (sibling == null)
             {
-                node = node.ParentNode;
-                if (node == null
-                    || node.NodeType != XmlNodeType.EntityReference)
+                current = current.ParentNode;
+                if (current == null
+                    || current.NodeType != XmlNodeType.EntityReference)
                 {
                     return null;
                 }
-                sibling = node.PreviousSibling;
+                sibling = current.PreviousSibling;
             }
             while (sibling != null
                    && sibling.NodeType == XmlNodeType.EntityReference)
@@ -2024,9 +2021,9 @@ namespace System.Xml
             return sibling;
         }
 
-        private XmlNode PreviousText(XmlNode node)
+        private XmlNode? PreviousText(XmlNode node)
         {
-            XmlNode text = node.PreviousText;
+            XmlNode? text = node.PreviousText;
 
             if (!_document.HasEntityReferences)
             {
@@ -2035,7 +2032,7 @@ namespace System.Xml
             return PreviousTextTail(node, text);
         }
 
-        private XmlNode PreviousTextTail(XmlNode node, XmlNode text)
+        private XmlNode? PreviousTextTail(XmlNode node, XmlNode? text)
         {
             if (text != null)
             {
@@ -2045,16 +2042,17 @@ namespace System.Xml
             {
                 return null;
             }
-            XmlNode sibling = node.PreviousSibling;
+            XmlNode? sibling = node.PreviousSibling;
+            XmlNode? current = node;
             while (sibling == null)
             {
-                node = node.ParentNode;
-                if (node == null
-                    || node.NodeType != XmlNodeType.EntityReference)
+                current = current.ParentNode;
+                if (current == null
+                    || current.NodeType != XmlNodeType.EntityReference)
                 {
                     return null;
                 }
-                sibling = node.PreviousSibling;
+                sibling = current.PreviousSibling;
             }
             while (sibling != null)
             {
@@ -2075,16 +2073,17 @@ namespace System.Xml
             return null;
         }
 
-        internal static bool IsFollowingSibling(XmlNode left, XmlNode right)
+        internal static bool IsFollowingSibling(XmlNode left, [NotNullWhen(true)] XmlNode? right)
         {
+            XmlNode? currentLeft = left;
             while (true)
             {
-                left = left.NextSibling;
-                if (left == null)
+                currentLeft = currentLeft.NextSibling;
+                if (currentLeft == null)
                 {
                     break;
                 }
-                if (left == right)
+                if (currentLeft == right)
                 {
                     return true;
                 }
@@ -2096,11 +2095,10 @@ namespace System.Xml
         {
             while (true)
             {
-                XmlNode parent = bottom.ParentNode;
+                XmlNode? parent = bottom.ParentNode;
                 if (parent == null)
                 {
-                    XmlAttribute attribute = bottom as XmlAttribute;
-                    if (attribute == null)
+                    if (!(bottom is XmlAttribute attribute))
                     {
                         break;
                     }
@@ -2156,28 +2154,30 @@ namespace System.Xml
         private XmlNode TextStart(XmlNode node)
         {
             XmlNode start;
+            XmlNode? current = node;
 
             do
             {
-                start = node;
-                node = PreviousSibling(node);
+                start = current;
+                current = PreviousSibling(current);
             }
-            while (node != null
-                   && node.IsText);
+            while (current != null
+                   && current.IsText);
             return start;
         }
 
         private XmlNode TextEnd(XmlNode node)
         {
             XmlNode end;
+            XmlNode? current = node;
 
             do
             {
-                end = node;
-                node = NextSibling(node);
+                end = current;
+                current = NextSibling(current);
             }
-            while (node != null
-                   && node.IsText);
+            while (current != null
+                   && current.IsText);
             return end;
         }
     }
index 8012cea..5019c9b 100644 (file)
@@ -472,7 +472,7 @@ namespace System.Xml
                     throw new InvalidOperationException(SR.Xdom_Node_Modify_ReadOnly);
                 }
 
-                DocumentXPathNavigator.DeleteToFollowingSibling(_start.NextSibling, _end);
+                DocumentXPathNavigator.DeleteToFollowingSibling(_start.NextSibling!, _end);
             }
 
             XmlNode fragment0 = _fragment[0];
index 1715d66..6001600 100644 (file)
@@ -634,10 +634,10 @@ namespace System.Xml
 
         internal override string XPLocalName { get { return LocalName; } }
 
-        internal override string? GetXPAttribute(string localName, string ns)
+        internal override string GetXPAttribute(string localName, string ns)
         {
             if (ns == OwnerDocument.strReservedXmlns)
-                return null;
+                return string.Empty;
 
             XmlAttribute? attr = GetAttributeNode(localName, ns);
             if (attr != null)
index 75e429e..c31e084 100644 (file)
@@ -1408,7 +1408,7 @@ namespace System.Xml
             }
         }
 
-        internal virtual string? GetXPAttribute(string localName, string namespaceURI)
+        internal virtual string GetXPAttribute(string localName, string namespaceURI)
         {
             return string.Empty;
         }
index e0a3912..077c176 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Collections.Generic;
 using System.Xml.Xsl.Qil;
 
index 6b1740e..a8c33e4 100644 (file)
@@ -1,27 +1,32 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+#nullable enable
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Xml.XPath;
 
 namespace System.Xml.Xsl.XPath
 {
+    // TODO-NULLABLE: Replace [MaybeNull] with ? once https://github.com/dotnet/runtime/pull/40197 is in.
     internal interface IXPathBuilder<Node>
     {
         // Should be called once per build
         void StartBuild();
 
         // Should be called after build for result tree post-processing
-        Node EndBuild(Node result);
+        [return: MaybeNull]
+        [return: NotNullIfNotNull("result")]
+        Node EndBuild([AllowNull] Node result);
 
         Node String(string value);
 
         Node Number(double value);
 
-        Node Operator(XPathOperator op, Node left, Node right);
+        Node Operator(XPathOperator op, [AllowNull] Node left, [AllowNull] Node right);
 
-        Node Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string prefix, string name);
+        Node Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string? prefix, string? name);
 
         Node JoinStep(Node left, Node right);
 
index ee3a212..18977c9 100644 (file)
@@ -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.
 
+#nullable enable
 namespace System.Xml.Xsl.XPath
 {
     // Order is important - we use them as an index in QilAxis & AxisMask arrays
index 8be18af..43631e6 100644 (file)
@@ -1,8 +1,10 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+#nullable enable
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Globalization;
 using System.Xml.Schema;
 using System.Xml.XPath;
@@ -69,7 +71,8 @@ namespace System.Xml.Xsl.XPath
             numFixupCurrent = numFixupPosition = numFixupLast = 0;
         }
 
-        public virtual QilNode EndBuild(QilNode result)
+        [return: NotNullIfNotNull("result")]
+        public virtual QilNode? EndBuild(QilNode? result)
         {
             if (result == null)
             { // special door to clean builder state in exception handlers
@@ -109,17 +112,21 @@ namespace System.Xml.Xsl.XPath
             return _f.Double(value);
         }
 
-        public virtual QilNode Operator(XPathOperator op, QilNode left, QilNode right)
+        public virtual QilNode Operator(XPathOperator op, QilNode? left, QilNode? right)
         {
             Debug.Assert(op != XPathOperator.Unknown);
-            switch (s_operatorGroup[(int)op])
+            XPathOperatorGroup opGroup = s_operatorGroup[(int)op];
+
+            Debug.Assert((opGroup != XPathOperatorGroup.Negate && right != null) || (opGroup == XPathOperatorGroup.Negate && right == null));
+
+            switch (opGroup)
             {
-                case XPathOperatorGroup.Logical: return LogicalOperator(op, left, right);
-                case XPathOperatorGroup.Equality: return EqualityOperator(op, left, right);
-                case XPathOperatorGroup.Relational: return RelationalOperator(op, left, right);
-                case XPathOperatorGroup.Arithmetic: return ArithmeticOperator(op, left, right);
-                case XPathOperatorGroup.Negate: return NegateOperator(op, left, right);
-                case XPathOperatorGroup.Union: return UnionOperator(op, left, right);
+                case XPathOperatorGroup.Logical: return LogicalOperator(op, left!, right!);
+                case XPathOperatorGroup.Equality: return EqualityOperator(op, left!, right!);
+                case XPathOperatorGroup.Relational: return RelationalOperator(op, left!, right!);
+                case XPathOperatorGroup.Arithmetic: return ArithmeticOperator(op, left!, right!);
+                case XPathOperatorGroup.Negate: return NegateOperator(op, left!);
+                case XPathOperatorGroup.Union: return UnionOperator(op, left, right!);
                 default:
                     Debug.Fail(op + " is not a valid XPathOperator");
                     return null;
@@ -268,10 +275,9 @@ namespace System.Xml.Xsl.XPath
             }
         }
 
-        private QilNode NegateOperator(XPathOperator op, QilNode left, QilNode right)
+        private QilNode NegateOperator(XPathOperator op, QilNode left)
         {
             Debug.Assert(op == XPathOperator.UnaryMinus);
-            Debug.Assert(right == null);
             return _f.Negate(_f.ConvertToNumber(left));
         }
 
@@ -292,7 +298,7 @@ namespace System.Xml.Xsl.XPath
             }
         }
 
-        private QilNode UnionOperator(XPathOperator op, QilNode left, QilNode right)
+        private QilNode UnionOperator(XPathOperator op, QilNode? left, QilNode right)
         {
             Debug.Assert(op == XPathOperator.Union);
             if (left == null)
@@ -321,7 +327,7 @@ namespace System.Xml.Xsl.XPath
             );
         }
 
-        private QilNode BuildAxisFilter(QilNode qilAxis, XPathAxis xpathAxis, XPathNodeType nodeType, string name, string nsUri)
+        private QilNode BuildAxisFilter(QilNode qilAxis, XPathAxis xpathAxis, XPathNodeType nodeType, string? name, string? nsUri)
         {
             XmlNodeKindFlags original = qilAxis.XmlType.NodeKinds;
             XmlNodeKindFlags required = AxisTypeMask(original, nodeType, xpathAxis);
@@ -383,7 +389,7 @@ namespace System.Xml.Xsl.XPath
                 /*All                  */ XmlNodeKindFlags.Any
         };
 
-        private QilNode BuildAxis(XPathAxis xpathAxis, XPathNodeType nodeType, string nsUri, string name)
+        private QilNode BuildAxis(XPathAxis xpathAxis, XPathNodeType nodeType, string? nsUri, string? name)
         {
             QilNode currentNode = GetCurrentNode();
             QilNode qilAxis;
@@ -406,7 +412,7 @@ namespace System.Xml.Xsl.XPath
                 // Can be done using BuildAxisFilter() but f.Root() sets wrong XmlNodeKindFlags
                 case XPathAxis.Root: return _f.Root(currentNode);
                 default:
-                    qilAxis = null;
+                    qilAxis = null!;
                     Debug.Fail("Invalid EnumValue 'XPathAxis'");
                     break;
             }
@@ -425,9 +431,9 @@ namespace System.Xml.Xsl.XPath
             return result;
         }
 
-        public virtual QilNode Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string prefix, string name)
+        public virtual QilNode Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string? prefix, string? name)
         {
-            string nsUri = prefix == null ? null : _environment.ResolvePrefix(prefix);
+            string? nsUri = prefix == null ? null : _environment.ResolvePrefix(prefix);
             return BuildAxis(xpathAxis, nodeType, nsUri, name);
         }
 
@@ -557,7 +563,7 @@ namespace System.Xml.Xsl.XPath
             Debug.Assert(!args.IsReadOnly, "Writable collection expected");
             if (prefix.Length == 0)
             {
-                FunctionInfo func;
+                FunctionInfo? func;
                 if (FunctionTable.TryGetValue(name, out func))
                 {
                     func.CastArguments(args, name, _f);
@@ -827,10 +833,10 @@ namespace System.Xml.Xsl.XPath
         {
             private new readonly QilPatternFactory f;
             private readonly QilNode _fixupCurrent, _fixupPosition, _fixupLast; // fixup nodes we are replacing
-            private QilIterator _current;
-            private QilNode _last;               // expressions we are using to replace fixupNodes
+            private QilIterator? _current;
+            private QilNode? _last;               // expressions we are using to replace fixupNodes
             private bool _justCount;          // Don't change tree, just count
-            private IXPathEnvironment _environment;  // temp solution
+            private IXPathEnvironment? _environment;  // temp solution
             public int numCurrent, numPosition, numLast; // here we are counting all replacements we have made
 
             public FixupVisitor(QilPatternFactory f, QilNode fixupCurrent, QilNode fixupPosition, QilNode fixupLast) : base(f.BaseFactory)
@@ -841,7 +847,7 @@ namespace System.Xml.Xsl.XPath
                 _fixupLast = fixupLast;
             }
 
-            public QilNode Fixup(QilNode inExpr, QilIterator current, QilNode last)
+            public QilNode Fixup(QilNode inExpr, QilIterator current, QilNode? last)
             {
                 QilDepthChecker.Check(inExpr);
                 _current = current;
@@ -975,11 +981,11 @@ namespace System.Xml.Xsl.XPath
             public T id;
             public int minArgs;
             public int maxArgs;
-            public XmlTypeCode[] argTypes;
+            public XmlTypeCode[]? argTypes;
 
             public const int Infinity = int.MaxValue;
 
-            public FunctionInfo(T id, int minArgs, int maxArgs, XmlTypeCode[] argTypes)
+            public FunctionInfo(T id, int minArgs, int maxArgs, XmlTypeCode[]? argTypes)
             {
                 Debug.Assert(maxArgs == 0 || maxArgs == Infinity || argTypes != null && argTypes.Length == maxArgs);
                 this.id = id;
@@ -1039,9 +1045,10 @@ namespace System.Xml.Xsl.XPath
                 }
                 else
                 {
+                    Debug.Assert(args.Count == 0 || argTypes != null);
                     for (int i = 0; i < args.Count; i++)
                     {
-                        if (argTypes[i] == XmlTypeCode.Node && f.CannotBeNodeSet(args[i]))
+                        if (argTypes![i] == XmlTypeCode.Node && f.CannotBeNodeSet(args[i]))
                         {
                             throw new XPathCompileException(SR.XPath_NodeSetArgumentExpected, name, (i + 1).ToString(CultureInfo.InvariantCulture));
                         }
index 353fa40..cc10b52 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Runtime.Serialization;
 using System.Text;
 
@@ -9,7 +10,7 @@ namespace System.Xml.Xsl.XPath
     [Serializable]
     internal class XPathCompileException : XslLoadException
     {
-        public string queryString;
+        public string? queryString;
         public int startChar;
         public int endChar;
 
@@ -28,9 +29,9 @@ namespace System.Xml.Xsl.XPath
         internal XPathCompileException(SerializationInfo info, StreamingContext context)
             : base(info, context)
         {
-            queryString = (string)info.GetValue("QueryString", typeof(string));
-            startChar = (int)info.GetValue("StartChar", typeof(int));
-            endChar = (int)info.GetValue("EndChar", typeof(int));
+            queryString = (string)info.GetValue("QueryString", typeof(string))!;
+            startChar = (int)info.GetValue("StartChar", typeof(int))!;
+            endChar = (int)info.GetValue("EndChar", typeof(int))!;
         }
 
         public override void GetObjectData(SerializationInfo info, StreamingContext context)
@@ -79,7 +80,7 @@ namespace System.Xml.Xsl.XPath
             }
         }
 
-        internal string MarkOutError()
+        internal string? MarkOutError()
         {
             if (queryString == null || queryString.Trim(' ').Length == 0)
             {
@@ -105,7 +106,7 @@ namespace System.Xml.Xsl.XPath
         internal override string FormatDetailedMessage()
         {
             string message = Message;
-            string error = MarkOutError();
+            string? error = MarkOutError();
 
             if (error != null && error.Length > 0)
             {
index f1b073d..f863ef7 100644 (file)
@@ -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.
 
+#nullable enable
 #if DontUse
 // XPathContext is not used any more but comments in it and Replacer visitor may be used to
 // optimize code XSLT generates on last().
index 58765d2..adc8c37 100644 (file)
@@ -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.
 
+#nullable enable
 namespace System.Xml.Xsl.XPath
 {
     // order is importent. We are using them as an index in OperatorGroup & QilOperator & XPathOperatorToQilNodeType arrays
index ab3f0ae..d707ad5 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Collections.Generic;
 using System.Diagnostics;
 
@@ -10,8 +11,8 @@ namespace System.Xml.Xsl.XPath
 
     internal class XPathParser<Node>
     {
-        private XPathScanner _scanner;
-        private IXPathBuilder<Node> _builder;
+        private XPathScanner? _scanner;
+        private IXPathBuilder<Node>? _builder;
         private readonly Stack<int> _posInfo = new Stack<int>();
 
         // Six possible causes of exceptions in the builder:
@@ -56,7 +57,7 @@ namespace System.Xml.Xsl.XPath
 #endif
             }
             Debug.Assert(_posInfo.Count == 0, "PushPosInfo() and PopPosInfo() calls have been unbalanced");
-            return result;
+            return result!;
         }
 
         #region Location paths and node tests
@@ -81,10 +82,10 @@ namespace System.Xml.Xsl.XPath
         */
         private Node ParseLocationPath()
         {
-            if (_scanner.Kind == LexKind.Slash)
+            if (_scanner!.Kind == LexKind.Slash)
             {
                 _scanner.NextLex();
-                Node opnd = _builder.Axis(XPathAxis.Root, XPathNodeType.All, null, null);
+                Node opnd = _builder!.Axis(XPathAxis.Root, XPathNodeType.All, null, null);
 
                 if (IsStep(_scanner.Kind))
                 {
@@ -95,7 +96,7 @@ namespace System.Xml.Xsl.XPath
             else if (_scanner.Kind == LexKind.SlashSlash)
             {
                 _scanner.NextLex();
-                return _builder.JoinStep(
+                return _builder!.JoinStep(
                     _builder.Axis(XPathAxis.Root, XPathNodeType.All, null, null),
                     _builder.JoinStep(
                         _builder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null),
@@ -121,19 +122,19 @@ namespace System.Xml.Xsl.XPath
             {
                 if (LocalAppContextSwitches.LimitXPathComplexity)
                 {
-                    throw _scanner.CreateException(SR.Xslt_InputTooComplex);
+                    throw _scanner!.CreateException(SR.Xslt_InputTooComplex);
                 }
             }
             Node opnd = ParseStep();
-            if (_scanner.Kind == LexKind.Slash)
+            if (_scanner!.Kind == LexKind.Slash)
             {
                 _scanner.NextLex();
-                opnd = _builder.JoinStep(opnd, ParseRelativeLocationPath());
+                opnd = _builder!.JoinStep(opnd, ParseRelativeLocationPath());
             }
             else if (_scanner.Kind == LexKind.SlashSlash)
             {
                 _scanner.NextLex();
-                opnd = _builder.JoinStep(opnd,
+                opnd = _builder!.JoinStep(opnd,
                     _builder.JoinStep(
                         _builder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null),
                         ParseRelativeLocationPath()
@@ -150,10 +151,10 @@ namespace System.Xml.Xsl.XPath
         private Node ParseStep()
         {
             Node opnd;
-            if (LexKind.Dot == _scanner.Kind)
+            if (LexKind.Dot == _scanner!.Kind)
             {                  // '.'
                 _scanner.NextLex();
-                opnd = _builder.Axis(XPathAxis.Self, XPathNodeType.All, null, null);
+                opnd = _builder!.Axis(XPathAxis.Self, XPathNodeType.All, null, null);
                 if (LexKind.LBracket == _scanner.Kind)
                 {
                     throw _scanner.CreateException(SR.XPath_PredicateAfterDot);
@@ -162,7 +163,7 @@ namespace System.Xml.Xsl.XPath
             else if (LexKind.DotDot == _scanner.Kind)
             {        // '..'
                 _scanner.NextLex();
-                opnd = _builder.Axis(XPathAxis.Parent, XPathNodeType.All, null, null);
+                opnd = _builder!.Axis(XPathAxis.Parent, XPathNodeType.All, null, null);
                 if (LexKind.LBracket == _scanner.Kind)
                 {
                     throw _scanner.CreateException(SR.XPath_PredicateAfterDotDot);
@@ -195,7 +196,7 @@ namespace System.Xml.Xsl.XPath
 
                 while (LexKind.LBracket == _scanner.Kind)
                 {
-                    opnd = _builder.Predicate(opnd, ParsePredicate(), IsReverseAxis(axis));
+                    opnd = _builder!.Predicate(opnd, ParsePredicate(), IsReverseAxis(axis));
                 }
             }
             return opnd;
@@ -216,12 +217,12 @@ namespace System.Xml.Xsl.XPath
         private Node ParseNodeTest(XPathAxis axis)
         {
             XPathNodeType nodeType;
-            string nodePrefix, nodeName;
+            string? nodePrefix, nodeName;
 
-            int startChar = _scanner.LexStart;
+            int startChar = _scanner!.LexStart;
             InternalParseNodeTest(_scanner, axis, out nodeType, out nodePrefix, out nodeName);
             PushPosInfo(startChar, _scanner.PrevLexEnd);
-            Node result = _builder.Axis(axis, nodeType, nodePrefix, nodeName);
+            Node result = _builder!.Axis(axis, nodeType, nodePrefix, nodeName);
             PopPosInfo();
             return result;
         }
@@ -245,7 +246,7 @@ namespace System.Xml.Xsl.XPath
             );
         }
 
-        internal static void InternalParseNodeTest(XPathScanner scanner, XPathAxis axis, out XPathNodeType nodeType, out string nodePrefix, out string nodeName)
+        internal static void InternalParseNodeTest(XPathScanner scanner, XPathAxis axis, out XPathNodeType nodeType, out string? nodePrefix, out string? nodeName)
         {
             switch (scanner.Kind)
             {
@@ -311,7 +312,7 @@ namespace System.Xml.Xsl.XPath
         */
         private Node ParsePredicate()
         {
-            _scanner.PassToken(LexKind.LBracket);
+            _scanner!.PassToken(LexKind.LBracket);
             Node opnd = ParseExpr();
             _scanner.PassToken(LexKind.RBracket);
             return opnd;
@@ -349,7 +350,7 @@ namespace System.Xml.Xsl.XPath
             {
                 if (LocalAppContextSwitches.LimitXPathComplexity)
                 {
-                    throw _scanner.CreateException(SR.Xslt_InputTooComplex);
+                    throw _scanner!.CreateException(SR.Xslt_InputTooComplex);
                 }
             }
 
@@ -357,12 +358,12 @@ namespace System.Xml.Xsl.XPath
             Node opnd;
 
             // Check for unary operators
-            if (_scanner.Kind == LexKind.Minus)
+            if (_scanner!.Kind == LexKind.Minus)
             {
                 op = XPathOperator.UnaryMinus;
                 int opPrec = s_XPathOperatorPrecedence[(int)op];
                 _scanner.NextLex();
-                opnd = _builder.Operator(op, ParseSubExpr(opPrec), default(Node));
+                opnd = _builder!.Operator(op, ParseSubExpr(opPrec), default(Node));
             }
             else
             {
@@ -381,7 +382,7 @@ namespace System.Xml.Xsl.XPath
 
                 // Operator's precedence is greater than the one of our caller, so process it here
                 _scanner.NextLex();
-                opnd = _builder.Operator(op, opnd, ParseSubExpr(/*callerPrec:*/opPrec));
+                opnd = _builder!.Operator(op, opnd, ParseSubExpr(/*callerPrec:*/opPrec));
             }
             --_parseSubExprDepth;
             return opnd;
@@ -411,13 +412,13 @@ namespace System.Xml.Xsl.XPath
         */
         private Node ParseUnionExpr()
         {
-            int startChar = _scanner.LexStart;
+            int startChar = _scanner!.LexStart;
             Node opnd1 = ParsePathExpr();
 
             if (_scanner.Kind == LexKind.Union)
             {
                 PushPosInfo(startChar, _scanner.PrevLexEnd);
-                opnd1 = _builder.Operator(XPathOperator.Union, default(Node), opnd1);
+                opnd1 = _builder!.Operator(XPathOperator.Union, default(Node), opnd1);
                 PopPosInfo();
 
                 while (_scanner.Kind == LexKind.Union)
@@ -441,7 +442,7 @@ namespace System.Xml.Xsl.XPath
             // Here we distinguish FilterExpr from LocationPath - the former starts with PrimaryExpr
             if (IsPrimaryExpr())
             {
-                int startChar = _scanner.LexStart;
+                int startChar = _scanner!.LexStart;
                 Node opnd = ParseFilterExpr();
                 int endChar = _scanner.PrevLexEnd;
 
@@ -449,14 +450,14 @@ namespace System.Xml.Xsl.XPath
                 {
                     _scanner.NextLex();
                     PushPosInfo(startChar, endChar);
-                    opnd = _builder.JoinStep(opnd, ParseRelativeLocationPath());
+                    opnd = _builder!.JoinStep(opnd, ParseRelativeLocationPath());
                     PopPosInfo();
                 }
                 else if (_scanner.Kind == LexKind.SlashSlash)
                 {
                     _scanner.NextLex();
                     PushPosInfo(startChar, endChar);
-                    opnd = _builder.JoinStep(opnd,
+                    opnd = _builder!.JoinStep(opnd,
                         _builder.JoinStep(
                             _builder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null),
                             ParseRelativeLocationPath()
@@ -477,14 +478,14 @@ namespace System.Xml.Xsl.XPath
         */
         private Node ParseFilterExpr()
         {
-            int startChar = _scanner.LexStart;
+            int startChar = _scanner!.LexStart;
             Node opnd = ParsePrimaryExpr();
             int endChar = _scanner.PrevLexEnd;
 
             while (_scanner.Kind == LexKind.LBracket)
             {
                 PushPosInfo(startChar, endChar);
-                opnd = _builder.Predicate(opnd, ParsePredicate(), /*reverseStep:*/false);
+                opnd = _builder!.Predicate(opnd, ParsePredicate(), /*reverseStep:*/false);
                 PopPosInfo();
             }
             return opnd;
@@ -493,7 +494,7 @@ namespace System.Xml.Xsl.XPath
         private bool IsPrimaryExpr()
         {
             return (
-                _scanner.Kind == LexKind.String ||
+                _scanner!.Kind == LexKind.String ||
                 _scanner.Kind == LexKind.Number ||
                 _scanner.Kind == LexKind.Dollar ||
                 _scanner.Kind == LexKind.LParens ||
@@ -508,14 +509,14 @@ namespace System.Xml.Xsl.XPath
         {
             Debug.Assert(IsPrimaryExpr());
             Node opnd;
-            switch (_scanner.Kind)
+            switch (_scanner!.Kind)
             {
                 case LexKind.String:
-                    opnd = _builder.String(_scanner.StringValue);
+                    opnd = _builder!.String(_scanner.StringValue);
                     _scanner.NextLex();
                     break;
                 case LexKind.Number:
-                    opnd = _builder.Number(XPathConvert.StringToDouble(_scanner.RawValue));
+                    opnd = _builder!.Number(XPathConvert.StringToDouble(_scanner.RawValue));
                     _scanner.NextLex();
                     break;
                 case LexKind.Dollar:
@@ -523,7 +524,7 @@ namespace System.Xml.Xsl.XPath
                     _scanner.NextLex();
                     _scanner.CheckToken(LexKind.Name);
                     PushPosInfo(startChar, _scanner.LexStart + _scanner.LexSize);
-                    opnd = _builder.Variable(_scanner.Prefix, _scanner.Name);
+                    opnd = _builder!.Variable(_scanner.Prefix, _scanner.Name);
                     PopPosInfo();
                     _scanner.NextLex();
                     break;
@@ -549,7 +550,7 @@ namespace System.Xml.Xsl.XPath
         private Node ParseFunctionCall()
         {
             List<Node> argList = new List<Node>();
-            string name = _scanner.Name;
+            string name = _scanner!.Name;
             string prefix = _scanner.Prefix;
             int startChar = _scanner.LexStart;
 
@@ -572,7 +573,7 @@ namespace System.Xml.Xsl.XPath
 
             _scanner.NextLex();          // move off the ')'
             PushPosInfo(startChar, _scanner.PrevLexEnd);
-            Node result = _builder.Function(prefix, name, argList);
+            Node result = _builder!.Function(prefix, name, argList);
             PopPosInfo();
             return result;
         }
index b6fe069..f92d203 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Diagnostics;
 using System.Xml.Schema;
 using System.Xml.Xsl.Qil;
@@ -289,7 +290,7 @@ namespace System.Xml.Xsl.XPath
         }
 
         // Returns null if the given expression is never a node-set
-        public QilNode TryEnsureNodeSet(QilNode n)
+        public QilNode? TryEnsureNodeSet(QilNode n)
         {
             if (n.XmlType.IsNode && n.XmlType.IsNotRtf)
             {
@@ -307,7 +308,7 @@ namespace System.Xml.Xsl.XPath
         // Throws an exception if the given expression is never a node-set
         public QilNode EnsureNodeSet(QilNode n)
         {
-            QilNode result = TryEnsureNodeSet(n);
+            QilNode? result = TryEnsureNodeSet(n);
             if (result == null)
             {
                 throw new XPathCompileException(SR.XPath_NodeSetExpected);
index 0221f1d..e6509bf 100644 (file)
@@ -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.
 
+#nullable enable
 // <spec>http://www.w3.org/TR/xpath#exprlex</spec>
 //------------------------------------------------------------------------------
 
@@ -62,9 +63,9 @@ namespace System.Xml.Xsl.XPath
         private int _curIndex;
         private char _curChar;
         private LexKind _kind;
-        private string _name;
-        private string _prefix;
-        private string _stringValue;
+        private string? _name;
+        private string? _prefix;
+        private string? _stringValue;
         private bool _canBeFunction;
         private int _lexStart;
         private int _prevLexEnd;
@@ -423,6 +424,8 @@ namespace System.Xml.Xsl.XPath
             }
             else
             {
+                Debug.Assert(_prefix != null);
+                Debug.Assert(_name != null);
                 if (_prefix.Length != 0 || _name.Length > 3)
                     return false;
 
index abf171e..c31f265 100644 (file)
@@ -8,7 +8,9 @@
 *
 */
 
+#nullable enable
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Globalization;
 
 namespace System.Xml.Xsl
@@ -2016,8 +2018,9 @@ namespace System.Xml.Xsl
                 AssertValid();
             }
 
-            public int CompareTo(object obj)
+            public int CompareTo(object? obj)
             {
+                Debug.Assert(obj != null);
                 BigInteger bi = (BigInteger)obj;
                 AssertValid();
                 bi.AssertValid();
index 9f6a873..ef4f222 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Collections;
 using System.Collections.Generic;
 using System.Diagnostics;
@@ -9,6 +10,7 @@ using System.Xml.XPath;
 using System.Xml.Schema;
 using System.Xml.Xsl.Qil;
 using System.Xml.Xsl.XPath;
+using System.Diagnostics.CodeAnalysis;
 
 namespace System.Xml.Xsl.Xslt
 {
@@ -61,7 +63,8 @@ namespace System.Xml.Xsl.Xslt
             filter.Variable.Binding = newBinding;
         }
 
-        public virtual QilNode EndBuild(QilNode result)
+        [return: NotNullIfNotNull("result")]
+        public virtual QilNode? EndBuild(QilNode? result)
         {
             Debug.Assert(_inTheBuild, "StartBuild() wasn't called");
             if (result == null)
@@ -78,7 +81,7 @@ namespace System.Xml.Xsl.Xslt
             return result;
         }
 
-        public QilNode Operator(XPathOperator op, QilNode left, QilNode right)
+        public QilNode Operator(XPathOperator op, QilNode? left, QilNode? right)
         {
             Debug.Assert(op == XPathOperator.Union);
             Debug.Assert(left != null);
@@ -97,7 +100,7 @@ namespace System.Xml.Xsl.Xslt
             }
         }
 
-        private static QilLoop BuildAxisFilter(QilPatternFactory f, QilIterator itr, XPathAxis xpathAxis, XPathNodeType nodeType, string name, string nsUri)
+        private static QilLoop BuildAxisFilter(QilPatternFactory f, QilIterator itr, XPathAxis xpathAxis, XPathNodeType nodeType, string? name, string? nsUri)
         {
             QilNode nameTest = (
                 name != null && nsUri != null ? f.Eq(f.NameOf(itr), f.QName(name, nsUri)) : // ns:bar || bar
@@ -120,7 +123,7 @@ namespace System.Xml.Xsl.Xslt
             return filter;
         }
 
-        public QilNode Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string prefix, string name)
+        public QilNode Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string? prefix, string? name)
         {
             Debug.Assert(
                 xpathAxis == XPathAxis.Child ||
@@ -141,7 +144,7 @@ namespace System.Xml.Xsl.Xslt
                     priority = 0.5;
                     break;
                 default:
-                    string nsUri = prefix == null ? null : _environment.ResolvePrefix(prefix);
+                    string? nsUri = prefix == null ? null : _environment.ResolvePrefix(prefix);
                     result = BuildAxisFilter(_f, _f.For(_fixupNode), xpathAxis, nodeType, name, nsUri);
                     switch (nodeType)
                     {
@@ -214,7 +217,9 @@ namespace System.Xml.Xsl.Xslt
                 }
             }
             Debug.Assert(right.NodeType == QilNodeType.Filter);
-            QilLoop lastParent = GetLastParent(right);
+            QilLoop? lastParent = GetLastParent(right);
+            Debug.Assert(lastParent != null);
+
             FixupFilterBinding(parentFilter, ancestor ? _f.Ancestor(lastParent.Variable) : _f.Parent(lastParent.Variable));
             lastParent.Body = _f.And(lastParent.Body, _f.Not(_f.IsEmpty(parentFilter)));
             SetPriority(right, 0.5);
@@ -336,7 +341,7 @@ namespace System.Xml.Xsl.Xslt
         private class Annotation
         {
             public double Priority;
-            public QilLoop Parent;
+            public QilLoop? Parent;
         }
 
         public static void SetPriority(QilNode node, double priority)
@@ -359,7 +364,7 @@ namespace System.Xml.Xsl.Xslt
             node.Annotation = ann;
         }
 
-        private static QilLoop GetLastParent(QilNode node)
+        private static QilLoop? GetLastParent(QilNode node)
         {
             return ((Annotation)node.Annotation).Parent;
         }
index 7b33bf0..16d2983 100644 (file)
@@ -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.
 
+#nullable enable
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Xml;
@@ -19,15 +20,15 @@ namespace System.Xml.Xsl.Xslt
             IXPathBuilder<QilNode> GetPredicateBuilder(QilNode context);
         }
 
-        private XPathScanner _scanner;
-        private IPatternBuilder _ptrnBuilder;
+        private XPathScanner? _scanner;
+        private IPatternBuilder? _ptrnBuilder;
         private readonly XPathParser _predicateParser = new XPathParser();
 
         public QilNode Parse(XPathScanner scanner, IPatternBuilder ptrnBuilder)
         {
             Debug.Assert(_scanner == null && _ptrnBuilder == null);
             Debug.Assert(scanner != null && ptrnBuilder != null);
-            QilNode result = null;
+            QilNode? result = null;
             ptrnBuilder.StartBuild();
             try
             {
@@ -44,7 +45,7 @@ namespace System.Xml.Xsl.Xslt
                 _scanner = null;
 #endif
             }
-            return result;
+            return result!;
         }
 
         /*
@@ -54,10 +55,10 @@ namespace System.Xml.Xsl.Xslt
         {
             QilNode opnd = ParseLocationPathPattern();
 
-            while (_scanner.Kind == LexKind.Union)
+            while (_scanner!.Kind == LexKind.Union)
             {
                 _scanner.NextLex();
-                opnd = _ptrnBuilder.Operator(XPathOperator.Union, opnd, ParseLocationPathPattern());
+                opnd = _ptrnBuilder!.Operator(XPathOperator.Union, opnd, ParseLocationPathPattern());
             }
             return opnd;
         }
@@ -69,11 +70,11 @@ namespace System.Xml.Xsl.Xslt
         {
             QilNode opnd;
 
-            switch (_scanner.Kind)
+            switch (_scanner!.Kind)
             {
                 case LexKind.Slash:
                     _scanner.NextLex();
-                    opnd = _ptrnBuilder.Axis(XPathAxis.Root, XPathNodeType.All, null, null);
+                    opnd = _ptrnBuilder!.Axis(XPathAxis.Root, XPathNodeType.All, null, null);
 
                     if (XPathParser.IsStep(_scanner.Kind))
                     {
@@ -82,7 +83,7 @@ namespace System.Xml.Xsl.Xslt
                     return opnd;
                 case LexKind.SlashSlash:
                     _scanner.NextLex();
-                    return _ptrnBuilder.JoinStep(
+                    return _ptrnBuilder!.JoinStep(
                         _ptrnBuilder.Axis(XPathAxis.Root, XPathNodeType.All, null, null),
                         _ptrnBuilder.JoinStep(
                             _ptrnBuilder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null),
@@ -97,11 +98,11 @@ namespace System.Xml.Xsl.Xslt
                         {
                             case LexKind.Slash:
                                 _scanner.NextLex();
-                                opnd = _ptrnBuilder.JoinStep(opnd, ParseRelativePathPattern());
+                                opnd = _ptrnBuilder!.JoinStep(opnd, ParseRelativePathPattern());
                                 break;
                             case LexKind.SlashSlash:
                                 _scanner.NextLex();
-                                opnd = _ptrnBuilder.JoinStep(opnd,
+                                opnd = _ptrnBuilder!.JoinStep(opnd,
                                     _ptrnBuilder.JoinStep(
                                         _ptrnBuilder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null),
                                         ParseRelativePathPattern()
@@ -122,7 +123,7 @@ namespace System.Xml.Xsl.Xslt
         */
         private QilNode ParseIdKeyPattern()
         {
-            Debug.Assert(_scanner.CanBeFunction);
+            Debug.Assert(_scanner!.CanBeFunction);
             Debug.Assert(_scanner.Prefix.Length == 0);
             Debug.Assert(_scanner.Name == "id" || _scanner.Name == "key");
             List<QilNode> args = new List<QilNode>(2);
@@ -132,7 +133,7 @@ namespace System.Xml.Xsl.Xslt
                 _scanner.NextLex();
                 _scanner.PassToken(LexKind.LParens);
                 _scanner.CheckToken(LexKind.String);
-                args.Add(_ptrnBuilder.String(_scanner.StringValue));
+                args.Add(_ptrnBuilder!.String(_scanner.StringValue));
                 _scanner.NextLex();
                 _scanner.PassToken(LexKind.RParens);
                 return _ptrnBuilder.Function("", "id", args);
@@ -142,7 +143,7 @@ namespace System.Xml.Xsl.Xslt
                 _scanner.NextLex();
                 _scanner.PassToken(LexKind.LParens);
                 _scanner.CheckToken(LexKind.String);
-                args.Add(_ptrnBuilder.String(_scanner.StringValue));
+                args.Add(_ptrnBuilder!.String(_scanner.StringValue));
                 _scanner.NextLex();
                 _scanner.PassToken(LexKind.Comma);
                 _scanner.CheckToken(LexKind.String);
@@ -165,19 +166,19 @@ namespace System.Xml.Xsl.Xslt
             {
                 if (LocalAppContextSwitches.LimitXPathComplexity)
                 {
-                    throw _scanner.CreateException(SR.Xslt_InputTooComplex);
+                    throw _scanner!.CreateException(SR.Xslt_InputTooComplex);
                 }
             }
             QilNode opnd = ParseStepPattern();
-            if (_scanner.Kind == LexKind.Slash)
+            if (_scanner!.Kind == LexKind.Slash)
             {
                 _scanner.NextLex();
-                opnd = _ptrnBuilder.JoinStep(opnd, ParseRelativePathPattern());
+                opnd = _ptrnBuilder!.JoinStep(opnd, ParseRelativePathPattern());
             }
             else if (_scanner.Kind == LexKind.SlashSlash)
             {
                 _scanner.NextLex();
-                opnd = _ptrnBuilder.JoinStep(opnd,
+                opnd = _ptrnBuilder!.JoinStep(opnd,
                     _ptrnBuilder.JoinStep(
                         _ptrnBuilder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null),
                         ParseRelativePathPattern()
@@ -197,7 +198,7 @@ namespace System.Xml.Xsl.Xslt
             QilNode opnd;
             XPathAxis axis;
 
-            switch (_scanner.Kind)
+            switch (_scanner!.Kind)
             {
                 case LexKind.Dot:
                 case LexKind.DotDot:
@@ -225,11 +226,11 @@ namespace System.Xml.Xsl.Xslt
             }
 
             XPathNodeType nodeType;
-            string nodePrefix, nodeName;
+            string? nodePrefix, nodeName;
             XPathParser.InternalParseNodeTest(_scanner, axis, out nodeType, out nodePrefix, out nodeName);
-            opnd = _ptrnBuilder.Axis(axis, nodeType, nodePrefix, nodeName);
+            opnd = _ptrnBuilder!.Axis(axis, nodeType, nodePrefix, nodeName);
 
-            XPathPatternBuilder xpathPatternBuilder = _ptrnBuilder as XPathPatternBuilder;
+            XPathPatternBuilder? xpathPatternBuilder = _ptrnBuilder as XPathPatternBuilder;
             if (xpathPatternBuilder != null)
             {
                 //for XPathPatternBuilder, get all predicates and then build them
@@ -256,9 +257,9 @@ namespace System.Xml.Xsl.Xslt
         */
         private QilNode ParsePredicate(QilNode context)
         {
-            Debug.Assert(_scanner.Kind == LexKind.LBracket);
+            Debug.Assert(_scanner!.Kind == LexKind.LBracket);
             _scanner.NextLex();
-            QilNode result = _predicateParser.Parse(_scanner, _ptrnBuilder.GetPredicateBuilder(context), LexKind.RBracket);
+            QilNode result = _predicateParser.Parse(_scanner, _ptrnBuilder!.GetPredicateBuilder(context), LexKind.RBracket);
             Debug.Assert(_scanner.Kind == LexKind.RBracket);
             _scanner.NextLex();
             return result;