1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Emit;
using Xunit;
namespace ILLink.RoslynAnalyzer.Tests
{
public static class CompilationExtensions
{
public static MetadataReference EmitToImageReference (
this Compilation comp,
EmitOptions? options = null,
bool embedInteropTypes = false,
ImmutableArray<string> aliases = default,
DiagnosticDescriptor[]? expectedWarnings = null) => EmitToPortableExecutableReference (comp, options, embedInteropTypes, aliases, expectedWarnings);
public static PortableExecutableReference EmitToPortableExecutableReference (
this Compilation comp,
EmitOptions? options = null,
bool embedInteropTypes = false,
ImmutableArray<string> aliases = default,
DiagnosticDescriptor[]? expectedWarnings = null)
{
var image = comp.EmitToArray (options, expectedWarnings: expectedWarnings);
if (comp.Options.OutputKind == OutputKind.NetModule) {
return ModuleMetadata.CreateFromImage (image).GetReference (display: comp.MakeSourceModuleName ());
} else {
return AssemblyMetadata.CreateFromImage (image).GetReference (aliases: aliases, embedInteropTypes: embedInteropTypes, display: comp.MakeSourceAssemblySimpleName ());
}
}
internal static ImmutableArray<byte> EmitToArray (
this Compilation compilation,
EmitOptions? options = null,
DiagnosticDescriptor[]? expectedWarnings = null,
Stream? pdbStream = null,
IMethodSymbol? debugEntryPoint = null,
Stream? sourceLinkStream = null,
IEnumerable<EmbeddedText>? embeddedTexts = null,
IEnumerable<ResourceDescription>? manifestResources = null,
Stream? metadataPEStream = null)
{
var peStream = new MemoryStream ();
var emitResult = compilation.Emit (
peStream: peStream,
metadataPEStream: metadataPEStream,
pdbStream: pdbStream,
xmlDocumentationStream: null,
win32Resources: null,
manifestResources: manifestResources,
options: options,
debugEntryPoint: debugEntryPoint,
sourceLinkStream: sourceLinkStream,
embeddedTexts: embeddedTexts,
cancellationToken: default (CancellationToken));
Assert.True (emitResult.Success, "Diagnostics:\r\n" + string.Join ("\r\n", emitResult.Diagnostics.Select (d => d.ToString ())));
return peStream.ToImmutable ();
}
/// <summary>
/// Reads bytes from specified <see cref="MemoryStream"/>.
/// </summary>
/// <param name="stream">The stream.</param>
/// <returns>Read-only content of the stream.</returns>
private static ImmutableArray<byte> ToImmutable (this MemoryStream stream)
{
return ImmutableArray.Create<byte> (stream.ToArray ());
}
internal static string MakeSourceModuleName (this Compilation compilation)
{
var UnspecifiedModuleAssemblyName = "?";
return compilation.Options.ModuleName ??
(compilation.AssemblyName != null ? compilation.AssemblyName + compilation.Options.OutputKind.GetDefaultExtension () : UnspecifiedModuleAssemblyName);
}
internal static string MakeSourceAssemblySimpleName (this Compilation compilation)
{
var UnspecifiedModuleAssemblyName = "?";
return compilation.AssemblyName ?? UnspecifiedModuleAssemblyName;
}
internal static string GetDefaultExtension (this OutputKind kind)
{
switch (kind) {
case OutputKind.ConsoleApplication:
case OutputKind.WindowsApplication:
case OutputKind.WindowsRuntimeApplication:
return ".exe";
case OutputKind.DynamicallyLinkedLibrary:
return ".dll";
case OutputKind.NetModule:
return ".netmodule";
case OutputKind.WindowsRuntimeMetadata:
return ".winmdobj";
default:
return ".dll";
}
}
}
}
|