diff options
author | Tlakaelel Axayakatl Ceja <tlakaelel.ceja@microsoft.com> | 2022-09-02 02:43:27 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-02 02:43:27 +0300 |
commit | f0b2510bfd53a35df0aeae48996d2905c1067022 (patch) | |
tree | bfb51822186b76120fad97339e4574968787d501 | |
parent | 1352b543cfdbaf33649bf164d7371a99dff72f10 (diff) |
Allow codefixer to annotate accessor declarations as methods (#3017)
Allow codefixer to insert a fix in accessor declarations if we target methods
Fix tests that had accessors and were annotating properties/events
Add tests
8 files changed, 210 insertions, 5 deletions
diff --git a/src/ILLink.CodeFix/BaseAttributeCodeFixProvider.cs b/src/ILLink.CodeFix/BaseAttributeCodeFixProvider.cs index 481c8ba10..cdf73ab1f 100644 --- a/src/ILLink.CodeFix/BaseAttributeCodeFixProvider.cs +++ b/src/ILLink.CodeFix/BaseAttributeCodeFixProvider.cs @@ -97,7 +97,7 @@ namespace ILLink.CodeFix case LambdaExpressionSyntax: return null; - case LocalFunctionStatementSyntax or BaseMethodDeclarationSyntax when targets.HasFlag (AttributeableParentTargets.MethodOrConstructor): + case LocalFunctionStatementSyntax or BaseMethodDeclarationSyntax or AccessorDeclarationSyntax when targets.HasFlag (AttributeableParentTargets.MethodOrConstructor): case PropertyDeclarationSyntax when targets.HasFlag (AttributeableParentTargets.Property): case FieldDeclarationSyntax when targets.HasFlag (AttributeableParentTargets.Field): case EventDeclarationSyntax when targets.HasFlag (AttributeableParentTargets.Event): diff --git a/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs b/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs index 1d80ed7a6..fe377003e 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs @@ -515,6 +515,55 @@ build_property.{MSBuildPropertyOptionNames.EnableSingleFileAnalyzer} = true"))); } [Fact] + public Task FixInPropertyAccessor () + { + var src = $$""" + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresAssemblyFilesAttribute("message")] + public int M1() => 0; + + public int field; + + private int M2 { + get { return M1(); } + set { field = M1(); } + } + } + """; + var fix = $$""" + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresAssemblyFilesAttribute("message")] + public int M1() => 0; + + public int field; + + private int M2 { + [RequiresAssemblyFiles("Calls C.M1()")] + get { return M1(); } + + [RequiresAssemblyFiles("Calls C.M1()")] + set { field = M1(); } + } + } + """; + var diag = new[] { + // /0/Test0.cs(12,16): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(12, 16, 12, 20).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(13,17): warning IL3002: Using member 'C.M1()' which has 'RequiresAssemblyFilesAttribute' can break functionality when embedded in a single-file app. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresAssemblyFiles).WithSpan(13, 17, 13, 21).WithArguments("C.M1()", " message.", "") + }; + return VerifyRequiresAssemblyFilesCodeFix (src, fix, diag, Array.Empty<DiagnosticResult> ()); + } + + [Fact] public Task FixInField () { var src = $$""" @@ -657,10 +706,10 @@ build_property.{MSBuildPropertyOptionNames.EnableSingleFileAnalyzer} = true"))); [RequiresAssemblyFiles("message")] public int M1() => 0; - [RequiresAssemblyFiles()] - public event EventHandler E1 + public event EventHandler E1 { - add + [RequiresAssemblyFiles()] + add { var a = M1(); } diff --git a/test/ILLink.RoslynAnalyzer.Tests/RequiresDynamicCodeAnalyzerTests.cs b/test/ILLink.RoslynAnalyzer.Tests/RequiresDynamicCodeAnalyzerTests.cs index cf55055dd..2ed2be672 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/RequiresDynamicCodeAnalyzerTests.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/RequiresDynamicCodeAnalyzerTests.cs @@ -284,5 +284,54 @@ build_property.{MSBuildPropertyOptionNames.EnableAotAnalyzer} = true"))); // Can't apply RDC on properties at the moment return VerifyRequiresDynamicCodeCodeFix (src, src, diag, diag); } + + [Fact] + public Task FixInPropertyAccessor () + { + var src = $$""" + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresDynamicCodeAttribute("message")] + public int M1() => 0; + + public int field; + + private int M2 { + get { return M1(); } + set { field = M1(); } + } + } + """; + var fix = $$""" + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresDynamicCodeAttribute("message")] + public int M1() => 0; + + public int field; + + private int M2 { + [RequiresDynamicCode("Calls C.M1()")] + get { return M1(); } + + [RequiresDynamicCode("Calls C.M1()")] + set { field = M1(); } + } + } + """; + var diag = new[] { + // /0/Test0.cs(12,16): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(12, 16, 12, 20).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(13,17): warning IL3050: Using member 'C.M1()' which has 'RequiresDynamicCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresDynamicCode).WithSpan(13, 17, 13, 21).WithArguments("C.M1()", " message.", "") + }; + return VerifyRequiresDynamicCodeCodeFix (src, fix, diag, Array.Empty<DiagnosticResult> ()); + } } } diff --git a/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs b/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs index 2576b1401..64dbdacfe 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs @@ -322,6 +322,55 @@ build_property.{MSBuildPropertyOptionNames.EnableTrimAnalyzer} = true"))); } [Fact] + public Task FixInPropertyAccessor () + { + var src = $$""" + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; + + public int field; + + private int M2 { + get { return M1(); } + set { field = M1(); } + } + } + """; + var fix = $$""" + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; + + public int field; + + private int M2 { + [RequiresUnreferencedCode("Calls C.M1()")] + get { return M1(); } + + [RequiresUnreferencedCode("Calls C.M1()")] + set { field = M1(); } + } + } + """; + var diag = new[] { + // /0/Test0.cs(12,16): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(12, 16, 12, 20).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(13,17): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCS.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(13, 17, 13, 21).WithArguments("C.M1()", " message.", "") + }; + return VerifyRequiresUnreferencedCodeCodeFix (src, fix, diag, Array.Empty<DiagnosticResult> ()); + } + + [Fact] public Task InvocationOnDynamicType () { var source = $$""" diff --git a/test/ILLink.RoslynAnalyzer.Tests/UnconditionalSuppressMessageCodeFixTests.cs b/test/ILLink.RoslynAnalyzer.Tests/UnconditionalSuppressMessageCodeFixTests.cs index ec5df8f94..c89330df1 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/UnconditionalSuppressMessageCodeFixTests.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/UnconditionalSuppressMessageCodeFixTests.cs @@ -4,6 +4,7 @@ using System; using System.Threading.Tasks; using ILLink.Shared; +using Microsoft; using Microsoft.CodeAnalysis.Testing; using Microsoft.CodeAnalysis.Text; using Xunit; @@ -270,6 +271,55 @@ public class C } [Fact] + public Task FixInPropertyAccessor () + { + var src = $$""" + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; + + public int field; + + private int M2 { + get { return M1(); } + set { field = M1(); } + } + } + """; + var fix = $$""" + using System; + using System.Diagnostics.CodeAnalysis; + + public class C + { + [RequiresUnreferencedCodeAttribute("message")] + public int M1() => 0; + + public int field; + + private int M2 { + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")] + get { return M1(); } + + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")] + set { field = M1(); } + } + } + """; + var diag = new[] { + // /0/Test0.cs(12,16): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCSUSMwithRUC.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(12, 16, 12, 20).WithArguments("C.M1()", " message.", ""), + // /0/Test0.cs(13,17): warning IL2026: Using member 'C.M1()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. message. + VerifyCSUSMwithRUC.Diagnostic(DiagnosticId.RequiresUnreferencedCode).WithSpan(13, 17, 13, 21).WithArguments("C.M1()", " message.", "") + }; + return VerifyUnconditionalSuppressMessageCodeFixWithRUC (src, fix, diag, Array.Empty<DiagnosticResult> ()); + } + + [Fact] public Task FixInField () { const string src = @" @@ -421,9 +471,9 @@ public class C [RequiresUnreferencedCodeAttribute(""message"")] public int M1() => 0; - [UnconditionalSuppressMessage(""Trimming"", ""IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code"", Justification = ""<Pending>"")] public event EventHandler E1 { + [UnconditionalSuppressMessage(""Trimming"", ""IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code"", Justification = ""<Pending>"")] add { var a = M1(); diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ExtensibilityTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ExtensibilityTests.g.cs index 809796a7c..a925192ed 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ExtensibilityTests.g.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ExtensibilityTests.g.cs @@ -34,6 +34,12 @@ namespace ILLink.RoslynAnalyzer.Tests } [Fact] + public Task CustomWarningUsage () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] public Task MarkHandlerUsage () { return RunTest (allowMissingWarnings: true); diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/Microsoft.Interop.JavaScript.JSImportGenerator/Microsoft.Interop.JavaScript.JSExportGenerator/JSExports.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/Microsoft.Interop.JavaScript.JSImportGenerator/Microsoft.Interop.JavaScript.JSExportGenerator/JSExports.g.cs new file mode 100644 index 000000000..e5b50076d --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/Microsoft.Interop.JavaScript.JSImportGenerator/Microsoft.Interop.JavaScript.JSExportGenerator/JSExports.g.cs @@ -0,0 +1 @@ +// <auto-generated/> diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/Microsoft.Interop.JavaScript.JSImportGenerator/Microsoft.Interop.JavaScript.JSImportGenerator/JSImports.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/Microsoft.Interop.JavaScript.JSImportGenerator/Microsoft.Interop.JavaScript.JSImportGenerator/JSImports.g.cs new file mode 100644 index 000000000..e5b50076d --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/Microsoft.Interop.JavaScript.JSImportGenerator/Microsoft.Interop.JavaScript.JSImportGenerator/JSImports.g.cs @@ -0,0 +1 @@ +// <auto-generated/> |