Skip to content

Commit cf1947b

Browse files
authored
feat: support C# 8 and nullable reference types (#245)
1 parent 8320e50 commit cf1947b

File tree

98 files changed

+665
-538
lines changed

Some content is hidden

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

98 files changed

+665
-538
lines changed

.editorconfig

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,32 +18,32 @@ indent_size = 2
1818
indent_size = 4
1919

2020
# Style I care about
21-
csharp_style_expression_bodied_constructors = false : error
22-
csharp_prefer_braces = true : error
23-
dotnet_sort_system_directives_first = true : error
21+
csharp_style_expression_bodied_constructors = false
22+
csharp_prefer_braces = true
23+
dotnet_sort_system_directives_first = true
2424

2525
# Stuff that is usually best
26-
csharp_style_inlined_variable_declaration = true : warning
27-
csharp_style_var_elsewhere = true : warning
28-
csharp_space_after_cast = true : warning
29-
csharp_style_pattern_matching_over_as_with_null_check = true : warning
30-
csharp_style_pattern_matching_over_is_with_cast_check = true : warning
31-
csharp_style_var_for_built_in_types = true : warning
32-
csharp_style_var_when_type_is_apparent = true : warning
33-
csharp_new_line_before_catch = true : warning
34-
csharp_new_line_before_else = true : warning
35-
csharp_new_line_before_finally = true : warning
36-
csharp_indent_case_contents = true : warning
26+
csharp_style_inlined_variable_declaration = true
27+
csharp_style_var_elsewhere = true
28+
csharp_space_after_cast = true
29+
csharp_style_pattern_matching_over_as_with_null_check = true
30+
csharp_style_pattern_matching_over_is_with_cast_check = true
31+
csharp_style_var_for_built_in_types = true
32+
csharp_style_var_when_type_is_apparent = true
33+
csharp_new_line_before_catch = true
34+
csharp_new_line_before_else = true
35+
csharp_new_line_before_finally = true
36+
csharp_indent_case_contents = true
3737
csharp_new_line_before_open_brace = all
38-
csharp_indent_switch_labels = true : warning
38+
csharp_indent_switch_labels = true
3939
csharp_indent_labels = one_less_than_current
40-
csharp_prefer_simple_default_expression = true : warning
40+
csharp_prefer_simple_default_expression = true
4141

4242
# Good defaults, but not always
43-
dotnet_style_object_initializer = true : suggestion
44-
csharp_style_expression_bodied_indexers = true : suggestion
45-
csharp_style_expression_bodied_accessors = true : suggestion
46-
csharp_style_throw_expression = true : suggestion
43+
dotnet_style_object_initializer = true
44+
csharp_style_expression_bodied_indexers = true
45+
csharp_style_expression_bodied_accessors = true
46+
csharp_style_throw_expression = true
4747

4848
# Naming styles
4949

CommandLineUtils.sln

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio 15
4-
VisualStudioVersion = 15.0.27130.2026
5-
MinimumVisualStudioVersion = 15.0.26124.0
3+
# Visual Studio 16
4+
VisualStudioVersion = 16.0.0.0
5+
MinimumVisualStudioVersion = 16.0.0.0
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{95D4B35E-0A21-4D64-8BAF-27DD6C019FC5}"
77
EndProject
88
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "McMaster.Extensions.CommandLineUtils", "src\CommandLineUtils\McMaster.Extensions.CommandLineUtils.csproj", "{CBCFAFF3-A3B1-4C41-B2D1-092BF7307A4E}"

Directory.Build.props

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@
2222
<EmbedUntrackedSources>true</EmbedUntrackedSources>
2323
<PackageIconUrl>https://natemcmaster.github.io/CommandLineUtils/logo.png</PackageIconUrl>
2424
<NoPackageAnalysis>true</NoPackageAnalysis>
25-
<LangVersion>7.2</LangVersion>
25+
<LangVersion>8.0</LangVersion>
26+
<Nullable>enable</Nullable>
27+
<!-- Some previews of .NET Core 3 don't have the rename yet -->
28+
<NullableContextOptions>enable</NullableContextOptions>
2629
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)src\StrongName.snk</AssemblyOriginatorKeyFile>
2730
<SignAssembly>true</SignAssembly>
2831
<AzureKeyVaultUrl>https://nmcmaster.vault.azure.net</AzureKeyVaultUrl>
@@ -31,7 +34,7 @@
3134
<CodeSignCertName>DigiCertCodeSign</CodeSignCertName>
3235

3336
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
34-
<GenerateFullPaths Condition="'$(VSCODE_CWD)' != ''">true</GenerateFullPaths>
37+
<GenerateFullPaths Condition="'$(TERM_PROGRAM)' == 'vscode'">true</GenerateFullPaths>
3538
<BaseIntermediateOutputPath>$(MSBuildThisFileDirectory).build\obj\$(MSBuildProjectName)\</BaseIntermediateOutputPath>
3639
<BaseOutputPath>$(MSBuildThisFileDirectory).build\bin\$(MSBuildProjectName)\</BaseOutputPath>
3740
</PropertyGroup>

azure-pipelines.yml

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,19 @@ variables:
1616
jobs:
1717
- job: Windows
1818
pool:
19-
vmImage: vs2017-win2016
19+
vmImage: windows-2019
2020
steps:
21-
- task: DotNetCoreInstaller@0
22-
displayName: Install .NET Core 2.2
21+
- task: UseDotNet@2
22+
displayName: Install .NET Core 3 SDK
2323
inputs:
24-
version: '2.2.102'
24+
version: '3.x'
25+
packageType: sdk
26+
includePreviewVersions: true
27+
- task: UseDotNet@2
28+
displayName: Install .NET Core 2.2 runtime
29+
inputs:
30+
version: '2.2.x'
31+
packageType: runtime
2532
- powershell: ./build.ps1 -ci
2633
displayName: Invoke build.ps1
2734
condition: eq(variables['kv-access-token'], '')
@@ -47,10 +54,17 @@ jobs:
4754
pool:
4855
vmImage: 'Ubuntu-16.04'
4956
steps:
50-
- task: DotNetCoreInstaller@0
51-
displayName: Install .NET Core 2.2
57+
- task: UseDotNet@2
58+
displayName: Install .NET Core 3 SDK
59+
inputs:
60+
version: '3.x'
61+
packageType: sdk
62+
includePreviewVersions: true
63+
- task: UseDotNet@2
64+
displayName: Install .NET Core 2.2 runtime
5265
inputs:
53-
version: '2.2.102'
66+
version: '2.2.x'
67+
packageType: runtime
5468
- script: ./build.ps1 -ci
5569
displayName: Invoke build.ps1
5670
- task: PublishTestResults@2

docs/generate.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ try {
2424
exec git worktree add $targetDir gh-pages 2>&1 | out-null
2525
}
2626

27-
$docfxVersion = '2.40.5'
27+
$docfxVersion = '2.43.1'
2828
$docfxRoot = "$buildRoot/packages/docfx.console/$docfxVersion"
2929
$docfx = "$docfxRoot/tools/docfx.exe"
3030
if (-not (Test-Path $docfx)) {

docs/samples/Directory.Build.props

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Project>
2+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)..\, Directory.Build.props))\Directory.Build.props" />
3+
4+
<PropertyGroup>
5+
<!-- Set samples to use the latest stable C# until C# 8 is released -->
6+
<LangVersion>7.3</LangVersion>
7+
<Nullable />
8+
<NullableContextOptions />
9+
</PropertyGroup>
10+
11+
</Project>

src/CommandLineUtils/Abstractions/IValueParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ public interface IValueParser
2424
/// <param name="culture">The culture that should be used to parse values.</param>
2525
/// <returns>The parsed value object.</returns>
2626
/// <throws name="System.FormatException">When the value cannot be parsed.</throws>
27-
object Parse(string argName, string value, CultureInfo culture);
27+
object? Parse(string? argName, string? value, CultureInfo culture);
2828
}
2929
}

src/CommandLineUtils/Abstractions/IValueParser{T}.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ public interface IValueParser<T> : IValueParser
1818
/// <param name="culture">The culture that should be used to parse values.</param>
1919
/// <returns>The parsed value object.</returns>
2020
/// <throws name="System.FormatException">When the value cannot be parsed.</throws>
21-
new T Parse(string argName, string value, CultureInfo culture);
21+
new T Parse(string? argName, string? value, CultureInfo culture);
2222
}
2323
}

src/CommandLineUtils/Abstractions/ParseResult.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,37 @@
11
// Copyright (c) Nate McMaster.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System;
5+
using System.ComponentModel;
6+
47
namespace McMaster.Extensions.CommandLineUtils.Abstractions
58
{
69
/// <summary>
710
/// The result of parsing command line arguments.
811
/// </summary>
912
public class ParseResult
1013
{
14+
/// <summary>
15+
/// Initializes <see cref="ParseResult"/>.
16+
/// </summary>
17+
/// <param name="selectedCommand">The command selected for execution.</param>
18+
public ParseResult(CommandLineApplication selectedCommand)
19+
{
20+
SelectedCommand = selectedCommand ?? throw new ArgumentNullException(nameof(selectedCommand));
21+
}
22+
23+
#pragma warning disable CS8618 // Non-nullable field is uninitialized.
24+
/// <summary>
25+
/// This constructor is obsolete and will be removed in a future version.
26+
/// The recommended replacement is <see cref="ParseResult(CommandLineApplication)" />
27+
/// </summary>
28+
[Obsolete("This constructor is obsolete and will be removed in a future version. The recommended replacement is ctor(CommandLineApplication selectedCommand)")]
29+
[EditorBrowsable(EditorBrowsableState.Never)]
30+
public ParseResult()
31+
{
32+
}
33+
#pragma warning restore CS8618 // Non-nullable field is uninitialized.
34+
1135
/// <summary>
1236
/// The application or subcommand that matches the command line arguments.
1337
/// </summary>

src/CommandLineUtils/Abstractions/ValueParserProvider.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public IValueParser GetParser(Type type)
7171
/// </remarks>
7272
/// <typeparam name="T"></typeparam>
7373
/// <returns></returns>
74-
public IValueParser<T> GetParser<T>()
74+
public IValueParser<T>? GetParser<T>()
7575
{
7676
var parser = GetParserImpl<T>();
7777
if (parser == null)
@@ -87,7 +87,7 @@ public IValueParser<T> GetParser<T>()
8787
return new GenericParserAdapter<T>(parser);
8888
}
8989

90-
internal IValueParser GetParserImpl<T>()
90+
internal IValueParser? GetParserImpl<T>()
9191
{
9292
var type = typeof(T);
9393
if (_parsers.TryGetValue(type, out var parser))
@@ -102,7 +102,7 @@ internal IValueParser GetParserImpl<T>()
102102
return EnumParser.Create(type);
103103
}
104104

105-
if (ReflectionHelper.IsNullableType(typeInfo, out var wrappedType))
105+
if (ReflectionHelper.IsNullableType(typeInfo, out var wrappedType) && wrappedType != null)
106106
{
107107
if (wrappedType.GetTypeInfo().IsEnum)
108108
{
@@ -187,7 +187,7 @@ private void SafeAdd(IValueParser parser, bool andReplace = false)
187187
throw new ArgumentNullException(nameof(parser));
188188
}
189189

190-
var targetType = parser.TargetType;
190+
Type targetType = parser.TargetType;
191191

192192
if (targetType == null)
193193
{
@@ -197,7 +197,7 @@ private void SafeAdd(IValueParser parser, bool andReplace = false)
197197
}
198198

199199
// strip nullable wrappers since we have a dedicated nullable value parser
200-
targetType = ReflectionHelper.IsNullableType(targetType.GetTypeInfo(), out var wrappedType)
200+
targetType = ReflectionHelper.IsNullableType(targetType.GetTypeInfo(), out var wrappedType) && wrappedType != null
201201
? wrappedType
202202
: targetType;
203203

@@ -219,7 +219,7 @@ private void SafeAdd(IValueParser parser, bool andReplace = false)
219219

220220
private sealed class GenericParserAdapter<T> : IValueParser<T>
221221
{
222-
private IValueParser _inner;
222+
private readonly IValueParser _inner;
223223

224224
public GenericParserAdapter(IValueParser inner)
225225
{
@@ -228,9 +228,9 @@ public GenericParserAdapter(IValueParser inner)
228228

229229
public Type TargetType => _inner.TargetType;
230230

231-
public T Parse(string argName, string value, CultureInfo culture) => (T)_inner.Parse(argName, value, culture);
231+
public T Parse(string? argName, string? value, CultureInfo culture) => (T)_inner.Parse(argName, value, culture)!;
232232

233-
object IValueParser.Parse(string argName, string value, CultureInfo culture) => _inner.Parse(argName, value, culture);
233+
object? IValueParser.Parse(string? argName, string? value, CultureInfo culture) => _inner.Parse(argName, value, culture);
234234
}
235235
}
236236
}

0 commit comments

Comments
 (0)