From c44e7e65f9abc4788cff7d9fd24cdc1f0294e750 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 5 Jan 2023 10:30:43 +0100 Subject: [PATCH 01/11] Add IT for S4200 --- .../Net7/S4200.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 analyzers/its/sources/ManuallyAddedNoncompliantIssues.CS/Net7/S4200.cs diff --git a/analyzers/its/sources/ManuallyAddedNoncompliantIssues.CS/Net7/S4200.cs b/analyzers/its/sources/ManuallyAddedNoncompliantIssues.CS/Net7/S4200.cs new file mode 100644 index 00000000000..6fe7954b4ba --- /dev/null +++ b/analyzers/its/sources/ManuallyAddedNoncompliantIssues.CS/Net7/S4200.cs @@ -0,0 +1,13 @@ +using System.Runtime.InteropServices; + +namespace Net7; + +public static partial class S4200 +{ + // Use Goto definition in VS on the methods to see the code generated by the Microsoft.Interop.LibraryImportGenerator + [LibraryImport("foo.dll")] + public static partial void DllImportAttributeAppliedToThisFunction(); // Noncompliant (S4200): Make this native method private and provide a wrapper. + + [LibraryImport("foo.dll", StringMarshalling = StringMarshalling.Utf8)] + public static partial void DllImportAttributeAppliedToGeneratedLocalFunction(string p); // Noncompliant +} From d13b33dce2bcc37c08910c088c7e8d7b7d7d4a36 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 5 Jan 2023 12:12:46 +0100 Subject: [PATCH 02/11] Add test case for DllImport applied to the method by the generator --- .../Rules/NativeMethodsShouldBeWrappedTest.cs | 6 +++++- ...iveMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs | 9 +++++++++ .../TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs | 9 +++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs index 29794d3a533..970cf3bd355 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs @@ -43,7 +43,11 @@ public void NativeMethodsShouldBeWrapped_CSharp10() => [TestMethod] public void NativeMethodsShouldBeWrapped_CSharp11() => - builder.AddPaths("NativeMethodsShouldBeWrapped.CSharp11.cs").WithOptions(ParseOptionsHelper.FromCSharp11).Verify(); + builder + .AddPaths("NativeMethodsShouldBeWrapped.CSharp11.cs") + .AddPaths("NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs") + .WithOptions(ParseOptionsHelper.FromCSharp11) + .Verify(); #endif diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs new file mode 100644 index 00000000000..802ce2acf3a --- /dev/null +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs @@ -0,0 +1,9 @@ +// +namespace LibraryImportAttributeTests +{ + public static unsafe partial class ExternMethods + { + [System.Runtime.InteropServices.DllImportAttribute("foo.dll", EntryPoint = "DllImportAttributeAppliedToThisFunction", ExactSpelling = true)] + public static extern partial void DllImportAttributeAppliedToThisFunction(); + } +} diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs index 55fee14dd8a..e00284f5a3e 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs @@ -8,3 +8,12 @@ public interface IInterface [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern virtual bool RemoveDirectory2(string name); // Noncompliant } + +namespace LibraryImportAttributeTests +{ + public static partial class ExternMethods + { + [LibraryImport("foo.dll")] + public static partial void DllImportAttributeAppliedToThisFunction(); + } +} From 8778236617a0fb52304ebb68dc274c0f183bb7c3 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 5 Jan 2023 12:36:50 +0100 Subject: [PATCH 03/11] Fix auto-generated code --- .../Rules/NativeMethodsShouldBeWrapped.cs | 13 +++++++++---- .../Rules/NativeMethodsShouldBeWrappedTest.cs | 1 + .../NativeMethodsShouldBeWrapped.CSharp11.cs | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/NativeMethodsShouldBeWrapped.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/NativeMethodsShouldBeWrapped.cs index 489cb169220..0358c0e0265 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/NativeMethodsShouldBeWrapped.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/NativeMethodsShouldBeWrapped.cs @@ -34,17 +34,22 @@ public sealed class NativeMethodsShouldBeWrapped : SonarDiagnosticAnalyzer protected override void Initialize(SonarAnalysisContext context) { context.RegisterSymbolAction(ReportPublicExternalMethods, SymbolKind.Method); - context.RegisterSyntaxNodeAction(ReportTrivialWrappers, SyntaxKind.MethodDeclaration); + context.RegisterSyntaxNodeActionInNonGenerated(ReportTrivialWrappers, SyntaxKind.MethodDeclaration); } private static void ReportPublicExternalMethods(SymbolAnalysisContext c) { var methodSymbol = (IMethodSymbol)c.Symbol; if (methodSymbol.IsExtern - && methodSymbol.IsPubliclyAccessible() - && methodSymbol.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax() is MethodDeclarationSyntax methodDeclaration) + && methodSymbol.IsPubliclyAccessible()) { - c.ReportIssue(Diagnostic.Create(Rule, methodDeclaration.Identifier.GetLocation(), MakeThisMethodPrivateMessage)); + foreach (var methodDeclaration in methodSymbol.DeclaringSyntaxReferences + .Where(x => !x.SyntaxTree.IsGenerated(CSharpGeneratedCodeRecognizer.Instance, c.Compilation)) + .Select(x => x.GetSyntax()) + .OfType()) + { + c.ReportIssue(Diagnostic.Create(Rule, methodDeclaration.Identifier.GetLocation(), MakeThisMethodPrivateMessage)); + } } } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs index 970cf3bd355..e0b76a4b3e4 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs @@ -47,6 +47,7 @@ public void NativeMethodsShouldBeWrapped_CSharp11() => .AddPaths("NativeMethodsShouldBeWrapped.CSharp11.cs") .AddPaths("NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs") .WithOptions(ParseOptionsHelper.FromCSharp11) + .WithConcurrentAnalysis(false) .Verify(); #endif diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs index e00284f5a3e..0e3606f021b 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs @@ -14,6 +14,6 @@ namespace LibraryImportAttributeTests public static partial class ExternMethods { [LibraryImport("foo.dll")] - public static partial void DllImportAttributeAppliedToThisFunction(); + public static partial void DllImportAttributeAppliedToThisFunction(); // Noncompliant } } From c963d32c919c16d29fa8e42a00a904a2497739fd Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 5 Jan 2023 12:39:46 +0100 Subject: [PATCH 04/11] Add test case for DllImportAttributeAppliedToGeneratedLocalFunction --- ...houldBeWrapped.CSharp11.SourceGenerator.cs | 29 +++++++++++++++++++ .../NativeMethodsShouldBeWrapped.CSharp11.cs | 3 ++ 2 files changed, 32 insertions(+) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs index 802ce2acf3a..69c6785313d 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs @@ -5,5 +5,34 @@ public static unsafe partial class ExternMethods { [System.Runtime.InteropServices.DllImportAttribute("foo.dll", EntryPoint = "DllImportAttributeAppliedToThisFunction", ExactSpelling = true)] public static extern partial void DllImportAttributeAppliedToThisFunction(); + + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "7.0.7.6804")] + [System.Runtime.CompilerServices.SkipLocalsInitAttribute] + public static partial void DllImportAttributeAppliedToGeneratedLocalFunction(string p) + { + byte* __p_native = default; + // Setup - Perform required setup. + global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn __p_native__marshaller = new(); + try + { + // Marshal - Convert managed data to native data. + byte* __p_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize]; + __p_native__marshaller.FromManaged(p, new System.Span(__p_native__stackptr, global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize)); + { + // PinnedMarshal - Convert managed data to native data that requires the managed data to be pinned. + __p_native = __p_native__marshaller.ToUnmanaged(); + __PInvoke(__p_native); + } + } + finally + { + // Cleanup - Perform required cleanup. + __p_native__marshaller.Free(); + } + + // Local P/Invoke + [System.Runtime.InteropServices.DllImportAttribute("foo.dll", EntryPoint = "DllImportAttributeAppliedToGeneratedLocalFunction", ExactSpelling = true)] + static extern unsafe void __PInvoke(byte* p); + } } } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs index 0e3606f021b..e53614384e2 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs @@ -15,5 +15,8 @@ public static partial class ExternMethods { [LibraryImport("foo.dll")] public static partial void DllImportAttributeAppliedToThisFunction(); // Noncompliant + + [LibraryImport("foo.dll", StringMarshalling = StringMarshalling.Utf8)] + public static partial void DllImportAttributeAppliedToGeneratedLocalFunction(string p); // Noncompliant } } From 456fbb02de0aacd50feb6a94a3d481f2078458a7 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 5 Jan 2023 12:46:22 +0100 Subject: [PATCH 05/11] Support LibraryImportAttribute --- .../SonarAnalyzer.CSharp/Rules/NativeMethodsShouldBeWrapped.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/NativeMethodsShouldBeWrapped.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/NativeMethodsShouldBeWrapped.cs index 0358c0e0265..49f19e4b950 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/NativeMethodsShouldBeWrapped.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/NativeMethodsShouldBeWrapped.cs @@ -40,7 +40,7 @@ protected override void Initialize(SonarAnalysisContext context) private static void ReportPublicExternalMethods(SymbolAnalysisContext c) { var methodSymbol = (IMethodSymbol)c.Symbol; - if (methodSymbol.IsExtern + if ((methodSymbol.IsExtern || methodSymbol.HasAttribute(KnownType.System_Runtime_InteropServices_LibraryImportAttribute)) && methodSymbol.IsPubliclyAccessible()) { foreach (var methodDeclaration in methodSymbol.DeclaringSyntaxReferences From 38cdf29b5c0887bb2c94d993d47db3958efbb6c6 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 5 Jan 2023 13:36:24 +0100 Subject: [PATCH 06/11] Add wrapper tests and fix support for LibraryImpoerAttribute --- .../Rules/NativeMethodsShouldBeWrapped.cs | 7 ++- ...houldBeWrapped.CSharp11.SourceGenerator.cs | 50 ++++++++++++++++++- .../NativeMethodsShouldBeWrapped.CSharp11.cs | 19 +++++++ 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/analyzers/src/SonarAnalyzer.CSharp/Rules/NativeMethodsShouldBeWrapped.cs b/analyzers/src/SonarAnalyzer.CSharp/Rules/NativeMethodsShouldBeWrapped.cs index 49f19e4b950..90586ff3021 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/Rules/NativeMethodsShouldBeWrapped.cs +++ b/analyzers/src/SonarAnalyzer.CSharp/Rules/NativeMethodsShouldBeWrapped.cs @@ -40,7 +40,7 @@ protected override void Initialize(SonarAnalysisContext context) private static void ReportPublicExternalMethods(SymbolAnalysisContext c) { var methodSymbol = (IMethodSymbol)c.Symbol; - if ((methodSymbol.IsExtern || methodSymbol.HasAttribute(KnownType.System_Runtime_InteropServices_LibraryImportAttribute)) + if (IsExternMethod(methodSymbol) && methodSymbol.IsPubliclyAccessible()) { foreach (var methodDeclaration in methodSymbol.DeclaringSyntaxReferences @@ -53,6 +53,9 @@ private static void ReportPublicExternalMethods(SymbolAnalysisContext c) } } + private static bool IsExternMethod(IMethodSymbol methodSymbol) => + methodSymbol.IsExtern || methodSymbol.HasAttribute(KnownType.System_Runtime_InteropServices_LibraryImportAttribute); + private static void ReportTrivialWrappers(SyntaxNodeAnalysisContext c) { var methodDeclaration = (MethodDeclarationSyntax)c.Node; @@ -102,7 +105,7 @@ a.Expression is LiteralExpressionSyntax private static ISet GetExternalMethods(IMethodSymbol methodSymbol) => methodSymbol.ContainingType.GetMembers() .OfType() - .Where(m => m.IsExtern) + .Where(IsExternMethod) .ToHashSet(); private static IEnumerable GetBodyDescendants(MethodDeclarationSyntax methodDeclaration) => diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs index 69c6785313d..957d70b8152 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs @@ -5,7 +5,20 @@ public static unsafe partial class ExternMethods { [System.Runtime.InteropServices.DllImportAttribute("foo.dll", EntryPoint = "DllImportAttributeAppliedToThisFunction", ExactSpelling = true)] public static extern partial void DllImportAttributeAppliedToThisFunction(); - + } +} +namespace LibraryImportAttributeTests +{ + public static unsafe partial class ExternMethods + { + [System.Runtime.InteropServices.DllImportAttribute("foo.dll", EntryPoint = "CompliantDllImportAttributeAppliedToThisFunction", ExactSpelling = true)] + private static extern partial void CompliantDllImportAttributeAppliedToThisFunction(int i); + } +} +namespace LibraryImportAttributeTests +{ + public static unsafe partial class ExternMethods + { [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "7.0.7.6804")] [System.Runtime.CompilerServices.SkipLocalsInitAttribute] public static partial void DllImportAttributeAppliedToGeneratedLocalFunction(string p) @@ -36,3 +49,38 @@ public static partial void DllImportAttributeAppliedToGeneratedLocalFunction(str } } } +namespace LibraryImportAttributeTests +{ + public static unsafe partial class ExternMethods + { + [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "7.0.7.6804")] + [System.Runtime.CompilerServices.SkipLocalsInitAttribute] + private static partial void CompliantDllImportAttributeAppliedToGeneratedLocalFunction(string p) + { + byte* __p_native = default; + // Setup - Perform required setup. + global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn __p_native__marshaller = new(); + try + { + // Marshal - Convert managed data to native data. + byte* __p_native__stackptr = stackalloc byte[global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize]; + __p_native__marshaller.FromManaged(p, new System.Span(__p_native__stackptr, global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller.ManagedToUnmanagedIn.BufferSize)); + { + // PinnedMarshal - Convert managed data to native data that requires the managed data to be pinned. + __p_native = __p_native__marshaller.ToUnmanaged(); + __PInvoke(__p_native); + } + } + finally + { + // Cleanup - Perform required cleanup. + __p_native__marshaller.Free(); + } + + // Local P/Invoke + [System.Runtime.InteropServices.DllImportAttribute("foo.dll", EntryPoint = "CompliantDllImportAttributeAppliedToGeneratedLocalFunction", ExactSpelling = true)] + static extern unsafe void __PInvoke(byte* p); + } + } +} + diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs index e53614384e2..3841a61b72c 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs @@ -11,12 +11,31 @@ public interface IInterface namespace LibraryImportAttributeTests { + // Copy the class to a .Net 7 project in VS and use "goto definition" on the methods to extract the code generated by the Microsoft.Interop.LibraryImportGenerator public static partial class ExternMethods { [LibraryImport("foo.dll")] public static partial void DllImportAttributeAppliedToThisFunction(); // Noncompliant + [LibraryImport("foo.dll")] + private static partial void CompliantDllImportAttributeAppliedToThisFunction(int i); // Compliant + [LibraryImport("foo.dll", StringMarshalling = StringMarshalling.Utf8)] public static partial void DllImportAttributeAppliedToGeneratedLocalFunction(string p); // Noncompliant + + [LibraryImport("foo.dll", StringMarshalling = StringMarshalling.Utf8)] + private static partial void CompliantDllImportAttributeAppliedToGeneratedLocalFunction(string p); // Compliant + + // Wrapper tests + + public static void CompliantDllImportAttributeAppliedToThisFunctionWrapper(int i) // Noncompliant + { + CompliantDllImportAttributeAppliedToThisFunction(i); + } + + public static void CompliantDllImportAttributeAppliedToGeneratedLocalFunctionWrapper(string p) // Noncompliant + { + CompliantDllImportAttributeAppliedToGeneratedLocalFunction(p); + } } } From 01427903eaeb9ee25d8f5483c7ab1b053cd41741 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 5 Jan 2023 14:08:19 +0100 Subject: [PATCH 07/11] Add message to assertion --- .../TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs index 3841a61b72c..2cfbf73f219 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs @@ -28,7 +28,7 @@ public static partial class ExternMethods // Wrapper tests - public static void CompliantDllImportAttributeAppliedToThisFunctionWrapper(int i) // Noncompliant + public static void CompliantDllImportAttributeAppliedToThisFunctionWrapper(int i) // Noncompliant {{Make this wrapper for native method 'CompliantDllImportAttributeAppliedToThisFunction' less trivial.}} { CompliantDllImportAttributeAppliedToThisFunction(i); } From 3e0a78138220d24b273d898efc5ba269c72dfc45 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 5 Jan 2023 14:09:23 +0100 Subject: [PATCH 08/11] Use expression body function in one test case --- .../TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs index 2cfbf73f219..7e8a2f4ebb3 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs @@ -34,8 +34,6 @@ public static partial class ExternMethods } public static void CompliantDllImportAttributeAppliedToGeneratedLocalFunctionWrapper(string p) // Noncompliant - { - CompliantDllImportAttributeAppliedToGeneratedLocalFunction(p); - } + => CompliantDllImportAttributeAppliedToGeneratedLocalFunction(p); } } From 7165f434d30688f5d4978ba6f0c62dc5086c26cc Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 11 Jan 2023 16:11:29 +0100 Subject: [PATCH 09/11] Add compliant wrapper --- .../TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs index 7e8a2f4ebb3..19776f847d4 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestCases/NativeMethodsShouldBeWrapped.CSharp11.cs @@ -28,11 +28,19 @@ public static partial class ExternMethods // Wrapper tests - public static void CompliantDllImportAttributeAppliedToThisFunctionWrapper(int i) // Noncompliant {{Make this wrapper for native method 'CompliantDllImportAttributeAppliedToThisFunction' less trivial.}} + public static void CompliantDllImportAttributeAppliedToThisFunctionNoncompliantWrapper(int i) // Noncompliant {{Make this wrapper for native method 'CompliantDllImportAttributeAppliedToThisFunction' less trivial.}} { CompliantDllImportAttributeAppliedToThisFunction(i); } + public static void CompliantDllImportAttributeAppliedToThisFunctionCompliantWrapper(int i) // Compliant + { + if (i > 0) + { + CompliantDllImportAttributeAppliedToThisFunction(i); + } + } + public static void CompliantDllImportAttributeAppliedToGeneratedLocalFunctionWrapper(string p) // Noncompliant => CompliantDllImportAttributeAppliedToGeneratedLocalFunction(p); } From 804ef7e2c4637b67af49af02487f235b06235882 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Mon, 16 Jan 2023 08:34:50 +0100 Subject: [PATCH 10/11] Add a comment about re-generating the SG code. --- .../Rules/NativeMethodsShouldBeWrappedTest.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs index e0b76a4b3e4..248384f4d64 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs @@ -41,6 +41,11 @@ public void NativeMethodsShouldBeWrapped_CSharp9() => public void NativeMethodsShouldBeWrapped_CSharp10() => builder.AddPaths("NativeMethodsShouldBeWrapped.CSharp10.cs").WithOptions(ParseOptionsHelper.FromCSharp10).Verify(); + // NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs contains the code as generated by the SourceGenerator. To regenerate it: + // * Take the code from NativeMethodsShouldBeWrapped.CSharp11.cs + // * Copy it to a new .Net 7 project + // * press F12 on any of the partial methods + // * copy the result to NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs [TestMethod] public void NativeMethodsShouldBeWrapped_CSharp11() => builder From 88283c03afdb96f47ef4d5d8812a4c00bb835281 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Mon, 16 Jan 2023 08:35:32 +0100 Subject: [PATCH 11/11] Grammar --- .../Rules/NativeMethodsShouldBeWrappedTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs index 248384f4d64..f4791f5b030 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/NativeMethodsShouldBeWrappedTest.cs @@ -44,8 +44,8 @@ public void NativeMethodsShouldBeWrapped_CSharp10() => // NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs contains the code as generated by the SourceGenerator. To regenerate it: // * Take the code from NativeMethodsShouldBeWrapped.CSharp11.cs // * Copy it to a new .Net 7 project - // * press F12 on any of the partial methods - // * copy the result to NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs + // * Press F12 on any of the partial methods + // * Copy the result to NativeMethodsShouldBeWrapped.CSharp11.SourceGenerator.cs [TestMethod] public void NativeMethodsShouldBeWrapped_CSharp11() => builder