-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Add nullable annotations to Http.Abstractions, Http.Features, Connections.Abstractions #22337
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
Conversation
I'll undo the MVC bits, but the rest of this should be good to go. |
7cf268c
to
7fc367a
Compare
…ions.Abstractions
7fc367a
to
ff2f78d
Compare
This is a continuation of #18084. Hopefully all of the initial comments listed there should be addressed. It'll be cool to get this in soon, since all of the middleware work is blocked on it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few things I noticed from reviewing public API changes.
} | ||
|
||
public static IList<EntityTagHeaderValue> ParseList(IList<string> inputs) | ||
public static IList<EntityTagHeaderValue> ParseList(IList<string>? inputs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ParseList.ParseList doesn't allow a null list be EntityTagHeaderValue does. Intended?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean TryParseList? I updated those to also allow nulls since the code that this calls is null tolerant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -13,7 +14,7 @@ internal CookieHeaderParser(bool supportsMultipleValues) | |||
{ | |||
} | |||
|
|||
public override bool TryParseValue(StringSegment value, ref int index, out CookieHeaderValue parsedValue) | |||
public override bool TryParseValue(StringSegment value, ref int index, [MaybeNull] out CookieHeaderValue? parsedValue) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need both [MaybeNull]
and ?
? Should this also use [NotNullWhen(true)]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing MaybeNull
would be the way to go. This can return a null value while returning true, so NotNullWhen
doesn't quite work.
|
||
public sealed override bool TryParseValue(StringSegment value, ref int index, out T parsedValue) | ||
public sealed override bool TryParseValue(StringSegment value, ref int index, [MaybeNull] out T parsedValue) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can [NotNullWhen(true)]
be applied here too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately not. The SupportsMultipleValues
pattern makes nullable annotations really awkward to use .
|
||
[return: MaybeNull] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this marked [return: MaybeNull]
? It looks like it throws if it's null. If you change this you can remove !
from some of the callsites.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BaseHeaderParser.TryParseValue
can return null while returning true when SupportsMultipleValue
is set. It would really have helped if the single-value parser and the multi-value parser where separate types so you could declare their behavior in code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we just throw from this method when it would otherwise return null? Do any of the callers actually handle null appropriately? It looks like most callers would blow up with a NullReferenceException.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some code paths actually handle this well: https://github.com/dotnet/aspnetcore/blob/master/src/Http/Headers/src/CacheControlHeaderValue.cs#L330-L334. Like I said, you really want to separate single and mullti-valued parsers for this to be expressed correctly, but that's well beyond the scope of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be too big a big change to have the callers that expect the return value could be null to call TryParseValue instead? I get not wanting to make this much bigger though. My browser is really struggling when I go to the files tab of this PR 😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing all the null-forgiviness from our src files is certainly desirable. But a) I'm too lazy b) fixing internal implementation, which mostly works well today, has marginal utility. Maybe somebody else would want to give this a go. 😸
🆙 📅 |
@@ -205,7 +206,7 @@ public IList<NameValueHeaderValue> Parameters | |||
/// </summary> | |||
public double? Quality | |||
{ | |||
get { return HeaderUtilities.GetQuality(_parameters); } | |||
get { return HeaderUtilities.GetQuality(Parameters); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't this _parameters to avoid having Parameters allocate if _parameters was null, and GetQuality was null tolerant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch. I missed addressing this from the original PR: https://github.com/dotnet/aspnetcore/pull/18084/files#r362617412
No description provided.