Skip to content

Commit

Permalink
Doing some minor code cleanup and adding some PInvokeGenerator tests (#…
Browse files Browse the repository at this point in the history
…50)

* Moving the IsFromMainFile check from the traverser to the writer

* Fixing up the structured traverser to always build a full tree for release mode.

* Modifying the command option aliases to be a single dash

* Adding a ClangSharpPInvokeGenerator test project
  • Loading branch information
tannergooding authored May 26, 2019
1 parent efd0434 commit 413a1c8
Show file tree
Hide file tree
Showing 16 changed files with 711 additions and 404 deletions.
6 changes: 6 additions & 0 deletions ClangSharp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClangSharp.Test", "ClangSha
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClangSharpPInvokeGenerator", "ClangSharpPInvokeGenerator\ClangSharpPInvokeGenerator.csproj", "{4E3FE01B-89FA-4E5B-856C-34A5E29110A9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClangSharpPInvokeGenerator.Test", "ClangSharpPInvokeGenerator.Test\ClangSharpPInvokeGenerator.Test.csproj", "{0F4159AF-BC55-4C98-A248-67B9B4D229F1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -26,6 +28,10 @@ Global
{4E3FE01B-89FA-4E5B-856C-34A5E29110A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E3FE01B-89FA-4E5B-856C-34A5E29110A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E3FE01B-89FA-4E5B-856C-34A5E29110A9}.Release|Any CPU.Build.0 = Release|Any CPU
{0F4159AF-BC55-4C98-A248-67B9B4D229F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0F4159AF-BC55-4C98-A248-67B9B4D229F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F4159AF-BC55-4C98-A248-67B9B4D229F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F4159AF-BC55-4C98-A248-67B9B4D229F1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<IsPackable>false</IsPackable>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\ClangSharpPInvokeGenerator\ClangSharpPInvokeGenerator.csproj" />
</ItemGroup>

</Project>
83 changes: 83 additions & 0 deletions ClangSharpPInvokeGenerator.Test/EnumDeclarationTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System.Threading.Tasks;
using Xunit;

namespace ClangSharpPInvokeGenerator.Test
{
public sealed class EnumDeclarationTest : PInvokeGeneratorTest
{
[Fact]
public async Task BasicTest()
{
var inputContents = @"enum MyEnum
{
MyEnum_Value0,
MyEnum_Value1,
MyEnum_Value2,
};
";

var expectedOutputContents = @"namespace ClangSharpPInvokeGenerator.Test
{
public enum MyEnum
{
MyEnum_Value0,
MyEnum_Value1,
MyEnum_Value2,
}
}
";

await ValidateGeneratedBindings(inputContents, expectedOutputContents);
}

[Fact]
public async Task BasicValueTest()
{
var inputContents = @"enum MyEnum
{
MyEnum_Value1 = 1,
MyEnum_Value2,
MyEnum_Value3,
};
";

var expectedOutputContents = @"namespace ClangSharpPInvokeGenerator.Test
{
public enum MyEnum
{
MyEnum_Value1 = 1,
MyEnum_Value2,
MyEnum_Value3,
}
}
";

await ValidateGeneratedBindings(inputContents, expectedOutputContents);
}

[Fact]
public async Task BasicTypedTest()
{
var inputContents = @"enum MyEnum : unsigned char
{
MyEnum_Value0,
MyEnum_Value1,
MyEnum_Value2,
};
";

var expectedOutputContents = @"namespace ClangSharpPInvokeGenerator.Test
{
public enum MyEnum : byte
{
MyEnum_Value0,
MyEnum_Value1,
MyEnum_Value2,
}
}
";

await ValidateGeneratedBindings(inputContents, expectedOutputContents);
}
}
}
50 changes: 50 additions & 0 deletions ClangSharpPInvokeGenerator.Test/PInvokeGeneratorTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Threading.Tasks;
using Xunit;

namespace ClangSharpPInvokeGenerator.Test
{
public abstract class PInvokeGeneratorTest : IDisposable
{
private TemporaryFile _inputFile = new TemporaryFile();
private TemporaryFile _outputFile = new TemporaryFile();

public TemporaryFile InputFile => _inputFile;

public TemporaryFile OutputFile => _outputFile;

public void Dispose()
{
if (_inputFile != null)
{
_inputFile.Dispose();
_inputFile = null;
}

if (_outputFile != null)
{
_outputFile.Dispose();
_outputFile = null;
}
}

protected async Task ValidateGeneratedBindings(string inputContents, string expectedOutputContents)
{
await InputFile.WriteAllText(inputContents);
await GenerateBindings();

var actualOutputContents = await OutputFile.ReadAllText();
Assert.Equal(expectedOutputContents, actualOutputContents);
}

protected async Task GenerateBindings()
{
await Program.Main(
"-f", InputFile.Path,
"-l", "ClangSharpPInvokeGenerator.Test",
"-n", "ClangSharpPInvokeGenerator.Test",
"-o", OutputFile.Path
);
}
}
}
50 changes: 50 additions & 0 deletions ClangSharpPInvokeGenerator.Test/TemporaryFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using IOPath = System.IO.Path;

namespace ClangSharpPInvokeGenerator.Test
{
public sealed class TemporaryFile : IDisposable
{
private string _path;

public TemporaryFile()
{
_path = IOPath.GetTempFileName();
}

public string Path => _path;

public void Dispose()
{
if (_path != null)
{
File.Delete(_path);
_path = null;
}
}

public Task<string[]> ReadAllLines(CancellationToken cancellationToken = default)
{
return File.ReadAllLinesAsync(_path, cancellationToken);
}

public Task<string> ReadAllText(CancellationToken cancellationToken = default)
{
return File.ReadAllTextAsync(_path, cancellationToken);
}

public Task WriteAllLines(IEnumerable<string> contents, CancellationToken cancellationToken = default)
{
return File.WriteAllLinesAsync(_path, contents, cancellationToken);
}

public Task WriteAllText(string contents, CancellationToken cancellationToken = default)
{
return File.WriteAllTextAsync(_path, contents, cancellationToken);
}
}
}
13 changes: 11 additions & 2 deletions ClangSharpPInvokeGenerator/CursorWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,16 @@ public void Visit(TranslationUnit translationUnit)
{
Debug.Assert(_outputBuilder is null);
_visitedCursors.Add(translationUnit);
VisitChildren(translationUnit);

foreach (var child in translationUnit.Children)
{
if (!child.IsFromMainFile)
{
continue;
}

Visit(child, translationUnit);
}
}

private string EscapeName(string name)
Expand Down Expand Up @@ -971,7 +980,7 @@ private void Visit(Cursor cursor, Cursor parent)

foreach (var child in cursor.Children)
{
Debug.Assert(_visitedCursors.Contains(child));
Debug.Assert(_visitedCursors.Contains(child) || !child.IsFromMainFile);
}
}

Expand Down
48 changes: 48 additions & 0 deletions ClangSharpPInvokeGenerator/Cursors/Attrs/Attr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,54 @@ namespace ClangSharpPInvokeGenerator
{
internal class Attr : Cursor
{
public static new Attr Create(CXCursor handle, Cursor parent)
{
switch (handle.Kind)
{
case CXCursorKind.CXCursor_UnexposedAttr:
{
return new UnexposedAttr(handle, parent);
}

case CXCursorKind.CXCursor_CXXFinalAttr:
{
return new CXXFinalAttr(handle, parent);
}

case CXCursorKind.CXCursor_PureAttr:
{
return new PureAttr(handle, parent);
}

case CXCursorKind.CXCursor_ConstAttr:
{
return new ConstAttr(handle, parent);
}

case CXCursorKind.CXCursor_VisibilityAttr:
{
return new VisibilityAttr(handle, parent);
}

case CXCursorKind.CXCursor_DLLExport:
{
return new DLLExport(handle, parent);
}

case CXCursorKind.CXCursor_DLLImport:
{
return new DLLImport(handle, parent);
}

default:
{
Debug.WriteLine($"Unhandled attribute kind: {handle.KindSpelling}.");
Debugger.Break();
return new Attr(handle, parent);
}
}
}

protected Attr(CXCursor handle, Cursor parent) : base(handle, parent)
{
Debug.Assert(handle.IsAttribute);
Expand Down
Loading

0 comments on commit 413a1c8

Please sign in to comment.