Skip to content

Instantly share code, notes, and snippets.

@ErikSchierboom
Last active December 11, 2019 06:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ErikSchierboom/f6ce7c0f560c70d53b020653ee02b1d1 to your computer and use it in GitHub Desktop.
Save ErikSchierboom/f6ce7c0f560c70d53b020653ee02b1d1 to your computer and use it in GitHub Desktop.
Compile C# in-memory
// analyzer Git SHA: d236535d1656e5e11c84b25bce8374d40b9d65e0
<Project>
<PropertyGroup>
<OutDir>/Users/erikschierboom/Downloads/temp/bin</OutDir>
<BaseIntermediateOutputPath>/Users/erikschierboom/Downloads/temp/obj</BaseIntermediateOutputPath>
</PropertyGroup>
</Project>
// var xElements = xDocument.XPathSelectElements("//TestRun/Results/UnitTestResult").ToList();
// var output = process.StandardOutput.ReadToEnd();
// var solution = SolutionParser.Parse(options);
// var (representation, mapping) = SolutionRepresenter.Represent(solution);
var name = options.Slug.Dehumanize().Pascalize();
//
// var impl = File.ReadAllText(Path.Join(options.InputDirectory, $"{name}.cs"));
// var test = File.ReadAllText(Path.Join(options.InputDirectory, $"{name}Test.cs"));
// var codeString = SourceText.From(impl);
// var codeStringTest = SourceText.From(test);
// var lamngoptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_3);
//
// var parsedSyntaxTree = SyntaxFactory.ParseSyntaxTree(codeString, lamngoptions);
// var parsedSyntaxTreeTest = SyntaxFactory.ParseSyntaxTree(codeStringTest, lamngoptions);
//
//
// var references = new MetadataReference[]
// {
// MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
// MetadataReference.CreateFromFile(typeof(Console).Assembly.Location),
// MetadataReference.CreateFromFile(typeof(System.Runtime.AssemblyTargetedPatchBandAttribute).Assembly.Location),
// MetadataReference.CreateFromFile(typeof(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo).Assembly.Location),
// MetadataReference.CreateFromFile(typeof(Xunit.Assert).Assembly.Location),
// MetadataReference.CreateFromFile(typeof(Xunit.FactAttribute).Assembly.Location),
// };
//
// var compilation = CSharpCompilation.Create("Hello.dll",
// new[] { parsedSyntaxTree, parsedSyntaxTreeTest },
// references: references,
// options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary,
// optimizationLevel: OptimizationLevel.Release,
// assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default));
//
// MSBuildLocator.RegisterDefaults();
// var msBuildWorkspace = MSBuildWorkspace.Create();
// var project = msBuildWorkspace.OpenProjectAsync(Path.Join(options.InputDirectory, $"{name}.csproj")).Result;
// project = project.WithMetadataReferences(project.MetadataReferences
// .Append(MetadataReference.CreateFromFile(typeof(Xunit.Assert).Assembly.Location))
// .Append(MetadataReference.CreateFromFile(typeof(Xunit.FactAttribute).Assembly.Location)));
// MetadataReference.CreateFromFile(typeof(Xunit.Assert).Assembly.Location),
// MetadataReference.CreateFromFile(typeof(Xunit.FactAttribute).Assembly.Location),
// var compilation = project.GetCompilationAsync().Result;
// var diagnostics = compilation.GetDiagnostics().ToList();
// var errors = diagnostics.Where(diag => diag.Severity == DiagnosticSeverity.Error).ToList();
// MappingWriter.WriteToFile(options);
// var stream = new MemoryStream();
// var emitResult = compilation.Emit(stream);
//
// if (emitResult.Success){
// stream.Seek(0, SeekOrigin.Begin);
//
//
// var assembly = AssemblyLoadContext.GetLoadContext(Assembly.Load(stream.ToArray()));
//
// stream.Seek(0, SeekOrigin.Begin);
// File.WriteAllBytes("/Users/erikschierboom/Downloads/test.dll", stream.ToArray());
//// AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(stream);
//
// ManualResetEvent finished = new ManualResetEvent(false);
//
// using (var runner = AssemblyRunner.WithoutAppDomain(testAssembly))
// {
// runner.OnDiscoveryComplete = OnDiscoveryComplete;
// runner.OnExecutionComplete = OnExecutionComplete;
// runner.OnTestFailed = OnTestFailed;
// runner.OnTestSkipped = OnTestSkipped;
//
// Console.WriteLine("Discovering...");
// runner.Start(typeName);
//
// finished.WaitOne();
// finished.Dispose();
// }
// }
// Xunit.Runners.AssemblyRunner.WithoutAppDomain()
public static Assembly GetAssembly(this Compilation compilation)
{
using (var memoryStream = new MemoryStream())
{
compilation.Emit(memoryStream);
return Assembly.Load(memoryStream.ToArray());
}
}
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Exercism.Analyzers.CSharp.Analysis.Compiling;
using Xunit;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace Exercism.Analyzers.CSharp.Analysis.Testing
{
internal static class InMemoryXunitTestRunner
{
private static readonly ISourceInformationProvider SourceInformationProvider = new NullSourceInformationProvider();
private static readonly IMessageSink DiagnosticMessageSink = new Xunit.Sdk.NullMessageSink();
private static readonly IMessageSink ExecutionMessageSink = new Xunit.Sdk.NullMessageSink();
public static async Task<RunSummary> RunAllTests(Microsoft.CodeAnalysis.Compilation compilation)
{
var compilationWithAllTestsEnabled = compilation.EnableAllTests();
var assemblyInfo = GetAssemblyInfo(compilationWithAllTestsEnabled);
using (var assemblyRunner = CreateTestAssemblyRunner(assemblyInfo))
return await assemblyRunner.RunAsync();
}
private static IReflectionAssemblyInfo GetAssemblyInfo(Microsoft.CodeAnalysis.Compilation compilation) =>
Reflector.Wrap(compilation.GetAssembly());
private static XunitTestAssemblyRunner CreateTestAssemblyRunner(IAssemblyInfo assemblyInfo) =>
new XunitTestAssemblyRunner(
new TestAssembly(assemblyInfo),
GetTestCases(assemblyInfo),
DiagnosticMessageSink,
ExecutionMessageSink,
TestFrameworkOptions.ForExecution());
private static IEnumerable<IXunitTestCase> GetTestCases(IAssemblyInfo assemblyInfo)
{
using (var discoverySink = new TestDiscoverySink())
using (var discoverer = new XunitTestFrameworkDiscoverer(assemblyInfo, SourceInformationProvider, DiagnosticMessageSink))
{
discoverer.Find(false, discoverySink, TestFrameworkOptions.ForDiscovery());
discoverySink.Finished.WaitOne();
return discoverySink.TestCases.Cast<IXunitTestCase>();
}
}
}
}
using Exercism.Analyzers.CSharp.Analysis.Compiling;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Exercism.Analyzers.CSharp.Analysis.Testing
{
internal class RemoveSkipAttributeArgumentSyntaxRewriter : CSharpSyntaxRewriter
{
public override SyntaxNode VisitAttributeArgument(AttributeArgumentSyntax node) =>
AttributeArgumentNameMatches(node) ? null : base.VisitAttributeArgument(node);
private static bool AttributeArgumentNameMatches(AttributeArgumentSyntax node) =>
node.NameEquals?.Name.GetName() == "Skip";
}
}
using Exercism.Analyzers.CSharp.Analysis.Compiling;
using Microsoft.CodeAnalysis;
namespace Exercism.Analyzers.CSharp.Analysis.Testing
{
internal static class CompilationExtensions
{
private static readonly RemoveSkipAttributeArgumentSyntaxRewriter RemoveSkipAttributeArgumentSyntaxRewriter = new RemoveSkipAttributeArgumentSyntaxRewriter();
public static Compilation EnableAllTests(this Compilation compilation) =>
compilation.Rewrite(RemoveSkipAttributeArgumentSyntaxRewriter);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment