// 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;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
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)
{
{
throw new InvalidOperationException(SR.Xdom_Node_Modify_ReadOnly);
}
- DeleteToFollowingSibling(node.NextSibling, end);
+ DeleteToFollowingSibling(node.NextSibling!, end);
}
goto case XmlNodeType.Element;
case XmlNodeType.Element:
{
get
{
- XmlAttribute attribute = _source as XmlAttribute;
- if (attribute != null
+ if (_source is XmlAttribute attribute
&& attribute.IsNamespace)
{
return string.Empty;
{
get
{
- XmlAttribute attribute = _source as XmlAttribute;
- if (attribute != null
+ if (_source is XmlAttribute attribute
&& attribute.IsNamespace)
{
return string.Empty;
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;
}
}
{
get
{
- XmlElement element = _document.DocumentElement;
+ XmlElement? element = _document.DocumentElement;
if (element != null)
{
return element.InnerText;
{
CalibrateText();
- string value = _source.Value;
- XmlNode nextSibling = NextSibling(_source);
+ string? value = _source.Value;
+ XmlNode? nextSibling = NextSibling(_source);
if (nextSibling != null
&& nextSibling.IsText)
{
&& 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;
}
}
{
get
{
- XmlElement element = _source as XmlElement;
- if (element != null)
+ if (_source is XmlElement element)
{
return element.IsEmpty;
}
{
get
{
- XmlElement element = _source as XmlElement;
- if (element != null
+ if (_source is XmlElement element
&& element.HasAttributes)
{
XmlAttributeCollection attributes = element.Attributes;
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;
public override bool MoveToFirstAttribute()
{
- XmlElement element = _source as XmlElement;
- if (element != null
+ if (_source is XmlElement element
&& element.HasAttributes)
{
XmlAttributeCollection attributes = element.Attributes;
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))
{
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;
}
}
}
- XmlElement element = node as XmlElement;
+ XmlElement? element = node as XmlElement;
if (element != null)
{
string localName;
do
{
- XmlAttribute attribute = element.GetAttributeNode(localName, namespaceUri);
+ XmlAttribute? attribute = element.GetAttributeNode(localName, namespaceUri);
if (attribute != null)
{
return attribute.Value;
{
return false;
}
- XmlElement element = _source as XmlElement;
+ XmlElement? element = _source as XmlElement;
if (element != null)
{
string localName;
do
{
- XmlAttribute attribute = element.GetAttributeNode(localName, namespaceUri);
+ XmlAttribute? attribute = element.GetAttributeNode(localName, namespaceUri);
if (attribute != null)
{
_namespaceParent = (XmlElement)_source;
public override bool MoveToFirstNamespace(XPathNamespaceScope scope)
{
- XmlElement element = _source as XmlElement;
- if (element == null)
+ if (!(_source is XmlElement element))
{
return false;
}
}
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)
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))
}
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)
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);
public override bool MoveToNext()
{
- XmlNode sibling = NextSibling(_source);
+ XmlNode? sibling = NextSibling(_source);
if (sibling == null)
{
return false;
}
}
}
- XmlNode parent = ParentNode(sibling);
+ XmlNode? parent = ParentNode(sibling);
Debug.Assert(parent != null);
while (!IsValidChild(parent, sibling))
{
public override bool MoveToPrevious()
{
- XmlNode sibling = PreviousSibling(_source);
+ XmlNode? sibling = PreviousSibling(_source);
if (sibling == null)
{
return false;
sibling = TextStart(sibling);
}
}
- XmlNode parent = ParentNode(sibling);
+ XmlNode? parent = ParentNode(sibling);
Debug.Assert(parent != null);
while (!IsValidChild(parent, sibling))
{
{
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))
{
public override bool MoveToFirstChild()
{
- XmlNode child;
+ XmlNode? child;
switch (_source.NodeType)
{
case XmlNodeType.Element:
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)
{
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;
}
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;
public override bool MoveToId(string id)
{
- XmlElement element = _document.GetElementById(id);
+ XmlElement? element = _document.GetElementById(id);
if (element != null)
{
_source = element;
return false;
}
- XmlNode child = FirstChild(_source);
+ XmlNode? child = FirstChild(_source);
if (child != null)
{
do
return false;
}
- XmlNode child = FirstChild(_source);
+ XmlNode? child = FirstChild(_source);
if (child != null)
{
int mask = GetContentKindMask(type);
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)
{
pastFollowing = that._source;
}
- XmlNode following = _source;
+ XmlNode? following = _source;
if (following.NodeType == XmlNodeType.Attribute)
{
following = ((XmlAttribute)following).OwnerElement;
}
do
{
- XmlNode firstChild = following.FirstChild;
+ XmlNode? firstChild = following.FirstChild;
if (firstChild != null)
{
following = firstChild;
{
while (true)
{
- XmlNode nextSibling = following.NextSibling;
+ XmlNode? nextSibling = following.NextSibling;
if (nextSibling != null)
{
following = nextSibling;
}
else
{
- XmlNode parent = following.ParentNode;
+ XmlNode? parent = following.ParentNode;
if (parent != null)
{
following = parent;
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)
{
{
return false;
}
- XmlNode following = _source;
+ XmlNode? following = _source;
switch (following.NodeType)
{
case XmlNodeType.Attribute:
}
do
{
- XmlNode firstChild = following.FirstChild;
+ XmlNode? firstChild = following.FirstChild;
if (firstChild != null)
{
following = firstChild;
{
while (true)
{
- XmlNode nextSibling = following.NextSibling;
+ XmlNode? nextSibling = following.NextSibling;
if (nextSibling != null)
{
following = nextSibling;
}
else
{
- XmlNode parent = following.ParentNode;
+ XmlNode? parent = following.ParentNode;
if (parent != null)
{
following = parent;
public override bool MoveToNext(string localName, string namespaceUri)
{
- XmlNode sibling = NextSibling(_source);
+ XmlNode? sibling = NextSibling(_source);
if (sibling == null)
{
return false;
public override bool MoveToNext(XPathNodeType type)
{
- XmlNode sibling = NextSibling(_source);
+ XmlNode? sibling = NextSibling(_source);
if (sibling == null)
{
return false;
{
get
{
- XmlNode child;
+ XmlNode? child;
switch (_source.NodeType)
{
case XmlNodeType.Element:
public override bool IsSamePosition(XPathNavigator other)
{
- DocumentXPathNavigator that = other as DocumentXPathNavigator;
- if (that != null)
+ if (other is DocumentXPathNavigator that)
{
this.CalibrateText();
that.CalibrateText();
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);
}
public override bool CheckValidity(XmlSchemaSet schemas, ValidationEventHandler validationEventHandler)
{
- XmlDocument ownerDocument;
+ XmlDocument? ownerDocument;
if (_source.NodeType == XmlNodeType.Document)
{
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;
}
private static int GetDepth(XmlNode node)
{
int depth = 0;
- XmlNode owner = OwnerNode(node);
+ XmlNode? owner = OwnerNode(node);
while (owner != null)
{
depth++;
{
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;
}
//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)
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;
}
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)
{
return XmlNodeOrder.Before;
}
+ Debug.Assert(node2 != null);
parent2 = OwnerNode(node2);
}
else if (depth1 > depth2)
{
return XmlNodeOrder.After;
}
+ Debug.Assert(node1 != null);
parent1 = OwnerNode(node1);
}
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);
public override XmlWriter ReplaceRange(XPathNavigator lastSiblingToReplace)
{
- DocumentXPathNavigator that = lastSiblingToReplace as DocumentXPathNavigator;
- if (that == null)
+ if (!(lastSiblingToReplace is DocumentXPathNavigator that))
{
if (lastSiblingToReplace == null)
{
public override void DeleteRange(XPathNavigator lastSiblingToDelete)
{
- DocumentXPathNavigator that = lastSiblingToDelete as DocumentXPathNavigator;
- if (that == null)
+ if (!(lastSiblingToDelete is DocumentXPathNavigator that))
{
if (lastSiblingToDelete == null)
{
{
goto default;
}
- XmlNode parent = OwnerNode(attribute);
+ XmlNode? parent = OwnerNode(attribute);
DeleteAttribute(attribute, _attributeIndex);
if (parent != null)
{
{
throw new InvalidOperationException(SR.Xpn_BadPosition);
}
- XmlNode parent = OwnerNode(node);
+ XmlNode? parent = OwnerNode(node);
DeleteToFollowingSibling(node, end);
if (parent != null)
{
{
goto default;
}
- XmlNode parent = OwnerNode(attribute);
+ XmlNode? parent = OwnerNode(attribute);
DeleteAttribute(attribute, _attributeIndex);
if (parent != null)
{
private static void DeleteAttribute(XmlAttribute attribute, int index)
{
- XmlAttributeCollection attributes;
+ XmlAttributeCollection? attributes;
if (!CheckAttributePosition(attribute, out attributes, index)
&& !ResetAttributePosition(attribute, attributes, out index))
internal static void DeleteToFollowingSibling(XmlNode node, XmlNode end)
{
- XmlNode parent = node.ParentNode;
+ XmlNode? parent = node.ParentNode;
if (parent == null)
{
}
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);
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);
}
}
- 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)
{
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;
private void CalibrateText()
{
- XmlNode text = PreviousText(_source);
+ XmlNode? text = PreviousText(_source);
while (text != null)
{
ResetPosition(text);
}
}
- private XmlNode ParentNode(XmlNode node)
+ private XmlNode? ParentNode(XmlNode node)
{
- XmlNode parent = node.ParentNode;
+ XmlNode? parent = node.ParentNode;
if (!_document.HasEntityReferences)
{
return ParentNodeTail(parent);
}
- private XmlNode ParentNodeTail(XmlNode parent)
+ private XmlNode? ParentNodeTail(XmlNode? parent)
{
while (parent != null
&& parent.NodeType == XmlNodeType.EntityReference)
return parent;
}
- private XmlNode FirstChild(XmlNode node)
+ private XmlNode? FirstChild(XmlNode node)
{
- XmlNode child = node.FirstChild;
+ XmlNode? child = node.FirstChild;
if (!_document.HasEntityReferences)
{
return FirstChildTail(child);
}
- private XmlNode FirstChildTail(XmlNode child)
+ private XmlNode? FirstChildTail(XmlNode? child)
{
while (child != null
&& child.NodeType == XmlNodeType.EntityReference)
return child;
}
- private XmlNode NextSibling(XmlNode node)
+ private XmlNode? NextSibling(XmlNode node)
{
- XmlNode sibling = node.NextSibling;
+ XmlNode? sibling = node.NextSibling;
if (!_document.HasEntityReferences)
{
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)
return sibling;
}
- private XmlNode PreviousSibling(XmlNode node)
+ private XmlNode? PreviousSibling(XmlNode node)
{
- XmlNode sibling = node.PreviousSibling;
+ XmlNode? sibling = node.PreviousSibling;
if (!_document.HasEntityReferences)
{
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)
return sibling;
}
- private XmlNode PreviousText(XmlNode node)
+ private XmlNode? PreviousText(XmlNode node)
{
- XmlNode text = node.PreviousText;
+ XmlNode? text = node.PreviousText;
if (!_document.HasEntityReferences)
{
return PreviousTextTail(node, text);
}
- private XmlNode PreviousTextTail(XmlNode node, XmlNode text)
+ private XmlNode? PreviousTextTail(XmlNode node, XmlNode? text)
{
if (text != null)
{
{
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)
{
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;
}
{
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;
}
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;
}
}
throw new InvalidOperationException(SR.Xdom_Node_Modify_ReadOnly);
}
- DocumentXPathNavigator.DeleteToFollowingSibling(_start.NextSibling, _end);
+ DocumentXPathNavigator.DeleteToFollowingSibling(_start.NextSibling!, _end);
}
XmlNode fragment0 = _fragment[0];
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)
}
}
- internal virtual string? GetXPAttribute(string localName, string namespaceURI)
+ internal virtual string GetXPAttribute(string localName, string namespaceURI)
{
return string.Empty;
}
// 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;
// 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);
// 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
// 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;
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
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;
}
}
- 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));
}
}
}
- 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)
);
}
- 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);
/*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;
// 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;
}
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);
}
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);
{
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)
_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;
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;
}
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));
}
// 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;
[Serializable]
internal class XPathCompileException : XslLoadException
{
- public string queryString;
+ public string? queryString;
public int startChar;
public int endChar;
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)
}
}
- internal string MarkOutError()
+ internal string? MarkOutError()
{
if (queryString == null || queryString.Trim(' ').Length == 0)
{
internal override string FormatDetailedMessage()
{
string message = Message;
- string error = MarkOutError();
+ string? error = MarkOutError();
if (error != null && error.Length > 0)
{
// 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().
// 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
// 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;
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:
#endif
}
Debug.Assert(_posInfo.Count == 0, "PushPosInfo() and PopPosInfo() calls have been unbalanced");
- return result;
+ return result!;
}
#region Location paths and node tests
*/
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))
{
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),
{
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()
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);
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);
while (LexKind.LBracket == _scanner.Kind)
{
- opnd = _builder.Predicate(opnd, ParsePredicate(), IsReverseAxis(axis));
+ opnd = _builder!.Predicate(opnd, ParsePredicate(), IsReverseAxis(axis));
}
}
return opnd;
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;
}
);
}
- 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)
{
*/
private Node ParsePredicate()
{
- _scanner.PassToken(LexKind.LBracket);
+ _scanner!.PassToken(LexKind.LBracket);
Node opnd = ParseExpr();
_scanner.PassToken(LexKind.RBracket);
return opnd;
{
if (LocalAppContextSwitches.LimitXPathComplexity)
{
- throw _scanner.CreateException(SR.Xslt_InputTooComplex);
+ throw _scanner!.CreateException(SR.Xslt_InputTooComplex);
}
}
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
{
// 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;
*/
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)
// 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;
{
_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()
*/
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;
private bool IsPrimaryExpr()
{
return (
- _scanner.Kind == LexKind.String ||
+ _scanner!.Kind == LexKind.String ||
_scanner.Kind == LexKind.Number ||
_scanner.Kind == LexKind.Dollar ||
_scanner.Kind == LexKind.LParens ||
{
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:
_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;
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;
_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;
}
// 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;
}
// 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)
{
// 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);
// 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>
//------------------------------------------------------------------------------
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;
}
else
{
+ Debug.Assert(_prefix != null);
+ Debug.Assert(_name != null);
if (_prefix.Length != 0 || _name.Length > 3)
return false;
*
*/
+#nullable enable
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
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();
// 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;
using System.Xml.Schema;
using System.Xml.Xsl.Qil;
using System.Xml.Xsl.XPath;
+using System.Diagnostics.CodeAnalysis;
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)
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);
}
}
- 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
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 ||
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)
{
}
}
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);
private class Annotation
{
public double Priority;
- public QilLoop Parent;
+ public QilLoop? Parent;
}
public static void SetPriority(QilNode node, double priority)
node.Annotation = ann;
}
- private static QilLoop GetLastParent(QilNode node)
+ private static QilLoop? GetLastParent(QilNode node)
{
return ((Annotation)node.Annotation).Parent;
}
// 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;
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
{
_scanner = null;
#endif
}
- return result;
+ return result!;
}
/*
{
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;
}
{
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))
{
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),
{
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()
*/
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);
_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);
_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);
{
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()
QilNode opnd;
XPathAxis axis;
- switch (_scanner.Kind)
+ switch (_scanner!.Kind)
{
case LexKind.Dot:
case LexKind.DotDot:
}
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
*/
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;