From 2daa3b6c31453fd56681bac2a25d44da93c49092 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sat, 20 Mar 2021 17:33:30 -0700 Subject: [PATCH 1/4] Adding XmlLatestWindows tests --- .../Abstractions/AccessSpecifier.cs | 4 +- .../Abstractions/ConstantDesc.cs | 4 +- .../Abstractions/ConstantKind.cs | 2 + .../Abstractions/FieldDesc.cs | 4 +- .../Abstractions/FunctionOrDelegateDesc.cs | 4 +- .../Abstractions/IOutputBuilder.Visit.cs | 2 + .../Abstractions/ParameterDesc.cs | 4 +- .../Abstractions/StructDesc.cs | 4 +- .../Abstractions/StructFlags.cs | 4 +- .../CSharp/CSharpOutputBuilder.Visit.cs | 4 +- .../CSharp/CSharpOutputBuilder.VisitDecl.cs | 2 + .../CSharp/CSharpOutputBuilder.cs | 4 +- .../CSharp/MarkerMode.cs | 2 + .../Extensions/StringExtensions.cs | 4 +- .../PInvokeGenerator.VisitDecl.cs | 2 +- .../PInvokeGenerator.cs | 88 +- .../XML/XmlOutputBuilder.Visit.cs | 2 + .../XML/XmlOutputBuilder.VisitDecl.cs | 51 +- .../XML/XmlOutputBuilder.cs | 6 +- .../Base/FunctionDeclarationDllImportTest.cs | 40 +- .../FunctionDeclarationDllImportTest.cs | 18 +- .../FunctionDeclarationDllImportTest.cs | 18 +- .../FunctionDeclarationDllImportTest.cs | 18 +- .../FunctionDeclarationDllImportTest.cs | 18 +- .../PInvokeGeneratorTest.cs | 13 +- .../CXXMethodDeclarationTest.cs | 912 ++++++++ .../XmlLatestWindows/EnumDeclarationTest.cs | 752 ++++++ .../FunctionDeclarationBodyImportTest.cs | 2013 +++++++++++++++++ .../FunctionDeclarationDllImportTest.cs | 399 ++++ .../FunctionPointerDeclarationTest.cs | 26 + .../XmlLatestWindows/StructDeclarationTest.cs | 1485 ++++++++++++ .../XmlLatestWindows/UnionDeclarationTest.cs | 1340 +++++++++++ .../XmlLatestWindows/VarDeclarationTest.cs | 373 +++ 33 files changed, 7508 insertions(+), 114 deletions(-) create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/EnumDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationBodyImportTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationDllImportTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionPointerDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/StructDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/VarDeclarationTest.cs diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/AccessSpecifier.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/AccessSpecifier.cs index 7503d241..bc74af20 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/AccessSpecifier.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/AccessSpecifier.cs @@ -1,4 +1,6 @@ -namespace ClangSharp.Abstractions +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +namespace ClangSharp.Abstractions { public enum AccessSpecifier : byte { diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/ConstantDesc.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/ConstantDesc.cs index a6431816..c5ad24e1 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/ConstantDesc.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/ConstantDesc.cs @@ -1,4 +1,6 @@ -namespace ClangSharp.Abstractions +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +namespace ClangSharp.Abstractions { internal struct ConstantDesc { diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/ConstantKind.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/ConstantKind.cs index ba20d75c..c04b91a2 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/ConstantKind.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/ConstantKind.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + using System; namespace ClangSharp.Abstractions diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/FieldDesc.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/FieldDesc.cs index 91e026df..006b5251 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/FieldDesc.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/FieldDesc.cs @@ -1,4 +1,6 @@ -namespace ClangSharp.Abstractions +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +namespace ClangSharp.Abstractions { internal struct FieldDesc { diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs index 8547992c..34112b45 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/FunctionOrDelegateDesc.cs @@ -1,4 +1,6 @@ -using System; +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; using System.Runtime.InteropServices; namespace ClangSharp.Abstractions diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/IOutputBuilder.Visit.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/IOutputBuilder.Visit.cs index bb0aac8a..2529a226 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/IOutputBuilder.Visit.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/IOutputBuilder.Visit.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + namespace ClangSharp.Abstractions { internal partial interface IOutputBuilder diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/ParameterDesc.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/ParameterDesc.cs index 10f367e4..fde0fb6a 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/ParameterDesc.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/ParameterDesc.cs @@ -1,4 +1,6 @@ -using System; +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; using System.Collections.Generic; namespace ClangSharp.Abstractions diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/StructDesc.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/StructDesc.cs index 7c29684e..42cf9735 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/StructDesc.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/StructDesc.cs @@ -1,4 +1,6 @@ -using System; +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; using System.Runtime.InteropServices; namespace ClangSharp.Abstractions diff --git a/sources/ClangSharp.PInvokeGenerator/Abstractions/StructFlags.cs b/sources/ClangSharp.PInvokeGenerator/Abstractions/StructFlags.cs index 34991433..637b5986 100644 --- a/sources/ClangSharp.PInvokeGenerator/Abstractions/StructFlags.cs +++ b/sources/ClangSharp.PInvokeGenerator/Abstractions/StructFlags.cs @@ -1,4 +1,6 @@ -using System; +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; namespace ClangSharp.Abstractions { diff --git a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs index dd0c12df..e52fe568 100644 --- a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs +++ b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.Visit.cs @@ -1,4 +1,6 @@ -namespace ClangSharp.CSharp +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +namespace ClangSharp.CSharp { internal partial class CSharpOutputBuilder { diff --git a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs index 65a59dee..e9b6bc82 100644 --- a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.VisitDecl.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + using System.Diagnostics; using System.Globalization; using System.Runtime.InteropServices; diff --git a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs index 0b131455..5ace7376 100644 --- a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs +++ b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs @@ -35,6 +35,8 @@ public CSharpOutputBuilder(string name, string indentationString = DefaultIndent public IEnumerable Contents => _contents; + public bool HasPendingLine => _currentLine.Length > 0; + public string IndentationString => _indentationString; public bool IsTestOutput => _isTestOutput; @@ -146,7 +148,7 @@ public void WriteNewlineIfNeeded() public void WritePendingLine() { - if (_currentLine.Length > 0) + if (HasPendingLine) { WriteNewline(); } diff --git a/sources/ClangSharp.PInvokeGenerator/CSharp/MarkerMode.cs b/sources/ClangSharp.PInvokeGenerator/CSharp/MarkerMode.cs index e6249153..02dcb07f 100644 --- a/sources/ClangSharp.PInvokeGenerator/CSharp/MarkerMode.cs +++ b/sources/ClangSharp.PInvokeGenerator/CSharp/MarkerMode.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + namespace ClangSharp.CSharp { internal enum MarkerMode diff --git a/sources/ClangSharp.PInvokeGenerator/Extensions/StringExtensions.cs b/sources/ClangSharp.PInvokeGenerator/Extensions/StringExtensions.cs index 540a26f1..1f73a826 100644 --- a/sources/ClangSharp.PInvokeGenerator/Extensions/StringExtensions.cs +++ b/sources/ClangSharp.PInvokeGenerator/Extensions/StringExtensions.cs @@ -1,4 +1,6 @@ -using System; +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; using System.Runtime.InteropServices; using ClangSharp.Abstractions; diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs index a16312c9..edb127df 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs @@ -472,7 +472,7 @@ private void VisitFunctionDecl(FunctionDecl functionDecl) var needsReturnFixup = isVirtual && NeedsReturnFixup(cxxMethodDecl); - if (!(functionDecl is CXXConstructorDecl)) + if ((functionDecl is not CXXConstructorDecl) || (_config.OutputMode == PInvokeGeneratorOutputMode.Xml)) { _outputBuilder.WriteReturnType(needsReturnFixup ? $"{returnTypeName}*" : returnTypeName); } diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs index 3a382e27..1d3e193b 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs @@ -113,6 +113,7 @@ public void Close() var usingDirectives = Enumerable.Empty(); var staticUsingDirectives = Enumerable.Empty(); + var hasAnyContents = false; foreach (var outputBuilder in _outputBuilderFactory.OutputBuilders) { @@ -120,6 +121,11 @@ public void Close() { usingDirectives = usingDirectives.Concat(csharpOutputBuilder.UsingDirectives); staticUsingDirectives = staticUsingDirectives.Concat(csharpOutputBuilder.StaticUsingDirectives); + hasAnyContents = csharpOutputBuilder.Contents.Any(); + } + else if (outputBuilder is XmlOutputBuilder xmlOutputBuilder) + { + hasAnyContents = xmlOutputBuilder.Contents.Any(); } } @@ -131,15 +137,20 @@ public void Close() usingDirectives = usingDirectives.Concat(staticUsingDirectives); - if (usingDirectives.Any()) + if (hasAnyContents) { using var sw = new StreamWriter(stream, defaultStreamWriterEncoding, DefaultStreamWriterBufferSize, leaveStreamOpen); + sw.NewLine = "\n"; + + if (_config.OutputMode == PInvokeGeneratorOutputMode.CSharp) { - sw.NewLine = "\n"; - if (_config.OutputMode == PInvokeGeneratorOutputMode.CSharp) + if (_config.HeaderText != string.Empty) { - sw.Write(_config.HeaderText); + sw.WriteLine(_config.HeaderText); + } + if (usingDirectives.Any()) + { foreach (var usingDirective in usingDirectives) { sw.Write("using "); @@ -149,18 +160,26 @@ public void Close() sw.WriteLine(); } - else if (_config.OutputMode == PInvokeGeneratorOutputMode.Xml) + } + else if (_config.OutputMode == PInvokeGeneratorOutputMode.Xml) + { + sw.WriteLine(""); + sw.WriteLine(""); + + if (_config.HeaderText != string.Empty) { - sw.WriteLine(""); - sw.WriteLine(""); - sw.WriteLine(" "); - foreach (var ln in _config.HeaderText.Split('\n')) + sw.WriteLine(" "); + + if (_config.HeaderText != string.Empty) { - sw.Write(" "); - sw.WriteLine(ln); + foreach (var ln in _config.HeaderText.Split('\n')) + { + sw.Write(" "); + sw.WriteLine(ln); + } } - sw.WriteLine(" "); + sw.WriteLine(" "); } } } @@ -198,7 +217,15 @@ public void Close() using var sw = new StreamWriter(stream, defaultStreamWriterEncoding, DefaultStreamWriterBufferSize, leaveStreamOpen); sw.NewLine = "\n"; - sw.WriteLine('}'); + if (_config.OutputMode == PInvokeGeneratorOutputMode.CSharp) + { + sw.WriteLine('}'); + } + else if (_config.OutputMode == PInvokeGeneratorOutputMode.Xml) + { + sw.WriteLine(" "); + sw.WriteLine(""); + } } _context.Clear(); @@ -349,18 +376,23 @@ private void CloseOutputBuilder(Stream stream, IOutputBuilder outputBuilder, boo sw.WriteLine(); } } - else if (outputBuilder is XmlOutputBuilder xmlOutputBuilder) + else if ((outputBuilder is XmlOutputBuilder xmlOutputBuilder) && xmlOutputBuilder.Contents.Any()) { - sw.WriteLine(""); - sw.WriteLine(""); - sw.WriteLine(" "); - foreach (var ln in _config.HeaderText.Split('\n')) - { - sw.Write(" "); - sw.WriteLine(ln); - } + sw.WriteLine(""); + sw.WriteLine(""); + + if (_config.HeaderText != string.Empty) + { + sw.WriteLine(" "); + + foreach (var ln in _config.HeaderText.Split('\n')) + { + sw.Write(" "); + sw.WriteLine(ln); + } - sw.WriteLine(" "); + sw.WriteLine(" "); + } } } @@ -440,23 +472,26 @@ void ForCSharp(CSharpOutputBuilder csharpOutputBuilder) void ForXml(XmlOutputBuilder xmlOutputBuilder) { - const string indent = " "; + const string indent = " "; var indentationString = indent; + if (emitNamespaceDeclaration) { sw.Write(indentationString); sw.Write(""); - indentationString += indent; } + indentationString += indent; + if (isMethodClass) { sw.Write(indentationString); sw.Write(""); + sw.WriteLine(""); } - - sw.WriteLine(""); } } diff --git a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.Visit.cs b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.Visit.cs index b2d2d1e2..e055cc06 100644 --- a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.Visit.cs +++ b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.Visit.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + namespace ClangSharp.XML { internal partial class XmlOutputBuilder diff --git a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs index 14b2fc4d..0b0d31db 100644 --- a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.VisitDecl.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; @@ -25,7 +27,7 @@ public void BeginConstant(in ConstantDesc desc) ? $"" : $""); _sb.Append($""); - _sb.Append(desc.TypeName.Replace("<", "<").Replace(">", ">")); + _sb.Append(EscapeText(desc.TypeName)); _sb.Append(""); } @@ -36,7 +38,10 @@ public void BeginConstant(in ConstantDesc desc) public void EndConstant(bool isConstant) => _sb.Append(isConstant ? "" : ""); public void BeginEnum(AccessSpecifier accessSpecifier, string typeName, string escapedName, string nativeTypeName) - => _sb.Append($"{typeName}"); + { + _sb.Append($""); + _sb.Append($"{typeName}"); + } public void EndEnum() => _sb.Append(""); @@ -54,15 +59,22 @@ public void BeginField(in FieldDesc desc) } _sb.Append('>'); - _sb.Append($" _sb.Append($" count=\"{count}\" fixed=\"{fixedName}\">" + - $"{typeName.Replace("<", "<").Replace(">", ">")}"); + $"{EscapeText(typeName)}"); public void WriteRegularField(string typeName, string escapedName) - => _sb.Append($">{typeName.Replace("<", "<").Replace(">", ">")}"); + => _sb.Append($">{EscapeText(typeName)}"); public void EndField(bool isBodyless = true) => _sb.Append(""); public void BeginFunctionOrDelegate( in FunctionOrDelegateDesc desc, ref bool isMethodClassUnsafe) @@ -105,7 +117,7 @@ public void BeginFunctionOrDelegate( _sb.Append(" static=\"true\""); } - if (!desc.IsUnsafe) + if (desc.IsUnsafe) { _sb.Append(" unsafe=\"true\""); } @@ -113,11 +125,12 @@ public void BeginFunctionOrDelegate( _sb.Append('>'); desc.WriteCustomAttrs(desc.CustomAttrGeneratorData); + _sb.Append("( public void WriteReturnType(string typeString) { - _sb.Append(typeString.Replace("<", "<").Replace(">", ">")); + _sb.Append(EscapeText(typeString)); _sb.Append(""); } @@ -140,7 +153,7 @@ public void BeginParameter(in ParameterDesc"); info.WriteCustomAttrs(info.CustomAttrGeneratorData); _sb.Append(""); - _sb.Append(info.Type.Replace("<", "<").Replace(">", ">")); + _sb.Append(EscapeText(info.Type)); _sb.Append(""); } @@ -295,14 +308,20 @@ public CSharpOutputBuilder BeginCSharpCode() public void EndCSharpCode(CSharpOutputBuilder output) { output.WritePendingLine(); + + var needsNewline = false; + foreach (var s in output.Contents) { - _sb.Append(s.Replace("&", "&") - .Replace("<", "<") - .Replace(">", ">") - .Replace("/*M*/<", "<") - .Replace("/*M*/>", ">")); - _sb.Append('\n'); + if (needsNewline) + { + _sb.Append('\n'); + } + + _sb.Append(EscapeText(s).Replace("/*M*/<", "<") + .Replace("/*M*/>", ">")); + + needsNewline = true; } _sb.Append(""); @@ -350,7 +369,7 @@ public void BeginIndexer(AccessSpecifier accessSpecifier, bool isUnsafe) public void WriteIndexer(string typeName) { _sb.Append(""); - _sb.Append(typeName.Replace("<", "<").Replace(">", ">")); + _sb.Append(EscapeText(typeName)); _sb.Append(""); } diff --git a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.cs b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.cs index 60587740..703db424 100644 --- a/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.cs +++ b/sources/ClangSharp.PInvokeGenerator/XML/XmlOutputBuilder.cs @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + using System.Collections.Generic; using System.IO; using System.Xml; @@ -25,7 +27,7 @@ public IEnumerable Contents XmlWriter writer = XmlWriter.Create(sw, new() { Indent = true, - IndentChars = " ", + IndentChars = " ", ConformanceLevel = ConformanceLevel.Fragment, NewLineChars = "\n", }); @@ -39,5 +41,7 @@ public IEnumerable Contents return sw.ToString().Split('\n'); } } + + private string EscapeText(string value) => new XText(value).ToString(); } } diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionDeclarationDllImportTest.cs index aeada887..05c77b80 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/Base/FunctionDeclarationDllImportTest.cs @@ -17,11 +17,11 @@ public abstract class FunctionDeclarationDllImportTest : PInvokeGeneratorTest public abstract Task FunctionPointerParameterTest(); [Theory] - [InlineData("MyTemplate", @"MyTemplate", "")] - [InlineData("MyTemplate", @"[NativeTypeName(""MyTemplate"")] MyTemplate", "")] - [InlineData("MyTemplate", @"[NativeTypeName(""MyTemplate"")] MyTemplate", "using System;\n")] - [InlineData("MyTemplate", @"[NativeTypeName(""MyTemplate"")] MyTemplate", "using System;\n")] - public abstract Task TemplateParameterTest(string nativeParameter, string expectedManagedParameter, string expectedUsingStatement); + [InlineData("int", false, "int", "")] + [InlineData("bool", true, "byte", "")] + [InlineData("float *", true, "IntPtr", "using System;\n")] + [InlineData("void (*)(int)", true, "IntPtr", "using System;\n")] + public abstract Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement); [Fact] public abstract Task TemplateMemberTest(); @@ -37,23 +37,23 @@ public abstract class FunctionDeclarationDllImportTest : PInvokeGeneratorTest public abstract Task WithLibraryPathStarTest(); [Theory] - [InlineData("unsigned char value = 0", @"[NativeTypeName(""unsigned char"")] byte value = 0")] - [InlineData("double value = 1.0", @"double value = 1.0")] - [InlineData("short value = 2", @"short value = 2")] - [InlineData("int value = 3", @"int value = 3")] - [InlineData("long long value = 4", @"[NativeTypeName(""long long"")] long value = 4")] - [InlineData("signed char value = 5", @"[NativeTypeName(""signed char"")] sbyte value = 5")] - [InlineData("float value = 6.0f", @"float value = 6.0f")] - [InlineData("unsigned short value = 7", @"[NativeTypeName(""unsigned short"")] ushort value = 7")] - [InlineData("unsigned int value = 8", @"[NativeTypeName(""unsigned int"")] uint value = 8")] - [InlineData("unsigned long long value = 9", @"[NativeTypeName(""unsigned long long"")] ulong value = 9")] - [InlineData("unsigned short value = 'A'", @"[NativeTypeName(""unsigned short"")] ushort value = (byte)('A')")] - public abstract Task OptionalParameterTest(string nativeParameters, string expectedManagedParameters); + [InlineData("unsigned char", "0", true, "byte", "0")] + [InlineData("double", "1.0", false, "double", "1.0")] + [InlineData("short", "2", false, "short", "2")] + [InlineData("int", "3", false, "int", "3")] + [InlineData("long long", "4", true, "long", "4")] + [InlineData("signed char", "5", true, "sbyte", "5")] + [InlineData("float", "6.0f", false, "float", "6.0f")] + [InlineData("unsigned short", "7", true, "ushort", "7")] + [InlineData("unsigned int", "8", true, "uint", "8")] + [InlineData("unsigned long long", "9", true, "ulong", "9")] + [InlineData("unsigned short", "'A'", true, "ushort", "(byte)('A')")] + public abstract Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit); [Theory] - [InlineData("void* value = nullptr", @"[NativeTypeName(""void *"")] void* value = null")] - [InlineData("void* value = 0", @"[NativeTypeName(""void *"")] void* value = null")] - public abstract Task OptionalParameterUnsafeTest(string nativeParameters, string expectedManagedParameters); + [InlineData("void *", "nullptr", "void*", "null")] + [InlineData("void *", "0", "void*", "null")] + public abstract Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit); [Fact] public abstract Task WithCallConvTest(); diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/FunctionDeclarationDllImportTest.cs index c457a3c2..b8303b95 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/FunctionDeclarationDllImportTest.cs @@ -65,11 +65,11 @@ public static partial class Methods return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); } - public override Task TemplateParameterTest(string nativeParameter, string expectedManagedParameter, string expectedUsingStatement) + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) { var inputContents = @$"template struct MyTemplate; -void MyFunction({nativeParameter} myStruct);"; +void MyFunction(MyTemplate<{nativeType}> myStruct);"; var expectedOutputContents = $@"{expectedUsingStatement}using System.Runtime.InteropServices; @@ -78,7 +78,7 @@ namespace ClangSharp.Test public static partial class Methods {{ [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void MyFunction({expectedManagedParameter} myStruct); + public static extern void MyFunction({(expectedNativeTypeAttr ? $@"[NativeTypeName(""MyTemplate<{nativeType}>"")] " : "")}MyTemplate<{expectedManagedType}> myStruct); }} }} "; @@ -178,9 +178,9 @@ public static partial class Methods return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty, withLibraryPaths: withLibraryPaths); } - public override Task OptionalParameterTest(string nativeParameters, string expectedManagedParameters) + public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeParameters});"; + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -189,7 +189,7 @@ namespace ClangSharp.Test public static partial class Methods {{ [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void MyFunction({expectedManagedParameters}); + public static extern void MyFunction({(expectedNativeTypeNameAttr ? $@"[NativeTypeName(""{nativeType}"")] " : "")}{expectedManagedType} value = {expectedManagedInit}); }} }} "; @@ -197,9 +197,9 @@ public static partial class Methods return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); } - public override Task OptionalParameterUnsafeTest(string nativeParameters, string expectedManagedParameters) + public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeParameters});"; + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -208,7 +208,7 @@ namespace ClangSharp.Test public static unsafe partial class Methods {{ [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void MyFunction({expectedManagedParameters}); + public static extern void MyFunction([NativeTypeName(""{nativeType}"")] {expectedManagedType} value = {expectedManagedInit}); }} }} "; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/FunctionDeclarationDllImportTest.cs index 0677bccd..2a02ecdb 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/FunctionDeclarationDllImportTest.cs @@ -65,11 +65,11 @@ public static partial class Methods return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); } - public override Task TemplateParameterTest(string nativeParameter, string expectedManagedParameter, string expectedUsingStatement) + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) { var inputContents = @$"template struct MyTemplate; -void MyFunction({nativeParameter} myStruct);"; +void MyFunction(MyTemplate<{nativeType}> myStruct);"; var expectedOutputContents = $@"{expectedUsingStatement}using System.Runtime.InteropServices; @@ -78,7 +78,7 @@ namespace ClangSharp.Test public static partial class Methods {{ [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void MyFunction({expectedManagedParameter} myStruct); + public static extern void MyFunction({(expectedNativeTypeAttr ? $@"[NativeTypeName(""MyTemplate<{nativeType}>"")] " : "")}MyTemplate<{expectedManagedType}> myStruct); }} }} "; @@ -178,9 +178,9 @@ public static partial class Methods return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty, withLibraryPaths: withLibraryPaths); } - public override Task OptionalParameterTest(string nativeParameters, string expectedManagedParameters) + public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeParameters});"; + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -189,7 +189,7 @@ namespace ClangSharp.Test public static partial class Methods {{ [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void MyFunction({expectedManagedParameters}); + public static extern void MyFunction({(expectedNativeTypeNameAttr ? $@"[NativeTypeName(""{nativeType}"")] " : "")}{expectedManagedType} value = {expectedManagedInit}); }} }} "; @@ -197,9 +197,9 @@ public static partial class Methods return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); } - public override Task OptionalParameterUnsafeTest(string nativeParameters, string expectedManagedParameters) + public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeParameters});"; + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -208,7 +208,7 @@ namespace ClangSharp.Test public static unsafe partial class Methods {{ [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void MyFunction({expectedManagedParameters}); + public static extern void MyFunction([NativeTypeName(""{nativeType}"")] {expectedManagedType} value = {expectedManagedInit}); }} }} "; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationDllImportTest.cs index 3aa61999..e2f632b0 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/FunctionDeclarationDllImportTest.cs @@ -65,11 +65,11 @@ public static partial class Methods return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents); } - public override Task TemplateParameterTest(string nativeParameter, string expectedManagedParameter, string expectedUsingStatement) + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) { var inputContents = @$"template struct MyTemplate; -void MyFunction({nativeParameter} myStruct);"; +void MyFunction(MyTemplate<{nativeType}> myStruct);"; var expectedOutputContents = $@"{expectedUsingStatement}using System.Runtime.InteropServices; @@ -78,7 +78,7 @@ namespace ClangSharp.Test public static partial class Methods {{ [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void MyFunction({expectedManagedParameter} myStruct); + public static extern void MyFunction({(expectedNativeTypeAttr ? $@"[NativeTypeName(""MyTemplate<{nativeType}>"")] " : "")}MyTemplate<{expectedManagedType}> myStruct); }} }} "; @@ -178,9 +178,9 @@ public static partial class Methods return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty, withLibraryPaths: withLibraryPaths); } - public override Task OptionalParameterTest(string nativeParameters, string expectedManagedParameters) + public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeParameters});"; + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -189,7 +189,7 @@ namespace ClangSharp.Test public static partial class Methods {{ [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void MyFunction({expectedManagedParameters}); + public static extern void MyFunction({(expectedNativeTypeNameAttr ? $@"[NativeTypeName(""{nativeType}"")] " : "")}{expectedManagedType} value = {expectedManagedInit}); }} }} "; @@ -197,9 +197,9 @@ public static partial class Methods return ValidateGeneratedCSharpLatestUnixBindingsAsync(inputContents, expectedOutputContents); } - public override Task OptionalParameterUnsafeTest(string nativeParameters, string expectedManagedParameters) + public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeParameters});"; + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -208,7 +208,7 @@ namespace ClangSharp.Test public static unsafe partial class Methods {{ [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void MyFunction({expectedManagedParameters}); + public static extern void MyFunction([NativeTypeName(""{nativeType}"")] {expectedManagedType} value = {expectedManagedInit}); }} }} "; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationDllImportTest.cs index f7c250bf..8966c96c 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationDllImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestWindows/FunctionDeclarationDllImportTest.cs @@ -65,11 +65,11 @@ public static partial class Methods return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents); } - public override Task TemplateParameterTest(string nativeParameter, string expectedManagedParameter, string expectedUsingStatement) + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) { var inputContents = @$"template struct MyTemplate; -void MyFunction({nativeParameter} myStruct);"; +void MyFunction(MyTemplate<{nativeType}> myStruct);"; var expectedOutputContents = $@"{expectedUsingStatement}using System.Runtime.InteropServices; @@ -78,7 +78,7 @@ namespace ClangSharp.Test public static partial class Methods {{ [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void MyFunction({expectedManagedParameter} myStruct); + public static extern void MyFunction({(expectedNativeTypeAttr ? $@"[NativeTypeName(""MyTemplate<{nativeType}>"")] " : "")}MyTemplate<{expectedManagedType}> myStruct); }} }} "; @@ -178,9 +178,9 @@ public static partial class Methods return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty, withLibraryPaths: withLibraryPaths); } - public override Task OptionalParameterTest(string nativeParameters, string expectedManagedParameters) + public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeParameters});"; + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -189,7 +189,7 @@ namespace ClangSharp.Test public static partial class Methods {{ [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void MyFunction({expectedManagedParameters}); + public static extern void MyFunction({(expectedNativeTypeNameAttr ? $@"[NativeTypeName(""{nativeType}"")] " : "")}{expectedManagedType} value = {expectedManagedInit}); }} }} "; @@ -197,9 +197,9 @@ public static partial class Methods return ValidateGeneratedCSharpLatestWindowsBindingsAsync(inputContents, expectedOutputContents); } - public override Task OptionalParameterUnsafeTest(string nativeParameters, string expectedManagedParameters) + public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) { - var inputContents = $@"void MyFunction({nativeParameters});"; + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; var expectedOutputContents = $@"using System.Runtime.InteropServices; @@ -208,7 +208,7 @@ namespace ClangSharp.Test public static unsafe partial class Methods {{ [DllImport(""ClangSharpPInvokeGenerator"", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - public static extern void MyFunction({expectedManagedParameters}); + public static extern void MyFunction([NativeTypeName(""{nativeType}"")] {expectedManagedType} value = {expectedManagedInit}); }} }} "; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/PInvokeGeneratorTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/PInvokeGeneratorTest.cs index 69adb374..8c53f4fb 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/PInvokeGeneratorTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/PInvokeGeneratorTest.cs @@ -2,7 +2,9 @@ using System.Collections.Generic; using System.IO; +using System.Runtime.CompilerServices; using System.Threading.Tasks; +using System.Xml.Linq; using ClangSharp.Interop; using Xunit; @@ -26,6 +28,11 @@ public abstract class PInvokeGeneratorTest "-Wno-c++11-narrowing" }; + protected string EscapeXml(string value) + { + return new XText(value).ToString(); + } + protected Task ValidateGeneratedCSharpLatestWindowsBindingsAsync(string inputContents, string expectedOutputContents, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null) { return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.None, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs); @@ -46,9 +53,9 @@ protected Task ValidateGeneratedCSharpCompatibleUnixBindingsAsync(string inputCo return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs); } - protected Task ValidateGeneratedXmlLatestWindowsBindingsAsync(string inputContents, string expectedOutputContents, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null) + protected Task ValidateGeneratedXmlLatestWindowsBindingsAsync(string inputContents, string expectedOutputContents, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null, [CallerFilePath] string filePath = "") { - return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.None, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs); + return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.None, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs, filePath); } protected Task ValidateGeneratedXmlLatestUnixBindingsAsync(string inputContents, string expectedOutputContents, string[] excludedNames = null, IReadOnlyDictionary remappedNames = null, IReadOnlyDictionary> withAttributes = null, IReadOnlyDictionary withCallConvs = null, IReadOnlyDictionary withLibraryPaths = null, string[] withSetLastErrors = null, IReadOnlyDictionary withTypes = null, IReadOnlyDictionary> withUsings = null, IEnumerable expectedDiagnostics = null, string libraryPath = DefaultLibraryPath, string[] commandlineArgs = null) @@ -66,7 +73,7 @@ protected Task ValidateGeneratedXmlCompatibleUnixBindingsAsync(string inputConte return ValidateGeneratedBindingsAsync(inputContents, expectedOutputContents, PInvokeGeneratorOutputMode.Xml, PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode | PInvokeGeneratorConfigurationOptions.GenerateUnixTypes, excludedNames, remappedNames, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings, expectedDiagnostics, libraryPath, commandlineArgs); } - private async Task ValidateGeneratedBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorOutputMode outputMode, PInvokeGeneratorConfigurationOptions configOptions, string[] excludedNames, IReadOnlyDictionary remappedNames, IReadOnlyDictionary> withAttributes, IReadOnlyDictionary withCallConvs, IReadOnlyDictionary withLibraryPaths, string[] withSetLastErrors, IReadOnlyDictionary withTypes, IReadOnlyDictionary> withUsings, IEnumerable expectedDiagnostics, string libraryPath, string[] commandlineArgs) + private async Task ValidateGeneratedBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorOutputMode outputMode, PInvokeGeneratorConfigurationOptions configOptions, string[] excludedNames, IReadOnlyDictionary remappedNames, IReadOnlyDictionary> withAttributes, IReadOnlyDictionary withCallConvs, IReadOnlyDictionary withLibraryPaths, string[] withSetLastErrors, IReadOnlyDictionary withTypes, IReadOnlyDictionary> withUsings, IEnumerable expectedDiagnostics, string libraryPath, string[] commandlineArgs, [CallerFilePath] string filePath = "") { Assert.True(File.Exists(DefaultInputFileName)); diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs new file mode 100644 index 00000000..5b1caa67 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/CXXMethodDeclarationTest.cs @@ -0,0 +1,912 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestWindows_CXXMethodDeclarationTest : CXXMethodDeclarationTest + { + public override Task ConstructorTest() + { + var inputContents = @"struct MyStruct +{ + int _value; + + MyStruct(int value) + { + _value = value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + void + + int + + _value = value; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ConstructorWithInitializeTest() + { + var inputContents = @"struct MyStruct +{ + int _x; + int _y; + int _z; + + MyStruct(int x) : _x(x) + { + } + + MyStruct(int x, int y) : _x(x), _y(y) + { + } + + MyStruct(int x, int y, int z) : _x(x), _y(y), _z() + { + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + int + + + void + + int + + + x + + + + + void + + int + + + int + + + x + + + y + + + + + void + + int + + + int + + + int + + + x + + + y + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ConversionTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + operator int() + { + return value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + return value; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DestructorTest() + { + var inputContents = @"struct MyStruct +{ + ~MyStruct() + { + } +}; +"; + + var expectedOutputContents = @" + + + + + void + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task InstanceTest() + { + var inputContents = @"struct MyStruct +{ + void MyVoidMethod(); + + int MyInt32Method() + { + return 0; + } + + void* MyVoidStarMethod() + { + return nullptr; + } +}; +"; + var callConv = "Cdecl"; + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN8MyStruct12MyVoidMethodEv" : "_ZN8MyStruct12MyVoidMethodEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + if (!Environment.Is64BitProcess) + { + callConv = "ThisCall"; + entryPoint = "?MyVoidMethod@MyStruct@@QAEXXZ"; + } + else + { + entryPoint = "?MyVoidMethod@MyStruct@@QEAAXXZ"; + } + } + + var expectedOutputContents = $@" + + + + + void + + + int + return 0; + + + void* + return null; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MemberCallTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + int MyFunction1() + { + return value; + } + + int MyFunction2() + { + return MyFunction1(); + } + + int MyFunction3() + { + return this->MyFunction1(); + } +}; + +int MyFunctionA(MyStruct x) +{ + return x.MyFunction1(); +} + +int MyFunctionB(MyStruct* x) +{ + return x->MyFunction2(); +} +"; + + var expectedOutputContents = @" + + + + + int + + + int + return value; + + + int + return MyFunction1(); + + + int + return this.MyFunction1(); + + + + + int + + MyStruct + + return x.MyFunction1(); + + + int + + MyStruct* + + return x->MyFunction2(); + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MemberTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + int MyFunction() + { + return value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + return value; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordTest() + { + var inputContents = @"struct MyStruct +{ + int Equals() { return 0; } + int Equals(int obj) { return 0; } + int Finalize() { return 0; } + int Finalize(int obj) { return 0; } + int GetHashCode() { return 0; } + int GetHashCode(int obj) { return 0; } + int GetType() { return 0; } + int GetType(int obj) { return 0; } + int MemberwiseClone() { return 0; } + int MemberwiseClone(int obj) { return 0; } + int ReferenceEquals() { return 0; } + int ReferenceEquals(int obj) { return 0; } + int ToString() { return 0; } + int ToString(int obj) { return 0; } +};"; + + var expectedOutputContents = $@" + + + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordVirtualTest() + { + var inputContents = @"struct MyStruct +{ + virtual int GetType(int obj) = 0; + virtual int GetType() = 0; + virtual int GetType(int objA, int objB) = 0; +};"; + + var callConv = "Cdecl"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + callConv = "ThisCall"; + } + + var expectedOutputContents = $@" + + + + + void** + + + int + + MyStruct* + + + int + + + + int + + MyStruct* + + + + int + + MyStruct* + + + int + + + int + + + + int + + int + + + return Marshal.GetDelegateForFunctionPointer<_GetType>((IntPtr)(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this), obj); + + + + int + + return Marshal.GetDelegateForFunctionPointer<_GetType1>((IntPtr)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this)); + + + + int + + int + + + int + + + return Marshal.GetDelegateForFunctionPointer<_GetType2>((IntPtr)(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this), objA, objB); + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task OperatorTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + MyStruct(int value) : value(value) + { + } + + MyStruct operator+(MyStruct rhs) + { + return MyStruct(value + rhs.value); + } +}; + +MyStruct operator-(MyStruct lhs, MyStruct rhs) +{ + return MyStruct(lhs.value - rhs.value); +} +"; + + var expectedOutputContents = @" + + + + + int + + + void + + int + + + value + + + + + MyStruct + + MyStruct + + return new MyStruct(value + rhs.value); + + + + + MyStruct + + MyStruct + + + MyStruct + + return new MyStruct(lhs.value - rhs.value); + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task OperatorCallTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + MyStruct(int value) : value(value) + { + } + + MyStruct operator+(MyStruct rhs) + { + return MyStruct(value + rhs.value); + } +}; + +MyStruct MyFunction1(MyStruct lhs, MyStruct rhs) +{ + return lhs + rhs; +} + +MyStruct operator-(MyStruct lhs, MyStruct rhs) +{ + return MyStruct(lhs.value - rhs.value); +} + +MyStruct MyFunction2(MyStruct lhs, MyStruct rhs) +{ + return lhs - rhs; +} +"; + + var expectedOutputContents = @" + + + + + int + + + void + + int + + + value + + + + + MyStruct + + MyStruct + + return new MyStruct(value + rhs.value); + + + + + MyStruct + + MyStruct + + + MyStruct + + return lhs.Add(rhs); + + + MyStruct + + MyStruct + + + MyStruct + + return new MyStruct(lhs.value - rhs.value); + + + MyStruct + + MyStruct + + + MyStruct + + return Subtract(lhs, rhs); + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task StaticTest() + { + var inputContents = @"struct MyStruct +{ + static void MyVoidMethod(); + + static int MyInt32Method() + { + return 0; + } + + static void* MyVoidStarMethod() + { + return nullptr; + } +}; +"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "?MyVoidMethod@MyStruct@@SAXXZ" : "_ZN8MyStruct12MyVoidMethodEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + entryPoint = $"_{entryPoint}"; + } + + var expectedOutputContents = $@" + + + + + void + + + int + return 0; + + + void* + return null; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ThisTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + int MyFunction() + { + return this->value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + return this.value; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnsafeDoesNotImpactDllImportTest() + { + var inputContents = @"struct MyStruct +{ + void* MyVoidStarMethod() + { + return nullptr; + } +}; + +void MyFunction();"; + + var expectedOutputContents = @" + + + + + void* + return null; + + + + + void + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task VirtualTest() + { + var inputContents = @"struct MyStruct +{ + virtual void MyVoidMethod() = 0; + + virtual char MyInt8Method() + { + return 0; + } + + virtual int MyInt32Method(); + + virtual void* MyVoidStarMethod() = 0; +}; +"; + + var callConv = "Cdecl"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + callConv = "ThisCall"; + } + + var expectedOutputContents = $@" + + + + + void** + + + void + + MyStruct* + + + + sbyte + + MyStruct* + + + + int + + MyStruct* + + + + void* + + MyStruct* + + + + void + + Marshal.GetDelegateForFunctionPointer<_MyVoidMethod>((IntPtr)(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this)); + + + + sbyte + + return Marshal.GetDelegateForFunctionPointer<_MyInt8Method>((IntPtr)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this)); + + + + int + + return Marshal.GetDelegateForFunctionPointer<_MyInt32Method>((IntPtr)(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this)); + + + + void* + + return Marshal.GetDelegateForFunctionPointer<_MyVoidStarMethod>((IntPtr)(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this)); + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/EnumDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/EnumDeclarationTest.cs new file mode 100644 index 00000000..1fbf5857 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/EnumDeclarationTest.cs @@ -0,0 +1,752 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestWindows_EnumDeclarationTest : EnumDeclarationTest + { + public override Task BasicTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicValueTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value1 = 1, + MyEnum_Value2, + MyEnum_Value3, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExcludeTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; +"; + + var expectedOutputContents = string.Empty; + + var excludedNames = new string[] { "MyEnum" }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task ExplicitTypedTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"enum MyEnum : {nativeType} +{{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}}; +"; + + var expectedOutputContents = $@" + + + + {EscapeXml(expectedManagedType)} + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExplicitTypedWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"enum MyEnum : {nativeType} +{{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}}; +"; + + var expectedOutputContents = $@" + + + + {EscapeXml(expectedManagedType)} + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RemapTest() + { + var inputContents = @"typedef enum _MyEnum : int +{ + MyEnum_Value1, + MyEnum_Value2, + MyEnum_Value3, +} MyEnum; +"; + + var expectedOutputContents = @" + + + + int + + int + + + int + + + int + + + + +"; + + var remappedNames = new Dictionary { ["_MyEnum"] = "MyEnum" }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task WithAttributeTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = 1, +}; +"; + + var expectedOutputContents = @" + + + Flags + + int + + int + + 1 + + + + + int + + int + + 1 + + + + + +"; + + var withAttributes = new Dictionary> + { + ["MyEnum1"] = new List() { "Flags" } + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withAttributes: withAttributes); + } + + public override Task WithAttributeStarTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = 1, +}; +"; + + var expectedOutputContents = @" + + + Flags + + int + + int + + 1 + + + + Flags + + int + + int + + 1 + + + + + +"; + + var withAttributes = new Dictionary> + { + ["*"] = new List() { "Flags" } + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withAttributes: withAttributes); + } + + public override Task WithAttributeStarPlusTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = 1, +}; +"; + + var expectedOutputContents = @" + + + Flags + + int + + int + + 1 + + + + Flags + EditorBrowsable(EditorBrowsableState.Never) + + int + + int + + 1 + + + + + +"; + + var withAttributes = new Dictionary> + { + ["*"] = new List() { "Flags" }, + ["MyEnum2"] = new List() { "EditorBrowsable(EditorBrowsableState.Never)" } + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withAttributes: withAttributes); + } + + public override Task WithNamespaceTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = MyEnum1_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + + int + + int + + MyEnum1_Value1 + + + + + +"; + + var withNamespaces = new Dictionary> + { + ["MyEnum1"] = new List() { "static ClangSharp.Test.MyEnum1" } + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withUsings: withNamespaces); + } + + public override Task WithNamespaceStarTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = MyEnum1_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + + int + + int + + MyEnum1_Value1 + + + + + +"; + + var withNamespaces = new Dictionary> + { + ["*"] = new List() { "static ClangSharp.Test.MyEnum1" } + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withUsings: withNamespaces); + } + + public override Task WithNamespaceStarPlusTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = MyEnum1_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + + int + + int + + MyEnum1_Value1 + + + + + +"; + + var withNamespaces = new Dictionary> + { + ["*"] = new List() { "static ClangSharp.Test.MyEnum1" }, + ["MyEnum2"] = new List() { "System" } + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withUsings: withNamespaces); + } + + public override Task WithCastToEnumType() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0 = (MyEnum) 10, + MyEnum_Value1 = (MyEnum) MyEnum_Value0, + MyEnum_Value2 = ((MyEnum) 10) + MyEnum_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + (int)(MyEnum)(10) + + + + int + + (int)(MyEnum)(MyEnum_Value0) + + + + int + + ((int)(MyEnum)(10)) + MyEnum_Value1 + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithMultipleEnumsTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value0 = 10, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value0 = MyEnum1_Value0, + MyEnum2_Value1 = MyEnum1_Value0 + (MyEnum1) 10, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 10 + + + + + int + + int + + MyEnum1_Value0 + + + + int + + MyEnum1_Value0 + (int)(MyEnum1)(10) + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithImplicitConversionTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2 = 0x80000000, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + + int + + + int + + + + int + + 0x80000000 + + + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithTypeTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; +"; + + var expectedOutputContents = @" + + + + uint + + uint + + + uint + + + uint + + + + +"; + + var withTypes = new Dictionary { + ["MyEnum"] = "uint" + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + + public override Task WithTypeAndImplicitConversionTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2 = 0x80000000, +}; +"; + + var expectedOutputContents = @" + + + + uint + + uint + + + uint + + + uint + + 0x80000000 + + + + + +"; + + var withTypes = new Dictionary + { + ["MyEnum"] = "uint" + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + + public override Task WithTypeStarTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value0 +}; + +enum MyEnum2 : int +{ + MyEnum2_Value0 +}; +"; + + var expectedOutputContents = @" + + + + uint + + uint + + + + uint + + uint + + + + +"; + + var withTypes = new Dictionary + { + ["*"] = "uint" + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + + public override Task WithTypeStarOverrideTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value0 +}; + +enum MyEnum2 : int +{ + MyEnum2_Value0 +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + + + uint + + uint + + + + +"; + + var withTypes = new Dictionary + { + ["*"] = "uint", + ["MyEnum1"] = "int", + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationBodyImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationBodyImportTest.cs new file mode 100644 index 00000000..7bfd6dd9 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationBodyImportTest.cs @@ -0,0 +1,2013 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Reflection.Emit; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestWindows_FunctionDeclarationBodyImportTest : FunctionDeclarationBodyImportTest + { + public override Task ArraySubscriptTest() + { + var inputContents = @"int MyFunction(int* pData, int index) +{ + return pData[index]; +} +"; + + var expectedOutputContents = @" + + + + + int + + int* + + + int + + return pData[index]; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicTest() + { + var inputContents = @"void MyFunction() +{ +} +"; + + var expectedOutputContents = @" + + + + + void + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BinaryOperatorBasicTest(string opcode) + { + var inputContents = $@"int MyFunction(int x, int y) +{{ + return x {opcode} y; +}} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + + int + + return x {EscapeXml(opcode)} y; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BinaryOperatorCompareTest(string opcode) + { + var inputContents = $@"bool MyFunction(int x, int y) +{{ + return x {opcode} y; +}} +"; + + var expectedOutputContents = $@" + + + + + bool + + int + + + int + + return x {EscapeXml(opcode)} y; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BinaryOperatorBooleanTest(string opcode) + { + var inputContents = $@"bool MyFunction(bool x, bool y) +{{ + return x {opcode} y; +}} +"; + + var expectedOutputContents = $@" + + + + + bool + + bool + + + bool + + return x {EscapeXml(opcode)} y; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BreakTest() + { + var inputContents = @"int MyFunction(int value) +{ + while (true) + { + break; + } + + return 0; +} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + while (true) + {{ + break; + }} + + return 0; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CallFunctionTest() + { + var inputContents = @"void MyCalledFunction() +{ +} + +void MyFunction() +{ + MyCalledFunction(); +} +"; + + var expectedOutputContents = $@" + + + + + void + + + + void + MyCalledFunction(); + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CallFunctionWithArgsTest() + { + var inputContents = @"void MyCalledFunction(int x, int y) +{ +} + +void MyFunction() +{ + MyCalledFunction(0, 1); +} +"; + + var expectedOutputContents = $@" + + + + + void + + int + + + int + + + + + void + MyCalledFunction(0, 1); + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CaseTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + { + case 0: + { + return 0; + } + + case 1: + case 2: + { + return 3; + } + } + + return -1; +} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + switch (value) + {{ + case 0: + {{ + return 0; + }} + + case 1: + case 2: + {{ + return 3; + }} + }} + + return -1; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CaseNoCompoundTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + { + case 0: + return 0; + + case 2: + case 3: + return 5; + } + + return -1; +} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + switch (value) + {{ + case 0: + {{ + return 0; + }} + + case 2: + case 3: + {{ + return 5; + }} + }} + + return -1; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CompareMultipleEnumTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; + +static inline int MyFunction(MyEnum x) +{ + return x == MyEnum_Value0 || + x == MyEnum_Value1 || + x == MyEnum_Value2; +} +"; + + var expectedOutputContents = $@" + + + + int + + int + + + int + + + int + + + + + int + + MyEnum + + return (x == MyEnum_Value0 || x == MyEnum_Value1 || x == MyEnum_Value2) ? 1 : 0; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ConditionalOperatorTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + return condition ? lhs : rhs; +} +"; + + var expectedOutputContents = $@" + + + + + int + + bool + + + int + + + int + + return condition ? lhs : rhs; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ContinueTest() + { + var inputContents = @"int MyFunction(int value) +{ + while (true) + { + continue; + } + + return 0; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + while (true) + { + continue; + } + + return 0; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CStyleFunctionalCastTest() + { + var inputContents = @"int MyFunction(float input) +{ + return (int)input; +} +"; + + var expectedOutputContents = @" + + + + + int + + float + + return (int)(input); + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxFunctionalCastTest() + { + var inputContents = @"int MyFunction(float input) +{ + return int(input); +} +"; + + var expectedOutputContents = @" + + + + + int + + float + + return (int)(input); + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxConstCastTest() + { + var inputContents = @"void* MyFunction(const void* input) +{ + return const_cast(input); +} +"; + + var expectedOutputContents = @" + + + + + void* + + void* + + return input; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxDynamicCastTest() + { + var inputContents = @"struct MyStructA +{ + virtual void MyMethod() = 0; +}; + +struct MyStructB : MyStructA { }; + +MyStructB* MyFunction(MyStructA* input) +{ + return dynamic_cast(input); +} +"; + + var callConv = "Cdecl"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + callConv = "ThisCall"; + } + + var expectedOutputContents = $@" + + + + + void** + + + void + + MyStructA* + + + + void + + Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))((MyStructA*)Unsafe.AsPointer(ref this)); + + + + + + void** + + + void + + MyStructB* + + + + void + + Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))((MyStructB*)Unsafe.AsPointer(ref this)); + + + + + + MyStructB* + + MyStructA* + + return (MyStructB*)(input); + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxReinterpretCastTest() + { + var inputContents = @"int* MyFunction(void* input) +{ + return reinterpret_cast(input); +} +"; + + var expectedOutputContents = @" + + + + + int* + + void* + + return (int*)(input); + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxStaticCastTest() + { + var inputContents = @"int* MyFunction(void* input) +{ + return static_cast(input); +} +"; + + var expectedOutputContents = @" + + + + + int* + + void* + + return (int*)(input); + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DeclTest() + { + var inputContents = @"\ +int MyFunction() +{ + int x = 0; + int y = 1, z = 2; + return x + y + z; +} +"; + + var expectedOutputContents = @" + + + + + int + int x = 0; + int y = 1, z = 2; + + return x + y + z; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DoTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + do + { + i++; + } + while (i < count); + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + do + { + i++; + } + while (i < count); + + return i; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DoNonCompoundTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + while (i < count) + i++; + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + while (i < count) + { + i++; + } + + return i; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ForTest() + { + var inputContents = @"int MyFunction(int count) +{ + for (int i = 0; i < count; i--) + { + i += 2; + } + + int x; + + for (x = 0; x < count; x--) + { + x += 2; + } + + x = 0; + + for (; x < count; x--) + { + x += 2; + } + + for (int i = 0;;i--) + { + i += 2; + } + + for (x = 0;;x--) + { + x += 2; + } + + for (int i = 0; i < count;) + { + i++; + } + + for (x = 0; x < count;) + { + x++; + } + + // x = 0; + // + // for (;; x--) + // { + // x += 2; + // } + + x = 0; + + for (; x < count;) + { + x++; + } + + for (int i = 0;;) + { + i++; + } + + for (x = 0;;) + { + x++; + } + + for (;;) + { + return -1; + } +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + for (int i = 0; i < count; i--) + { + i += 2; + } + + int x; + + for (x = 0; x < count; x--) + { + x += 2; + } + + x = 0; + for (; x < count; x--) + { + x += 2; + } + + for (int i = 0;; i--) + { + i += 2; + } + + for (x = 0;; x--) + { + x += 2; + } + + for (int i = 0; i < count;) + { + i++; + } + + for (x = 0; x < count;) + { + x++; + } + + x = 0; + for (; x < count;) + { + x++; + } + + for (int i = 0;;) + { + i++; + } + + for (x = 0;;) + { + x++; + } + + for (;;) + { + return -1; + } + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ForNonCompoundTest() + { + var inputContents = @"int MyFunction(int count) +{ + for (int i = 0; i < count; i--) + i += 2; + + int x; + + for (x = 0; x < count; x--) + x += 2; + + x = 0; + + for (; x < count; x--) + x += 2; + + for (int i = 0;;i--) + i += 2; + + for (x = 0;;x--) + x += 2; + + for (int i = 0; i < count;) + i++; + + for (x = 0; x < count;) + x++; + + // x = 0; + // + // for (;; x--) + // x += 2; + + x = 0; + + for (; x < count;) + x++; + + for (int i = 0;;) + i++; + + for (x = 0;;) + x++; + + for (;;) + return -1; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + for (int i = 0; i < count; i--) + { + i += 2; + } + + int x; + + for (x = 0; x < count; x--) + { + x += 2; + } + + x = 0; + for (; x < count; x--) + { + x += 2; + } + + for (int i = 0;; i--) + { + i += 2; + } + + for (x = 0;; x--) + { + x += 2; + } + + for (int i = 0; i < count;) + { + i++; + } + + for (x = 0; x < count;) + { + x++; + } + + x = 0; + for (; x < count;) + { + x++; + } + + for (int i = 0;;) + { + i++; + } + + for (x = 0;;) + { + x++; + } + + for (;;) + { + return -1; + } + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + if (condition) + { + return lhs; + } + + return rhs; +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + if (condition) + { + return lhs; + } + + return rhs; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfElseTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + if (condition) + { + return lhs; + } + else + { + return rhs; + } +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + if (condition) + { + return lhs; + } + else + { + return rhs; + } + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfElseIfTest() + { + var inputContents = @"int MyFunction(bool condition1, int a, int b, bool condition2, int c) +{ + if (condition1) + { + return a; + } + else if (condition2) + { + return b; + } + + return c; +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + + bool + + + int + + if (condition1) + { + return a; + } + else if (condition2) + { + return b; + } + + return c; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfElseNonCompoundTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + if (condition) + return lhs; + else + return rhs; +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + if (condition) + { + return lhs; + } + else + { + return rhs; + } + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task InitListForArrayTest() + { + var inputContents = @" +void MyFunction() +{ + int x[4] = { 1, 2, 3, 4 }; + int y[4] = { 1, 2, 3 }; + int z[] = { 1, 2 }; +} +"; + + var expectedOutputContents = @" + + + + + void + int[] x = new int[4] + { + 1, + 2, + 3, + 4, + }; + int[] y = new int[4] + { + 1, + 2, + 3, + default, + }; + int[] z = new int[2] + { + 1, + 2, + }; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task InitListForRecordDeclTest() + { + var inputContents = @"struct MyStruct +{ + float x; + float y; + float z; + float w; +}; + +MyStruct MyFunction1() +{ + return { 1.0f, 2.0f, 3.0f, 4.0f }; +} + +MyStruct MyFunction2() +{ + return { 1.0f, 2.0f, 3.0f }; +} +"; + + var expectedOutputContents = @" + + + + + float + + + float + + + float + + + float + + + + + MyStruct + return new MyStruct + { + x = 1.0f, + y = 2.0f, + z = 3.0f, + w = 4.0f, + }; + + + MyStruct + return new MyStruct + { + x = 1.0f, + y = 2.0f, + z = 3.0f, + }; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MemberTest() + { + var inputContents = @"struct MyStruct +{ + int value; +}; + +int MyFunction1(MyStruct instance) +{ + return instance.value; +} + +int MyFunction2(MyStruct* instance) +{ + return instance->value; +} +"; + + var expectedOutputContents = @" + + + + + int + + + + + int + + MyStruct + + return instance.value; + + + int + + MyStruct* + + return instance->value; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RefToPtrTest() + { + var inputContents = @"struct MyStruct { + int value; +}; + +bool MyFunction(const MyStruct& lhs, const MyStruct& rhs) +{ + return lhs.value == rhs.value; +} +"; + + var expectedOutputContents = @" + + + + + int + + + + + bool + + MyStruct* + + + MyStruct* + + return lhs->value == rhs->value; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnCXXNullPtrTest() + { + var inputContents = @"void* MyFunction() +{ + return nullptr; +} +"; + + var expectedOutputContents = @" + + + + + void* + return null; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnCXXBooleanLiteralTest(string value) + { + var inputContents = $@"bool MyFunction() +{{ + return {value}; +}} +"; + + var expectedOutputContents = $@" + + + + + bool + return {value}; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnFloatingLiteralDoubleTest(string value) + { + var inputContents = $@"double MyFunction() +{{ + return {value}; +}} +"; + + var expectedOutputContents = $@" + + + + + double + return {value}; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnFloatingLiteralSingleTest(string value) + { + var inputContents = $@"float MyFunction() +{{ + return {value}; +}} +"; + + var expectedOutputContents = $@" + + + + + float + return {value}; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnEmptyTest() + { + var inputContents = @"void MyFunction() +{ + return; +} +"; + + var expectedOutputContents = @" + + + + + void + return; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnIntegerLiteralInt32Test() + { + var inputContents = @"int MyFunction() +{ + return -1; +} +"; + + var expectedOutputContents = @" + + + + + int + return -1; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task AccessUnionMemberTest() + { + var inputContents = @"union MyUnion +{ + struct { int a; }; +}; + +void MyFunction() +{ + MyUnion myUnion; + myUnion.a = 10; +} +"; + + var expectedOutputContents = @" + + + + + _Anonymous_e__Struct + + + ref int + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.a, 1)); + + + + + int + + + + + + void + MyUnion myUnion = new MyUnion(); + + myUnion.Anonymous.a = 10; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnStructTest() + { + var inputContents = @"struct MyStruct +{ + double r; + double g; + double b; +}; + +MyStruct MyFunction() +{ + MyStruct myStruct; + return myStruct; +} +"; + + var expectedOutputContents = @" + + + + + double + + + double + + + double + + + + + MyStruct + MyStruct myStruct = new MyStruct(); + + return myStruct; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SwitchTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + { + default: + { + return 0; + } + } +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + switch (value) + { + default: + { + return 0; + } + } + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SwitchNonCompoundTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + default: + { + return 0; + } + + switch (value) + default: + return 0; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + switch (value) + { + default: + { + return 0; + } + } + + switch (value) + { + default: + { + return 0; + } + } + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorAddrOfTest() + { + var inputContents = @"int* MyFunction(int value) +{ + return &value; +} +"; + + var expectedOutputContents = @" + + + + + int* + + int + + return &value; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorDerefTest() + { + var inputContents = @"int MyFunction(int* value) +{ + return *value; +} +"; + + var expectedOutputContents = @" + + + + + int + + int* + + return *value; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorLogicalNotTest() + { + var inputContents = @"bool MyFunction(bool value) +{ + return !value; +} +"; + + var expectedOutputContents = @" + + + + + bool + + bool + + return !value; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorPostfixTest(string opcode) + { + var inputContents = $@"int MyFunction(int value) +{{ + return value{opcode}; +}} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + return value{opcode}; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorPrefixTest(string opcode) + { + var inputContents = $@"int MyFunction(int value) +{{ + return {opcode}value; +}} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + return {opcode}value; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WhileTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + while (i < count) + { + i++; + } + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + while (i < count) + { + i++; + } + + return i; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WhileNonCompoundTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + while (i < count) + i++; + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + while (i < count) + { + i++; + } + + return i; + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationDllImportTest.cs new file mode 100644 index 00000000..55a21869 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationDllImportTest.cs @@ -0,0 +1,399 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestWindows_FunctionDeclarationDllImportTest : FunctionDeclarationDllImportTest + { + public override Task BasicTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ArrayParameterTest() + { + var inputContents = @"void MyFunction(const float color[4]);"; + + var expectedOutputContents = @" + + + + + void + + float* + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FunctionPointerParameterTest() + { + var inputContents = @"void MyFunction(void (*callback)());"; + + var expectedOutputContents = @" + + + + + void + + IntPtr + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) + { + var inputContents = @$"template struct MyTemplate; + +void MyFunction(MyTemplate<{nativeType}> myStruct);"; + + var expectedOutputContents = $@" + + + + + void + + MyTemplate<{expectedManagedType}> + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: new[] { "MyTemplate" }); + } + + public override Task TemplateMemberTest() + { + var inputContents = @$"template struct MyTemplate +{{ +}}; + +struct MyStruct +{{ + MyTemplate a; +}}; +"; + + var expectedOutputContents = $@" + + + + + MyTemplate<IntPtr> + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: new[] { "MyTemplate" }); + } + + public override Task NoLibraryPathTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty); + } + + public override Task WithLibraryPathTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + var withLibraryPaths = new Dictionary + { + ["MyFunction"] = "ClangSharpPInvokeGenerator" + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty, withLibraryPaths: withLibraryPaths); + } + + public override Task WithLibraryPathStarTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + var withLibraryPaths = new Dictionary + { + ["*"] = "ClangSharpPInvokeGenerator" + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty, withLibraryPaths: withLibraryPaths); + } + + public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) + { + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + + var expectedOutputContents = $@" + + + + + void + + {expectedManagedType} + + {expectedManagedInit} + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) + { + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + + var expectedOutputContents = $@" + + + + + void + + {expectedManagedType} + + {expectedManagedInit} + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithCallConvTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withCallConvs = new Dictionary { + ["MyFunction1"] = "Winapi" + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withCallConvs: withCallConvs); + } + + public override Task WithCallConvStarTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withCallConvs = new Dictionary + { + ["*"] = "Winapi" + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withCallConvs: withCallConvs); + } + + public override Task WithCallConvStarOverrideTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withCallConvs = new Dictionary + { + ["*"] = "Winapi", + ["MyFunction2"] = "StdCall" + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withCallConvs: withCallConvs); + } + + public override Task WithSetLastErrorTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withSetLastErrors = new string[] + { + "MyFunction1" + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withSetLastErrors: withSetLastErrors); + } + + public override Task WithSetLastErrorStarTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withSetLastErrors = new string[] + { + "*" + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, withSetLastErrors: withSetLastErrors); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionPointerDeclarationTest.cs new file mode 100644 index 00000000..8db6f1fa --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionPointerDeclarationTest.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestWindows_FunctionPointerDeclarationTest : FunctionPointerDeclarationTest + { + public override Task BasicTest() + { + var inputContents = @"typedef void (*Callback)();"; + + var expectedOutputContents = @" + + + + void + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/StructDeclarationTest.cs new file mode 100644 index 00000000..a69c2d25 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/StructDeclarationTest.cs @@ -0,0 +1,1485 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestWindows_StructDeclarationTest : StructDeclarationTest + { + public override Task BasicTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicTestInCMode(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef struct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}} MyStruct; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + } + + public override Task BasicWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BitfieldTest() + { + var inputContents = @"struct MyStruct1 +{ + unsigned int o0_b0_24 : 24; + unsigned int o4_b0_16 : 16; + unsigned int o4_b16_3 : 3; + int o4_b19_3 : 3; + unsigned char o8_b0_1 : 1; + int o12_b0_1 : 1; + int o12_b1_1 : 1; +}; + +struct MyStruct2 +{ + unsigned int o0_b0_1 : 1; + int x; + unsigned int o8_b0_1 : 1; +}; + +struct MyStruct3 +{ + unsigned int o0_b0_1 : 1; + unsigned int o0_b1_1 : 1; +}; +"; + + var expectedOutputContents = @" + + + + + uint + + + uint + + return _bitfield1 & 0xFFFFFFu; + + + + _bitfield1 = (_bitfield1 & ~0xFFFFFFu) | (value & 0xFFFFFFu); + + + + uint + + + uint + + return _bitfield2 & 0xFFFFu; + + + + _bitfield2 = (_bitfield2 & ~0xFFFFu) | (value & 0xFFFFu); + + + + uint + + return (_bitfield2 >> 16) & 0x7u; + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 16)) | ((value & 0x7u) << 16); + + + + int + + return (int)((_bitfield2 >> 19) & 0x7u); + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 19)) | (uint)((value & 0x7) << 19); + + + + byte + + + byte + + return (byte)(_bitfield3 & 0x1u); + + + + _bitfield3 = (byte)((_bitfield3 & ~0x1u) | (value & 0x1u)); + + + + int + + + int + + return _bitfield4 & 0x1; + + + + _bitfield4 = (_bitfield4 & ~0x1) | (value & 0x1); + + + + int + + return (_bitfield4 >> 1) & 0x1; + + + + _bitfield4 = (_bitfield4 & ~(0x1 << 1)) | ((value & 0x1) << 1); + + + + + + uint + + + uint + + return _bitfield1 & 0x1u; + + + + _bitfield1 = (_bitfield1 & ~0x1u) | (value & 0x1u); + + + + int + + + uint + + + uint + + return _bitfield2 & 0x1u; + + + + _bitfield2 = (_bitfield2 & ~0x1u) | (value & 0x1u); + + + + + + uint + + + uint + + return _bitfield & 0x1u; + + + + _bitfield = (_bitfield & ~0x1u) | (value & 0x1u); + + + + uint + + return (_bitfield >> 1) & 0x1u; + + + + _bitfield = (_bitfield & ~(0x1u << 1)) | ((value & 0x1u) << 1); + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExcludeTest() + { + var inputContents = "typedef struct MyStruct MyStruct;"; + var expectedOutputContents = string.Empty; + + var excludedNames = new string[] { "MyStruct" }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task FixedSizedBufferNonPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +struct MyOtherStruct +{{ + MyStruct c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + return ref AsSpan()[index]; + + + + Span<MyStruct> + MemoryMarshal.CreateSpan(ref e0, 3); + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +struct MyOtherStruct +{{ + MyStruct c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + return ref AsSpan()[index]; + + + + Span<MyStruct> + MemoryMarshal.CreateSpan(ref e0, 24); + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +typedef MyStruct MyBuffer[3]; + +struct MyOtherStruct +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + return ref AsSpan()[index]; + + + + Span<MyStruct> + MemoryMarshal.CreateSpan(ref e0, 3); + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +struct MyOtherStruct +{{ + MyStruct c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + return ref AsSpan()[index]; + + + + Span<MyStruct> + MemoryMarshal.CreateSpan(ref e0, 3); + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPointerTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + ref {expectedManagedType} + + int + + + fixed ({expectedManagedType}* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyBuffer[3]; + +struct MyStruct +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task GuidTest() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Non-Windows doesn't support __declspec(uuid("")) + return Task.CompletedTask; + } + + var inputContents = $@"#define DECLSPEC_UUID(x) __declspec(uuid(x)) + +struct __declspec(uuid(""00000000-0000-0000-C000-000000000046"")) MyStruct1 +{{ + int x; +}}; + +struct DECLSPEC_UUID(""00000000-0000-0000-C000-000000000047"") MyStruct2 +{{ + int x; +}}; +"; + + var expectedOutputContents = $@" + + + + + int + + + + + int + + + + + + + + +"; + + var excludedNames = new string[] { "DECLSPEC_UUID" }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task InheritanceTest() + { + var inputContents = @"struct MyStruct1A +{ + int x; + int y; +}; + +struct MyStruct1B +{ + int x; + int y; +}; + +struct MyStruct2 : MyStruct1A, MyStruct1B +{ + int z; + int w; +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + + + int + + + int + + + + + MyStruct1A + + + MyStruct1B + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column) + { + var inputContents = $@"typedef union {{ + {nativeType} value; +}} MyUnion; + +struct MyStruct +{{ + {nativeType} x; + {nativeType} y; + + struct + {{ + {nativeType} z; + + struct + {{ + {nativeType} value; + }} w; + + MyUnion u; + {nativeType} buffer1[4]; + MyUnion buffer2[4]; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + {expectedManagedType} + + + {expectedManagedType} + + + _Anonymous_e__Struct + + + ref {expectedManagedType} + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.z, 1)); + + + + ref _Anonymous_e__Struct._w_e__Struct + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.w, 1)); + + + + ref MyUnion + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.u, 1)); + + + + Span<{expectedManagedType}> + + return MemoryMarshal.CreateSpan(ref Anonymous.buffer1[0], 4); + + + + Span<MyUnion> + + return Anonymous.buffer2.AsSpan(); + + + + + {expectedManagedType} + + + _w_e__Struct + + + MyUnion + + + {expectedManagedType} + + + MyUnion + + + + {expectedManagedType} + + + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + return ref AsSpan()[index]; + + + + Span<MyUnion> + MemoryMarshal.CreateSpan(ref e0, 4); + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedAnonymousWithBitfieldTest() + { + var inputContents = @"struct MyStruct +{ + int x; + int y; + + struct + { + int z; + + struct + { + int w; + int o0_b0_16 : 16; + int o0_b16_4 : 4; + }; + }; +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + _Anonymous_e__Struct + + + ref int + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.z, 1)); + + + + ref int + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.Anonymous.w, 1)); + + + + int + + return Anonymous.Anonymous.o0_b0_16; + + + Anonymous.Anonymous.o0_b0_16 = value; + + + + int + + return Anonymous.Anonymous.o0_b16_4; + + + Anonymous.Anonymous.o0_b16_4 = value; + + + + + int + + + _Anonymous_e__Struct + + + + int + + + int + + + int + + return _bitfield & 0xFFFF; + + + + _bitfield = (_bitfield & ~0xFFFF) | (value & 0xFFFF); + + + + int + + return (_bitfield >> 16) & 0xF; + + + + _bitfield = (_bitfield & ~(0xF << 16)) | ((value & 0xF) << 16); + + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + struct MyNestedStruct + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + struct MyNestedStruct + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordTest() + { + var inputContents = @"struct MyStruct +{ + int Equals; + int Finalize; + int GetHashCode; + int GetType; + int MemberwiseClone; + int ReferenceEquals; + int ToString; +};"; + + var expectedOutputContents = $@" + + + + + int + + + int + + + int + + + int + + + int + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NoDefinitionTest() + { + var inputContents = "typedef struct MyStruct MyStruct;"; + + var expectedOutputContents = $@" + + + + + +"; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfTest() + { + var inputContents = @"struct example_s { + example_s* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfViaTypedefTest() + { + var inputContents = @"typedef struct example_s example_t; + +struct example_s { + example_t* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RemapTest() + { + var inputContents = "typedef struct _MyStruct MyStruct;"; + + var expectedOutputContents = $@" + + + + + +"; + + var remappedNames = new Dictionary { ["_MyStruct"] = "MyStruct" }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task RemapNestedAnonymousTest() + { + var inputContents = @"struct MyStruct +{ + double r; + double g; + double b; + + struct + { + double a; + }; +};"; + + var expectedOutputContents = @" + + + + + double + + + double + + + double + + + _Anonymous_e__Struct + + + ref double + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.a, 1)); + + + + + double + + + + + +"; + + var remappedNames = new Dictionary { + ["__AnonymousField_ClangUnsavedFile_L7_C5"] = "Anonymous", + ["__AnonymousRecord_ClangUnsavedFile_L7_C5"] = "_Anonymous_e__Struct" + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task SkipNonDefinitionTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef struct MyStruct MyStruct; + +struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionPointerTest() + { + var inputContents = @"typedef struct MyStruct* MyStructPtr; +typedef struct MyStruct& MyStructRef; +"; + + var expectedOutputContents = @" + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef struct MyStruct MyStruct; + +struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task TypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyTypedefAlias; + +struct MyStruct +{{ + MyTypedefAlias r; + MyTypedefAlias g; + MyTypedefAlias b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UsingDeclarationTest() + { + var inputContents = @"struct MyStruct1A +{ + void MyMethod() { } +}; + +struct MyStruct1B : MyStruct1A +{ + using MyStruct1A::MyMethod; +}; +"; + + var expectedOutputContents = @" + + + + + void + + + + + + void + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs new file mode 100644 index 00000000..7133c8d8 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs @@ -0,0 +1,1340 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestWindows_UnionDeclarationTest : UnionDeclarationTest + { + public override Task BasicTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicTestInCMode(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef union +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}} MyUnion; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + } + + public override Task BasicWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BitfieldTest() + { + var inputContents = @"union MyUnion1 +{ + unsigned int o0_b0_24 : 24; + unsigned int o4_b0_16 : 16; + unsigned int o4_b16_3 : 3; + int o4_b19_3 : 3; + unsigned char o8_b0_1 : 1; + int o12_b0_1 : 1; + int o12_b1_1 : 1; +}; + +union MyUnion2 +{ + unsigned int o0_b0_1 : 1; + int x; + unsigned int o8_b0_1 : 1; +}; + +union MyUnion3 +{ + unsigned int o0_b0_1 : 1; + unsigned int o0_b1_1 : 1; +}; +"; + + string expectedPack = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ", Pack = 1" : ""; + + var expectedOutputContents = $@" + + + + + uint + + + uint + + return _bitfield1 & 0xFFFFFFu; + + + + _bitfield1 = (_bitfield1 & ~0xFFFFFFu) | (value & 0xFFFFFFu); + + + + uint + + + uint + + return _bitfield2 & 0xFFFFu; + + + + _bitfield2 = (_bitfield2 & ~0xFFFFu) | (value & 0xFFFFu); + + + + uint + + return (_bitfield2 >> 16) & 0x7u; + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 16)) | ((value & 0x7u) << 16); + + + + int + + return (int)((_bitfield2 >> 19) & 0x7u); + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 19)) | (uint)((value & 0x7) << 19); + + + + byte + + + byte + + return (byte)(_bitfield3 & 0x1u); + + + + _bitfield3 = (byte)((_bitfield3 & ~0x1u) | (value & 0x1u)); + + + + int + + + int + + return _bitfield4 & 0x1; + + + + _bitfield4 = (_bitfield4 & ~0x1) | (value & 0x1); + + + + int + + return (_bitfield4 >> 1) & 0x1; + + + + _bitfield4 = (_bitfield4 & ~(0x1 << 1)) | ((value & 0x1) << 1); + + + + + + uint + + + uint + + return _bitfield1 & 0x1u; + + + + _bitfield1 = (_bitfield1 & ~0x1u) | (value & 0x1u); + + + + int + + + uint + + + uint + + return _bitfield2 & 0x1u; + + + + _bitfield2 = (_bitfield2 & ~0x1u) | (value & 0x1u); + + + + + + uint + + + uint + + return _bitfield & 0x1u; + + + + _bitfield = (_bitfield & ~0x1u) | (value & 0x1u); + + + + uint + + return (_bitfield >> 1) & 0x1u; + + + + _bitfield = (_bitfield & ~(0x1u << 1)) | ((value & 0x1u) << 1); + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExcludeTest() + { + var inputContents = "typedef union MyUnion MyUnion;"; + var expectedOutputContents = string.Empty; + + var excludedNames = new string[] { "MyUnion" }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task FixedSizedBufferNonPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +union MyOtherUnion +{{ + MyUnion c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + return ref AsSpan()[index]; + + + + Span<MyUnion> + MemoryMarshal.CreateSpan(ref e0, 3); + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +union MyOtherUnion +{{ + MyUnion c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + return ref AsSpan()[index]; + + + + Span<MyUnion> + MemoryMarshal.CreateSpan(ref e0, 24); + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +typedef MyUnion MyBuffer[3]; + +union MyOtherUnion +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + return ref AsSpan()[index]; + + + + Span<MyUnion> + MemoryMarshal.CreateSpan(ref e0, 3); + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +union MyOtherUnion +{{ + MyUnion c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + return ref AsSpan()[index]; + + + + Span<MyUnion> + MemoryMarshal.CreateSpan(ref e0, 3); + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPointerTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + ref {expectedManagedType} + + int + + + fixed ({expectedManagedType}* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyBuffer[3]; + +union MyUnion +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + public override Task GuidTest() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Non-Windows doesn't support __declspec(uuid("")) + return Task.CompletedTask; + } + + var inputContents = $@"#define DECLSPEC_UUID(x) __declspec(uuid(x)) + +union __declspec(uuid(""00000000-0000-0000-C000-000000000046"")) MyUnion1 +{{ + int x; +}}; + +union DECLSPEC_UUID(""00000000-0000-0000-C000-000000000047"") MyUnion2 +{{ + int x; +}}; +"; + + var expectedOutputContents = $@" + + + + + int + + + + + int + + + + + + + + +"; + + var excludedNames = new string[] { "DECLSPEC_UUID" }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column) + { + var inputContents = $@"typedef struct {{ + {nativeType} value; +}} MyStruct; + +union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + union + {{ + {nativeType} a; + + MyStruct s; + + {nativeType} buffer[4]; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + _Anonymous_e__Union + + + ref {expectedManagedType} + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.a, 1)); + + + + ref MyStruct + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.s, 1)); + + + + Span<{expectedManagedType}> + + return MemoryMarshal.CreateSpan(ref Anonymous.buffer[0], 4); + + + + + {expectedManagedType} + + + MyStruct + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedAnonymousWithBitfieldTest() + { + var inputContents = @"union MyUnion +{ + int x; + int y; + + union + { + int z; + + union + { + int w; + int o0_b0_16 : 16; + int o0_b16_4 : 4; + }; + }; +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + _Anonymous_e__Union + + + ref int + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.z, 1)); + + + + ref int + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.Anonymous.w, 1)); + + + + int + + return Anonymous.Anonymous.o0_b0_16; + + + Anonymous.Anonymous.o0_b0_16 = value; + + + + int + + return Anonymous.Anonymous.o0_b16_4; + + + Anonymous.Anonymous.o0_b16_4 = value; + + + + + int + + + _Anonymous_e__Union + + + + int + + + int + + + int + + return _bitfield & 0xFFFF; + + + + _bitfield = (_bitfield & ~0xFFFF) | (value & 0xFFFF); + + + + int + + return (_bitfield >> 16) & 0xF; + + + + _bitfield = (_bitfield & ~(0xF << 16)) | ((value & 0xF) << 16); + + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + + public override Task NestedTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + union MyNestedUnion + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + union MyNestedUnion + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordTest() + { + var inputContents = @"union MyUnion +{ + int Equals; + int Finalize; + int GetHashCode; + int GetType; + int MemberwiseClone; + int ReferenceEquals; + int ToString; +};"; + + var expectedOutputContents = $@" + + + + + int + + + int + + + int + + + int + + + int + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NoDefinitionTest() + { + var inputContents = "typedef union MyUnion MyUnion;"; + + var expectedOutputContents = $@" + + + + + +"; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfTest() + { + var inputContents = @"union example_s { + example_s* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfViaTypedefTest() + { + var inputContents = @"typedef union example_s example_t; + +union example_s { + example_t* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RemapTest() + { + var inputContents = "typedef union _MyUnion MyUnion;"; + + var expectedOutputContents = $@" + + + + + +"; + + var remappedNames = new Dictionary { ["_MyUnion"] = "MyUnion" }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task RemapNestedAnonymousTest() + { + var inputContents = @"union MyUnion +{ + double r; + double g; + double b; + + union + { + double a; + }; +};"; + + var expectedOutputContents = @" + + + + + double + + + double + + + double + + + _Anonymous_e__Union + + + ref double + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.a, 1)); + + + + + double + + + + + +"; + + var remappedNames = new Dictionary { + ["__AnonymousField_ClangUnsavedFile_L7_C5"] = "Anonymous", + ["__AnonymousRecord_ClangUnsavedFile_L7_C5"] = "_Anonymous_e__Union" + }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task SkipNonDefinitionTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef union MyUnion MyUnion; + +union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionPointerTest() + { + var inputContents = @"typedef union MyUnion* MyUnionPtr; +typedef union MyUnion& MyUnionRef; +"; + + var expectedOutputContents = @" + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef union MyUnion MyUnion; + +union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task TypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyTypedefAlias; + +union MyUnion +{{ + MyTypedefAlias r; + MyTypedefAlias g; + MyTypedefAlias b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/VarDeclarationTest.cs new file mode 100644 index 00000000..957a9aa0 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/VarDeclarationTest.cs @@ -0,0 +1,373 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestWindows_VarDeclarationTest : VarDeclarationTest + { + public override Task BasicTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"{nativeType} MyVariable = 0;"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + 0 + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"{nativeType} MyVariable = 0;"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + 0 + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task GuidMacroTest() + { + var inputContents = $@"struct GUID {{ + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; +}}; + +const GUID IID_IUnknown = {{ 0x00000000, 0x0000, 0x0000, {{ 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 }} }}; +"; + + var expectedOutputContents = $@" + + + + + Guid + + new Guid(0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46) + + + + + +"; + var excludedNames = new string[] { "GUID" }; + var remappedNames = new Dictionary { ["GUID"] = "Guid" }; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames, remappedNames: remappedNames); + } + + public override Task MacroTest(string nativeValue, string expectedManagedType, string expectedManagedValue) + { + var inputContents = $@"#define MyMacro1 {nativeValue} +#define MyMacro2 MyMacro1"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + {expectedManagedValue} + + + + {expectedManagedType} + + {expectedManagedValue} + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MultilineMacroTest() + { + var inputContents = $@"#define MyMacro1 0 + \ +1"; + + var expectedOutputContents = $@" + + + + + int + + 0 + 1 + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NoInitializerTest(string nativeType) + { + var inputContents = $@"{nativeType} MyVariable;"; + var expectedOutputContents = ""; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task Utf8StringLiteralMacroTest() + { + var inputContents = $@"#define MyMacro1 ""Test"""; + + var expectedOutputContents = $@" + + + + + ReadOnlySpan<byte> + + new byte[] {{ 0x54, 0x65, 0x73, 0x74, 0x00 }} + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task Utf16StringLiteralMacroTest() + { + var inputContents = $@"#define MyMacro1 u""Test"""; + + var expectedOutputContents = $@" + + + + + string + + ""Test"" + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WideStringLiteralConstTest() + { + var inputContents = $@"const wchar_t MyConst1[] = L""Test"";"; + + var expectedOutputContents = $@" + + + + + string + + ""Test"" + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task StringLiteralConstTest() + { + var inputContents = $@"const char MyConst1[] = ""Test"";"; + + var expectedOutputContents = $@" + + + + + ReadOnlySpan<byte> + + new byte[] {{ 0x54, 0x65, 0x73, 0x74, 0x00 }} + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedConversionMacroTest() + { + var inputContents = $@"#define MyMacro1 (long)0x80000000L +#define MyMacro2 (int)0x80000000"; + + var expectedOutputContents = $@" + + + + + int + + + + (int)(0x80000000) + + + + + + int + + + + (int)(0x80000000) + + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedFunctionLikeCastMacroTest() + { + var inputContents = $@"#define MyMacro1 unsigned(-1)"; + + var expectedOutputContents = $@" + + + + + uint + + + + (uint)(-1) + + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedConversionMacroTest2() + { + var inputContents = $@"#define MyMacro1(x, y, z) ((int)(((unsigned long)(x)<<31) | ((unsigned long)(y)<<16) | ((unsigned long)(z)))) +#define MyMacro2(n) MyMacro1(1, 2, n) +#define MyMacro3 MyMacro2(3)"; + + var expectedOutputContents = $@" + + + + + int + + + ((int)(((uint)(1) << 31) | ((uint)(2) << 16) | ((uint)(3)))) + + + + + + +"; + + var excludedNames = new string[] { "MyMacro1", "MyMacro2" }; + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task UncheckedPointerMacroTest() + { + var inputContents = $@"#define Macro1 ((int*) -1)"; + + var expectedOutputContents = $@" + + + + + int* + + + ((int*)(-1)) + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedReinterpretCastMacroTest() + { + var inputContents = $@"#define Macro1 reinterpret_cast(-1)"; + + var expectedOutputContents = $@" + + + + + int* + + + + (int*)(-1) + + + + + + + +"; + + return ValidateGeneratedXmlLatestWindowsBindingsAsync(inputContents, expectedOutputContents); + } + } +} From d08cd88e54c074c09566a7255caa4da158a7b18d Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sat, 20 Mar 2021 17:58:06 -0700 Subject: [PATCH 2/4] Adding XmlCompatibleWindows tests --- .../CXXMethodDeclarationTest.cs | 933 ++++++++ .../EnumDeclarationTest.cs | 752 ++++++ .../FunctionDeclarationBodyImportTest.cs | 2022 +++++++++++++++++ .../FunctionDeclarationDllImportTest.cs | 399 ++++ .../FunctionPointerDeclarationTest.cs | 26 + .../StructDeclarationTest.cs | 1504 ++++++++++++ .../UnionDeclarationTest.cs | 1354 +++++++++++ .../VarDeclarationTest.cs | 373 +++ 8 files changed, 7363 insertions(+) create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/EnumDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationBodyImportTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationDllImportTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionPointerDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/StructDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/VarDeclarationTest.cs diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs new file mode 100644 index 00000000..da367060 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/CXXMethodDeclarationTest.cs @@ -0,0 +1,933 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleWindows_CXXMethodDeclarationTest : CXXMethodDeclarationTest + { + public override Task ConstructorTest() + { + var inputContents = @"struct MyStruct +{ + int _value; + + MyStruct(int value) + { + _value = value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + void + + int + + _value = value; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ConstructorWithInitializeTest() + { + var inputContents = @"struct MyStruct +{ + int _x; + int _y; + int _z; + + MyStruct(int x) : _x(x) + { + } + + MyStruct(int x, int y) : _x(x), _y(y) + { + } + + MyStruct(int x, int y, int z) : _x(x), _y(y), _z() + { + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + int + + + void + + int + + + x + + + + + void + + int + + + int + + + x + + + y + + + + + void + + int + + + int + + + int + + + x + + + y + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ConversionTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + operator int() + { + return value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + return value; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DestructorTest() + { + var inputContents = @"struct MyStruct +{ + ~MyStruct() + { + } +}; +"; + + var expectedOutputContents = @" + + + + + void + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task InstanceTest() + { + var inputContents = @"struct MyStruct +{ + void MyVoidMethod(); + + int MyInt32Method() + { + return 0; + } + + void* MyVoidStarMethod() + { + return nullptr; + } +}; +"; + var callConv = "Cdecl"; + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN8MyStruct12MyVoidMethodEv" : "_ZN8MyStruct12MyVoidMethodEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + if (!Environment.Is64BitProcess) + { + callConv = "ThisCall"; + entryPoint = "?MyVoidMethod@MyStruct@@QAEXXZ"; + } + else + { + entryPoint = "?MyVoidMethod@MyStruct@@QEAAXXZ"; + } + } + + var expectedOutputContents = $@" + + + + + void + + + int + return 0; + + + void* + return null; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MemberCallTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + int MyFunction1() + { + return value; + } + + int MyFunction2() + { + return MyFunction1(); + } + + int MyFunction3() + { + return this->MyFunction1(); + } +}; + +int MyFunctionA(MyStruct x) +{ + return x.MyFunction1(); +} + +int MyFunctionB(MyStruct* x) +{ + return x->MyFunction2(); +} +"; + + var expectedOutputContents = @" + + + + + int + + + int + return value; + + + int + return MyFunction1(); + + + int + return this.MyFunction1(); + + + + + int + + MyStruct + + return x.MyFunction1(); + + + int + + MyStruct* + + return x->MyFunction2(); + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MemberTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + int MyFunction() + { + return value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + return value; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordTest() + { + var inputContents = @"struct MyStruct +{ + int Equals() { return 0; } + int Equals(int obj) { return 0; } + int Finalize() { return 0; } + int Finalize(int obj) { return 0; } + int GetHashCode() { return 0; } + int GetHashCode(int obj) { return 0; } + int GetType() { return 0; } + int GetType(int obj) { return 0; } + int MemberwiseClone() { return 0; } + int MemberwiseClone(int obj) { return 0; } + int ReferenceEquals() { return 0; } + int ReferenceEquals(int obj) { return 0; } + int ToString() { return 0; } + int ToString(int obj) { return 0; } +};"; + + var expectedOutputContents = $@" + + + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordVirtualTest() + { + var inputContents = @"struct MyStruct +{ + virtual int GetType(int obj) = 0; + virtual int GetType() = 0; + virtual int GetType(int objA, int objB) = 0; +};"; + + var callConv = "Cdecl"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + callConv = "ThisCall"; + } + + var expectedOutputContents = $@" + + + + + void** + + + int + + MyStruct* + + + int + + + + int + + MyStruct* + + + + int + + MyStruct* + + + int + + + int + + + + int + + int + + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType>((IntPtr)(lpVtbl[0]))(pThis, obj); + }} + + + + int + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType1>((IntPtr)(lpVtbl[1]))(pThis); + }} + + + + int + + int + + + int + + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType2>((IntPtr)(lpVtbl[2]))(pThis, objA, objB); + }} + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task OperatorTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + MyStruct(int value) : value(value) + { + } + + MyStruct operator+(MyStruct rhs) + { + return MyStruct(value + rhs.value); + } +}; + +MyStruct operator-(MyStruct lhs, MyStruct rhs) +{ + return MyStruct(lhs.value - rhs.value); +} +"; + + var expectedOutputContents = @" + + + + + int + + + void + + int + + + value + + + + + MyStruct + + MyStruct + + return new MyStruct(value + rhs.value); + + + + + MyStruct + + MyStruct + + + MyStruct + + return new MyStruct(lhs.value - rhs.value); + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task OperatorCallTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + MyStruct(int value) : value(value) + { + } + + MyStruct operator+(MyStruct rhs) + { + return MyStruct(value + rhs.value); + } +}; + +MyStruct MyFunction1(MyStruct lhs, MyStruct rhs) +{ + return lhs + rhs; +} + +MyStruct operator-(MyStruct lhs, MyStruct rhs) +{ + return MyStruct(lhs.value - rhs.value); +} + +MyStruct MyFunction2(MyStruct lhs, MyStruct rhs) +{ + return lhs - rhs; +} +"; + + var expectedOutputContents = @" + + + + + int + + + void + + int + + + value + + + + + MyStruct + + MyStruct + + return new MyStruct(value + rhs.value); + + + + + MyStruct + + MyStruct + + + MyStruct + + return lhs.Add(rhs); + + + MyStruct + + MyStruct + + + MyStruct + + return new MyStruct(lhs.value - rhs.value); + + + MyStruct + + MyStruct + + + MyStruct + + return Subtract(lhs, rhs); + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task StaticTest() + { + var inputContents = @"struct MyStruct +{ + static void MyVoidMethod(); + + static int MyInt32Method() + { + return 0; + } + + static void* MyVoidStarMethod() + { + return nullptr; + } +}; +"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "?MyVoidMethod@MyStruct@@SAXXZ" : "_ZN8MyStruct12MyVoidMethodEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + entryPoint = $"_{entryPoint}"; + } + + var expectedOutputContents = $@" + + + + + void + + + int + return 0; + + + void* + return null; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ThisTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + int MyFunction() + { + return this->value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + return this.value; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnsafeDoesNotImpactDllImportTest() + { + var inputContents = @"struct MyStruct +{ + void* MyVoidStarMethod() + { + return nullptr; + } +}; + +void MyFunction();"; + + var expectedOutputContents = @" + + + + + void* + return null; + + + + + void + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task VirtualTest() + { + var inputContents = @"struct MyStruct +{ + virtual void MyVoidMethod() = 0; + + virtual char MyInt8Method() + { + return 0; + } + + virtual int MyInt32Method(); + + virtual void* MyVoidStarMethod() = 0; +}; +"; + + var callConv = "Cdecl"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + callConv = "ThisCall"; + } + + var expectedOutputContents = $@" + + + + + void** + + + void + + MyStruct* + + + + sbyte + + MyStruct* + + + + int + + MyStruct* + + + + void* + + MyStruct* + + + + void + + fixed (MyStruct* pThis = &this) + {{ + Marshal.GetDelegateForFunctionPointer<_MyVoidMethod>((IntPtr)(lpVtbl[0]))(pThis); + }} + + + + sbyte + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_MyInt8Method>((IntPtr)(lpVtbl[1]))(pThis); + }} + + + + int + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_MyInt32Method>((IntPtr)(lpVtbl[2]))(pThis); + }} + + + + void* + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_MyVoidStarMethod>((IntPtr)(lpVtbl[3]))(pThis); + }} + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/EnumDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/EnumDeclarationTest.cs new file mode 100644 index 00000000..c76ac896 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/EnumDeclarationTest.cs @@ -0,0 +1,752 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleWindows_EnumDeclarationTest : EnumDeclarationTest + { + public override Task BasicTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicValueTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value1 = 1, + MyEnum_Value2, + MyEnum_Value3, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExcludeTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; +"; + + var expectedOutputContents = string.Empty; + + var excludedNames = new string[] { "MyEnum" }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task ExplicitTypedTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"enum MyEnum : {nativeType} +{{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}}; +"; + + var expectedOutputContents = $@" + + + + {EscapeXml(expectedManagedType)} + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExplicitTypedWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"enum MyEnum : {nativeType} +{{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}}; +"; + + var expectedOutputContents = $@" + + + + {EscapeXml(expectedManagedType)} + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RemapTest() + { + var inputContents = @"typedef enum _MyEnum : int +{ + MyEnum_Value1, + MyEnum_Value2, + MyEnum_Value3, +} MyEnum; +"; + + var expectedOutputContents = @" + + + + int + + int + + + int + + + int + + + + +"; + + var remappedNames = new Dictionary { ["_MyEnum"] = "MyEnum" }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task WithAttributeTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = 1, +}; +"; + + var expectedOutputContents = @" + + + Flags + + int + + int + + 1 + + + + + int + + int + + 1 + + + + + +"; + + var withAttributes = new Dictionary> + { + ["MyEnum1"] = new List() { "Flags" } + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withAttributes: withAttributes); + } + + public override Task WithAttributeStarTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = 1, +}; +"; + + var expectedOutputContents = @" + + + Flags + + int + + int + + 1 + + + + Flags + + int + + int + + 1 + + + + + +"; + + var withAttributes = new Dictionary> + { + ["*"] = new List() { "Flags" } + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withAttributes: withAttributes); + } + + public override Task WithAttributeStarPlusTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = 1, +}; +"; + + var expectedOutputContents = @" + + + Flags + + int + + int + + 1 + + + + Flags + EditorBrowsable(EditorBrowsableState.Never) + + int + + int + + 1 + + + + + +"; + + var withAttributes = new Dictionary> + { + ["*"] = new List() { "Flags" }, + ["MyEnum2"] = new List() { "EditorBrowsable(EditorBrowsableState.Never)" } + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withAttributes: withAttributes); + } + + public override Task WithNamespaceTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = MyEnum1_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + + int + + int + + MyEnum1_Value1 + + + + + +"; + + var withNamespaces = new Dictionary> + { + ["MyEnum1"] = new List() { "static ClangSharp.Test.MyEnum1" } + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withUsings: withNamespaces); + } + + public override Task WithNamespaceStarTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = MyEnum1_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + + int + + int + + MyEnum1_Value1 + + + + + +"; + + var withNamespaces = new Dictionary> + { + ["*"] = new List() { "static ClangSharp.Test.MyEnum1" } + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withUsings: withNamespaces); + } + + public override Task WithNamespaceStarPlusTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = MyEnum1_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + + int + + int + + MyEnum1_Value1 + + + + + +"; + + var withNamespaces = new Dictionary> + { + ["*"] = new List() { "static ClangSharp.Test.MyEnum1" }, + ["MyEnum2"] = new List() { "System" } + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withUsings: withNamespaces); + } + + public override Task WithCastToEnumType() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0 = (MyEnum) 10, + MyEnum_Value1 = (MyEnum) MyEnum_Value0, + MyEnum_Value2 = ((MyEnum) 10) + MyEnum_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + (int)(MyEnum)(10) + + + + int + + (int)(MyEnum)(MyEnum_Value0) + + + + int + + ((int)(MyEnum)(10)) + MyEnum_Value1 + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithMultipleEnumsTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value0 = 10, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value0 = MyEnum1_Value0, + MyEnum2_Value1 = MyEnum1_Value0 + (MyEnum1) 10, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 10 + + + + + int + + int + + MyEnum1_Value0 + + + + int + + MyEnum1_Value0 + (int)(MyEnum1)(10) + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithImplicitConversionTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2 = 0x80000000, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + + int + + + int + + + + int + + 0x80000000 + + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithTypeTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; +"; + + var expectedOutputContents = @" + + + + uint + + uint + + + uint + + + uint + + + + +"; + + var withTypes = new Dictionary { + ["MyEnum"] = "uint" + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + + public override Task WithTypeAndImplicitConversionTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2 = 0x80000000, +}; +"; + + var expectedOutputContents = @" + + + + uint + + uint + + + uint + + + uint + + 0x80000000 + + + + + +"; + + var withTypes = new Dictionary + { + ["MyEnum"] = "uint" + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + + public override Task WithTypeStarTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value0 +}; + +enum MyEnum2 : int +{ + MyEnum2_Value0 +}; +"; + + var expectedOutputContents = @" + + + + uint + + uint + + + + uint + + uint + + + + +"; + + var withTypes = new Dictionary + { + ["*"] = "uint" + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + + public override Task WithTypeStarOverrideTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value0 +}; + +enum MyEnum2 : int +{ + MyEnum2_Value0 +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + + + uint + + uint + + + + +"; + + var withTypes = new Dictionary + { + ["*"] = "uint", + ["MyEnum1"] = "int", + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationBodyImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationBodyImportTest.cs new file mode 100644 index 00000000..2d48049d --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationBodyImportTest.cs @@ -0,0 +1,2022 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Reflection.Emit; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleWindows_FunctionDeclarationBodyImportTest : FunctionDeclarationBodyImportTest + { + public override Task ArraySubscriptTest() + { + var inputContents = @"int MyFunction(int* pData, int index) +{ + return pData[index]; +} +"; + + var expectedOutputContents = @" + + + + + int + + int* + + + int + + return pData[index]; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicTest() + { + var inputContents = @"void MyFunction() +{ +} +"; + + var expectedOutputContents = @" + + + + + void + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BinaryOperatorBasicTest(string opcode) + { + var inputContents = $@"int MyFunction(int x, int y) +{{ + return x {opcode} y; +}} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + + int + + return x {EscapeXml(opcode)} y; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BinaryOperatorCompareTest(string opcode) + { + var inputContents = $@"bool MyFunction(int x, int y) +{{ + return x {opcode} y; +}} +"; + + var expectedOutputContents = $@" + + + + + bool + + int + + + int + + return x {EscapeXml(opcode)} y; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BinaryOperatorBooleanTest(string opcode) + { + var inputContents = $@"bool MyFunction(bool x, bool y) +{{ + return x {opcode} y; +}} +"; + + var expectedOutputContents = $@" + + + + + bool + + bool + + + bool + + return x {EscapeXml(opcode)} y; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BreakTest() + { + var inputContents = @"int MyFunction(int value) +{ + while (true) + { + break; + } + + return 0; +} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + while (true) + {{ + break; + }} + + return 0; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CallFunctionTest() + { + var inputContents = @"void MyCalledFunction() +{ +} + +void MyFunction() +{ + MyCalledFunction(); +} +"; + + var expectedOutputContents = $@" + + + + + void + + + + void + MyCalledFunction(); + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CallFunctionWithArgsTest() + { + var inputContents = @"void MyCalledFunction(int x, int y) +{ +} + +void MyFunction() +{ + MyCalledFunction(0, 1); +} +"; + + var expectedOutputContents = $@" + + + + + void + + int + + + int + + + + + void + MyCalledFunction(0, 1); + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CaseTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + { + case 0: + { + return 0; + } + + case 1: + case 2: + { + return 3; + } + } + + return -1; +} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + switch (value) + {{ + case 0: + {{ + return 0; + }} + + case 1: + case 2: + {{ + return 3; + }} + }} + + return -1; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CaseNoCompoundTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + { + case 0: + return 0; + + case 2: + case 3: + return 5; + } + + return -1; +} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + switch (value) + {{ + case 0: + {{ + return 0; + }} + + case 2: + case 3: + {{ + return 5; + }} + }} + + return -1; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CompareMultipleEnumTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; + +static inline int MyFunction(MyEnum x) +{ + return x == MyEnum_Value0 || + x == MyEnum_Value1 || + x == MyEnum_Value2; +} +"; + + var expectedOutputContents = $@" + + + + int + + int + + + int + + + int + + + + + int + + MyEnum + + return (x == MyEnum_Value0 || x == MyEnum_Value1 || x == MyEnum_Value2) ? 1 : 0; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ConditionalOperatorTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + return condition ? lhs : rhs; +} +"; + + var expectedOutputContents = $@" + + + + + int + + bool + + + int + + + int + + return condition ? lhs : rhs; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ContinueTest() + { + var inputContents = @"int MyFunction(int value) +{ + while (true) + { + continue; + } + + return 0; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + while (true) + { + continue; + } + + return 0; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CStyleFunctionalCastTest() + { + var inputContents = @"int MyFunction(float input) +{ + return (int)input; +} +"; + + var expectedOutputContents = @" + + + + + int + + float + + return (int)(input); + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxFunctionalCastTest() + { + var inputContents = @"int MyFunction(float input) +{ + return int(input); +} +"; + + var expectedOutputContents = @" + + + + + int + + float + + return (int)(input); + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxConstCastTest() + { + var inputContents = @"void* MyFunction(const void* input) +{ + return const_cast(input); +} +"; + + var expectedOutputContents = @" + + + + + void* + + void* + + return input; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxDynamicCastTest() + { + var inputContents = @"struct MyStructA +{ + virtual void MyMethod() = 0; +}; + +struct MyStructB : MyStructA { }; + +MyStructB* MyFunction(MyStructA* input) +{ + return dynamic_cast(input); +} +"; + + var callConv = "Cdecl"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + callConv = "ThisCall"; + } + + var expectedOutputContents = $@" + + + + + void** + + + void + + MyStructA* + + + + void + + fixed (MyStructA* pThis = &this) + {{ + Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))(pThis); + }} + + + + + + void** + + + void + + MyStructB* + + + + void + + fixed (MyStructB* pThis = &this) + {{ + Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))(pThis); + }} + + + + + + MyStructB* + + MyStructA* + + return (MyStructB*)(input); + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxReinterpretCastTest() + { + var inputContents = @"int* MyFunction(void* input) +{ + return reinterpret_cast(input); +} +"; + + var expectedOutputContents = @" + + + + + int* + + void* + + return (int*)(input); + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxStaticCastTest() + { + var inputContents = @"int* MyFunction(void* input) +{ + return static_cast(input); +} +"; + + var expectedOutputContents = @" + + + + + int* + + void* + + return (int*)(input); + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DeclTest() + { + var inputContents = @"\ +int MyFunction() +{ + int x = 0; + int y = 1, z = 2; + return x + y + z; +} +"; + + var expectedOutputContents = @" + + + + + int + int x = 0; + int y = 1, z = 2; + + return x + y + z; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DoTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + do + { + i++; + } + while (i < count); + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + do + { + i++; + } + while (i < count); + + return i; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DoNonCompoundTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + while (i < count) + i++; + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + while (i < count) + { + i++; + } + + return i; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ForTest() + { + var inputContents = @"int MyFunction(int count) +{ + for (int i = 0; i < count; i--) + { + i += 2; + } + + int x; + + for (x = 0; x < count; x--) + { + x += 2; + } + + x = 0; + + for (; x < count; x--) + { + x += 2; + } + + for (int i = 0;;i--) + { + i += 2; + } + + for (x = 0;;x--) + { + x += 2; + } + + for (int i = 0; i < count;) + { + i++; + } + + for (x = 0; x < count;) + { + x++; + } + + // x = 0; + // + // for (;; x--) + // { + // x += 2; + // } + + x = 0; + + for (; x < count;) + { + x++; + } + + for (int i = 0;;) + { + i++; + } + + for (x = 0;;) + { + x++; + } + + for (;;) + { + return -1; + } +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + for (int i = 0; i < count; i--) + { + i += 2; + } + + int x; + + for (x = 0; x < count; x--) + { + x += 2; + } + + x = 0; + for (; x < count; x--) + { + x += 2; + } + + for (int i = 0;; i--) + { + i += 2; + } + + for (x = 0;; x--) + { + x += 2; + } + + for (int i = 0; i < count;) + { + i++; + } + + for (x = 0; x < count;) + { + x++; + } + + x = 0; + for (; x < count;) + { + x++; + } + + for (int i = 0;;) + { + i++; + } + + for (x = 0;;) + { + x++; + } + + for (;;) + { + return -1; + } + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ForNonCompoundTest() + { + var inputContents = @"int MyFunction(int count) +{ + for (int i = 0; i < count; i--) + i += 2; + + int x; + + for (x = 0; x < count; x--) + x += 2; + + x = 0; + + for (; x < count; x--) + x += 2; + + for (int i = 0;;i--) + i += 2; + + for (x = 0;;x--) + x += 2; + + for (int i = 0; i < count;) + i++; + + for (x = 0; x < count;) + x++; + + // x = 0; + // + // for (;; x--) + // x += 2; + + x = 0; + + for (; x < count;) + x++; + + for (int i = 0;;) + i++; + + for (x = 0;;) + x++; + + for (;;) + return -1; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + for (int i = 0; i < count; i--) + { + i += 2; + } + + int x; + + for (x = 0; x < count; x--) + { + x += 2; + } + + x = 0; + for (; x < count; x--) + { + x += 2; + } + + for (int i = 0;; i--) + { + i += 2; + } + + for (x = 0;; x--) + { + x += 2; + } + + for (int i = 0; i < count;) + { + i++; + } + + for (x = 0; x < count;) + { + x++; + } + + x = 0; + for (; x < count;) + { + x++; + } + + for (int i = 0;;) + { + i++; + } + + for (x = 0;;) + { + x++; + } + + for (;;) + { + return -1; + } + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + if (condition) + { + return lhs; + } + + return rhs; +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + if (condition) + { + return lhs; + } + + return rhs; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfElseTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + if (condition) + { + return lhs; + } + else + { + return rhs; + } +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + if (condition) + { + return lhs; + } + else + { + return rhs; + } + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfElseIfTest() + { + var inputContents = @"int MyFunction(bool condition1, int a, int b, bool condition2, int c) +{ + if (condition1) + { + return a; + } + else if (condition2) + { + return b; + } + + return c; +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + + bool + + + int + + if (condition1) + { + return a; + } + else if (condition2) + { + return b; + } + + return c; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfElseNonCompoundTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + if (condition) + return lhs; + else + return rhs; +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + if (condition) + { + return lhs; + } + else + { + return rhs; + } + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task InitListForArrayTest() + { + var inputContents = @" +void MyFunction() +{ + int x[4] = { 1, 2, 3, 4 }; + int y[4] = { 1, 2, 3 }; + int z[] = { 1, 2 }; +} +"; + + var expectedOutputContents = @" + + + + + void + int[] x = new int[4] + { + 1, + 2, + 3, + 4, + }; + int[] y = new int[4] + { + 1, + 2, + 3, + default, + }; + int[] z = new int[2] + { + 1, + 2, + }; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task InitListForRecordDeclTest() + { + var inputContents = @"struct MyStruct +{ + float x; + float y; + float z; + float w; +}; + +MyStruct MyFunction1() +{ + return { 1.0f, 2.0f, 3.0f, 4.0f }; +} + +MyStruct MyFunction2() +{ + return { 1.0f, 2.0f, 3.0f }; +} +"; + + var expectedOutputContents = @" + + + + + float + + + float + + + float + + + float + + + + + MyStruct + return new MyStruct + { + x = 1.0f, + y = 2.0f, + z = 3.0f, + w = 4.0f, + }; + + + MyStruct + return new MyStruct + { + x = 1.0f, + y = 2.0f, + z = 3.0f, + }; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MemberTest() + { + var inputContents = @"struct MyStruct +{ + int value; +}; + +int MyFunction1(MyStruct instance) +{ + return instance.value; +} + +int MyFunction2(MyStruct* instance) +{ + return instance->value; +} +"; + + var expectedOutputContents = @" + + + + + int + + + + + int + + MyStruct + + return instance.value; + + + int + + MyStruct* + + return instance->value; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RefToPtrTest() + { + var inputContents = @"struct MyStruct { + int value; +}; + +bool MyFunction(const MyStruct& lhs, const MyStruct& rhs) +{ + return lhs.value == rhs.value; +} +"; + + var expectedOutputContents = @" + + + + + int + + + + + bool + + MyStruct* + + + MyStruct* + + return lhs->value == rhs->value; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnCXXNullPtrTest() + { + var inputContents = @"void* MyFunction() +{ + return nullptr; +} +"; + + var expectedOutputContents = @" + + + + + void* + return null; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnCXXBooleanLiteralTest(string value) + { + var inputContents = $@"bool MyFunction() +{{ + return {value}; +}} +"; + + var expectedOutputContents = $@" + + + + + bool + return {value}; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnFloatingLiteralDoubleTest(string value) + { + var inputContents = $@"double MyFunction() +{{ + return {value}; +}} +"; + + var expectedOutputContents = $@" + + + + + double + return {value}; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnFloatingLiteralSingleTest(string value) + { + var inputContents = $@"float MyFunction() +{{ + return {value}; +}} +"; + + var expectedOutputContents = $@" + + + + + float + return {value}; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnEmptyTest() + { + var inputContents = @"void MyFunction() +{ + return; +} +"; + + var expectedOutputContents = @" + + + + + void + return; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnIntegerLiteralInt32Test() + { + var inputContents = @"int MyFunction() +{ + return -1; +} +"; + + var expectedOutputContents = @" + + + + + int + return -1; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task AccessUnionMemberTest() + { + var inputContents = @"union MyUnion +{ + struct { int a; }; +}; + +void MyFunction() +{ + MyUnion myUnion; + myUnion.a = 10; +} +"; + + var expectedOutputContents = @" + + + + + _Anonymous_e__Struct + + + ref int + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + { + return ref pField->a; + } + + + + + int + + + + + + void + MyUnion myUnion = new MyUnion(); + + myUnion.Anonymous.a = 10; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnStructTest() + { + var inputContents = @"struct MyStruct +{ + double r; + double g; + double b; +}; + +MyStruct MyFunction() +{ + MyStruct myStruct; + return myStruct; +} +"; + + var expectedOutputContents = @" + + + + + double + + + double + + + double + + + + + MyStruct + MyStruct myStruct = new MyStruct(); + + return myStruct; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SwitchTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + { + default: + { + return 0; + } + } +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + switch (value) + { + default: + { + return 0; + } + } + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SwitchNonCompoundTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + default: + { + return 0; + } + + switch (value) + default: + return 0; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + switch (value) + { + default: + { + return 0; + } + } + + switch (value) + { + default: + { + return 0; + } + } + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorAddrOfTest() + { + var inputContents = @"int* MyFunction(int value) +{ + return &value; +} +"; + + var expectedOutputContents = @" + + + + + int* + + int + + return &value; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorDerefTest() + { + var inputContents = @"int MyFunction(int* value) +{ + return *value; +} +"; + + var expectedOutputContents = @" + + + + + int + + int* + + return *value; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorLogicalNotTest() + { + var inputContents = @"bool MyFunction(bool value) +{ + return !value; +} +"; + + var expectedOutputContents = @" + + + + + bool + + bool + + return !value; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorPostfixTest(string opcode) + { + var inputContents = $@"int MyFunction(int value) +{{ + return value{opcode}; +}} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + return value{opcode}; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorPrefixTest(string opcode) + { + var inputContents = $@"int MyFunction(int value) +{{ + return {opcode}value; +}} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + return {opcode}value; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WhileTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + while (i < count) + { + i++; + } + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + while (i < count) + { + i++; + } + + return i; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WhileNonCompoundTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + while (i < count) + i++; + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + while (i < count) + { + i++; + } + + return i; + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationDllImportTest.cs new file mode 100644 index 00000000..eb552111 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationDllImportTest.cs @@ -0,0 +1,399 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleWindows_FunctionDeclarationDllImportTest : FunctionDeclarationDllImportTest + { + public override Task BasicTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ArrayParameterTest() + { + var inputContents = @"void MyFunction(const float color[4]);"; + + var expectedOutputContents = @" + + + + + void + + float* + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FunctionPointerParameterTest() + { + var inputContents = @"void MyFunction(void (*callback)());"; + + var expectedOutputContents = @" + + + + + void + + IntPtr + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) + { + var inputContents = @$"template struct MyTemplate; + +void MyFunction(MyTemplate<{nativeType}> myStruct);"; + + var expectedOutputContents = $@" + + + + + void + + MyTemplate<{expectedManagedType}> + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: new[] { "MyTemplate" }); + } + + public override Task TemplateMemberTest() + { + var inputContents = @$"template struct MyTemplate +{{ +}}; + +struct MyStruct +{{ + MyTemplate a; +}}; +"; + + var expectedOutputContents = $@" + + + + + MyTemplate<IntPtr> + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: new[] { "MyTemplate" }); + } + + public override Task NoLibraryPathTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty); + } + + public override Task WithLibraryPathTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + var withLibraryPaths = new Dictionary + { + ["MyFunction"] = "ClangSharpPInvokeGenerator" + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty, withLibraryPaths: withLibraryPaths); + } + + public override Task WithLibraryPathStarTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + var withLibraryPaths = new Dictionary + { + ["*"] = "ClangSharpPInvokeGenerator" + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty, withLibraryPaths: withLibraryPaths); + } + + public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) + { + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + + var expectedOutputContents = $@" + + + + + void + + {expectedManagedType} + + {expectedManagedInit} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) + { + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + + var expectedOutputContents = $@" + + + + + void + + {expectedManagedType} + + {expectedManagedInit} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithCallConvTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withCallConvs = new Dictionary { + ["MyFunction1"] = "Winapi" + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withCallConvs: withCallConvs); + } + + public override Task WithCallConvStarTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withCallConvs = new Dictionary + { + ["*"] = "Winapi" + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withCallConvs: withCallConvs); + } + + public override Task WithCallConvStarOverrideTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withCallConvs = new Dictionary + { + ["*"] = "Winapi", + ["MyFunction2"] = "StdCall" + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withCallConvs: withCallConvs); + } + + public override Task WithSetLastErrorTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withSetLastErrors = new string[] + { + "MyFunction1" + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withSetLastErrors: withSetLastErrors); + } + + public override Task WithSetLastErrorStarTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withSetLastErrors = new string[] + { + "*" + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, withSetLastErrors: withSetLastErrors); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionPointerDeclarationTest.cs new file mode 100644 index 00000000..547114d5 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionPointerDeclarationTest.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleWindows_FunctionPointerDeclarationTest : FunctionPointerDeclarationTest + { + public override Task BasicTest() + { + var inputContents = @"typedef void (*Callback)();"; + + var expectedOutputContents = @" + + + + void + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/StructDeclarationTest.cs new file mode 100644 index 00000000..f4259655 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/StructDeclarationTest.cs @@ -0,0 +1,1504 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleWindows_StructDeclarationTest : StructDeclarationTest + { + public override Task BasicTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicTestInCMode(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef struct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}} MyStruct; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + } + + public override Task BasicWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BitfieldTest() + { + var inputContents = @"struct MyStruct1 +{ + unsigned int o0_b0_24 : 24; + unsigned int o4_b0_16 : 16; + unsigned int o4_b16_3 : 3; + int o4_b19_3 : 3; + unsigned char o8_b0_1 : 1; + int o12_b0_1 : 1; + int o12_b1_1 : 1; +}; + +struct MyStruct2 +{ + unsigned int o0_b0_1 : 1; + int x; + unsigned int o8_b0_1 : 1; +}; + +struct MyStruct3 +{ + unsigned int o0_b0_1 : 1; + unsigned int o0_b1_1 : 1; +}; +"; + + var expectedOutputContents = @" + + + + + uint + + + uint + + return _bitfield1 & 0xFFFFFFu; + + + + _bitfield1 = (_bitfield1 & ~0xFFFFFFu) | (value & 0xFFFFFFu); + + + + uint + + + uint + + return _bitfield2 & 0xFFFFu; + + + + _bitfield2 = (_bitfield2 & ~0xFFFFu) | (value & 0xFFFFu); + + + + uint + + return (_bitfield2 >> 16) & 0x7u; + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 16)) | ((value & 0x7u) << 16); + + + + int + + return (int)((_bitfield2 >> 19) & 0x7u); + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 19)) | (uint)((value & 0x7) << 19); + + + + byte + + + byte + + return (byte)(_bitfield3 & 0x1u); + + + + _bitfield3 = (byte)((_bitfield3 & ~0x1u) | (value & 0x1u)); + + + + int + + + int + + return _bitfield4 & 0x1; + + + + _bitfield4 = (_bitfield4 & ~0x1) | (value & 0x1); + + + + int + + return (_bitfield4 >> 1) & 0x1; + + + + _bitfield4 = (_bitfield4 & ~(0x1 << 1)) | ((value & 0x1) << 1); + + + + + + uint + + + uint + + return _bitfield1 & 0x1u; + + + + _bitfield1 = (_bitfield1 & ~0x1u) | (value & 0x1u); + + + + int + + + uint + + + uint + + return _bitfield2 & 0x1u; + + + + _bitfield2 = (_bitfield2 & ~0x1u) | (value & 0x1u); + + + + + + uint + + + uint + + return _bitfield & 0x1u; + + + + _bitfield = (_bitfield & ~0x1u) | (value & 0x1u); + + + + uint + + return (_bitfield >> 1) & 0x1u; + + + + _bitfield = (_bitfield & ~(0x1u << 1)) | ((value & 0x1u) << 1); + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExcludeTest() + { + var inputContents = "typedef struct MyStruct MyStruct;"; + var expectedOutputContents = string.Empty; + + var excludedNames = new string[] { "MyStruct" }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task FixedSizedBufferNonPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +struct MyOtherStruct +{{ + MyStruct c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + fixed (MyStruct* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +struct MyOtherStruct +{{ + MyStruct c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + fixed (MyStruct* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +typedef MyStruct MyBuffer[3]; + +struct MyOtherStruct +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + fixed (MyStruct* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +struct MyOtherStruct +{{ + MyStruct c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + fixed (MyStruct* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPointerTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + ref {expectedManagedType} + + int + + + fixed ({expectedManagedType}* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyBuffer[3]; + +struct MyStruct +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task GuidTest() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Non-Windows doesn't support __declspec(uuid("")) + return Task.CompletedTask; + } + + var inputContents = $@"#define DECLSPEC_UUID(x) __declspec(uuid(x)) + +struct __declspec(uuid(""00000000-0000-0000-C000-000000000046"")) MyStruct1 +{{ + int x; +}}; + +struct DECLSPEC_UUID(""00000000-0000-0000-C000-000000000047"") MyStruct2 +{{ + int x; +}}; +"; + + var expectedOutputContents = $@" + + + + + int + + + + + int + + + + + + + + +"; + + var excludedNames = new string[] { "DECLSPEC_UUID" }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task InheritanceTest() + { + var inputContents = @"struct MyStruct1A +{ + int x; + int y; +}; + +struct MyStruct1B +{ + int x; + int y; +}; + +struct MyStruct2 : MyStruct1A, MyStruct1B +{ + int z; + int w; +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + + + int + + + int + + + + + MyStruct1A + + + MyStruct1B + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column) + { + var inputContents = $@"typedef union {{ + {nativeType} value; +}} MyUnion; + +struct MyStruct +{{ + {nativeType} x; + {nativeType} y; + + struct + {{ + {nativeType} z; + + struct + {{ + {nativeType} value; + }} w; + + MyUnion u; + {nativeType} buffer1[4]; + MyUnion buffer2[4]; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + {expectedManagedType} + + + {expectedManagedType} + + + _Anonymous_e__Struct + + + ref {expectedManagedType} + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + {{ + return ref pField->z; + }} + + + + ref _Anonymous_e__Struct._w_e__Struct + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + {{ + return ref pField->w; + }} + + + + ref MyUnion + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + {{ + return ref pField->u; + }} + + + + ref {expectedManagedType} + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + {{ + return ref pField->buffer1[0]; + }} + + + + ref _Anonymous_e__Struct._buffer2_e__FixedBuffer + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + {{ + return ref pField->buffer2; + }} + + + + + {expectedManagedType} + + + _w_e__Struct + + + MyUnion + + + {expectedManagedType} + + + MyUnion + + + + {expectedManagedType} + + + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + fixed (MyUnion* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedAnonymousWithBitfieldTest() + { + var inputContents = @"struct MyStruct +{ + int x; + int y; + + struct + { + int z; + + struct + { + int w; + int o0_b0_16 : 16; + int o0_b16_4 : 4; + }; + }; +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + _Anonymous_e__Struct + + + ref int + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + { + return ref pField->z; + } + + + + ref int + + fixed (_Anonymous_e__Struct._Anonymous_e__Struct* pField = &Anonymous.Anonymous) + { + return ref pField->w; + } + + + + int + + return Anonymous.Anonymous.o0_b0_16; + + + Anonymous.Anonymous.o0_b0_16 = value; + + + + int + + return Anonymous.Anonymous.o0_b16_4; + + + Anonymous.Anonymous.o0_b16_4 = value; + + + + + int + + + _Anonymous_e__Struct + + + + int + + + int + + + int + + return _bitfield & 0xFFFF; + + + + _bitfield = (_bitfield & ~0xFFFF) | (value & 0xFFFF); + + + + int + + return (_bitfield >> 16) & 0xF; + + + + _bitfield = (_bitfield & ~(0xF << 16)) | ((value & 0xF) << 16); + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + struct MyNestedStruct + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + struct MyNestedStruct + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordTest() + { + var inputContents = @"struct MyStruct +{ + int Equals; + int Finalize; + int GetHashCode; + int GetType; + int MemberwiseClone; + int ReferenceEquals; + int ToString; +};"; + + var expectedOutputContents = $@" + + + + + int + + + int + + + int + + + int + + + int + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NoDefinitionTest() + { + var inputContents = "typedef struct MyStruct MyStruct;"; + + var expectedOutputContents = $@" + + + + + +"; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfTest() + { + var inputContents = @"struct example_s { + example_s* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfViaTypedefTest() + { + var inputContents = @"typedef struct example_s example_t; + +struct example_s { + example_t* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RemapTest() + { + var inputContents = "typedef struct _MyStruct MyStruct;"; + + var expectedOutputContents = $@" + + + + + +"; + + var remappedNames = new Dictionary { ["_MyStruct"] = "MyStruct" }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task RemapNestedAnonymousTest() + { + var inputContents = @"struct MyStruct +{ + double r; + double g; + double b; + + struct + { + double a; + }; +};"; + + var expectedOutputContents = @" + + + + + double + + + double + + + double + + + _Anonymous_e__Struct + + + ref double + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + { + return ref pField->a; + } + + + + + double + + + + + +"; + + var remappedNames = new Dictionary { + ["__AnonymousField_ClangUnsavedFile_L7_C5"] = "Anonymous", + ["__AnonymousRecord_ClangUnsavedFile_L7_C5"] = "_Anonymous_e__Struct" + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task SkipNonDefinitionTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef struct MyStruct MyStruct; + +struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionPointerTest() + { + var inputContents = @"typedef struct MyStruct* MyStructPtr; +typedef struct MyStruct& MyStructRef; +"; + + var expectedOutputContents = @" + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef struct MyStruct MyStruct; + +struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task TypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyTypedefAlias; + +struct MyStruct +{{ + MyTypedefAlias r; + MyTypedefAlias g; + MyTypedefAlias b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UsingDeclarationTest() + { + var inputContents = @"struct MyStruct1A +{ + void MyMethod() { } +}; + +struct MyStruct1B : MyStruct1A +{ + using MyStruct1A::MyMethod; +}; +"; + + var expectedOutputContents = @" + + + + + void + + + + + + void + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs new file mode 100644 index 00000000..70a6e775 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs @@ -0,0 +1,1354 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleWindows_UnionDeclarationTest : UnionDeclarationTest + { + public override Task BasicTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicTestInCMode(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef union +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}} MyUnion; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + } + + public override Task BasicWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BitfieldTest() + { + var inputContents = @"union MyUnion1 +{ + unsigned int o0_b0_24 : 24; + unsigned int o4_b0_16 : 16; + unsigned int o4_b16_3 : 3; + int o4_b19_3 : 3; + unsigned char o8_b0_1 : 1; + int o12_b0_1 : 1; + int o12_b1_1 : 1; +}; + +union MyUnion2 +{ + unsigned int o0_b0_1 : 1; + int x; + unsigned int o8_b0_1 : 1; +}; + +union MyUnion3 +{ + unsigned int o0_b0_1 : 1; + unsigned int o0_b1_1 : 1; +}; +"; + + string expectedPack = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ", Pack = 1" : ""; + + var expectedOutputContents = $@" + + + + + uint + + + uint + + return _bitfield1 & 0xFFFFFFu; + + + + _bitfield1 = (_bitfield1 & ~0xFFFFFFu) | (value & 0xFFFFFFu); + + + + uint + + + uint + + return _bitfield2 & 0xFFFFu; + + + + _bitfield2 = (_bitfield2 & ~0xFFFFu) | (value & 0xFFFFu); + + + + uint + + return (_bitfield2 >> 16) & 0x7u; + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 16)) | ((value & 0x7u) << 16); + + + + int + + return (int)((_bitfield2 >> 19) & 0x7u); + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 19)) | (uint)((value & 0x7) << 19); + + + + byte + + + byte + + return (byte)(_bitfield3 & 0x1u); + + + + _bitfield3 = (byte)((_bitfield3 & ~0x1u) | (value & 0x1u)); + + + + int + + + int + + return _bitfield4 & 0x1; + + + + _bitfield4 = (_bitfield4 & ~0x1) | (value & 0x1); + + + + int + + return (_bitfield4 >> 1) & 0x1; + + + + _bitfield4 = (_bitfield4 & ~(0x1 << 1)) | ((value & 0x1) << 1); + + + + + + uint + + + uint + + return _bitfield1 & 0x1u; + + + + _bitfield1 = (_bitfield1 & ~0x1u) | (value & 0x1u); + + + + int + + + uint + + + uint + + return _bitfield2 & 0x1u; + + + + _bitfield2 = (_bitfield2 & ~0x1u) | (value & 0x1u); + + + + + + uint + + + uint + + return _bitfield & 0x1u; + + + + _bitfield = (_bitfield & ~0x1u) | (value & 0x1u); + + + + uint + + return (_bitfield >> 1) & 0x1u; + + + + _bitfield = (_bitfield & ~(0x1u << 1)) | ((value & 0x1u) << 1); + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExcludeTest() + { + var inputContents = "typedef union MyUnion MyUnion;"; + var expectedOutputContents = string.Empty; + + var excludedNames = new string[] { "MyUnion" }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task FixedSizedBufferNonPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +union MyOtherUnion +{{ + MyUnion c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + fixed (MyUnion* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +union MyOtherUnion +{{ + MyUnion c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + fixed (MyUnion* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +typedef MyUnion MyBuffer[3]; + +union MyOtherUnion +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + fixed (MyUnion* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +union MyOtherUnion +{{ + MyUnion c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + fixed (MyUnion* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPointerTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + ref {expectedManagedType} + + int + + + fixed ({expectedManagedType}* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyBuffer[3]; + +union MyUnion +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + public override Task GuidTest() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Non-Windows doesn't support __declspec(uuid("")) + return Task.CompletedTask; + } + + var inputContents = $@"#define DECLSPEC_UUID(x) __declspec(uuid(x)) + +union __declspec(uuid(""00000000-0000-0000-C000-000000000046"")) MyUnion1 +{{ + int x; +}}; + +union DECLSPEC_UUID(""00000000-0000-0000-C000-000000000047"") MyUnion2 +{{ + int x; +}}; +"; + + var expectedOutputContents = $@" + + + + + int + + + + + int + + + + + + + + +"; + + var excludedNames = new string[] { "DECLSPEC_UUID" }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column) + { + var inputContents = $@"typedef struct {{ + {nativeType} value; +}} MyStruct; + +union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + union + {{ + {nativeType} a; + + MyStruct s; + + {nativeType} buffer[4]; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + _Anonymous_e__Union + + + ref {expectedManagedType} + + fixed (_Anonymous_e__Union* pField = &Anonymous) + {{ + return ref pField->a; + }} + + + + ref MyStruct + + fixed (_Anonymous_e__Union* pField = &Anonymous) + {{ + return ref pField->s; + }} + + + + ref {expectedManagedType} + + fixed (_Anonymous_e__Union* pField = &Anonymous) + {{ + return ref pField->buffer[0]; + }} + + + + + {expectedManagedType} + + + MyStruct + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedAnonymousWithBitfieldTest() + { + var inputContents = @"union MyUnion +{ + int x; + int y; + + union + { + int z; + + union + { + int w; + int o0_b0_16 : 16; + int o0_b16_4 : 4; + }; + }; +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + _Anonymous_e__Union + + + ref int + + fixed (_Anonymous_e__Union* pField = &Anonymous) + { + return ref pField->z; + } + + + + ref int + + fixed (_Anonymous_e__Union._Anonymous_e__Union* pField = &Anonymous.Anonymous) + { + return ref pField->w; + } + + + + int + + return Anonymous.Anonymous.o0_b0_16; + + + Anonymous.Anonymous.o0_b0_16 = value; + + + + int + + return Anonymous.Anonymous.o0_b16_4; + + + Anonymous.Anonymous.o0_b16_4 = value; + + + + + int + + + _Anonymous_e__Union + + + + int + + + int + + + int + + return _bitfield & 0xFFFF; + + + + _bitfield = (_bitfield & ~0xFFFF) | (value & 0xFFFF); + + + + int + + return (_bitfield >> 16) & 0xF; + + + + _bitfield = (_bitfield & ~(0xF << 16)) | ((value & 0xF) << 16); + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + + public override Task NestedTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + union MyNestedUnion + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + union MyNestedUnion + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordTest() + { + var inputContents = @"union MyUnion +{ + int Equals; + int Finalize; + int GetHashCode; + int GetType; + int MemberwiseClone; + int ReferenceEquals; + int ToString; +};"; + + var expectedOutputContents = $@" + + + + + int + + + int + + + int + + + int + + + int + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NoDefinitionTest() + { + var inputContents = "typedef union MyUnion MyUnion;"; + + var expectedOutputContents = $@" + + + + + +"; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfTest() + { + var inputContents = @"union example_s { + example_s* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfViaTypedefTest() + { + var inputContents = @"typedef union example_s example_t; + +union example_s { + example_t* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RemapTest() + { + var inputContents = "typedef union _MyUnion MyUnion;"; + + var expectedOutputContents = $@" + + + + + +"; + + var remappedNames = new Dictionary { ["_MyUnion"] = "MyUnion" }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task RemapNestedAnonymousTest() + { + var inputContents = @"union MyUnion +{ + double r; + double g; + double b; + + union + { + double a; + }; +};"; + + var expectedOutputContents = @" + + + + + double + + + double + + + double + + + _Anonymous_e__Union + + + ref double + + fixed (_Anonymous_e__Union* pField = &Anonymous) + { + return ref pField->a; + } + + + + + double + + + + + +"; + + var remappedNames = new Dictionary { + ["__AnonymousField_ClangUnsavedFile_L7_C5"] = "Anonymous", + ["__AnonymousRecord_ClangUnsavedFile_L7_C5"] = "_Anonymous_e__Union" + }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task SkipNonDefinitionTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef union MyUnion MyUnion; + +union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionPointerTest() + { + var inputContents = @"typedef union MyUnion* MyUnionPtr; +typedef union MyUnion& MyUnionRef; +"; + + var expectedOutputContents = @" + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef union MyUnion MyUnion; + +union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task TypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyTypedefAlias; + +union MyUnion +{{ + MyTypedefAlias r; + MyTypedefAlias g; + MyTypedefAlias b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/VarDeclarationTest.cs new file mode 100644 index 00000000..01e281cc --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/VarDeclarationTest.cs @@ -0,0 +1,373 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleWindows_VarDeclarationTest : VarDeclarationTest + { + public override Task BasicTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"{nativeType} MyVariable = 0;"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + 0 + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"{nativeType} MyVariable = 0;"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + 0 + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task GuidMacroTest() + { + var inputContents = $@"struct GUID {{ + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; +}}; + +const GUID IID_IUnknown = {{ 0x00000000, 0x0000, 0x0000, {{ 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 }} }}; +"; + + var expectedOutputContents = $@" + + + + + Guid + + new Guid(0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46) + + + + + +"; + var excludedNames = new string[] { "GUID" }; + var remappedNames = new Dictionary { ["GUID"] = "Guid" }; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames, remappedNames: remappedNames); + } + + public override Task MacroTest(string nativeValue, string expectedManagedType, string expectedManagedValue) + { + var inputContents = $@"#define MyMacro1 {nativeValue} +#define MyMacro2 MyMacro1"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + {expectedManagedValue} + + + + {expectedManagedType} + + {expectedManagedValue} + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MultilineMacroTest() + { + var inputContents = $@"#define MyMacro1 0 + \ +1"; + + var expectedOutputContents = $@" + + + + + int + + 0 + 1 + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NoInitializerTest(string nativeType) + { + var inputContents = $@"{nativeType} MyVariable;"; + var expectedOutputContents = ""; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task Utf8StringLiteralMacroTest() + { + var inputContents = $@"#define MyMacro1 ""Test"""; + + var expectedOutputContents = $@" + + + + + ReadOnlySpan<byte> + + new byte[] {{ 0x54, 0x65, 0x73, 0x74, 0x00 }} + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task Utf16StringLiteralMacroTest() + { + var inputContents = $@"#define MyMacro1 u""Test"""; + + var expectedOutputContents = $@" + + + + + string + + ""Test"" + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WideStringLiteralConstTest() + { + var inputContents = $@"const wchar_t MyConst1[] = L""Test"";"; + + var expectedOutputContents = $@" + + + + + string + + ""Test"" + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task StringLiteralConstTest() + { + var inputContents = $@"const char MyConst1[] = ""Test"";"; + + var expectedOutputContents = $@" + + + + + ReadOnlySpan<byte> + + new byte[] {{ 0x54, 0x65, 0x73, 0x74, 0x00 }} + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedConversionMacroTest() + { + var inputContents = $@"#define MyMacro1 (long)0x80000000L +#define MyMacro2 (int)0x80000000"; + + var expectedOutputContents = $@" + + + + + int + + + + (int)(0x80000000) + + + + + + int + + + + (int)(0x80000000) + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedFunctionLikeCastMacroTest() + { + var inputContents = $@"#define MyMacro1 unsigned(-1)"; + + var expectedOutputContents = $@" + + + + + uint + + + + (uint)(-1) + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedConversionMacroTest2() + { + var inputContents = $@"#define MyMacro1(x, y, z) ((int)(((unsigned long)(x)<<31) | ((unsigned long)(y)<<16) | ((unsigned long)(z)))) +#define MyMacro2(n) MyMacro1(1, 2, n) +#define MyMacro3 MyMacro2(3)"; + + var expectedOutputContents = $@" + + + + + int + + + ((int)(((uint)(1) << 31) | ((uint)(2) << 16) | ((uint)(3)))) + + + + + + +"; + + var excludedNames = new string[] { "MyMacro1", "MyMacro2" }; + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task UncheckedPointerMacroTest() + { + var inputContents = $@"#define Macro1 ((int*) -1)"; + + var expectedOutputContents = $@" + + + + + int* + + + ((int*)(-1)) + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedReinterpretCastMacroTest() + { + var inputContents = $@"#define Macro1 reinterpret_cast(-1)"; + + var expectedOutputContents = $@" + + + + + int* + + + + (int*)(-1) + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents); + } + } +} From 5fa6e5d6a87bca5625c9a00c4d8fe62c6e734a24 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sat, 20 Mar 2021 18:17:33 -0700 Subject: [PATCH 3/4] Adding XmlLatestUnix and XmlCompatibleUnix tests --- .../Cursors/Decls/EnumConstantDecl.cs | 1 - sources/ClangSharp/Cursors/Exprs/FullExpr.cs | 1 - .../ClangSharp/Cursors/Stmts/DefaultStmt.cs | 1 - sources/ClangSharp/Cursors/Stmts/WhileStmt.cs | 1 - .../CSharpLatestUnix/VarDeclarationTest.cs | 1 - .../CXXMethodDeclarationTest.cs | 933 ++++++++ .../XmlCompatibleUnix/EnumDeclarationTest.cs | 752 ++++++ .../FunctionDeclarationBodyImportTest.cs | 2021 +++++++++++++++++ .../FunctionDeclarationDllImportTest.cs | 399 ++++ .../FunctionPointerDeclarationTest.cs | 26 + .../StructDeclarationTest.cs | 1498 ++++++++++++ .../XmlCompatibleUnix/UnionDeclarationTest.cs | 1348 +++++++++++ .../XmlCompatibleUnix/VarDeclarationTest.cs | 353 +++ .../FunctionDeclarationBodyImportTest.cs | 1 - .../XmlLatestUnix/CXXMethodDeclarationTest.cs | 912 ++++++++ .../XmlLatestUnix/EnumDeclarationTest.cs | 752 ++++++ .../FunctionDeclarationBodyImportTest.cs | 2012 ++++++++++++++++ .../FunctionDeclarationDllImportTest.cs | 399 ++++ .../FunctionPointerDeclarationTest.cs | 26 + .../XmlLatestUnix/StructDeclarationTest.cs | 1479 ++++++++++++ .../XmlLatestUnix/UnionDeclarationTest.cs | 1334 +++++++++++ .../XmlLatestUnix/VarDeclarationTest.cs | 353 +++ .../FunctionDeclarationBodyImportTest.cs | 1 - 23 files changed, 14597 insertions(+), 7 deletions(-) create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/EnumDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionDeclarationBodyImportTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionDeclarationDllImportTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionPointerDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/StructDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/VarDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/EnumDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationBodyImportTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationDllImportTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionPointerDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/StructDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs create mode 100644 tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/VarDeclarationTest.cs diff --git a/sources/ClangSharp/Cursors/Decls/EnumConstantDecl.cs b/sources/ClangSharp/Cursors/Decls/EnumConstantDecl.cs index 941e0cda..ef966b0c 100644 --- a/sources/ClangSharp/Cursors/Decls/EnumConstantDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/EnumConstantDecl.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. using System; -using System.Linq; using ClangSharp.Interop; namespace ClangSharp diff --git a/sources/ClangSharp/Cursors/Exprs/FullExpr.cs b/sources/ClangSharp/Cursors/Exprs/FullExpr.cs index 991b4b8e..e28c659a 100644 --- a/sources/ClangSharp/Cursors/Exprs/FullExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/FullExpr.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. using System; -using System.Linq; using ClangSharp.Interop; namespace ClangSharp diff --git a/sources/ClangSharp/Cursors/Stmts/DefaultStmt.cs b/sources/ClangSharp/Cursors/Stmts/DefaultStmt.cs index 8a75bbf3..c6e6ad37 100644 --- a/sources/ClangSharp/Cursors/Stmts/DefaultStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/DefaultStmt.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. -using System; using ClangSharp.Interop; namespace ClangSharp diff --git a/sources/ClangSharp/Cursors/Stmts/WhileStmt.cs b/sources/ClangSharp/Cursors/Stmts/WhileStmt.cs index a54a7bd0..a1b286a2 100644 --- a/sources/ClangSharp/Cursors/Stmts/WhileStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/WhileStmt.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. using System; -using System.Linq; using ClangSharp.Interop; namespace ClangSharp diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/VarDeclarationTest.cs index 4b495d18..4fb0dca1 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/VarDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpLatestUnix/VarDeclarationTest.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. using System.Collections.Generic; -using System.Data.Common; using System.Threading.Tasks; namespace ClangSharp.UnitTests diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs new file mode 100644 index 00000000..37e1b126 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/CXXMethodDeclarationTest.cs @@ -0,0 +1,933 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleUnix_CXXMethodDeclarationTest : CXXMethodDeclarationTest + { + public override Task ConstructorTest() + { + var inputContents = @"struct MyStruct +{ + int _value; + + MyStruct(int value) + { + _value = value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + void + + int + + _value = value; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ConstructorWithInitializeTest() + { + var inputContents = @"struct MyStruct +{ + int _x; + int _y; + int _z; + + MyStruct(int x) : _x(x) + { + } + + MyStruct(int x, int y) : _x(x), _y(y) + { + } + + MyStruct(int x, int y, int z) : _x(x), _y(y), _z() + { + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + int + + + void + + int + + + x + + + + + void + + int + + + int + + + x + + + y + + + + + void + + int + + + int + + + int + + + x + + + y + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ConversionTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + operator int() + { + return value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + return value; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DestructorTest() + { + var inputContents = @"struct MyStruct +{ + ~MyStruct() + { + } +}; +"; + + var expectedOutputContents = @" + + + + + void + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task InstanceTest() + { + var inputContents = @"struct MyStruct +{ + void MyVoidMethod(); + + int MyInt32Method() + { + return 0; + } + + void* MyVoidStarMethod() + { + return nullptr; + } +}; +"; + var callConv = "Cdecl"; + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN8MyStruct12MyVoidMethodEv" : "_ZN8MyStruct12MyVoidMethodEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + if (!Environment.Is64BitProcess) + { + callConv = "ThisCall"; + entryPoint = "?MyVoidMethod@MyStruct@@QAEXXZ"; + } + else + { + entryPoint = "?MyVoidMethod@MyStruct@@QEAAXXZ"; + } + } + + var expectedOutputContents = $@" + + + + + void + + + int + return 0; + + + void* + return null; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MemberCallTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + int MyFunction1() + { + return value; + } + + int MyFunction2() + { + return MyFunction1(); + } + + int MyFunction3() + { + return this->MyFunction1(); + } +}; + +int MyFunctionA(MyStruct x) +{ + return x.MyFunction1(); +} + +int MyFunctionB(MyStruct* x) +{ + return x->MyFunction2(); +} +"; + + var expectedOutputContents = @" + + + + + int + + + int + return value; + + + int + return MyFunction1(); + + + int + return this.MyFunction1(); + + + + + int + + MyStruct + + return x.MyFunction1(); + + + int + + MyStruct* + + return x->MyFunction2(); + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MemberTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + int MyFunction() + { + return value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + return value; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordTest() + { + var inputContents = @"struct MyStruct +{ + int Equals() { return 0; } + int Equals(int obj) { return 0; } + int Finalize() { return 0; } + int Finalize(int obj) { return 0; } + int GetHashCode() { return 0; } + int GetHashCode(int obj) { return 0; } + int GetType() { return 0; } + int GetType(int obj) { return 0; } + int MemberwiseClone() { return 0; } + int MemberwiseClone(int obj) { return 0; } + int ReferenceEquals() { return 0; } + int ReferenceEquals(int obj) { return 0; } + int ToString() { return 0; } + int ToString(int obj) { return 0; } +};"; + + var expectedOutputContents = $@" + + + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordVirtualTest() + { + var inputContents = @"struct MyStruct +{ + virtual int GetType(int obj) = 0; + virtual int GetType() = 0; + virtual int GetType(int objA, int objB) = 0; +};"; + + var callConv = "Cdecl"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + callConv = "ThisCall"; + } + + var expectedOutputContents = $@" + + + + + void** + + + int + + MyStruct* + + + int + + + + int + + MyStruct* + + + + int + + MyStruct* + + + int + + + int + + + + int + + int + + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType>((IntPtr)(lpVtbl[0]))(pThis, obj); + }} + + + + int + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType1>((IntPtr)(lpVtbl[1]))(pThis); + }} + + + + int + + int + + + int + + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_GetType2>((IntPtr)(lpVtbl[2]))(pThis, objA, objB); + }} + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task OperatorTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + MyStruct(int value) : value(value) + { + } + + MyStruct operator+(MyStruct rhs) + { + return MyStruct(value + rhs.value); + } +}; + +MyStruct operator-(MyStruct lhs, MyStruct rhs) +{ + return MyStruct(lhs.value - rhs.value); +} +"; + + var expectedOutputContents = @" + + + + + int + + + void + + int + + + value + + + + + MyStruct + + MyStruct + + return new MyStruct(value + rhs.value); + + + + + MyStruct + + MyStruct + + + MyStruct + + return new MyStruct(lhs.value - rhs.value); + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task OperatorCallTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + MyStruct(int value) : value(value) + { + } + + MyStruct operator+(MyStruct rhs) + { + return MyStruct(value + rhs.value); + } +}; + +MyStruct MyFunction1(MyStruct lhs, MyStruct rhs) +{ + return lhs + rhs; +} + +MyStruct operator-(MyStruct lhs, MyStruct rhs) +{ + return MyStruct(lhs.value - rhs.value); +} + +MyStruct MyFunction2(MyStruct lhs, MyStruct rhs) +{ + return lhs - rhs; +} +"; + + var expectedOutputContents = @" + + + + + int + + + void + + int + + + value + + + + + MyStruct + + MyStruct + + return new MyStruct(value + rhs.value); + + + + + MyStruct + + MyStruct + + + MyStruct + + return lhs.Add(rhs); + + + MyStruct + + MyStruct + + + MyStruct + + return new MyStruct(lhs.value - rhs.value); + + + MyStruct + + MyStruct + + + MyStruct + + return Subtract(lhs, rhs); + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task StaticTest() + { + var inputContents = @"struct MyStruct +{ + static void MyVoidMethod(); + + static int MyInt32Method() + { + return 0; + } + + static void* MyVoidStarMethod() + { + return nullptr; + } +}; +"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "?MyVoidMethod@MyStruct@@SAXXZ" : "_ZN8MyStruct12MyVoidMethodEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + entryPoint = $"_{entryPoint}"; + } + + var expectedOutputContents = $@" + + + + + void + + + int + return 0; + + + void* + return null; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ThisTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + int MyFunction() + { + return this->value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + return this.value; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnsafeDoesNotImpactDllImportTest() + { + var inputContents = @"struct MyStruct +{ + void* MyVoidStarMethod() + { + return nullptr; + } +}; + +void MyFunction();"; + + var expectedOutputContents = @" + + + + + void* + return null; + + + + + void + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task VirtualTest() + { + var inputContents = @"struct MyStruct +{ + virtual void MyVoidMethod() = 0; + + virtual char MyInt8Method() + { + return 0; + } + + virtual int MyInt32Method(); + + virtual void* MyVoidStarMethod() = 0; +}; +"; + + var callConv = "Cdecl"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + callConv = "ThisCall"; + } + + var expectedOutputContents = $@" + + + + + void** + + + void + + MyStruct* + + + + sbyte + + MyStruct* + + + + int + + MyStruct* + + + + void* + + MyStruct* + + + + void + + fixed (MyStruct* pThis = &this) + {{ + Marshal.GetDelegateForFunctionPointer<_MyVoidMethod>((IntPtr)(lpVtbl[0]))(pThis); + }} + + + + sbyte + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_MyInt8Method>((IntPtr)(lpVtbl[1]))(pThis); + }} + + + + int + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_MyInt32Method>((IntPtr)(lpVtbl[2]))(pThis); + }} + + + + void* + + fixed (MyStruct* pThis = &this) + {{ + return Marshal.GetDelegateForFunctionPointer<_MyVoidStarMethod>((IntPtr)(lpVtbl[3]))(pThis); + }} + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/EnumDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/EnumDeclarationTest.cs new file mode 100644 index 00000000..ccb9b175 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/EnumDeclarationTest.cs @@ -0,0 +1,752 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleUnix_EnumDeclarationTest : EnumDeclarationTest + { + public override Task BasicTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicValueTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value1 = 1, + MyEnum_Value2, + MyEnum_Value3, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExcludeTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; +"; + + var expectedOutputContents = string.Empty; + + var excludedNames = new string[] { "MyEnum" }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task ExplicitTypedTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"enum MyEnum : {nativeType} +{{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}}; +"; + + var expectedOutputContents = $@" + + + + {EscapeXml(expectedManagedType)} + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExplicitTypedWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"enum MyEnum : {nativeType} +{{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}}; +"; + + var expectedOutputContents = $@" + + + + {EscapeXml(expectedManagedType)} + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RemapTest() + { + var inputContents = @"typedef enum _MyEnum : int +{ + MyEnum_Value1, + MyEnum_Value2, + MyEnum_Value3, +} MyEnum; +"; + + var expectedOutputContents = @" + + + + int + + int + + + int + + + int + + + + +"; + + var remappedNames = new Dictionary { ["_MyEnum"] = "MyEnum" }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task WithAttributeTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = 1, +}; +"; + + var expectedOutputContents = @" + + + Flags + + int + + int + + 1 + + + + + int + + int + + 1 + + + + + +"; + + var withAttributes = new Dictionary> + { + ["MyEnum1"] = new List() { "Flags" } + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withAttributes: withAttributes); + } + + public override Task WithAttributeStarTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = 1, +}; +"; + + var expectedOutputContents = @" + + + Flags + + int + + int + + 1 + + + + Flags + + int + + int + + 1 + + + + + +"; + + var withAttributes = new Dictionary> + { + ["*"] = new List() { "Flags" } + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withAttributes: withAttributes); + } + + public override Task WithAttributeStarPlusTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = 1, +}; +"; + + var expectedOutputContents = @" + + + Flags + + int + + int + + 1 + + + + Flags + EditorBrowsable(EditorBrowsableState.Never) + + int + + int + + 1 + + + + + +"; + + var withAttributes = new Dictionary> + { + ["*"] = new List() { "Flags" }, + ["MyEnum2"] = new List() { "EditorBrowsable(EditorBrowsableState.Never)" } + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withAttributes: withAttributes); + } + + public override Task WithNamespaceTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = MyEnum1_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + + int + + int + + MyEnum1_Value1 + + + + + +"; + + var withNamespaces = new Dictionary> + { + ["MyEnum1"] = new List() { "static ClangSharp.Test.MyEnum1" } + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withUsings: withNamespaces); + } + + public override Task WithNamespaceStarTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = MyEnum1_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + + int + + int + + MyEnum1_Value1 + + + + + +"; + + var withNamespaces = new Dictionary> + { + ["*"] = new List() { "static ClangSharp.Test.MyEnum1" } + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withUsings: withNamespaces); + } + + public override Task WithNamespaceStarPlusTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = MyEnum1_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + + int + + int + + MyEnum1_Value1 + + + + + +"; + + var withNamespaces = new Dictionary> + { + ["*"] = new List() { "static ClangSharp.Test.MyEnum1" }, + ["MyEnum2"] = new List() { "System" } + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withUsings: withNamespaces); + } + + public override Task WithCastToEnumType() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0 = (MyEnum) 10, + MyEnum_Value1 = (MyEnum) MyEnum_Value0, + MyEnum_Value2 = ((MyEnum) 10) + MyEnum_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + (int)(MyEnum)(10) + + + + int + + (int)(MyEnum)(MyEnum_Value0) + + + + int + + ((int)(MyEnum)(10)) + MyEnum_Value1 + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithMultipleEnumsTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value0 = 10, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value0 = MyEnum1_Value0, + MyEnum2_Value1 = MyEnum1_Value0 + (MyEnum1) 10, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 10 + + + + + int + + int + + MyEnum1_Value0 + + + + int + + MyEnum1_Value0 + (int)(MyEnum1)(10) + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithImplicitConversionTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2 = 0x80000000, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + + int + + + int + + + + int + + 0x80000000 + + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithTypeTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; +"; + + var expectedOutputContents = @" + + + + uint + + uint + + + uint + + + uint + + + + +"; + + var withTypes = new Dictionary { + ["MyEnum"] = "uint" + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + + public override Task WithTypeAndImplicitConversionTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2 = 0x80000000, +}; +"; + + var expectedOutputContents = @" + + + + uint + + uint + + + uint + + + uint + + 0x80000000 + + + + + +"; + + var withTypes = new Dictionary + { + ["MyEnum"] = "uint" + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + + public override Task WithTypeStarTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value0 +}; + +enum MyEnum2 : int +{ + MyEnum2_Value0 +}; +"; + + var expectedOutputContents = @" + + + + uint + + uint + + + + uint + + uint + + + + +"; + + var withTypes = new Dictionary + { + ["*"] = "uint" + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + + public override Task WithTypeStarOverrideTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value0 +}; + +enum MyEnum2 : int +{ + MyEnum2_Value0 +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + + + uint + + uint + + + + +"; + + var withTypes = new Dictionary + { + ["*"] = "uint", + ["MyEnum1"] = "int", + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionDeclarationBodyImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionDeclarationBodyImportTest.cs new file mode 100644 index 00000000..581a782c --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionDeclarationBodyImportTest.cs @@ -0,0 +1,2021 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleUnix_FunctionDeclarationBodyImportTest : FunctionDeclarationBodyImportTest + { + public override Task ArraySubscriptTest() + { + var inputContents = @"int MyFunction(int* pData, int index) +{ + return pData[index]; +} +"; + + var expectedOutputContents = @" + + + + + int + + int* + + + int + + return pData[index]; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicTest() + { + var inputContents = @"void MyFunction() +{ +} +"; + + var expectedOutputContents = @" + + + + + void + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BinaryOperatorBasicTest(string opcode) + { + var inputContents = $@"int MyFunction(int x, int y) +{{ + return x {opcode} y; +}} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + + int + + return x {EscapeXml(opcode)} y; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BinaryOperatorCompareTest(string opcode) + { + var inputContents = $@"bool MyFunction(int x, int y) +{{ + return x {opcode} y; +}} +"; + + var expectedOutputContents = $@" + + + + + bool + + int + + + int + + return x {EscapeXml(opcode)} y; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BinaryOperatorBooleanTest(string opcode) + { + var inputContents = $@"bool MyFunction(bool x, bool y) +{{ + return x {opcode} y; +}} +"; + + var expectedOutputContents = $@" + + + + + bool + + bool + + + bool + + return x {EscapeXml(opcode)} y; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BreakTest() + { + var inputContents = @"int MyFunction(int value) +{ + while (true) + { + break; + } + + return 0; +} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + while (true) + {{ + break; + }} + + return 0; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CallFunctionTest() + { + var inputContents = @"void MyCalledFunction() +{ +} + +void MyFunction() +{ + MyCalledFunction(); +} +"; + + var expectedOutputContents = $@" + + + + + void + + + + void + MyCalledFunction(); + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CallFunctionWithArgsTest() + { + var inputContents = @"void MyCalledFunction(int x, int y) +{ +} + +void MyFunction() +{ + MyCalledFunction(0, 1); +} +"; + + var expectedOutputContents = $@" + + + + + void + + int + + + int + + + + + void + MyCalledFunction(0, 1); + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CaseTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + { + case 0: + { + return 0; + } + + case 1: + case 2: + { + return 3; + } + } + + return -1; +} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + switch (value) + {{ + case 0: + {{ + return 0; + }} + + case 1: + case 2: + {{ + return 3; + }} + }} + + return -1; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CaseNoCompoundTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + { + case 0: + return 0; + + case 2: + case 3: + return 5; + } + + return -1; +} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + switch (value) + {{ + case 0: + {{ + return 0; + }} + + case 2: + case 3: + {{ + return 5; + }} + }} + + return -1; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CompareMultipleEnumTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; + +static inline int MyFunction(MyEnum x) +{ + return x == MyEnum_Value0 || + x == MyEnum_Value1 || + x == MyEnum_Value2; +} +"; + + var expectedOutputContents = $@" + + + + int + + int + + + int + + + int + + + + + int + + MyEnum + + return (x == MyEnum_Value0 || x == MyEnum_Value1 || x == MyEnum_Value2) ? 1 : 0; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ConditionalOperatorTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + return condition ? lhs : rhs; +} +"; + + var expectedOutputContents = $@" + + + + + int + + bool + + + int + + + int + + return condition ? lhs : rhs; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ContinueTest() + { + var inputContents = @"int MyFunction(int value) +{ + while (true) + { + continue; + } + + return 0; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + while (true) + { + continue; + } + + return 0; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CStyleFunctionalCastTest() + { + var inputContents = @"int MyFunction(float input) +{ + return (int)input; +} +"; + + var expectedOutputContents = @" + + + + + int + + float + + return (int)(input); + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxFunctionalCastTest() + { + var inputContents = @"int MyFunction(float input) +{ + return int(input); +} +"; + + var expectedOutputContents = @" + + + + + int + + float + + return (int)(input); + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxConstCastTest() + { + var inputContents = @"void* MyFunction(const void* input) +{ + return const_cast(input); +} +"; + + var expectedOutputContents = @" + + + + + void* + + void* + + return input; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxDynamicCastTest() + { + var inputContents = @"struct MyStructA +{ + virtual void MyMethod() = 0; +}; + +struct MyStructB : MyStructA { }; + +MyStructB* MyFunction(MyStructA* input) +{ + return dynamic_cast(input); +} +"; + + var callConv = "Cdecl"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + callConv = "ThisCall"; + } + + var expectedOutputContents = $@" + + + + + void** + + + void + + MyStructA* + + + + void + + fixed (MyStructA* pThis = &this) + {{ + Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))(pThis); + }} + + + + + + void** + + + void + + MyStructB* + + + + void + + fixed (MyStructB* pThis = &this) + {{ + Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))(pThis); + }} + + + + + + MyStructB* + + MyStructA* + + return (MyStructB*)(input); + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxReinterpretCastTest() + { + var inputContents = @"int* MyFunction(void* input) +{ + return reinterpret_cast(input); +} +"; + + var expectedOutputContents = @" + + + + + int* + + void* + + return (int*)(input); + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxStaticCastTest() + { + var inputContents = @"int* MyFunction(void* input) +{ + return static_cast(input); +} +"; + + var expectedOutputContents = @" + + + + + int* + + void* + + return (int*)(input); + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DeclTest() + { + var inputContents = @"\ +int MyFunction() +{ + int x = 0; + int y = 1, z = 2; + return x + y + z; +} +"; + + var expectedOutputContents = @" + + + + + int + int x = 0; + int y = 1, z = 2; + + return x + y + z; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DoTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + do + { + i++; + } + while (i < count); + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + do + { + i++; + } + while (i < count); + + return i; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DoNonCompoundTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + while (i < count) + i++; + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + while (i < count) + { + i++; + } + + return i; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ForTest() + { + var inputContents = @"int MyFunction(int count) +{ + for (int i = 0; i < count; i--) + { + i += 2; + } + + int x; + + for (x = 0; x < count; x--) + { + x += 2; + } + + x = 0; + + for (; x < count; x--) + { + x += 2; + } + + for (int i = 0;;i--) + { + i += 2; + } + + for (x = 0;;x--) + { + x += 2; + } + + for (int i = 0; i < count;) + { + i++; + } + + for (x = 0; x < count;) + { + x++; + } + + // x = 0; + // + // for (;; x--) + // { + // x += 2; + // } + + x = 0; + + for (; x < count;) + { + x++; + } + + for (int i = 0;;) + { + i++; + } + + for (x = 0;;) + { + x++; + } + + for (;;) + { + return -1; + } +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + for (int i = 0; i < count; i--) + { + i += 2; + } + + int x; + + for (x = 0; x < count; x--) + { + x += 2; + } + + x = 0; + for (; x < count; x--) + { + x += 2; + } + + for (int i = 0;; i--) + { + i += 2; + } + + for (x = 0;; x--) + { + x += 2; + } + + for (int i = 0; i < count;) + { + i++; + } + + for (x = 0; x < count;) + { + x++; + } + + x = 0; + for (; x < count;) + { + x++; + } + + for (int i = 0;;) + { + i++; + } + + for (x = 0;;) + { + x++; + } + + for (;;) + { + return -1; + } + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ForNonCompoundTest() + { + var inputContents = @"int MyFunction(int count) +{ + for (int i = 0; i < count; i--) + i += 2; + + int x; + + for (x = 0; x < count; x--) + x += 2; + + x = 0; + + for (; x < count; x--) + x += 2; + + for (int i = 0;;i--) + i += 2; + + for (x = 0;;x--) + x += 2; + + for (int i = 0; i < count;) + i++; + + for (x = 0; x < count;) + x++; + + // x = 0; + // + // for (;; x--) + // x += 2; + + x = 0; + + for (; x < count;) + x++; + + for (int i = 0;;) + i++; + + for (x = 0;;) + x++; + + for (;;) + return -1; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + for (int i = 0; i < count; i--) + { + i += 2; + } + + int x; + + for (x = 0; x < count; x--) + { + x += 2; + } + + x = 0; + for (; x < count; x--) + { + x += 2; + } + + for (int i = 0;; i--) + { + i += 2; + } + + for (x = 0;; x--) + { + x += 2; + } + + for (int i = 0; i < count;) + { + i++; + } + + for (x = 0; x < count;) + { + x++; + } + + x = 0; + for (; x < count;) + { + x++; + } + + for (int i = 0;;) + { + i++; + } + + for (x = 0;;) + { + x++; + } + + for (;;) + { + return -1; + } + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + if (condition) + { + return lhs; + } + + return rhs; +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + if (condition) + { + return lhs; + } + + return rhs; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfElseTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + if (condition) + { + return lhs; + } + else + { + return rhs; + } +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + if (condition) + { + return lhs; + } + else + { + return rhs; + } + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfElseIfTest() + { + var inputContents = @"int MyFunction(bool condition1, int a, int b, bool condition2, int c) +{ + if (condition1) + { + return a; + } + else if (condition2) + { + return b; + } + + return c; +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + + bool + + + int + + if (condition1) + { + return a; + } + else if (condition2) + { + return b; + } + + return c; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfElseNonCompoundTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + if (condition) + return lhs; + else + return rhs; +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + if (condition) + { + return lhs; + } + else + { + return rhs; + } + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task InitListForArrayTest() + { + var inputContents = @" +void MyFunction() +{ + int x[4] = { 1, 2, 3, 4 }; + int y[4] = { 1, 2, 3 }; + int z[] = { 1, 2 }; +} +"; + + var expectedOutputContents = @" + + + + + void + int[] x = new int[4] + { + 1, + 2, + 3, + 4, + }; + int[] y = new int[4] + { + 1, + 2, + 3, + default, + }; + int[] z = new int[2] + { + 1, + 2, + }; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task InitListForRecordDeclTest() + { + var inputContents = @"struct MyStruct +{ + float x; + float y; + float z; + float w; +}; + +MyStruct MyFunction1() +{ + return { 1.0f, 2.0f, 3.0f, 4.0f }; +} + +MyStruct MyFunction2() +{ + return { 1.0f, 2.0f, 3.0f }; +} +"; + + var expectedOutputContents = @" + + + + + float + + + float + + + float + + + float + + + + + MyStruct + return new MyStruct + { + x = 1.0f, + y = 2.0f, + z = 3.0f, + w = 4.0f, + }; + + + MyStruct + return new MyStruct + { + x = 1.0f, + y = 2.0f, + z = 3.0f, + }; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MemberTest() + { + var inputContents = @"struct MyStruct +{ + int value; +}; + +int MyFunction1(MyStruct instance) +{ + return instance.value; +} + +int MyFunction2(MyStruct* instance) +{ + return instance->value; +} +"; + + var expectedOutputContents = @" + + + + + int + + + + + int + + MyStruct + + return instance.value; + + + int + + MyStruct* + + return instance->value; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RefToPtrTest() + { + var inputContents = @"struct MyStruct { + int value; +}; + +bool MyFunction(const MyStruct& lhs, const MyStruct& rhs) +{ + return lhs.value == rhs.value; +} +"; + + var expectedOutputContents = @" + + + + + int + + + + + bool + + MyStruct* + + + MyStruct* + + return lhs->value == rhs->value; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnCXXNullPtrTest() + { + var inputContents = @"void* MyFunction() +{ + return nullptr; +} +"; + + var expectedOutputContents = @" + + + + + void* + return null; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnCXXBooleanLiteralTest(string value) + { + var inputContents = $@"bool MyFunction() +{{ + return {value}; +}} +"; + + var expectedOutputContents = $@" + + + + + bool + return {value}; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnFloatingLiteralDoubleTest(string value) + { + var inputContents = $@"double MyFunction() +{{ + return {value}; +}} +"; + + var expectedOutputContents = $@" + + + + + double + return {value}; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnFloatingLiteralSingleTest(string value) + { + var inputContents = $@"float MyFunction() +{{ + return {value}; +}} +"; + + var expectedOutputContents = $@" + + + + + float + return {value}; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnEmptyTest() + { + var inputContents = @"void MyFunction() +{ + return; +} +"; + + var expectedOutputContents = @" + + + + + void + return; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnIntegerLiteralInt32Test() + { + var inputContents = @"int MyFunction() +{ + return -1; +} +"; + + var expectedOutputContents = @" + + + + + int + return -1; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task AccessUnionMemberTest() + { + var inputContents = @"union MyUnion +{ + struct { int a; }; +}; + +void MyFunction() +{ + MyUnion myUnion; + myUnion.a = 10; +} +"; + + var expectedOutputContents = @" + + + + + _Anonymous_e__Struct + + + ref int + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + { + return ref pField->a; + } + + + + + int + + + + + + void + MyUnion myUnion = new MyUnion(); + + myUnion.Anonymous.a = 10; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnStructTest() + { + var inputContents = @"struct MyStruct +{ + double r; + double g; + double b; +}; + +MyStruct MyFunction() +{ + MyStruct myStruct; + return myStruct; +} +"; + + var expectedOutputContents = @" + + + + + double + + + double + + + double + + + + + MyStruct + MyStruct myStruct = new MyStruct(); + + return myStruct; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SwitchTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + { + default: + { + return 0; + } + } +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + switch (value) + { + default: + { + return 0; + } + } + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SwitchNonCompoundTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + default: + { + return 0; + } + + switch (value) + default: + return 0; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + switch (value) + { + default: + { + return 0; + } + } + + switch (value) + { + default: + { + return 0; + } + } + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorAddrOfTest() + { + var inputContents = @"int* MyFunction(int value) +{ + return &value; +} +"; + + var expectedOutputContents = @" + + + + + int* + + int + + return &value; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorDerefTest() + { + var inputContents = @"int MyFunction(int* value) +{ + return *value; +} +"; + + var expectedOutputContents = @" + + + + + int + + int* + + return *value; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorLogicalNotTest() + { + var inputContents = @"bool MyFunction(bool value) +{ + return !value; +} +"; + + var expectedOutputContents = @" + + + + + bool + + bool + + return !value; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorPostfixTest(string opcode) + { + var inputContents = $@"int MyFunction(int value) +{{ + return value{opcode}; +}} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + return value{opcode}; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorPrefixTest(string opcode) + { + var inputContents = $@"int MyFunction(int value) +{{ + return {opcode}value; +}} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + return {opcode}value; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WhileTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + while (i < count) + { + i++; + } + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + while (i < count) + { + i++; + } + + return i; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WhileNonCompoundTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + while (i < count) + i++; + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + while (i < count) + { + i++; + } + + return i; + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionDeclarationDllImportTest.cs new file mode 100644 index 00000000..f46aa235 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionDeclarationDllImportTest.cs @@ -0,0 +1,399 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleUnix_FunctionDeclarationDllImportTest : FunctionDeclarationDllImportTest + { + public override Task BasicTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ArrayParameterTest() + { + var inputContents = @"void MyFunction(const float color[4]);"; + + var expectedOutputContents = @" + + + + + void + + float* + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FunctionPointerParameterTest() + { + var inputContents = @"void MyFunction(void (*callback)());"; + + var expectedOutputContents = @" + + + + + void + + IntPtr + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) + { + var inputContents = @$"template struct MyTemplate; + +void MyFunction(MyTemplate<{nativeType}> myStruct);"; + + var expectedOutputContents = $@" + + + + + void + + MyTemplate<{expectedManagedType}> + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: new[] { "MyTemplate" }); + } + + public override Task TemplateMemberTest() + { + var inputContents = @$"template struct MyTemplate +{{ +}}; + +struct MyStruct +{{ + MyTemplate a; +}}; +"; + + var expectedOutputContents = $@" + + + + + MyTemplate<IntPtr> + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: new[] { "MyTemplate" }); + } + + public override Task NoLibraryPathTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty); + } + + public override Task WithLibraryPathTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + var withLibraryPaths = new Dictionary + { + ["MyFunction"] = "ClangSharpPInvokeGenerator" + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty, withLibraryPaths: withLibraryPaths); + } + + public override Task WithLibraryPathStarTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + var withLibraryPaths = new Dictionary + { + ["*"] = "ClangSharpPInvokeGenerator" + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty, withLibraryPaths: withLibraryPaths); + } + + public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) + { + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + + var expectedOutputContents = $@" + + + + + void + + {expectedManagedType} + + {expectedManagedInit} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) + { + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + + var expectedOutputContents = $@" + + + + + void + + {expectedManagedType} + + {expectedManagedInit} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithCallConvTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withCallConvs = new Dictionary { + ["MyFunction1"] = "Winapi" + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withCallConvs: withCallConvs); + } + + public override Task WithCallConvStarTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withCallConvs = new Dictionary + { + ["*"] = "Winapi" + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withCallConvs: withCallConvs); + } + + public override Task WithCallConvStarOverrideTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withCallConvs = new Dictionary + { + ["*"] = "Winapi", + ["MyFunction2"] = "StdCall" + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withCallConvs: withCallConvs); + } + + public override Task WithSetLastErrorTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withSetLastErrors = new string[] + { + "MyFunction1" + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withSetLastErrors: withSetLastErrors); + } + + public override Task WithSetLastErrorStarTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withSetLastErrors = new string[] + { + "*" + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, withSetLastErrors: withSetLastErrors); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionPointerDeclarationTest.cs new file mode 100644 index 00000000..abea8fc0 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/FunctionPointerDeclarationTest.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleUnix_FunctionPointerDeclarationTest : FunctionPointerDeclarationTest + { + public override Task BasicTest() + { + var inputContents = @"typedef void (*Callback)();"; + + var expectedOutputContents = @" + + + + void + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/StructDeclarationTest.cs new file mode 100644 index 00000000..03d6176b --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/StructDeclarationTest.cs @@ -0,0 +1,1498 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleUnix_StructDeclarationTest : StructDeclarationTest + { + public override Task BasicTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicTestInCMode(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef struct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}} MyStruct; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + } + + public override Task BasicWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BitfieldTest() + { + var inputContents = @"struct MyStruct1 +{ + unsigned int o0_b0_24 : 24; + unsigned int o4_b0_16 : 16; + unsigned int o4_b16_3 : 3; + int o4_b19_3 : 3; + unsigned char o8_b0_1 : 1; + int o12_b0_1 : 1; + int o12_b1_1 : 1; +}; + +struct MyStruct2 +{ + unsigned int o0_b0_1 : 1; + int x; + unsigned int o8_b0_1 : 1; +}; + +struct MyStruct3 +{ + unsigned int o0_b0_1 : 1; + unsigned int o0_b1_1 : 1; +}; +"; + + var expectedOutputContents = @" + + + + + uint + + + uint + + return _bitfield1 & 0xFFFFFFu; + + + + _bitfield1 = (_bitfield1 & ~0xFFFFFFu) | (value & 0xFFFFFFu); + + + + uint + + + uint + + return _bitfield2 & 0xFFFFu; + + + + _bitfield2 = (_bitfield2 & ~0xFFFFu) | (value & 0xFFFFu); + + + + uint + + return (_bitfield2 >> 16) & 0x7u; + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 16)) | ((value & 0x7u) << 16); + + + + int + + return (int)((_bitfield2 >> 19) & 0x7u); + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 19)) | (uint)((value & 0x7) << 19); + + + + byte + + return (byte)((_bitfield2 >> 22) & 0x1u); + + + + _bitfield2 = (_bitfield2 & ~(0x1u << 22)) | (uint)((value & 0x1u) << 22); + + + + int + + return (int)((_bitfield2 >> 23) & 0x1u); + + + + _bitfield2 = (_bitfield2 & ~(0x1u << 23)) | (uint)((value & 0x1) << 23); + + + + int + + return (int)((_bitfield2 >> 24) & 0x1u); + + + + _bitfield2 = (_bitfield2 & ~(0x1u << 24)) | (uint)((value & 0x1) << 24); + + + + + + uint + + + uint + + return _bitfield1 & 0x1u; + + + + _bitfield1 = (_bitfield1 & ~0x1u) | (value & 0x1u); + + + + int + + + uint + + + uint + + return _bitfield2 & 0x1u; + + + + _bitfield2 = (_bitfield2 & ~0x1u) | (value & 0x1u); + + + + + + uint + + + uint + + return _bitfield & 0x1u; + + + + _bitfield = (_bitfield & ~0x1u) | (value & 0x1u); + + + + uint + + return (_bitfield >> 1) & 0x1u; + + + + _bitfield = (_bitfield & ~(0x1u << 1)) | ((value & 0x1u) << 1); + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExcludeTest() + { + var inputContents = "typedef struct MyStruct MyStruct;"; + var expectedOutputContents = string.Empty; + + var excludedNames = new string[] { "MyStruct" }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task FixedSizedBufferNonPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +struct MyOtherStruct +{{ + MyStruct c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + fixed (MyStruct* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +struct MyOtherStruct +{{ + MyStruct c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + fixed (MyStruct* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +typedef MyStruct MyBuffer[3]; + +struct MyOtherStruct +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + fixed (MyStruct* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +struct MyOtherStruct +{{ + MyStruct c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + fixed (MyStruct* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPointerTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + ref {expectedManagedType} + + int + + + fixed ({expectedManagedType}* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyBuffer[3]; + +struct MyStruct +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task GuidTest() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Non-Unix doesn't support __declspec(uuid("")) + return Task.CompletedTask; + } + + var inputContents = $@"#define DECLSPEC_UUID(x) __declspec(uuid(x)) + +struct __declspec(uuid(""00000000-0000-0000-C000-000000000046"")) MyStruct1 +{{ + int x; +}}; + +struct DECLSPEC_UUID(""00000000-0000-0000-C000-000000000047"") MyStruct2 +{{ + int x; +}}; +"; + + var expectedOutputContents = $@" + + + + + int + + + + + int + + + + + + + + +"; + + var excludedNames = new string[] { "DECLSPEC_UUID" }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task InheritanceTest() + { + var inputContents = @"struct MyStruct1A +{ + int x; + int y; +}; + +struct MyStruct1B +{ + int x; + int y; +}; + +struct MyStruct2 : MyStruct1A, MyStruct1B +{ + int z; + int w; +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + + + int + + + int + + + + + MyStruct1A + + + MyStruct1B + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column) + { + var inputContents = $@"typedef union {{ + {nativeType} value; +}} MyUnion; + +struct MyStruct +{{ + {nativeType} x; + {nativeType} y; + + struct + {{ + {nativeType} z; + + struct + {{ + {nativeType} value; + }} w; + + MyUnion u; + {nativeType} buffer1[4]; + MyUnion buffer2[4]; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + {expectedManagedType} + + + {expectedManagedType} + + + _Anonymous_e__Struct + + + ref {expectedManagedType} + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + {{ + return ref pField->z; + }} + + + + ref _Anonymous_e__Struct._w_e__Struct + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + {{ + return ref pField->w; + }} + + + + ref MyUnion + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + {{ + return ref pField->u; + }} + + + + ref {expectedManagedType} + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + {{ + return ref pField->buffer1[0]; + }} + + + + ref _Anonymous_e__Struct._buffer2_e__FixedBuffer + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + {{ + return ref pField->buffer2; + }} + + + + + {expectedManagedType} + + + _w_e__Struct + + + MyUnion + + + {expectedManagedType} + + + MyUnion + + + + {expectedManagedType} + + + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + fixed (MyUnion* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedAnonymousWithBitfieldTest() + { + var inputContents = @"struct MyStruct +{ + int x; + int y; + + struct + { + int z; + + struct + { + int w; + int o0_b0_16 : 16; + int o0_b16_4 : 4; + }; + }; +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + _Anonymous_e__Struct + + + ref int + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + { + return ref pField->z; + } + + + + ref int + + fixed (_Anonymous_e__Struct._Anonymous_e__Struct* pField = &Anonymous.Anonymous) + { + return ref pField->w; + } + + + + int + + return Anonymous.Anonymous.o0_b0_16; + + + Anonymous.Anonymous.o0_b0_16 = value; + + + + int + + return Anonymous.Anonymous.o0_b16_4; + + + Anonymous.Anonymous.o0_b16_4 = value; + + + + + int + + + _Anonymous_e__Struct + + + + int + + + int + + + int + + return _bitfield & 0xFFFF; + + + + _bitfield = (_bitfield & ~0xFFFF) | (value & 0xFFFF); + + + + int + + return (_bitfield >> 16) & 0xF; + + + + _bitfield = (_bitfield & ~(0xF << 16)) | ((value & 0xF) << 16); + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + struct MyNestedStruct + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + struct MyNestedStruct + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordTest() + { + var inputContents = @"struct MyStruct +{ + int Equals; + int Finalize; + int GetHashCode; + int GetType; + int MemberwiseClone; + int ReferenceEquals; + int ToString; +};"; + + var expectedOutputContents = $@" + + + + + int + + + int + + + int + + + int + + + int + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NoDefinitionTest() + { + var inputContents = "typedef struct MyStruct MyStruct;"; + + var expectedOutputContents = $@" + + + + + +"; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfTest() + { + var inputContents = @"struct example_s { + example_s* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfViaTypedefTest() + { + var inputContents = @"typedef struct example_s example_t; + +struct example_s { + example_t* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RemapTest() + { + var inputContents = "typedef struct _MyStruct MyStruct;"; + + var expectedOutputContents = $@" + + + + + +"; + + var remappedNames = new Dictionary { ["_MyStruct"] = "MyStruct" }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task RemapNestedAnonymousTest() + { + var inputContents = @"struct MyStruct +{ + double r; + double g; + double b; + + struct + { + double a; + }; +};"; + + var expectedOutputContents = @" + + + + + double + + + double + + + double + + + _Anonymous_e__Struct + + + ref double + + fixed (_Anonymous_e__Struct* pField = &Anonymous) + { + return ref pField->a; + } + + + + + double + + + + + +"; + + var remappedNames = new Dictionary { + ["__AnonymousField_ClangUnsavedFile_L7_C5"] = "Anonymous", + ["__AnonymousRecord_ClangUnsavedFile_L7_C5"] = "_Anonymous_e__Struct" + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task SkipNonDefinitionTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef struct MyStruct MyStruct; + +struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionPointerTest() + { + var inputContents = @"typedef struct MyStruct* MyStructPtr; +typedef struct MyStruct& MyStructRef; +"; + + var expectedOutputContents = @" + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef struct MyStruct MyStruct; + +struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task TypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyTypedefAlias; + +struct MyStruct +{{ + MyTypedefAlias r; + MyTypedefAlias g; + MyTypedefAlias b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UsingDeclarationTest() + { + var inputContents = @"struct MyStruct1A +{ + void MyMethod() { } +}; + +struct MyStruct1B : MyStruct1A +{ + using MyStruct1A::MyMethod; +}; +"; + + var expectedOutputContents = @" + + + + + void + + + + + + void + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs new file mode 100644 index 00000000..9e4699dc --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs @@ -0,0 +1,1348 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleUnix_UnionDeclarationTest : UnionDeclarationTest + { + public override Task BasicTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicTestInCMode(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef union +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}} MyUnion; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + } + + public override Task BasicWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BitfieldTest() + { + var inputContents = @"union MyUnion1 +{ + unsigned int o0_b0_24 : 24; + unsigned int o4_b0_16 : 16; + unsigned int o4_b16_3 : 3; + int o4_b19_3 : 3; + unsigned char o8_b0_1 : 1; + int o12_b0_1 : 1; + int o12_b1_1 : 1; +}; + +union MyUnion2 +{ + unsigned int o0_b0_1 : 1; + int x; + unsigned int o8_b0_1 : 1; +}; + +union MyUnion3 +{ + unsigned int o0_b0_1 : 1; + unsigned int o0_b1_1 : 1; +}; +"; + + string expectedPack = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ", Pack = 1" : ""; + + var expectedOutputContents = $@" + + + + + uint + + + uint + + return _bitfield1 & 0xFFFFFFu; + + + + _bitfield1 = (_bitfield1 & ~0xFFFFFFu) | (value & 0xFFFFFFu); + + + + uint + + + uint + + return _bitfield2 & 0xFFFFu; + + + + _bitfield2 = (_bitfield2 & ~0xFFFFu) | (value & 0xFFFFu); + + + + uint + + return (_bitfield2 >> 16) & 0x7u; + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 16)) | ((value & 0x7u) << 16); + + + + int + + return (int)((_bitfield2 >> 19) & 0x7u); + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 19)) | (uint)((value & 0x7) << 19); + + + + byte + + return (byte)((_bitfield2 >> 22) & 0x1u); + + + + _bitfield2 = (_bitfield2 & ~(0x1u << 22)) | (uint)((value & 0x1u) << 22); + + + + int + + return (int)((_bitfield2 >> 23) & 0x1u); + + + + _bitfield2 = (_bitfield2 & ~(0x1u << 23)) | (uint)((value & 0x1) << 23); + + + + int + + return (int)((_bitfield2 >> 24) & 0x1u); + + + + _bitfield2 = (_bitfield2 & ~(0x1u << 24)) | (uint)((value & 0x1) << 24); + + + + + + uint + + + uint + + return _bitfield1 & 0x1u; + + + + _bitfield1 = (_bitfield1 & ~0x1u) | (value & 0x1u); + + + + int + + + uint + + + uint + + return _bitfield2 & 0x1u; + + + + _bitfield2 = (_bitfield2 & ~0x1u) | (value & 0x1u); + + + + + + uint + + + uint + + return _bitfield & 0x1u; + + + + _bitfield = (_bitfield & ~0x1u) | (value & 0x1u); + + + + uint + + return (_bitfield >> 1) & 0x1u; + + + + _bitfield = (_bitfield & ~(0x1u << 1)) | ((value & 0x1u) << 1); + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExcludeTest() + { + var inputContents = "typedef union MyUnion MyUnion;"; + var expectedOutputContents = string.Empty; + + var excludedNames = new string[] { "MyUnion" }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task FixedSizedBufferNonPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +union MyOtherUnion +{{ + MyUnion c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + fixed (MyUnion* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +union MyOtherUnion +{{ + MyUnion c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + fixed (MyUnion* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +typedef MyUnion MyBuffer[3]; + +union MyOtherUnion +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + fixed (MyUnion* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +union MyOtherUnion +{{ + MyUnion c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + fixed (MyUnion* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPointerTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + ref {expectedManagedType} + + int + + + fixed ({expectedManagedType}* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyBuffer[3]; + +union MyUnion +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + public override Task GuidTest() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Non-Unix doesn't support __declspec(uuid("")) + return Task.CompletedTask; + } + + var inputContents = $@"#define DECLSPEC_UUID(x) __declspec(uuid(x)) + +union __declspec(uuid(""00000000-0000-0000-C000-000000000046"")) MyUnion1 +{{ + int x; +}}; + +union DECLSPEC_UUID(""00000000-0000-0000-C000-000000000047"") MyUnion2 +{{ + int x; +}}; +"; + + var expectedOutputContents = $@" + + + + + int + + + + + int + + + + + + + + +"; + + var excludedNames = new string[] { "DECLSPEC_UUID" }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column) + { + var inputContents = $@"typedef struct {{ + {nativeType} value; +}} MyStruct; + +union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + union + {{ + {nativeType} a; + + MyStruct s; + + {nativeType} buffer[4]; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + _Anonymous_e__Union + + + ref {expectedManagedType} + + fixed (_Anonymous_e__Union* pField = &Anonymous) + {{ + return ref pField->a; + }} + + + + ref MyStruct + + fixed (_Anonymous_e__Union* pField = &Anonymous) + {{ + return ref pField->s; + }} + + + + ref {expectedManagedType} + + fixed (_Anonymous_e__Union* pField = &Anonymous) + {{ + return ref pField->buffer[0]; + }} + + + + + {expectedManagedType} + + + MyStruct + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedAnonymousWithBitfieldTest() + { + var inputContents = @"union MyUnion +{ + int x; + int y; + + union + { + int z; + + union + { + int w; + int o0_b0_16 : 16; + int o0_b16_4 : 4; + }; + }; +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + _Anonymous_e__Union + + + ref int + + fixed (_Anonymous_e__Union* pField = &Anonymous) + { + return ref pField->z; + } + + + + ref int + + fixed (_Anonymous_e__Union._Anonymous_e__Union* pField = &Anonymous.Anonymous) + { + return ref pField->w; + } + + + + int + + return Anonymous.Anonymous.o0_b0_16; + + + Anonymous.Anonymous.o0_b0_16 = value; + + + + int + + return Anonymous.Anonymous.o0_b16_4; + + + Anonymous.Anonymous.o0_b16_4 = value; + + + + + int + + + _Anonymous_e__Union + + + + int + + + int + + + int + + return _bitfield & 0xFFFF; + + + + _bitfield = (_bitfield & ~0xFFFF) | (value & 0xFFFF); + + + + int + + return (_bitfield >> 16) & 0xF; + + + + _bitfield = (_bitfield & ~(0xF << 16)) | ((value & 0xF) << 16); + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + + public override Task NestedTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + union MyNestedUnion + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + union MyNestedUnion + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordTest() + { + var inputContents = @"union MyUnion +{ + int Equals; + int Finalize; + int GetHashCode; + int GetType; + int MemberwiseClone; + int ReferenceEquals; + int ToString; +};"; + + var expectedOutputContents = $@" + + + + + int + + + int + + + int + + + int + + + int + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NoDefinitionTest() + { + var inputContents = "typedef union MyUnion MyUnion;"; + + var expectedOutputContents = $@" + + + + + +"; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfTest() + { + var inputContents = @"union example_s { + example_s* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfViaTypedefTest() + { + var inputContents = @"typedef union example_s example_t; + +union example_s { + example_t* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RemapTest() + { + var inputContents = "typedef union _MyUnion MyUnion;"; + + var expectedOutputContents = $@" + + + + + +"; + + var remappedNames = new Dictionary { ["_MyUnion"] = "MyUnion" }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task RemapNestedAnonymousTest() + { + var inputContents = @"union MyUnion +{ + double r; + double g; + double b; + + union + { + double a; + }; +};"; + + var expectedOutputContents = @" + + + + + double + + + double + + + double + + + _Anonymous_e__Union + + + ref double + + fixed (_Anonymous_e__Union* pField = &Anonymous) + { + return ref pField->a; + } + + + + + double + + + + + +"; + + var remappedNames = new Dictionary { + ["__AnonymousField_ClangUnsavedFile_L7_C5"] = "Anonymous", + ["__AnonymousRecord_ClangUnsavedFile_L7_C5"] = "_Anonymous_e__Union" + }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task SkipNonDefinitionTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef union MyUnion MyUnion; + +union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionPointerTest() + { + var inputContents = @"typedef union MyUnion* MyUnionPtr; +typedef union MyUnion& MyUnionRef; +"; + + var expectedOutputContents = @" + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef union MyUnion MyUnion; + +union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task TypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyTypedefAlias; + +union MyUnion +{{ + MyTypedefAlias r; + MyTypedefAlias g; + MyTypedefAlias b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/VarDeclarationTest.cs new file mode 100644 index 00000000..f43170a7 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/VarDeclarationTest.cs @@ -0,0 +1,353 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlCompatibleUnix_VarDeclarationTest : VarDeclarationTest + { + public override Task BasicTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"{nativeType} MyVariable = 0;"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + 0 + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"{nativeType} MyVariable = 0;"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + 0 + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task GuidMacroTest() + { + var inputContents = $@"struct GUID {{ + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; +}}; + +const GUID IID_IUnknown = {{ 0x00000000, 0x0000, 0x0000, {{ 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 }} }}; +"; + + var expectedOutputContents = $@" + + + + + Guid + + new Guid(0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46) + + + + + +"; + var excludedNames = new string[] { "GUID" }; + var remappedNames = new Dictionary { ["GUID"] = "Guid" }; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames, remappedNames: remappedNames); + } + + public override Task MacroTest(string nativeValue, string expectedManagedType, string expectedManagedValue) + { + var inputContents = $@"#define MyMacro1 {nativeValue} +#define MyMacro2 MyMacro1"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + {expectedManagedValue} + + + + {expectedManagedType} + + {expectedManagedValue} + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MultilineMacroTest() + { + var inputContents = $@"#define MyMacro1 0 + \ +1"; + + var expectedOutputContents = $@" + + + + + int + + 0 + 1 + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NoInitializerTest(string nativeType) + { + var inputContents = $@"{nativeType} MyVariable;"; + var expectedOutputContents = ""; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task Utf8StringLiteralMacroTest() + { + var inputContents = $@"#define MyMacro1 ""Test"""; + + var expectedOutputContents = $@" + + + + + ReadOnlySpan<byte> + + new byte[] {{ 0x54, 0x65, 0x73, 0x74, 0x00 }} + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task Utf16StringLiteralMacroTest() + { + var inputContents = $@"#define MyMacro1 u""Test"""; + + var expectedOutputContents = $@" + + + + + string + + ""Test"" + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WideStringLiteralConstTest() + { + // Unsupported string literal kind: 'CX_CLK_Wide' + return Task.CompletedTask; + } + + public override Task StringLiteralConstTest() + { + var inputContents = $@"const char MyConst1[] = ""Test"";"; + + var expectedOutputContents = $@" + + + + + ReadOnlySpan<byte> + + new byte[] {{ 0x54, 0x65, 0x73, 0x74, 0x00 }} + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedConversionMacroTest() + { + var inputContents = $@"#define MyMacro1 (long)0x80000000L +#define MyMacro2 (int)0x80000000"; + + var expectedOutputContents = $@" + + + + + IntPtr + + (IntPtr)(0x80000000) + + + + int + + + + (int)(0x80000000) + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedFunctionLikeCastMacroTest() + { + var inputContents = $@"#define MyMacro1 unsigned(-1)"; + + var expectedOutputContents = $@" + + + + + uint + + + + (uint)(-1) + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedConversionMacroTest2() + { + var inputContents = $@"#define MyMacro1(x, y, z) ((int)(((unsigned long)(x)<<31) | ((unsigned long)(y)<<16) | ((unsigned long)(z)))) +#define MyMacro2(n) MyMacro1(1, 2, n) +#define MyMacro3 MyMacro2(3)"; + + var expectedOutputContents = $@" + + + + + int + + + ((int)(((UIntPtr)(1) << 31) | ((UIntPtr)(2) << 16) | ((UIntPtr)(3)))) + + + + + + +"; + + var excludedNames = new string[] { "MyMacro1", "MyMacro2" }; + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task UncheckedPointerMacroTest() + { + var inputContents = $@"#define Macro1 ((int*) -1)"; + + var expectedOutputContents = $@" + + + + + int* + + + ((int*)(-1)) + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedReinterpretCastMacroTest() + { + var inputContents = $@"#define Macro1 reinterpret_cast(-1)"; + + var expectedOutputContents = $@" + + + + + int* + + + + (int*)(-1) + + + + + + + +"; + + return ValidateGeneratedXmlCompatibleUnixBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationBodyImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationBodyImportTest.cs index 2d48049d..93539671 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationBodyImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/FunctionDeclarationBodyImportTest.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. using System; -using System.Reflection.Emit; using System.Runtime.InteropServices; using System.Threading.Tasks; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs new file mode 100644 index 00000000..4baa99cd --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/CXXMethodDeclarationTest.cs @@ -0,0 +1,912 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestUnix_CXXMethodDeclarationTest : CXXMethodDeclarationTest + { + public override Task ConstructorTest() + { + var inputContents = @"struct MyStruct +{ + int _value; + + MyStruct(int value) + { + _value = value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + void + + int + + _value = value; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ConstructorWithInitializeTest() + { + var inputContents = @"struct MyStruct +{ + int _x; + int _y; + int _z; + + MyStruct(int x) : _x(x) + { + } + + MyStruct(int x, int y) : _x(x), _y(y) + { + } + + MyStruct(int x, int y, int z) : _x(x), _y(y), _z() + { + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + int + + + void + + int + + + x + + + + + void + + int + + + int + + + x + + + y + + + + + void + + int + + + int + + + int + + + x + + + y + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ConversionTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + operator int() + { + return value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + return value; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DestructorTest() + { + var inputContents = @"struct MyStruct +{ + ~MyStruct() + { + } +}; +"; + + var expectedOutputContents = @" + + + + + void + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task InstanceTest() + { + var inputContents = @"struct MyStruct +{ + void MyVoidMethod(); + + int MyInt32Method() + { + return 0; + } + + void* MyVoidStarMethod() + { + return nullptr; + } +}; +"; + var callConv = "Cdecl"; + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__ZN8MyStruct12MyVoidMethodEv" : "_ZN8MyStruct12MyVoidMethodEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + if (!Environment.Is64BitProcess) + { + callConv = "ThisCall"; + entryPoint = "?MyVoidMethod@MyStruct@@QAEXXZ"; + } + else + { + entryPoint = "?MyVoidMethod@MyStruct@@QEAAXXZ"; + } + } + + var expectedOutputContents = $@" + + + + + void + + + int + return 0; + + + void* + return null; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MemberCallTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + int MyFunction1() + { + return value; + } + + int MyFunction2() + { + return MyFunction1(); + } + + int MyFunction3() + { + return this->MyFunction1(); + } +}; + +int MyFunctionA(MyStruct x) +{ + return x.MyFunction1(); +} + +int MyFunctionB(MyStruct* x) +{ + return x->MyFunction2(); +} +"; + + var expectedOutputContents = @" + + + + + int + + + int + return value; + + + int + return MyFunction1(); + + + int + return this.MyFunction1(); + + + + + int + + MyStruct + + return x.MyFunction1(); + + + int + + MyStruct* + + return x->MyFunction2(); + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MemberTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + int MyFunction() + { + return value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + return value; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordTest() + { + var inputContents = @"struct MyStruct +{ + int Equals() { return 0; } + int Equals(int obj) { return 0; } + int Finalize() { return 0; } + int Finalize(int obj) { return 0; } + int GetHashCode() { return 0; } + int GetHashCode(int obj) { return 0; } + int GetType() { return 0; } + int GetType(int obj) { return 0; } + int MemberwiseClone() { return 0; } + int MemberwiseClone(int obj) { return 0; } + int ReferenceEquals() { return 0; } + int ReferenceEquals(int obj) { return 0; } + int ToString() { return 0; } + int ToString(int obj) { return 0; } +};"; + + var expectedOutputContents = $@" + + + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + int + return 0; + + + int + + int + + return 0; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordVirtualTest() + { + var inputContents = @"struct MyStruct +{ + virtual int GetType(int obj) = 0; + virtual int GetType() = 0; + virtual int GetType(int objA, int objB) = 0; +};"; + + var callConv = "Cdecl"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + callConv = "ThisCall"; + } + + var expectedOutputContents = $@" + + + + + void** + + + int + + MyStruct* + + + int + + + + int + + MyStruct* + + + + int + + MyStruct* + + + int + + + int + + + + int + + int + + + return Marshal.GetDelegateForFunctionPointer<_GetType>((IntPtr)(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this), obj); + + + + int + + return Marshal.GetDelegateForFunctionPointer<_GetType1>((IntPtr)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this)); + + + + int + + int + + + int + + + return Marshal.GetDelegateForFunctionPointer<_GetType2>((IntPtr)(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this), objA, objB); + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task OperatorTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + MyStruct(int value) : value(value) + { + } + + MyStruct operator+(MyStruct rhs) + { + return MyStruct(value + rhs.value); + } +}; + +MyStruct operator-(MyStruct lhs, MyStruct rhs) +{ + return MyStruct(lhs.value - rhs.value); +} +"; + + var expectedOutputContents = @" + + + + + int + + + void + + int + + + value + + + + + MyStruct + + MyStruct + + return new MyStruct(value + rhs.value); + + + + + MyStruct + + MyStruct + + + MyStruct + + return new MyStruct(lhs.value - rhs.value); + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task OperatorCallTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + MyStruct(int value) : value(value) + { + } + + MyStruct operator+(MyStruct rhs) + { + return MyStruct(value + rhs.value); + } +}; + +MyStruct MyFunction1(MyStruct lhs, MyStruct rhs) +{ + return lhs + rhs; +} + +MyStruct operator-(MyStruct lhs, MyStruct rhs) +{ + return MyStruct(lhs.value - rhs.value); +} + +MyStruct MyFunction2(MyStruct lhs, MyStruct rhs) +{ + return lhs - rhs; +} +"; + + var expectedOutputContents = @" + + + + + int + + + void + + int + + + value + + + + + MyStruct + + MyStruct + + return new MyStruct(value + rhs.value); + + + + + MyStruct + + MyStruct + + + MyStruct + + return lhs.Add(rhs); + + + MyStruct + + MyStruct + + + MyStruct + + return new MyStruct(lhs.value - rhs.value); + + + MyStruct + + MyStruct + + + MyStruct + + return Subtract(lhs, rhs); + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task StaticTest() + { + var inputContents = @"struct MyStruct +{ + static void MyVoidMethod(); + + static int MyInt32Method() + { + return 0; + } + + static void* MyVoidStarMethod() + { + return nullptr; + } +}; +"; + + var entryPoint = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "?MyVoidMethod@MyStruct@@SAXXZ" : "_ZN8MyStruct12MyVoidMethodEv"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + entryPoint = $"_{entryPoint}"; + } + + var expectedOutputContents = $@" + + + + + void + + + int + return 0; + + + void* + return null; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ThisTest() + { + var inputContents = @"struct MyStruct +{ + int value; + + int MyFunction() + { + return this->value; + } +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + return this.value; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnsafeDoesNotImpactDllImportTest() + { + var inputContents = @"struct MyStruct +{ + void* MyVoidStarMethod() + { + return nullptr; + } +}; + +void MyFunction();"; + + var expectedOutputContents = @" + + + + + void* + return null; + + + + + void + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task VirtualTest() + { + var inputContents = @"struct MyStruct +{ + virtual void MyVoidMethod() = 0; + + virtual char MyInt8Method() + { + return 0; + } + + virtual int MyInt32Method(); + + virtual void* MyVoidStarMethod() = 0; +}; +"; + + var callConv = "Cdecl"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + callConv = "ThisCall"; + } + + var expectedOutputContents = $@" + + + + + void** + + + void + + MyStruct* + + + + sbyte + + MyStruct* + + + + int + + MyStruct* + + + + void* + + MyStruct* + + + + void + + Marshal.GetDelegateForFunctionPointer<_MyVoidMethod>((IntPtr)(lpVtbl[0]))((MyStruct*)Unsafe.AsPointer(ref this)); + + + + sbyte + + return Marshal.GetDelegateForFunctionPointer<_MyInt8Method>((IntPtr)(lpVtbl[1]))((MyStruct*)Unsafe.AsPointer(ref this)); + + + + int + + return Marshal.GetDelegateForFunctionPointer<_MyInt32Method>((IntPtr)(lpVtbl[2]))((MyStruct*)Unsafe.AsPointer(ref this)); + + + + void* + + return Marshal.GetDelegateForFunctionPointer<_MyVoidStarMethod>((IntPtr)(lpVtbl[3]))((MyStruct*)Unsafe.AsPointer(ref this)); + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/EnumDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/EnumDeclarationTest.cs new file mode 100644 index 00000000..4f56cd8b --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/EnumDeclarationTest.cs @@ -0,0 +1,752 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestUnix_EnumDeclarationTest : EnumDeclarationTest + { + public override Task BasicTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicValueTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value1 = 1, + MyEnum_Value2, + MyEnum_Value3, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExcludeTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; +"; + + var expectedOutputContents = string.Empty; + + var excludedNames = new string[] { "MyEnum" }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task ExplicitTypedTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"enum MyEnum : {nativeType} +{{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}}; +"; + + var expectedOutputContents = $@" + + + + {EscapeXml(expectedManagedType)} + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExplicitTypedWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"enum MyEnum : {nativeType} +{{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}}; +"; + + var expectedOutputContents = $@" + + + + {EscapeXml(expectedManagedType)} + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + {EscapeXml(expectedManagedType)} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RemapTest() + { + var inputContents = @"typedef enum _MyEnum : int +{ + MyEnum_Value1, + MyEnum_Value2, + MyEnum_Value3, +} MyEnum; +"; + + var expectedOutputContents = @" + + + + int + + int + + + int + + + int + + + + +"; + + var remappedNames = new Dictionary { ["_MyEnum"] = "MyEnum" }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task WithAttributeTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = 1, +}; +"; + + var expectedOutputContents = @" + + + Flags + + int + + int + + 1 + + + + + int + + int + + 1 + + + + + +"; + + var withAttributes = new Dictionary> + { + ["MyEnum1"] = new List() { "Flags" } + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withAttributes: withAttributes); + } + + public override Task WithAttributeStarTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = 1, +}; +"; + + var expectedOutputContents = @" + + + Flags + + int + + int + + 1 + + + + Flags + + int + + int + + 1 + + + + + +"; + + var withAttributes = new Dictionary> + { + ["*"] = new List() { "Flags" } + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withAttributes: withAttributes); + } + + public override Task WithAttributeStarPlusTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = 1, +}; +"; + + var expectedOutputContents = @" + + + Flags + + int + + int + + 1 + + + + Flags + EditorBrowsable(EditorBrowsableState.Never) + + int + + int + + 1 + + + + + +"; + + var withAttributes = new Dictionary> + { + ["*"] = new List() { "Flags" }, + ["MyEnum2"] = new List() { "EditorBrowsable(EditorBrowsableState.Never)" } + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withAttributes: withAttributes); + } + + public override Task WithNamespaceTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = MyEnum1_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + + int + + int + + MyEnum1_Value1 + + + + + +"; + + var withNamespaces = new Dictionary> + { + ["MyEnum1"] = new List() { "static ClangSharp.Test.MyEnum1" } + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withUsings: withNamespaces); + } + + public override Task WithNamespaceStarTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = MyEnum1_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + + int + + int + + MyEnum1_Value1 + + + + + +"; + + var withNamespaces = new Dictionary> + { + ["*"] = new List() { "static ClangSharp.Test.MyEnum1" } + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withUsings: withNamespaces); + } + + public override Task WithNamespaceStarPlusTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value1 = 1, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value1 = MyEnum1_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 1 + + + + + int + + int + + MyEnum1_Value1 + + + + + +"; + + var withNamespaces = new Dictionary> + { + ["*"] = new List() { "static ClangSharp.Test.MyEnum1" }, + ["MyEnum2"] = new List() { "System" } + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withUsings: withNamespaces); + } + + public override Task WithCastToEnumType() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0 = (MyEnum) 10, + MyEnum_Value1 = (MyEnum) MyEnum_Value0, + MyEnum_Value2 = ((MyEnum) 10) + MyEnum_Value1, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + (int)(MyEnum)(10) + + + + int + + (int)(MyEnum)(MyEnum_Value0) + + + + int + + ((int)(MyEnum)(10)) + MyEnum_Value1 + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithMultipleEnumsTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value0 = 10, +}; + +enum MyEnum2 : int +{ + MyEnum2_Value0 = MyEnum1_Value0, + MyEnum2_Value1 = MyEnum1_Value0 + (MyEnum1) 10, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + 10 + + + + + int + + int + + MyEnum1_Value0 + + + + int + + MyEnum1_Value0 + (int)(MyEnum1)(10) + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithImplicitConversionTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2 = 0x80000000, +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + + int + + + int + + + + int + + 0x80000000 + + + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithTypeTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; +"; + + var expectedOutputContents = @" + + + + uint + + uint + + + uint + + + uint + + + + +"; + + var withTypes = new Dictionary { + ["MyEnum"] = "uint" + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + + public override Task WithTypeAndImplicitConversionTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2 = 0x80000000, +}; +"; + + var expectedOutputContents = @" + + + + uint + + uint + + + uint + + + uint + + 0x80000000 + + + + + +"; + + var withTypes = new Dictionary + { + ["MyEnum"] = "uint" + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + + public override Task WithTypeStarTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value0 +}; + +enum MyEnum2 : int +{ + MyEnum2_Value0 +}; +"; + + var expectedOutputContents = @" + + + + uint + + uint + + + + uint + + uint + + + + +"; + + var withTypes = new Dictionary + { + ["*"] = "uint" + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + + public override Task WithTypeStarOverrideTest() + { + var inputContents = @"enum MyEnum1 : int +{ + MyEnum1_Value0 +}; + +enum MyEnum2 : int +{ + MyEnum2_Value0 +}; +"; + + var expectedOutputContents = @" + + + + int + + int + + + + uint + + uint + + + + +"; + + var withTypes = new Dictionary + { + ["*"] = "uint", + ["MyEnum1"] = "int", + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withTypes: withTypes); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationBodyImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationBodyImportTest.cs new file mode 100644 index 00000000..c1f4f4bf --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationBodyImportTest.cs @@ -0,0 +1,2012 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestUnix_FunctionDeclarationBodyImportTest : FunctionDeclarationBodyImportTest + { + public override Task ArraySubscriptTest() + { + var inputContents = @"int MyFunction(int* pData, int index) +{ + return pData[index]; +} +"; + + var expectedOutputContents = @" + + + + + int + + int* + + + int + + return pData[index]; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicTest() + { + var inputContents = @"void MyFunction() +{ +} +"; + + var expectedOutputContents = @" + + + + + void + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BinaryOperatorBasicTest(string opcode) + { + var inputContents = $@"int MyFunction(int x, int y) +{{ + return x {opcode} y; +}} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + + int + + return x {EscapeXml(opcode)} y; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BinaryOperatorCompareTest(string opcode) + { + var inputContents = $@"bool MyFunction(int x, int y) +{{ + return x {opcode} y; +}} +"; + + var expectedOutputContents = $@" + + + + + bool + + int + + + int + + return x {EscapeXml(opcode)} y; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BinaryOperatorBooleanTest(string opcode) + { + var inputContents = $@"bool MyFunction(bool x, bool y) +{{ + return x {opcode} y; +}} +"; + + var expectedOutputContents = $@" + + + + + bool + + bool + + + bool + + return x {EscapeXml(opcode)} y; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BreakTest() + { + var inputContents = @"int MyFunction(int value) +{ + while (true) + { + break; + } + + return 0; +} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + while (true) + {{ + break; + }} + + return 0; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CallFunctionTest() + { + var inputContents = @"void MyCalledFunction() +{ +} + +void MyFunction() +{ + MyCalledFunction(); +} +"; + + var expectedOutputContents = $@" + + + + + void + + + + void + MyCalledFunction(); + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CallFunctionWithArgsTest() + { + var inputContents = @"void MyCalledFunction(int x, int y) +{ +} + +void MyFunction() +{ + MyCalledFunction(0, 1); +} +"; + + var expectedOutputContents = $@" + + + + + void + + int + + + int + + + + + void + MyCalledFunction(0, 1); + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CaseTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + { + case 0: + { + return 0; + } + + case 1: + case 2: + { + return 3; + } + } + + return -1; +} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + switch (value) + {{ + case 0: + {{ + return 0; + }} + + case 1: + case 2: + {{ + return 3; + }} + }} + + return -1; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CaseNoCompoundTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + { + case 0: + return 0; + + case 2: + case 3: + return 5; + } + + return -1; +} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + switch (value) + {{ + case 0: + {{ + return 0; + }} + + case 2: + case 3: + {{ + return 5; + }} + }} + + return -1; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CompareMultipleEnumTest() + { + var inputContents = @"enum MyEnum : int +{ + MyEnum_Value0, + MyEnum_Value1, + MyEnum_Value2, +}; + +static inline int MyFunction(MyEnum x) +{ + return x == MyEnum_Value0 || + x == MyEnum_Value1 || + x == MyEnum_Value2; +} +"; + + var expectedOutputContents = $@" + + + + int + + int + + + int + + + int + + + + + int + + MyEnum + + return (x == MyEnum_Value0 || x == MyEnum_Value1 || x == MyEnum_Value2) ? 1 : 0; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ConditionalOperatorTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + return condition ? lhs : rhs; +} +"; + + var expectedOutputContents = $@" + + + + + int + + bool + + + int + + + int + + return condition ? lhs : rhs; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ContinueTest() + { + var inputContents = @"int MyFunction(int value) +{ + while (true) + { + continue; + } + + return 0; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + while (true) + { + continue; + } + + return 0; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CStyleFunctionalCastTest() + { + var inputContents = @"int MyFunction(float input) +{ + return (int)input; +} +"; + + var expectedOutputContents = @" + + + + + int + + float + + return (int)(input); + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxFunctionalCastTest() + { + var inputContents = @"int MyFunction(float input) +{ + return int(input); +} +"; + + var expectedOutputContents = @" + + + + + int + + float + + return (int)(input); + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxConstCastTest() + { + var inputContents = @"void* MyFunction(const void* input) +{ + return const_cast(input); +} +"; + + var expectedOutputContents = @" + + + + + void* + + void* + + return input; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxDynamicCastTest() + { + var inputContents = @"struct MyStructA +{ + virtual void MyMethod() = 0; +}; + +struct MyStructB : MyStructA { }; + +MyStructB* MyFunction(MyStructA* input) +{ + return dynamic_cast(input); +} +"; + + var callConv = "Cdecl"; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Environment.Is64BitProcess) + { + callConv = "ThisCall"; + } + + var expectedOutputContents = $@" + + + + + void** + + + void + + MyStructA* + + + + void + + Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))((MyStructA*)Unsafe.AsPointer(ref this)); + + + + + + void** + + + void + + MyStructB* + + + + void + + Marshal.GetDelegateForFunctionPointer<_MyMethod>((IntPtr)(lpVtbl[0]))((MyStructB*)Unsafe.AsPointer(ref this)); + + + + + + MyStructB* + + MyStructA* + + return (MyStructB*)(input); + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxReinterpretCastTest() + { + var inputContents = @"int* MyFunction(void* input) +{ + return reinterpret_cast(input); +} +"; + + var expectedOutputContents = @" + + + + + int* + + void* + + return (int*)(input); + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task CxxStaticCastTest() + { + var inputContents = @"int* MyFunction(void* input) +{ + return static_cast(input); +} +"; + + var expectedOutputContents = @" + + + + + int* + + void* + + return (int*)(input); + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DeclTest() + { + var inputContents = @"\ +int MyFunction() +{ + int x = 0; + int y = 1, z = 2; + return x + y + z; +} +"; + + var expectedOutputContents = @" + + + + + int + int x = 0; + int y = 1, z = 2; + + return x + y + z; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DoTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + do + { + i++; + } + while (i < count); + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + do + { + i++; + } + while (i < count); + + return i; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task DoNonCompoundTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + while (i < count) + i++; + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + while (i < count) + { + i++; + } + + return i; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ForTest() + { + var inputContents = @"int MyFunction(int count) +{ + for (int i = 0; i < count; i--) + { + i += 2; + } + + int x; + + for (x = 0; x < count; x--) + { + x += 2; + } + + x = 0; + + for (; x < count; x--) + { + x += 2; + } + + for (int i = 0;;i--) + { + i += 2; + } + + for (x = 0;;x--) + { + x += 2; + } + + for (int i = 0; i < count;) + { + i++; + } + + for (x = 0; x < count;) + { + x++; + } + + // x = 0; + // + // for (;; x--) + // { + // x += 2; + // } + + x = 0; + + for (; x < count;) + { + x++; + } + + for (int i = 0;;) + { + i++; + } + + for (x = 0;;) + { + x++; + } + + for (;;) + { + return -1; + } +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + for (int i = 0; i < count; i--) + { + i += 2; + } + + int x; + + for (x = 0; x < count; x--) + { + x += 2; + } + + x = 0; + for (; x < count; x--) + { + x += 2; + } + + for (int i = 0;; i--) + { + i += 2; + } + + for (x = 0;; x--) + { + x += 2; + } + + for (int i = 0; i < count;) + { + i++; + } + + for (x = 0; x < count;) + { + x++; + } + + x = 0; + for (; x < count;) + { + x++; + } + + for (int i = 0;;) + { + i++; + } + + for (x = 0;;) + { + x++; + } + + for (;;) + { + return -1; + } + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ForNonCompoundTest() + { + var inputContents = @"int MyFunction(int count) +{ + for (int i = 0; i < count; i--) + i += 2; + + int x; + + for (x = 0; x < count; x--) + x += 2; + + x = 0; + + for (; x < count; x--) + x += 2; + + for (int i = 0;;i--) + i += 2; + + for (x = 0;;x--) + x += 2; + + for (int i = 0; i < count;) + i++; + + for (x = 0; x < count;) + x++; + + // x = 0; + // + // for (;; x--) + // x += 2; + + x = 0; + + for (; x < count;) + x++; + + for (int i = 0;;) + i++; + + for (x = 0;;) + x++; + + for (;;) + return -1; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + for (int i = 0; i < count; i--) + { + i += 2; + } + + int x; + + for (x = 0; x < count; x--) + { + x += 2; + } + + x = 0; + for (; x < count; x--) + { + x += 2; + } + + for (int i = 0;; i--) + { + i += 2; + } + + for (x = 0;; x--) + { + x += 2; + } + + for (int i = 0; i < count;) + { + i++; + } + + for (x = 0; x < count;) + { + x++; + } + + x = 0; + for (; x < count;) + { + x++; + } + + for (int i = 0;;) + { + i++; + } + + for (x = 0;;) + { + x++; + } + + for (;;) + { + return -1; + } + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + if (condition) + { + return lhs; + } + + return rhs; +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + if (condition) + { + return lhs; + } + + return rhs; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfElseTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + if (condition) + { + return lhs; + } + else + { + return rhs; + } +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + if (condition) + { + return lhs; + } + else + { + return rhs; + } + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfElseIfTest() + { + var inputContents = @"int MyFunction(bool condition1, int a, int b, bool condition2, int c) +{ + if (condition1) + { + return a; + } + else if (condition2) + { + return b; + } + + return c; +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + + bool + + + int + + if (condition1) + { + return a; + } + else if (condition2) + { + return b; + } + + return c; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task IfElseNonCompoundTest() + { + var inputContents = @"int MyFunction(bool condition, int lhs, int rhs) +{ + if (condition) + return lhs; + else + return rhs; +} +"; + + var expectedOutputContents = @" + + + + + int + + bool + + + int + + + int + + if (condition) + { + return lhs; + } + else + { + return rhs; + } + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task InitListForArrayTest() + { + var inputContents = @" +void MyFunction() +{ + int x[4] = { 1, 2, 3, 4 }; + int y[4] = { 1, 2, 3 }; + int z[] = { 1, 2 }; +} +"; + + var expectedOutputContents = @" + + + + + void + int[] x = new int[4] + { + 1, + 2, + 3, + 4, + }; + int[] y = new int[4] + { + 1, + 2, + 3, + default, + }; + int[] z = new int[2] + { + 1, + 2, + }; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task InitListForRecordDeclTest() + { + var inputContents = @"struct MyStruct +{ + float x; + float y; + float z; + float w; +}; + +MyStruct MyFunction1() +{ + return { 1.0f, 2.0f, 3.0f, 4.0f }; +} + +MyStruct MyFunction2() +{ + return { 1.0f, 2.0f, 3.0f }; +} +"; + + var expectedOutputContents = @" + + + + + float + + + float + + + float + + + float + + + + + MyStruct + return new MyStruct + { + x = 1.0f, + y = 2.0f, + z = 3.0f, + w = 4.0f, + }; + + + MyStruct + return new MyStruct + { + x = 1.0f, + y = 2.0f, + z = 3.0f, + }; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MemberTest() + { + var inputContents = @"struct MyStruct +{ + int value; +}; + +int MyFunction1(MyStruct instance) +{ + return instance.value; +} + +int MyFunction2(MyStruct* instance) +{ + return instance->value; +} +"; + + var expectedOutputContents = @" + + + + + int + + + + + int + + MyStruct + + return instance.value; + + + int + + MyStruct* + + return instance->value; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RefToPtrTest() + { + var inputContents = @"struct MyStruct { + int value; +}; + +bool MyFunction(const MyStruct& lhs, const MyStruct& rhs) +{ + return lhs.value == rhs.value; +} +"; + + var expectedOutputContents = @" + + + + + int + + + + + bool + + MyStruct* + + + MyStruct* + + return lhs->value == rhs->value; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnCXXNullPtrTest() + { + var inputContents = @"void* MyFunction() +{ + return nullptr; +} +"; + + var expectedOutputContents = @" + + + + + void* + return null; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnCXXBooleanLiteralTest(string value) + { + var inputContents = $@"bool MyFunction() +{{ + return {value}; +}} +"; + + var expectedOutputContents = $@" + + + + + bool + return {value}; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnFloatingLiteralDoubleTest(string value) + { + var inputContents = $@"double MyFunction() +{{ + return {value}; +}} +"; + + var expectedOutputContents = $@" + + + + + double + return {value}; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnFloatingLiteralSingleTest(string value) + { + var inputContents = $@"float MyFunction() +{{ + return {value}; +}} +"; + + var expectedOutputContents = $@" + + + + + float + return {value}; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnEmptyTest() + { + var inputContents = @"void MyFunction() +{ + return; +} +"; + + var expectedOutputContents = @" + + + + + void + return; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnIntegerLiteralInt32Test() + { + var inputContents = @"int MyFunction() +{ + return -1; +} +"; + + var expectedOutputContents = @" + + + + + int + return -1; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task AccessUnionMemberTest() + { + var inputContents = @"union MyUnion +{ + struct { int a; }; +}; + +void MyFunction() +{ + MyUnion myUnion; + myUnion.a = 10; +} +"; + + var expectedOutputContents = @" + + + + + _Anonymous_e__Struct + + + ref int + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.a, 1)); + + + + + int + + + + + + void + MyUnion myUnion = new MyUnion(); + + myUnion.Anonymous.a = 10; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ReturnStructTest() + { + var inputContents = @"struct MyStruct +{ + double r; + double g; + double b; +}; + +MyStruct MyFunction() +{ + MyStruct myStruct; + return myStruct; +} +"; + + var expectedOutputContents = @" + + + + + double + + + double + + + double + + + + + MyStruct + MyStruct myStruct = new MyStruct(); + + return myStruct; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SwitchTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + { + default: + { + return 0; + } + } +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + switch (value) + { + default: + { + return 0; + } + } + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SwitchNonCompoundTest() + { + var inputContents = @"int MyFunction(int value) +{ + switch (value) + default: + { + return 0; + } + + switch (value) + default: + return 0; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + switch (value) + { + default: + { + return 0; + } + } + + switch (value) + { + default: + { + return 0; + } + } + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorAddrOfTest() + { + var inputContents = @"int* MyFunction(int value) +{ + return &value; +} +"; + + var expectedOutputContents = @" + + + + + int* + + int + + return &value; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorDerefTest() + { + var inputContents = @"int MyFunction(int* value) +{ + return *value; +} +"; + + var expectedOutputContents = @" + + + + + int + + int* + + return *value; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorLogicalNotTest() + { + var inputContents = @"bool MyFunction(bool value) +{ + return !value; +} +"; + + var expectedOutputContents = @" + + + + + bool + + bool + + return !value; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorPostfixTest(string opcode) + { + var inputContents = $@"int MyFunction(int value) +{{ + return value{opcode}; +}} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + return value{opcode}; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UnaryOperatorPrefixTest(string opcode) + { + var inputContents = $@"int MyFunction(int value) +{{ + return {opcode}value; +}} +"; + + var expectedOutputContents = $@" + + + + + int + + int + + return {opcode}value; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WhileTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + while (i < count) + { + i++; + } + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + while (i < count) + { + i++; + } + + return i; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WhileNonCompoundTest() + { + var inputContents = @"int MyFunction(int count) +{ + int i = 0; + + while (i < count) + i++; + + return i; +} +"; + + var expectedOutputContents = @" + + + + + int + + int + + int i = 0; + + while (i < count) + { + i++; + } + + return i; + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationDllImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationDllImportTest.cs new file mode 100644 index 00000000..14b62f38 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionDeclarationDllImportTest.cs @@ -0,0 +1,399 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestUnix_FunctionDeclarationDllImportTest : FunctionDeclarationDllImportTest + { + public override Task BasicTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ArrayParameterTest() + { + var inputContents = @"void MyFunction(const float color[4]);"; + + var expectedOutputContents = @" + + + + + void + + float* + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FunctionPointerParameterTest() + { + var inputContents = @"void MyFunction(void (*callback)());"; + + var expectedOutputContents = @" + + + + + void + + IntPtr + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task TemplateParameterTest(string nativeType, bool expectedNativeTypeAttr, string expectedManagedType, string expectedUsingStatement) + { + var inputContents = @$"template struct MyTemplate; + +void MyFunction(MyTemplate<{nativeType}> myStruct);"; + + var expectedOutputContents = $@" + + + + + void + + MyTemplate<{expectedManagedType}> + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: new[] { "MyTemplate" }); + } + + public override Task TemplateMemberTest() + { + var inputContents = @$"template struct MyTemplate +{{ +}}; + +struct MyStruct +{{ + MyTemplate a; +}}; +"; + + var expectedOutputContents = $@" + + + + + MyTemplate<IntPtr> + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: new[] { "MyTemplate" }); + } + + public override Task NoLibraryPathTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty); + } + + public override Task WithLibraryPathTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + var withLibraryPaths = new Dictionary + { + ["MyFunction"] = "ClangSharpPInvokeGenerator" + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty, withLibraryPaths: withLibraryPaths); + } + + public override Task WithLibraryPathStarTest() + { + var inputContents = @"void MyFunction();"; + + var expectedOutputContents = @" + + + + + void + + + + +"; + + var withLibraryPaths = new Dictionary + { + ["*"] = "ClangSharpPInvokeGenerator" + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, libraryPath: string.Empty, withLibraryPaths: withLibraryPaths); + } + + public override Task OptionalParameterTest(string nativeType, string nativeInit, bool expectedNativeTypeNameAttr, string expectedManagedType, string expectedManagedInit) + { + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + + var expectedOutputContents = $@" + + + + + void + + {expectedManagedType} + + {expectedManagedInit} + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task OptionalParameterUnsafeTest(string nativeType, string nativeInit, string expectedManagedType, string expectedManagedInit) + { + var inputContents = $@"void MyFunction({nativeType} value = {nativeInit});"; + + var expectedOutputContents = $@" + + + + + void + + {expectedManagedType} + + {expectedManagedInit} + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WithCallConvTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withCallConvs = new Dictionary { + ["MyFunction1"] = "Winapi" + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withCallConvs: withCallConvs); + } + + public override Task WithCallConvStarTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withCallConvs = new Dictionary + { + ["*"] = "Winapi" + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withCallConvs: withCallConvs); + } + + public override Task WithCallConvStarOverrideTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withCallConvs = new Dictionary + { + ["*"] = "Winapi", + ["MyFunction2"] = "StdCall" + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withCallConvs: withCallConvs); + } + + public override Task WithSetLastErrorTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withSetLastErrors = new string[] + { + "MyFunction1" + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withSetLastErrors: withSetLastErrors); + } + + public override Task WithSetLastErrorStarTest() + { + var inputContents = @"void MyFunction1(int value); void MyFunction2(int value);"; + + var expectedOutputContents = @" + + + + + void + + int + + + + void + + int + + + + + +"; + + var withSetLastErrors = new string[] + { + "*" + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, withSetLastErrors: withSetLastErrors); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionPointerDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionPointerDeclarationTest.cs new file mode 100644 index 00000000..00312581 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/FunctionPointerDeclarationTest.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestUnix_FunctionPointerDeclarationTest : FunctionPointerDeclarationTest + { + public override Task BasicTest() + { + var inputContents = @"typedef void (*Callback)();"; + + var expectedOutputContents = @" + + + + void + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/StructDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/StructDeclarationTest.cs new file mode 100644 index 00000000..9cf8f55b --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/StructDeclarationTest.cs @@ -0,0 +1,1479 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestUnix_StructDeclarationTest : StructDeclarationTest + { + public override Task BasicTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicTestInCMode(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef struct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}} MyStruct; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + } + + public override Task BasicWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BitfieldTest() + { + var inputContents = @"struct MyStruct1 +{ + unsigned int o0_b0_24 : 24; + unsigned int o4_b0_16 : 16; + unsigned int o4_b16_3 : 3; + int o4_b19_3 : 3; + unsigned char o8_b0_1 : 1; + int o12_b0_1 : 1; + int o12_b1_1 : 1; +}; + +struct MyStruct2 +{ + unsigned int o0_b0_1 : 1; + int x; + unsigned int o8_b0_1 : 1; +}; + +struct MyStruct3 +{ + unsigned int o0_b0_1 : 1; + unsigned int o0_b1_1 : 1; +}; +"; + + var expectedOutputContents = @" + + + + + uint + + + uint + + return _bitfield1 & 0xFFFFFFu; + + + + _bitfield1 = (_bitfield1 & ~0xFFFFFFu) | (value & 0xFFFFFFu); + + + + uint + + + uint + + return _bitfield2 & 0xFFFFu; + + + + _bitfield2 = (_bitfield2 & ~0xFFFFu) | (value & 0xFFFFu); + + + + uint + + return (_bitfield2 >> 16) & 0x7u; + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 16)) | ((value & 0x7u) << 16); + + + + int + + return (int)((_bitfield2 >> 19) & 0x7u); + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 19)) | (uint)((value & 0x7) << 19); + + + + byte + + return (byte)((_bitfield2 >> 22) & 0x1u); + + + + _bitfield2 = (_bitfield2 & ~(0x1u << 22)) | (uint)((value & 0x1u) << 22); + + + + int + + return (int)((_bitfield2 >> 23) & 0x1u); + + + + _bitfield2 = (_bitfield2 & ~(0x1u << 23)) | (uint)((value & 0x1) << 23); + + + + int + + return (int)((_bitfield2 >> 24) & 0x1u); + + + + _bitfield2 = (_bitfield2 & ~(0x1u << 24)) | (uint)((value & 0x1) << 24); + + + + + + uint + + + uint + + return _bitfield1 & 0x1u; + + + + _bitfield1 = (_bitfield1 & ~0x1u) | (value & 0x1u); + + + + int + + + uint + + + uint + + return _bitfield2 & 0x1u; + + + + _bitfield2 = (_bitfield2 & ~0x1u) | (value & 0x1u); + + + + + + uint + + + uint + + return _bitfield & 0x1u; + + + + _bitfield = (_bitfield & ~0x1u) | (value & 0x1u); + + + + uint + + return (_bitfield >> 1) & 0x1u; + + + + _bitfield = (_bitfield & ~(0x1u << 1)) | ((value & 0x1u) << 1); + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExcludeTest() + { + var inputContents = "typedef struct MyStruct MyStruct;"; + var expectedOutputContents = string.Empty; + + var excludedNames = new string[] { "MyStruct" }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task FixedSizedBufferNonPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +struct MyOtherStruct +{{ + MyStruct c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + return ref AsSpan()[index]; + + + + Span<MyStruct> + MemoryMarshal.CreateSpan(ref e0, 3); + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +struct MyOtherStruct +{{ + MyStruct c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + return ref AsSpan()[index]; + + + + Span<MyStruct> + MemoryMarshal.CreateSpan(ref e0, 24); + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +typedef MyStruct MyBuffer[3]; + +struct MyOtherStruct +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + return ref AsSpan()[index]; + + + + Span<MyStruct> + MemoryMarshal.CreateSpan(ref e0, 3); + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} value; +}}; + +struct MyOtherStruct +{{ + MyStruct c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyStruct + + + + MyStruct + + + MyStruct + + + MyStruct + + + ref MyStruct + + int + + + return ref AsSpan()[index]; + + + + Span<MyStruct> + MemoryMarshal.CreateSpan(ref e0, 3); + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPointerTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + ref {expectedManagedType} + + int + + + fixed ({expectedManagedType}* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyBuffer[3]; + +struct MyStruct +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task GuidTest() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Non-Unix doesn't support __declspec(uuid("")) + return Task.CompletedTask; + } + + var inputContents = $@"#define DECLSPEC_UUID(x) __declspec(uuid(x)) + +struct __declspec(uuid(""00000000-0000-0000-C000-000000000046"")) MyStruct1 +{{ + int x; +}}; + +struct DECLSPEC_UUID(""00000000-0000-0000-C000-000000000047"") MyStruct2 +{{ + int x; +}}; +"; + + var expectedOutputContents = $@" + + + + + int + + + + + int + + + + + + + + +"; + + var excludedNames = new string[] { "DECLSPEC_UUID" }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task InheritanceTest() + { + var inputContents = @"struct MyStruct1A +{ + int x; + int y; +}; + +struct MyStruct1B +{ + int x; + int y; +}; + +struct MyStruct2 : MyStruct1A, MyStruct1B +{ + int z; + int w; +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + + + int + + + int + + + + + MyStruct1A + + + MyStruct1B + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column) + { + var inputContents = $@"typedef union {{ + {nativeType} value; +}} MyUnion; + +struct MyStruct +{{ + {nativeType} x; + {nativeType} y; + + struct + {{ + {nativeType} z; + + struct + {{ + {nativeType} value; + }} w; + + MyUnion u; + {nativeType} buffer1[4]; + MyUnion buffer2[4]; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + {expectedManagedType} + + + {expectedManagedType} + + + _Anonymous_e__Struct + + + ref {expectedManagedType} + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.z, 1)); + + + + ref _Anonymous_e__Struct._w_e__Struct + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.w, 1)); + + + + ref MyUnion + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.u, 1)); + + + + Span<{expectedManagedType}> + + return MemoryMarshal.CreateSpan(ref Anonymous.buffer1[0], 4); + + + + Span<MyUnion> + + return Anonymous.buffer2.AsSpan(); + + + + + {expectedManagedType} + + + _w_e__Struct + + + MyUnion + + + {expectedManagedType} + + + MyUnion + + + + {expectedManagedType} + + + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + return ref AsSpan()[index]; + + + + Span<MyUnion> + MemoryMarshal.CreateSpan(ref e0, 4); + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedAnonymousWithBitfieldTest() + { + var inputContents = @"struct MyStruct +{ + int x; + int y; + + struct + { + int z; + + struct + { + int w; + int o0_b0_16 : 16; + int o0_b16_4 : 4; + }; + }; +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + _Anonymous_e__Struct + + + ref int + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.z, 1)); + + + + ref int + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.Anonymous.w, 1)); + + + + int + + return Anonymous.Anonymous.o0_b0_16; + + + Anonymous.Anonymous.o0_b0_16 = value; + + + + int + + return Anonymous.Anonymous.o0_b16_4; + + + Anonymous.Anonymous.o0_b16_4 = value; + + + + + int + + + _Anonymous_e__Struct + + + + int + + + int + + + int + + return _bitfield & 0xFFFF; + + + + _bitfield = (_bitfield & ~0xFFFF) | (value & 0xFFFF); + + + + int + + return (_bitfield >> 16) & 0xF; + + + + _bitfield = (_bitfield & ~(0xF << 16)) | ((value & 0xF) << 16); + + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + struct MyNestedStruct + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + struct MyNestedStruct + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordTest() + { + var inputContents = @"struct MyStruct +{ + int Equals; + int Finalize; + int GetHashCode; + int GetType; + int MemberwiseClone; + int ReferenceEquals; + int ToString; +};"; + + var expectedOutputContents = $@" + + + + + int + + + int + + + int + + + int + + + int + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NoDefinitionTest() + { + var inputContents = "typedef struct MyStruct MyStruct;"; + + var expectedOutputContents = $@" + + + + + +"; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfTest() + { + var inputContents = @"struct example_s { + example_s* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfViaTypedefTest() + { + var inputContents = @"typedef struct example_s example_t; + +struct example_s { + example_t* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RemapTest() + { + var inputContents = "typedef struct _MyStruct MyStruct;"; + + var expectedOutputContents = $@" + + + + + +"; + + var remappedNames = new Dictionary { ["_MyStruct"] = "MyStruct" }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task RemapNestedAnonymousTest() + { + var inputContents = @"struct MyStruct +{ + double r; + double g; + double b; + + struct + { + double a; + }; +};"; + + var expectedOutputContents = @" + + + + + double + + + double + + + double + + + _Anonymous_e__Struct + + + ref double + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.a, 1)); + + + + + double + + + + + +"; + + var remappedNames = new Dictionary { + ["__AnonymousField_ClangUnsavedFile_L7_C5"] = "Anonymous", + ["__AnonymousRecord_ClangUnsavedFile_L7_C5"] = "_Anonymous_e__Struct" + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task SkipNonDefinitionTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef struct MyStruct MyStruct; + +struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionPointerTest() + { + var inputContents = @"typedef struct MyStruct* MyStructPtr; +typedef struct MyStruct& MyStructRef; +"; + + var expectedOutputContents = @" + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef struct MyStruct MyStruct; + +struct MyStruct +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task TypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyTypedefAlias; + +struct MyStruct +{{ + MyTypedefAlias r; + MyTypedefAlias g; + MyTypedefAlias b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UsingDeclarationTest() + { + var inputContents = @"struct MyStruct1A +{ + void MyMethod() { } +}; + +struct MyStruct1B : MyStruct1A +{ + using MyStruct1A::MyMethod; +}; +"; + + var expectedOutputContents = @" + + + + + void + + + + + + void + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs new file mode 100644 index 00000000..964a2cb5 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs @@ -0,0 +1,1334 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestUnix_UnionDeclarationTest : UnionDeclarationTest + { + public override Task BasicTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicTestInCMode(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef union +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}} MyUnion; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, commandlineArgs: Array.Empty()); + } + + public override Task BasicWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BitfieldTest() + { + var inputContents = @"union MyUnion1 +{ + unsigned int o0_b0_24 : 24; + unsigned int o4_b0_16 : 16; + unsigned int o4_b16_3 : 3; + int o4_b19_3 : 3; + unsigned char o8_b0_1 : 1; + int o12_b0_1 : 1; + int o12_b1_1 : 1; +}; + +union MyUnion2 +{ + unsigned int o0_b0_1 : 1; + int x; + unsigned int o8_b0_1 : 1; +}; + +union MyUnion3 +{ + unsigned int o0_b0_1 : 1; + unsigned int o0_b1_1 : 1; +}; +"; + + string expectedPack = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ", Pack = 1" : ""; + + var expectedOutputContents = $@" + + + + + uint + + + uint + + return _bitfield1 & 0xFFFFFFu; + + + + _bitfield1 = (_bitfield1 & ~0xFFFFFFu) | (value & 0xFFFFFFu); + + + + uint + + + uint + + return _bitfield2 & 0xFFFFu; + + + + _bitfield2 = (_bitfield2 & ~0xFFFFu) | (value & 0xFFFFu); + + + + uint + + return (_bitfield2 >> 16) & 0x7u; + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 16)) | ((value & 0x7u) << 16); + + + + int + + return (int)((_bitfield2 >> 19) & 0x7u); + + + + _bitfield2 = (_bitfield2 & ~(0x7u << 19)) | (uint)((value & 0x7) << 19); + + + + byte + + return (byte)((_bitfield2 >> 22) & 0x1u); + + + + _bitfield2 = (_bitfield2 & ~(0x1u << 22)) | (uint)((value & 0x1u) << 22); + + + + int + + return (int)((_bitfield2 >> 23) & 0x1u); + + + + _bitfield2 = (_bitfield2 & ~(0x1u << 23)) | (uint)((value & 0x1) << 23); + + + + int + + return (int)((_bitfield2 >> 24) & 0x1u); + + + + _bitfield2 = (_bitfield2 & ~(0x1u << 24)) | (uint)((value & 0x1) << 24); + + + + + + uint + + + uint + + return _bitfield1 & 0x1u; + + + + _bitfield1 = (_bitfield1 & ~0x1u) | (value & 0x1u); + + + + int + + + uint + + + uint + + return _bitfield2 & 0x1u; + + + + _bitfield2 = (_bitfield2 & ~0x1u) | (value & 0x1u); + + + + + + uint + + + uint + + return _bitfield & 0x1u; + + + + _bitfield = (_bitfield & ~0x1u) | (value & 0x1u); + + + + uint + + return (_bitfield >> 1) & 0x1u; + + + + _bitfield = (_bitfield & ~(0x1u << 1)) | ((value & 0x1u) << 1); + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task ExcludeTest() + { + var inputContents = "typedef union MyUnion MyUnion;"; + var expectedOutputContents = string.Empty; + + var excludedNames = new string[] { "MyUnion" }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task FixedSizedBufferNonPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +union MyOtherUnion +{{ + MyUnion c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + return ref AsSpan()[index]; + + + + Span<MyUnion> + MemoryMarshal.CreateSpan(ref e0, 3); + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +union MyOtherUnion +{{ + MyUnion c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + return ref AsSpan()[index]; + + + + Span<MyUnion> + MemoryMarshal.CreateSpan(ref e0, 24); + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +typedef MyUnion MyBuffer[3]; + +union MyOtherUnion +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + return ref AsSpan()[index]; + + + + Span<MyUnion> + MemoryMarshal.CreateSpan(ref e0, 3); + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferNonPrimitiveWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} value; +}}; + +union MyOtherUnion +{{ + MyUnion c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + MyUnion + + + + MyUnion + + + MyUnion + + + MyUnion + + + ref MyUnion + + int + + + return ref AsSpan()[index]; + + + + Span<MyUnion> + MemoryMarshal.CreateSpan(ref e0, 3); + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPointerTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + ref {expectedManagedType} + + int + + + fixed ({expectedManagedType}* pThis = &e0) + {{ + return ref pThis[index]; + }} + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} c[3]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveMultidimensionalTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} c[2][1][3][4]; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task FixedSizedBufferPrimitiveTypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyBuffer[3]; + +union MyUnion +{{ + MyBuffer c; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + public override Task GuidTest() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Non-Unix doesn't support __declspec(uuid("")) + return Task.CompletedTask; + } + + var inputContents = $@"#define DECLSPEC_UUID(x) __declspec(uuid(x)) + +union __declspec(uuid(""00000000-0000-0000-C000-000000000046"")) MyUnion1 +{{ + int x; +}}; + +union DECLSPEC_UUID(""00000000-0000-0000-C000-000000000047"") MyUnion2 +{{ + int x; +}}; +"; + + var expectedOutputContents = $@" + + + + + int + + + + + int + + + + + + + + +"; + + var excludedNames = new string[] { "DECLSPEC_UUID" }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task NestedAnonymousTest(string nativeType, string expectedManagedType, int line, int column) + { + var inputContents = $@"typedef struct {{ + {nativeType} value; +}} MyStruct; + +union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + union + {{ + {nativeType} a; + + MyStruct s; + + {nativeType} buffer[4]; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + _Anonymous_e__Union + + + ref {expectedManagedType} + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.a, 1)); + + + + ref MyStruct + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.s, 1)); + + + + Span<{expectedManagedType}> + + return MemoryMarshal.CreateSpan(ref Anonymous.buffer[0], 4); + + + + + {expectedManagedType} + + + MyStruct + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedAnonymousWithBitfieldTest() + { + var inputContents = @"union MyUnion +{ + int x; + int y; + + union + { + int z; + + union + { + int w; + int o0_b0_16 : 16; + int o0_b16_4 : 4; + }; + }; +}; +"; + + var expectedOutputContents = @" + + + + + int + + + int + + + _Anonymous_e__Union + + + ref int + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.z, 1)); + + + + ref int + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.Anonymous.w, 1)); + + + + int + + return Anonymous.Anonymous.o0_b0_16; + + + Anonymous.Anonymous.o0_b0_16 = value; + + + + int + + return Anonymous.Anonymous.o0_b16_4; + + + Anonymous.Anonymous.o0_b16_4 = value; + + + + + int + + + _Anonymous_e__Union + + + + int + + + int + + + int + + return _bitfield & 0xFFFF; + + + + _bitfield = (_bitfield & ~0xFFFF) | (value & 0xFFFF); + + + + int + + return (_bitfield >> 16) & 0xF; + + + + _bitfield = (_bitfield & ~(0xF << 16)) | ((value & 0xF) << 16); + + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + + public override Task NestedTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + union MyNestedUnion + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NestedWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + + union MyNestedUnion + {{ + {nativeType} r; + {nativeType} g; + {nativeType} b; + {nativeType} a; + }}; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NewKeywordTest() + { + var inputContents = @"union MyUnion +{ + int Equals; + int Finalize; + int GetHashCode; + int GetType; + int MemberwiseClone; + int ReferenceEquals; + int ToString; +};"; + + var expectedOutputContents = $@" + + + + + int + + + int + + + int + + + int + + + int + + + int + + + int + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NoDefinitionTest() + { + var inputContents = "typedef union MyUnion MyUnion;"; + + var expectedOutputContents = $@" + + + + + +"; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfTest() + { + var inputContents = @"union example_s { + example_s* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task PointerToSelfViaTypedefTest() + { + var inputContents = @"typedef union example_s example_t; + +union example_s { + example_t* next; + void* data; +};"; + + var expectedOutputContents = $@" + + + + + example_s* + + + void* + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task RemapTest() + { + var inputContents = "typedef union _MyUnion MyUnion;"; + + var expectedOutputContents = $@" + + + + + +"; + + var remappedNames = new Dictionary { ["_MyUnion"] = "MyUnion" }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task RemapNestedAnonymousTest() + { + var inputContents = @"union MyUnion +{ + double r; + double g; + double b; + + union + { + double a; + }; +};"; + + var expectedOutputContents = @" + + + + + double + + + double + + + double + + + _Anonymous_e__Union + + + ref double + + return ref MemoryMarshal.GetReference(MemoryMarshal.CreateSpan(ref Anonymous.a, 1)); + + + + + double + + + + + +"; + + var remappedNames = new Dictionary { + ["__AnonymousField_ClangUnsavedFile_L7_C5"] = "Anonymous", + ["__AnonymousRecord_ClangUnsavedFile_L7_C5"] = "_Anonymous_e__Union" + }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, remappedNames: remappedNames); + } + + public override Task SkipNonDefinitionTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef union MyUnion MyUnion; + +union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionPointerTest() + { + var inputContents = @"typedef union MyUnion* MyUnionPtr; +typedef union MyUnion& MyUnionRef; +"; + + var expectedOutputContents = @" + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task SkipNonDefinitionWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef union MyUnion MyUnion; + +union MyUnion +{{ + {nativeType} r; + {nativeType} g; + {nativeType} b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task TypedefTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"typedef {nativeType} MyTypedefAlias; + +union MyUnion +{{ + MyTypedefAlias r; + MyTypedefAlias g; + MyTypedefAlias b; +}}; +"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + + {expectedManagedType} + + + {expectedManagedType} + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/VarDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/VarDeclarationTest.cs new file mode 100644 index 00000000..b3283f82 --- /dev/null +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/VarDeclarationTest.cs @@ -0,0 +1,353 @@ +// Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace ClangSharp.UnitTests +{ + public sealed class XmlLatestUnix_VarDeclarationTest : VarDeclarationTest + { + public override Task BasicTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"{nativeType} MyVariable = 0;"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + 0 + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task BasicWithNativeTypeNameTest(string nativeType, string expectedManagedType) + { + var inputContents = $@"{nativeType} MyVariable = 0;"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + 0 + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task GuidMacroTest() + { + var inputContents = $@"struct GUID {{ + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; +}}; + +const GUID IID_IUnknown = {{ 0x00000000, 0x0000, 0x0000, {{ 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 }} }}; +"; + + var expectedOutputContents = $@" + + + + + Guid + + new Guid(0x00000000, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46) + + + + + +"; + var excludedNames = new string[] { "GUID" }; + var remappedNames = new Dictionary { ["GUID"] = "Guid" }; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames, remappedNames: remappedNames); + } + + public override Task MacroTest(string nativeValue, string expectedManagedType, string expectedManagedValue) + { + var inputContents = $@"#define MyMacro1 {nativeValue} +#define MyMacro2 MyMacro1"; + + var expectedOutputContents = $@" + + + + + {expectedManagedType} + + {expectedManagedValue} + + + + {expectedManagedType} + + {expectedManagedValue} + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task MultilineMacroTest() + { + var inputContents = $@"#define MyMacro1 0 + \ +1"; + + var expectedOutputContents = $@" + + + + + int + + 0 + 1 + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task NoInitializerTest(string nativeType) + { + var inputContents = $@"{nativeType} MyVariable;"; + var expectedOutputContents = ""; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task Utf8StringLiteralMacroTest() + { + var inputContents = $@"#define MyMacro1 ""Test"""; + + var expectedOutputContents = $@" + + + + + ReadOnlySpan<byte> + + new byte[] {{ 0x54, 0x65, 0x73, 0x74, 0x00 }} + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task Utf16StringLiteralMacroTest() + { + var inputContents = $@"#define MyMacro1 u""Test"""; + + var expectedOutputContents = $@" + + + + + string + + ""Test"" + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task WideStringLiteralConstTest() + { + // Unsupported string literal kind: 'CX_CLK_Wide' + return Task.CompletedTask; + } + + public override Task StringLiteralConstTest() + { + var inputContents = $@"const char MyConst1[] = ""Test"";"; + + var expectedOutputContents = $@" + + + + + ReadOnlySpan<byte> + + new byte[] {{ 0x54, 0x65, 0x73, 0x74, 0x00 }} + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedConversionMacroTest() + { + var inputContents = $@"#define MyMacro1 (long)0x80000000L +#define MyMacro2 (int)0x80000000"; + + var expectedOutputContents = $@" + + + + + IntPtr + + (IntPtr)(0x80000000) + + + + int + + + + (int)(0x80000000) + + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedFunctionLikeCastMacroTest() + { + var inputContents = $@"#define MyMacro1 unsigned(-1)"; + + var expectedOutputContents = $@" + + + + + uint + + + + (uint)(-1) + + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedConversionMacroTest2() + { + var inputContents = $@"#define MyMacro1(x, y, z) ((int)(((unsigned long)(x)<<31) | ((unsigned long)(y)<<16) | ((unsigned long)(z)))) +#define MyMacro2(n) MyMacro1(1, 2, n) +#define MyMacro3 MyMacro2(3)"; + + var expectedOutputContents = $@" + + + + + int + + + ((int)(((UIntPtr)(1) << 31) | ((UIntPtr)(2) << 16) | ((UIntPtr)(3)))) + + + + + + +"; + + var excludedNames = new string[] { "MyMacro1", "MyMacro2" }; + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents, excludedNames: excludedNames); + } + + public override Task UncheckedPointerMacroTest() + { + var inputContents = $@"#define Macro1 ((int*) -1)"; + + var expectedOutputContents = $@" + + + + + int* + + + ((int*)(-1)) + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + + public override Task UncheckedReinterpretCastMacroTest() + { + var inputContents = $@"#define Macro1 reinterpret_cast(-1)"; + + var expectedOutputContents = $@" + + + + + int* + + + + (int*)(-1) + + + + + + + +"; + + return ValidateGeneratedXmlLatestUnixBindingsAsync(inputContents, expectedOutputContents); + } + } +} diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationBodyImportTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationBodyImportTest.cs index 7bfd6dd9..c4f811a4 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationBodyImportTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/FunctionDeclarationBodyImportTest.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft and Contributors. All rights reserved. Licensed under the University of Illinois/NCSA Open Source License. See LICENSE.txt in the project root for license information. using System; -using System.Reflection.Emit; using System.Runtime.InteropServices; using System.Threading.Tasks; From d7219f2e9bb35e21ee542af039b9c61c70345ef7 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sat, 20 Mar 2021 18:30:42 -0700 Subject: [PATCH 4/4] Ensure we use expectedPack for XmlCompatibleUnix --- .../XmlCompatibleUnix/UnionDeclarationTest.cs | 6 +++--- .../XmlCompatibleWindows/UnionDeclarationTest.cs | 6 +++--- .../XmlLatestUnix/UnionDeclarationTest.cs | 6 +++--- .../XmlLatestWindows/UnionDeclarationTest.cs | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs index 9e4699dc..de84f605 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleUnix/UnionDeclarationTest.cs @@ -128,12 +128,12 @@ union MyUnion3 }; "; - string expectedPack = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ", Pack = 1" : ""; + string expectedPack = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @" pack=""1""" : ""; var expectedOutputContents = $@" - + uint @@ -242,7 +242,7 @@ union MyUnion3 - + uint diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs index 70a6e775..97e430bd 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlCompatibleWindows/UnionDeclarationTest.cs @@ -128,12 +128,12 @@ union MyUnion3 }; "; - string expectedPack = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ", Pack = 1" : ""; + string expectedPack = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @" pack=""1""" : ""; var expectedOutputContents = $@" - + uint @@ -248,7 +248,7 @@ union MyUnion3 - + uint diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs index 964a2cb5..b974b9d1 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestUnix/UnionDeclarationTest.cs @@ -128,12 +128,12 @@ union MyUnion3 }; "; - string expectedPack = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ", Pack = 1" : ""; + string expectedPack = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @" pack=""1""" : ""; var expectedOutputContents = $@" - + uint @@ -242,7 +242,7 @@ union MyUnion3 - + uint diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs index 7133c8d8..77078d67 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/XmlLatestWindows/UnionDeclarationTest.cs @@ -128,12 +128,12 @@ union MyUnion3 }; "; - string expectedPack = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ", Pack = 1" : ""; + string expectedPack = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @" pack=""1""" : ""; var expectedOutputContents = $@" - + uint @@ -248,7 +248,7 @@ union MyUnion3 - + uint