Skip to content

Commit 5409a36

Browse files
authored
Remove RequiresUnsafeAnalyzer and update the fixer (#127768)
See #127761 (comment). Related to #125800 and dotnet/roslyn#81207.
1 parent 5d5af62 commit 5409a36

16 files changed

Lines changed: 412 additions & 1680 deletions

eng/Version.Details.props

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ This file should be imported by eng/Versions.props
66
<Project>
77
<PropertyGroup>
88
<!-- dotnet-dotnet dependencies -->
9-
<MicrosoftCodeAnalysisPackageVersion>5.7.0-1.26257.113</MicrosoftCodeAnalysisPackageVersion>
10-
<MicrosoftCodeAnalysisAnalyzersPackageVersion>5.7.0-1.26257.113</MicrosoftCodeAnalysisAnalyzersPackageVersion>
11-
<MicrosoftCodeAnalysisCSharpPackageVersion>5.7.0-1.26257.113</MicrosoftCodeAnalysisCSharpPackageVersion>
9+
<MicrosoftCodeAnalysisPackageVersion>5.8.0-1.26266.103</MicrosoftCodeAnalysisPackageVersion>
10+
<MicrosoftCodeAnalysisAnalyzersPackageVersion>5.8.0-1.26266.103</MicrosoftCodeAnalysisAnalyzersPackageVersion>
11+
<MicrosoftCodeAnalysisCSharpPackageVersion>5.8.0-1.26266.103</MicrosoftCodeAnalysisCSharpPackageVersion>
1212
<MicrosoftCodeAnalysisNetAnalyzersPackageVersion>11.0.100-preview.5.26257.113</MicrosoftCodeAnalysisNetAnalyzersPackageVersion>
1313
<MicrosoftDotNetApiCompatTaskPackageVersion>11.0.100-preview.5.26257.113</MicrosoftDotNetApiCompatTaskPackageVersion>
1414
<MicrosoftDotNetArcadeSdkPackageVersion>11.0.0-beta.26257.113</MicrosoftDotNetArcadeSdkPackageVersion>
@@ -31,7 +31,7 @@ This file should be imported by eng/Versions.props
3131
<MicrosoftDotNetXUnitAssertPackageVersion>3.2.2-beta.26257.113</MicrosoftDotNetXUnitAssertPackageVersion>
3232
<MicrosoftDotNetXUnitConsoleRunnerPackageVersion>2.9.3-beta.26257.113</MicrosoftDotNetXUnitConsoleRunnerPackageVersion>
3333
<MicrosoftDotNetXUnitExtensionsPackageVersion>11.0.0-beta.26257.113</MicrosoftDotNetXUnitExtensionsPackageVersion>
34-
<MicrosoftNetCompilersToolsetPackageVersion>5.7.0-1.26257.113</MicrosoftNetCompilersToolsetPackageVersion>
34+
<MicrosoftNetCompilersToolsetPackageVersion>5.8.0-1.26266.103</MicrosoftNetCompilersToolsetPackageVersion>
3535
<MicrosoftNETSdkILPackageVersion>11.0.0-preview.5.26257.113</MicrosoftNETSdkILPackageVersion>
3636
<MicrosoftNETWorkloadEmscriptenCurrentManifest110100TransportPackageVersion>11.0.100-preview.5.26257.113</MicrosoftNETWorkloadEmscriptenCurrentManifest110100TransportPackageVersion>
3737
<MicrosoftNETCoreAppRefPackageVersion>11.0.0-preview.5.26257.113</MicrosoftNETCoreAppRefPackageVersion>

eng/Version.Details.xml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -327,21 +327,21 @@
327327
<Uri>https://github.com/dotnet/runtime-assets</Uri>
328328
<Sha>6af4bc0beb5fd7bc49a4a986a04ff6f6e4b83ab1</Sha>
329329
</Dependency>
330-
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="5.7.0-1.26257.113">
330+
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="5.8.0-1.26266.103">
331331
<Uri>https://github.com/dotnet/dotnet</Uri>
332-
<Sha>0eae08ed2f094f44e0151e4815e7cdd1a334fcdf</Sha>
332+
<Sha>3a62cc842c76761d4742f1d103892f19fd06dd3a</Sha>
333333
</Dependency>
334-
<Dependency Name="Microsoft.CodeAnalysis" Version="5.7.0-1.26257.113">
334+
<Dependency Name="Microsoft.CodeAnalysis" Version="5.8.0-1.26266.103">
335335
<Uri>https://github.com/dotnet/dotnet</Uri>
336-
<Sha>0eae08ed2f094f44e0151e4815e7cdd1a334fcdf</Sha>
336+
<Sha>3a62cc842c76761d4742f1d103892f19fd06dd3a</Sha>
337337
</Dependency>
338-
<Dependency Name="Microsoft.CodeAnalysis.CSharp" Version="5.7.0-1.26257.113">
338+
<Dependency Name="Microsoft.CodeAnalysis.CSharp" Version="5.8.0-1.26266.103">
339339
<Uri>https://github.com/dotnet/dotnet</Uri>
340-
<Sha>0eae08ed2f094f44e0151e4815e7cdd1a334fcdf</Sha>
340+
<Sha>3a62cc842c76761d4742f1d103892f19fd06dd3a</Sha>
341341
</Dependency>
342-
<Dependency Name="Microsoft.CodeAnalysis.Analyzers" Version="5.7.0-1.26257.113">
342+
<Dependency Name="Microsoft.CodeAnalysis.Analyzers" Version="5.8.0-1.26266.103">
343343
<Uri>https://github.com/dotnet/dotnet</Uri>
344-
<Sha>0eae08ed2f094f44e0151e4815e7cdd1a334fcdf</Sha>
344+
<Sha>3a62cc842c76761d4742f1d103892f19fd06dd3a</Sha>
345345
</Dependency>
346346
<Dependency Name="Microsoft.CodeAnalysis.NetAnalyzers" Version="11.0.100-preview.5.26257.113">
347347
<Uri>https://github.com/dotnet/dotnet</Uri>

src/tools/illink/src/ILLink.CodeFix/RequiresUnsafeCodeFixProvider.cs

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
using System.Threading;
1010
using System.Threading.Tasks;
1111
using ILLink.CodeFixProvider;
12-
using ILLink.RoslynAnalyzer;
13-
using ILLink.Shared;
1412
using Microsoft.CodeAnalysis;
1513
using Microsoft.CodeAnalysis.CodeActions;
1614
using Microsoft.CodeAnalysis.CodeFixes;
@@ -21,34 +19,39 @@
2119
namespace ILLink.CodeFix
2220
{
2321
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(RequiresUnsafeCodeFixProvider)), Shared]
24-
public sealed class RequiresUnsafeCodeFixProvider : BaseAttributeCodeFixProvider
22+
public sealed class RequiresUnsafeCodeFixProvider : Microsoft.CodeAnalysis.CodeFixes.CodeFixProvider
2523
{
2624
private const string WrapInUnsafeBlockTitle = "Wrap in unsafe block";
2725

28-
public static ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(DiagnosticDescriptors.GetDiagnosticDescriptor(DiagnosticId.RequiresUnsafe));
26+
public const string UnsafeMemberOperationDiagnosticId = "CS9362";
2927

30-
public sealed override ImmutableArray<string> FixableDiagnosticIds => SupportedDiagnostics.Select(dd => dd.Id).ToImmutableArray();
28+
public sealed override ImmutableArray<string> FixableDiagnosticIds => [UnsafeMemberOperationDiagnosticId];
3129

32-
private protected override LocalizableString CodeFixTitle => new LocalizableResourceString(nameof(Resources.RequiresUnsafeCodeFixTitle), Resources.ResourceManager, typeof(Resources));
33-
34-
private protected override string FullyQualifiedAttributeName => RequiresUnsafeAnalyzer.FullyQualifiedRequiresUnsafeAttribute;
35-
36-
private protected override AttributeableParentTargets AttributableParentTargets => AttributeableParentTargets.MethodOrConstructor;
30+
private static LocalizableString CodeFixTitle => new LocalizableResourceString(nameof(Resources.RequiresUnsafeCodeFixTitle), Resources.ResourceManager, typeof(Resources));
3731

3832
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
3933
{
40-
// Register the base code fix (add RequiresUnsafe attribute)
41-
await BaseRegisterCodeFixesAsync(context).ConfigureAwait(false);
42-
43-
// Register the "wrap in unsafe block" code fix
4434
var document = context.Document;
4535
var diagnostic = context.Diagnostics.First();
36+
var codeFixTitle = CodeFixTitle.ToString();
4637

4738
if (await document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false) is not { } root)
4839
return;
4940

5041
SyntaxNode targetNode = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);
5142

43+
// Register "add unsafe modifier" code fix
44+
var unsafeModifierTarget = GetUnsafeModifierTarget(targetNode);
45+
if (unsafeModifierTarget is not null && !HasUnsafeModifier(unsafeModifierTarget))
46+
{
47+
context.RegisterCodeFix(CodeAction.Create(
48+
title: codeFixTitle,
49+
createChangedDocument: ct => AddUnsafeModifierAsync(document, unsafeModifierTarget, ct),
50+
equivalenceKey: codeFixTitle), diagnostic);
51+
}
52+
53+
// Register the "wrap in unsafe block" code fix
54+
5255
// Find the statement containing the unsafe call
5356
var containingStatement = targetNode.AncestorsAndSelf().OfType<StatementSyntax>().FirstOrDefault();
5457

@@ -127,6 +130,39 @@ private static bool IsEmbeddedStatement(StatementSyntax statement)
127130
|| statement.Parent is FixedStatementSyntax;
128131
}
129132

133+
private static async Task<Document> AddUnsafeModifierAsync(
134+
Document document,
135+
SyntaxNode declaration,
136+
CancellationToken cancellationToken)
137+
{
138+
var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);
139+
var modifiers = editor.Generator.GetModifiers(declaration);
140+
editor.SetModifiers(declaration, modifiers.WithIsUnsafe(true));
141+
return editor.GetChangedDocument();
142+
}
143+
144+
private static SyntaxNode? GetUnsafeModifierTarget(SyntaxNode targetNode)
145+
=> targetNode.AncestorsAndSelf().FirstOrDefault(static node => node is MethodDeclarationSyntax
146+
or ConstructorDeclarationSyntax
147+
or DestructorDeclarationSyntax
148+
or LocalFunctionStatementSyntax
149+
or PropertyDeclarationSyntax
150+
or IndexerDeclarationSyntax
151+
or AccessorDeclarationSyntax);
152+
153+
private static bool HasUnsafeModifier(SyntaxNode declaration)
154+
=> declaration switch
155+
{
156+
MethodDeclarationSyntax method => method.Modifiers.Any(SyntaxKind.UnsafeKeyword),
157+
ConstructorDeclarationSyntax constructor => constructor.Modifiers.Any(SyntaxKind.UnsafeKeyword),
158+
DestructorDeclarationSyntax destructor => destructor.Modifiers.Any(SyntaxKind.UnsafeKeyword),
159+
LocalFunctionStatementSyntax localFunction => localFunction.Modifiers.Any(SyntaxKind.UnsafeKeyword),
160+
PropertyDeclarationSyntax property => property.Modifiers.Any(SyntaxKind.UnsafeKeyword),
161+
IndexerDeclarationSyntax indexer => indexer.Modifiers.Any(SyntaxKind.UnsafeKeyword),
162+
AccessorDeclarationSyntax accessor => accessor.Modifiers.Any(SyntaxKind.UnsafeKeyword),
163+
_ => false
164+
};
165+
130166
private static async Task<Document> WrapStatementsInUnsafeBlockAsync(
131167
Document document,
132168
BlockSyntax parentBlock,
@@ -480,9 +516,6 @@ private static async Task<Document> ConvertExpressionBodyToUnsafeBlockAsync(
480516
return editor.GetChangedDocument();
481517
}
482518

483-
protected override SyntaxNode[] GetAttributeArguments(ISymbol? attributableSymbol, ISymbol targetSymbol, SyntaxGenerator syntaxGenerator, Diagnostic diagnostic) =>
484-
RequiresHelpers.GetAttributeArgumentsForRequires(targetSymbol, syntaxGenerator, HasPublicAccessibility(attributableSymbol));
485-
486519
/// <summary>
487520
/// Checks if the arrow expression clause or its expression has preprocessor directive trivia.
488521
/// Converting expression bodies with directives to block bodies is error-prone, so we skip the fix.

src/tools/illink/src/ILLink.CodeFix/Resources.resx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,15 +127,12 @@
127127
<value>Add RequiresDynamicCode attribute to parent method</value>
128128
</data>
129129
<data name="RequiresUnsafeCodeFixTitle" xml:space="preserve">
130-
<value>Add RequiresUnsafe attribute to parent method</value>
130+
<value>Add 'unsafe' to parent method</value>
131131
</data>
132132
<data name="UconditionalSuppressMessageCodeFixTitle" xml:space="preserve">
133133
<value>Add UnconditionalSuppressMessage attribute to parent method</value>
134134
</data>
135135
<data name="DynamicallyAccessedMembersCodeFixTitle" xml:space="preserve">
136136
<value>Add DynamicallyAccessedMembers attribute to source of warning</value>
137137
</data>
138-
<data name="UnsafeMethodMissingRequiresUnsafeCodeFixTitle" xml:space="preserve">
139-
<value>Add RequiresUnsafe attribute to method with pointer types</value>
140-
</data>
141138
</root>

src/tools/illink/src/ILLink.CodeFix/UnsafeMethodMissingRequiresUnsafeCodeFixProvider.cs

Lines changed: 0 additions & 83 deletions
This file was deleted.

src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ private static ImmutableArray<RequiresAnalyzerBase> GetRequiresAnalyzers()
3131
builder.Add(new RequiresAssemblyFilesAnalyzer());
3232
builder.Add(new RequiresUnreferencedCodeAnalyzer());
3333
builder.Add(new RequiresDynamicCodeAnalyzer());
34-
#if DEBUG
35-
builder.Add(new RequiresUnsafeAnalyzer());
36-
#endif
3734
return builder.ToImmutable();
3835
}
3936

src/tools/illink/src/ILLink.RoslynAnalyzer/MSBuildPropertyOptionNames.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ public static class MSBuildPropertyOptionNames
99
public const string IncludeAllContentForSelfExtract = nameof(IncludeAllContentForSelfExtract);
1010
public const string EnableTrimAnalyzer = nameof(EnableTrimAnalyzer);
1111
public const string EnableAotAnalyzer = nameof(EnableAotAnalyzer);
12-
#if DEBUG
13-
public const string EnableUnsafeAnalyzer = nameof(EnableUnsafeAnalyzer);
14-
#endif
1512
public const string VerifyReferenceAotCompatibility = nameof(VerifyReferenceAotCompatibility);
1613
public const string VerifyReferenceTrimCompatibility = nameof(VerifyReferenceTrimCompatibility);
1714
}

0 commit comments

Comments
 (0)