-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Add nullable annotations to Http.Abstractions, Http.Features, Connections.Abstractions #18084
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
…ions.Abstractions
@@ -14,9 +15,9 @@ protected BaseHeaderParser(bool supportsMultipleValues) | |||
|
|||
protected abstract int GetParsedValueLength(StringSegment value, int startIndex, out T parsedValue); | |||
|
|||
public sealed override bool TryParseValue(StringSegment value, ref int index, out T parsedValue) | |||
public sealed override bool TryParseValue(StringSegment value, ref int index, [MaybeNullWhen(false)]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.
It looks like TryParseValue can return true even in cases where parsedValue is never set if SupportsMultipleValues is also true.
@@ -27,7 +28,7 @@ public bool SupportsMultipleValues | |||
// pointing to the next non-whitespace character after a delimiter. E.g. if called with a start index of 0 | |||
// for string "value , second_value", then after the call completes, 'index' must point to 's', i.e. the first | |||
// non-whitespace after the separator ','. | |||
public abstract bool TryParseValue(StringSegment value, ref int index, out T parsedValue); | |||
public abstract bool TryParseValue(StringSegment value, ref int index, [NotNullWhen(true)]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.
Shouldn't the type be marked nullable when using attributes like NotNullWhen?
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.
How do you plan to handle microsoft.extensions.activatorutilities.sources?
@@ -31,12 +31,12 @@ public class CacheControlHeaderValue | |||
// Cache-Control headers, only one instance of CacheControlHeaderValue is created (if all headers contain valid | |||
// values, otherwise we may have multiple strings containing the invalid values). | |||
private static readonly HttpHeaderParser<CacheControlHeaderValue> Parser | |||
= new GenericHeaderParser<CacheControlHeaderValue>(true, GetCacheControlLength); | |||
= new GenericHeaderParser<CacheControlHeaderValue>(true, GetCacheControlLength!); |
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.
Error CS8622 Nullability of reference types in type of parameter 'parsedValue' of 'int CacheControlHeaderValue.GetCacheControlLength(StringSegment input, int startIndex, out CacheControlHeaderValue? parsedValue)' doesn't match the target delegate 'GenericHeaderParser<CacheControlHeaderValue>.GetParsedValueLengthDelegate'. Microsoft.Net.Http.Headers D:\github\AspNetCore\src\Http\Headers\src\CacheControlHeaderValue.cs 34 Active
This seems like something the tooling should be able to handle?
internal delegate int GetParsedValueLengthDelegate(StringSegment value, int startIndex, [MaybeNull]out T parsedValue);
int GetCacheControlLength(StringSegment input, int startIndex, out CacheControlHeaderValue? parsedValue)
Or is the issue that T is unconstrained and could be a value type?
@@ -605,7 +604,7 @@ private static bool TrySetTimeSpan(NameValueHeaderValue nameValue, ref TimeSpan? | |||
{ | |||
Contract.Requires(nameValue != null); | |||
|
|||
if (nameValue.Value == null) | |||
if (nameValue!.Value == null) |
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.
The warning goes away if you remove Contract.Requires. These are redundant now and could be removed.
@@ -142,7 +143,7 @@ public StringSegment FileNameStar | |||
else | |||
{ | |||
string sizeString = value.GetValueOrDefault().ToString(CultureInfo.InvariantCulture); | |||
_parameters.Add(new NameValueHeaderValue(SizeString, sizeString)); | |||
_parameters!.Add(new NameValueHeaderValue(SizeString, sizeString)); |
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.
This is an actual bug. NameValueHeaderValue.Find
allows _parameters to be null. new ContentDispositionHeaderValue("foo") { Size = 1 }
throws
System.NullReferenceException : Object reference not set to an instance of an object.
Stack Trace:
ContentDispositionHeaderValue.set_Size(Nullable`1 value) line 146
The fix would be to use Parameters.Add
instead.
@@ -41,15 +41,15 @@ internal static void SetQuality(IList<NameValueHeaderValue> parameters, double? | |||
} | |||
else | |||
{ | |||
parameters.Add(new NameValueHeaderValue(QualityName, qualityString)); | |||
parameters!.Add(new NameValueHeaderValue(QualityName, qualityString)); |
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.
Same issue with Contract.Requires.
@@ -166,7 +167,7 @@ public virtual string ToString(object value) | |||
{ | |||
Contract.Requires(value != null); | |||
|
|||
return value.ToString(); | |||
return value!.ToString()!; |
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.
Same issue with Contract.Requires.
@@ -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.
GetQuality is wrong in this case, it works just fine if parameters is null, the Contract.Requires can be removed and paramters can be marked as nullable. There's no point in allocating an empty Paramaters collection just to search it for a property we know isn't there.
|
||
if (nameValueLength == 0) | ||
{ | ||
// There may be a trailing ';' | ||
return current - startIndex; | ||
} | ||
|
||
nameValueCollection.Add(parameter); | ||
nameValueCollection!.Add(parameter!); |
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.
Same Contract.Requires issue.
@@ -121,7 +121,7 @@ public override int GetHashCode() | |||
return 0; | |||
} | |||
|
|||
rangeCollection.Add(range); | |||
rangeCollection!.Add(range!); |
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.
Contract.Requires
@@ -14,9 +15,9 @@ protected BaseHeaderParser(bool supportsMultipleValues) | |||
|
|||
protected abstract int GetParsedValueLength(StringSegment value, int startIndex, out T parsedValue); | |||
|
|||
public sealed override bool TryParseValue(StringSegment value, ref int index, out T parsedValue) | |||
public sealed override bool TryParseValue(StringSegment value, ref int index, [MaybeNullWhen(false)]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.
public sealed override bool TryParseValue(StringSegment value, ref int index, [MaybeNullWhen(false)]out T parsedValue) | |
public sealed override bool TryParseValue(StringSegment value, ref int index, [MaybeNullWhen(false)] out T parsedValue) |
nit: I prefer a space here, though I'm willing to be overruled
API review YO |
Sounds like there are some build issues with using nullable annotations here. @JamesNK you can check in with @dotnet/aspnet-build and see if we can figure this out? |
/azp run |
Pull request contains merge conflicts. |
That's just what @JamesNK said in Triage ;). |
No immediate plans to look at this. Can re-open when I have time in the future. |
Addresses #5680
Annotations on projects at the bottom of the dependency tree. Because I haven't converted the tests there may be some types that are not null but should be. Should discover those as more projects are annotated.