Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port nullability annotations to System.Xml.ReaderWriter contract #41083

Merged
merged 5 commits into from
Aug 27, 2020

Conversation

jozkee
Copy link
Member

@jozkee jozkee commented Aug 20, 2020

Contributes to #2339

@jozkee jozkee added this to the 5.0.0 milestone Aug 20, 2020
@jozkee jozkee requested review from krwq, buyaa-n and a team August 20, 2020 10:32
@jozkee jozkee self-assigned this Aug 20, 2020
@ghost
Copy link

ghost commented Aug 20, 2020

Tagging subscribers to this area: @buyaa-n, @krwq
See info in area-owners.md if you want to be subscribed.

@eerhardt
Copy link
Member

    string System.Xml.IXmlNamespaceResolver.LookupNamespace(string prefix) { throw null; }

Should this return string? ? The non-interface implementation method can return null above.


Refers to: src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs:1073 in a2a0ead. [](commit_id = a2a0ead2ac98db85b3d8bcb5de769dafdc7ca897, deletion_comment = False)

@eerhardt
Copy link
Member

    public virtual bool IsStartElement(string localname, string ns) { throw null; }

Should ns be string? ns ? I believe this allows for null.


Refers to: src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs:825 in a2a0ead. [](commit_id = a2a0ead2ac98db85b3d8bcb5de769dafdc7ca897, deletion_comment = False)

@eerhardt
Copy link
Member

    public void WriteAttributeString(string? prefix, string localName, string? ns, string? value) { }

How come this overload has string? value, but the 2 above it have string value?


Refers to: src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs:1249 in a2a0ead. [](commit_id = a2a0ead2ac98db85b3d8bcb5de769dafdc7ca897, deletion_comment = False)

public virtual string SetAttribute(string localName, string namespaceURI, string value) { throw null; }
public virtual System.Xml.XmlAttribute SetAttributeNode(string localName, string namespaceURI) { throw null; }
public virtual string SetAttribute(string localName, string? namespaceURI, string value) { throw null; }
public virtual System.Xml.XmlAttribute SetAttributeNode(string localName, string? namespaceURI) { throw null; }
public virtual System.Xml.XmlAttribute SetAttributeNode(System.Xml.XmlAttribute newAttr) { throw null; }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per documentation:

If the attribute replaces an existing attribute with the same name, the old XmlAttribute is returned; otherwise, null is returned.

Suggested change
public virtual System.Xml.XmlAttribute SetAttributeNode(System.Xml.XmlAttribute newAttr) { throw null; }
public virtual System.Xml.XmlAttribute? SetAttributeNode(System.Xml.XmlAttribute newAttr) { throw null; }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe this actually returns null - looking at the implementation it returns old node if it already exists and new node if it doesn't

Copy link
Member Author

@jozkee jozkee Aug 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it because is virtual and someone could override it to return null; looking at "find all references" in VS, we don't even dereference the method's return value so it doesn't really affect libraries code if the method returns null or not.

If you feels like is pointless to make it nullable I can undo this change.

public virtual System.Xml.XmlText CreateTextNode(string? text) { throw null; }
public virtual System.Xml.XmlWhitespace CreateWhitespace(string? text) { throw null; }
public virtual System.Xml.XmlDeclaration CreateXmlDeclaration(string version, string? encoding, string? standalone) { throw null; }
public virtual System.Xml.XmlElement? GetElementById(string elementId) { throw null; }
public virtual System.Xml.XmlNodeList GetElementsByTagName(string name) { throw null; }
public virtual System.Xml.XmlNodeList GetElementsByTagName(string localName, string namespaceURI) { throw null; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string namespaceURI is correct here as it will throw but I think this is incidental and due to bug in the code, I think we should ideally fix the bug and change annotation (not in this PR)

[System.Diagnostics.DebuggerStepThroughAttribute]
public virtual System.Threading.Tasks.Task<object> ReadContentAsAsync(System.Type returnType, System.Xml.IXmlNamespaceResolver namespaceResolver) { throw null; }
public virtual System.Threading.Tasks.Task<object> ReadContentAsAsync(System.Type returnType, System.Xml.IXmlNamespaceResolver? namespaceResolver) { throw null; }
Copy link
Member

@krwq krwq Aug 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most likely couple of namespaceResolvers below should be nullable, i.e.:
ReadElementContentAs, ReadElementContentAsAsync

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems it will throw InvalidOperationException in some cases when this is null

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's why I didn't change those signatures on #41079

Copy link
Member

@krwq krwq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM after fixing/resolving comments

@krwq
Copy link
Member

krwq commented Aug 27, 2020

    public virtual bool IsStartElement(string localname, string ns) { throw null; }

Should ns be string? ns ? I believe this allows for null.

Refers to: src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs:825 in a2a0ead. [](commit_id = a2a0ead, deletion_comment = False)

I think this will always return false if you pass null. In all other places null implies string.Empty - I think it might be better to leave it as non-null

@eerhardt
Copy link
Member

I think this will always return false if you pass null. In all other places null implies string.Empty - I think it might be better to leave it as non-null

You're right. I looked at the implementation and this appears broken to me. We should leave it as you have it now, and I opened #41461 for us to consider to make it nullable in the future.

@jozkee jozkee merged commit 031368a into dotnet:master Aug 27, 2020
@jozkee jozkee deleted the nullability_7 branch August 27, 2020 20:04
carlossanlop pushed a commit to carlossanlop/runtime that referenced this pull request Aug 28, 2020
…net#41083)

* Port nullability annotations to System.Xml.ReaderWriter contract assembly

* Port annotations of recently updated members in Xml/Serialization

* Fix anontations on XmlElement discovered while updating System.Data.Common Xml related annotations

* Fix Xml related annotations on System.Data.Common

* address feedback

Co-authored-by: Krzysztof Wicher <kwicher@microsoft.com>
@ghost ghost locked as resolved and limited conversation to collaborators Dec 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants