From 5114a073641d5a4ba0e96ceff0a6c76bf86bd518 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Wed, 23 Aug 2023 10:35:32 -0700 Subject: [PATCH 1/9] Add support for generating the DisableRuntimeMarshalling attribute --- .../PInvokeGenerator.VisitDecl.cs | 15 ++-- .../PInvokeGenerator.cs | 77 ++++++++++++++++--- .../PInvokeGeneratorConfiguration.cs | 2 + .../PInvokeGeneratorConfigurationOptions.cs | 2 + sources/ClangSharpPInvokeGenerator/Program.cs | 7 ++ 5 files changed, 86 insertions(+), 17 deletions(-) diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs index 7324752a..1ee2d36c 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs @@ -418,9 +418,9 @@ private void VisitFieldDecl(FieldDecl fieldDecl) var type = fieldDecl.Type; var typeName = GetRemappedTypeName(fieldDecl, context: null, type, out var nativeTypeName); - if (typeName == "bool") + if (!_config.GenerateDisableRuntimeMarshalling && (typeName == "bool")) { - // bool is not blittable, so we shouldn't use it for structs that may be in P/Invoke signatures + // bool is not blittable when DisableRuntimeMarshalling is not specified, so we shouldn't use it for structs that may be in P/Invoke signatures typeName = "byte"; nativeTypeName = string.IsNullOrWhiteSpace(nativeTypeName) ? "bool" : nativeTypeName; } @@ -429,7 +429,7 @@ private void VisitFieldDecl(FieldDecl fieldDecl) { // bool* is not blittable in compat mode, so we shouldn't use it for structs that may be in P/Invoke signatures typeName = typeName.Replace("bool*", "byte*"); - nativeTypeName = string.IsNullOrWhiteSpace(nativeTypeName) ? typeName.Replace("byte*", "bool *") : nativeTypeName; + nativeTypeName = string.IsNullOrWhiteSpace(nativeTypeName) ? typeName.Replace("byte*", "bool*") : nativeTypeName; } var parent = fieldDecl.Parent; @@ -555,9 +555,9 @@ private void VisitFunctionDecl(FunctionDecl functionDecl) if (isVirtual || (body is null)) { - if (returnTypeName == "bool") + if (!_config.GenerateDisableRuntimeMarshalling && (returnTypeName == "bool")) { - // bool is not blittable, so we shouldn't use it for P/Invoke signatures + // bool is not blittable when DisableRuntimeMarshalling is not specified, so we shouldn't use it for P/Invoke signatures returnTypeName = "byte"; nativeTypeName = string.IsNullOrWhiteSpace(nativeTypeName) ? "bool" : nativeTypeName; } @@ -566,7 +566,7 @@ private void VisitFunctionDecl(FunctionDecl functionDecl) { // bool* is not blittable in compat mode, so we shouldn't use it for P/Invoke signatures returnTypeName = returnTypeName.Replace("bool*", "byte*"); - nativeTypeName = string.IsNullOrWhiteSpace(nativeTypeName) ? returnTypeName.Replace("byte*", "bool *") : nativeTypeName; + nativeTypeName = string.IsNullOrWhiteSpace(nativeTypeName) ? returnTypeName.Replace("byte*", "bool*") : nativeTypeName; } } @@ -2306,8 +2306,9 @@ void OutputVtblHelperMethod(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethod body.Write(')'); - if (returnTypeName == "bool") + if (!_config.GenerateDisableRuntimeMarshalling && (returnTypeName == "bool")) { + // bool is not blittable when DisableRuntimeMarshalling is not specified, so we shouldn't use it for P/Invoke signatures body.Write(" != 0"); } diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs index 55b73055..5619dbea 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs @@ -357,6 +357,7 @@ public void Close() Debug.Assert(leaveStreamOpen is true); } + GenerateDisableRuntimeMarshallingAttribute(this, stream, leaveStreamOpen); GenerateNativeBitfieldAttribute(this, stream, leaveStreamOpen); GenerateNativeInheritanceAttribute(this, stream, leaveStreamOpen); GenerateNativeTypeNameAttribute(this, stream, leaveStreamOpen); @@ -404,6 +405,39 @@ public void Close() _uuidsToGenerate.Clear(); _visitedFiles.Clear(); + static void GenerateDisableRuntimeMarshallingAttribute(PInvokeGenerator generator, Stream? stream, bool leaveStreamOpen) + { + var config = generator.Config; + + if (!config.GenerateDisableRuntimeMarshalling) + { + return; + } + + if (stream is null) + { + var outputPath = Path.Combine(config.OutputLocation, "DisableRuntimeMarshalling.cs"); + stream = generator._outputStreamFactory(outputPath); + } + + using var sw = new StreamWriter(stream, s_defaultStreamWriterEncoding, DefaultStreamWriterBufferSize, leaveStreamOpen); + sw.NewLine = "\n"; + + if (config.HeaderText != string.Empty) + { + sw.WriteLine(config.HeaderText); + } + + sw.WriteLine("using System.Runtime.CompilerServices;"); + sw.WriteLine(); + sw.WriteLine("[assembly: DisableRuntimeMarshalling]"); + + if (!leaveStreamOpen) + { + stream = null; + } + } + static void GenerateNativeBitfieldAttribute(PInvokeGenerator generator, Stream? stream, bool leaveStreamOpen) { var config = generator.Config; @@ -3148,9 +3182,9 @@ private string GetTargetTypeName(Cursor cursor, out string nativeTypeName) { targetTypeName = GetRemappedTypeName(parmVarDecl, context: null, parmVarDecl.Type, out nativeTypeName); - if ((parmVarDecl.ParentFunctionOrMethod is FunctionDecl functionDecl) && ((functionDecl is CXXMethodDecl { IsVirtual: true }) || (functionDecl.Body is null)) && (targetTypeName == "bool")) + if (!_config.GenerateDisableRuntimeMarshalling && (parmVarDecl.ParentFunctionOrMethod is FunctionDecl functionDecl) && ((functionDecl is CXXMethodDecl { IsVirtual: true }) || (functionDecl.Body is null)) && (targetTypeName == "bool")) { - // bool is not blittable, so we shouldn't use it for P/Invoke signatures + // bool is not blittable when DisableRuntimeMarshalling is not specified, so we shouldn't use it for P/Invoke signatures targetTypeName = "byte"; nativeTypeName = string.IsNullOrWhiteSpace(nativeTypeName) ? "bool" : nativeTypeName; } @@ -3263,6 +3297,15 @@ private string GetTypeName(Cursor? cursor, Cursor? context, Type rootType, Type } case CXType_Char16: + { + if (_config.GenerateDisableRuntimeMarshalling) + { + result.typeName = (cursor is null) ? "Char" : "char"; + break; + } + goto case CXType_UShort; + } + case CXType_UShort: { result.typeName = (cursor is null) ? "UInt16" : "ushort"; @@ -3309,7 +3352,7 @@ private string GetTypeName(Cursor? cursor, Cursor? context, Type rootType, Type } else { - goto case CXType_UShort; + goto case CXType_Char16; } } @@ -3540,9 +3583,9 @@ private string GetTypeName(Cursor? cursor, Cursor? context, Type rootType, Type } } - if (typeName == "bool") + if (!_config.GenerateDisableRuntimeMarshalling && (typeName == "bool")) { - // bool is not blittable, so we shouldn't use it for P/Invoke signatures + // bool is not blittable when DisableRuntimeMarshalling is not specified, so we shouldn't use it for P/Invoke signatures typeName = "byte"; } @@ -3648,9 +3691,9 @@ private string GetTypeNameForPointeeType(Cursor? cursor, Cursor? context, Type r var needsReturnFixup = false; var returnTypeName = GetRemappedTypeName(cursor, context: null, functionType.ReturnType, out _, skipUsing: true); - if (returnTypeName == "bool") + if (!_config.GenerateDisableRuntimeMarshalling && (returnTypeName == "bool")) { - // bool is not blittable, so we shouldn't use it for P/Invoke signatures + // bool is not blittable when DisableRuntimeMarshalling is not specified, so we shouldn't use it for P/Invoke signatures returnTypeName = "byte"; } @@ -3722,9 +3765,9 @@ private string GetTypeNameForPointeeType(Cursor? cursor, Cursor? context, Type r { var typeName = GetRemappedTypeName(cursor, context: null, paramType, out _, skipUsing: true); - if (typeName == "bool") + if (!_config.GenerateDisableRuntimeMarshalling && (typeName == "bool")) { - // bool is not blittable, so we shouldn't use it for P/Invoke signatures + // bool is not blittable when DisableRuntimeMarshalling is not specified, so we shouldn't use it for P/Invoke signatures typeName = "byte"; } @@ -5520,8 +5563,12 @@ private bool IsUnchecked(string targetTypeName, Stmt stmt) { switch (targetTypeName) { + case "bool": + case "Boolean": case "byte": case "Byte": + case "char": + case "Char": case "ushort": case "UInt16": case "uint": @@ -5698,6 +5745,13 @@ private static bool IsUnchecked(string typeName, long signedValue, bool isNegati return unsignedValue is < byte.MinValue or > byte.MaxValue; } + case "char": + case "Char": + { + var unsignedValue = unchecked((ulong)signedValue); + return unsignedValue is < char.MinValue or > char.MaxValue; + } + case "ushort": case "UInt16": { @@ -5844,12 +5898,15 @@ private static bool IsUnsigned(string typeName) { case "byte": case "Byte": - case "UInt16": + case "char": + case "Char": case "nuint": + case "UInt16": case "uint": case "UInt32": case "ulong": case "UInt64": + case "UIntPtr": case "ushort": case var _ when typeName.EndsWith("*"): { diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs index a662a949..db43d19a 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs @@ -216,6 +216,8 @@ public IReadOnlyCollection ExcludedNames public bool GenerateCppAttributes => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateCppAttributes); + public bool GenerateDisableRuntimeMarshalling => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateDisableRuntimeMarshalling); + public bool GenerateDocIncludes => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateDocIncludes); public bool GenerateExplicitVtbls => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls); diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs index 99f7d604..c374c19f 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs @@ -80,4 +80,6 @@ public enum PInvokeGeneratorConfigurationOptions : ulong GenerateLatestCode = 1UL << 34, GenerateNativeBitfieldAttribute = 1UL << 35, + + GenerateDisableRuntimeMarshalling = 1UL << 36, } diff --git a/sources/ClangSharpPInvokeGenerator/Program.cs b/sources/ClangSharpPInvokeGenerator/Program.cs index 9fe74bd7..4996207a 100644 --- a/sources/ClangSharpPInvokeGenerator/Program.cs +++ b/sources/ClangSharpPInvokeGenerator/Program.cs @@ -109,6 +109,7 @@ public class Program new TwoColumnHelpRow("generate-aggressive-inlining", "[MethodImpl(MethodImplOptions.AggressiveInlining)] should be added to generated helper functions."), new TwoColumnHelpRow("generate-cpp-attributes", "[CppAttributeList(\"\")] should be generated to document the encountered C++ attributes."), + new TwoColumnHelpRow("generate-disable-runtime-marshalling", "[assembly: DisableRuntimeMarshalling] should be generated."), new TwoColumnHelpRow("generate-doc-includes", " xml documentation tags should be generated for declarations."), new TwoColumnHelpRow("generate-file-scoped-namespaces", "Namespaces should be scoped to the file to reduce nesting."), new TwoColumnHelpRow("generate-guid-member", "Types with an associated GUID should have a corresponding member generated."), @@ -564,6 +565,12 @@ public static void Run(InvocationContext context) break; } + case "generate-disable-runtime-marshalling": + { + configOptions |= PInvokeGeneratorConfigurationOptions.GenerateDisableRuntimeMarshalling; + break; + } + case "generate-doc-includes": { configOptions |= PInvokeGeneratorConfigurationOptions.GenerateDocIncludes; From d047868ca0c6a4533b8ed03bb2b546c9e4c8bea6 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 15 Oct 2023 07:47:46 -0700 Subject: [PATCH 2/9] Add support for CallConvMemberFunction --- .../Abstractions/CallConv.cs | 13 +++++ .../Abstractions/FunctionOrDelegateDesc.cs | 2 +- .../CSharp/CSharpOutputBuilder.VisitDecl.cs | 6 +-- .../Extensions/StringExtensions.cs | 13 ++--- .../PInvokeGenerator.cs | 54 ++++++++++++------- .../PInvokeGeneratorConfiguration.cs | 2 + .../PInvokeGeneratorConfigurationOptions.cs | 2 + .../XML/XmlOutputBuilder.VisitDecl.cs | 4 +- sources/ClangSharpPInvokeGenerator/Program.cs | 7 +++ 9 files changed, 72 insertions(+), 31 deletions(-) create mode 100644 sources/ClangSharp.PInvokeGenerator/Abstractions/CallConv.cs diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/CallConv.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/CallConv.cs new file mode 100644 index 00000000..6dc83a24 --- /dev/null +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/CallConv.cs @@ -0,0 +1,13 @@ +// Copyright © Tanner Gooding and Contributors. Licensed under the MIT License (MIT). See License.md in the repository root for more information. + +namespace ClangSharp.Abstractions; + +internal enum CallConv +{ + Winapi = 1, + Cdecl = 2, + StdCall = 3, + ThisCall = 4, + FastCall = 5, + MemberFunction = 6, +} diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs index 555dae8f..e33fc682 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs @@ -15,7 +15,7 @@ internal struct FunctionOrDelegateDesc public string ParentName { get; set; } public string? LibraryPath { get; set; } public string ReturnType { get; set; } - public CallingConvention CallingConvention { get; set; } + public CallConv CallingConvention { get; set; } public FunctionOrDelegateFlags Flags { get; set; } public long? VtblIndex { get; set; } public CXSourceLocation? Location { get; set; } diff --git a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs index 83049da6..3edec5fd 100644 --- a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs @@ -393,7 +393,7 @@ public void BeginFunctionOrDelegate(in FunctionOrDelegateDesc desc, ref bool isM AddUsingDirective("System.Runtime.InteropServices"); WriteIndented("[UnmanagedFunctionPointer"); - if (desc.CallingConvention != CallingConvention.Winapi) + if (desc.CallingConvention != CallConv.Winapi) { Write("(CallingConvention."); Write(desc.CallingConvention); @@ -414,7 +414,7 @@ public void BeginFunctionOrDelegate(in FunctionOrDelegateDesc desc, ref bool isM Write(", "); - if (desc.CallingConvention != CallingConvention.Winapi) + if (desc.CallingConvention != CallConv.Winapi) { Write("CallingConvention = CallingConvention."); Write(desc.CallingConvention); @@ -568,7 +568,7 @@ public void BeginFunctionInnerPrototype(in FunctionOrDelegateDesc desc) { Write("delegate* unmanaged"); - if (desc.CallingConvention != CallingConvention.Winapi) + if (desc.CallingConvention != CallConv.Winapi) { Write('['); Write(desc.CallingConvention); diff --git a/sources/ClangSharp.PInvokeGenerator/Extensions/StringExtensions.cs b/sources/ClangSharp.PInvokeGenerator/Extensions/StringExtensions.cs index 3d13b023..c47b8074 100644 --- a/sources/ClangSharp.PInvokeGenerator/Extensions/StringExtensions.cs +++ b/sources/ClangSharp.PInvokeGenerator/Extensions/StringExtensions.cs @@ -31,13 +31,14 @@ public static string NormalizeFullPath(this string str) _ => "public" }; - public static string AsString(this CallingConvention value, bool isForFnPtr) => value switch + public static string AsString(this CallConv value, bool isForFnPtr) => value switch { - CallingConvention.Winapi => "Winapi", - CallingConvention.Cdecl => "Cdecl", - CallingConvention.StdCall => isForFnPtr ? "Stdcall" : "StdCall", - CallingConvention.ThisCall => isForFnPtr ? "Thiscall" : "ThisCall", - CallingConvention.FastCall => isForFnPtr ? "Fastcall" : "FastCall", + CallConv.Winapi => "Winapi", + CallConv.Cdecl => "Cdecl", + CallConv.StdCall => isForFnPtr ? "Stdcall" : "StdCall", + CallConv.ThisCall => isForFnPtr ? "Thiscall" : "ThisCall", + CallConv.FastCall => isForFnPtr ? "Fastcall" : "FastCall", + CallConv.MemberFunction => "MemberFunction", _ => throw new ArgumentOutOfRangeException(nameof(value), value, null) }; } diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs index 5619dbea..375bfc43 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs @@ -2396,13 +2396,21 @@ private BitfieldDesc[] GetBitfieldDescs(RecordDecl recordDecl) return bitfieldDescs.ToArray(); } - private CallingConvention GetCallingConvention(Cursor? cursor, Cursor? context, Type type) + private CallConv GetCallingConvention(Cursor? cursor, Cursor? context, Type type) { if (cursor is FunctionDecl functionDecl) { if (functionDecl.IsVariadic) { - return CallingConvention.Cdecl; + return CallConv.Cdecl; + } + + if (_config.GenerateCallConvMemberFunction) + { + if ((cursor is CXXMethodDecl cxxMethodDecl) && cxxMethodDecl.IsInstance) + { + return CallConv.MemberFunction; + } } } @@ -2410,7 +2418,7 @@ private CallingConvention GetCallingConvention(Cursor? cursor, Cursor? context, { if (TryGetRemappedValue(namedDecl, _config.WithCallConvs, out var callConv, matchStar: true)) { - if (Enum.TryParse(callConv, true, out var remappedCallingConvention)) + if (Enum.TryParse(callConv, true, out var remappedCallingConvention)) { return remappedCallingConvention; } @@ -2422,14 +2430,22 @@ private CallingConvention GetCallingConvention(Cursor? cursor, Cursor? context, return GetCallingConvention(cursor, context, type, ref wasRemapped); } - private CallingConvention GetCallingConvention(Cursor? cursor, Cursor? context, Type type, ref bool wasRemapped) + private CallConv GetCallingConvention(Cursor? cursor, Cursor? context, Type type, ref bool wasRemapped) { var remappedName = GetRemappedTypeName(cursor, context, type, out _, ignoreTransparentStructsWhereRequired: false, skipUsing: true); if (_config.WithCallConvs.TryGetValue(remappedName, out var callConv) || _config.WithCallConvs.TryGetValue("*", out callConv)) { - if (Enum.TryParse(callConv, true, out var remappedCallingConvention)) + if (Enum.TryParse(callConv, true, out var remappedCallingConvention)) { + if (_config.GenerateCallConvMemberFunction) + { + if ((cursor is CXXMethodDecl cxxMethodDecl) && cxxMethodDecl.IsInstance) + { + return CallConv.MemberFunction; + } + } + wasRemapped = true; return remappedCallingConvention; } @@ -2450,27 +2466,27 @@ private CallingConvention GetCallingConvention(Cursor? cursor, Cursor? context, case CX_AttrKind_MSABI: case CX_AttrKind_SysVABI: { - return CallingConvention.Winapi; + return CallConv.Winapi; } case CX_AttrKind_CDecl: { - return CallingConvention.Cdecl; + return CallConv.Cdecl; } case CX_AttrKind_FastCall: { - return CallingConvention.FastCall; + return CallConv.FastCall; } case CX_AttrKind_StdCall: { - return CallingConvention.StdCall; + return CallConv.StdCall; } case CX_AttrKind_ThisCall: { - return CallingConvention.ThisCall; + return _config.GenerateCallConvMemberFunction ? CallConv.MemberFunction : CallConv.ThisCall; } case CX_AttrKind_AArch64VectorPcs: @@ -2499,33 +2515,33 @@ private CallingConvention GetCallingConvention(Cursor? cursor, Cursor? context, case CXCallingConv_C: { return ((cursor is CXXMethodDecl cxxMethodDecl) && cxxMethodDecl.IsInstance) - ? CallingConvention.ThisCall - : CallingConvention.Cdecl; + ? (_config.GenerateCallConvMemberFunction ? CallConv.MemberFunction : CallConv.ThisCall) + : CallConv.Cdecl; } case CXCallingConv_X86StdCall: { - return CallingConvention.StdCall; + return CallConv.StdCall; } case CXCallingConv_X86FastCall: { - return CallingConvention.FastCall; + return CallConv.FastCall; } case CXCallingConv_X86ThisCall: { - return CallingConvention.ThisCall; + return _config.GenerateCallConvMemberFunction ? CallConv.MemberFunction : CallConv.ThisCall; } case CXCallingConv_Win64: { - return CallingConvention.Winapi; + return CallConv.Winapi; } default: { - const CallingConvention Name = CallingConvention.Winapi; + const CallConv Name = CallConv.Winapi; AddDiagnostic(DiagnosticLevel.Warning, $"Unsupported calling convention: '{callingConv}'. Falling back to '{Name}'.", cursor); return Name; } @@ -3708,7 +3724,7 @@ private string GetTypeNameForPointeeType(Cursor? cursor, Cursor? context, Type r _ = nameBuilder.Append(" unmanaged"); var hasSuppressGCTransition = HasSuppressGCTransition(cursor); - if (callConv != CallingConvention.Winapi) + if (callConv != CallConv.Winapi) { _ = nameBuilder.Append('['); _ = nameBuilder.Append(callConv.AsString(true)); @@ -5955,7 +5971,7 @@ private bool NeedsReturnFixup(CXXMethodDecl cxxMethodDecl) } else if (IsType(cxxMethodDecl, cxxMethodDecl.ReturnType)) { - needsReturnFixup = true; + needsReturnFixup = !_config.GenerateCallConvMemberFunction; } else { diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs index db43d19a..e9eb59af 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs @@ -212,6 +212,8 @@ public IReadOnlyCollection ExcludedNames public bool GenerateAggressiveInlining => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateAggressiveInlining); + public bool GenerateCallConvMemberFunction => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateCallConvMemberFunction); + public bool GenerateCompatibleCode => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode); public bool GenerateCppAttributes => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateCppAttributes); diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs index c374c19f..a654e7df 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs @@ -82,4 +82,6 @@ public enum PInvokeGeneratorConfigurationOptions : ulong GenerateNativeBitfieldAttribute = 1UL << 35, GenerateDisableRuntimeMarshalling = 1UL << 36, + + GenerateCallConvMemberFunction = 1UL << 37, } diff --git a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs index dcbbadad..0c688f91 100644 --- a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs @@ -108,7 +108,7 @@ public void BeginFunctionOrDelegate(in FunctionOrDelegateDesc desc, ref bool isM { Debug.Assert(!desc.HasFnPtrCodeGen); _ = _sb.Append($" xml documentation tags should be generated for declarations."), @@ -559,6 +560,12 @@ public static void Run(InvocationContext context) break; } + case "generate-callconv-member-function": + { + configOptions |= PInvokeGeneratorConfigurationOptions.GenerateCallConvMemberFunction; + break; + } + case "generate-cpp-attributes": { configOptions |= PInvokeGeneratorConfigurationOptions.GenerateCppAttributes; From 2bebf0e90cd222740cbc0a9d0e4cf56e28272183 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 15 Oct 2023 10:03:40 -0700 Subject: [PATCH 3/9] Resolve analyzer warnings and take advantage of new language features --- .../ClangSharp.Interop.csproj | 20 +- sources/ClangSharp.Interop/Configuration.cs | 5 +- .../Extensions/CXClientData.cs | 9 +- .../Extensions/CXCompileCommands.cs | 9 +- .../Extensions/CXDiagnostic.cs | 11 +- .../Internals/MarshaledString.cs | 2 +- .../Shims/MemberNotNullWhenAttribute.cs | 18 +- sources/ClangSharp.Interop/clang.cs | 2 +- .../Abstractions/BitfieldDesc.cs | 11 +- .../Abstractions/BitfieldRegion.cs | 12 + .../Abstractions/EnumDesc.cs | 2 +- .../Abstractions/EnumFlags.cs | 2 +- .../Abstractions/FunctionOrDelegateDesc.cs | 1 - .../Abstractions/StructFlags.cs | 2 +- .../{Abstractions => }/AccessSpecifier.cs | 4 +- .../CSharp/CSharpOutputBuilder.Visit.cs | 23 +- .../CSharp/CSharpOutputBuilder.VisitDecl.cs | 7 +- .../CSharp/CSharpOutputBuilder.cs | 50 +- .../ClangSharp.PInvokeGenerator.csproj | 2 + .../Extensions/StringExtensions.cs | 5 +- .../FunctionOrDelegateFlags.cs | 2 +- .../OutputBuilderFactory.cs | 2 +- .../PInvokeGenerator.VisitDecl.cs | 93 ++-- ...InvokeGenerator.VisitPreprocessedEntity.cs | 3 +- .../PInvokeGenerator.VisitStmt.cs | 49 +- .../PInvokeGenerator.cs | 525 +++++++++--------- .../PInvokeGeneratorConfiguration.cs | 47 +- .../PInvokeGeneratorConfigurationOptions.cs | 78 +-- .../XML/XmlOutputBuilder.Visit.cs | 9 +- .../XML/XmlOutputBuilder.VisitDecl.cs | 48 +- .../XML/XmlOutputBuilder.cs | 18 +- sources/ClangSharp/ClangSharp.csproj | 4 + sources/ClangSharp/Cursors/Cursor.cs | 3 +- sources/ClangSharp/Cursors/Decls/BlockDecl.cs | 2 +- .../Cursors/Decls/CXXConstructorDecl.cs | 1 - sources/ClangSharp/Cursors/Decls/Decl.cs | 2 +- sources/ClangSharp/Cursors/Exprs/CallExpr.cs | 2 +- .../Cursors/Exprs/CharacterLiteral.cs | 3 +- .../Cursors/Exprs/FloatingLiteral.cs | 3 +- .../Cursors/Exprs/IntegerLiteral.cs | 3 +- .../ClangSharp/Cursors/Stmts/CapturedStmt.cs | 4 +- sources/ClangSharp/TranslationUnit.cs | 18 +- sources/ClangSharpPInvokeGenerator/Program.cs | 369 ++++++------ .../Base/CXXMethodDeclarationTest.cs | 8 +- .../Base/EnumDeclarationTest.cs | 2 +- .../Base/FunctionDeclarationDllImportTest.cs | 2 +- .../Base/StructDeclarationTest.cs | 4 +- .../Base/UnionDeclarationTest.cs | 4 +- .../Base/VarDeclarationTest.cs | 4 +- .../StructDeclarationTest.cs | 3 +- .../UnionDeclarationTest.cs | 2 +- .../StructDeclarationTest.cs | 3 +- .../UnionDeclarationTest.cs | 2 +- .../StructDeclarationTest.cs | 3 +- .../CSharpDefaultUnix/UnionDeclarationTest.cs | 2 +- .../StructDeclarationTest.cs | 3 +- .../UnionDeclarationTest.cs | 2 +- .../CSharpLatestUnix/StructDeclarationTest.cs | 3 +- .../CSharpLatestUnix/UnionDeclarationTest.cs | 2 +- .../StructDeclarationTest.cs | 3 +- .../UnionDeclarationTest.cs | 2 +- .../StructDeclarationTest.cs | 3 +- .../CSharpPreviewUnix/UnionDeclarationTest.cs | 2 +- .../StructDeclarationTest.cs | 3 +- .../UnionDeclarationTest.cs | 2 +- .../CTest.cs | 8 +- ...angSharp.PInvokeGenerator.UnitTests.csproj | 3 + .../PInvokeGeneratorTest.cs | 89 ++- .../StructDeclarationTest.cs | 3 +- .../XmlCompatibleUnix/UnionDeclarationTest.cs | 2 +- .../StructDeclarationTest.cs | 3 +- .../UnionDeclarationTest.cs | 2 +- .../XmlDefaultUnix/StructDeclarationTest.cs | 3 +- .../XmlDefaultUnix/UnionDeclarationTest.cs | 2 +- .../StructDeclarationTest.cs | 3 +- .../XmlDefaultWindows/UnionDeclarationTest.cs | 2 +- .../XmlLatestUnix/StructDeclarationTest.cs | 3 +- .../XmlLatestUnix/UnionDeclarationTest.cs | 2 +- .../XmlLatestWindows/StructDeclarationTest.cs | 3 +- .../XmlLatestWindows/UnionDeclarationTest.cs | 2 +- .../XmlPreviewUnix/StructDeclarationTest.cs | 3 +- .../XmlPreviewUnix/UnionDeclarationTest.cs | 2 +- .../StructDeclarationTest.cs | 3 +- .../XmlPreviewWindows/UnionDeclarationTest.cs | 2 +- .../CXVirtualFileOverlayTest.cs | 28 +- .../ClangSharp.UnitTests.csproj | 2 + .../CursorTests/DeclTest.cs | 3 +- .../TranslationUnitTest.cs | 6 +- 88 files changed, 852 insertions(+), 876 deletions(-) create mode 100644 sources/ClangSharp.PInvokeGenerator/Abstractions/BitfieldRegion.cs rename sources/ClangSharp.PInvokeGenerator/{Abstractions => }/AccessSpecifier.cs (80%) diff --git a/sources/ClangSharp.Interop/ClangSharp.Interop.csproj b/sources/ClangSharp.Interop/ClangSharp.Interop.csproj index 70d1f97a..d2268b8d 100644 --- a/sources/ClangSharp.Interop/ClangSharp.Interop.csproj +++ b/sources/ClangSharp.Interop/ClangSharp.Interop.csproj @@ -2,7 +2,25 @@ - $(NoWarn);CA1069 + + + + + + + + + + + + + + + + + + + $(NoWarn);CA1003;CA1008;CA1027;CA1034;CA1051;CA1069;CA1305;CA1508;CA1707;CA1708;CA1710;CA1711;CA1712;CA1720;CA1721;CA1724;CA1815;CA2225 net8.0;netstandard2.0 diff --git a/sources/ClangSharp.Interop/Configuration.cs b/sources/ClangSharp.Interop/Configuration.cs index a7ba5829..52c84265 100644 --- a/sources/ClangSharp.Interop/Configuration.cs +++ b/sources/ClangSharp.Interop/Configuration.cs @@ -1,6 +1,9 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. using System; +using System.Runtime.InteropServices; + +[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories)] namespace ClangSharp.Interop; @@ -27,4 +30,4 @@ private static bool GetAppContextData(string name, bool defaultValue) return defaultValue; } } -} \ No newline at end of file +} diff --git a/sources/ClangSharp.Interop/Extensions/CXClientData.cs b/sources/ClangSharp.Interop/Extensions/CXClientData.cs index e044d9cf..589179fd 100644 --- a/sources/ClangSharp.Interop/Extensions/CXClientData.cs +++ b/sources/ClangSharp.Interop/Extensions/CXClientData.cs @@ -4,14 +4,9 @@ namespace ClangSharp.Interop; -public unsafe partial struct CXClientData : IEquatable +public unsafe partial struct CXClientData(IntPtr handle) : IEquatable { - public CXClientData(IntPtr handle) - { - Handle = handle; - } - - public IntPtr Handle { get; set; } + public IntPtr Handle { get; set; } = handle; public static explicit operator CXClientData(void* value) => new CXClientData((IntPtr)value); diff --git a/sources/ClangSharp.Interop/Extensions/CXCompileCommands.cs b/sources/ClangSharp.Interop/Extensions/CXCompileCommands.cs index 14b1dbd7..d5f19bd3 100644 --- a/sources/ClangSharp.Interop/Extensions/CXCompileCommands.cs +++ b/sources/ClangSharp.Interop/Extensions/CXCompileCommands.cs @@ -6,18 +6,13 @@ namespace ClangSharp.Interop; -public unsafe partial struct CXCompileCommands : IDisposable, IEquatable, IReadOnlyCollection +public unsafe partial struct CXCompileCommands(IntPtr handle) : IDisposable, IEquatable, IReadOnlyCollection { - public CXCompileCommands(IntPtr handle) - { - Handle = handle; - } - public readonly CXCompileCommand this[uint index] => GetCommand(index); public readonly int Count => (int)Size; - public IntPtr Handle { get; set; } + public IntPtr Handle { get; set; } = handle; public readonly uint Size => clang.CompileCommands_getSize(this); diff --git a/sources/ClangSharp.Interop/Extensions/CXDiagnostic.cs b/sources/ClangSharp.Interop/Extensions/CXDiagnostic.cs index 70ace825..873d549a 100644 --- a/sources/ClangSharp.Interop/Extensions/CXDiagnostic.cs +++ b/sources/ClangSharp.Interop/Extensions/CXDiagnostic.cs @@ -4,13 +4,8 @@ namespace ClangSharp.Interop; -public unsafe partial struct CXDiagnostic : IDisposable, IEquatable +public unsafe partial struct CXDiagnostic(IntPtr handle) : IDisposable, IEquatable { - public CXDiagnostic(IntPtr handle) - { - Handle = handle; - } - public static CXDiagnosticDisplayOptions DefaultDisplayOptions => (CXDiagnosticDisplayOptions)clang.defaultDiagnosticDisplayOptions(); public readonly uint Category => clang.getDiagnosticCategory(this); @@ -19,7 +14,7 @@ public CXDiagnostic(IntPtr handle) public readonly CXDiagnosticSet ChildDiagnostics => (CXDiagnosticSet)clang.getChildDiagnostics(this); - public IntPtr Handle { get; set; } + public IntPtr Handle { get; set; } = handle; public readonly CXSourceLocation Location => clang.getDiagnosticLocation(this); @@ -54,7 +49,7 @@ public void Dispose() public readonly CXString Format(CXDiagnosticDisplayOptions options) => clang.formatDiagnostic(this, (uint)options); - [Obsolete("Use " + nameof(CategoryText) + " instead.")] + [Obsolete($"Use {nameof(CategoryText)} instead.")] public static CXString GetCategoryName(uint category) => clang.getDiagnosticCategoryName(category); public readonly CXString GetFixIt(uint fixIt, out CXSourceRange replacementRange) diff --git a/sources/ClangSharp.Interop/Internals/MarshaledString.cs b/sources/ClangSharp.Interop/Internals/MarshaledString.cs index 1d6c64dc..152149c3 100644 --- a/sources/ClangSharp.Interop/Internals/MarshaledString.cs +++ b/sources/ClangSharp.Interop/Internals/MarshaledString.cs @@ -20,7 +20,7 @@ public MarshaledString(string? input) } else { - var valueBytes = (input.Length != 0) ? Encoding.UTF8.GetBytes(input) : Array.Empty(); + var valueBytes = (input.Length != 0) ? Encoding.UTF8.GetBytes(input) : []; length = valueBytes.Length; value = Marshal.AllocHGlobal(length + 1); Marshal.Copy(valueBytes, 0, value, length); diff --git a/sources/ClangSharp.Interop/Shims/MemberNotNullWhenAttribute.cs b/sources/ClangSharp.Interop/Shims/MemberNotNullWhenAttribute.cs index e21c3fc0..a129d411 100644 --- a/sources/ClangSharp.Interop/Shims/MemberNotNullWhenAttribute.cs +++ b/sources/ClangSharp.Interop/Shims/MemberNotNullWhenAttribute.cs @@ -3,21 +3,9 @@ namespace System.Diagnostics.CodeAnalysis; [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] -internal sealed class MemberNotNullWhenAttribute : Attribute +internal sealed class MemberNotNullWhenAttribute(bool returnValue, params string[] members) : Attribute { - public MemberNotNullWhenAttribute(bool returnValue, string member) - { - ReturnValue = returnValue; - Members = new[] { member }; - } + public bool ReturnValue { get; } = returnValue; - public MemberNotNullWhenAttribute(bool returnValue, params string[] members) - { - ReturnValue = returnValue; - Members = members; - } - - public bool ReturnValue { get; } - - public string[] Members { get; } + public string[] Members { get; } = members; } diff --git a/sources/ClangSharp.Interop/clang.cs b/sources/ClangSharp.Interop/clang.cs index 47baef81..38cbad3b 100644 --- a/sources/ClangSharp.Interop/clang.cs +++ b/sources/ClangSharp.Interop/clang.cs @@ -26,7 +26,7 @@ private static IntPtr OnDllImport(string libraryName, Assembly assembly, DllImpo return nativeLibrary; } - if (libraryName.Equals("libclang") && TryResolveClang(assembly, searchPath, out nativeLibrary)) + if (libraryName.Equals("libclang", StringComparison.Ordinal) && TryResolveClang(assembly, searchPath, out nativeLibrary)) { return nativeLibrary; } diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/BitfieldDesc.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/BitfieldDesc.cs index f5672d2d..0e2bf1bb 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/BitfieldDesc.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/BitfieldDesc.cs @@ -4,18 +4,9 @@ namespace ClangSharp.Abstractions; -public struct BitfieldDesc +internal struct BitfieldDesc { public Type TypeBacking { get; set; } public List Regions { get; set; } } - -public struct BitfieldRegion -{ - public string Name { get; set; } - - public long Offset { get; set; } - - public long Length { get; set; } -} diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/BitfieldRegion.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/BitfieldRegion.cs new file mode 100644 index 00000000..f41623d0 --- /dev/null +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/BitfieldRegion.cs @@ -0,0 +1,12 @@ +// Copyright © Tanner Gooding and Contributors. Licensed under the MIT License (MIT). See License.md in the repository root for more information. + +namespace ClangSharp.Abstractions; + +internal struct BitfieldRegion +{ + public string Name { get; set; } + + public long Offset { get; set; } + + public long Length { get; set; } +} diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/EnumDesc.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/EnumDesc.cs index 57d5a8d2..3ed8b718 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/EnumDesc.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/EnumDesc.cs @@ -3,7 +3,7 @@ namespace ClangSharp.Abstractions; -public struct EnumDesc +internal struct EnumDesc { public AccessSpecifier AccessSpecifier { get; set; } public string TypeName { get; set; } diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/EnumFlags.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/EnumFlags.cs index 0e773f28..37dadc63 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/EnumFlags.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/EnumFlags.cs @@ -5,7 +5,7 @@ namespace ClangSharp.Abstractions; [Flags] -public enum EnumFlags +internal enum EnumFlags { None = 0, Nested = 1 << 0, diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs index e33fc682..d05c90b3 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. using System; -using System.Runtime.InteropServices; using ClangSharp.Interop; namespace ClangSharp.Abstractions; diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/StructFlags.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/StructFlags.cs index e1dee003..db6962db 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/StructFlags.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/StructFlags.cs @@ -5,7 +5,7 @@ namespace ClangSharp.Abstractions; [Flags] -public enum StructFlags +internal enum StructFlags { None = 0, Unsafe = 1 << 0, diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/AccessSpecifier.cs b/sources/ClangSharp.PInvokeGenerator/AccessSpecifier.cs similarity index 80% rename from sources/ClangSharp.PInvokeGenerator/Abstractions/AccessSpecifier.cs rename to sources/ClangSharp.PInvokeGenerator/AccessSpecifier.cs index 38927c59..ee8aa6a6 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/AccessSpecifier.cs +++ b/sources/ClangSharp.PInvokeGenerator/AccessSpecifier.cs @@ -1,8 +1,8 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -namespace ClangSharp.Abstractions; +namespace ClangSharp; -public enum AccessSpecifier : byte +public enum AccessSpecifier { None, Public, diff --git a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs index c2f7a2fb..046ed538 100644 --- a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs +++ b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs @@ -1,36 +1,38 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. using System; +using System.Globalization; using System.Runtime.CompilerServices; namespace ClangSharp.CSharp; internal partial class CSharpOutputBuilder { - private bool _customAttrIsForParameter = false; + private bool _customAttrIsForParameter; + public void WriteCustomAttribute(string attribute, Action? callback = null) { - if (attribute.Equals("Flags") || attribute.Equals("Obsolete")) + if (attribute.Equals("Flags", StringComparison.Ordinal) || attribute.Equals("Obsolete", StringComparison.Ordinal)) { AddUsingDirective("System"); } - else if (attribute.Equals("EditorBrowsable") || attribute.StartsWith("EditorBrowsable(")) + else if (attribute.Equals("EditorBrowsable", StringComparison.Ordinal) || attribute.StartsWith("EditorBrowsable(", StringComparison.Ordinal)) { AddUsingDirective("System.ComponentModel"); } - else if (attribute.Equals("UnscopedRef")) + else if (attribute.Equals("UnscopedRef", StringComparison.Ordinal)) { AddUsingDirective("System.Diagnostics.CodeAnalysis"); } - else if (attribute.StartsWith("InlineArray(")) + else if (attribute.StartsWith("InlineArray(", StringComparison.Ordinal)) { AddUsingDirective("System.Runtime.CompilerServices"); } - else if (attribute.StartsWith("Guid(")|| attribute.Equals("Optional") || attribute.StartsWith("Optional, DefaultParameterValue(")) + else if (attribute.StartsWith("Guid(", StringComparison.Ordinal) || attribute.Equals("Optional", StringComparison.Ordinal) || attribute.StartsWith("Optional, DefaultParameterValue(", StringComparison.Ordinal)) { AddUsingDirective("System.Runtime.InteropServices"); } - else if (attribute.StartsWith("SupportedOSPlatform(")) + else if (attribute.StartsWith("SupportedOSPlatform(", StringComparison.Ordinal)) { AddUsingDirective("System.Runtime.Versioning"); } @@ -123,7 +125,12 @@ public void WriteIid(string name, Guid value) } else { - var valueString = value.ToString("X").ToUpperInvariant().Replace("{", "").Replace("}", "").Replace('X', 'x').Replace(",", ", "); + var valueString = value.ToString("X", CultureInfo.InvariantCulture) + .ToUpperInvariant() + .Replace("{", "", StringComparison.Ordinal) + .Replace("}", "", StringComparison.Ordinal) + .Replace('X', 'x') + .Replace(",", ", ", StringComparison.Ordinal); WriteIid(name, valueString); } } diff --git a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs index 3edec5fd..83b230fa 100644 --- a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs @@ -1,8 +1,8 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. +using System; using System.Diagnostics; using System.Globalization; -using System.Runtime.InteropServices; using ClangSharp.Abstractions; using ClangSharp.Interop; @@ -269,7 +269,7 @@ public void BeginEnum(in EnumDesc desc) Write(" enum "); Write(desc.EscapedName); - if (!desc.TypeName.Equals("int")) + if (!desc.TypeName.Equals("int", StringComparison.Ordinal)) { Write(" : "); Write(desc.TypeName); @@ -654,7 +654,8 @@ public void EndFunctionInnerPrototype(in FunctionOrDelegateDesc desc) public void BeginConstructorInitializer(string memberRefName, string memberInitName) { WriteIndentation(); - if (memberRefName.Equals(memberInitName)) + + if (memberRefName.Equals(memberInitName, StringComparison.Ordinal)) { Write("this"); Write('.'); diff --git a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs index 298454a1..40671131 100644 --- a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs +++ b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs @@ -1,44 +1,32 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. +using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.Text; namespace ClangSharp.CSharp; -internal sealed partial class CSharpOutputBuilder +internal sealed partial class CSharpOutputBuilder(string name, PInvokeGeneratorConfiguration config, string indentationString = CSharpOutputBuilder.DefaultIndentationString, + bool isTestOutput = false, MarkerMode markerMode = MarkerMode.None, + bool writeSourceLocation = false) { public const string DefaultIndentationString = " "; - private readonly string _name; - private readonly PInvokeGeneratorConfiguration _config; - private readonly List _contents; - private readonly StringBuilder _currentLine; - private readonly SortedSet _usingDirectives; - private readonly SortedSet _staticUsingDirectives; - private readonly string _indentationString; - private readonly bool _isTestOutput; + private readonly string _name = name; + private readonly PInvokeGeneratorConfiguration _config = config; + private readonly List _contents = []; + private readonly StringBuilder _currentLine = new StringBuilder(); + private readonly SortedSet _usingDirectives = []; + private readonly SortedSet _staticUsingDirectives = []; + private readonly string _indentationString = indentationString; + private readonly bool _isTestOutput = isTestOutput; private int _indentationLevel; private bool _isInMarkerInterface; - private readonly MarkerMode _markerMode; - private readonly bool _writeSourceLocation; - - public CSharpOutputBuilder(string name, PInvokeGeneratorConfiguration config, string indentationString = DefaultIndentationString, - bool isTestOutput = false, MarkerMode markerMode = MarkerMode.None, - bool writeSourceLocation = false) - { - _name = name; - _config = config; - _contents = new List(); - _currentLine = new StringBuilder(); - _usingDirectives = new SortedSet(); - _staticUsingDirectives = new SortedSet(); - _indentationString = indentationString; - _isTestOutput = isTestOutput; - _markerMode = markerMode; - _writeSourceLocation = writeSourceLocation; - } + private readonly MarkerMode _markerMode = markerMode; + private readonly bool _writeSourceLocation = writeSourceLocation; public IEnumerable Contents => _contents; @@ -62,7 +50,7 @@ public CSharpOutputBuilder(string name, PInvokeGeneratorConfiguration config, st public IEnumerable UsingDirectives => _usingDirectives; - public void AddUsingDirective(string namespaceName) => _ = namespaceName.StartsWith("static ") ? _staticUsingDirectives.Add(namespaceName) : _usingDirectives.Add(namespaceName); + public void AddUsingDirective(string namespaceName) => _ = namespaceName.StartsWith("static ", StringComparison.Ordinal) ? _staticUsingDirectives.Add(namespaceName) : _usingDirectives.Add(namespaceName); public void DecreaseIndentation() { @@ -161,7 +149,7 @@ public void WriteSemicolonIfNeeded() public void WriteValueAsBytes(ulong value, int sizeInChars) { Write("0x"); - Write(((byte)value).ToString("X2")); + Write(((byte)value).ToString("X2", CultureInfo.InvariantCulture)); for (var i = 1; i < sizeInChars; i++) { @@ -169,7 +157,7 @@ public void WriteValueAsBytes(ulong value, int sizeInChars) value >>= 8; Write("0x"); - Write(((byte)value).ToString("X2")); + Write(((byte)value).ToString("X2", CultureInfo.InvariantCulture)); } } @@ -315,7 +303,7 @@ private void AddNativeTypeNameAttribute(string nativeTypeName, string? prefix = { foreach (var entry in _config.NativeTypeNamesToStrip) { - nativeTypeName = nativeTypeName.Replace(entry, ""); + nativeTypeName = nativeTypeName.Replace(entry, "", StringComparison.Ordinal); } if (string.IsNullOrWhiteSpace(nativeTypeName)) diff --git a/sources/ClangSharp.PInvokeGenerator/ClangSharp.PInvokeGenerator.csproj b/sources/ClangSharp.PInvokeGenerator/ClangSharp.PInvokeGenerator.csproj index d2790af9..93876a29 100644 --- a/sources/ClangSharp.PInvokeGenerator/ClangSharp.PInvokeGenerator.csproj +++ b/sources/ClangSharp.PInvokeGenerator/ClangSharp.PInvokeGenerator.csproj @@ -2,6 +2,8 @@ + + $(NoWarn);CA1303 ClangSharp net8.0 diff --git a/sources/ClangSharp.PInvokeGenerator/Extensions/StringExtensions.cs b/sources/ClangSharp.PInvokeGenerator/Extensions/StringExtensions.cs index c47b8074..c995e34e 100644 --- a/sources/ClangSharp.PInvokeGenerator/Extensions/StringExtensions.cs +++ b/sources/ClangSharp.PInvokeGenerator/Extensions/StringExtensions.cs @@ -2,7 +2,6 @@ using System; using System.IO; -using System.Runtime.InteropServices; using ClangSharp.Abstractions; namespace ClangSharp; @@ -10,12 +9,12 @@ namespace ClangSharp; internal static class StringExtensions { public static string Unquote(this string str) - => str.StartsWith("\"") && str.EndsWith("\"") && !str.EndsWith("\\\"") + => str.StartsWith('\"') && str.EndsWith('\"') && !str.EndsWith("\\\"", StringComparison.Ordinal) ? str[1..^1] : str; public static string NormalizePath(this string str) - => str.Replace('\\', '/').Replace("//", "/"); + => str.Replace('\\', '/').Replace("//", "/", StringComparison.Ordinal); public static string NormalizeFullPath(this string str) => string.IsNullOrWhiteSpace(str) ? str : Path.GetFullPath(str).NormalizePath(); diff --git a/sources/ClangSharp.PInvokeGenerator/FunctionOrDelegateFlags.cs b/sources/ClangSharp.PInvokeGenerator/FunctionOrDelegateFlags.cs index 1dabadcd..aeb0eab6 100644 --- a/sources/ClangSharp.PInvokeGenerator/FunctionOrDelegateFlags.cs +++ b/sources/ClangSharp.PInvokeGenerator/FunctionOrDelegateFlags.cs @@ -3,7 +3,7 @@ namespace ClangSharp; [Flags] -public enum FunctionOrDelegateFlags +internal enum FunctionOrDelegateFlags { IsVirtual = 1 << 0, IsDllImport = 1 << 1, diff --git a/sources/ClangSharp.PInvokeGenerator/OutputBuilderFactory.cs b/sources/ClangSharp.PInvokeGenerator/OutputBuilderFactory.cs index 446e169f..eaa1dc9e 100644 --- a/sources/ClangSharp.PInvokeGenerator/OutputBuilderFactory.cs +++ b/sources/ClangSharp.PInvokeGenerator/OutputBuilderFactory.cs @@ -19,7 +19,7 @@ public OutputBuilderFactory(PInvokeGeneratorConfiguration config) { _config = config; _writeSourceLocation = config.GenerateSourceLocationAttribute; - _outputBuilders = new Dictionary(); + _outputBuilders = []; } public IEnumerable OutputBuilders => _outputBuilders.Values; diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs index 1ee2d36c..e579c456 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs @@ -280,7 +280,7 @@ private void VisitEnumConstantDecl(EnumConstantDecl enumConstantDecl) { parentName = GetRemappedCursorName(enumDecl); - if (parentName.StartsWith("__AnonymousEnum_")) + if (parentName.StartsWith("__AnonymousEnum_", StringComparison.Ordinal)) { parentName = ""; isAnonymousEnum = true; @@ -347,7 +347,7 @@ private void VisitEnumDecl(EnumDecl enumDecl) var escapedName = EscapeName(name); var isAnonymousEnum = false; - if (name.StartsWith("__AnonymousEnum_")) + if (name.StartsWith("__AnonymousEnum_", StringComparison.Ordinal)) { isAnonymousEnum = true; @@ -418,18 +418,18 @@ private void VisitFieldDecl(FieldDecl fieldDecl) var type = fieldDecl.Type; var typeName = GetRemappedTypeName(fieldDecl, context: null, type, out var nativeTypeName); - if (!_config.GenerateDisableRuntimeMarshalling && (typeName == "bool")) + if (!_config.GenerateDisableRuntimeMarshalling && typeName.Equals("bool", StringComparison.Ordinal)) { // bool is not blittable when DisableRuntimeMarshalling is not specified, so we shouldn't use it for structs that may be in P/Invoke signatures typeName = "byte"; nativeTypeName = string.IsNullOrWhiteSpace(nativeTypeName) ? "bool" : nativeTypeName; } - if (_config.GenerateCompatibleCode && typeName.StartsWith("bool*")) + if (_config.GenerateCompatibleCode && typeName.StartsWith("bool*", StringComparison.Ordinal)) { // bool* is not blittable in compat mode, so we shouldn't use it for structs that may be in P/Invoke signatures - typeName = typeName.Replace("bool*", "byte*"); - nativeTypeName = string.IsNullOrWhiteSpace(nativeTypeName) ? typeName.Replace("byte*", "bool*") : nativeTypeName; + typeName = typeName.Replace("bool*", "byte*", StringComparison.Ordinal); + nativeTypeName = string.IsNullOrWhiteSpace(nativeTypeName) ? typeName.Replace("byte*", "bool*", StringComparison.Ordinal) : nativeTypeName; } var parent = fieldDecl.Parent; @@ -462,13 +462,13 @@ private void VisitFieldDecl(FieldDecl fieldDecl) if (IsTypeConstantOrIncompleteArray(fieldDecl, type, out var arrayType)) { - var count = Math.Max((arrayType as ConstantArrayType)?.Size ?? 0, 1).ToString(); + var count = Math.Max((arrayType as ConstantArrayType)?.Size ?? 0, 1).ToString(CultureInfo.InvariantCulture); var elementType = arrayType.ElementType; while (IsTypeConstantOrIncompleteArray(fieldDecl, elementType, out var subArrayType)) { count += " * "; - count += Math.Max((subArrayType as ConstantArrayType)?.Size ?? 0, 1).ToString(); + count += Math.Max((subArrayType as ConstantArrayType)?.Size ?? 0, 1).ToString(CultureInfo.InvariantCulture); elementType = subArrayType.ElementType; } @@ -555,18 +555,18 @@ private void VisitFunctionDecl(FunctionDecl functionDecl) if (isVirtual || (body is null)) { - if (!_config.GenerateDisableRuntimeMarshalling && (returnTypeName == "bool")) + if (!_config.GenerateDisableRuntimeMarshalling && returnTypeName.Equals("bool", StringComparison.Ordinal)) { // bool is not blittable when DisableRuntimeMarshalling is not specified, so we shouldn't use it for P/Invoke signatures returnTypeName = "byte"; nativeTypeName = string.IsNullOrWhiteSpace(nativeTypeName) ? "bool" : nativeTypeName; } - if (_config.GenerateCompatibleCode && returnTypeName.StartsWith("bool*")) + if (_config.GenerateCompatibleCode && returnTypeName.StartsWith("bool*", StringComparison.Ordinal)) { // bool* is not blittable in compat mode, so we shouldn't use it for P/Invoke signatures - returnTypeName = returnTypeName.Replace("bool*", "byte*"); - nativeTypeName = string.IsNullOrWhiteSpace(nativeTypeName) ? returnTypeName.Replace("byte*", "bool*") : nativeTypeName; + returnTypeName = returnTypeName.Replace("bool*", "byte*", StringComparison.Ordinal); + nativeTypeName = string.IsNullOrWhiteSpace(nativeTypeName) ? returnTypeName.Replace("byte*", "bool*", StringComparison.Ordinal) : nativeTypeName; } } @@ -861,15 +861,15 @@ private void VisitIndirectFieldDecl(IndirectFieldDecl indirectFieldDecl) { var contextNamePart = GetRemappedCursorName(rootRecordDecl); - if (contextNamePart.StartsWith("_")) + if (contextNamePart.StartsWith('_')) { var suffixLength = 0; - if (contextNamePart.EndsWith("_e__Union")) + if (contextNamePart.EndsWith("_e__Union", StringComparison.Ordinal)) { suffixLength = 10; } - else if (contextNamePart.EndsWith("_e__Struct")) + else if (contextNamePart.EndsWith("_e__Struct", StringComparison.Ordinal)) { suffixLength = 11; } @@ -992,7 +992,7 @@ private void VisitIndirectFieldDecl(IndirectFieldDecl indirectFieldDecl) _outputBuilder.WriteRegularField(typeString, escapedName); - var isIndirectPointerField = IsTypePointerOrReference(indirectFieldDecl, type) && (typeName != "IntPtr") && (typeName != "UIntPtr"); + var isIndirectPointerField = IsTypePointerOrReference(indirectFieldDecl, type) && !typeName.Equals("IntPtr", StringComparison.Ordinal) && !typeName.Equals("UIntPtr", StringComparison.Ordinal); _outputBuilder.BeginBody(); _outputBuilder.BeginGetter(_config.GenerateAggressiveInlining, isReadOnly: fieldDecl.IsBitField && !Config.GenerateCompatibleCode); @@ -1179,7 +1179,7 @@ void ForFunctionDecl(ParmVarDecl parmVarDecl, FunctionDecl functionDecl) var index = parameters.IndexOf(parmVarDecl); var lastIndex = parameters.Count - 1; - if (name.Equals("param")) + if (name.Equals("param", StringComparison.Ordinal)) { escapedName += index; } @@ -1279,7 +1279,7 @@ void ForTypedefDecl(ParmVarDecl parmVarDecl, TypedefDecl typedefDecl) var index = parameters.IndexOf(parmVarDecl); var lastIndex = parameters.Count - 1; - if (name.Equals("param")) + if (name.Equals("param", StringComparison.Ordinal)) { escapedName += index; } @@ -1355,13 +1355,11 @@ private void VisitRecordDecl(RecordDecl recordDecl) var alignment = Math.Max(recordDecl.TypeForDecl.Handle.AlignOf, 1); var maxAlignm = recordDecl.Fields.Any() ? recordDecl.Fields.Max((fieldDecl) => Math.Max(fieldDecl.Type.Handle.AlignOf, 1)) : alignment; - var isTopLevelStruct = _config.WithTypes.TryGetValue(name, out var withType) && (withType == "struct"); + var isTopLevelStruct = _config.WithTypes.TryGetValue(name, out var withType) && withType.Equals("struct", StringComparison.Ordinal); var generateTestsClass = !recordDecl.IsAnonymousStructOrUnion && recordDecl.DeclContext is not RecordDecl; if ((_testOutputBuilder is not null) && generateTestsClass && !isTopLevelStruct) { - Debug.Assert(_testOutputBuilder is not null); - _testOutputBuilder.WriteIndented("/// Provides validation of the struct."); @@ -1472,7 +1470,7 @@ private void VisitRecordDecl(RecordDecl recordDecl) nativeNameWithExtras = nativeTypeNameBuilder.ToString(); nativeInheritance = GetCursorName(cxxRecordDecl.Bases[cxxRecordDecl.Bases.Count - 1].Referenced); - baseTypeNames = baseTypeNamesBuilder.ToArray(); + baseTypeNames = [.. baseTypeNamesBuilder]; } if (!TryGetRemappedValue(recordDecl, _config.WithPackings, out var pack)) @@ -1518,12 +1516,12 @@ private void VisitRecordDecl(RecordDecl recordDecl) { if (!_topLevelClassAttributes.TryGetValue(name, out var withAttributes)) { - withAttributes = new List(); + withAttributes = []; } if (!_topLevelClassUsings.TryGetValue(name, out var withUsings)) { - withUsings = new HashSet(); + withUsings = []; } if (desc.LayoutAttribute is not null) @@ -1544,7 +1542,7 @@ private void VisitRecordDecl(RecordDecl recordDecl) { foreach (var entry in _config.NativeTypeNamesToStrip) { - nativeTypeName = nativeTypeName.Replace(entry, ""); + nativeTypeName = nativeTypeName.Replace(entry, "", StringComparison.Ordinal); } if (!string.IsNullOrWhiteSpace(nativeTypeName)) @@ -2071,7 +2069,7 @@ void OutputVtblEntry(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethodDecl) if (_config.GenerateMarkerInterfaces && !_config.ExcludeFnptrCodegen) { var cxxRecordDeclName = GetRemappedCursorName(cxxRecordDecl); - cxxMethodDeclTypeName = cxxMethodDeclTypeName.Replace($"<{cxxRecordDeclName}*,", "= 0) { index++; - bitfieldName += index.ToString(); + bitfieldName += index.ToString(CultureInfo.InvariantCulture); } remainingBits = currentSize * 8; @@ -2437,7 +2436,7 @@ void VisitBitfieldDecl(FieldDecl fieldDecl, BitfieldDesc[] bitfieldDescs, Record if (index >= 0) { - bitfieldName += index.ToString(); + bitfieldName += index.ToString(CultureInfo.InvariantCulture); } var bitfieldDesc = (index > 0) ? bitfieldDescs[index - 1] : bitfieldDescs[0]; @@ -2446,7 +2445,7 @@ void VisitBitfieldDecl(FieldDecl fieldDecl, BitfieldDesc[] bitfieldDescs, Record } var bitfieldOffset = (currentSize * 8) - remainingBits; - var bitwidthHexStringBacking = ((1 << fieldDecl.BitWidthValue) - 1).ToString("X"); + var bitwidthHexStringBacking = ((1 << fieldDecl.BitWidthValue) - 1).ToString("X", CultureInfo.InvariantCulture); if (!IsType(fieldDecl, typeBacking, out var builtinTypeBacking)) { @@ -2479,7 +2478,7 @@ void VisitBitfieldDecl(FieldDecl fieldDecl, BitfieldDesc[] bitfieldDescs, Record case CXType_ULongLong: { - if (typeNameBacking == "nuint") + if (typeNameBacking.Equals("nuint", StringComparison.Ordinal)) { goto case CXType_UInt; } @@ -2512,7 +2511,7 @@ void VisitBitfieldDecl(FieldDecl fieldDecl, BitfieldDesc[] bitfieldDescs, Record { isTypeBackingSigned = true; - if (typeNameBacking == "nint") + if (typeNameBacking.Equals("nint", StringComparison.Ordinal)) { goto case CXType_Int; } @@ -2528,7 +2527,7 @@ void VisitBitfieldDecl(FieldDecl fieldDecl, BitfieldDesc[] bitfieldDescs, Record } } - var bitwidthHexString = ((1 << fieldDecl.BitWidthValue) - 1).ToString("X"); + var bitwidthHexString = ((1 << fieldDecl.BitWidthValue) - 1).ToString("X", CultureInfo.InvariantCulture); var type = fieldDecl.Type; if (IsType(fieldDecl, type, out var builtinType)) @@ -2578,7 +2577,7 @@ void VisitBitfieldDecl(FieldDecl fieldDecl, BitfieldDesc[] bitfieldDescs, Record case CXType_ULongLong: { - if (typeNameBacking == "nuint") + if (typeNameBacking.Equals("nuint", StringComparison.Ordinal)) { goto case CXType_UInt; } @@ -2611,7 +2610,7 @@ void VisitBitfieldDecl(FieldDecl fieldDecl, BitfieldDesc[] bitfieldDescs, Record { isTypeSigned = true; - if (typeNameBacking == "nint") + if (typeNameBacking.Equals("nint", StringComparison.Ordinal)) { goto case CXType_Int; } @@ -2661,7 +2660,7 @@ void VisitBitfieldDecl(FieldDecl fieldDecl, BitfieldDesc[] bitfieldDescs, Record var recordDeclName = GetCursorName(recordDecl); var isSmallType = currentSize < 4; - var isRemappedToSelf = _config.RemappedNames.TryGetValue(typeName, out var remappedTypeName) && typeName.Equals(remappedTypeName); + var isRemappedToSelf = _config.RemappedNames.TryGetValue(typeName, out var remappedTypeName) && typeName.Equals(remappedTypeName, StringComparison.Ordinal); var isTypeMismatch = type != builtinTypeBacking; var isUnsignedToSigned = !isTypeBackingSigned && isTypeSigned; @@ -2883,7 +2882,7 @@ void VisitConstantOrIncompleteArrayFieldDecl(RecordDecl recordDecl, FieldDecl co var accessSpecifier = GetAccessSpecifier(constantOrIncompleteArray, matchStar: false); var elementType = arrayType.ElementType; var isUnsafeElementType = IsTypePointerOrReference(constantOrIncompleteArray, arrayType.ElementType) && - (arrayTypeName != "IntPtr") && (arrayTypeName != "UIntPtr"); + !arrayTypeName.Equals("IntPtr", StringComparison.Ordinal) && !arrayTypeName.Equals("UIntPtr", StringComparison.Ordinal); var name = GetArtificialFixedSizedBufferName(constantOrIncompleteArray); var escapedName = EscapeName(name); @@ -2956,14 +2955,14 @@ void VisitConstantOrIncompleteArrayFieldDecl(RecordDecl recordDecl, FieldDecl co { var dimension = sizePerDimension[0]; var firstDimension = dimension.index++; - var fieldName = "e" + firstDimension; + var fieldName = $"e{firstDimension}"; sizePerDimension[0] = dimension; var separateStride = false; for (var d = 1; d < sizePerDimension.Count; d++) { dimension = sizePerDimension[d]; - fieldName += "_" + dimension.index; + fieldName += $"_{dimension.index}"; sizePerDimension[d] = dimension; var previousDimension = sizePerDimension[d - 1]; @@ -2979,7 +2978,7 @@ void VisitConstantOrIncompleteArrayFieldDecl(RecordDecl recordDecl, FieldDecl co sizePerDimension[d] = dimension; } - if (firstFieldName == "") + if (string.IsNullOrEmpty(firstFieldName)) { firstFieldName = fieldName; } @@ -3227,7 +3226,7 @@ void ForUnderlyingType(TypedefDecl typedefDecl, Type underlyingType, bool onlyHa { if (!_allValidNameRemappings.TryGetValue(underlyingName, out var allRemappings)) { - allRemappings = new HashSet(); + allRemappings = []; _allValidNameRemappings[underlyingName] = allRemappings; } _ = allRemappings.Add(typedefName); @@ -3237,7 +3236,7 @@ void ForUnderlyingType(TypedefDecl typedefDecl, Type underlyingType, bool onlyHa { if (!_traversedValidNameRemappings.TryGetValue(underlyingName, out var traversedRemappings)) { - traversedRemappings = new HashSet(); + traversedRemappings = []; _traversedValidNameRemappings[underlyingName] = traversedRemappings; } _ = traversedRemappings.Add(typedefName); @@ -3277,7 +3276,7 @@ private void VisitVarDecl(VarDecl varDecl) var isMacroDefinitionRecord = false; var nativeName = GetCursorName(varDecl); - if (nativeName.StartsWith("ClangSharpMacro_" + "")) + if (nativeName.StartsWith("ClangSharpMacro_", StringComparison.Ordinal)) { type = varDecl.Init.Type; nativeName = nativeName["ClangSharpMacro_".Length..]; @@ -3436,7 +3435,7 @@ private void VisitVarDecl(VarDecl varDecl) } } - if (typeName == "Guid") + if (typeName.Equals("Guid", StringComparison.Ordinal)) { _ = _generatedUuids.Add(name); } @@ -3463,7 +3462,7 @@ private void VisitVarDecl(VarDecl varDecl) StartUsingOutputBuilder(className); Debug.Assert(_outputBuilder is not null); - if ((kind == ValueKind.String) && typeName.StartsWith("ReadOnlySpan<")) + if ((kind == ValueKind.String) && typeName.StartsWith("ReadOnlySpan<", StringComparison.Ordinal)) { _outputBuilder.EmitSystemSupport(); } @@ -3552,7 +3551,7 @@ void ForDeclStmt(VarDecl varDecl, DeclStmt declStmt) private bool IsConstant(string targetTypeName, Expr initExpr) { - if (IsTypePointerOrReference(initExpr) && (targetTypeName != "string")) + if (IsTypePointerOrReference(initExpr) && !targetTypeName.Equals("string", StringComparison.Ordinal)) { return false; } diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitPreprocessedEntity.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitPreprocessedEntity.cs index 24c455e7..9b64e6e6 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitPreprocessedEntity.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitPreprocessedEntity.cs @@ -1,5 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. +using System.Globalization; using ClangSharp.Interop; using static ClangSharp.Interop.CXTokenKind; @@ -34,7 +35,7 @@ private unsafe void VisitMacroDefinitionRecord(MacroDefinitionRecord macroDefini var macroName = $"ClangSharpMacro_{macroDefinitionRecord.Spelling}"; _ = _fileContentsBuilder.Append('\n'); - _ = _fileContentsBuilder.Append($"const {_placeholderMacroType} {macroName} = "); + _ = _fileContentsBuilder.Append(CultureInfo.InvariantCulture, $"const {_placeholderMacroType} {macroName} = "); var sourceRangeEnd = tokens[^1].GetExtent(translationUnitHandle).End; var sourceRangeStart = tokens[1].GetLocation(translationUnitHandle); diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs index 7cde15d0..efcec766 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -239,7 +240,7 @@ private void VisitCallExpr(CallExpr callExpr) } else { - AddDiagnostic(DiagnosticLevel.Error, $"Unsupported callee declaration: '{calleeDecl?.DeclKindName}'. Generated bindings may be incomplete.", calleeDecl); + AddDiagnostic(DiagnosticLevel.Error, $"Unsupported callee declaration: '{calleeDecl.DeclKindName}'. Generated bindings may be incomplete.", calleeDecl); } void VisitArgs(CallExpr callExpr) @@ -334,12 +335,12 @@ private void VisitCharacterLiteral(CharacterLiteral characterLiteral) if (characterLiteral.Value > ushort.MaxValue) { outputBuilder.Write("0x"); - outputBuilder.Write(characterLiteral.Value.ToString("X8")); + outputBuilder.Write(characterLiteral.Value.ToString("X8", CultureInfo.InvariantCulture)); } else if (characterLiteral.Value > byte.MaxValue) { outputBuilder.Write("0x"); - outputBuilder.Write(characterLiteral.Value.ToString("X4")); + outputBuilder.Write(characterLiteral.Value.ToString("X4", CultureInfo.InvariantCulture)); } else { @@ -364,7 +365,7 @@ private void VisitCharacterLiteral(CharacterLiteral characterLiteral) targetTypeNumBits = targetType.Handle.NumBits; } - if (targetTypeName != "") + if (!string.IsNullOrEmpty(targetTypeName)) { if (!IsUnsigned(targetTypeName)) { @@ -384,7 +385,7 @@ private void VisitCharacterLiteral(CharacterLiteral characterLiteral) outputBuilder.Write(EscapeCharacter((char)characterLiteral.Value)); outputBuilder.Write('\''); - if (castType != "") + if (!string.IsNullOrEmpty(castType)) { outputBuilder.Write(')'); } @@ -407,7 +408,7 @@ private void VisitCharacterLiteral(CharacterLiteral characterLiteral) if (characterLiteral.Value > ushort.MaxValue) { outputBuilder.Write("0x"); - outputBuilder.Write(characterLiteral.Value.ToString("X8")); + outputBuilder.Write(characterLiteral.Value.ToString("X8", CultureInfo.InvariantCulture)); } else { @@ -421,7 +422,7 @@ private void VisitCharacterLiteral(CharacterLiteral characterLiteral) case CX_CLK_UTF32: { outputBuilder.Write("0x"); - outputBuilder.Write(characterLiteral.Value.ToString("X8")); + outputBuilder.Write(characterLiteral.Value.ToString("X8", CultureInfo.InvariantCulture)); break; } @@ -771,7 +772,7 @@ private void VisitDeclRefExpr(DeclRefExpr declRefExpr) if (!_config.DontUseUsingStaticsForEnums) { - if (enumName.StartsWith("__AnonymousEnum_")) + if (enumName.StartsWith("__AnonymousEnum_", StringComparison.Ordinal)) { var className = GetClass(enumName); @@ -908,7 +909,7 @@ private void VisitExplicitCastExpr(ExplicitCastExpr explicitCastExpr) { var cursorName = GetCursorName(varDecl); - if (cursorName.StartsWith("ClangSharpMacro_") && _config.WithTransparentStructs.TryGetValue(typeName, out var transparentStruct)) + if (cursorName.StartsWith("ClangSharpMacro_", StringComparison.Ordinal) && _config.WithTransparentStructs.TryGetValue(typeName, out var transparentStruct)) { if (!IsPrimitiveValue(explicitCastExpr, type) || IsConstant(typeName, varDecl.Init)) { @@ -917,11 +918,11 @@ private void VisitExplicitCastExpr(ExplicitCastExpr explicitCastExpr) } } - if (typeName == "IntPtr") + if (typeName.Equals("IntPtr", StringComparison.Ordinal)) { typeName = "nint"; } - else if (typeName == "UIntPtr") + else if (typeName.Equals("UIntPtr", StringComparison.Ordinal)) { typeName = "nuint"; } @@ -944,7 +945,7 @@ private void VisitExprWithCleanups(ExprWithCleanups exprWithCleanups) private void VisitFloatingLiteral(FloatingLiteral floatingLiteral) { var outputBuilder = StartCSharpCode(); - if (floatingLiteral.ValueString.EndsWith(".f")) + if (floatingLiteral.ValueString.EndsWith(".f", StringComparison.Ordinal)) { outputBuilder.Write(floatingLiteral.ValueString[0..^1]); outputBuilder.Write("0f"); @@ -953,7 +954,7 @@ private void VisitFloatingLiteral(FloatingLiteral floatingLiteral) { outputBuilder.Write(floatingLiteral.ValueString); - if (floatingLiteral.ValueString.EndsWith(".")) + if (floatingLiteral.ValueString.EndsWith('.')) { outputBuilder.Write('0'); } @@ -1348,7 +1349,7 @@ void ForRecordType(CSharpOutputBuilder outputBuilder, InitListExpr initListExpr, outputBuilder.Write("new "); outputBuilder.Write(typeName); - if (typeName == "Guid") + if (typeName.Equals("Guid", StringComparison.Ordinal)) { outputBuilder.Write('('); @@ -1565,7 +1566,7 @@ void HandleUnmanagedConstant(CSharpOutputBuilder outputBuilder, InitListExpr ini _testOutputBuilder.WriteLine("Test()"); _testOutputBuilder.WriteBlockStart(); - if (typeName == "Guid") + if (typeName.Equals("Guid", StringComparison.Ordinal)) { if (_config.GenerateTestsNUnit) { @@ -1682,7 +1683,7 @@ private void VisitIntegerLiteral(IntegerLiteral integerLiteral) { var valueString = integerLiteral.ValueString; - if (valueString.EndsWith("l", StringComparison.OrdinalIgnoreCase)) + if (valueString.EndsWith('l') || valueString.EndsWith('L')) { valueString = valueString[0..^1]; } @@ -1715,11 +1716,11 @@ private void VisitIntegerLiteral(IntegerLiteral integerLiteral) { valueString = valueString[0..^2] + "UL"; } - else if (valueString.EndsWith("l", StringComparison.OrdinalIgnoreCase)) + else if (valueString.EndsWith('l') || valueString.EndsWith('L')) { valueString = valueString[0..^1] + "L"; } - else if (valueString.EndsWith("u", StringComparison.OrdinalIgnoreCase)) + else if (valueString.EndsWith('u') || valueString.EndsWith('U')) { valueString = valueString[0..^1] + "U"; } @@ -2485,7 +2486,7 @@ private void VisitStringLiteral(StringLiteral stringLiteral) { if (userData is ValueDesc valueDesc) { - if ((valueDesc.Kind == ValueKind.String) && (valueDesc.TypeName == "byte[]")) + if ((valueDesc.Kind == ValueKind.String) && valueDesc.TypeName.Equals("byte[]", StringComparison.Ordinal)) { outputBuilder.Write(".ToArray()"); } @@ -2501,7 +2502,7 @@ private void VisitStringLiteral(StringLiteral stringLiteral) foreach (var b in bytes) { outputBuilder.Write("0x"); - outputBuilder.Write(b.ToString("X2")); + outputBuilder.Write(b.ToString("X2", CultureInfo.InvariantCulture)); outputBuilder.Write(", "); } @@ -2540,7 +2541,7 @@ private void VisitStringLiteral(StringLiteral stringLiteral) foreach (var codepoint in codepoints) { outputBuilder.Write("0x"); - outputBuilder.Write(codepoint.ToString("X8")); + outputBuilder.Write(codepoint.ToString("X8", CultureInfo.InvariantCulture)); outputBuilder.Write(", "); } @@ -2648,7 +2649,7 @@ private void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr unaryExprOrT } else { - AddDiagnostic(DiagnosticLevel.Error, $"Unsupported callee declaration: '{calleeDecl?.DeclKindName}'. Generated bindings may be incomplete.", calleeDecl); + AddDiagnostic(DiagnosticLevel.Error, $"Unsupported callee declaration: '{calleeDecl.DeclKindName}'. Generated bindings may be incomplete.", calleeDecl); } } else if (IsPrevContextStmt(out var expr, out _)) @@ -2673,10 +2674,10 @@ private void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr unaryExprOrT { var cursorName = GetCursorName(varDecl); - if (cursorName.StartsWith("ClangSharpMacro_")) + if (cursorName.StartsWith("ClangSharpMacro_", StringComparison.Ordinal)) { cursorName = cursorName["ClangSharpMacro_".Length..]; - parentTypeIsVariableSized |= _config.WithTypes.TryGetValue(cursorName, out var remappedTypeName) && ((remappedTypeName == "int") || (remappedTypeName == "uint")); + parentTypeIsVariableSized |= _config.WithTypes.TryGetValue(cursorName, out var remappedTypeName) && (remappedTypeName.Equals("int", StringComparison.Ordinal) || remappedTypeName.Equals("uint", StringComparison.Ordinal)); } } diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs index 375bfc43..144244f4 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.IO; using System.Linq; using System.Runtime.InteropServices; @@ -33,8 +34,8 @@ public sealed partial class PInvokeGenerator : IDisposable private const int DefaultStreamWriterBufferSize = 1024; private static readonly Encoding s_defaultStreamWriterEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); - private static readonly string[] s_doubleColonSeparator = new string[] { "::" }; - private static readonly char[] s_doubleQuoteSeparator = new char[] { '"' }; + private static readonly string[] s_doubleColonSeparator = ["::"]; + private static readonly char[] s_doubleQuoteSeparator = ['"']; private const string ExpectedClangVersion = "version 16.0"; private const string ExpectedClangSharpVersion = "version 16.0"; @@ -101,70 +102,72 @@ public PInvokeGenerator(PInvokeGeneratorConfiguration config, Func { + var directoryPath = Path.GetDirectoryName(path) ?? ""; + _ = Directory.CreateDirectory(directoryPath); + return new FileStream(path, FileMode.Create); + }); + _fileContentsBuilder = new StringBuilder(); + _visitedFiles = []; + _diagnostics = []; + _context = new LinkedList<(Cursor, object?)>(); + _config = config; + _uuidsToGenerate = []; + _generatedUuids = []; + _cursorNames = []; + _cursorQualifiedNames = new Dictionary<(NamedDecl, bool), string>(); + _typeNames = new Dictionary<(Cursor?, Cursor?, Type), (string, string)>(); + _allValidNameRemappings = new Dictionary>() { + ["intptr_t"] = ["IntPtr", "nint"], + ["ptrdiff_t"] = ["IntPtr", "nint"], + ["size_t"] = ["UIntPtr", "nuint"], + ["uintptr_t"] = ["UIntPtr", "nuint"], + ["_GUID"] = ["Guid"], + }; + _traversedValidNameRemappings = []; + _overloadIndices = []; + _isExcluded = []; + _topLevelClassHasGuidMember = []; + _topLevelClassIsUnsafe = []; + _topLevelClassNames = []; + _topLevelClassAttributes = []; + _topLevelClassUsings = []; + _usedRemappings = []; + _filePath = ""; + _clangCommandLineArgs = []; + _placeholderMacroType = GetPlaceholderMacroType(); } - - var clangSharpVersion = string.Empty; - - try - { - clangSharpVersion = clangsharp.getVersion().ToString(); - } - catch + else { - Console.WriteLine(); - Console.WriteLine("*****IMPORTANT*****"); - Console.WriteLine($"Failed to resolve libClangSharp."); - Console.WriteLine("If you are running as a dotnet tool, you may need to manually copy the appropriate DLLs from NuGet due to limitations in the dotnet tool support. Please see https://github.com/dotnet/clangsharp for more details."); - Console.WriteLine("*****IMPORTANT*****"); - Console.WriteLine(); - - throw; + throw new InvalidOperationException($"Invalid libClang version. Returned string '{clangVersion}' does not contain '{ExpectedClangVersion}'"); } - - if (!clangSharpVersion.Contains(ExpectedClangSharpVersion)) - { - throw new InvalidOperationException($"Invalid libClang version. Returned string '{clangSharpVersion}' does not contain '{ExpectedClangSharpVersion}'"); - } - - _index = CXIndex.Create(); - _outputBuilderFactory = new OutputBuilderFactory(config); - _outputStreamFactory = outputStreamFactory ?? ((path) => { - var directoryPath = Path.GetDirectoryName(path) ?? ""; - _ = Directory.CreateDirectory(directoryPath); - return new FileStream(path, FileMode.Create); - }); - _fileContentsBuilder = new StringBuilder(); - _visitedFiles = new HashSet(); - _diagnostics = new List(); - _context = new LinkedList<(Cursor, object?)>(); - _config = config; - _uuidsToGenerate = new Dictionary(); - _generatedUuids = new HashSet(); - _cursorNames = new Dictionary(); - _cursorQualifiedNames = new Dictionary<(NamedDecl, bool), string>(); - _typeNames = new Dictionary<(Cursor?, Cursor?, Type), (string, string)>(); - _allValidNameRemappings = new Dictionary>() { - ["intptr_t"] = new HashSet() { "IntPtr", "nint" }, - ["ptrdiff_t"] = new HashSet() { "IntPtr", "nint" }, - ["size_t"] = new HashSet() { "UIntPtr", "nuint" }, - ["uintptr_t"] = new HashSet() { "UIntPtr", "nuint" }, - ["_GUID"] = new HashSet() { "Guid" }, - }; - _traversedValidNameRemappings = new Dictionary>(); - _overloadIndices = new Dictionary(); - _isExcluded = new Dictionary(); - _topLevelClassHasGuidMember = new Dictionary(); - _topLevelClassIsUnsafe = new Dictionary(); - _topLevelClassNames = new HashSet(); - _topLevelClassAttributes = new Dictionary>(); - _topLevelClassUsings = new Dictionary>(); - _usedRemappings = new HashSet(); - _filePath = ""; - _clangCommandLineArgs = Array.Empty(); - _placeholderMacroType = GetPlaceholderMacroType(); } ~PInvokeGenerator() @@ -236,16 +239,24 @@ public void Close() stream = _outputStreamFactory(outputPath); leaveStreamOpen = true; - var usingDirectives = Enumerable.Empty(); - var staticUsingDirectives = Enumerable.Empty(); + var usingDirectives = new SortedSet(StringComparer.Ordinal); + var staticUsingDirectives = new SortedSet(StringComparer.Ordinal); var hasAnyContents = false; foreach (var outputBuilder in _outputBuilderFactory.OutputBuilders) { if (outputBuilder is CSharpOutputBuilder csharpOutputBuilder) { - usingDirectives = usingDirectives.Concat(csharpOutputBuilder.UsingDirectives); - staticUsingDirectives = staticUsingDirectives.Concat(csharpOutputBuilder.StaticUsingDirectives); + foreach (var usingDirective in csharpOutputBuilder.UsingDirectives) + { + _ = usingDirectives.Add(usingDirective); + } + + foreach (var staticUsingDirective in csharpOutputBuilder.StaticUsingDirectives) + { + _ = staticUsingDirectives.Add(staticUsingDirective); + } + hasAnyContents = csharpOutputBuilder.Contents.Any(); } else if (outputBuilder is XmlOutputBuilder xmlOutputBuilder) @@ -254,13 +265,10 @@ public void Close() } } - usingDirectives = usingDirectives.Distinct() - .OrderBy((usingDirective) => usingDirective); - - staticUsingDirectives = staticUsingDirectives.Distinct() - .OrderBy((staticUsingDirective) => staticUsingDirective); - - usingDirectives = usingDirectives.Concat(staticUsingDirectives); + foreach (var staticUsingDirective in staticUsingDirectives) + { + _ = usingDirectives.Add(staticUsingDirective); + } if (hasAnyContents) { @@ -269,12 +277,12 @@ public void Close() if (_config.OutputMode == PInvokeGeneratorOutputMode.CSharp) { - if (_config.HeaderText != string.Empty) + if (!string.IsNullOrEmpty(_config.HeaderText)) { sw.WriteLine(_config.HeaderText); } - if (usingDirectives.Any()) + if (usingDirectives.Count != 0) { foreach (var usingDirective in usingDirectives) { @@ -291,11 +299,11 @@ public void Close() sw.WriteLine(""); sw.WriteLine(""); - if (_config.HeaderText != string.Empty) + if (!string.IsNullOrEmpty(_config.HeaderText)) { sw.WriteLine(" "); - if (_config.HeaderText != string.Empty) + if (!string.IsNullOrEmpty(_config.HeaderText)) { foreach (var ln in _config.HeaderText.Split('\n')) { @@ -372,9 +380,6 @@ public void Close() foreach (var entry in methodClassOutputBuilders) { - var hasGuidMember = _config.GenerateGuidMember && _config.GenerateLatestCode; - hasGuidMember &= _uuidsToGenerate.ContainsKey(entry.Value.Name) || _generatedUuids.Contains(entry.Value.Name); - CloseOutputBuilder(stream, entry.Value, isMethodClass: true, leaveStreamOpen, emitNamespaceDeclaration); } @@ -423,7 +428,7 @@ static void GenerateDisableRuntimeMarshallingAttribute(PInvokeGenerator generato using var sw = new StreamWriter(stream, s_defaultStreamWriterEncoding, DefaultStreamWriterBufferSize, leaveStreamOpen); sw.NewLine = "\n"; - if (config.HeaderText != string.Empty) + if (!string.IsNullOrEmpty(config.HeaderText)) { sw.WriteLine(config.HeaderText); } @@ -456,7 +461,7 @@ static void GenerateNativeBitfieldAttribute(PInvokeGenerator generator, Stream? using var sw = new StreamWriter(stream, s_defaultStreamWriterEncoding, DefaultStreamWriterBufferSize, leaveStreamOpen); sw.NewLine = "\n"; - if (config.HeaderText != string.Empty) + if (!string.IsNullOrEmpty(config.HeaderText)) { sw.WriteLine(config.HeaderText); } @@ -560,7 +565,7 @@ static void GenerateNativeInheritanceAttribute(PInvokeGenerator generator, Strea using var sw = new StreamWriter(stream, s_defaultStreamWriterEncoding, DefaultStreamWriterBufferSize, leaveStreamOpen); sw.NewLine = "\n"; - if (config.HeaderText != string.Empty) + if (!string.IsNullOrEmpty(config.HeaderText)) { sw.WriteLine(config.HeaderText); } @@ -643,7 +648,7 @@ static void GenerateNativeTypeNameAttribute(PInvokeGenerator generator, Stream? using var sw = new StreamWriter(stream, s_defaultStreamWriterEncoding, DefaultStreamWriterBufferSize, leaveStreamOpen); sw.NewLine = "\n"; - if (config.HeaderText != string.Empty) + if (!string.IsNullOrEmpty(config.HeaderText)) { sw.WriteLine(config.HeaderText); } @@ -732,7 +737,7 @@ static void GenerateSetsLastSystemErrorAttribute(PInvokeGenerator generator, Str using var sw = new StreamWriter(stream, s_defaultStreamWriterEncoding, DefaultStreamWriterBufferSize, leaveStreamOpen); sw.NewLine = "\n"; - if (config.HeaderText != string.Empty) + if (!string.IsNullOrEmpty(config.HeaderText)) { sw.WriteLine(config.HeaderText); } @@ -810,7 +815,7 @@ static void GenerateVtblIndexAttribute(PInvokeGenerator generator, Stream? strea using var sw = new StreamWriter(stream, s_defaultStreamWriterEncoding, DefaultStreamWriterBufferSize, leaveStreamOpen); sw.NewLine = "\n"; - if (config.HeaderText != string.Empty) + if (!string.IsNullOrEmpty(config.HeaderText)) { sw.WriteLine(config.HeaderText); } @@ -890,7 +895,7 @@ static void GenerateTransparentStructs(PInvokeGenerator generator, Stream? strea var type = transparentStruct.Value.Name; var kind = transparentStruct.Value.Kind; - var isTypePointer = type.Contains('*'); + var isTypePointer = type.Contains('*', StringComparison.Ordinal); if (stream is null) { @@ -901,7 +906,7 @@ static void GenerateTransparentStructs(PInvokeGenerator generator, Stream? strea using var sw = new StreamWriter(stream, s_defaultStreamWriterEncoding, DefaultStreamWriterBufferSize, leaveStreamOpen); sw.NewLine = "\n"; - if (config.HeaderText != string.Empty) + if (!string.IsNullOrEmpty(config.HeaderText)) { sw.WriteLine(config.HeaderText); } @@ -1105,7 +1110,7 @@ static void GenerateTransparentStructs(PInvokeGenerator generator, Stream? strea sw.Write("(void* value) => new "); sw.Write(name); - if (type == "void*") + if (type.Equals("void*", StringComparison.Ordinal)) { sw.WriteLine("(value);"); } @@ -1150,7 +1155,7 @@ static void GenerateTransparentStructs(PInvokeGenerator generator, Stream? strea sw.WriteLine(); - if ((kind == PInvokeGeneratorTransparentStructKind.HandleWin32) && (name != "HANDLE")) + if ((kind == PInvokeGeneratorTransparentStructKind.HandleWin32) && !name.Equals("HANDLE", StringComparison.Ordinal)) { // Win32 handle like transparent structs can also be cast to/from HANDLE @@ -1186,11 +1191,11 @@ static void GenerateTransparentStructs(PInvokeGenerator generator, Stream? strea sw.Write("(bool value) => new "); sw.Write(name); - if (type == "int") + if (type.Equals("int", StringComparison.Ordinal)) { sw.WriteLine("(value ? 1 : 0);"); } - else if (type == "uint") + else if (type.Equals("uint", StringComparison.Ordinal)) { sw.WriteLine("(value ? 1u : 0u);"); } @@ -1369,7 +1374,7 @@ static void GenerateTransparentStructs(PInvokeGenerator generator, Stream? strea static (int srcSize, int dstSize, int sign) GetSizeAndSignOf(string type) { - if (type.Contains('*')) + if (type.Contains('*', StringComparison.Ordinal)) { return (8, 4, +1); } @@ -1394,15 +1399,17 @@ static void OutputConversions(StreamWriter sw, string indentString, string name, var (typeSrcSize, typeDstSize, typeSign) = GetSizeAndSignOf(type); var (targetSrcSize, targetDstSize, targetSign) = GetSizeAndSignOf(target); - var isTypePointer = type.Contains('*'); - var isPointerToNativeCast = (isTypePointer && target == "nint") || (isTypePointer && target == "nuint"); + var isTypePointer = type.Contains('*', StringComparison.Ordinal); + var isPointerToNativeCast = (isTypePointer && target.Equals("nint", StringComparison.Ordinal)) || (isTypePointer && target.Equals("nuint", StringComparison.Ordinal)); // public static castFromKind operator name(target value) => new name((type)(value)); var castFromKind = "implicit"; var areEquivalentTypeAndTarget = (type == target) || isPointerToNativeCast - || ((type == "nint") && (target == "int")) || ((type == "nuint") && (target == "uint")) - || ((type == "long") && (target == "nint")) || ((type == "ulong") && (target == "nuint")); + || (type.Equals("nint", StringComparison.Ordinal) && target.Equals("int", StringComparison.Ordinal)) + || (type.Equals("nuint", StringComparison.Ordinal) && target.Equals("uint", StringComparison.Ordinal)) + || (type.Equals("long", StringComparison.Ordinal) && target.Equals("nint", StringComparison.Ordinal)) + || (type.Equals("ulong", StringComparison.Ordinal) && target.Equals("nuint", StringComparison.Ordinal)); if (((typeDstSize <= targetSrcSize) && !areEquivalentTypeAndTarget) || ((targetSign == -1) && (typeSign == +1)) || IsTransparentStructHandle(kind)) { @@ -1420,7 +1427,7 @@ static void OutputConversions(StreamWriter sw, string indentString, string name, sw.Write(name); sw.Write('('); - if ((castFromKind == "explicit") || isPointerToNativeCast) + if (castFromKind.Equals("explicit", StringComparison.Ordinal) || isPointerToNativeCast) { sw.Write("unchecked(("); sw.Write(type); @@ -1429,7 +1436,7 @@ static void OutputConversions(StreamWriter sw, string indentString, string name, sw.Write("value"); - if ((castFromKind == "explicit") || isPointerToNativeCast) + if (castFromKind.Equals("explicit", StringComparison.Ordinal) || isPointerToNativeCast) { sw.Write("))"); } @@ -1441,8 +1448,10 @@ static void OutputConversions(StreamWriter sw, string indentString, string name, var castToKind = "implicit"; areEquivalentTypeAndTarget = (type == target) || isPointerToNativeCast - || ((type == "int") && (target == "nint")) || ((type == "uint") && (target == "nuint")) - || ((type == "nint") && (target == "long")) || ((type == "nuint") && (target == "ulong")); + || (type.Equals("int", StringComparison.Ordinal) && target.Equals("nint", StringComparison.Ordinal)) + || (type.Equals("uint", StringComparison.Ordinal) && target.Equals("nuint", StringComparison.Ordinal)) + || (type.Equals("nint", StringComparison.Ordinal) && target.Equals("long", StringComparison.Ordinal)) + || (type.Equals("nuint", StringComparison.Ordinal) && target.Equals("ulong", StringComparison.Ordinal)); if (((targetDstSize <= typeSrcSize) && !areEquivalentTypeAndTarget) || ((typeSign == -1) && (targetSign == +1))) { @@ -1458,7 +1467,7 @@ static void OutputConversions(StreamWriter sw, string indentString, string name, sw.Write(name); sw.Write(" value) => "); - if ((castToKind == "explicit") || isPointerToNativeCast) + if (castToKind.Equals("explicit", StringComparison.Ordinal) || isPointerToNativeCast) { sw.Write('('); sw.Write(target); @@ -1467,7 +1476,7 @@ static void OutputConversions(StreamWriter sw, string indentString, string name, sw.Write("value.Value"); - if ((castToKind == "explicit") || isPointerToNativeCast) + if (castToKind.Equals("explicit", StringComparison.Ordinal) || isPointerToNativeCast) { sw.Write(')'); } @@ -1486,6 +1495,7 @@ public void Dispose() public void GenerateBindings(TranslationUnit translationUnit, string filePath, string[] clangCommandLineArgs, CXTranslationUnit_Flags translationFlags) { + ArgumentNullException.ThrowIfNull(translationUnit); Debug.Assert(_outputBuilder is null); _filePath = filePath; @@ -1516,6 +1526,8 @@ public void GenerateBindings(TranslationUnit translationUnit, string filePath, s } } +#pragma warning disable CA1031 // Do not catch general exception types + try { if (_config.GenerateMacroBindings) @@ -1570,14 +1582,14 @@ public void GenerateBindings(TranslationUnit translationUnit, string filePath, s var altName = name; var smlName = name; - if (name.Contains("::")) + if (name.Contains("::", StringComparison.Ordinal)) { - altName = name.Replace("::", "."); + altName = name.Replace("::", ".", StringComparison.Ordinal); smlName = altName.Split('.')[^1]; } - else if (name.Contains('.')) + else if (name.Contains('.', StringComparison.Ordinal)) { - altName = name.Replace(".", "::"); + altName = name.Replace(".", "::", StringComparison.Ordinal); smlName = altName.Split("::")[^1]; } else @@ -1612,14 +1624,14 @@ public void GenerateBindings(TranslationUnit translationUnit, string filePath, s var altName = name; var smlName = name; - if (name.Contains("::")) + if (name.Contains("::", StringComparison.Ordinal)) { - altName = name.Replace("::", "."); + altName = name.Replace("::", ".", StringComparison.Ordinal); smlName = altName.Split('.')[^1]; } - else if (name.Contains('.')) + else if (name.Contains('.', StringComparison.Ordinal)) { - altName = name.Replace(".", "::"); + altName = name.Replace(".", "::", StringComparison.Ordinal); smlName = altName.Split("::")[^1]; } else @@ -1653,14 +1665,14 @@ public void GenerateBindings(TranslationUnit translationUnit, string filePath, s var altName = name; var smlName = name; - if (name.Contains("::")) + if (name.Contains("::", StringComparison.Ordinal)) { - altName = name.Replace("::", "."); + altName = name.Replace("::", ".", StringComparison.Ordinal); smlName = altName.Split('.')[^1]; } - else if (name.Contains('.')) + else if (name.Contains('.', StringComparison.Ordinal)) { - altName = name.Replace(".", "::"); + altName = name.Replace(".", "::", StringComparison.Ordinal); smlName = altName.Split("::")[^1]; } else @@ -1692,7 +1704,7 @@ static string GetFoundRemappingString(string name, HashSet remappings) recommendedRemapping = remappings.Single(); } - if ((recommendedRemapping == "") && name.StartsWith("_")) + if (string.IsNullOrEmpty(recommendedRemapping) && name.StartsWith('_')) { var remapping = name[1..]; @@ -1702,7 +1714,7 @@ static string GetFoundRemappingString(string name, HashSet remappings) } } - if ((recommendedRemapping == "") && name.StartsWith("tag")) + if (string.IsNullOrEmpty(recommendedRemapping) && name.StartsWith("tag", StringComparison.Ordinal)) { var remapping = name[3..]; @@ -1712,7 +1724,7 @@ static string GetFoundRemappingString(string name, HashSet remappings) } } - if ((recommendedRemapping == "") && name.EndsWith("_")) + if (string.IsNullOrEmpty(recommendedRemapping) && name.EndsWith('_')) { var remapping = name[0..^1]; @@ -1722,7 +1734,7 @@ static string GetFoundRemappingString(string name, HashSet remappings) } } - if ((recommendedRemapping == "") && name.EndsWith("tag")) + if (string.IsNullOrEmpty(recommendedRemapping) && name.EndsWith("tag", StringComparison.Ordinal)) { var remapping = name[0..^3]; @@ -1732,7 +1744,7 @@ static string GetFoundRemappingString(string name, HashSet remappings) } } - if (recommendedRemapping == "") + if (string.IsNullOrEmpty(recommendedRemapping)) { var remapping = name.ToUpperInvariant(); @@ -1746,7 +1758,7 @@ static string GetFoundRemappingString(string name, HashSet remappings) var remainingRemappings = (IEnumerable)remappings; var remainingString = "Found"; - if (recommendedRemapping != "") + if (!string.IsNullOrEmpty(recommendedRemapping)) { result += $"Recommended remapping: '{name}={recommendedRemapping}'."; @@ -1777,6 +1789,8 @@ static string GetFoundRemappingString(string name, HashSet remappings) _diagnostics.Add(diagnostic); } +#pragma warning restore CA1031 // Do not catch general exception types + GC.KeepAlive(translationUnit); } @@ -1815,7 +1829,7 @@ private void AddUsingDirective(IOutputBuilder? outputBuilder, string namespaceNa if (_currentNamespace is not null) { - if (!_currentNamespace.StartsWith(namespaceName)) + if (!_currentNamespace.StartsWith(namespaceName, StringComparison.Ordinal)) { needsUsing = true; } @@ -1844,7 +1858,7 @@ private void CloseOutputBuilder(Stream stream, IOutputBuilder outputBuilder, boo { if (outputBuilder is CSharpOutputBuilder csharpOutputBuilder) { - if (_config.HeaderText != string.Empty) + if (!string.IsNullOrEmpty(_config.HeaderText)) { sw.WriteLine(_config.HeaderText); } @@ -1862,9 +1876,14 @@ private void CloseOutputBuilder(Stream stream, IOutputBuilder outputBuilder, boo } } - var usingDirectives = csharpOutputBuilder.UsingDirectives.Concat(csharpOutputBuilder.StaticUsingDirectives); + var usingDirectives = new SortedSet(csharpOutputBuilder.UsingDirectives, StringComparer.Ordinal); - if (usingDirectives.Any()) + foreach (var staticUsingDirective in csharpOutputBuilder.StaticUsingDirectives) + { + _ = usingDirectives.Add(staticUsingDirective); + } + + if (usingDirectives.Count != 0) { foreach (var usingDirective in usingDirectives) { @@ -1881,7 +1900,7 @@ private void CloseOutputBuilder(Stream stream, IOutputBuilder outputBuilder, boo sw.WriteLine(""); sw.WriteLine(""); - if (_config.HeaderText != string.Empty) + if (!string.IsNullOrEmpty(_config.HeaderText)) { sw.WriteLine(" "); @@ -1939,7 +1958,7 @@ void ForCSharp(CSharpOutputBuilder csharpOutputBuilder) if (isMethodClass) { - var isTopLevelStruct = _config.WithTypes.TryGetValue(nonTestName, out var withType) && (withType == "struct"); + var isTopLevelStruct = _config.WithTypes.TryGetValue(nonTestName, out var withType) && withType.Equals("struct", StringComparison.Ordinal); if (outputBuilder.IsTestOutput) { @@ -1966,7 +1985,7 @@ void ForCSharp(CSharpOutputBuilder csharpOutputBuilder) { foreach (var attribute in withAttributes) { - if (outputBuilder.IsTestOutput && !attribute.StartsWith("SupportedOSPlatform(")) + if (outputBuilder.IsTestOutput && !attribute.StartsWith("SupportedOSPlatform(", StringComparison.Ordinal)) { continue; } @@ -2223,7 +2242,7 @@ private static string EscapeName(string name) private string EscapeAndStripName(string name) { - if (name.StartsWith(_config.MethodPrefixToStrip)) + if (name.StartsWith(_config.MethodPrefixToStrip, StringComparison.Ordinal)) { name = name[_config.MethodPrefixToStrip.Length..]; } @@ -2241,12 +2260,12 @@ private string EscapeAndStripName(string name) _ => value.ToString(), }; - internal static string EscapeString(string value) => value.Replace("\0", "\\0") - .Replace("\\", "\\\\") - .Replace("\r", "\\r") - .Replace("\n", "\\n") - .Replace("\t", "\\t") - .Replace("\"", "\\\""); + internal static string EscapeString(string value) => value.Replace("\0", "\\0", StringComparison.Ordinal) + .Replace("\\", "\\\\", StringComparison.Ordinal) + .Replace("\r", "\\r", StringComparison.Ordinal) + .Replace("\n", "\\n", StringComparison.Ordinal) + .Replace("\t", "\\t", StringComparison.Ordinal) + .Replace("\"", "\\\"", StringComparison.Ordinal); private AccessSpecifier GetAccessSpecifier(NamedDecl namedDecl, bool matchStar) { @@ -2349,13 +2368,13 @@ private BitfieldDesc[] GetBitfieldDescs(RecordDecl recordDecl) var bitfieldDesc = new BitfieldDesc { TypeBacking = typeBacking, - Regions = new List() { + Regions = [ new BitfieldRegion { Name = GetRemappedCursorName(fieldDecl), Offset = 0, Length = fieldDecl.BitWidthValue }, - } + ] }; bitfieldDescs.Add(bitfieldDesc); } @@ -2393,7 +2412,7 @@ private BitfieldDesc[] GetBitfieldDescs(RecordDecl recordDecl) previousSize = Math.Max(previousSize, currentSize); } - return bitfieldDescs.ToArray(); + return [.. bitfieldDescs]; } private CallConv GetCallingConvention(Cursor? cursor, Cursor? context, Type type) @@ -2565,15 +2584,15 @@ private string GetCursorName(NamedDecl namedDecl) name = namedDecl.Name.NormalizePath(); // strip the prefix - if (name.StartsWith("enum ")) + if (name.StartsWith("enum ", StringComparison.Ordinal)) { name = name[5..]; } - else if (name.StartsWith("struct ")) + else if (name.StartsWith("struct ", StringComparison.Ordinal)) { name = name[7..]; } - else if (name.StartsWith("union ")) + else if (name.StartsWith("union ", StringComparison.Ordinal)) { name = name[6..]; } @@ -2593,13 +2612,13 @@ private string GetCursorName(NamedDecl namedDecl) #if DEBUG if (name.StartsWith('(')) { - Debug.Assert(name.StartsWith("(anonymous enum at ") || - name.StartsWith("(anonymous struct at ") || - name.StartsWith("(anonymous union at ") || - name.StartsWith("(unnamed enum at ") || - name.StartsWith("(unnamed struct at ") || - name.StartsWith("(unnamed union at ") || - name.StartsWith("(unnamed at ")); + Debug.Assert(name.StartsWith("(anonymous enum at ", StringComparison.Ordinal) || + name.StartsWith("(anonymous struct at ", StringComparison.Ordinal) || + name.StartsWith("(anonymous union at ", StringComparison.Ordinal) || + name.StartsWith("(unnamed enum at ", StringComparison.Ordinal) || + name.StartsWith("(unnamed struct at ", StringComparison.Ordinal) || + name.StartsWith("(unnamed union at ", StringComparison.Ordinal) || + name.StartsWith("(unnamed at ", StringComparison.Ordinal)); Debug.Assert(name.EndsWith(')')); } #endif @@ -2900,7 +2919,7 @@ private string GetRemappedCursorName(NamedDecl namedDecl, out string nativeTypeN return remappedName; } - name = name.Replace("::", "."); + name = name.Replace("::", ".", StringComparison.Ordinal); remappedName = GetRemappedName(name, namedDecl, tryRemapOperatorName: true, out wasRemapped, skipUsing); if (wasRemapped) @@ -2917,7 +2936,7 @@ private string GetRemappedCursorName(NamedDecl namedDecl, out string nativeTypeN return remappedName; } - name = name.Replace("::", "."); + name = name.Replace("::", ".", StringComparison.Ordinal); remappedName = GetRemappedName(name, namedDecl, tryRemapOperatorName: true, out wasRemapped, skipUsing); if (wasRemapped) @@ -2941,7 +2960,7 @@ private string GetRemappedCursorName(NamedDecl namedDecl, out string nativeTypeN } else if (namedDecl is FieldDecl fieldDecl) { - if (name.StartsWith("__AnonymousFieldDecl_")) + if (name.StartsWith("__AnonymousFieldDecl_", StringComparison.Ordinal)) { remappedName = "Anonymous"; @@ -2951,11 +2970,11 @@ private string GetRemappedCursorName(NamedDecl namedDecl, out string nativeTypeN if (parent.AnonymousFields.Count > 1) { var index = parent.AnonymousFields.IndexOf(fieldDecl) + 1; - remappedName += index.ToString(); + remappedName += index.ToString(CultureInfo.InvariantCulture); } } } - else if ((namedDecl is RecordDecl recordDecl) && name.StartsWith("__AnonymousRecord_")) + else if ((namedDecl is RecordDecl recordDecl) && name.StartsWith("__AnonymousRecord_", StringComparison.Ordinal)) { if (recordDecl.Parent is RecordDecl parentRecordDecl) { @@ -2971,7 +2990,7 @@ private string GetRemappedCursorName(NamedDecl namedDecl, out string nativeTypeN else if (parentRecordDecl.AnonymousRecords.Count > 1) { var index = parentRecordDecl.AnonymousRecords.IndexOf(recordDecl) + 1; - remappedName += index.ToString(); + remappedName += index.ToString(CultureInfo.InvariantCulture); } remappedName += $"_e__{(recordDecl.IsUnion ? "Union" : "Struct")}"; @@ -2993,7 +3012,7 @@ private string GetRemappedName(string name, Cursor? cursor, bool tryRemapOperato return AddUsingDirectiveIfNeeded(_outputBuilder, remappedName, skipUsing); } - if (name.StartsWith("const ")) + if (name.StartsWith("const ", StringComparison.Ordinal)) { var tmpName = name[6..]; @@ -3015,7 +3034,7 @@ private string GetRemappedName(string name, Cursor? cursor, bool tryRemapOperato return AddUsingDirectiveIfNeeded(_outputBuilder, remappedName, skipUsing); } - if ((cursor is CXXBaseSpecifier cxxBaseSpecifier) && remappedName.StartsWith("__AnonymousBase_")) + if ((cursor is CXXBaseSpecifier cxxBaseSpecifier) && remappedName.StartsWith("__AnonymousBase_", StringComparison.Ordinal)) { Debug.Assert(_cxxRecordDeclContext is not null); remappedName = "Base"; @@ -3023,7 +3042,7 @@ private string GetRemappedName(string name, Cursor? cursor, bool tryRemapOperato if (_cxxRecordDeclContext.Bases.Count > 1) { var index = _cxxRecordDeclContext.Bases.IndexOf(cxxBaseSpecifier) + 1; - remappedName += index.ToString(); + remappedName += index.ToString(CultureInfo.InvariantCulture); } wasRemapped = true; @@ -3059,7 +3078,7 @@ private string GetRemappedTypeName(Cursor? cursor, Cursor? context, Type type, o if (!wasRemapped) { - nameToCheck = nameToCheck.Replace("::", "."); + nameToCheck = nameToCheck.Replace("::", ".", StringComparison.Ordinal); remappedName = GetRemappedName(nameToCheck, cursor, tryRemapOperatorName: false, out wasRemapped, skipUsing, skipUsingIfNotRemapped: true); if (!wasRemapped) @@ -3074,7 +3093,7 @@ private string GetRemappedTypeName(Cursor? cursor, Cursor? context, Type type, o type = arrayType.ElementType; } - if (IsType(cursor, type, out var recordType) && remappedName.StartsWith("__AnonymousRecord_")) + if (IsType(cursor, type, out var recordType) && remappedName.StartsWith("__AnonymousRecord_", StringComparison.Ordinal)) { var recordDecl = recordType.Decl; remappedName = "_Anonymous"; @@ -3113,14 +3132,14 @@ private string GetRemappedTypeName(Cursor? cursor, Cursor? context, Type type, o if (index != 0) { - remappedName += index.ToString(); + remappedName += index.ToString(CultureInfo.InvariantCulture); } } } remappedName += $"_e__{(recordDecl.IsUnion ? "Union" : "Struct")}"; } - else if (IsType(cursor, type, out var enumType) && remappedName.StartsWith("__AnonymousEnum_")) + else if (IsType(cursor, type, out var enumType) && remappedName.StartsWith("__AnonymousEnum_", StringComparison.Ordinal)) { remappedName = GetRemappedTypeName(enumType.Decl, context: null, enumType.Decl.IntegerType, out _, skipUsing); } @@ -3198,7 +3217,7 @@ private string GetTargetTypeName(Cursor cursor, out string nativeTypeName) { targetTypeName = GetRemappedTypeName(parmVarDecl, context: null, parmVarDecl.Type, out nativeTypeName); - if (!_config.GenerateDisableRuntimeMarshalling && (parmVarDecl.ParentFunctionOrMethod is FunctionDecl functionDecl) && ((functionDecl is CXXMethodDecl { IsVirtual: true }) || (functionDecl.Body is null)) && (targetTypeName == "bool")) + if (!_config.GenerateDisableRuntimeMarshalling && (parmVarDecl.ParentFunctionOrMethod is FunctionDecl functionDecl) && (((functionDecl is CXXMethodDecl cxxMethodDecl) && cxxMethodDecl.IsVirtual) || (functionDecl.Body is null)) && targetTypeName.Equals("bool", StringComparison.Ordinal)) { // bool is not blittable when DisableRuntimeMarshalling is not specified, so we shouldn't use it for P/Invoke signatures targetTypeName = "byte"; @@ -3210,7 +3229,7 @@ private string GetTargetTypeName(Cursor cursor, out string nativeTypeName) var type = varDecl.Type; var cursorName = GetCursorName(varDecl); - if (cursorName.StartsWith("ClangSharpMacro_")) + if (cursorName.StartsWith("ClangSharpMacro_", StringComparison.Ordinal)) { cursorName = cursorName["ClangSharpMacro_".Length..]; @@ -3267,9 +3286,9 @@ private string GetTypeName(Cursor? cursor, Cursor? context, Type rootType, Type if (!_typeNames.TryGetValue((cursor, context, type), out var result)) { result.typeName = type.AsString.NormalizePath() - .Replace("unnamed enum at", "anonymous enum at") - .Replace("unnamed struct at", "anonymous struct at") - .Replace("unnamed union at", "anonymous union at"); + .Replace("unnamed enum at", "anonymous enum at", StringComparison.Ordinal) + .Replace("unnamed struct at", "anonymous struct at", StringComparison.Ordinal) + .Replace("unnamed union at", "anonymous union at", StringComparison.Ordinal); result.nativeTypeName = result.typeName; @@ -3452,10 +3471,10 @@ private string GetTypeName(Cursor? cursor, Cursor? context, Type rootType, Type result.typeName = GetTypeName(cursor, context, rootType, elaboratedType.NamedType, ignoreTransparentStructsWhereRequired, out var nativeNamedTypeName); if (!string.IsNullOrWhiteSpace(nativeNamedTypeName) && - !result.nativeTypeName.StartsWith("const ") && - !result.nativeTypeName.StartsWith("enum ") && - !result.nativeTypeName.StartsWith("struct ") && - !result.nativeTypeName.StartsWith("union ")) + !result.nativeTypeName.StartsWith("const ", StringComparison.Ordinal) && + !result.nativeTypeName.StartsWith("enum ", StringComparison.Ordinal) && + !result.nativeTypeName.StartsWith("struct ", StringComparison.Ordinal) && + !result.nativeTypeName.StartsWith("union ", StringComparison.Ordinal)) { result.nativeTypeName = nativeNamedTypeName; } @@ -3513,21 +3532,21 @@ private string GetTypeName(Cursor? cursor, Cursor? context, Type rootType, Type { // The default name should be correct for C++, but C may have a prefix we need to strip - if (result.typeName.StartsWith("enum ")) + if (result.typeName.StartsWith("enum ", StringComparison.Ordinal)) { result.typeName = result.typeName[5..]; } - else if (result.typeName.StartsWith("struct ")) + else if (result.typeName.StartsWith("struct ", StringComparison.Ordinal)) { result.typeName = result.typeName[7..]; } - else if (result.typeName.StartsWith("union ")) + else if (result.typeName.StartsWith("union ", StringComparison.Ordinal)) { result.typeName = result.typeName[6..]; } } - if (result.typeName.Contains("::")) + if (result.typeName.Contains("::", StringComparison.Ordinal)) { result.typeName = result.typeName.Split(s_doubleColonSeparator, StringSplitOptions.RemoveEmptyEntries).Last(); result.typeName = GetRemappedName(result.typeName, cursor, tryRemapOperatorName: false, out _, skipUsing: true); @@ -3544,7 +3563,7 @@ private string GetTypeName(Cursor? cursor, Cursor? context, Type rootType, Type var templateTypeDeclName = GetRemappedCursorName(templateTypeDecl, out _, skipUsing: true); var isStdAtomic = false; - if (templateTypeDeclName == "atomic") + if (templateTypeDeclName.Equals("atomic", StringComparison.Ordinal)) { isStdAtomic = (templateTypeDecl.Parent is NamespaceDecl namespaceDecl) && namespaceDecl.IsStdNamespace; } @@ -3599,13 +3618,13 @@ private string GetTypeName(Cursor? cursor, Cursor? context, Type rootType, Type } } - if (!_config.GenerateDisableRuntimeMarshalling && (typeName == "bool")) + if (!_config.GenerateDisableRuntimeMarshalling && typeName.Equals("bool", StringComparison.Ordinal)) { // bool is not blittable when DisableRuntimeMarshalling is not specified, so we shouldn't use it for P/Invoke signatures typeName = "byte"; } - if (typeName.EndsWith("*") || typeName.Contains("delegate*")) + if (typeName.EndsWith('*') || typeName.Contains("delegate*", StringComparison.Ordinal)) { // Pointers are not yet supported as generic arguments; remap to IntPtr typeName = "IntPtr"; @@ -3687,10 +3706,10 @@ private string GetTypeNameForPointeeType(Cursor? cursor, Cursor? context, Type r name = GetTypeNameForPointeeType(cursor, context, rootType, elaboratedType.NamedType, ignoreTransparentStructsWhereRequired, out var nativeNamedTypeName, out isAdjusted); if (!string.IsNullOrWhiteSpace(nativeNamedTypeName) && - !nativePointeeTypeName.StartsWith("const ") && - !nativePointeeTypeName.StartsWith("enum ") && - !nativePointeeTypeName.StartsWith("struct ") && - !nativePointeeTypeName.StartsWith("union ")) + !nativePointeeTypeName.StartsWith("const ", StringComparison.Ordinal) && + !nativePointeeTypeName.StartsWith("enum ", StringComparison.Ordinal) && + !nativePointeeTypeName.StartsWith("struct ", StringComparison.Ordinal) && + !nativePointeeTypeName.StartsWith("union ", StringComparison.Ordinal)) { nativePointeeTypeName = nativeNamedTypeName; isAdjusted = true; @@ -3707,7 +3726,7 @@ private string GetTypeNameForPointeeType(Cursor? cursor, Cursor? context, Type r var needsReturnFixup = false; var returnTypeName = GetRemappedTypeName(cursor, context: null, functionType.ReturnType, out _, skipUsing: true); - if (!_config.GenerateDisableRuntimeMarshalling && (returnTypeName == "bool")) + if (!_config.GenerateDisableRuntimeMarshalling && returnTypeName.Equals("bool", StringComparison.Ordinal)) { // bool is not blittable when DisableRuntimeMarshalling is not specified, so we shouldn't use it for P/Invoke signatures returnTypeName = "byte"; @@ -3717,7 +3736,7 @@ private string GetTypeNameForPointeeType(Cursor? cursor, Cursor? context, Type r _ = nameBuilder.Append("delegate"); _ = nameBuilder.Append('*'); - var isMacroDefinitionRecord = (cursor is VarDecl varDecl) && GetCursorName(varDecl).StartsWith("ClangSharpMacro_"); + var isMacroDefinitionRecord = (cursor is VarDecl varDecl) && GetCursorName(varDecl).StartsWith("ClangSharpMacro_", StringComparison.Ordinal); if (!isMacroDefinitionRecord) { @@ -3781,7 +3800,7 @@ private string GetTypeNameForPointeeType(Cursor? cursor, Cursor? context, Type r { var typeName = GetRemappedTypeName(cursor, context: null, paramType, out _, skipUsing: true); - if (!_config.GenerateDisableRuntimeMarshalling && (typeName == "bool")) + if (!_config.GenerateDisableRuntimeMarshalling && typeName.Equals("bool", StringComparison.Ordinal)) { // bool is not blittable when DisableRuntimeMarshalling is not specified, so we shouldn't use it for P/Invoke signatures typeName = "byte"; @@ -4022,8 +4041,7 @@ private void GetTypeSize(Cursor cursor, Type type, ref long alignment32, ref lon } else if (type is InjectedClassNameType) { - Debug.Assert(size32 == 0); - Debug.Assert(size64 == 0); + // Nothing to handle } else if (type is RecordType recordType) { @@ -4238,7 +4256,7 @@ private void GetTypeSize(Cursor cursor, Type type, ref long alignment32, ref lon var name = GetTypeName(cursor, context: null, type, ignoreTransparentStructsWhereRequired: false, out _); var remappedName = GetRemappedTypeName(cursor, context: null, type, out _, skipUsing: true, ignoreTransparentStructsWhereRequired: false); - if ((remappedName == name) && _config.WithTransparentStructs.TryGetValue(remappedName, out var transparentStruct) && ((transparentStruct.Name == "long") || (transparentStruct.Name == "ulong"))) + if ((remappedName == name) && _config.WithTransparentStructs.TryGetValue(remappedName, out var transparentStruct) && (transparentStruct.Name.Equals("long", StringComparison.Ordinal) || transparentStruct.Name.Equals("ulong", StringComparison.Ordinal))) { size32 = 8; size64 = 8; @@ -4255,7 +4273,11 @@ private void GetTypeSize(Cursor cursor, Type type, ref long alignment32, ref lon has8BytePrimitiveField = true; } - else if (remappedName.Equals("IntPtr") || remappedName.Equals("nint") || remappedName.Equals("nuint") || remappedName.Equals("UIntPtr") || remappedName.EndsWith("*")) + else if (remappedName.Equals("IntPtr", StringComparison.Ordinal) || + remappedName.Equals("nint", StringComparison.Ordinal) || + remappedName.Equals("nuint", StringComparison.Ordinal) || + remappedName.Equals("UIntPtr", StringComparison.Ordinal) || + remappedName.EndsWith('*')) { size32 = 4; size64 = 8; @@ -4307,8 +4329,7 @@ private void GetTypeSize(Cursor cursor, Type type, ref long alignment32, ref lon } else if (type is TemplateTypeParmType) { - Debug.Assert(size32 == 0); - Debug.Assert(size64 == 0); + // Nothing to handle } else { @@ -4402,7 +4423,7 @@ private bool HasVtbl(CXXRecordDecl cxxRecordDecl, out bool hasBaseVtbl) private bool IsEnumOperator(FunctionDecl functionDecl, string name) { - if (name.StartsWith("operator") && ((functionDecl.Parameters.Count == 1) || (functionDecl.Parameters.Count == 2))) + if (name.StartsWith("operator", StringComparison.Ordinal) && ((functionDecl.Parameters.Count == 1) || (functionDecl.Parameters.Count == 2))) { var parmVarDecl1 = functionDecl.Parameters[0]; var parmVarDecl1Type = parmVarDecl1.Type; @@ -4455,7 +4476,7 @@ private bool IsExcluded(Cursor cursor, out bool isExcludedByConflictingDefinitio bool IsAlwaysIncluded(Cursor cursor) { - return (cursor is TranslationUnitDecl) || (cursor is LinkageSpecDecl) || (cursor is NamespaceDecl) || ((cursor is VarDecl varDecl) && varDecl.Name.StartsWith("ClangSharpMacro_")); + return (cursor is TranslationUnitDecl) || (cursor is LinkageSpecDecl) || (cursor is NamespaceDecl) || ((cursor is VarDecl varDecl) && varDecl.Name.StartsWith("ClangSharpMacro_", StringComparison.Ordinal)); } bool IsExcludedByConfig(Cursor cursor) @@ -4552,14 +4573,14 @@ bool IsExcludedByName(Cursor cursor, ref uint isExcludedValue) return false; } - if (qualifiedName.Contains("ClangSharpMacro_")) + if (qualifiedName.Contains("ClangSharpMacro_", StringComparison.Ordinal)) { - qualifiedName = qualifiedName.Replace("ClangSharpMacro_", ""); + qualifiedName = qualifiedName.Replace("ClangSharpMacro_", "", StringComparison.Ordinal); } - if (name.Contains("ClangSharpMacro_")) + if (name.Contains("ClangSharpMacro_", StringComparison.Ordinal)) { - name = name.Replace("ClangSharpMacro_", ""); + name = name.Replace("ClangSharpMacro_", "", StringComparison.Ordinal); } if (cursor is RecordDecl recordDecl) @@ -4591,7 +4612,7 @@ bool IsExcludedByName(Cursor cursor, ref uint isExcludedValue) } } - var dottedQualifiedName = qualifiedName.Replace("::", "."); + var dottedQualifiedName = qualifiedName.Replace("::", ".", StringComparison.Ordinal); if (_config.ExcludedNames.Contains(qualifiedName) || _config.ExcludedNames.Contains(dottedQualifiedName)) { @@ -4613,7 +4634,7 @@ bool IsExcludedByName(Cursor cursor, ref uint isExcludedValue) return true; } - var dottedQualifiedNameWithoutParameters = qualifiedNameWithoutParameters.Replace("::", "."); + var dottedQualifiedNameWithoutParameters = qualifiedNameWithoutParameters.Replace("::", ".", StringComparison.Ordinal); if (_config.ExcludedNames.Contains(qualifiedNameWithoutParameters) || _config.ExcludedNames.Contains(dottedQualifiedNameWithoutParameters) || _config.ExcludedNames.Contains(name)) { @@ -4702,15 +4723,15 @@ bool IsComProxy(FunctionDecl functionDecl, string name) { var parmVarDecl = null as ParmVarDecl; - if (name.EndsWith("_UserFree") || name.EndsWith("_UserFree64") || - name.EndsWith("_UserMarshal") || name.EndsWith("_UserMarshal64") || - name.EndsWith("_UserSize") || name.EndsWith("_UserSize64") || - name.EndsWith("_UserUnmarshal") || name.EndsWith("_UserUnmarshal64")) + if (name.EndsWith("_UserFree", StringComparison.Ordinal) || name.EndsWith("_UserFree64", StringComparison.Ordinal) || + name.EndsWith("_UserMarshal", StringComparison.Ordinal) || name.EndsWith("_UserMarshal64", StringComparison.Ordinal) || + name.EndsWith("_UserSize", StringComparison.Ordinal) || name.EndsWith("_UserSize64", StringComparison.Ordinal) || + name.EndsWith("_UserUnmarshal", StringComparison.Ordinal) || name.EndsWith("_UserUnmarshal64", StringComparison.Ordinal)) { var parameters = functionDecl.Parameters; parmVarDecl = (parameters.Count != 0) ? parameters[^1] : null; } - else if (name.EndsWith("_Proxy") || name.EndsWith("_Stub")) + else if (name.EndsWith("_Proxy", StringComparison.Ordinal) || name.EndsWith("_Stub", StringComparison.Ordinal)) { var parameters = functionDecl.Parameters; parmVarDecl = (parameters.Count != 0) ? parameters[0] : null; @@ -4719,7 +4740,7 @@ bool IsComProxy(FunctionDecl functionDecl, string name) if ((parmVarDecl is not null) && IsType(parmVarDecl, out var pointerType)) { var typeName = GetTypeName(parmVarDecl, context: null, pointerType.PointeeType, ignoreTransparentStructsWhereRequired: false, out var nativeTypeName); - return name.StartsWith($"{nativeTypeName}_") || name.StartsWith($"{typeName}_") || (typeName == "IRpcStubBuffer"); + return name.StartsWith($"{nativeTypeName}_", StringComparison.Ordinal) || name.StartsWith($"{typeName}_", StringComparison.Ordinal) || typeName.Equals("IRpcStubBuffer", StringComparison.Ordinal); } return false; } @@ -4865,14 +4886,14 @@ bool IsEmptyRecord(RecordDecl recordDecl) { if (recordDecl.Fields.Count != 0) { - if (!GetCursorName(recordDecl).EndsWith("__") || (recordDecl.Fields.Count != 1)) + if (!GetCursorName(recordDecl).EndsWith("__", StringComparison.Ordinal) || (recordDecl.Fields.Count != 1)) { return false; } var field = recordDecl.Fields[0]; - if ((GetCursorName(field) != "unused") || !IsType(field, out var builtinType) || (builtinType.Kind != CXType_Int)) + if (!GetCursorName(field).Equals("unused", StringComparison.Ordinal) || !IsType(field, out var builtinType) || (builtinType.Kind != CXType_Int)) { return false; } @@ -4961,10 +4982,10 @@ private bool IsFixedSize(Cursor cursor, Type type) var name = GetTypeName(cursor, context: null, type, ignoreTransparentStructsWhereRequired: false, out _); var remappedName = GetRemappedTypeName(cursor, context: null, type, out _, skipUsing: true, ignoreTransparentStructsWhereRequired: false); - return (remappedName != "IntPtr") - && (remappedName != "nint") - && (remappedName != "nuint") - && (remappedName != "UIntPtr") + return !remappedName.Equals("IntPtr", StringComparison.Ordinal) + && !remappedName.Equals("nint", StringComparison.Ordinal) + && !remappedName.Equals("nuint", StringComparison.Ordinal) + && !remappedName.Equals("UIntPtr", StringComparison.Ordinal) && IsFixedSize(cursor, typedefType.Decl.UnderlyingType); } else @@ -4977,7 +4998,7 @@ private bool IsFixedSize(Cursor cursor, Type type) private static bool IsNativeTypeNameEquivalent(string nativeTypeName, string typeName) { return nativeTypeName.Equals(typeName, StringComparison.OrdinalIgnoreCase) - || nativeTypeName.Replace(" ", "").Equals(typeName, StringComparison.OrdinalIgnoreCase); + || nativeTypeName.Replace(" ", "", StringComparison.Ordinal).Equals(typeName, StringComparison.OrdinalIgnoreCase); } private bool IsPrevContextDecl([MaybeNullWhen(false)] out T cursor, out object? userData) @@ -5250,7 +5271,7 @@ private bool IsUnchecked(string targetTypeName, Stmt stmt) { var cursorName = GetCursorName(parentVarDecl); - if (cursorName.StartsWith("ClangSharpMacro_") && _config.WithTransparentStructs.TryGetValue(targetTypeName, out var transparentStruct)) + if (cursorName.StartsWith("ClangSharpMacro_", StringComparison.Ordinal) && _config.WithTransparentStructs.TryGetValue(targetTypeName, out var transparentStruct)) { targetTypeName = transparentStruct.Name; } @@ -5469,7 +5490,7 @@ private bool IsUnchecked(string targetTypeName, Stmt stmt) { var integerLiteral = (IntegerLiteral)stmt; var signedValue = integerLiteral.Value; - return IsUnchecked(targetTypeName, signedValue, integerLiteral.IsNegative, isHex: integerLiteral.ValueString.StartsWith("0x")); + return IsUnchecked(targetTypeName, signedValue, integerLiteral.IsNegative, isHex: integerLiteral.ValueString.StartsWith("0x", StringComparison.Ordinal)); } case CX_StmtClass_LambdaExpr: @@ -5905,7 +5926,7 @@ private bool IsUnsafe(TypedefDecl typedefDecl, FunctionProtoType functionProtoTy private bool IsUnsafe(NamedDecl namedDecl, Type type) { var remappedName = GetRemappedTypeName(namedDecl, context: null, type, out _, skipUsing: true, ignoreTransparentStructsWhereRequired: false); - return remappedName.Contains('*'); + return remappedName.Contains('*', StringComparison.Ordinal); } private static bool IsUnsigned(string typeName) @@ -5924,7 +5945,7 @@ private static bool IsUnsigned(string typeName) case "UInt64": case "UIntPtr": case "ushort": - case var _ when typeName.EndsWith("*"): + case var _ when typeName.EndsWith('*'): { return true; } @@ -5984,20 +6005,20 @@ private bool NeedsReturnFixup(CXXMethodDecl cxxMethodDecl) private static bool NeedsNewKeyword(string name) { - return name.Equals("Equals") - || name.Equals("GetHashCode") - || name.Equals("GetType") - || name.Equals("MemberwiseClone") - || name.Equals("ReferenceEquals") - || name.Equals("ToString"); + return name.Equals("Equals",StringComparison.Ordinal) + || name.Equals("GetHashCode", StringComparison.Ordinal) + || name.Equals("GetType", StringComparison.Ordinal) + || name.Equals("MemberwiseClone", StringComparison.Ordinal) + || name.Equals("ReferenceEquals", StringComparison.Ordinal) + || name.Equals("ToString", StringComparison.Ordinal); } private static bool NeedsNewKeyword(string name, IReadOnlyList parmVarDecls) { - return (name.Equals("GetHashCode") - || name.Equals("GetType") - || name.Equals("MemberwiseClone") - || name.Equals("ToString")) && parmVarDecls.Count == 0; + return (parmVarDecls.Count == 0) && (name.Equals("GetHashCode", StringComparison.Ordinal) + || name.Equals("GetType", StringComparison.Ordinal) + || name.Equals("MemberwiseClone", StringComparison.Ordinal) + || name.Equals("ToString", StringComparison.Ordinal)); } private void ParenthesizeStmt(Stmt stmt) @@ -6031,12 +6052,12 @@ private void ParenthesizeStmt(Stmt stmt) private string PrefixAndStripName(string name, uint overloadIndex) { - if (name.StartsWith(_config.MethodPrefixToStrip)) + if (name.StartsWith(_config.MethodPrefixToStrip, StringComparison.Ordinal)) { name = name[_config.MethodPrefixToStrip.Length..]; } - return $"_{name}{((overloadIndex != 0) ? overloadIndex.ToString() : "")}"; + return $"_{name}{((overloadIndex != 0) ? overloadIndex.ToString(CultureInfo.InvariantCulture) : "")}"; } private void StartUsingOutputBuilder(string name, bool includeTestOutput = false) @@ -6110,7 +6131,7 @@ void CreateTestOutputBuilder(string name, string nameTests) { _testOutputBuilder = _outputBuilderFactory.CreateTests(nameTests); - var isTopLevelStruct = _config.WithTypes.TryGetValue(name, out var withType) && (withType == "struct"); + var isTopLevelStruct = _config.WithTypes.TryGetValue(name, out var withType) && withType.Equals("struct", StringComparison.Ordinal); if (!_topLevelClassNames.Contains(name) || isTopLevelStruct) { @@ -6148,19 +6169,19 @@ private bool TryGetUuid(RecordDecl recordDecl, out Guid uuid) return true; } - var uuidAttrs = recordDecl.Attrs.Where((attr) => attr.Kind == CX_AttrKind_Uuid); + var uuidAttrs = recordDecl.Attrs.Where((attr) => attr.Kind == CX_AttrKind_Uuid).ToArray(); - if (!uuidAttrs.Any()) + if (uuidAttrs.Length == 0) { uuid = Guid.Empty; return false; } - else if (uuidAttrs.Count() != 1) + else if (uuidAttrs.Length != 1) { AddDiagnostic(DiagnosticLevel.Warning, $"Multiply uuid attributes for {recordDecl.Name}. Falling back to first attribute.", recordDecl); } - var uuidAttr = uuidAttrs.First(); + var uuidAttr = uuidAttrs[0]; var uuidAttrText = GetSourceRangeContents(recordDecl.TranslationUnit.Handle, uuidAttr.Extent); var uuidText = uuidAttrText.Split(s_doubleQuoteSeparator, StringSplitOptions.RemoveEmptyEntries)[1]; @@ -6404,7 +6425,7 @@ private void Visit(Cursor cursor) { var targetTypeName = GetTargetTypeName(PreviousContext.Cursor, out _); - if (targetTypeName != "") + if (!string.IsNullOrEmpty(targetTypeName)) { UncheckStmt(targetTypeName, stmt); } @@ -6440,7 +6461,7 @@ private void WithAttributes(NamedDecl namedDecl, bool onlySupportedOSPlatform = if (TryGetRemappedValue(namedDecl, _config.WithAttributes, out var attributes)) { - foreach (var attribute in attributes.Where((a) => !onlySupportedOSPlatform || a.StartsWith("SupportedOSPlatform("))) + foreach (var attribute in attributes.Where((a) => !onlySupportedOSPlatform || a.StartsWith("SupportedOSPlatform(", StringComparison.Ordinal))) { outputBuilder.WriteCustomAttribute(attribute); } @@ -6493,7 +6514,7 @@ private void WithAttributes(NamedDecl namedDecl, bool onlySupportedOSPlatform = var attrText = GetSourceRangeContents(namedDecl.TranslationUnit.Handle, attr.Extent); - var textStart = attrText.IndexOf('"'); + var textStart = attrText.IndexOf('"', StringComparison.Ordinal); var textLength = attrText.LastIndexOf('"') - textStart; if (textLength > 1) @@ -6551,7 +6572,7 @@ private string GetClass(string remappedName, bool disallowPrefixMatch = false) private bool TryGetClass(string remappedName, [MaybeNullWhen(false)] out string className, bool disallowPrefixMatch = false) { - var index = remappedName.IndexOf('*'); + var index = remappedName.IndexOf('*', StringComparison.Ordinal); if (index != -1) { @@ -6572,14 +6593,14 @@ private bool TryGetClass(string remappedName, [MaybeNullWhen(false)] out string foreach (var withClass in _config.WithClasses) { - if (!withClass.Key.EndsWith("*")) + if (!withClass.Key.EndsWith('*')) { continue; } var prefix = withClass.Key[0..^1]; - if (remappedName.StartsWith(prefix)) + if (remappedName.StartsWith(prefix, StringComparison.Ordinal)) { className = withClass.Value; _ = _topLevelClassNames.Add(className); @@ -6609,7 +6630,7 @@ private string GetNamespace(string remappedName, NamedDecl? namedDecl = null) private bool TryGetNamespace(string remappedName, [MaybeNullWhen(false)] out string namespaceName) { - var index = remappedName.IndexOf('*'); + var index = remappedName.IndexOf('*', StringComparison.Ordinal); if (index != -1) { @@ -6625,7 +6646,7 @@ private bool HasRemapping(NamedDecl namedDecl, IReadOnlyCollection entri { var name = GetCursorQualifiedName(namedDecl); - if (name.StartsWith("ClangSharpMacro_")) + if (name.StartsWith("ClangSharpMacro_", StringComparison.Ordinal)) { name = name["ClangSharpMacro_".Length..]; } @@ -6635,7 +6656,7 @@ private bool HasRemapping(NamedDecl namedDecl, IReadOnlyCollection entri return true; } - name = name.Replace("::", "."); + name = name.Replace("::", ".", StringComparison.Ordinal); if (entries.Contains(name)) { @@ -6644,7 +6665,7 @@ private bool HasRemapping(NamedDecl namedDecl, IReadOnlyCollection entri name = GetCursorQualifiedName(namedDecl, truncateParameters: true); - if (name.StartsWith("ClangSharpMacro_")) + if (name.StartsWith("ClangSharpMacro_", StringComparison.Ordinal)) { name = name["ClangSharpMacro_".Length..]; } @@ -6654,7 +6675,7 @@ private bool HasRemapping(NamedDecl namedDecl, IReadOnlyCollection entri return true; } - name = name.Replace("::", "."); + name = name.Replace("::", ".", StringComparison.Ordinal); if (entries.Contains(name)) { @@ -6663,7 +6684,7 @@ private bool HasRemapping(NamedDecl namedDecl, IReadOnlyCollection entri name = GetRemappedCursorName(namedDecl); - if (name.StartsWith("ClangSharpMacro_")) + if (name.StartsWith("ClangSharpMacro_", StringComparison.Ordinal)) { name = name["ClangSharpMacro_".Length..]; } @@ -6675,7 +6696,7 @@ private bool TryGetRemappedValue(NamedDecl namedDecl, IReadOnlyDictionary(NamedDecl namedDecl, IReadOnlyDictionary(NamedDecl namedDecl, IReadOnlyDictionary(NamedDecl namedDecl, IReadOnlyDictionary(NamedDecl namedDecl, IReadOnlyDictionary(); - _forceRemappedNames = new SortedSet(); - _includedNames = new SortedSet(); - _nativeTypeNamesToStrip = new SortedSet(); - _withManualImports = new SortedSet(); - _traversalNames = new SortedSet(); - _withSetLastErrors = new SortedSet(); - _withSuppressGCTransitions = new SortedSet(); - - _remappedNames = new SortedDictionary(); - _withAccessSpecifiers = new SortedDictionary(); - _withAttributes = new SortedDictionary>(); - _withCallConvs = new SortedDictionary(); - _withClasses = new SortedDictionary(); - _withGuids = new SortedDictionary(); - _withLibraryPaths = new SortedDictionary(); - _withNamespaces = new SortedDictionary(); - _withTransparentStructs = new SortedDictionary(); - _withTypes = new SortedDictionary(); - _withUsings = new SortedDictionary>(); - _withPackings = new SortedDictionary(); + _excludedNames = []; + _forceRemappedNames = []; + _includedNames = []; + _nativeTypeNamesToStrip = []; + _withManualImports = []; + _traversalNames = []; + _withSetLastErrors = []; + _withSuppressGCTransitions = []; + + _remappedNames = []; + _withAccessSpecifiers = []; + _withAttributes = []; + _withCallConvs = []; + _withClasses = []; + _withGuids = []; + _withLibraryPaths = []; + _withNamespaces = []; + _withTransparentStructs = []; + _withTypes = []; + _withUsings = []; + _withPackings = []; if ((outputMode == PInvokeGeneratorOutputMode.Xml) && !options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateMultipleFiles) && (options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateTestsNUnit) || options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateTestsXUnit))) { @@ -581,6 +580,8 @@ public IReadOnlyDictionary WithPackings public static AccessSpecifier ConvertStringToAccessSpecifier(string input) { + ArgumentNullException.ThrowIfNull(input); + return input.Equals("internal", StringComparison.OrdinalIgnoreCase) ? AccessSpecifier.Internal : input.Equals("private", StringComparison.OrdinalIgnoreCase) ? AccessSpecifier.Private : input.Equals("private protected", StringComparison.OrdinalIgnoreCase) ? AccessSpecifier.PrivateProtected @@ -655,5 +656,5 @@ private static void AddRange(SortedSet hashSet, IEnumerable (ValueStartsWithAt(value.Name) ? value.Name[1..] : value.Name, value.Kind); - private static bool ValueStartsWithAt(string value) => value.StartsWith("@"); + private static bool ValueStartsWithAt(string value) => value.StartsWith('@'); } diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs index a654e7df..60343e0b 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfigurationOptions.cs @@ -5,83 +5,83 @@ namespace ClangSharp; [Flags] -public enum PInvokeGeneratorConfigurationOptions : ulong +public enum PInvokeGeneratorConfigurationOptions : long { None = 0, - GenerateMultipleFiles = 1UL << 0, + GenerateMultipleFiles = 1L << 0, - GenerateUnixTypes = 1UL << 1, + GenerateUnixTypes = 1L << 1, - NoDefaultRemappings = 1UL << 2, + NoDefaultRemappings = 1L << 2, - GenerateCompatibleCode = 1UL << 3, + GenerateCompatibleCode = 1L << 3, - ExcludeNIntCodegen = 1UL << 4, + ExcludeNIntCodegen = 1L << 4, - ExcludeFnptrCodegen = 1UL << 5, + ExcludeFnptrCodegen = 1L << 5, - LogExclusions = 1UL << 6, + LogExclusions = 1L << 6, - LogVisitedFiles = 1UL << 7, + LogVisitedFiles = 1L << 7, - GenerateExplicitVtbls = 1UL << 8, + GenerateExplicitVtbls = 1L << 8, - GenerateTestsNUnit = 1UL << 9, + GenerateTestsNUnit = 1L << 9, - GenerateTestsXUnit = 1UL << 10, + GenerateTestsXUnit = 1L << 10, - GenerateMacroBindings = 1UL << 11, + GenerateMacroBindings = 1L << 11, - ExcludeComProxies = 1UL << 12, + ExcludeComProxies = 1L << 12, - ExcludeEmptyRecords = 1UL << 13, + ExcludeEmptyRecords = 1L << 13, - ExcludeEnumOperators = 1UL << 14, + ExcludeEnumOperators = 1L << 14, - GenerateAggressiveInlining = 1UL << 15, + GenerateAggressiveInlining = 1L << 15, - ExcludeFunctionsWithBody = 1UL << 16, + ExcludeFunctionsWithBody = 1L << 16, - ExcludeAnonymousFieldHelpers = 1UL << 17, + ExcludeAnonymousFieldHelpers = 1L << 17, - LogPotentialTypedefRemappings = 1UL << 18, + LogPotentialTypedefRemappings = 1L << 18, - GenerateCppAttributes = 1UL << 19, + GenerateCppAttributes = 1L << 19, - GenerateNativeInheritanceAttribute = 1UL << 20, + GenerateNativeInheritanceAttribute = 1L << 20, - DontUseUsingStaticsForEnums = 1UL << 21, + DontUseUsingStaticsForEnums = 1L << 21, - GenerateVtblIndexAttribute = 1UL << 22, + GenerateVtblIndexAttribute = 1L << 22, - GeneratePreviewCode = 1UL << 23, + GeneratePreviewCode = 1L << 23, - GenerateTemplateBindings = 1UL << 24, + GenerateTemplateBindings = 1L << 24, - GenerateSourceLocationAttribute = 1UL << 25, + GenerateSourceLocationAttribute = 1L << 25, - GenerateUnmanagedConstants = 1UL << 26, + GenerateUnmanagedConstants = 1L << 26, - GenerateHelperTypes = 1UL << 27, + GenerateHelperTypes = 1L << 27, - GenerateTrimmableVtbls = 1UL << 28, + GenerateTrimmableVtbls = 1L << 28, - GenerateMarkerInterfaces = 1UL << 29, + GenerateMarkerInterfaces = 1L << 29, - GenerateFileScopedNamespaces = 1UL << 30, + GenerateFileScopedNamespaces = 1L << 30, - GenerateSetsLastSystemErrorAttribute = 1UL << 31, + GenerateSetsLastSystemErrorAttribute = 1L << 31, - GenerateDocIncludes = 1UL << 32, + GenerateDocIncludes = 1L << 32, - GenerateGuidMember = 1UL << 33, + GenerateGuidMember = 1L << 33, - GenerateLatestCode = 1UL << 34, + GenerateLatestCode = 1L << 34, - GenerateNativeBitfieldAttribute = 1UL << 35, + GenerateNativeBitfieldAttribute = 1L << 35, - GenerateDisableRuntimeMarshalling = 1UL << 36, + GenerateDisableRuntimeMarshalling = 1L << 36, - GenerateCallConvMemberFunction = 1UL << 37, + GenerateCallConvMemberFunction = 1L << 37, } diff --git a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.Visit.cs b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.Visit.cs index a0b9883f..d4c81ca2 100644 --- a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.Visit.cs +++ b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.Visit.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. using System; +using System.Globalization; namespace ClangSharp.XML; @@ -8,14 +9,18 @@ internal partial class XmlOutputBuilder { public void WriteCustomAttribute(string attribute, Action? callback = null) { - _ = _sb.Append($"{attribute}"); + _ = _sb.Append(CultureInfo.InvariantCulture, $"{attribute}"); callback?.Invoke(); _ = _sb.Append("\n"); } public void WriteIid(string name, Guid value) { - var valueString = value.ToString("X").ToUpperInvariant().Replace("{", "").Replace("}", "").Replace('X', 'x').Replace(",", ", "); + var valueString = value.ToString("X", CultureInfo.InvariantCulture).ToUpperInvariant() + .Replace("{", "", StringComparison.Ordinal) + .Replace("}", "", StringComparison.Ordinal) + .Replace('X', 'x') + .Replace(",", ", ", StringComparison.Ordinal); WriteIid(name, valueString); } diff --git a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs index 0c688f91..8138dfb6 100644 --- a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs @@ -1,7 +1,8 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. +using System; using System.Diagnostics; -using System.Runtime.InteropServices; +using System.Globalization; using System.Text; using ClangSharp.Abstractions; using ClangSharp.CSharp; @@ -38,10 +39,10 @@ public void BeginValue(in ValueDesc desc) : desc.IsConstant ? _sb.Append(""); + _ = _sb.Append(CultureInfo.InvariantCulture, $" name=\"{desc.EscapedName}\" access=\"{desc.AccessSpecifier.AsString()}\">"); desc.WriteCustomAttrs?.Invoke(desc.CustomAttrGeneratorData); - _ = _sb.Append($""); + _ = _sb.Append(CultureInfo.InvariantCulture, $""); _ = _sb.Append(EscapeText(desc.TypeName)); _ = _sb.Append(""); @@ -68,24 +69,24 @@ public void EndValue(in ValueDesc desc) public void BeginEnum(in EnumDesc desc) { - _ = _sb.Append($""); + _ = _sb.Append(CultureInfo.InvariantCulture, $""); desc.WriteCustomAttrs?.Invoke(desc.CustomAttrGeneratorData); - _ = _sb.Append($"{desc.TypeName}"); + _ = _sb.Append(CultureInfo.InvariantCulture, $"{desc.TypeName}"); } public void EndEnum(in EnumDesc desc) => _sb.Append(""); public void BeginField(in FieldDesc desc) { - _ = _sb.Append($"'); @@ -96,35 +97,34 @@ public void BeginField(in FieldDesc desc) } public void WriteFixedCountField(string typeName, string escapedName, string fixedName, string count) - => _sb.Append($" count=\"{count}\" fixed=\"{fixedName}\">" + - $"{EscapeText(typeName)}"); + => _sb.Append(CultureInfo.InvariantCulture, $" count=\"{count}\" fixed=\"{fixedName}\">{EscapeText(typeName)}"); public void WriteRegularField(string typeName, string escapedName) - => _sb.Append($">{EscapeText(typeName)}"); + => _sb.Append(CultureInfo.InvariantCulture, $">{EscapeText(typeName)}"); public void EndField(in FieldDesc desc) => _sb.Append(""); public void BeginFunctionOrDelegate(in FunctionOrDelegateDesc desc, ref bool isMethodClassUnsafe) { if (desc.IsVirtual) { Debug.Assert(!desc.HasFnPtrCodeGen); - _ = _sb.Append($"'); @@ -174,7 +174,7 @@ public void BeginFunctionInnerPrototype(in FunctionOrDelegateDesc info) public void BeginParameter(in ParameterDesc info) { - _ = _sb.Append($""); + _ = _sb.Append(CultureInfo.InvariantCulture, $""); info.WriteCustomAttrs?.Invoke(info.CustomAttrGeneratorData); _ = _sb.Append(""); _ = _sb.Append(EscapeText(info.Type)); @@ -210,7 +210,7 @@ public void BeginConstructorInitializers() public void BeginConstructorInitializer(string memberRefName, string memberInitName) => // "hint" is the name we're initializing using, but should only be used as a "hint" rather than a definitive // value, which is contained within the init block. - _ = _sb.Append($""); + _ = _sb.Append(CultureInfo.InvariantCulture, $""); public void EndConstructorInitializer() => _sb.Append(""); @@ -323,8 +323,8 @@ public void EndCSharpCode(CSharpOutputBuilder output) _ = _sb.Append('\n'); } - _ = _sb.Append(EscapeText(s).Replace("/*M*/<", "<") - .Replace("/*M*/>", ">")); + _ = _sb.Append(EscapeText(s).Replace("/*M*/<", "<", StringComparison.Ordinal) + .Replace("/*M*/>", ">", StringComparison.Ordinal)); needsNewline = true; } @@ -398,7 +398,7 @@ private void AddNativeTypeNameAttribute(string? nativeTypeName) foreach (var entry in _config.NativeTypeNamesToStrip) { - nativeTypeName = nativeTypeName.Replace(entry, ""); + nativeTypeName = nativeTypeName.Replace(entry, "", StringComparison.Ordinal); } if (string.IsNullOrWhiteSpace(nativeTypeName)) diff --git a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.cs b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.cs index 8561c4d1..0d8d5126 100644 --- a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.cs +++ b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.cs @@ -8,29 +8,23 @@ namespace ClangSharp.XML; -internal partial class XmlOutputBuilder : IOutputBuilder +internal partial class XmlOutputBuilder(string name, PInvokeGeneratorConfiguration config) : IOutputBuilder { - private readonly PInvokeGeneratorConfiguration _config; + private readonly PInvokeGeneratorConfiguration _config = config; - public XmlOutputBuilder(string name, PInvokeGeneratorConfiguration config) - { - Name = name; - _config = config; - } - - public string Name { get; } + public string Name { get; } = name; public string Extension { get; } = ".xml"; public bool IsUncheckedContext { get; private set; } - public bool IsTestOutput { get; } = false; + public bool IsTestOutput { get; } public IEnumerable Contents { get { StringWriter sw = new(); - var writer = XmlWriter.Create(sw, new() + using var writer = XmlWriter.Create(sw, new() { Indent = true, IndentChars = " ", @@ -38,7 +32,7 @@ public IEnumerable Contents NewLineChars = "\n", }); - foreach (var node in XElement.Parse("" + _sb + "").Nodes()) + foreach (var node in XElement.Parse($"{_sb}").Nodes()) { node.WriteTo(writer); } diff --git a/sources/ClangSharp/ClangSharp.csproj b/sources/ClangSharp/ClangSharp.csproj index c0ffbb00..aa8ce820 100644 --- a/sources/ClangSharp/ClangSharp.csproj +++ b/sources/ClangSharp/ClangSharp.csproj @@ -2,6 +2,10 @@ + + + + $(NoWarn);CA1034;CA1040;CA1720 net8.0;netstandard2.0 diff --git a/sources/ClangSharp/Cursors/Cursor.cs b/sources/ClangSharp/Cursors/Cursor.cs index ccf2a6aa..772d5206 100644 --- a/sources/ClangSharp/Cursors/Cursor.cs +++ b/sources/ClangSharp/Cursors/Cursor.cs @@ -65,7 +65,7 @@ public IReadOnlyList CursorChildren cursorChildrenHandle.Free(); #if NET6_0_OR_GREATER - [UnmanagedCallersOnly(CallConvs = new System.Type[] { typeof(CallConvCdecl) })] + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])] #endif static CXChildVisitResult Visitor(CXCursor cursor, CXCursor parent, void* client_data) { @@ -80,7 +80,6 @@ static CXChildVisitResult Visitor(CXCursor cursor, CXCursor parent, void* client } } - Debug.Assert(_cursorChildren is not null); return _cursorChildren!; } } diff --git a/sources/ClangSharp/Cursors/Decls/BlockDecl.cs b/sources/ClangSharp/Cursors/Decls/BlockDecl.cs index 1345497b..b52ad9a1 100644 --- a/sources/ClangSharp/Cursors/Decls/BlockDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/BlockDecl.cs @@ -75,5 +75,5 @@ internal BlockDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_De public nuint ParamSize => NumParams; - public bool CapturesVariable(VarDecl var) => Handle.CapturesVariable(var.Handle); + public bool CapturesVariable(VarDecl var) => Handle.CapturesVariable((var is not null) ? var.Handle : CXCursor.Null); } diff --git a/sources/ClangSharp/Cursors/Decls/CXXConstructorDecl.cs b/sources/ClangSharp/Cursors/Decls/CXXConstructorDecl.cs index 17b6bcdd..6781c882 100644 --- a/sources/ClangSharp/Cursors/Decls/CXXConstructorDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/CXXConstructorDecl.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; diff --git a/sources/ClangSharp/Cursors/Decls/Decl.cs b/sources/ClangSharp/Cursors/Decls/Decl.cs index c149cb0e..e509e4a5 100644 --- a/sources/ClangSharp/Cursors/Decls/Decl.cs +++ b/sources/ClangSharp/Cursors/Decls/Decl.cs @@ -121,7 +121,7 @@ public bool IsStdNamespace { var redeclContext = parent!.RedeclContext; Debug.Assert(redeclContext is not null); - return redeclContext!.IsTranslationUnit && (nd.Name == "std"); + return redeclContext!.IsTranslationUnit && nd.Name.Equals("std", StringComparison.Ordinal); } } diff --git a/sources/ClangSharp/Cursors/Exprs/CallExpr.cs b/sources/ClangSharp/Cursors/Exprs/CallExpr.cs index b944462e..0fb2f058 100644 --- a/sources/ClangSharp/Cursors/Exprs/CallExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CallExpr.cs @@ -40,7 +40,7 @@ private protected CallExpr(CXCursor handle, CXCursorKind expectedCursorKind, CX_ public FunctionDecl? DirectCallee => CalleeDecl as FunctionDecl; - public bool IsCallToStdMove => (NumArgs == 1) && (DirectCallee is FunctionDecl fd) && fd.IsInStdNamespace && (fd.Name == "move"); + public bool IsCallToStdMove => (NumArgs == 1) && (DirectCallee is FunctionDecl fd) && fd.IsInStdNamespace && fd.Name.Equals("move", StringComparison.Ordinal); public uint NumArgs => (uint)Handle.NumArguments; } diff --git a/sources/ClangSharp/Cursors/Exprs/CharacterLiteral.cs b/sources/ClangSharp/Cursors/Exprs/CharacterLiteral.cs index 1ab655fd..3741af7f 100644 --- a/sources/ClangSharp/Cursors/Exprs/CharacterLiteral.cs +++ b/sources/ClangSharp/Cursors/Exprs/CharacterLiteral.cs @@ -2,6 +2,7 @@ using System; using System.Diagnostics; +using System.Globalization; using ClangSharp.Interop; using static ClangSharp.Interop.CX_StmtClass; using static ClangSharp.Interop.CXCursorKind; @@ -27,7 +28,7 @@ internal CharacterLiteral(CXCursor handle) : base(handle, CXCursor_CharacterLite if ((tokens.Length == 0) || (tokens[0].Kind is not CXToken_Literal and not CXToken_Identifier)) { Debug.Assert(false, "Failed to stringify tokens for character literal."); - return Value.ToString(); + return Value.ToString(CultureInfo.InvariantCulture); } } diff --git a/sources/ClangSharp/Cursors/Exprs/FloatingLiteral.cs b/sources/ClangSharp/Cursors/Exprs/FloatingLiteral.cs index 83dc6d5f..b99fbeb6 100644 --- a/sources/ClangSharp/Cursors/Exprs/FloatingLiteral.cs +++ b/sources/ClangSharp/Cursors/Exprs/FloatingLiteral.cs @@ -2,6 +2,7 @@ using System; using System.Diagnostics; +using System.Globalization; using ClangSharp.Interop; using static ClangSharp.Interop.CX_StmtClass; using static ClangSharp.Interop.CXCursorKind; @@ -25,7 +26,7 @@ internal FloatingLiteral(CXCursor handle) : base(handle, CXCursor_FloatingLitera if ((tokens.Length == 0) || (tokens[0].Kind is not CXToken_Literal and not CXToken_Identifier)) { Debug.Assert(false, "Failed to stringify tokens for floating literal."); - return ValueAsApproximateDouble.ToString(); + return ValueAsApproximateDouble.ToString(CultureInfo.InvariantCulture); } } diff --git a/sources/ClangSharp/Cursors/Exprs/IntegerLiteral.cs b/sources/ClangSharp/Cursors/Exprs/IntegerLiteral.cs index f548464a..976c965a 100644 --- a/sources/ClangSharp/Cursors/Exprs/IntegerLiteral.cs +++ b/sources/ClangSharp/Cursors/Exprs/IntegerLiteral.cs @@ -2,6 +2,7 @@ using System; using System.Diagnostics; +using System.Globalization; using ClangSharp.Interop; using static ClangSharp.Interop.CX_StmtClass; using static ClangSharp.Interop.CXCursorKind; @@ -25,7 +26,7 @@ internal IntegerLiteral(CXCursor handle) : base(handle, CXCursor_IntegerLiteral, if ((tokens.Length == 0) || (tokens[0].Kind is not CXToken_Literal and not CXToken_Identifier)) { Debug.Assert(false, "Failed to stringify tokens for integer literal."); - return Value.ToString(); + return Value.ToString(CultureInfo.InvariantCulture); } } diff --git a/sources/ClangSharp/Cursors/Stmts/CapturedStmt.cs b/sources/ClangSharp/Cursors/Stmts/CapturedStmt.cs index fc098e83..b194370d 100644 --- a/sources/ClangSharp/Cursors/Stmts/CapturedStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/CapturedStmt.cs @@ -55,6 +55,8 @@ internal CapturedStmt(CXCursor handle) : base(handle, CXCursor_UnexposedStmt, CX public bool CapturesVariable(VarDecl var) { + var canonicalDecl = var?.CanonicalDecl; + foreach (var i in Captures) { if (!i.CapturesVariable && !i.CapturesVariableByCopy) @@ -62,7 +64,7 @@ public bool CapturesVariable(VarDecl var) continue; } - if (i.CapturedVar.CanonicalDecl == var.CanonicalDecl) + if (i.CapturedVar.CanonicalDecl == canonicalDecl) { return true; } diff --git a/sources/ClangSharp/TranslationUnit.cs b/sources/ClangSharp/TranslationUnit.cs index e86d51b7..41f16045 100644 --- a/sources/ClangSharp/TranslationUnit.cs +++ b/sources/ClangSharp/TranslationUnit.cs @@ -29,11 +29,11 @@ private TranslationUnit(CXTranslationUnit handle) { Handle = handle; - _createdCursors = new Dictionary>(); - _createdTemplateArguments = new Dictionary>(); - _createdTemplateArgumentLocs = new Dictionary>(); - _createdTemplateNames = new Dictionary>(); - _createdTypes = new Dictionary>(); + _createdCursors = []; + _createdTemplateArguments = []; + _createdTemplateArgumentLocs = []; + _createdTemplateNames = []; + _createdTypes = []; _translationUnitDecl = new Lazy(() => GetOrCreate(Handle.Cursor)); } @@ -119,7 +119,7 @@ internal TemplateArgument GetOrCreate(CX_TemplateArgument handle) if (handle.kind == CXTemplateArgumentKind_Invalid) { - Debug.Assert(handle.kind != CXTemplateArgumentKind_Invalid); + Debug.Assert(false, "Unsupported template argument encountered."); return null!; } else if (!_createdTemplateArguments.TryGetValue(handle, out templateArgumentRef)) @@ -142,7 +142,7 @@ internal TemplateArgumentLoc GetOrCreate(CX_TemplateArgumentLoc handle) if (handle.value == null) { - Debug.Assert(handle.value != null); + Debug.Assert(false, "Unsupported template argument location encountered."); return null!; } else if (!_createdTemplateArgumentLocs.TryGetValue(handle, out templateArgumentLocRef)) @@ -165,7 +165,7 @@ internal TemplateName GetOrCreate(CX_TemplateName handle) if (handle.kind == CX_TNK_Invalid) { - Debug.Assert(handle.kind != CX_TNK_Invalid); + Debug.Assert(false, "Unsupported template name encountered."); return null!; } else if (!_createdTemplateNames.TryGetValue(handle, out templateNameRef)) @@ -189,7 +189,7 @@ internal TType GetOrCreate(CXType handle) if (handle.kind == CXType_Invalid) { - Debug.Assert(handle.kind != CXType_Invalid); + Debug.Assert(false, "Unsupported type encountered."); return null!; } else if (!_createdTypes.TryGetValue(handle, out typeRef)) diff --git a/sources/ClangSharpPInvokeGenerator/Program.cs b/sources/ClangSharpPInvokeGenerator/Program.cs index cb8457c6..b97fb533 100644 --- a/sources/ClangSharpPInvokeGenerator/Program.cs +++ b/sources/ClangSharpPInvokeGenerator/Program.cs @@ -13,7 +13,6 @@ using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; using ClangSharp.Interop; using static ClangSharp.Interop.CXDiagnosticSeverity; using static ClangSharp.Interop.CXErrorCode; @@ -21,49 +20,49 @@ namespace ClangSharp; -public class Program +public static class Program { - private static readonly RootCommand s_rootCommand; - - private static readonly Option s_versionOption; - private static readonly Option s_additionalOption; - private static readonly Option s_configOption; - private static readonly Option s_defineMacros; - private static readonly Option s_excludedNames; - private static readonly Option s_files; - private static readonly Option s_fileDirectory; - private static readonly Option s_headerFile; - private static readonly Option s_includedNames; - private static readonly Option s_includeDirectories; - private static readonly Option s_language; - private static readonly Option s_libraryPath; - private static readonly Option s_methodClassName; - private static readonly Option s_methodPrefixToStrip; - private static readonly Option s_nativeTypeNamesToStrip; - private static readonly Option s_namespaceName; - private static readonly Option s_outputLocation; - private static readonly Option s_outputMode; - private static readonly Option s_remappedNameValuePairs; - private static readonly Option s_std; - private static readonly Option s_testOutputLocation; - private static readonly Option s_traversalNames; - private static readonly Option s_withAccessSpecifierNameValuePairs; - private static readonly Option s_withAttributeNameValuePairs; - private static readonly Option s_withCallConvNameValuePairs; - private static readonly Option s_withClassNameValuePairs; - private static readonly Option s_withGuidNameValuePairs; - private static readonly Option s_withLibraryPathNameValuePairs; - private static readonly Option s_withManualImports; - private static readonly Option s_withNamespaceNameValuePairs; - private static readonly Option s_withSetLastErrors; - private static readonly Option s_withSuppressGCTransitions; - private static readonly Option s_withTransparentStructNameValuePairs; - private static readonly Option s_withTypeNameValuePairs; - private static readonly Option s_withUsingNameValuePairs; - private static readonly Option s_withPackingNameValuePairs; - - private static readonly TwoColumnHelpRow[] s_configOptions = new TwoColumnHelpRow[] - { + private static readonly Option s_additionalOption = GetAdditionalOption(); + private static readonly Option s_configOption = GetConfigOption(); + private static readonly Option s_defineMacros = GetDefineMacroOption(); + private static readonly Option s_excludedNames = GetExcludeOption(); + private static readonly Option s_files = GetFileOption(); + private static readonly Option s_fileDirectory = GetFileDirectoryOption(); + private static readonly Option s_headerFile = GetHeaderOption(); + private static readonly Option s_includedNames = GetIncludeOption(); + private static readonly Option s_includeDirectories = GetIncludeDirectoryOption(); + private static readonly Option s_language = GetLanguageOption(); + private static readonly Option s_libraryPath = GetLibraryOption(); + private static readonly Option s_methodClassName = GetMethodClassNameOption(); + private static readonly Option s_methodPrefixToStrip = GetPrefixStripOption(); + private static readonly Option s_namespaceName = GetNamespaceOption(); + private static readonly Option s_nativeTypeNamesToStrip = GetNativeTypeNamesStripOption(); + private static readonly Option s_outputLocation = GetOutputOption(); + private static readonly Option s_outputMode = GetOutputModeOption(); + private static readonly Option s_remappedNameValuePairs = GetRemapOption(); + private static readonly Option s_std = GetStdOption(); + private static readonly Option s_testOutputLocation = GetTestOutputOption(); + private static readonly Option s_traversalNames = GetTraverseOption(); + private static readonly Option s_versionOption = GetVersionOption(); + private static readonly Option s_withAccessSpecifierNameValuePairs = GetWithAccessSpecifierOption(); + private static readonly Option s_withAttributeNameValuePairs = GetWithAttributeOption(); + private static readonly Option s_withCallConvNameValuePairs = GetWithCallConvOption(); + private static readonly Option s_withClassNameValuePairs = GetWithClassOption(); + private static readonly Option s_withGuidNameValuePairs = GetWithGuidOption(); + private static readonly Option s_withLibraryPathNameValuePairs = GetWithLibraryPathOption(); + private static readonly Option s_withManualImports = GetWithManualImportOption(); + private static readonly Option s_withNamespaceNameValuePairs = GetWithNamespaceOption(); + private static readonly Option s_withSetLastErrors = GetWithSetLastErrorOption(); + private static readonly Option s_withSuppressGCTransitions = GetWithSuppressGCTransitionOption(); + private static readonly Option s_withTransparentStructNameValuePairs = GetWithTransparentStructOption(); + private static readonly Option s_withTypeNameValuePairs = GetWithTypeOption(); + private static readonly Option s_withUsingNameValuePairs = GetWithUsingOption(); + private static readonly Option s_withPackingNameValuePairs = GetWithPackingOption(); + + private static readonly RootCommand s_rootCommand = GetRootCommand(); + + private static readonly TwoColumnHelpRow[] s_configOptions = + [ new TwoColumnHelpRow("?, h, help", "Show help and usage information for -c, --config"), // Codegen Options @@ -129,125 +128,44 @@ public class Program new TwoColumnHelpRow("log-exclusions", "A list of excluded declaration types should be generated. This will also log if the exclusion was due to an exact or partial match."), new TwoColumnHelpRow("log-potential-typedef-remappings", "A list of potential typedef remappings should be generated. This can help identify missing remappings."), new TwoColumnHelpRow("log-visited-files", "A list of the visited files should be generated. This can help identify traversal issues."), - }; - - private static readonly string[] s_additionalOptionAliases = new string[] { "--additional", "-a" }; - private static readonly string[] s_configOptionAliases = new string[] { "--config", "-c" }; - private static readonly string[] s_defineMacroOptionAliases = new string[] { "--define-macro", "-D" }; - private static readonly string[] s_excludeOptionAliases = new string[] { "--exclude", "-e" }; - private static readonly string[] s_fileOptionAliases = new string[] { "--file", "-f" }; - private static readonly string[] s_fileDirectionOptionAliases = new string[] { "--file-directory", "-F" }; - private static readonly string[] s_headerOptionAliases = new string[] { "--headerFile", "-h" }; - private static readonly string[] s_includeOptionAliases = new string[] { "--include", "-i" }; - private static readonly string[] s_includeDirectoryOptionAliases = new string[] { "--include-directory", "-I" }; - private static readonly string[] s_languageOptionAliases = new string[] { "--language", "-x" }; - private static readonly string[] s_libraryOptionAliases = new string[] { "--libraryPath", "-l" }; - private static readonly string[] s_methodClassNameOptionAliases = new string[] { "--methodClassName", "-m" }; - private static readonly string[] s_namespaceOptionAliases = new string[] { "--namespace", "-n" }; - private static readonly string[] s_nativeTypeNamesStripOptionAliases = new string[] { "--nativeTypeNamesToStrip" }; - private static readonly string[] s_outputModeOptionAliases = new string[] { "--output-mode", "-om" }; - private static readonly string[] s_outputOptionAliases = new string[] { "--output", "-o" }; - private static readonly string[] s_prefixStripOptionAliases = new string[] { "--prefixStrip", "-p" }; - private static readonly string[] s_remapOptionAliases = new string[] { "--remap", "-r" }; - private static readonly string[] s_stdOptionAliases = new string[] { "--std", "-std" }; - private static readonly string[] s_testOutputOptionAliases = new string[] { "--test-output", "-to" }; - private static readonly string[] s_versionOptionAliases = new string[] { "--version", "-v" }; - private static readonly string[] s_traverseOptionAliases = new string[] { "--traverse", "-t" }; - private static readonly string[] s_withAccessSpecifierOptionAliases = new string[] { "--with-access-specifier", "-was" }; - private static readonly string[] s_withAttributeOptionAliases = new string[] { "--with-attribute", "-wa" }; - private static readonly string[] s_withCallConvOptionAliases = new string[] { "--with-callconv", "-wcc" }; - private static readonly string[] s_withClassOptionAliases = new string[] { "--with-class", "-wc" }; - private static readonly string[] s_withGuidOptionAliases = new string[] { "--with-guid", "-wg" }; - private static readonly string[] s_withLibraryPathOptionAliases = new string[] { "--with-librarypath", "-wlb" }; - private static readonly string[] s_withManualImportOptionAliases = new string[] { "--with-manual-import", "-wmi" }; - private static readonly string[] s_withNamespaceOptionAliases = new string[] { "--with-namespace", "-wn" }; - private static readonly string[] s_withSetLastErrorOptionAliases = new string[] { "--with-setlasterror", "-wsle" }; - private static readonly string[] s_withSuppressGCTransitionOptionAliases = new string[] { "--with-suppressgctransition", "-wsgct" }; - private static readonly string[] s_withTransparentStructOptionAliases = new string[] { "--with-transparent-struct", "-wts" }; - private static readonly string[] s_withTypeOptionAliases = new string[] { "--with-type", "-wt" }; - private static readonly string[] s_withUsingOptionAliases = new string[] { "--with-using", "-wu" }; - private static readonly string[] s_withPackingOptionAliases = new string[] { "--with-packing", "-wp" }; - - static Program() - { - s_additionalOption = GetAdditionalOption(); - s_configOption = GetConfigOption(); - s_defineMacros = GetDefineMacroOption(); - s_excludedNames = GetExcludeOption(); - s_files = GetFileOption(); - s_fileDirectory = GetFileDirectoryOption(); - s_headerFile = GetHeaderOption(); - s_includedNames = GetIncludeOption(); - s_includeDirectories = GetIncludeDirectoryOption(); - s_language = GetLanguageOption(); - s_libraryPath = GetLibraryOption(); - s_methodClassName = GetMethodClassNameOption(); - s_namespaceName = GetNamespaceOption(); - s_outputMode = GetOutputModeOption(); - s_outputLocation = GetOutputOption(); - s_methodPrefixToStrip = GetPrefixStripOption(); - s_nativeTypeNamesToStrip = GetNativeTypeNamesStripOption(); - s_remappedNameValuePairs = GetRemapOption(); - s_std = GetStdOption(); - s_testOutputLocation = GetTestOutputOption(); - s_traversalNames = GetTraverseOption(); - s_versionOption = GetVersionOption(); - s_withAccessSpecifierNameValuePairs = GetWithAccessSpecifierOption(); - s_withAttributeNameValuePairs = GetWithAttributeOption(); - s_withCallConvNameValuePairs = GetWithCallConvOption(); - s_withClassNameValuePairs = GetWithClassOption(); - s_withGuidNameValuePairs = GetWithGuidOption(); - s_withLibraryPathNameValuePairs = GetWithLibraryPathOption(); - s_withManualImports = GetWithManualImportOption(); - s_withNamespaceNameValuePairs = GetWithNamespaceOption(); - s_withSetLastErrors = GetWithSetLastErrorOption(); - s_withSuppressGCTransitions = GetWithSuppressGCTransitionOption(); - s_withTransparentStructNameValuePairs = GetWithTransparentStructOption(); - s_withTypeNameValuePairs = GetWithTypeOption(); - s_withUsingNameValuePairs = GetWithUsingOption(); - s_withPackingNameValuePairs = GetWithPackingOption(); - - s_rootCommand = new RootCommand("ClangSharp P/Invoke Binding Generator") - { - s_additionalOption, - s_configOption, - s_defineMacros, - s_excludedNames, - s_files, - s_fileDirectory, - s_headerFile, - s_includedNames, - s_includeDirectories, - s_language, - s_libraryPath, - s_methodClassName, - s_namespaceName, - s_outputMode, - s_outputLocation, - s_methodPrefixToStrip, - s_nativeTypeNamesToStrip, - s_remappedNameValuePairs, - s_std, - s_testOutputLocation, - s_traversalNames, - s_versionOption, - s_withAccessSpecifierNameValuePairs, - s_withAttributeNameValuePairs, - s_withCallConvNameValuePairs, - s_withClassNameValuePairs, - s_withGuidNameValuePairs, - s_withLibraryPathNameValuePairs, - s_withManualImports, - s_withNamespaceNameValuePairs, - s_withSetLastErrors, - s_withSuppressGCTransitions, - s_withTransparentStructNameValuePairs, - s_withTypeNameValuePairs, - s_withUsingNameValuePairs, - s_withPackingNameValuePairs - }; - Handler.SetHandler(s_rootCommand, (Action)Run); - } + ]; + + private static readonly string[] s_additionalOptionAliases = ["--additional", "-a"]; + private static readonly string[] s_configOptionAliases = ["--config", "-c"]; + private static readonly string[] s_defineMacroOptionAliases = ["--define-macro", "-D"]; + private static readonly string[] s_excludeOptionAliases = ["--exclude", "-e"]; + private static readonly string[] s_fileOptionAliases = ["--file", "-f"]; + private static readonly string[] s_fileDirectionOptionAliases = ["--file-directory", "-F"]; + private static readonly string[] s_headerOptionAliases = ["--headerFile", "-h"]; + private static readonly string[] s_includeOptionAliases = ["--include", "-i"]; + private static readonly string[] s_includeDirectoryOptionAliases = ["--include-directory", "-I"]; + private static readonly string[] s_languageOptionAliases = ["--language", "-x"]; + private static readonly string[] s_libraryOptionAliases = ["--libraryPath", "-l"]; + private static readonly string[] s_methodClassNameOptionAliases = ["--methodClassName", "-m"]; + private static readonly string[] s_namespaceOptionAliases = ["--namespace", "-n"]; + private static readonly string[] s_nativeTypeNamesStripOptionAliases = ["--nativeTypeNamesToStrip"]; + private static readonly string[] s_outputModeOptionAliases = ["--output-mode", "-om"]; + private static readonly string[] s_outputOptionAliases = ["--output", "-o"]; + private static readonly string[] s_prefixStripOptionAliases = ["--prefixStrip", "-p"]; + private static readonly string[] s_remapOptionAliases = ["--remap", "-r"]; + private static readonly string[] s_stdOptionAliases = ["--std", "-std"]; + private static readonly string[] s_testOutputOptionAliases = ["--test-output", "-to"]; + private static readonly string[] s_versionOptionAliases = ["--version", "-v"]; + private static readonly string[] s_traverseOptionAliases = ["--traverse", "-t"]; + private static readonly string[] s_withAccessSpecifierOptionAliases = ["--with-access-specifier", "-was"]; + private static readonly string[] s_withAttributeOptionAliases = ["--with-attribute", "-wa"]; + private static readonly string[] s_withCallConvOptionAliases = ["--with-callconv", "-wcc"]; + private static readonly string[] s_withClassOptionAliases = ["--with-class", "-wc"]; + private static readonly string[] s_withGuidOptionAliases = ["--with-guid", "-wg"]; + private static readonly string[] s_withLibraryPathOptionAliases = ["--with-librarypath", "-wlb"]; + private static readonly string[] s_withManualImportOptionAliases = ["--with-manual-import", "-wmi"]; + private static readonly string[] s_withNamespaceOptionAliases = ["--with-namespace", "-wn"]; + private static readonly string[] s_withSetLastErrorOptionAliases = ["--with-setlasterror", "-wsle"]; + private static readonly string[] s_withSuppressGCTransitionOptionAliases = ["--with-suppressgctransition", "-wsgct"]; + private static readonly string[] s_withTransparentStructOptionAliases = ["--with-transparent-struct", "-wts"]; + private static readonly string[] s_withTypeOptionAliases = ["--with-type", "-wt"]; + private static readonly string[] s_withUsingOptionAliases = ["--with-using", "-wu"]; + private static readonly string[] s_withPackingOptionAliases = ["--with-packing", "-wp"]; public static IEnumerable GetExtendedHelp(HelpContext context) { @@ -275,46 +193,48 @@ public static async Task Main(params string[] args) .UseExceptionHandler() .CancelOnProcessTermination() .Build(); - return await parser.InvokeAsync(args); + return await parser.InvokeAsync(args).ConfigureAwait(false); } public static void Run(InvocationContext context) { - var additionalArgs = context.ParseResult.GetValueForOption(s_additionalOption) ?? Array.Empty(); - var configSwitches = context.ParseResult.GetValueForOption(s_configOption) ?? Array.Empty(); - var defineMacros = context.ParseResult.GetValueForOption(s_defineMacros) ?? Array.Empty(); - var excludedNames = context.ParseResult.GetValueForOption(s_excludedNames) ?? Array.Empty(); - var files = context.ParseResult.GetValueForOption(s_files) ?? Array.Empty(); + ArgumentNullException.ThrowIfNull(context); + + var additionalArgs = context.ParseResult.GetValueForOption(s_additionalOption) ?? []; + var configSwitches = context.ParseResult.GetValueForOption(s_configOption) ?? []; + var defineMacros = context.ParseResult.GetValueForOption(s_defineMacros) ?? []; + var excludedNames = context.ParseResult.GetValueForOption(s_excludedNames) ?? []; + var files = context.ParseResult.GetValueForOption(s_files) ?? []; var fileDirectory = context.ParseResult.GetValueForOption(s_fileDirectory) ?? ""; var headerFile = context.ParseResult.GetValueForOption(s_headerFile) ?? ""; - var includedNames = context.ParseResult.GetValueForOption(s_includedNames) ?? Array.Empty(); - var includeDirectories = context.ParseResult.GetValueForOption(s_includeDirectories) ?? Array.Empty(); + var includedNames = context.ParseResult.GetValueForOption(s_includedNames) ?? []; + var includeDirectories = context.ParseResult.GetValueForOption(s_includeDirectories) ?? []; var language = context.ParseResult.GetValueForOption(s_language) ?? ""; var libraryPath = context.ParseResult.GetValueForOption(s_libraryPath) ?? ""; var methodClassName = context.ParseResult.GetValueForOption(s_methodClassName) ?? ""; var methodPrefixToStrip = context.ParseResult.GetValueForOption(s_methodPrefixToStrip) ?? ""; - var nativeTypeNamesToStrip = context.ParseResult.GetValueForOption(s_nativeTypeNamesToStrip) ?? Array.Empty(); + var nativeTypeNamesToStrip = context.ParseResult.GetValueForOption(s_nativeTypeNamesToStrip) ?? []; var namespaceName = context.ParseResult.GetValueForOption(s_namespaceName) ?? ""; var outputLocation = context.ParseResult.GetValueForOption(s_outputLocation) ?? ""; var outputMode = context.ParseResult.GetValueForOption(s_outputMode); - var remappedNameValuePairs = context.ParseResult.GetValueForOption(s_remappedNameValuePairs) ?? Array.Empty(); + var remappedNameValuePairs = context.ParseResult.GetValueForOption(s_remappedNameValuePairs) ?? []; var std = context.ParseResult.GetValueForOption(s_std) ?? ""; var testOutputLocation = context.ParseResult.GetValueForOption(s_testOutputLocation) ?? ""; - var traversalNames = context.ParseResult.GetValueForOption(s_traversalNames) ?? Array.Empty(); - var withAccessSpecifierNameValuePairs = context.ParseResult.GetValueForOption(s_withAccessSpecifierNameValuePairs) ?? Array.Empty(); - var withAttributeNameValuePairs = context.ParseResult.GetValueForOption(s_withAttributeNameValuePairs) ?? Array.Empty(); - var withCallConvNameValuePairs = context.ParseResult.GetValueForOption(s_withCallConvNameValuePairs) ?? Array.Empty(); - var withClassNameValuePairs = context.ParseResult.GetValueForOption(s_withClassNameValuePairs) ?? Array.Empty(); - var withGuidNameValuePairs = context.ParseResult.GetValueForOption(s_withGuidNameValuePairs) ?? Array.Empty(); - var withLibraryPathNameValuePairs = context.ParseResult.GetValueForOption(s_withLibraryPathNameValuePairs) ?? Array.Empty(); - var withManualImports = context.ParseResult.GetValueForOption(s_withManualImports) ?? Array.Empty(); - var withNamespaceNameValuePairs = context.ParseResult.GetValueForOption(s_withNamespaceNameValuePairs) ?? Array.Empty(); - var withSetLastErrors = context.ParseResult.GetValueForOption(s_withSetLastErrors) ?? Array.Empty(); - var withSuppressGCTransitions = context.ParseResult.GetValueForOption(s_withSuppressGCTransitions) ?? Array.Empty(); - var withTransparentStructNameValuePairs = context.ParseResult.GetValueForOption(s_withTransparentStructNameValuePairs) ?? Array.Empty(); - var withTypeNameValuePairs = context.ParseResult.GetValueForOption(s_withTypeNameValuePairs) ?? Array.Empty(); - var withUsingNameValuePairs = context.ParseResult.GetValueForOption(s_withUsingNameValuePairs) ?? Array.Empty(); - var withPackingNameValuePairs = context.ParseResult.GetValueForOption(s_withPackingNameValuePairs) ?? Array.Empty(); + var traversalNames = context.ParseResult.GetValueForOption(s_traversalNames) ?? []; + var withAccessSpecifierNameValuePairs = context.ParseResult.GetValueForOption(s_withAccessSpecifierNameValuePairs) ?? []; + var withAttributeNameValuePairs = context.ParseResult.GetValueForOption(s_withAttributeNameValuePairs) ?? []; + var withCallConvNameValuePairs = context.ParseResult.GetValueForOption(s_withCallConvNameValuePairs) ?? []; + var withClassNameValuePairs = context.ParseResult.GetValueForOption(s_withClassNameValuePairs) ?? []; + var withGuidNameValuePairs = context.ParseResult.GetValueForOption(s_withGuidNameValuePairs) ?? []; + var withLibraryPathNameValuePairs = context.ParseResult.GetValueForOption(s_withLibraryPathNameValuePairs) ?? []; + var withManualImports = context.ParseResult.GetValueForOption(s_withManualImports) ?? []; + var withNamespaceNameValuePairs = context.ParseResult.GetValueForOption(s_withNamespaceNameValuePairs) ?? []; + var withSetLastErrors = context.ParseResult.GetValueForOption(s_withSetLastErrors) ?? []; + var withSuppressGCTransitions = context.ParseResult.GetValueForOption(s_withSuppressGCTransitions) ?? []; + var withTransparentStructNameValuePairs = context.ParseResult.GetValueForOption(s_withTransparentStructNameValuePairs) ?? []; + var withTypeNameValuePairs = context.ParseResult.GetValueForOption(s_withTypeNameValuePairs) ?? []; + var withUsingNameValuePairs = context.ParseResult.GetValueForOption(s_withUsingNameValuePairs) ?? []; + var withPackingNameValuePairs = context.ParseResult.GetValueForOption(s_withPackingNameValuePairs) ?? []; var versionResult = context.ParseResult.FindResultFor(s_versionOption); @@ -715,8 +635,10 @@ public static void Run(InvocationContext context) } context.Console.Error.Write(Environment.NewLine); - new CustomHelpBuilder(context.Console, context.LocalizationResources) - .Write(s_rootCommand, context.Console.Out.CreateTextWriter()); + using var textWriter = context.Console.Out.CreateTextWriter(); + var customHelpBuilder = new CustomHelpBuilder(context.Console, context.LocalizationResources); + customHelpBuilder.Write(s_rootCommand, textWriter); + context.ExitCode = -1; return; } @@ -725,15 +647,15 @@ public static void Run(InvocationContext context) ? new string[] { $"--language={language}", // Treat subsequent input files as having type "-Wno-pragma-once-outside-header" // We are processing files which may be header files - } : new string[] { + } : [ $"--language={language}", // Treat subsequent input files as having type $"--std={std}", // Language standard to compile for "-Wno-pragma-once-outside-header" // We are processing files which may be header files - }; + ]; - clangCommandLineArgs = clangCommandLineArgs.Concat(includeDirectories.Select(x => "--include-directory=" + x)).ToArray(); - clangCommandLineArgs = clangCommandLineArgs.Concat(defineMacros.Select(x => "--define-macro=" + x)).ToArray(); - clangCommandLineArgs = clangCommandLineArgs.Concat(additionalArgs).ToArray(); + clangCommandLineArgs = [.. clangCommandLineArgs, .. includeDirectories.Select(x => $"--include-directory={x}")]; + clangCommandLineArgs = [.. clangCommandLineArgs, .. defineMacros.Select(x => $"--define-macro={x}")]; + clangCommandLineArgs = [.. clangCommandLineArgs, .. additionalArgs]; var translationFlags = CXTranslationUnit_None; @@ -812,6 +734,8 @@ public static void Run(InvocationContext context) continue; } +#pragma warning disable CA1031 // Do not catch general exception types + try { using var translationUnit = TranslationUnit.GetOrCreate(handle); @@ -824,6 +748,8 @@ public static void Run(InvocationContext context) { context.Console.WriteLine(e.ToString()); } + +#pragma warning restore CA1031 // Do not catch general exception types } if (pinvokeGenerator.Diagnostics.Count != 0) @@ -862,7 +788,7 @@ public static void Run(InvocationContext context) private static void ParseKeyValuePairs(IEnumerable keyValuePairs, List errorList, out Dictionary result) { - result = new Dictionary(); + result = []; foreach (var keyValuePair in keyValuePairs) { @@ -888,7 +814,7 @@ private static void ParseKeyValuePairs(IEnumerable keyValuePairs, List keyValuePairs, List errorList, out Dictionary result) { - result = new Dictionary(); + result = []; foreach (var keyValuePair in keyValuePairs) { @@ -914,7 +840,7 @@ private static void ParseKeyValuePairs(IEnumerable keyValuePairs, List keyValuePairs, List errorList, out Dictionary result) { - result = new Dictionary(); + result = []; foreach (var keyValuePair in keyValuePairs) { @@ -946,7 +872,7 @@ private static void ParseKeyValuePairs(IEnumerable keyValuePairs, List keyValuePairs, List errorList, out Dictionary result) { - result = new Dictionary(); + result = []; foreach (var keyValuePair in keyValuePairs) { @@ -986,7 +912,7 @@ private static void ParseKeyValuePairs(IEnumerable keyValuePairs, List keyValuePairs, List errorList, out Dictionary> result) { - result = new Dictionary>(); + result = []; foreach (var keyValuePair in keyValuePairs) { @@ -1191,6 +1117,51 @@ private static Option GetRemapOption() }; } + private static RootCommand GetRootCommand() + { + var rootCommand = new RootCommand("ClangSharp P/Invoke Binding Generator") + { + s_additionalOption, + s_configOption, + s_defineMacros, + s_excludedNames, + s_files, + s_fileDirectory, + s_headerFile, + s_includedNames, + s_includeDirectories, + s_language, + s_libraryPath, + s_methodClassName, + s_namespaceName, + s_outputMode, + s_outputLocation, + s_methodPrefixToStrip, + s_nativeTypeNamesToStrip, + s_remappedNameValuePairs, + s_std, + s_testOutputLocation, + s_traversalNames, + s_versionOption, + s_withAccessSpecifierNameValuePairs, + s_withAttributeNameValuePairs, + s_withCallConvNameValuePairs, + s_withClassNameValuePairs, + s_withGuidNameValuePairs, + s_withLibraryPathNameValuePairs, + s_withManualImports, + s_withNamespaceNameValuePairs, + s_withSetLastErrors, + s_withSuppressGCTransitions, + s_withTransparentStructNameValuePairs, + s_withTypeNameValuePairs, + s_withUsingNameValuePairs, + s_withPackingNameValuePairs + }; + Handler.SetHandler(rootCommand, (Action)Run); + return rootCommand; + } + private static Option GetStdOption() { return new Option( diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs index 9b4a4dfc..a553add5 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/CXXMethodDeclarationTest.cs @@ -70,9 +70,9 @@ public virtual Task MacrosExpansionTest() int size; } context_t; -int buf_close(void *pcontext) +int buf_close(void *pContext) { - ((context_t*)pcontext)->buf=0; + ((context_t*)pContext)->buf=0; return 0; } "; @@ -89,9 +89,9 @@ public unsafe partial struct context_t public static unsafe partial class Methods { - public static int buf_close(void* pcontext) + public static int buf_close(void* pContext) { - ((context_t*)(pcontext))->buf = null; + ((context_t*)(pContext))->buf = null; return 0; } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/EnumDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/EnumDeclarationTest.cs index 498e3e22..1048a150 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/EnumDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/EnumDeclarationTest.cs @@ -7,7 +7,7 @@ namespace ClangSharp.UnitTests; public abstract class EnumDeclarationTest : PInvokeGeneratorTest { - protected static readonly string[] ExcludeTestExcludedNames = new[] { "MyEnum" }; + protected static readonly string[] ExcludeTestExcludedNames = ["MyEnum"]; [Test] public Task BasicTest() => BasicTestImpl(); diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionDeclarationDllImportTest.cs index 8f78cf03..dede50f2 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionDeclarationDllImportTest.cs @@ -7,7 +7,7 @@ namespace ClangSharp.UnitTests; public abstract class FunctionDeclarationDllImportTest : PInvokeGeneratorTest { - protected static readonly string[] TemplateTestExcludedNames = new[] { "MyTemplate" }; + protected static readonly string[] TemplateTestExcludedNames = ["MyTemplate"]; [Test] public Task BasicTest() => BasicTestImpl(); diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/StructDeclarationTest.cs index 7cbce4d0..1433a5c7 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/StructDeclarationTest.cs @@ -7,8 +7,8 @@ namespace ClangSharp.UnitTests; public abstract class StructDeclarationTest : PInvokeGeneratorTest { - protected static readonly string[] ExcludeTestExcludedNames = new[] { "MyStruct" }; - protected static readonly string[] GuidTestExcludedNames = new[] { "DECLSPEC_UUID" }; + protected static readonly string[] ExcludeTestExcludedNames = ["MyStruct"]; + protected static readonly string[] GuidTestExcludedNames = ["DECLSPEC_UUID"]; [TestCase("double", "double")] [TestCase("short", "short")] diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/UnionDeclarationTest.cs index 11d52129..cd36e8ab 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/UnionDeclarationTest.cs @@ -7,8 +7,8 @@ namespace ClangSharp.UnitTests; public abstract class UnionDeclarationTest : PInvokeGeneratorTest { - protected static readonly string[] ExcludeTestExcludedNames = new[] { "MyUnion" }; - protected static readonly string[] GuidTestExcludedNames = new[] { "DECLSPEC_UUID" }; + protected static readonly string[] ExcludeTestExcludedNames = ["MyUnion"]; + protected static readonly string[] GuidTestExcludedNames = ["DECLSPEC_UUID"]; [TestCase("double", "double")] [TestCase("short", "short")] diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/VarDeclarationTest.cs index 709a29fa..13137540 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/VarDeclarationTest.cs @@ -7,8 +7,8 @@ namespace ClangSharp.UnitTests; public abstract class VarDeclarationTest : PInvokeGeneratorTest { - protected static readonly string[] GuidMacroTestExcludedNames = new[] { "GUID" }; - protected static readonly string[] UncheckedConversionMacroTest2ExcludedNames = new string[] { "MyMacro1", "MyMacro2" }; + protected static readonly string[] GuidMacroTestExcludedNames = ["GUID"]; + protected static readonly string[] UncheckedConversionMacroTest2ExcludedNames = ["MyMacro1", "MyMacro2"]; [TestCase("double", "double")] [TestCase("short", "short")] diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/StructDeclarationTest.cs index c5a6e734..6d5f47a7 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -79,7 +78,7 @@ public partial struct MyStruct }} }} "; - return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/UnionDeclarationTest.cs index 478a9067..6f31ed6c 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/UnionDeclarationTest.cs @@ -69,7 +69,7 @@ public partial struct MyUnion }} }} "; - return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/StructDeclarationTest.cs index 3891d46d..a3f6b0d9 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -79,7 +78,7 @@ public partial struct MyStruct }} }} "; - return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/UnionDeclarationTest.cs index dc5185e5..bf49d6be 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/UnionDeclarationTest.cs @@ -69,7 +69,7 @@ public partial struct MyUnion }} }} "; - return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/StructDeclarationTest.cs index 10b38a2b..380b1a4c 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -79,7 +78,7 @@ public partial struct MyStruct }} }} "; - return ValidateGeneratedCSharpDefaultUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpDefaultUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/UnionDeclarationTest.cs index 50017715..eeb3b452 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultUnix/UnionDeclarationTest.cs @@ -69,7 +69,7 @@ public partial struct MyUnion }} }} "; - return ValidateGeneratedCSharpDefaultUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpDefaultUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/StructDeclarationTest.cs index eab5616f..b9ddfd41 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -79,7 +78,7 @@ public partial struct MyStruct }} }} "; - return ValidateGeneratedCSharpDefaultWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpDefaultWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/UnionDeclarationTest.cs index 99c3875e..fca75b1e 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpDefaultWindows/UnionDeclarationTest.cs @@ -69,7 +69,7 @@ public partial struct MyUnion }} }} "; - return ValidateGeneratedCSharpDefaultWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpDefaultWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/StructDeclarationTest.cs index fcd6d39c..96eea6bb 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -79,7 +78,7 @@ public partial struct MyStruct }} }} "; - return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/UnionDeclarationTest.cs index 2aedcee4..5ffdabb6 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/UnionDeclarationTest.cs @@ -69,7 +69,7 @@ public partial struct MyUnion }} }} "; - return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/StructDeclarationTest.cs index 307d53a9..f971e7c1 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -79,7 +78,7 @@ public partial struct MyStruct }} }} "; - return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/UnionDeclarationTest.cs index c2bfa898..b90bb054 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/UnionDeclarationTest.cs @@ -69,7 +69,7 @@ public partial struct MyUnion }} }} "; - return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/StructDeclarationTest.cs index 4b7a07e8..c8ca84a3 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -79,7 +78,7 @@ public partial struct MyStruct }} }} "; - return ValidateGeneratedCSharpPreviewUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpPreviewUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/UnionDeclarationTest.cs index 3ddf2903..6015518e 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/UnionDeclarationTest.cs @@ -69,7 +69,7 @@ public partial struct MyUnion }} }} "; - return ValidateGeneratedCSharpPreviewUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpPreviewUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/StructDeclarationTest.cs index be3988ae..69763c80 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -79,7 +78,7 @@ public partial struct MyStruct }} }} "; - return ValidateGeneratedCSharpPreviewWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpPreviewWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/UnionDeclarationTest.cs index a3001b64..bfaa48b2 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewWindows/UnionDeclarationTest.cs @@ -69,7 +69,7 @@ public partial struct MyUnion }} }} "; - return ValidateGeneratedCSharpPreviewWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedCSharpPreviewWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CTest.cs index c16f20ce..9f08dc19 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CTest.cs @@ -63,7 +63,7 @@ public partial struct MyStruct "; } - return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: DefaultCClangCommandLineArgs, language: "c", languageStandard: DefaultCStandard); + return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: DefaultCClangCommandLineArgs, language: "c", languageStandard: DefaultCStandard); } [Test] @@ -141,7 +141,7 @@ public unsafe partial struct _union1_e__Union } } "; - return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: DefaultCClangCommandLineArgs, language: "c", languageStandard: DefaultCStandard); + return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: DefaultCClangCommandLineArgs, language: "c", languageStandard: DefaultCStandard); } [Test] @@ -182,7 +182,7 @@ public unsafe partial struct _MyOtherUnion } } "; - return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: DefaultCClangCommandLineArgs, language: "c", languageStandard: DefaultCStandard); + return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: DefaultCClangCommandLineArgs, language: "c", languageStandard: DefaultCStandard); } [Test] @@ -204,6 +204,6 @@ public static partial class Methods } "; - return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: DefaultCClangCommandLineArgs, language: "c", languageStandard: DefaultCStandard); + return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: DefaultCClangCommandLineArgs, language: "c", languageStandard: DefaultCStandard); } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/ClangSharp.PInvokeGenerator.UnitTests.csproj b/tests/ClangSharp.PInvokeGenerator.UnitTests/ClangSharp.PInvokeGenerator.UnitTests.csproj index cf071218..68071b2f 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/ClangSharp.PInvokeGenerator.UnitTests.csproj +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/ClangSharp.PInvokeGenerator.UnitTests.csproj @@ -2,6 +2,9 @@ + + + $(NoWarn);CA1707;CA1711 ClangSharp.UnitTests net8.0 diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/PInvokeGeneratorTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/PInvokeGeneratorTest.cs index c73299d4..53637790 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/PInvokeGeneratorTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/PInvokeGeneratorTest.cs @@ -3,10 +3,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Runtime.CompilerServices; using System.Threading.Tasks; using System.Xml.Linq; -using ClangSharp.Abstractions; using ClangSharp.Interop; using NUnit.Framework; using static ClangSharp.Interop.CXTranslationUnit_Flags; @@ -25,74 +23,74 @@ public abstract class PInvokeGeneratorTest protected const string DefaultCStandard = "c17"; protected const string DefaultCppStandard = "c++17"; - protected static readonly string[] DefaultCClangCommandLineArgs = new string[] - { + protected static readonly string[] DefaultCClangCommandLineArgs = + [ $"-std={DefaultCStandard}", // The input files should be compiled for C 17 "-xc", // The input files are C - }; + ]; - protected static readonly string[] DefaultCppClangCommandLineArgs = new string[] - { + protected static readonly string[] DefaultCppClangCommandLineArgs = + [ $"-std={DefaultCppStandard}", // The input files should be compiled for C++ 17 "-xc++", // The input files are C++ "-Wno-pragma-once-outside-header", // We are processing files which may be header files "-Wno-c++11-narrowing" - }; + ]; protected static string EscapeXml(string value) => new XText(value).ToString(); - protected static Task ValidateGeneratedCSharpPreviewWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GeneratePreviewCode | PInvokeGeneratorConfigurationOptions.None | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard); + protected static Task ValidateGeneratedCSharpPreviewWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GeneratePreviewCode | PInvokeGeneratorConfigurationOptions.None | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedCSharpPreviewUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GeneratePreviewCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard); + protected static Task ValidateGeneratedCSharpPreviewUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GeneratePreviewCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedCSharpLatestWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateLatestCode | PInvokeGeneratorConfigurationOptions.None | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard); + protected static Task ValidateGeneratedCSharpLatestWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateLatestCode | PInvokeGeneratorConfigurationOptions.None | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedCSharpLatestUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateLatestCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard); + protected static Task ValidateGeneratedCSharpLatestUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateLatestCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedCSharpDefaultWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.None | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard); + protected static Task ValidateGeneratedCSharpDefaultWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.None | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedCSharpDefaultUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard); + protected static Task ValidateGeneratedCSharpDefaultUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard); + protected static Task ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedCSharpCompatibleUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard); + protected static Task ValidateGeneratedCSharpCompatibleUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedXmlPreviewWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard, [CallerFilePath] string filePath = "") - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GeneratePreviewCode | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard, filePath); + protected static Task ValidateGeneratedXmlPreviewWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GeneratePreviewCode | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedXmlPreviewUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GeneratePreviewCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard); + protected static Task ValidateGeneratedXmlPreviewUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GeneratePreviewCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedXmlLatestWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard, [CallerFilePath] string filePath = "") - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateLatestCode | PInvokeGeneratorConfigurationOptions.None | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard, filePath); + protected static Task ValidateGeneratedXmlLatestWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateLatestCode | PInvokeGeneratorConfigurationOptions.None | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedXmlLatestUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateLatestCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard); + protected static Task ValidateGeneratedXmlLatestUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateLatestCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedXmlDefaultWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard, [CallerFilePath] string filePath = "") - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.None | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard, filePath); + protected static Task ValidateGeneratedXmlDefaultWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.None | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedXmlDefaultUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard); + protected static Task ValidateGeneratedXmlDefaultUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedXmlCompatibleWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard); + protected static Task ValidateGeneratedXmlCompatibleWindowsBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - protected static Task ValidateGeneratedXmlCompatibleUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandlineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) - => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandlineArgs, language, languageStandard); + protected static Task ValidateGeneratedXmlCompatibleUnixBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions additionalConfigOptions = PInvokeGeneratorConfigurationOptions.None, string[]? excludedNames = null, IReadOnlyDictionary? remappedNames = null, IReadOnlyDictionary? withAccessSpecifiers = null, IReadOnlyDictionary>? withAttributes = null, IReadOnlyDictionary? withCallConvs = null, IReadOnlyDictionary? withClasses = null, IReadOnlyDictionary? withLibraryPaths = null, IReadOnlyDictionary? withNamespaces = null, string[]? withSetLastErrors = null, IReadOnlyDictionary? withTransparentStructs = null, IReadOnlyDictionary? withTypes = null, IReadOnlyDictionary>? withUsings = null, IReadOnlyDictionary? withPackings = null, IEnumerable? expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[]? commandLineArgs = null, string language = "c++", string languageStandard = DefaultCppStandard) + => ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes | additionalConfigOptions, excludedNames, remappedNames, withAccessSpecifiers, withAttributes, withCallConvs, withClasses, withLibraryPaths, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings, withPackings, expectedDiagnostics, libraryPath, commandLineArgs, language, languageStandard); - private static async Task ValidateGeneratedBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorOutputMode outputMode, PInvokeGeneratorConfigurationOptions configOptions, string[]? excludedNames, IReadOnlyDictionary? remappedNames, IReadOnlyDictionary? withAccessSpecifiers, IReadOnlyDictionary>? withAttributes, IReadOnlyDictionary? withCallConvs, IReadOnlyDictionary? withClasses, IReadOnlyDictionary? withLibraryPaths, IReadOnlyDictionary? withNamespaces, string[]? withSetLastErrors, IReadOnlyDictionary? withTransparentStructs, IReadOnlyDictionary? withTypes, IReadOnlyDictionary>? withUsings, IReadOnlyDictionary? withPackings, IEnumerable? expectedDiagnostics, string libraryPath, string[]? commandlineArgs, string language, string languageStandard, [CallerFilePath] string filePath = "") + private static async Task ValidateGeneratedBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorOutputMode outputMode, PInvokeGeneratorConfigurationOptions configOptions, string[]? excludedNames, IReadOnlyDictionary? remappedNames, IReadOnlyDictionary? withAccessSpecifiers, IReadOnlyDictionary>? withAttributes, IReadOnlyDictionary? withCallConvs, IReadOnlyDictionary? withClasses, IReadOnlyDictionary? withLibraryPaths, IReadOnlyDictionary? withNamespaces, string[]? withSetLastErrors, IReadOnlyDictionary? withTransparentStructs, IReadOnlyDictionary? withTypes, IReadOnlyDictionary>? withUsings, IReadOnlyDictionary? withPackings, IEnumerable? expectedDiagnostics, string libraryPath, string[]? commandLineArgs, string language, string languageStandard) { Assert.True(File.Exists(DefaultInputFileName)); - commandlineArgs ??= DefaultCppClangCommandLineArgs; + commandLineArgs ??= DefaultCppClangCommandLineArgs; configOptions |= PInvokeGeneratorConfigurationOptions.GenerateMacroBindings; @@ -126,12 +124,12 @@ private static async Task ValidateGeneratedBindingsAsync(string inputContents, s using (var pinvokeGenerator = new PInvokeGenerator(config, (path) => outputStream)) { - var handle = CXTranslationUnit.Parse(pinvokeGenerator.IndexHandle, DefaultInputFileName, commandlineArgs, unsavedFiles, DefaultTranslationUnitFlags); + var handle = CXTranslationUnit.Parse(pinvokeGenerator.IndexHandle, DefaultInputFileName, commandLineArgs, unsavedFiles, DefaultTranslationUnitFlags); using var translationUnit = TranslationUnit.GetOrCreate(handle); Debug.Assert(translationUnit is not null); - pinvokeGenerator.GenerateBindings(translationUnit, DefaultInputFileName, commandlineArgs, DefaultTranslationUnitFlags); + pinvokeGenerator.GenerateBindings(translationUnit, DefaultInputFileName, commandLineArgs, DefaultTranslationUnitFlags); if (expectedDiagnostics is null) { @@ -144,7 +142,8 @@ private static async Task ValidateGeneratedBindingsAsync(string inputContents, s } outputStream.Position = 0; - var actualOutputContents = await new StreamReader(outputStream).ReadToEndAsync(); + using var streamReader = new StreamReader(outputStream); + var actualOutputContents = await streamReader.ReadToEndAsync().ConfigureAwait(false); Assert.AreEqual(expectedOutputContents, actualOutputContents); } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/StructDeclarationTest.cs index d5c1bcd1..1eeaf41a 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -91,7 +90,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs index 0a11fe20..fe430d13 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs @@ -67,7 +67,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/StructDeclarationTest.cs index 526e98c4..9cfa644e 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -91,7 +90,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs index 68c72e66..a3af56a2 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs @@ -67,7 +67,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/StructDeclarationTest.cs index 478542a4..369c7914 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -91,7 +90,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlDefaultUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlDefaultUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/UnionDeclarationTest.cs index 1faf5552..cc480472 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultUnix/UnionDeclarationTest.cs @@ -67,7 +67,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlDefaultUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlDefaultUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/StructDeclarationTest.cs index 954296a1..b9bcee3a 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -91,7 +90,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlDefaultWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlDefaultWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/UnionDeclarationTest.cs index 8674d5e4..31c6d3f8 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlDefaultWindows/UnionDeclarationTest.cs @@ -67,7 +67,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlDefaultWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlDefaultWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/StructDeclarationTest.cs index 2fb18be5..5190c342 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -91,7 +90,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs index 8305b9ee..cb74e887 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs @@ -67,7 +67,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/StructDeclarationTest.cs index d889d67e..ce9855df 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -91,7 +90,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs index 9e2c68f1..27dbb2d1 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs @@ -67,7 +67,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/StructDeclarationTest.cs index c48aeb49..5f5ca818 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -91,7 +90,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlPreviewUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlPreviewUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/UnionDeclarationTest.cs index c066b551..3237e297 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/UnionDeclarationTest.cs @@ -67,7 +67,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlPreviewUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlPreviewUnixBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/StructDeclarationTest.cs index c53019fe..c3fe8b96 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/StructDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/StructDeclarationTest.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading.Tasks; -using ClangSharp.Abstractions; namespace ClangSharp.UnitTests; @@ -91,7 +90,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlPreviewWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlPreviewWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/UnionDeclarationTest.cs index 1f6bc318..a522a1e6 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewWindows/UnionDeclarationTest.cs @@ -67,7 +67,7 @@ protected override Task BasicTestInCModeImpl(string nativeType, string expectedM "; - return ValidateGeneratedXmlPreviewWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + return ValidateGeneratedXmlPreviewWindowsBindingsAsync(inputContents, expectedOutputContents, commandLineArgs: []); } protected override Task BasicWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType) diff --git a/tests/ClangSharp.UnitTests/CXVirtualFileOverlayTest.cs b/tests/ClangSharp.UnitTests/CXVirtualFileOverlayTest.cs index 0482ec7b..1e2b3132 100644 --- a/tests/ClangSharp.UnitTests/CXVirtualFileOverlayTest.cs +++ b/tests/ClangSharp.UnitTests/CXVirtualFileOverlayTest.cs @@ -15,18 +15,12 @@ namespace ClangSharp.UnitTests; // on Windows, but clang doesn't seem to support this) public class CXVirtualFileOverlayTest { - public class TestVFO : IDisposable + internal sealed class TestVFO(string? contents) : IDisposable { - public CXVirtualFileOverlay VFO; + public CXVirtualFileOverlay VFO = CXVirtualFileOverlay.Create(options: 0); - private readonly string? _contents; - private bool _isDisposed = false; - - public TestVFO(string? contents) - { - VFO = CXVirtualFileOverlay.Create(options: 0); - _contents = Fix(contents); - } + private readonly string? _contents = Fix(contents); + private bool _isDisposed; ~TestVFO() { @@ -59,7 +53,7 @@ public void MapError(string? vPath, string? rPath, CXErrorCode expErr) } var replacement = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "C:" : ""; - return text.Replace("$ROOT$", replacement); + return text.Replace("$ROOT$", replacement, StringComparison.Ordinal); } public void Dispose() @@ -68,7 +62,7 @@ public void Dispose() GC.SuppressFinalize(this); } - protected virtual void Dispose(bool isDisposing) + private void Dispose(bool isDisposing) { if (_isDisposed) { @@ -251,7 +245,7 @@ public void SharedPrefix() + " },\n" + " {\n" + " 'type': 'directory',\n" - + " 'name': \"$ROOT$/path/foobar\",\n" + + " 'name': \"$ROOT$/path/fooBar\",\n" + " 'contents': [\n" + " {\n" + " 'type': 'file',\n" @@ -266,8 +260,8 @@ public void SharedPrefix() + " 'contents': [\n" + " {\n" + " 'type': 'file',\n" - + " 'name': \"foobarbaz.h\",\n" - + " 'external-contents': \"$ROOT$/real/foobarbaz.h\"\n" + + " 'name': \"fooBarBaz.h\",\n" + + " 'external-contents': \"$ROOT$/real/fooBarBaz.h\"\n" + " }\n" + " ]\n" + " }\n" @@ -277,8 +271,8 @@ public void SharedPrefix() using var t = new TestVFO(contents); t.Map("$ROOT$/path/foo/bar.h", "$ROOT$/real/bar.h"); t.Map("$ROOT$/path/foo/bar", "$ROOT$/real/bar"); - t.Map("$ROOT$/path/foobar/baz.h", "$ROOT$/real/baz.h"); - t.Map("$ROOT$/path/foobarbaz.h", "$ROOT$/real/foobarbaz.h"); + t.Map("$ROOT$/path/fooBar/baz.h", "$ROOT$/real/baz.h"); + t.Map("$ROOT$/path/fooBarBaz.h", "$ROOT$/real/fooBarBaz.h"); } [Test] diff --git a/tests/ClangSharp.UnitTests/ClangSharp.UnitTests.csproj b/tests/ClangSharp.UnitTests/ClangSharp.UnitTests.csproj index 809e4542..c7b8b05c 100644 --- a/tests/ClangSharp.UnitTests/ClangSharp.UnitTests.csproj +++ b/tests/ClangSharp.UnitTests/ClangSharp.UnitTests.csproj @@ -2,6 +2,8 @@ + + $(NoWarn);CA1707 net8.0 diff --git a/tests/ClangSharp.UnitTests/CursorTests/DeclTest.cs b/tests/ClangSharp.UnitTests/CursorTests/DeclTest.cs index 72bbd7a7..96317468 100644 --- a/tests/ClangSharp.UnitTests/CursorTests/DeclTest.cs +++ b/tests/ClangSharp.UnitTests/CursorTests/DeclTest.cs @@ -1,5 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. +using System; using System.Linq; using ClangSharp.Interop; using NUnit.Framework; @@ -22,7 +23,7 @@ public void AccessSpecDeclTest(string accessSpecifier, CX_CXXAccessSpecifier exp using var translationUnit = CreateTranslationUnit(inputContents); - var recordDecl = translationUnit.TranslationUnitDecl.Decls.OfType().Where((recordDecl) => recordDecl.Name == "MyStruct").Single(); + var recordDecl = translationUnit.TranslationUnitDecl.Decls.OfType().Where((recordDecl) => recordDecl.Name.Equals("MyStruct", StringComparison.Ordinal)).Single(); var accessSpecDecl = recordDecl.Decls.OfType().Single(); Assert.AreEqual(expectedAccessSpecifier, accessSpecDecl.Access); diff --git a/tests/ClangSharp.UnitTests/TranslationUnitTest.cs b/tests/ClangSharp.UnitTests/TranslationUnitTest.cs index 56f9a66d..68b22ce6 100644 --- a/tests/ClangSharp.UnitTests/TranslationUnitTest.cs +++ b/tests/ClangSharp.UnitTests/TranslationUnitTest.cs @@ -17,12 +17,12 @@ public abstract class TranslationUnitTest protected const CXTranslationUnit_Flags DefaultTranslationUnitFlags = CXTranslationUnit_IncludeAttributedTypes // Include attributed types in CXType | CXTranslationUnit_VisitImplicitAttributes; // Implicit attributes should be visited - protected static readonly string[] DefaultClangCommandLineArgs = new string[] - { + protected static readonly string[] DefaultClangCommandLineArgs = + [ "-std=c++17", // The input files should be compiled for C++ 17 "-xc++", // The input files are C++ "-Wno-pragma-once-outside-header" // We are processing files which may be header files - }; + ]; protected static TranslationUnit CreateTranslationUnit(string inputContents) { From c03292c9e6f03685ea61fb55db810e331b62b134 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 15 Oct 2023 11:01:15 -0700 Subject: [PATCH 4/9] Fixing some minor handling around bitfields and the like --- .../PInvokeGenerator.VisitDecl.cs | 4 +- .../PInvokeGenerator.VisitStmt.cs | 13 +++- .../PInvokeGenerator.cs | 7 +- sources/ClangSharpPInvokeGenerator/Program.cs | 74 +++++++++---------- .../Properties/launchSettings.json | 5 ++ 5 files changed, 62 insertions(+), 41 deletions(-) diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs index e579c456..c1ae83c2 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs @@ -1382,7 +1382,7 @@ private void VisitRecordDecl(RecordDecl recordDecl) _uuidsToGenerate.Add(uuidName, uuid); - if (_testOutputBuilder is not null) + if ((_testOutputBuilder is not null) && (uuid != Guid.Empty)) { var className = GetClass(uuidName); @@ -2686,7 +2686,7 @@ void VisitBitfieldDecl(FieldDecl fieldDecl, BitfieldDesc[] bitfieldDescs, Record code.Write(")("); } - if ((!needsParenFirst && (bitfieldOffset != 0)) || (!needsCast && isTypeSigned)) + if ((!needsParenFirst && (bitfieldOffset != 0)) || (!isUnsignedToSigned && isTypeSigned)) { code.Write('('); } diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs index efcec766..6a47be3f 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs @@ -2746,9 +2746,20 @@ private void VisitUnaryOperator(UnaryOperator unaryOperator) break; } + case CX_UO_Deref: + { + if (_topLevelClassNames.Contains(outputBuilder.Name)) + { + _topLevelClassIsUnsafe[outputBuilder.Name] = true; + } + + outputBuilder.Write(unaryOperator.OpcodeStr); + Visit(unaryOperator.SubExpr); + break; + } + case CX_UO_PreInc: case CX_UO_PreDec: - case CX_UO_Deref: case CX_UO_Plus: case CX_UO_Minus: case CX_UO_Not: diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs index 144244f4..cd470b6e 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs @@ -2426,7 +2426,7 @@ private CallConv GetCallingConvention(Cursor? cursor, Cursor? context, Type type if (_config.GenerateCallConvMemberFunction) { - if ((cursor is CXXMethodDecl cxxMethodDecl) && cxxMethodDecl.IsInstance) + if ((cursor is CXXMethodDecl cxxMethodDecl) && cxxMethodDecl.IsInstance && (context is not null)) { return CallConv.MemberFunction; } @@ -4610,6 +4610,11 @@ bool IsExcludedByName(Cursor cursor, ref uint isExcludedValue) isExcludedValue |= 0b10; } } + + if (_config.GenerateDisableRuntimeMarshalling && functionDecl.IsVariadic) + { + isExcludedByConfigOption = true; + } } var dottedQualifiedName = qualifiedName.Replace("::", ".", StringComparison.Ordinal); diff --git a/sources/ClangSharpPInvokeGenerator/Program.cs b/sources/ClangSharpPInvokeGenerator/Program.cs index b97fb533..8bb0cae5 100644 --- a/sources/ClangSharpPInvokeGenerator/Program.cs +++ b/sources/ClangSharpPInvokeGenerator/Program.cs @@ -22,6 +22,43 @@ namespace ClangSharp; public static class Program { + private static readonly string[] s_additionalOptionAliases = ["--additional", "-a"]; + private static readonly string[] s_configOptionAliases = ["--config", "-c"]; + private static readonly string[] s_defineMacroOptionAliases = ["--define-macro", "-D"]; + private static readonly string[] s_excludeOptionAliases = ["--exclude", "-e"]; + private static readonly string[] s_fileOptionAliases = ["--file", "-f"]; + private static readonly string[] s_fileDirectionOptionAliases = ["--file-directory", "-F"]; + private static readonly string[] s_headerOptionAliases = ["--headerFile", "-h"]; + private static readonly string[] s_includeOptionAliases = ["--include", "-i"]; + private static readonly string[] s_includeDirectoryOptionAliases = ["--include-directory", "-I"]; + private static readonly string[] s_languageOptionAliases = ["--language", "-x"]; + private static readonly string[] s_libraryOptionAliases = ["--libraryPath", "-l"]; + private static readonly string[] s_methodClassNameOptionAliases = ["--methodClassName", "-m"]; + private static readonly string[] s_namespaceOptionAliases = ["--namespace", "-n"]; + private static readonly string[] s_nativeTypeNamesStripOptionAliases = ["--nativeTypeNamesToStrip"]; + private static readonly string[] s_outputModeOptionAliases = ["--output-mode", "-om"]; + private static readonly string[] s_outputOptionAliases = ["--output", "-o"]; + private static readonly string[] s_prefixStripOptionAliases = ["--prefixStrip", "-p"]; + private static readonly string[] s_remapOptionAliases = ["--remap", "-r"]; + private static readonly string[] s_stdOptionAliases = ["--std", "-std"]; + private static readonly string[] s_testOutputOptionAliases = ["--test-output", "-to"]; + private static readonly string[] s_versionOptionAliases = ["--version", "-v"]; + private static readonly string[] s_traverseOptionAliases = ["--traverse", "-t"]; + private static readonly string[] s_withAccessSpecifierOptionAliases = ["--with-access-specifier", "-was"]; + private static readonly string[] s_withAttributeOptionAliases = ["--with-attribute", "-wa"]; + private static readonly string[] s_withCallConvOptionAliases = ["--with-callconv", "-wcc"]; + private static readonly string[] s_withClassOptionAliases = ["--with-class", "-wc"]; + private static readonly string[] s_withGuidOptionAliases = ["--with-guid", "-wg"]; + private static readonly string[] s_withLibraryPathOptionAliases = ["--with-librarypath", "-wlb"]; + private static readonly string[] s_withManualImportOptionAliases = ["--with-manual-import", "-wmi"]; + private static readonly string[] s_withNamespaceOptionAliases = ["--with-namespace", "-wn"]; + private static readonly string[] s_withSetLastErrorOptionAliases = ["--with-setlasterror", "-wsle"]; + private static readonly string[] s_withSuppressGCTransitionOptionAliases = ["--with-suppressgctransition", "-wsgct"]; + private static readonly string[] s_withTransparentStructOptionAliases = ["--with-transparent-struct", "-wts"]; + private static readonly string[] s_withTypeOptionAliases = ["--with-type", "-wt"]; + private static readonly string[] s_withUsingOptionAliases = ["--with-using", "-wu"]; + private static readonly string[] s_withPackingOptionAliases = ["--with-packing", "-wp"]; + private static readonly Option s_additionalOption = GetAdditionalOption(); private static readonly Option s_configOption = GetConfigOption(); private static readonly Option s_defineMacros = GetDefineMacroOption(); @@ -130,43 +167,6 @@ public static class Program new TwoColumnHelpRow("log-visited-files", "A list of the visited files should be generated. This can help identify traversal issues."), ]; - private static readonly string[] s_additionalOptionAliases = ["--additional", "-a"]; - private static readonly string[] s_configOptionAliases = ["--config", "-c"]; - private static readonly string[] s_defineMacroOptionAliases = ["--define-macro", "-D"]; - private static readonly string[] s_excludeOptionAliases = ["--exclude", "-e"]; - private static readonly string[] s_fileOptionAliases = ["--file", "-f"]; - private static readonly string[] s_fileDirectionOptionAliases = ["--file-directory", "-F"]; - private static readonly string[] s_headerOptionAliases = ["--headerFile", "-h"]; - private static readonly string[] s_includeOptionAliases = ["--include", "-i"]; - private static readonly string[] s_includeDirectoryOptionAliases = ["--include-directory", "-I"]; - private static readonly string[] s_languageOptionAliases = ["--language", "-x"]; - private static readonly string[] s_libraryOptionAliases = ["--libraryPath", "-l"]; - private static readonly string[] s_methodClassNameOptionAliases = ["--methodClassName", "-m"]; - private static readonly string[] s_namespaceOptionAliases = ["--namespace", "-n"]; - private static readonly string[] s_nativeTypeNamesStripOptionAliases = ["--nativeTypeNamesToStrip"]; - private static readonly string[] s_outputModeOptionAliases = ["--output-mode", "-om"]; - private static readonly string[] s_outputOptionAliases = ["--output", "-o"]; - private static readonly string[] s_prefixStripOptionAliases = ["--prefixStrip", "-p"]; - private static readonly string[] s_remapOptionAliases = ["--remap", "-r"]; - private static readonly string[] s_stdOptionAliases = ["--std", "-std"]; - private static readonly string[] s_testOutputOptionAliases = ["--test-output", "-to"]; - private static readonly string[] s_versionOptionAliases = ["--version", "-v"]; - private static readonly string[] s_traverseOptionAliases = ["--traverse", "-t"]; - private static readonly string[] s_withAccessSpecifierOptionAliases = ["--with-access-specifier", "-was"]; - private static readonly string[] s_withAttributeOptionAliases = ["--with-attribute", "-wa"]; - private static readonly string[] s_withCallConvOptionAliases = ["--with-callconv", "-wcc"]; - private static readonly string[] s_withClassOptionAliases = ["--with-class", "-wc"]; - private static readonly string[] s_withGuidOptionAliases = ["--with-guid", "-wg"]; - private static readonly string[] s_withLibraryPathOptionAliases = ["--with-librarypath", "-wlb"]; - private static readonly string[] s_withManualImportOptionAliases = ["--with-manual-import", "-wmi"]; - private static readonly string[] s_withNamespaceOptionAliases = ["--with-namespace", "-wn"]; - private static readonly string[] s_withSetLastErrorOptionAliases = ["--with-setlasterror", "-wsle"]; - private static readonly string[] s_withSuppressGCTransitionOptionAliases = ["--with-suppressgctransition", "-wsgct"]; - private static readonly string[] s_withTransparentStructOptionAliases = ["--with-transparent-struct", "-wts"]; - private static readonly string[] s_withTypeOptionAliases = ["--with-type", "-wt"]; - private static readonly string[] s_withUsingOptionAliases = ["--with-using", "-wu"]; - private static readonly string[] s_withPackingOptionAliases = ["--with-packing", "-wp"]; - public static IEnumerable GetExtendedHelp(HelpContext context) { foreach (var sectionDelegate in HelpBuilder.Default.GetLayout()) diff --git a/sources/ClangSharpPInvokeGenerator/Properties/launchSettings.json b/sources/ClangSharpPInvokeGenerator/Properties/launchSettings.json index 41b61022..922ee360 100644 --- a/sources/ClangSharpPInvokeGenerator/Properties/launchSettings.json +++ b/sources/ClangSharpPInvokeGenerator/Properties/launchSettings.json @@ -13,5 +13,10 @@ "commandName": "Project", "commandLineArgs": "\"@$(MSBuildProjectDirectory)/Properties/GenerateLLVM.rsp\" --file-directory \"$(LLVMIncludePath)\" --include-directory \"$(LLVMIncludePath)\" --libraryPath $(LibLLVMName)" }, + "GenerateLocal": { + "commandName": "Project", + "commandLineArgs": "@generate.rsp", + "workingDirectory": "D:\\Users\\tagoo\\source\\repos\\terrafx.interop.windows\\generation\\Windows\\um\\sapi" + } } } From e01b9139111460b7a57f708c83cdcdb8728d9eef Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 15 Oct 2023 11:35:03 -0700 Subject: [PATCH 5/9] Move NoWarn to its own property group --- sources/ClangSharp.Interop/ClangSharp.Interop.csproj | 5 ++++- .../ClangSharp.PInvokeGenerator.csproj | 7 +++++-- sources/ClangSharp/ClangSharp.csproj | 5 ++++- .../ClangSharp.PInvokeGenerator.UnitTests.csproj | 7 +++++-- tests/ClangSharp.UnitTests/ClangSharp.UnitTests.csproj | 5 ++++- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/sources/ClangSharp.Interop/ClangSharp.Interop.csproj b/sources/ClangSharp.Interop/ClangSharp.Interop.csproj index d2268b8d..2a2cea46 100644 --- a/sources/ClangSharp.Interop/ClangSharp.Interop.csproj +++ b/sources/ClangSharp.Interop/ClangSharp.Interop.csproj @@ -1,6 +1,10 @@ + + net8.0;netstandard2.0 + + @@ -21,7 +25,6 @@ $(NoWarn);CA1003;CA1008;CA1027;CA1034;CA1051;CA1069;CA1305;CA1508;CA1707;CA1708;CA1710;CA1711;CA1712;CA1720;CA1721;CA1724;CA1815;CA2225 - net8.0;netstandard2.0 diff --git a/sources/ClangSharp.PInvokeGenerator/ClangSharp.PInvokeGenerator.csproj b/sources/ClangSharp.PInvokeGenerator/ClangSharp.PInvokeGenerator.csproj index 93876a29..a8c82d4a 100644 --- a/sources/ClangSharp.PInvokeGenerator/ClangSharp.PInvokeGenerator.csproj +++ b/sources/ClangSharp.PInvokeGenerator/ClangSharp.PInvokeGenerator.csproj @@ -2,12 +2,15 @@ - - $(NoWarn);CA1303 ClangSharp net8.0 + + + $(NoWarn);CA1303 + + diff --git a/sources/ClangSharp/ClangSharp.csproj b/sources/ClangSharp/ClangSharp.csproj index aa8ce820..de7a59d4 100644 --- a/sources/ClangSharp/ClangSharp.csproj +++ b/sources/ClangSharp/ClangSharp.csproj @@ -1,12 +1,15 @@ + + net8.0;netstandard2.0 + + $(NoWarn);CA1034;CA1040;CA1720 - net8.0;netstandard2.0 diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/ClangSharp.PInvokeGenerator.UnitTests.csproj b/tests/ClangSharp.PInvokeGenerator.UnitTests/ClangSharp.PInvokeGenerator.UnitTests.csproj index 68071b2f..cfdb757b 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/ClangSharp.PInvokeGenerator.UnitTests.csproj +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/ClangSharp.PInvokeGenerator.UnitTests.csproj @@ -1,12 +1,15 @@ + + ClangSharp.UnitTests + net8.0 + + $(NoWarn);CA1707;CA1711 - ClangSharp.UnitTests - net8.0 diff --git a/tests/ClangSharp.UnitTests/ClangSharp.UnitTests.csproj b/tests/ClangSharp.UnitTests/ClangSharp.UnitTests.csproj index c7b8b05c..837ec2d8 100644 --- a/tests/ClangSharp.UnitTests/ClangSharp.UnitTests.csproj +++ b/tests/ClangSharp.UnitTests/ClangSharp.UnitTests.csproj @@ -1,10 +1,13 @@ + + net8.0 + + $(NoWarn);CA1707 - net8.0 From 0d5a9156eaab049d2e4555cba027d11c1bd2293f Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 15 Oct 2023 11:42:38 -0700 Subject: [PATCH 6/9] Allow CI to pass --- sources/ClangSharp/Cursors/Cursor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/ClangSharp/Cursors/Cursor.cs b/sources/ClangSharp/Cursors/Cursor.cs index 772d5206..e5ddef9f 100644 --- a/sources/ClangSharp/Cursors/Cursor.cs +++ b/sources/ClangSharp/Cursors/Cursor.cs @@ -65,7 +65,7 @@ public IReadOnlyList CursorChildren cursorChildrenHandle.Free(); #if NET6_0_OR_GREATER - [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])] + [UnmanagedCallersOnly(CallConvs = new System.Type[] { typeof(CallConvCdecl) })] #endif static CXChildVisitResult Visitor(CXCursor cursor, CXCursor parent, void* client_data) { From 82ba1e390e098ec642c354404717d4f54b7bf9a2 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sun, 15 Oct 2023 11:57:09 -0700 Subject: [PATCH 7/9] Skip baseline package validation --- sources/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/Directory.Build.props b/sources/Directory.Build.props index 6f7f4210..4d57183b 100644 --- a/sources/Directory.Build.props +++ b/sources/Directory.Build.props @@ -13,7 +13,7 @@ sources true - true + false From 988a31955947f18247d77f63d491710570c38953 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 16 Oct 2023 08:45:22 -0700 Subject: [PATCH 8/9] Add a diagnostic when offsetof is used with DisableRuntimeMarshalling --- .../PInvokeGenerator.VisitDecl.cs | 2 +- .../PInvokeGenerator.VisitStmt.cs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs index c1ae83c2..5bdbd972 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs @@ -1674,7 +1674,7 @@ private void VisitRecordDecl(RecordDecl recordDecl) } } - if ((_testOutputBuilder is not null) && generateTestsClass) + if ((_testOutputBuilder is not null) && generateTestsClass && !_config.GenerateDisableRuntimeMarshalling) { _testOutputBuilder.WriteIndented("/// Validates that the Date: Mon, 16 Oct 2023 10:30:18 -0700 Subject: [PATCH 9/9] Add support for collection expressions --- .../CSharp/CSharpOutputBuilder.Visit.cs | 24 +++++++++- .../PInvokeGenerator.VisitStmt.cs | 44 +++++++++++++++++-- .../PInvokeGenerator.cs | 13 ++++-- .../CSharpPreviewUnix/VarDeclarationTest.cs | 24 +++++----- .../XmlPreviewUnix/VarDeclarationTest.cs | 12 ++--- 5 files changed, 91 insertions(+), 26 deletions(-) diff --git a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs index 046ed538..24263826 100644 --- a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs +++ b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs @@ -87,7 +87,17 @@ public void WriteIid(string name, Guid value) WriteIndentedLine("get"); WriteBlockStart(); - WriteIndentedLine("ReadOnlySpan data = new byte[] {"); + WriteIndented("ReadOnlySpan data = "); + + if (_config.GeneratePreviewCode) + { + WriteLine('['); + } + else + { + WriteLine("new byte[] {"); + } + IncreaseIndentation(); WriteIndentation(); @@ -113,7 +123,17 @@ public void WriteIid(string name, Guid value) WriteNewline(); DecreaseIndentation(); - WriteIndentedLine("};"); + + if (_config.GeneratePreviewCode) + { + WriteIndented(']'); + } + else + { + WriteIndented('}'); + } + + WriteLine(';'); NeedsNewline = true; diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs index 0b23e0b1..3a561d2f 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs @@ -1501,14 +1501,34 @@ void HandleUnmanagedConstant(CSharpOutputBuilder outputBuilder, InitListExpr ini outputBuilder.AddUsingDirective("System.Runtime.CompilerServices"); outputBuilder.AddUsingDirective("System.Runtime.InteropServices"); - outputBuilder.WriteIndentedLine("ReadOnlySpan data = new byte[] {"); + outputBuilder.WriteIndented("ReadOnlySpan data = "); + + if (_config.GeneratePreviewCode) + { + outputBuilder.WriteLine("["); + } + else + { + outputBuilder.WriteLine("new byte[] {"); + } + outputBuilder.IncreaseIndentation(); HandleInitListExpr(outputBuilder, initListExpr); outputBuilder.WriteNewline(); outputBuilder.DecreaseIndentation(); - outputBuilder.WriteIndentedLine("};"); + + if (_config.GeneratePreviewCode) + { + outputBuilder.WriteIndented(']'); + } + else + { + outputBuilder.WriteIndented('}'); + } + + outputBuilder.WriteLine(';'); outputBuilder.NeedsNewline = true; long rootSize = -1; @@ -2533,7 +2553,14 @@ private void VisitStringLiteral(StringLiteral stringLiteral) case CX_CLK_UTF32: { - outputBuilder.Write("new uint[] { "); + if (_config.GeneratePreviewCode) + { + outputBuilder.Write('['); + } + else + { + outputBuilder.Write("new uint[] { "); + } var bytes = Encoding.UTF32.GetBytes(stringLiteral.String); var codepoints = MemoryMarshal.Cast(bytes); @@ -2545,7 +2572,16 @@ private void VisitStringLiteral(StringLiteral stringLiteral) outputBuilder.Write(", "); } - outputBuilder.Write("0x00000000 }"); + outputBuilder.Write("0x00000000"); + + if (_config.GeneratePreviewCode) + { + outputBuilder.Write(']'); + } + else + { + outputBuilder.Write(" }"); + } break; } diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs index cd470b6e..109f6787 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs @@ -1769,7 +1769,7 @@ static string GetFoundRemappingString(string name, HashSet remappings) else { result += ' '; - remainingRemappings = remappings.Except(new string[] { recommendedRemapping }); + remainingRemappings = remappings.Except([recommendedRemapping]); remainingString = "Other"; } } @@ -1848,7 +1848,6 @@ private void AddUsingDirective(IOutputBuilder? outputBuilder, string namespaceNa private void CloseOutputBuilder(Stream stream, IOutputBuilder outputBuilder, bool isMethodClass, bool leaveStreamOpen, bool emitNamespaceDeclaration) { ArgumentNullException.ThrowIfNull(stream); - ArgumentNullException.ThrowIfNull(outputBuilder); using var sw = new StreamWriter(stream, s_defaultStreamWriterEncoding, DefaultStreamWriterBufferSize, leaveStreamOpen); @@ -1917,11 +1916,17 @@ private void CloseOutputBuilder(Stream stream, IOutputBuilder outputBuilder, boo if (outputBuilder is CSharpOutputBuilder csOutputBuilder) { - ForCSharp(csOutputBuilder); + if (csOutputBuilder.Contents.Any()) + { + ForCSharp(csOutputBuilder); + } } else if (outputBuilder is XmlOutputBuilder xmlOutputBuilder) { - ForXml(xmlOutputBuilder); + if (xmlOutputBuilder.Contents.Any()) + { + ForXml(xmlOutputBuilder); + } } void ForCSharp(CSharpOutputBuilder csharpOutputBuilder) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/VarDeclarationTest.cs index e16e43df..0ad4d6ab 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpPreviewUnix/VarDeclarationTest.cs @@ -156,23 +156,25 @@ protected override Task WideStringLiteralConstTestImpl() const wchar_t* MyConst2 = L""Test""; const wchar_t* const MyConst3 = L""Test"";"; - var expectedOutputContents = $@"namespace ClangSharp.Test + var expectedOutputContents = $@"using System; + +namespace ClangSharp.Test {{ public static partial class Methods {{ [NativeTypeName(""const wchar_t[5]"")] - public static readonly uint[] MyConst1 = new uint[] {{ 0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000 }}; + public static ReadOnlySpan MyConst1 => [0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000]; [NativeTypeName(""const wchar_t *"")] - public static uint[] MyConst2 = new uint[] {{ 0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000 }}; + public static uint[] MyConst2 = [0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000]; [NativeTypeName(""const wchar_t *const"")] - public static readonly uint[] MyConst3 = new uint[] {{ 0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000 }}; + public static ReadOnlySpan MyConst3 => [0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000]; }} }} "; - return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + return ValidateGeneratedCSharpPreviewUnixBindingsAsync(inputContents, expectedOutputContents); } protected override Task StringLiteralConstTestImpl() @@ -208,23 +210,25 @@ protected override Task WideStringLiteralStaticConstTestImpl() static const wchar_t* MyConst2 = L""Test""; static const wchar_t* const MyConst3 = L""Test"";"; - var expectedOutputContents = $@"namespace ClangSharp.Test + var expectedOutputContents = $@"using System; + +namespace ClangSharp.Test {{ public static partial class Methods {{ [NativeTypeName(""const wchar_t[5]"")] - public static readonly uint[] MyConst1 = new uint[] {{ 0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000 }}; + public static ReadOnlySpan MyConst1 => [0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000]; [NativeTypeName(""const wchar_t *"")] - public static uint[] MyConst2 = new uint[] {{ 0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000 }}; + public static uint[] MyConst2 = [0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000]; [NativeTypeName(""const wchar_t *const"")] - public static readonly uint[] MyConst3 = new uint[] {{ 0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000 }}; + public static ReadOnlySpan MyConst3 => [0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000]; }} }} "; - return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + return ValidateGeneratedCSharpPreviewUnixBindingsAsync(inputContents, expectedOutputContents); } protected override Task StringLiteralStaticConstTestImpl() diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/VarDeclarationTest.cs index 612618a0..fbc6c8e3 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlPreviewUnix/VarDeclarationTest.cs @@ -198,19 +198,19 @@ protected override Task WideStringLiteralConstTestImpl() ReadOnlySpan<uint> - new uint[] {{ 0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000 }} + [0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000] uint[] - new uint[] {{ 0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000 }} + [0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000] ReadOnlySpan<uint> - new uint[] {{ 0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000 }} + [0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000] @@ -270,19 +270,19 @@ protected override Task WideStringLiteralStaticConstTestImpl() ReadOnlySpan<uint> - new uint[] {{ 0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000 }} + [0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000] uint[] - new uint[] {{ 0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000 }} + [0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000] ReadOnlySpan<uint> - new uint[] {{ 0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000 }} + [0x00000054, 0x00000065, 0x00000073, 0x00000074, 0x00000000]