Skip to content

Commit

Permalink
Added logpoints for outcome and progress
Browse files Browse the repository at this point in the history
  • Loading branch information
MeikTranel committed Dec 4, 2019
1 parent 6b17375 commit 98f0ba0
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 36 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ Once we have a solid base, we will bump to v1 without any breaking changes from
* #13 Fixed export writing task confusing success and failure (Thanks, @filmor)
* #10 Fixed a bug where loading a NXPorts enabled project in designtime build mode (e.g. Visual Studio) would be blocked by a failing AssemblyExportWriterTask
* #14 NXPorts now removes the obsolete `NXPorts.Attributes.dll` from the build output
* Significantly increased logging output to support diagnosing issues when using NXPorts.
30 changes: 25 additions & 5 deletions src/NXPorts/AssemblyExportWriterTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,19 @@ public sealed class AssemblyExportWriterTask : Task

public override bool Execute()
{
using (var expAttributedAssembly = new ExportAttributedAssembly(InputAssembly))
try
{
Write(expAttributedAssembly, OutputPath);
return !Log.HasLoggedErrors;
using (var expAttributedAssembly = new ExportAttributedAssembly(InputAssembly))
{
Log.LogMessage(MessageImportance.Normal, $"Found {expAttributedAssembly.ExportDefinitions.Count} annotated method(s) ready for reweaving.");
Write(expAttributedAssembly, OutputPath);
}
}
catch (Exception e)
{
Log.LogErrorFromException(e, true, true, null);
}
return !Log.HasLoggedErrors;
}

public void Write(ExportAttributedAssembly sourceAssembly, string outputPath)
Expand All @@ -40,6 +48,16 @@ public void Write(ExportAttributedAssembly sourceAssembly, string outputPath)
{
foreach (var exportDefinition in sourceAssembly.ExportDefinitions)
{
var message = $"Reweaving method '{exportDefinition.MethodDefinition.FullName}' with alias '{exportDefinition.Alias}' and calling convention '{exportDefinition.CallingConvention}'";
if (exportDefinition.TryApproximateMethodSourcePosition(out var sourcePosition)) {
Log.LogMessage(
subcategory: null, code: null, helpKeyword: null,
file: sourcePosition.FilePath, lineNumber: sourcePosition.Line ?? 0, columnNumber: sourcePosition.Column ?? 0, endLineNumber: 0, endColumnNumber: 0,
MessageImportance.Low, message
);
} else {
Log.LogMessage(MessageImportance.Low, message);
}
var returnType = exportDefinition.MethodDefinition.MethodSig.RetType;
exportDefinition.MethodDefinition.ExportInfo = new MethodExportInfo(exportDefinition.Alias);
exportDefinition.MethodDefinition.MethodSig.RetType = new CModOptSig(
Expand All @@ -51,15 +69,17 @@ public void Write(ExportAttributedAssembly sourceAssembly, string outputPath)
);
exportDefinition.MethodDefinition.CustomAttributes.RemoveAll(typeof(ExportAttribute).FullName);
}
Log.LogMessage(MessageImportance.Low, "Clearing assembly of incompatible assembly flags.");
RemoveToxicDebuggableAttribute(sourceAssembly.Module);

Log.LogMessage(MessageImportance.Low, "Adjusting PE32 header to reflect the reweaving changes to the assembly file.");
var moduleWriterOptions = new ModuleWriterOptions(sourceAssembly.Module);
moduleWriterOptions.Cor20HeaderOptions.Flags = StrictenCor20HeaderFlags(moduleWriterOptions.Cor20HeaderOptions.Flags);
moduleWriterOptions.Cor20HeaderOptions.Flags &= ~ComImageFlags.ILOnly;
moduleWriterOptions.PEHeadersOptions.Characteristics |= Characteristics.Dll;

Log.LogMessage(MessageImportance.Low, "Writing the new assembly file to disk...");
sourceAssembly.Module.Write(outputStream, moduleWriterOptions);
}
Log.LogMessage(MessageImportance.Normal, $"Successfully rewritten assembly at '{outputPath}'.");
}

private static void RemoveToxicDebuggableAttribute(ModuleDefMD module)
Expand Down
9 changes: 4 additions & 5 deletions src/NXPorts/ExportDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,18 @@ public bool Equals(ExportDefinition other)

public bool TryApproximateMethodSourcePosition(out SourcePosition sourcePosition)
{
sourcePosition = new SourcePosition(String.Empty);
sourcePosition = null;
var firstILInstruction = this.MethodDefinition.Body.Instructions.First();
var sequencePoint = firstILInstruction.SequencePoint;
if (sequencePoint != null)
return false;
else
{
if (sequencePoint != null) {
sourcePosition = new SourcePosition(
filePath: sequencePoint.Document.Url,
line: sequencePoint.StartLine - 1,
column: sequencePoint.StartColumn
);
return true;
} else {
return false;
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/NXPorts/SourcePosition.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;

namespace NXPorts
{
public class SourcePosition {
Expand All @@ -7,8 +9,8 @@ public class SourcePosition {

public SourcePosition(string filePath)
{
if (string.IsNullOrEmpty(filePath))
throw new System.ArgumentException("message", nameof(filePath));
if (filePath == null)
throw new ArgumentNullException(nameof(filePath));

this.FilePath = filePath;
}
Expand Down
4 changes: 4 additions & 0 deletions tests/NXPorts.Tests/AssemblyExportWriter_Tests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using dnlib.DotNet;
using Microsoft.Build.Utilities.ProjectCreation;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NXPorts.Tests.Infrastructure;
using PeNet;
Expand Down Expand Up @@ -31,6 +32,7 @@ public static string DoSomething()
using (var testExportAttributedAssembly = new ExportAttributedAssembly("./test.dll"))
{
var writer = new AssemblyExportWriterTask();
writer.BuildEngine = BuildEngine.Create();
writer.Write(testExportAttributedAssembly, "./test.dll");
}

Expand Down Expand Up @@ -62,6 +64,7 @@ public static void DoSomething() { }
using (var testExportAttributedAssembly = new ExportAttributedAssembly("./test.dll"))
{
var writer = new AssemblyExportWriterTask();
writer.BuildEngine = BuildEngine.Create();
writer.Write(testExportAttributedAssembly, "./test.dll");
}

Expand Down Expand Up @@ -97,6 +100,7 @@ public static void DoSomething()
using (var testExportAttributedAssembly = new ExportAttributedAssembly("./test.dll"))
{
var writer = new AssemblyExportWriterTask();
writer.BuildEngine = BuildEngine.Create();
writer.Write(testExportAttributedAssembly, "./testOut.dll");
}

Expand Down
23 changes: 23 additions & 0 deletions tests/NXPorts.Tests/Infrastructure/TestEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.IO;
using System.Linq;
using System.Reflection;
using Buildalyzer;
using Buildalyzer.Environment;
using Microsoft.Build.Utilities.ProjectCreation;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
Expand Down Expand Up @@ -83,6 +85,27 @@ public void CopyFileFromTestFiles(string relativeTestFilesPath)
{
CopyFileFromTestFiles(relativeTestFilesPath, relativeTestFilesPath);
}

public (AnalyzerResults AnalyzerResults, string log) Build(string projectFilePath, bool designTime = false)
{
using(var logWriter = new StringWriter())
{
var analyzerResults = new AnalyzerManager(
new AnalyzerManagerOptions()
{
LogWriter = logWriter
}
).GetProject(projectFilePath).Build(
new EnvironmentOptions()
{
DesignTime = designTime
}
);
return (analyzerResults, logWriter.ToString());
}
}


private static string GetApplicationDirectory()
{
return new Uri(Path.GetDirectoryName(Assembly.GetAssembly(typeof(TestEnvironment)).CodeBase)).LocalPath;
Expand Down
36 changes: 12 additions & 24 deletions tests/NXPorts.Tests/SdkBasedCSProjTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,9 @@ public void Building_a_simple_SDK_based_project_with_exports_succeeds()
testEnv.SetupNXPortsProject("./sdknet48.csproj").Save();
testEnv.CopyFileFromTestFiles("Simple.cs");

var results = new AnalyzerManager().GetProject("./sdknet48.csproj").Build(
new EnvironmentOptions()
{
DesignTime = false
}
);
var results = testEnv.Build("./sdknet48.csproj");
Assert.IsTrue(results.AnalyzerResults.OverallSuccess, "The build failed.");

Assert.IsTrue(results.OverallSuccess);
var buildOutputFile = new PeFile("./bin/debug/net48/sdknet48.dll");
Assert.AreEqual(1, buildOutputFile.ExportedFunctions.Length, "There is more or less than one export function listed in the resulting dll.");
Assert.AreEqual("DoSomething", buildOutputFile.ExportedFunctions[0].Name);
Expand All @@ -40,14 +35,9 @@ public void Designtime_builds_of_NXPorts_enabled_projects_do_not_error()
testEnv.SetupNXPortsProject("./sdknet48.csproj").Save();
testEnv.CopyFileFromTestFiles("Simple.cs");

var results = new AnalyzerManager().GetProject("./sdknet48.csproj").Build(
new EnvironmentOptions()
{
DesignTime = true
}
);
var results = testEnv.Build("./sdknet48.csproj", true);

Assert.IsTrue(results.OverallSuccess);
Assert.IsTrue(results.AnalyzerResults.OverallSuccess, "The designtime build failed.");
}
}

Expand All @@ -59,22 +49,20 @@ public void The_attributes_assembly_file_does_not_end_up_in_the_build_output()
testEnv.SetupNXPortsProject("./sdknet48.csproj").Save();
testEnv.CopyFileFromTestFiles("Simple.cs");

var results = new AnalyzerManager().GetProject("./sdknet48.csproj").Build(
new EnvironmentOptions()
{
DesignTime = false
}
);
Assert.IsTrue(results.OverallSuccess);
if(results.TryGetTargetFramework("net48", out var net48results))
var results = testEnv.Build("./sdknet48.csproj");
Assert.IsTrue(results.AnalyzerResults.OverallSuccess, "The build failed.");
if (results.AnalyzerResults.TryGetTargetFramework("net48", out var net48results))
{
Assert.IsFalse(
File.Exists(Path.Combine(Path.GetDirectoryName(net48results.ProjectFilePath),"bin/debug/net48/NXPorts.Attributes.dll")),
File.Exists(Path.Combine(Path.GetDirectoryName(net48results.ProjectFilePath), "bin/debug/net48/NXPorts.Attributes.dll")),
"NXPorts wasn't removed the from the build output."
);
} else {
}
else
{
Assert.Inconclusive("Failed to retrieve build results");
}

}
}
}
Expand Down

0 comments on commit 98f0ba0

Please sign in to comment.