Skip to content

Commit

Permalink
refactor builder (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
elringus committed Jan 5, 2024
1 parent 12305fc commit d594dc1
Show file tree
Hide file tree
Showing 45 changed files with 500 additions and 362 deletions.
15 changes: 10 additions & 5 deletions src/cs/.scripts/cover.ps1
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
try {
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:ExcludeByAttribute=GeneratedCodeAttribute
reportgenerator "-reports:*/*.xml" "-targetdir:.cover" -reporttypes:HTML
serve .cover
$out = "../.cover/"
$json = "../.cover/coverage.json"
dotnet test Bootsharp.Common.Test/Bootsharp.Common.Test.csproj /p:CollectCoverage=true /p:ExcludeByAttribute=GeneratedCodeAttribute /p:CoverletOutput=$out
dotnet test Bootsharp.Generate.Test/Bootsharp.Generate.Test.csproj /p:CollectCoverage=true /p:ExcludeByAttribute=GeneratedCodeAttribute /p:CoverletOutput=$out /p:MergeWith=$json
dotnet test Bootsharp.Inject.Test/Bootsharp.Inject.Test.csproj /p:CollectCoverage=true /p:ExcludeByAttribute=GeneratedCodeAttribute /p:CoverletOutput=$out /p:MergeWith=$json
dotnet test Bootsharp.Publish.Test/Bootsharp.Publish.Test.csproj /p:CollectCoverage=true /p:CoverletOutputFormat="json%2copencover" /p:ExcludeByAttribute=GeneratedCodeAttribute /p:CoverletOutput=$out /p:MergeWith=$json
reportgenerator "-reports:*/*.xml" "-targetdir:.cover" -reporttypes:HTML
python -m webbrowser http://localhost:3000
serve .cover
} finally {
rm ./*/coverage.opencover.xml -force
rm ./.cover -r -force
rm .cover -r -force
}
7 changes: 6 additions & 1 deletion src/cs/Bootsharp.Common.Test/TypesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ public class TypesTest
[Fact]
public void Records ()
{
// TODO: Remove once coverlet properly handles record coverage.
// TODO: Remove when coverlet bug is resolved: https://github.com/coverlet-coverage/coverlet/issues/1561
_ = new SolutionMeta { Assemblies = [], Methods = [], Types = [] } with { Assemblies = default };
_ = new AssemblyMeta { Name = "", Bytes = [] } with { Name = "foo" };
_ = new MethodMeta { Name = "", JSName = "", Arguments = default, Assembly = "", Type = default, Space = "", JSSpace = "", ReturnValue = default } with { Assembly = "foo" };
_ = new ArgumentMeta { Name = "", JSName = "", Value = default } with { Name = "foo" };
_ = new ValueMeta { Type = default, Nullable = true, TypeSyntax = "", Void = true, Serialized = true, Async = true, JSTypeSyntax = "" } with { TypeSyntax = "foo" };
_ = new MockItem("") with { Id = "foo" };
_ = new MockItemWithEnum(default) with { Enum = MockEnum.Bar };
_ = new MockRecord(default) with { Items = new[] { new MockItem("") } };
Expand Down
22 changes: 22 additions & 0 deletions src/cs/Bootsharp.Common/Meta/ArgumentMeta.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Bootsharp;

/// <summary>
/// Bootsharp-specific metadata of an interop method argument.
/// </summary>
public sealed record ArgumentMeta
{
/// <summary>
/// C# name of the argument, as specified in source code.
/// </summary>
public required string Name { get; init; }
/// <summary>
/// JavaScript name of the argument, to be specified in source code.
/// </summary>
public required string JSName { get; init; }
/// <summary>
/// Metadata of the argument's value.
/// </summary>
public required ValueMeta Value { get; init; }

public override string ToString () => $"{Name}: {Value.JSTypeSyntax}";
}
16 changes: 16 additions & 0 deletions src/cs/Bootsharp.Common/Meta/AssemblyMeta.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Bootsharp;

/// <summary>
/// Bootsharp-specific metadata of a C# assembly included in compiled solution.
/// </summary>
public sealed record AssemblyMeta
{
/// <summary>
/// Name of the assembly; equals DLL file name, w/o the extension.
/// </summary>
public required string Name { get; init; }
/// <summary>
/// Raw binary content of the assembly.
/// </summary>
public required byte[] Bytes { get; init; }
}
47 changes: 47 additions & 0 deletions src/cs/Bootsharp.Common/Meta/MethodMeta.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
namespace Bootsharp;

/// <summary>
/// Bootsharp-specific metadata of an interop method.
/// </summary>
public sealed record MethodMeta
{
/// <summary>
/// Type of interop the method is implementing.
/// </summary>
public required MethodType Type { get; init; }
/// <summary>
/// C# assembly name (DLL file name, w/o the extension), under which the method is declared.
/// </summary>
public required string Assembly { get; init; }
/// <summary>
/// Full name of the C# type (including namespace), under which the method is declared.
/// </summary>
public required string Space { get; init; }
/// <summary>
/// JavaScript object name(s) (joined with dot when nested) under which the associated interop
/// function will be declared; resolved from <see cref="Space"/> with user-defined converters.
/// </summary>
public required string JSSpace { get; init; }
/// <summary>
/// C# name of the method, as specified in source code.
/// </summary>
public required string Name { get; init; }
/// <summary>
/// JavaScript name of the method (function), as will be specified in source code.
/// </summary>
public required string JSName { get; init; }
/// <summary>
/// Arguments of the method, in declaration order.
/// </summary>
public required IReadOnlyList<ArgumentMeta> Arguments { get; init; }
/// <summary>
/// Metadata of the value returned by the method.
/// </summary>
public required ValueMeta ReturnValue { get; init; }

public override string ToString ()
{
var args = string.Join(", ", Arguments.Select(a => a.ToString()));
return $"[{Type}] {Assembly}.{Space}.{Name} ({args}) => {ReturnValue}";
}
}
23 changes: 23 additions & 0 deletions src/cs/Bootsharp.Common/Meta/MethodType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace Bootsharp;

/// <summary>
/// Type of interop method.
/// </summary>
public enum MethodType
{
/// <summary>
/// The method is implemented in C# and invoked from JavaScript;
/// implementation has <see cref="JSInvokableAttribute"/>.
/// </summary>
Invokable,
/// <summary>
/// The method is implemented in JavaScript and invoked from C#;
/// implementation has <see cref="JSFunctionAttribute"/>.
/// </summary>
Function,
/// <summary>
/// The method is invoked from C# to notify subscribers in JavaScript;
/// implementation has <see cref="JSEventAttribute"/>.
/// </summary>
Event
}
22 changes: 22 additions & 0 deletions src/cs/Bootsharp.Common/Meta/SolutionMeta.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Bootsharp;

/// <summary>
/// Bootsharp-specific metadata of the compiled solution.
/// </summary>
public sealed record SolutionMeta
{
/// <summary>
/// Assemblies included in the solution.
/// </summary>
public required IReadOnlyCollection<AssemblyMeta> Assemblies { get; init; }
/// <summary>
/// Interop methods in the solution: either top-level (eg [JSInvokable]) or
/// members of the auto-generated interop classes (eg [JSExport]).
/// </summary>
public required IReadOnlyCollection<MethodMeta> Methods { get; init; }
/// <summary>
/// Types referenced in the interop methods signatures, including
/// types associated with the prior types, crawled recursively.
/// </summary>
public required IReadOnlyCollection<Type> Types { get; init; }
}
36 changes: 36 additions & 0 deletions src/cs/Bootsharp.Common/Meta/ValueMeta.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace Bootsharp;

/// <summary>
/// Bootsharp-specific metadata of interop method's argument or returned value.
/// </summary>
public sealed record ValueMeta
{
/// <summary>
/// C# type of the value.
/// </summary>
public required Type Type { get; init; }
/// <summary>
/// C# syntax of the value type, as specified in source code.
/// </summary>
public required string TypeSyntax { get; init; }
/// <summary>
/// TypeScript syntax of the value type, to be specified in source code.
/// </summary>
public required string JSTypeSyntax { get; init; }
/// <summary>
/// Whether the value is optional/nullable.
/// </summary>
public required bool Nullable { get; init; }
/// <summary>
/// Whether the value type is of an async nature (eg, task or promise).
/// </summary>
public required bool Async { get; init; }
/// <summary>
/// Whether the value is void (when method return value).
/// </summary>
public required bool Void { get; init; }
/// <summary>
/// Whether the value has to be marshalled to/from JSON for interop.
/// </summary>
public required bool Serialized { get; init; }
}
9 changes: 9 additions & 0 deletions src/cs/Bootsharp.Common/Preferences.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// namespace Bootsharp;

// /// <summary>
// /// User preferences for Bootsharp behaviour.
// /// </summary>
// public record Preferences
// {
//
// }
12 changes: 6 additions & 6 deletions src/cs/Bootsharp.Publish.Test/Emit/EmitTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@

public class EmitTest : TaskTest
{
protected string GeneratedExports => ReadProjectFile(exportPath);
protected string GeneratedImports => ReadProjectFile(importPath);
protected string GeneratedInteropExports => ReadProjectFile(interopExportsPath);
protected string GeneratedInteropImports => ReadProjectFile(interopImportsPath);
protected string GeneratedSerializer => ReadProjectFile(serializerPath);

private string exportPath => $"{Project.Root}/InteropExports.g.cs";
private string importPath => $"{Project.Root}/InteropImports.g.cs";
private string interopExportsPath => $"{Project.Root}/InteropExports.g.cs";
private string interopImportsPath => $"{Project.Root}/InteropImports.g.cs";
private string serializerPath => $"{Project.Root}/SerializerContext.g.cs";

public override void Execute () => CreateTask().Execute();

private BootsharpEmit CreateTask () => new() {
InspectedDirectory = Project.Root,
EntryAssemblyName = LastAddedAssemblyName ?? "System.Runtime.dll",
ExportsFilePath = exportPath,
ImportsFilePath = importPath,
ExportsFilePath = interopExportsPath,
ImportsFilePath = interopImportsPath,
SerializerFilePath = serializerPath,
BuildEngine = Engine
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
namespace Bootsharp.Publish.Test;

public class ExportTest : EmitTest
public class InteropExportTest : EmitTest
{
protected override string TestedContent => GeneratedExports;
protected override string TestedContent => GeneratedInteropExports;

[Fact]
public void WhenNothingInspectedNothingIsGenerated ()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
namespace Bootsharp.Publish.Test;

public class ImportTest : EmitTest
public class InteropImportTest : EmitTest
{
protected override string TestedContent => GeneratedImports;
protected override string TestedContent => GeneratedInteropImports;

[Fact]
public void WhenNothingInspectedNothingIsGenerated ()
Expand Down
23 changes: 23 additions & 0 deletions src/cs/Bootsharp.Publish.Test/Pack/AssemblyInspectionTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace Bootsharp.Publish.Test;

public class AssemblyInspectionTest : PackTest
{
[Fact]
public void AllAssembliesAreInspected ()
{
AddAssembly("Foo.dll");
Execute();
Assert.Contains(Engine.Messages, w => w.Contains("Foo"));
Assert.Contains(Engine.Messages, w => w.Contains("Bootsharp.Common"));
Assert.Contains(Engine.Messages, w => w.Contains("System.Runtime"));
Assert.Contains(Engine.Messages, w => w.Contains("System.Private.CoreLib"));
}

[Fact]
public void WhenAssemblyInspectionFailsWarningIsLogged ()
{
File.WriteAllText(Path.Combine(Project.Root, "foo.dll"), "corrupted");
Execute();
Assert.Contains(Engine.Warnings, w => w.Contains("Failed to inspect 'foo.dll' assembly"));
}
}
35 changes: 0 additions & 35 deletions src/cs/Bootsharp.Publish.Test/Pack/InspectionTest.cs

This file was deleted.

12 changes: 0 additions & 12 deletions src/cs/Bootsharp.Publish/AssemblyInspector/Argument.cs

This file was deleted.

3 changes: 0 additions & 3 deletions src/cs/Bootsharp.Publish/AssemblyInspector/Assembly.cs

This file was deleted.

Loading

0 comments on commit d594dc1

Please sign in to comment.