Skip to content

Commit f37fa30

Browse files
pranavkmJamesNK
andauthored
Add nullable annotations to Http.Abstractions, Http.Features, Connections.Abstractions (#22337)
* Add nullable annotations to Http.Abstractions, Http.Features, Connections.Abstractions Co-authored-by: James Newton-King <[email protected]>
1 parent 8e4dadc commit f37fa30

File tree

123 files changed

+1060
-1050
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+1060
-1050
lines changed

src/Http/Headers/ref/Microsoft.Net.Http.Headers.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<Project Sdk="Microsoft.NET.Sdk">
33
<PropertyGroup>
44
<TargetFrameworks>$(DefaultNetCoreTargetFramework)</TargetFrameworks>
5+
<Nullable>annotations</Nullable>
56
</PropertyGroup>
67
<ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
78
<Compile Include="Microsoft.Net.Http.Headers.netcoreapp.cs" />

src/Http/Headers/ref/Microsoft.Net.Http.Headers.netcoreapp.cs

Lines changed: 57 additions & 57 deletions
Large diffs are not rendered by default.

src/Http/Headers/src/BaseHeaderParser.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System.Diagnostics.CodeAnalysis;
45
using Microsoft.Extensions.Primitives;
56

67
namespace Microsoft.Net.Http.Headers
@@ -12,11 +13,11 @@ protected BaseHeaderParser(bool supportsMultipleValues)
1213
{
1314
}
1415

15-
protected abstract int GetParsedValueLength(StringSegment value, int startIndex, out T parsedValue);
16+
protected abstract int GetParsedValueLength(StringSegment value, int startIndex, [MaybeNull] out T parsedValue);
1617

17-
public sealed override bool TryParseValue(StringSegment value, ref int index, out T parsedValue)
18+
public sealed override bool TryParseValue(StringSegment value, ref int index, [MaybeNull] out T parsedValue)
1819
{
19-
parsedValue = default(T);
20+
parsedValue = default;
2021

2122
// If multiple values are supported (i.e. list of values), then accept an empty string: The header may
2223
// be added multiple times to the request/response message. E.g.

src/Http/Headers/src/CacheControlHeaderValue.cs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Diagnostics.CodeAnalysis;
67
using System.Diagnostics.Contracts;
78
using System.Globalization;
89
using System.Text;
@@ -31,12 +32,12 @@ public class CacheControlHeaderValue
3132
// Cache-Control headers, only one instance of CacheControlHeaderValue is created (if all headers contain valid
3233
// values, otherwise we may have multiple strings containing the invalid values).
3334
private static readonly HttpHeaderParser<CacheControlHeaderValue> Parser
34-
= new GenericHeaderParser<CacheControlHeaderValue>(true, GetCacheControlLength);
35+
= new GenericHeaderParser<CacheControlHeaderValue>(true, GetCacheControlLength!);
3536

3637
private static readonly Action<StringSegment> CheckIsValidTokenAction = CheckIsValidToken;
3738

3839
private bool _noCache;
39-
private ICollection<StringSegment> _noCacheHeaders;
40+
private ICollection<StringSegment>? _noCacheHeaders;
4041
private bool _noStore;
4142
private TimeSpan? _maxAge;
4243
private TimeSpan? _sharedMaxAge;
@@ -47,10 +48,10 @@ private static readonly HttpHeaderParser<CacheControlHeaderValue> Parser
4748
private bool _onlyIfCached;
4849
private bool _public;
4950
private bool _private;
50-
private ICollection<StringSegment> _privateHeaders;
51+
private ICollection<StringSegment>? _privateHeaders;
5152
private bool _mustRevalidate;
5253
private bool _proxyRevalidate;
53-
private IList<NameValueHeaderValue> _extensions;
54+
private IList<NameValueHeaderValue>? _extensions;
5455

5556
public CacheControlHeaderValue()
5657
{
@@ -240,7 +241,7 @@ public override string ToString()
240241
return sb.ToString();
241242
}
242243

243-
public override bool Equals(object obj)
244+
public override bool Equals(object? obj)
244245
{
245246
var other = obj as CacheControlHeaderValue;
246247

@@ -325,7 +326,7 @@ public override int GetHashCode()
325326

326327
public static CacheControlHeaderValue Parse(StringSegment input)
327328
{
328-
int index = 0;
329+
var index = 0;
329330
// Cache-Control is unusual because there are no required values so the parser will succeed for an empty string, but still return null.
330331
var result = Parser.ParseValue(input, ref index);
331332
if (result == null)
@@ -335,9 +336,9 @@ public static CacheControlHeaderValue Parse(StringSegment input)
335336
return result;
336337
}
337338

338-
public static bool TryParse(StringSegment input, out CacheControlHeaderValue parsedValue)
339+
public static bool TryParse(StringSegment input, [NotNullWhen(true)] out CacheControlHeaderValue? parsedValue)
339340
{
340-
int index = 0;
341+
var index = 0;
341342
// Cache-Control is unusual because there are no required values so the parser will succeed for an empty string, but still return null.
342343
if (Parser.TryParseValue(input, ref index, out parsedValue) && parsedValue != null)
343344
{
@@ -347,7 +348,7 @@ public static bool TryParse(StringSegment input, out CacheControlHeaderValue par
347348
return false;
348349
}
349350

350-
private static int GetCacheControlLength(StringSegment input, int startIndex, out CacheControlHeaderValue parsedValue)
351+
private static int GetCacheControlLength(StringSegment input, int startIndex, out CacheControlHeaderValue? parsedValue)
351352
{
352353
Contract.Requires(startIndex >= 0);
353354

@@ -361,16 +362,18 @@ private static int GetCacheControlLength(StringSegment input, int startIndex, ou
361362
// Cache-Control header consists of a list of name/value pairs, where the value is optional. So use an
362363
// instance of NameValueHeaderParser to parse the string.
363364
var current = startIndex;
364-
NameValueHeaderValue nameValue = null;
365365
var nameValueList = new List<NameValueHeaderValue>();
366366
while (current < input.Length)
367367
{
368-
if (!NameValueHeaderValue.MultipleValueParser.TryParseValue(input, ref current, out nameValue))
368+
if (!NameValueHeaderValue.MultipleValueParser.TryParseValue(input, ref current, out var nameValue))
369369
{
370370
return 0;
371371
}
372372

373-
nameValueList.Add(nameValue);
373+
if (nameValue != null)
374+
{
375+
nameValueList.Add(nameValue);
376+
}
374377
}
375378

376379
// If we get here, we were able to successfully parse the string as list of name/value pairs. Now analyze
@@ -539,10 +542,8 @@ private static bool TrySetTokenOnlyValue(NameValueHeaderValue nameValue, ref boo
539542
private static bool TrySetOptionalTokenList(
540543
NameValueHeaderValue nameValue,
541544
ref bool boolField,
542-
ref ICollection<StringSegment> destination)
545+
ref ICollection<StringSegment>? destination)
543546
{
544-
Contract.Requires(nameValue != null);
545-
546547
if (nameValue.Value == null)
547548
{
548549
boolField = true;
@@ -603,8 +604,6 @@ private static bool TrySetOptionalTokenList(
603604

604605
private static bool TrySetTimeSpan(NameValueHeaderValue nameValue, ref TimeSpan? timeSpan)
605606
{
606-
Contract.Requires(nameValue != null);
607-
608607
if (nameValue.Value == null)
609608
{
610609
return false;

src/Http/Headers/src/ContentDispositionHeaderValue.cs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Buffers;
66
using System.Collections.Generic;
7+
using System.Diagnostics.CodeAnalysis;
78
using System.Diagnostics.Contracts;
89
using System.Globalization;
910
using System.Linq;
@@ -26,10 +27,10 @@ public class ContentDispositionHeaderValue
2627
private static readonly char[] SingleQuote = new char[] { '\'' };
2728

2829
private static readonly HttpHeaderParser<ContentDispositionHeaderValue> Parser
29-
= new GenericHeaderParser<ContentDispositionHeaderValue>(false, GetDispositionTypeLength);
30+
= new GenericHeaderParser<ContentDispositionHeaderValue>(false, GetDispositionTypeLength!);
3031

3132
// Use list instead of dictionary since we may have multiple parameters with the same name.
32-
private ObjectCollection<NameValueHeaderValue> _parameters;
33+
private ObjectCollection<NameValueHeaderValue>? _parameters;
3334
private StringSegment _dispositionType;
3435

3536
private ContentDispositionHeaderValue()
@@ -109,11 +110,10 @@ public long? Size
109110
get
110111
{
111112
var sizeParameter = NameValueHeaderValue.Find(_parameters, SizeString);
112-
long value;
113113
if (sizeParameter != null)
114114
{
115115
var sizeString = sizeParameter.Value;
116-
if (HeaderUtilities.TryParseNonNegativeInt64(sizeString, out value))
116+
if (HeaderUtilities.TryParseNonNegativeInt64(sizeString, out var value))
117117
{
118118
return value;
119119
}
@@ -128,7 +128,7 @@ public long? Size
128128
// Remove parameter
129129
if (sizeParameter != null)
130130
{
131-
_parameters.Remove(sizeParameter);
131+
_parameters!.Remove(sizeParameter);
132132
}
133133
}
134134
else if (value < 0)
@@ -141,8 +141,8 @@ public long? Size
141141
}
142142
else
143143
{
144-
string sizeString = value.GetValueOrDefault().ToString(CultureInfo.InvariantCulture);
145-
_parameters.Add(new NameValueHeaderValue(SizeString, sizeString));
144+
var sizeString = value.GetValueOrDefault().ToString(CultureInfo.InvariantCulture);
145+
Parameters.Add(new NameValueHeaderValue(SizeString, sizeString));
146146
}
147147
}
148148
}
@@ -180,7 +180,7 @@ public override string ToString()
180180
return _dispositionType + NameValueHeaderValue.ToString(_parameters, ';', true);
181181
}
182182

183-
public override bool Equals(object obj)
183+
public override bool Equals(object? obj)
184184
{
185185
var other = obj as ContentDispositionHeaderValue;
186186

@@ -202,16 +202,16 @@ public override int GetHashCode()
202202
public static ContentDispositionHeaderValue Parse(StringSegment input)
203203
{
204204
var index = 0;
205-
return Parser.ParseValue(input, ref index);
205+
return Parser.ParseValue(input, ref index)!;
206206
}
207207

208-
public static bool TryParse(StringSegment input, out ContentDispositionHeaderValue parsedValue)
208+
public static bool TryParse(StringSegment input, [NotNullWhen(true)] out ContentDispositionHeaderValue? parsedValue)
209209
{
210210
var index = 0;
211-
return Parser.TryParseValue(input, ref index, out parsedValue);
211+
return Parser.TryParseValue(input, ref index, out parsedValue!);
212212
}
213213

214-
private static int GetDispositionTypeLength(StringSegment input, int startIndex, out ContentDispositionHeaderValue parsedValue)
214+
private static int GetDispositionTypeLength(StringSegment input, int startIndex, out ContentDispositionHeaderValue? parsedValue)
215215
{
216216
Contract.Requires(startIndex >= 0);
217217

@@ -253,7 +253,7 @@ private static int GetDispositionTypeLength(StringSegment input, int startIndex,
253253

254254
private static int GetDispositionTypeExpressionLength(StringSegment input, int startIndex, out StringSegment dispositionType)
255255
{
256-
Contract.Requires((input != null) && (input.Length > 0) && (startIndex < input.Length));
256+
Contract.Requires((input.Length > 0) && (startIndex < input.Length));
257257

258258
// This method just parses the disposition type string, it does not parse parameters.
259259
dispositionType = null;
@@ -318,7 +318,7 @@ private void SetDate(string parameter, DateTimeOffset? date)
318318
// Remove parameter
319319
if (dateParameter != null)
320320
{
321-
_parameters.Remove(dateParameter);
321+
_parameters!.Remove(dateParameter);
322322
}
323323
}
324324
else
@@ -343,7 +343,7 @@ private StringSegment GetName(string parameter)
343343
var nameParameter = NameValueHeaderValue.Find(_parameters, parameter);
344344
if (nameParameter != null)
345345
{
346-
string result;
346+
string? result;
347347
// filename*=utf-8'lang'%7FMyString
348348
if (parameter.EndsWith("*", StringComparison.Ordinal))
349349
{
@@ -375,7 +375,7 @@ private void SetName(StringSegment parameter, StringSegment value)
375375
// Remove parameter
376376
if (nameParameter != null)
377377
{
378-
_parameters.Remove(nameParameter);
378+
_parameters!.Remove(nameParameter);
379379
}
380380
}
381381
else
@@ -497,7 +497,7 @@ private unsafe string EncodeMime(StringSegment input)
497497
}
498498

499499
// Attempt to decode MIME encoded strings
500-
private bool TryDecodeMime(StringSegment input, out string output)
500+
private bool TryDecodeMime(StringSegment input, [NotNullWhen(true)] out string? output)
501501
{
502502
Contract.Assert(input != null);
503503

@@ -582,7 +582,7 @@ private static void HexEscape(StringBuilder builder, char c)
582582

583583
// Attempt to decode using RFC 5987 encoding.
584584
// encoding'language'my%20string
585-
private bool TryDecode5987(StringSegment input, out string output)
585+
private bool TryDecode5987(StringSegment input, [NotNullWhen(true)] out string? output)
586586
{
587587
output = null;
588588

@@ -593,7 +593,7 @@ private bool TryDecode5987(StringSegment input, out string output)
593593
}
594594

595595
var decoded = new StringBuilder();
596-
byte[] unescapedBytes = null;
596+
byte[]? unescapedBytes = null;
597597
try
598598
{
599599
var encoding = Encoding.GetEncoding(parts[0].ToString());

src/Http/Headers/src/ContentRangeHeaderValue.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Diagnostics.CodeAnalysis;
56
using System.Diagnostics.Contracts;
67
using System.Globalization;
78
using System.Text;
@@ -12,7 +13,7 @@ namespace Microsoft.Net.Http.Headers
1213
public class ContentRangeHeaderValue
1314
{
1415
private static readonly HttpHeaderParser<ContentRangeHeaderValue> Parser
15-
= new GenericHeaderParser<ContentRangeHeaderValue>(false, GetContentRangeLength);
16+
= new GenericHeaderParser<ContentRangeHeaderValue>(false, GetContentRangeLength!);
1617

1718
private StringSegment _unit;
1819
private long? _from;
@@ -113,7 +114,7 @@ public long? Length
113114
get { return _from != null; }
114115
}
115116

116-
public override bool Equals(object obj)
117+
public override bool Equals(object? obj)
117118
{
118119
var other = obj as ContentRangeHeaderValue;
119120

@@ -176,16 +177,16 @@ public override string ToString()
176177
public static ContentRangeHeaderValue Parse(StringSegment input)
177178
{
178179
var index = 0;
179-
return Parser.ParseValue(input, ref index);
180+
return Parser.ParseValue(input, ref index)!;
180181
}
181182

182-
public static bool TryParse(StringSegment input, out ContentRangeHeaderValue parsedValue)
183+
public static bool TryParse(StringSegment input, [NotNullWhen(true)] out ContentRangeHeaderValue parsedValue)
183184
{
184185
var index = 0;
185-
return Parser.TryParseValue(input, ref index, out parsedValue);
186+
return Parser.TryParseValue(input, ref index, out parsedValue!);
186187
}
187188

188-
private static int GetContentRangeLength(StringSegment input, int startIndex, out ContentRangeHeaderValue parsedValue)
189+
private static int GetContentRangeLength(StringSegment input, int startIndex, out ContentRangeHeaderValue? parsedValue)
189190
{
190191
Contract.Requires(startIndex >= 0);
191192

@@ -351,7 +352,7 @@ private static bool TryCreateContentRange(
351352
int toLength,
352353
int lengthStartIndex,
353354
int lengthLength,
354-
out ContentRangeHeaderValue parsedValue)
355+
[NotNullWhen(true)]out ContentRangeHeaderValue? parsedValue)
355356
{
356357
parsedValue = null;
357358

src/Http/Headers/src/CookieHeaderParser.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ internal CookieHeaderParser(bool supportsMultipleValues)
1313
{
1414
}
1515

16-
public override bool TryParseValue(StringSegment value, ref int index, out CookieHeaderValue parsedValue)
16+
public override bool TryParseValue(StringSegment value, ref int index, out CookieHeaderValue? parsedValue)
1717
{
1818
parsedValue = null;
1919

@@ -43,8 +43,7 @@ public override bool TryParseValue(StringSegment value, ref int index, out Cooki
4343
return SupportsMultipleValues;
4444
}
4545

46-
CookieHeaderValue result = null;
47-
if (!CookieHeaderValue.TryGetCookieLength(value, ref current, out result))
46+
if (!CookieHeaderValue.TryGetCookieLength(value, ref current, out var result))
4847
{
4948
return false;
5049
}
@@ -64,7 +63,6 @@ public override bool TryParseValue(StringSegment value, ref int index, out Cooki
6463

6564
private static int GetNextNonEmptyOrWhitespaceIndex(StringSegment input, int startIndex, bool skipEmptyValues, out bool separatorFound)
6665
{
67-
Contract.Requires(input != null);
6866
Contract.Requires(startIndex <= input.Length); // it's OK if index == value.Length.
6967

7068
separatorFound = false;

0 commit comments

Comments
 (0)