Skip to content
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

Added support for <WarningsAsErrors>nullable</WarningsAsErrors> #2406

Merged
merged 4 commits into from
Jun 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# Changelog
All changes to the project will be documented in this file.

## [1.39.0]
## [1.39.1]
* Added support for `<WarningsAsErrors>nullable</WarningsAsErrors>` ([#2292](https://github.com/OmniSharp/omnisharp-roslyn/issues/2292), PR: [#2406](https://github.com/OmniSharp/omnisharp-roslyn/pull/2406))

## [1.39.0] - 2022-05-19
* Update Roslyn to 4.3.0-2.22267.5 (PR: [#2401](https://github.com/OmniSharp/omnisharp-roslyn/pull/2401))
* Fixed run script for Mono ([OmniSharp/omnisharp-vscode#5181](https://github.com/OmniSharp/omnisharp-vscode/issues/5181), [OmniSharp/omnisharp-vscode#5179](https://github.com/OmniSharp/omnisharp-vscode/issues/5179), PR: [#2398](https://github.com/OmniSharp/omnisharp-roslyn/pull/2398))
* Fall back to /usr/lib/os-release if /etc/os-release doesn't exist (PR: [#2380](https://github.com/OmniSharp/omnisharp-roslyn/pull/2380))
Expand Down
77 changes: 77 additions & 0 deletions src/OmniSharp.MSBuild/Errors/Errors.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System.Collections.Immutable;

namespace OmniSharp.MSBuild
{
internal static class Errors
{
public static readonly ImmutableHashSet<string> NullableWarnings;

// sourced from https://github.com/dotnet/roslyn/blob/v4.2.0-3.22151.16/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs#L27-L82
static Errors()
{
ImmutableHashSet<string>.Builder nullableWarnings = ImmutableHashSet.CreateBuilder<string>();

nullableWarnings.Add("CS8601"); // WRN_NullReferenceAssignment
nullableWarnings.Add("CS8602"); // WRN_NullReferenceReceiver
nullableWarnings.Add("CS8603"); // WRN_NullReferenceReturn
nullableWarnings.Add("CS8604"); // WRN_NullReferenceArgument

nullableWarnings.Add("CS8618"); // WRN_UninitializedNonNullableField
nullableWarnings.Add("CS8619"); // WRN_NullabilityMismatchInAssignment
nullableWarnings.Add("CS8620"); // WRN_NullabilityMismatchInArgument
nullableWarnings.Add("CS8624"); // WRN_NullabilityMismatchInArgumentForOutput

nullableWarnings.Add("CS8621"); // WRN_NullabilityMismatchInReturnTypeOfTargetDelegate
nullableWarnings.Add("CS8622"); // WRN_NullabilityMismatchInParameterTypeOfTargetDelegate
nullableWarnings.Add("CS8625"); // WRN_NullAsNonNullable
nullableWarnings.Add("CS8629"); // WRN_NullableValueTypeMayBeNull
nullableWarnings.Add("CS8631"); // WRN_NullabilityMismatchInTypeParameterConstraint
nullableWarnings.Add("CS8634"); // WRN_NullabilityMismatchInTypeParameterReferenceTypeConstraint
nullableWarnings.Add("CS8714"); // WRN_NullabilityMismatchInTypeParameterNotNullConstraint

nullableWarnings.Add("CS8597"); // WRN_ThrowPossibleNull
nullableWarnings.Add("CS8605"); // WRN_UnboxPossibleNull
nullableWarnings.Add("CS8655"); // WRN_SwitchExpressionNotExhaustiveForNull
nullableWarnings.Add("CS8847"); // WRN_SwitchExpressionNotExhaustiveForNullWithWhen

nullableWarnings.Add("CS8600"); // WRN_ConvertingNullableToNonNullable
nullableWarnings.Add("CS8607"); // WRN_DisallowNullAttributeForbidsMaybeNullAssignment
nullableWarnings.Add("CS8762"); // WRN_ParameterConditionallyDisallowsNull
nullableWarnings.Add("CS8763"); // WRN_ShouldNotReturn


nullableWarnings.Add("CS8608"); // WRN_NullabilityMismatchInTypeOnOverride
nullableWarnings.Add("CS8609"); // WRN_NullabilityMismatchInReturnTypeOnOverride
nullableWarnings.Add("CS8819"); // WRN_NullabilityMismatchInReturnTypeOnPartial
nullableWarnings.Add("CS8610"); // WRN_NullabilityMismatchInParameterTypeOnOverride
nullableWarnings.Add("CS8611"); // WRN_NullabilityMismatchInParameterTypeOnPartial
nullableWarnings.Add("CS8612"); // WRN_NullabilityMismatchInTypeOnImplicitImplementation
nullableWarnings.Add("CS8613"); // WRN_NullabilityMismatchInReturnTypeOnImplicitImplementation
nullableWarnings.Add("CS8614"); // WRN_NullabilityMismatchInParameterTypeOnImplicitImplementation
nullableWarnings.Add("CS8615"); // WRN_NullabilityMismatchInTypeOnExplicitImplementation
nullableWarnings.Add("CS8616"); // WRN_NullabilityMismatchInReturnTypeOnExplicitImplementation
nullableWarnings.Add("CS8617"); // WRN_NullabilityMismatchInParameterTypeOnExplicitImplementation
nullableWarnings.Add("CS8633"); // WRN_NullabilityMismatchInConstraintsOnImplicitImplementation
nullableWarnings.Add("CS8643"); // WRN_NullabilityMismatchInExplicitlyImplementedInterface
nullableWarnings.Add("CS8644"); // WRN_NullabilityMismatchInInterfaceImplementedByBase
nullableWarnings.Add("CS8645"); // WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList
nullableWarnings.Add("CS8667"); // WRN_NullabilityMismatchInConstraintsOnPartialImplementation
nullableWarnings.Add("CS8670"); // WRN_NullReferenceInitializer
nullableWarnings.Add("CS8770"); // WRN_DoesNotReturnMismatch
nullableWarnings.Add("CS8769"); // WRN_TopLevelNullabilityMismatchInParameterTypeOnExplicitImplementation
nullableWarnings.Add("CS8767"); // WRN_TopLevelNullabilityMismatchInParameterTypeOnImplicitImplementation
nullableWarnings.Add("CS8765"); // WRN_TopLevelNullabilityMismatchInParameterTypeOnOverride
nullableWarnings.Add("CS8768"); // WRN_TopLevelNullabilityMismatchInReturnTypeOnExplicitImplementation
nullableWarnings.Add("CS8766"); // WRN_TopLevelNullabilityMismatchInReturnTypeOnImplicitImplementation
nullableWarnings.Add("CS8764"); // WRN_TopLevelNullabilityMismatchInReturnTypeOnOverride
nullableWarnings.Add("CS8774"); // WRN_MemberNotNull
nullableWarnings.Add("CS8776"); // WRN_MemberNotNullBadMember
nullableWarnings.Add("CS8775"); // WRN_MemberNotNullWhen
nullableWarnings.Add("CS8777"); // WRN_ParameterDisallowsNull
nullableWarnings.Add("CS8824"); // WRN_ParameterNotNullIfNotNull
nullableWarnings.Add("CS8825"); // WRN_ReturnNotNullIfNotNull

NullableWarnings = nullableWarnings.ToImmutable();
}
}
}
29 changes: 21 additions & 8 deletions src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfoExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.IO;
Expand Down Expand Up @@ -64,27 +65,39 @@ public static ImmutableDictionary<string, ReportDiagnostic> GetDiagnosticOptions
var specificRules = projectFileInfo.RuleSet?.SpecificDiagnosticOptions ?? ImmutableDictionary<string, ReportDiagnostic>.Empty;

// suppressions capture NoWarn and they have the highest priority
var combinedRules = specificRules.Concat(suppressions.Where(x => !specificRules.Keys.Contains(x.Key))).ToDictionary(x => x.Key, x => x.Value);
var combinedRules = specificRules.Concat(suppressions.Where(x => !specificRules.ContainsKey(x.Key))).ToDictionary(x => x.Key, x => x.Value);

// then handle WarningsAsErrors
foreach (var warningAsError in projectFileInfo.WarningsAsErrors)
{
if (!suppressions.ContainsKey(warningAsError))
if (string.Equals(warningAsError, "nullable", StringComparison.OrdinalIgnoreCase))
{
combinedRules[warningAsError] = ReportDiagnostic.Error;
foreach (var id in Errors.NullableWarnings)
{
AddIfNotSuppressed(id, ReportDiagnostic.Error);
}
}
else
{
AddIfNotSuppressed(warningAsError, ReportDiagnostic.Error);
}
}

// WarningsNotAsErrors can overwrite WarningsAsErrors
foreach (var warningNotAsError in projectFileInfo.WarningsNotAsErrors)
{
if (!suppressions.ContainsKey(warningNotAsError))
{
combinedRules[warningNotAsError] = ReportDiagnostic.Warn;
}
AddIfNotSuppressed(warningNotAsError, ReportDiagnostic.Warn);
}

return combinedRules.ToImmutableDictionary();

void AddIfNotSuppressed(string code, ReportDiagnostic diagnostic)
{
if (!suppressions.ContainsKey(code))
{
combinedRules[code] = diagnostic;
}
}
}

public static ProjectInfo CreateProjectInfo(this ProjectFileInfo projectFileInfo, IAnalyzerAssemblyLoader analyzerAssemblyLoader)
Expand Down
1 change: 1 addition & 0 deletions test-assets/test-projects/WarningsAsErrors/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public class Program
{
public static async Task Main(string[] args)
{
string bar = null;
Console.WriteLine("Hello World!");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<NoWarn>CS7081</NoWarn>
<WarningsAsErrors>CS1998,CS7080,CS7081</WarningsAsErrors>
<WarningsAsErrors>nullable,CS1998,CS7080,CS7081</WarningsAsErrors>
<WarningsNotAsErrors>CS7080,CS7082</WarningsNotAsErrors>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
3 changes: 3 additions & 0 deletions tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ public async Task WarningsAsErrors()
Assert.Equal(ReportDiagnostic.Warn, compilationOptions.SpecificDiagnosticOptions["CS7082"]);
// CS7081 is both WarningsAsErrors and NoWarn, but NoWarn are higher priority
Assert.Equal(ReportDiagnostic.Suppress, compilationOptions.SpecificDiagnosticOptions["CS7081"]);

// nullable warning as error
Assert.Equal(ReportDiagnostic.Error, compilationOptions.SpecificDiagnosticOptions["CS8600"]);
}
}

Expand Down