Skip to content

Fix not offering to remove unnecessary nullable pragmas #79356

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

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,19 @@
namespace Microsoft.CodeAnalysis.RemoveUnnecessaryNullableDirective;

[DiagnosticAnalyzer(LanguageNames.CSharp)]
internal sealed class CSharpRemoveUnnecessaryNullableDirectiveDiagnosticAnalyzer
: AbstractBuiltInUnnecessaryCodeStyleDiagnosticAnalyzer
internal sealed class CSharpRemoveUnnecessaryNullableDirectiveDiagnosticAnalyzer()
: AbstractBuiltInUnnecessaryCodeStyleDiagnosticAnalyzer(IDEDiagnosticIds.RemoveUnnecessaryNullableDirectiveDiagnosticId,
EnforceOnBuildValues.RemoveUnnecessaryNullableDirective,
option: null,
fadingOption: null,
new LocalizableResourceString(nameof(CSharpAnalyzersResources.Remove_unnecessary_nullable_directive), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources)),
new LocalizableResourceString(nameof(CSharpAnalyzersResources.Nullable_directive_is_unnecessary), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources)))
{
public CSharpRemoveUnnecessaryNullableDirectiveDiagnosticAnalyzer()
: base(IDEDiagnosticIds.RemoveUnnecessaryNullableDirectiveDiagnosticId,
EnforceOnBuildValues.RemoveUnnecessaryNullableDirective,
option: null,
fadingOption: null,
new LocalizableResourceString(nameof(CSharpAnalyzersResources.Remove_unnecessary_nullable_directive), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources)),
new LocalizableResourceString(nameof(CSharpAnalyzersResources.Nullable_directive_is_unnecessary), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources)))
{
}

public override DiagnosticAnalyzerCategory GetAnalyzerCategory()
=> DiagnosticAnalyzerCategory.SemanticDocumentAnalysis;

protected override void InitializeWorker(AnalysisContext context)
{
context.RegisterCompilationStartAction(AnalyzeCompilation);
}
=> context.RegisterCompilationStartAction(AnalyzeCompilation);

private void AnalyzeCompilation(CompilationStartAnalysisContext context)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ private static bool IsLanguageRestrictedToNonNullForm(TypeSyntax node)
return true;
}

// An attribute name cannot itself be nullable. `[CLSCompliant?]` is not a thing.
if (node.IsParentKind(SyntaxKind.Attribute))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An attribute can have a constructor parameter/property initializer, which can lead to warnings after nullable directive removed, e.g. [MyAttr(null, Prop = null)] with MyAttr declared as

#nullable enable

class MyAttr : Attribute
{
    public object Prop { get; set; }

    public MyAttr(string s) { }
}

Does this change account for that? Add test cases for this

return true;

return false;

// If this is Y in X.Y, walk up to X.Y
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.CodeAnalysis.RemoveUnnecessaryNullableDirective;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.RemoveUnnecessaryNullableDirective;
Expand Down Expand Up @@ -62,6 +63,32 @@ enum EnumName
}
""");

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65401")]
public Task TestUnnecessaryDisableEnumDeclaration_WithAttribute()
=> VerifyCodeFixAsync(
NullableContextOptions.Enable,
"""
[|#nullable disable|]
using System;
[CLSCompliant(false)]
enum EnumName
{
First,
Second,
}
""",
"""
using System;
[CLSCompliant(false)]
enum EnumName
{
First,
Second,
}
""");

[Fact]
public Task TestUnnecessaryDisableEnumDeclarationWithFileHeader()
=> VerifyCodeFixAsync(
Expand Down
Loading