Skip to content

Commit c407b0e

Browse files
committed
[generator-Tests] Run directly with Roslyn as DotNetCompilerPlatform doesn't work on .NET Core.
1 parent 56955d9 commit c407b0e

File tree

2 files changed

+64
-55
lines changed

2 files changed

+64
-55
lines changed

tests/generator-Tests/Integration-Tests/Compiler.cs

Lines changed: 63 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,29 @@
11
using System;
2-
using System.Reflection;
3-
using System.CodeDom.Compiler;
2+
using System.Collections.Generic;
43
using System.IO;
54
using System.Linq;
6-
using System.Collections.Generic;
5+
using System.Reflection;
6+
using System.Text;
7+
using Microsoft.CodeAnalysis;
8+
using Microsoft.CodeAnalysis.CSharp;
79
using NUnit.Framework;
810

911
namespace generatortests
1012
{
11-
public static class Compiler
13+
class Compiler
1214
{
13-
const string RoslynEnvironmentVariable = "ROSLYN_COMPILER_LOCATION";
14-
private static string unitTestFrameworkAssemblyPath = typeof(Assert).Assembly.Location;
15-
private static string supportFilePath = typeof(Compiler).Assembly.Location;
16-
17-
static CodeDomProvider GetCodeDomProvider ()
18-
{
19-
if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
20-
//NOTE: there is an issue where Roslyn's csc.exe isn't copied to output for non-ASP.NET projects
21-
// Comments on this here: https://stackoverflow.com/a/40311406/132442
22-
// They added an environment variable as a workaround: https://github.com/aspnet/RoslynCodeDomProvider/pull/12
23-
if (string.IsNullOrEmpty (Environment.GetEnvironmentVariable (RoslynEnvironmentVariable, EnvironmentVariableTarget.Process))) {
24-
string roslynPath = Path.GetFullPath (Path.Combine (unitTestFrameworkAssemblyPath, "..", "..", "..", "packages", "microsoft.codedom.providers.dotnetcompilerplatform", "2.0.1", "tools", "RoslynLatest"));
25-
Environment.SetEnvironmentVariable (RoslynEnvironmentVariable, roslynPath, EnvironmentVariableTarget.Process);
26-
}
27-
28-
return new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider ();
29-
} else {
30-
return new Microsoft.CSharp.CSharpCodeProvider ();
31-
}
32-
}
15+
private static string supportFilePath = typeof (Compiler).Assembly.Location;
16+
private static string unitTestFrameworkAssemblyPath = typeof (Assert).Assembly.Location;
3317

3418
public static Assembly Compile (Xamarin.Android.Binder.CodeGeneratorOptions options,
3519
string assemblyFileName, IEnumerable<string> AdditionalSourceDirectories,
3620
out bool hasErrors, out string output, bool allowWarnings)
3721
{
22+
// Gather all the files we need to compile
3823
var generatedCodePath = options.ManagedCallableWrapperSourceOutputDirectory;
3924
var sourceFiles = Directory.EnumerateFiles (generatedCodePath, "*.cs",
4025
SearchOption.AllDirectories).ToList ();
41-
sourceFiles = sourceFiles.Select (x => Path.GetFullPath(x)).ToList ();
26+
sourceFiles = sourceFiles.Select (x => Path.GetFullPath (x)).ToList ();
4227

4328
var supportFiles = Directory.EnumerateFiles (Path.Combine (Path.GetDirectoryName (supportFilePath), "SupportFiles"),
4429
"*.cs", SearchOption.AllDirectories);
@@ -49,36 +34,51 @@ public static Assembly Compile (Xamarin.Android.Binder.CodeGeneratorOptions opti
4934
sourceFiles.AddRange (additonal);
5035
}
5136

52-
CompilerParameters parameters = new CompilerParameters ();
53-
parameters.GenerateExecutable = false;
54-
parameters.GenerateInMemory = true;
55-
parameters.CompilerOptions = "/unsafe";
56-
parameters.OutputAssembly = assemblyFileName;
57-
parameters.ReferencedAssemblies.Add (unitTestFrameworkAssemblyPath);
58-
parameters.ReferencedAssemblies.Add (typeof (Enumerable).Assembly.Location);
59-
60-
var binDir = Path.GetDirectoryName (typeof (BaseGeneratorTest).Assembly.Location);
61-
var facDir = GetFacadesPath ();
62-
parameters.ReferencedAssemblies.Add (Path.Combine (binDir, "Java.Interop.dll"));
63-
parameters.ReferencedAssemblies.Add (Path.Combine (facDir, "netstandard.dll"));
64-
#if DEBUG
65-
parameters.IncludeDebugInformation = true;
66-
#else
67-
parameters.IncludeDebugInformation = false;
68-
#endif
69-
70-
using (var codeProvider = GetCodeDomProvider ()) {
71-
CompilerResults results = codeProvider.CompileAssemblyFromFile (parameters, sourceFiles.ToArray ());
72-
73-
hasErrors = false;
74-
75-
foreach (CompilerError message in results.Errors) {
76-
hasErrors |= !message.IsWarning || !allowWarnings;
37+
// Parse the source files
38+
var syntax_trees = sourceFiles.Distinct ().Select (s => CSharpSyntaxTree.ParseText (File.ReadAllText (s))).ToArray ();
39+
40+
// Set up the assemblies we need to reference
41+
var binDir = Path.GetDirectoryName (typeof (BaseGeneratorTest).Assembly.Location);
42+
var facDir = GetFacadesPath ();
43+
44+
var references = new [] {
45+
MetadataReference.CreateFromFile (unitTestFrameworkAssemblyPath),
46+
MetadataReference.CreateFromFile (typeof(object).Assembly.Location),
47+
MetadataReference.CreateFromFile (typeof(Enumerable).Assembly.Location),
48+
MetadataReference.CreateFromFile (Path.Combine (binDir, "Java.Interop.dll")),
49+
MetadataReference.CreateFromFile (Path.Combine (facDir, "netstandard.dll"))
50+
};
51+
52+
// Compile!
53+
var compilation = CSharpCompilation.Create (
54+
Path.GetFileName (assemblyFileName),
55+
syntaxTrees: syntax_trees,
56+
references: references,
57+
options: new CSharpCompilationOptions (OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true));
58+
59+
// Save assembly to a memory stream and load it with reflection
60+
using (var ms = new MemoryStream ()) {
61+
var result = compilation.Emit (ms);
62+
var success = result.Success && (allowWarnings || !result.Diagnostics.Any (d => d.Severity == DiagnosticSeverity.Warning));
63+
64+
if (!success) {
65+
var failures = result.Diagnostics.Where (diagnostic =>
66+
diagnostic.Severity == DiagnosticSeverity.Warning ||
67+
diagnostic.Severity == DiagnosticSeverity.Error);
68+
69+
hasErrors = true;
70+
output = OutputDiagnostics (failures);
71+
} else {
72+
ms.Seek (0, SeekOrigin.Begin);
73+
74+
hasErrors = false;
75+
output = null;
76+
77+
return Assembly.Load (ms.ToArray ());
7778
}
78-
output = string.Join (Environment.NewLine, results.Output.Cast<string> ());
79-
80-
return results.CompiledAssembly;
8179
}
80+
81+
return null;
8282
}
8383

8484
static string GetFacadesPath ()
@@ -94,6 +94,15 @@ static string GetFacadesPath ()
9494

9595
return dir;
9696
}
97+
98+
static string OutputDiagnostics (IEnumerable<Diagnostic> diagnostics)
99+
{
100+
var sb = new StringBuilder ();
101+
102+
foreach (var d in diagnostics)
103+
sb.AppendLine ($"{d.Id}: {d.GetMessage ()} ({d.Location})");
104+
105+
return sb.ToString ();
106+
}
97107
}
98108
}
99-

tests/generator-Tests/generator-Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313
<Import Project="..\..\build-tools\scripts\cecil.projitems" />
1414

1515
<ItemGroup>
16+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.5.0" />
1617
<PackageReference Include="nunit" Version="3.11.0" />
1718
<PackageReference Include="NUnit.ConsoleRunner" Version="3.9.0" />
1819
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
1920
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
20-
<PackageReference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" Version="2.0.1" />
2121
</ItemGroup>
2222

2323
<ItemGroup>

0 commit comments

Comments
 (0)