Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Annotate System.ComponentModel.Primitives for nullable #41185

Merged
merged 4 commits into from
Sep 24, 2019

Conversation

buyaa-n
Copy link

@buyaa-n buyaa-n commented Sep 18, 2019

Contributes to #40623
cc: @dotnet/nullablefc

{
ISite s = _site;
ISite? s = _site;
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 think ToString could be returning null here. You should be able to change return type back to string

Copy link
Author

Choose a reason for hiding this comment

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

I agree, just because of Type.FullName return nullable, not sure if i should suppress that and make it non null

Copy link
Member

Choose a reason for hiding this comment

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

GetType().FullName can definitely return null if the type has GenericTypeParameters: https://source.dot.net/#System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs,1491 -- however since this type is not generic it will never be null, so I think we should just use ! on the return.

Copy link
Author

Choose a reason for hiding this comment

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

Will update thanks!

@@ -39,7 +39,7 @@ public partial class CategoryAttribute : System.Attribute
public static System.ComponentModel.CategoryAttribute Layout { get { throw null; } }
public static System.ComponentModel.CategoryAttribute Mouse { get { throw null; } }
public static System.ComponentModel.CategoryAttribute WindowStyle { get { throw null; } }
public override bool Equals(object obj) { throw null; }
public override bool Equals(object? obj) { throw null; }
public override int GetHashCode() { throw null; }
protected virtual string GetLocalizedString(string value) { 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.

GetLocalizedString should return a nullable string.

Copy link
Author

Choose a reason for hiding this comment

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

I was thinking same at first, but then noticed the only method called here returning not null even suppresed possible null return, maybe that one annotated incorrectly? From SR.sc:

internal static string GetResourceString(string resourceKey, string? defaultString = null)
{
    if (UsingResourceKeys())
    {
        return defaultString ?? resourceKey;
    }

    string? resourceString = null;
    try
    {
        resourceString = ResourceManager.GetString(resourceKey);
    }
    catch (MissingManifestResourceException) { }

    if (defaultString != null && resourceKey.Equals(resourceString))
    {
        return defaultString;
    }

    return resourceString!; // only null if missing resources
}

Copy link
Member

Choose a reason for hiding this comment

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

That's the base implementation, but it's virtual, so derived types could be overriding it and returning null. Since it's protected, really the only code that might call this method is this class (technically a derived one could as well, but that's unlikely), and it's already checking to see if the method returns null, which both suggests that was part of the design and means that there's little harm in allowing null.

Copy link
Author

Choose a reason for hiding this comment

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

oh I see, good to know

protected virtual object GetService(System.Type service) { throw null; }
public override string ToString() { throw null; }
protected virtual object? GetService(System.Type service) { throw null; }
public override string? ToString() { 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'm curious why you made this nullable. Do you know of a case where a Component-derived type returns null from ToString?

Copy link
Author

Choose a reason for hiding this comment

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

Just because of Type.FullName, got feedback from Maryam and Santi about that #41185 (comment) and made it not nullable, but seems I didn't pushed that change yet

void Add(System.ComponentModel.IComponent component, string name);
void Remove(System.ComponentModel.IComponent component);
void Add(System.ComponentModel.IComponent? component);
void Add(System.ComponentModel.IComponent? component, string name);
Copy link
Member

Choose a reason for hiding this comment

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

name should be a nullable string

{
if (obj == this)
{
return true;
}

BrowsableAttribute other = obj as BrowsableAttribute;
BrowsableAttribute? other = obj as BrowsableAttribute;
return other?.Browsable == Browsable;
Copy link
Member

Choose a reason for hiding this comment

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

Nit: I suggest we simplify this to:

public override bool Equals(object? obj) =>
    obj is BrowsableAttribute other && other.Browsable == Browsable;

{
if (obj == this)
{
return true;
}

CategoryAttribute other = obj as CategoryAttribute;
CategoryAttribute? other = obj as CategoryAttribute;
return other != null && Category == other.Category;
Copy link
Member

Choose a reason for hiding this comment

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

Ditto

{
if (obj == this)
{
return true;
}

DescriptionAttribute other = obj as DescriptionAttribute;
DescriptionAttribute? other = obj as DescriptionAttribute;
return other != null && other.Description == Description;
Copy link
Member

Choose a reason for hiding this comment

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

Same as earlier cases.

{
if (obj == this)
{
return true;
}

DesignOnlyAttribute other = obj as DesignOnlyAttribute;
DesignOnlyAttribute? other = obj as DesignOnlyAttribute;
return other?.IsDesignOnly == IsDesignOnly;
Copy link
Member

Choose a reason for hiding this comment

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

Ditto; I'll stop commenting on these.

@buyaa-n
Copy link
Author

buyaa-n commented Sep 20, 2019

@stephentoub addressed feedback please re review

@buyaa-n
Copy link
Author

buyaa-n commented Sep 24, 2019

As all comments addressed and not receiving more am gonna merge this PR

@buyaa-n buyaa-n merged commit da147ec into dotnet:master Sep 24, 2019
@buyaa-n buyaa-n deleted the componentmodel_primitives_nullable branch November 1, 2019 21:04
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
…#41185)

* Annotate System.ComponentModel.Primitives for nullable

Commit migrated from dotnet/corefx@da147ec
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.

4 participants