From 365f1cc67eb43289756de807c08a5c992ded2492 Mon Sep 17 00:00:00 2001 From: filipw Date: Fri, 3 Jun 2022 11:50:17 +0200 Subject: [PATCH 1/4] support nullable --- src/OmniSharp.MSBuild/Errors/Errors.cs | 76 +++++++++++++++++++ .../ProjectFile/ProjectFileInfoExtensions.cs | 29 +++++-- 2 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 src/OmniSharp.MSBuild/Errors/Errors.cs diff --git a/src/OmniSharp.MSBuild/Errors/Errors.cs b/src/OmniSharp.MSBuild/Errors/Errors.cs new file mode 100644 index 0000000000..1e8392d2e7 --- /dev/null +++ b/src/OmniSharp.MSBuild/Errors/Errors.cs @@ -0,0 +1,76 @@ +using System.Collections.Immutable; + +namespace OmniSharp.MSBuild +{ + internal static class Errors + { + public static readonly ImmutableHashSet NullableWarnings; + + static Errors() + { + ImmutableHashSet.Builder nullableWarnings = ImmutableHashSet.CreateBuilder(); + + 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(); + } + } +} diff --git a/src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfoExtensions.cs b/src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfoExtensions.cs index 629693be7d..7ef657e829 100644 --- a/src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfoExtensions.cs +++ b/src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfoExtensions.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.Globalization; using System.IO; @@ -64,27 +65,39 @@ public static ImmutableDictionary GetDiagnosticOptions var specificRules = projectFileInfo.RuleSet?.SpecificDiagnosticOptions ?? ImmutableDictionary.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) From 20f0fa48636dd5651cf9d3666e43fa2a0a04b8a2 Mon Sep 17 00:00:00 2001 From: filipw Date: Fri, 3 Jun 2022 12:30:45 +0200 Subject: [PATCH 2/4] added test for nullable warning as error --- src/OmniSharp.MSBuild/Errors/Errors.cs | 1 + test-assets/test-projects/WarningsAsErrors/Program.cs | 1 + .../test-projects/WarningsAsErrors/WarningsAsErrors.csproj | 5 +++-- test-assets/test-projects/WarningsAsErrors/global.json | 5 +++++ tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs | 3 +++ 5 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 test-assets/test-projects/WarningsAsErrors/global.json diff --git a/src/OmniSharp.MSBuild/Errors/Errors.cs b/src/OmniSharp.MSBuild/Errors/Errors.cs index 1e8392d2e7..cbddb61137 100644 --- a/src/OmniSharp.MSBuild/Errors/Errors.cs +++ b/src/OmniSharp.MSBuild/Errors/Errors.cs @@ -6,6 +6,7 @@ internal static class Errors { public static readonly ImmutableHashSet 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.Builder nullableWarnings = ImmutableHashSet.CreateBuilder(); diff --git a/test-assets/test-projects/WarningsAsErrors/Program.cs b/test-assets/test-projects/WarningsAsErrors/Program.cs index c57ef04586..6a7a8237a8 100644 --- a/test-assets/test-projects/WarningsAsErrors/Program.cs +++ b/test-assets/test-projects/WarningsAsErrors/Program.cs @@ -7,6 +7,7 @@ public class Program { public static async Task Main(string[] args) { + string bar = null; Console.WriteLine("Hello World!"); } } diff --git a/test-assets/test-projects/WarningsAsErrors/WarningsAsErrors.csproj b/test-assets/test-projects/WarningsAsErrors/WarningsAsErrors.csproj index 0ac74eb557..9400d0ae00 100644 --- a/test-assets/test-projects/WarningsAsErrors/WarningsAsErrors.csproj +++ b/test-assets/test-projects/WarningsAsErrors/WarningsAsErrors.csproj @@ -2,10 +2,11 @@ Exe - netcoreapp3.1 + net6.0 CS7081 - CS1998,CS7080,CS7081 + nullable,CS1998,CS7080,CS7081 CS7080,CS7082 + enable \ No newline at end of file diff --git a/test-assets/test-projects/WarningsAsErrors/global.json b/test-assets/test-projects/WarningsAsErrors/global.json new file mode 100644 index 0000000000..e96609fe7d --- /dev/null +++ b/test-assets/test-projects/WarningsAsErrors/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "6.0.300" + } +} diff --git a/tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs b/tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs index c9967cf82c..68be48bcd6 100644 --- a/tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs +++ b/tests/OmniSharp.MSBuild.Tests/ProjectFileInfoTests.cs @@ -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"]); } } From e9f3ffc0c26f00d1d0b5775137c47c4e9d0cf288 Mon Sep 17 00:00:00 2001 From: filipw Date: Fri, 3 Jun 2022 12:34:36 +0200 Subject: [PATCH 3/4] changelog update --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 218d0158e5..ebacaafdeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 `nullable` ([#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)) From dc14b2efa09781702a963a26832d09ed8174ec9f Mon Sep 17 00:00:00 2001 From: filipw Date: Fri, 3 Jun 2022 15:20:20 +0200 Subject: [PATCH 4/4] revert test project to .netcoreapp3.1 --- .../test-projects/WarningsAsErrors/WarningsAsErrors.csproj | 2 +- test-assets/test-projects/WarningsAsErrors/global.json | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 test-assets/test-projects/WarningsAsErrors/global.json diff --git a/test-assets/test-projects/WarningsAsErrors/WarningsAsErrors.csproj b/test-assets/test-projects/WarningsAsErrors/WarningsAsErrors.csproj index 9400d0ae00..ef9cd6d52b 100644 --- a/test-assets/test-projects/WarningsAsErrors/WarningsAsErrors.csproj +++ b/test-assets/test-projects/WarningsAsErrors/WarningsAsErrors.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + netcoreapp3.1 CS7081 nullable,CS1998,CS7080,CS7081 CS7080,CS7082 diff --git a/test-assets/test-projects/WarningsAsErrors/global.json b/test-assets/test-projects/WarningsAsErrors/global.json deleted file mode 100644 index e96609fe7d..0000000000 --- a/test-assets/test-projects/WarningsAsErrors/global.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "sdk": { - "version": "6.0.300" - } -}