Skip to content

Commit

Permalink
fix inspection
Browse files Browse the repository at this point in the history
  • Loading branch information
elringus committed Jan 23, 2024
1 parent 77b692d commit ad0c4b4
Show file tree
Hide file tree
Showing 14 changed files with 43 additions and 61 deletions.
2 changes: 0 additions & 2 deletions src/cs/Bootsharp.Common.Test/TypesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ public void ImportParametersEqualArguments ()
(import.ConstructorArguments[0].Value as IReadOnlyCollection<CustomAttributeTypedArgument>).Select(a => a.Value));
}

private static object GetNamedValue (IList<CustomAttributeNamedArgument> args, string key) =>
args.First(a => a.MemberName == key).TypedValue.Value;
private static CustomAttributeData GetMockExportAttribute () =>
typeof(TypesTest).Assembly.CustomAttributes
.First(a => a.AttributeType == typeof(JSExportAttribute));
Expand Down
15 changes: 10 additions & 5 deletions src/cs/Bootsharp.Publish.Test/Pack/AssemblyInspectionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,22 @@ public class AssemblyInspectionTest : PackTest
[Fact]
public void AllAssembliesAreInspected ()
{
AddAssembly("Foo.dll");
AddAssembly("foo.dll",
WithClass("[JSInvokable] public static void Inv () {}")
);
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"));
Assert.Contains(Engine.Messages, w => w.Contains("foo"));
}

[Fact]
public void WhenAssemblyInspectionFailsWarningIsLogged ()
{
AddAssembly("foo.dll",
WithClass("[JSInvokable] public static void InvFoo () {}")
);
AddAssembly("bar.dll",
WithClass("[JSInvokable] public static void InvBar () {}")
);
File.WriteAllText(Path.Combine(Project.Root, "foo.dll"), "corrupted");
Execute();
Assert.Contains(Engine.Warnings, w => w.Contains("Failed to inspect 'foo.dll' assembly"));
Expand Down
6 changes: 6 additions & 0 deletions src/cs/Bootsharp.Publish.Test/Pack/PackTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ public override void Execute ()
Task.Execute();
}

protected override void AddAssembly (string assemblyName, params MockSource[] sources)
{
base.AddAssembly(assemblyName, sources);
Project.WriteFile(assemblyName[..^3] + "wasm", "");
}

private BootsharpPack CreateTask () => new() {
BuildDirectory = Project.Root,
InspectedDirectory = Project.Root,
Expand Down
6 changes: 0 additions & 6 deletions src/cs/Bootsharp.Publish.Test/Pack/ResourceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ public void BinariesEmbeddedWhenEnabled ()
Execute();
Contains($$"""wasm: { name: "dotnet.native.wasm", content: "{{Convert.ToBase64String(MockWasmBinary)}}" },""");
Contains("{ name: \"Foo.wasm\", content: \"");
Contains("{ name: \"Bootsharp.Common.wasm\", content: \"");
Contains("{ name: \"System.Runtime.wasm\", content: \"");
Contains("{ name: \"System.Private.CoreLib.wasm\", content: \"");
}

[Fact]
Expand All @@ -33,8 +30,5 @@ public void BinariesNotEmbeddedWhenDisabled ()
Execute();
Contains("""wasm: { name: "dotnet.native.wasm", content: undefined },""");
Contains("""{ name: "Foo.wasm", content: undefined""");
Contains("""{ name: "Bootsharp.Common.wasm", content: undefined""");
Contains("""{ name: "System.Runtime.wasm", content: undefined""");
Contains("""{ name: "System.Private.CoreLib.wasm", content: undefined""");
}
}
2 changes: 1 addition & 1 deletion src/cs/Bootsharp.Publish.Test/TaskTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public void Dispose ()
GC.SuppressFinalize(this);
}

protected void AddAssembly (string assemblyName, params MockSource[] sources)
protected virtual void AddAssembly (string assemblyName, params MockSource[] sources)
{
LastAddedAssemblyName = assemblyName;
Project.AddAssembly(new(assemblyName, sources));
Expand Down
1 change: 0 additions & 1 deletion src/cs/Bootsharp.Publish.Test/TypesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ public class TypesTest
public void Temp ()
{
// TODO: Remove when coverlet bug is resolved: https://github.com/coverlet-coverage/coverlet/issues/1561
_ = new AssemblyMeta { Name = "", Bytes = [] } with { Name = "foo" };
_ = new InterfaceMeta { Kind = default, TypeSyntax = "", Name = "", Namespace = "", Methods = [] } with { Name = "foo" };
_ = new InterfaceMethodMeta { Name = "", Generated = default } with { Name = "foo" };
_ = new MethodMeta { Name = "", JSName = "", Arguments = default, Assembly = "", Kind = default, Space = "", JSSpace = "", ReturnValue = default } with { Assembly = "foo" };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ namespace Bootsharp.Publish;

internal class AssemblyInspection (MetadataLoadContext ctx) : IDisposable
{
public required IReadOnlyCollection<AssemblyMeta> Assemblies { get; init; }
public required IReadOnlyCollection<InterfaceMeta> Interfaces { get; init; }
public required IReadOnlyCollection<MethodMeta> Methods { get; init; }
public required IReadOnlyCollection<Type> Crawled { get; init; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,22 @@ namespace Bootsharp.Publish;

internal sealed class AssemblyInspector (Preferences prefs, string entryAssemblyName)
{
private readonly List<AssemblyMeta> assemblies = [];
private readonly List<InterfaceMeta> interfaces = [];
private readonly List<MethodMeta> methods = [];
private readonly List<string> warnings = [];
private readonly TypeConverter converter = new(prefs);

public AssemblyInspection InspectInDirectory (string directory)
public AssemblyInspection InspectInDirectory (string directory, IEnumerable<string> paths)
{
var ctx = CreateLoadContext(directory);
foreach (var assemblyPath in Directory.GetFiles(directory, "*.dll"))
foreach (var assemblyPath in paths)
try { InspectAssemblyFile(assemblyPath, ctx); }
catch (Exception e) { AddSkippedAssemblyWarning(assemblyPath, e); }
return CreateInspection(ctx);
}

private void InspectAssemblyFile (string assemblyPath, MetadataLoadContext ctx)
{
assemblies.Add(CreateAssembly(assemblyPath));
if (!ShouldIgnoreAssembly(assemblyPath))
InspectAssembly(ctx.LoadFromAssemblyPath(assemblyPath));
}
Expand All @@ -35,18 +33,12 @@ private void AddSkippedAssemblyWarning (string assemblyPath, Exception exception
}

private AssemblyInspection CreateInspection (MetadataLoadContext ctx) => new(ctx) {
Assemblies = [..assemblies],
Interfaces = [..interfaces],
Methods = [..methods],
Crawled = [..converter.CrawledTypes],
Warnings = [..warnings]
};

private AssemblyMeta CreateAssembly (string assemblyPath) => new() {
Name = Path.GetFileNameWithoutExtension(assemblyPath),
Bytes = File.ReadAllBytes(assemblyPath)
};

private void InspectAssembly (Assembly assembly)
{
foreach (var exported in assembly.GetExportedTypes())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ internal sealed class InspectionReporter (TaskLoggingHelper logger)
public void Report (AssemblyInspection inspection)
{
logger.LogMessage(MessageImportance.Normal, "Bootsharp assembly inspection result:");
logger.LogMessage(MessageImportance.Normal, JoinLines($"Discovered {inspection.Assemblies.Count} assemblies:",
JoinLines(inspection.Assemblies.Select(a => a.Name))));
logger.LogMessage(MessageImportance.Normal, JoinLines($"Discovered {inspection.Methods.Count} JS methods:",
logger.LogMessage(MessageImportance.Normal, JoinLines("Discovered assemblies:",
JoinLines(inspection.Methods.GroupBy(m => m.Assembly).Select(g => g.Key))));
logger.LogMessage(MessageImportance.Normal, JoinLines("Discovered interop methods:",
JoinLines(inspection.Methods.Select(m => m.ToString()))));

foreach (var warning in inspection.Warnings)
Expand Down
7 changes: 0 additions & 7 deletions src/cs/Bootsharp.Publish/Common/Meta/AssemblyMeta.cs

This file was deleted.

3 changes: 2 additions & 1 deletion src/cs/Bootsharp.Publish/Emit/BootsharpEmit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ private Preferences ResolvePreferences ()
private AssemblyInspection InspectAssemblies (Preferences prefs)
{
var inspector = new AssemblyInspector(prefs, EntryAssemblyName);
var inspection = inspector.InspectInDirectory(InspectedDirectory);
var inspected = Directory.GetFiles(InspectedDirectory, "*.dll");
var inspection = inspector.InspectInDirectory(InspectedDirectory, inspected);
new InspectionReporter(Log).Report(inspection);
return inspection;
}
Expand Down
10 changes: 7 additions & 3 deletions src/cs/Bootsharp.Publish/Pack/BootsharpPack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ private Preferences ResolvePreferences ()
private AssemblyInspection InspectAssemblies (Preferences prefs)
{
var inspector = new AssemblyInspector(prefs, EntryAssemblyName);
var inspection = inspector.InspectInDirectory(InspectedDirectory);
// Assemblies in publish dir are trimmed and don't contain some data (eg, method arg names).
// While the inspected dir contains extra assemblies we don't need in build. Hence the filtering.
var included = Directory.GetFiles(BuildDirectory, "*.wasm").Select(Path.GetFileNameWithoutExtension).ToHashSet();
var inspected = Directory.GetFiles(InspectedDirectory, "*.dll").Where(p => included.Contains(Path.GetFileNameWithoutExtension(p)));
var inspection = inspector.InspectInDirectory(InspectedDirectory, inspected);
new InspectionReporter(Log).Report(inspection);
return inspection;
}
Expand All @@ -53,8 +57,8 @@ private void GenerateDeclarations (Preferences prefs, AssemblyInspection inspect

private void GenerateResources (AssemblyInspection inspection)
{
var generator = new ResourceGenerator(EntryAssemblyName, BuildDirectory, EmbedBinaries);
var content = generator.Generate(inspection);
var generator = new ResourceGenerator(EntryAssemblyName, EmbedBinaries);
var content = generator.Generate(BuildDirectory);
File.WriteAllText(Path.Combine(BuildDirectory, "resources.g.js"), content);
}

Expand Down
31 changes: 11 additions & 20 deletions src/cs/Bootsharp.Publish/Pack/ResourceGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
namespace Bootsharp.Publish;

internal sealed class ResourceGenerator (string entryAssemblyName, string buildDir, bool embed)
internal sealed class ResourceGenerator (string entryAssemblyName, bool embed)
{
public string Generate (AssemblyInspection inspection)
private readonly List<string> assemblies = [];
private string wasm = null!;

public string Generate (string buildDir)
{
var wasm = BuildBin("dotnet.native.wasm", GenerateWasm());
var assemblies = inspection.Assemblies.Select(BuildAssembly);
foreach (var path in Directory.GetFiles(buildDir, "*.wasm"))
if (path.EndsWith("dotnet.native.wasm")) wasm = BuildBin(path);
else assemblies.Add(BuildBin(path));
return
$$"""
export default {
Expand All @@ -18,23 +22,10 @@ public string Generate (AssemblyInspection inspection)
""";
}

private string GenerateWasm ()
{
if (!embed) return "undefined";
var path = Path.Combine(buildDir, "dotnet.native.wasm");
var bytes = File.ReadAllBytes(path);
return ToBase64(bytes);
}

private string BuildAssembly (AssemblyMeta assembly)
{
var name = assembly.Name + ".wasm";
var content = embed ? ToBase64(assembly.Bytes) : "undefined";
return BuildBin(name, content);
}

private string BuildBin (string name, string content)
private string BuildBin (string path)
{
var name = Path.GetFileName(path);
var content = embed ? ToBase64(File.ReadAllBytes(path)) : "undefined";
return $$"""{ name: "{{name}}", content: {{content}} }""";
}

Expand Down
2 changes: 1 addition & 1 deletion src/cs/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>0.2.0-alpha.58</Version>
<Version>0.2.0-alpha.63</Version>
<Authors>Elringus</Authors>
<PackageTags>javascript typescript ts js wasm node deno bun interop codegen</PackageTags>
<PackageProjectUrl>https://bootsharp.com</PackageProjectUrl>
Expand Down

0 comments on commit ad0c4b4

Please sign in to comment.