diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
index 92a0774c3d8fa..1ee083781590c 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
+++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs
@@ -6766,6 +6766,15 @@ internal static string ERR_NoNamespacePrivate {
}
}
+ ///
+ /// Looks up a localized string similar to Cannot compile net modules when using /refout or /refonly..
+ ///
+ internal static string ERR_NoNetModuleOutputWhenRefOutOrRefOnly {
+ get {
+ return ResourceManager.GetString("ERR_NoNetModuleOutputWhenRefOutOrRefOnly", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Cannot create an instance of the abstract class or interface '{0}'.
///
@@ -6829,6 +6838,15 @@ internal static string ERR_NoPIANestedType {
}
}
+ ///
+ /// Looks up a localized string similar to Do not use refout when using refonly..
+ ///
+ internal static string ERR_NoRefOutWhenRefOnly {
+ get {
+ return ResourceManager.GetString("ERR_NoRefOutWhenRefOnly", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to '{0}': cannot override because '{1}' does not have an overridable set accessor.
///
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index 4a782f374669a..6f947e4563a11 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -2288,6 +2288,12 @@ If such a class is used as a base class and if the deriving class defines a dest
Merge conflict marker encountered
+
+ Do not use refout when using refonly.
+
+
+ Cannot compile net modules when using /refout or /refonly.
+
Overloadable operator expected
diff --git a/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs b/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs
index f83230991b3f1..eea38cd266404 100644
--- a/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs
+++ b/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs
@@ -67,6 +67,8 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable ar
string outputDirectory = baseDirectory;
ImmutableArray> pathMap = ImmutableArray>.Empty;
string outputFileName = null;
+ string outputRefFilePath = null;
+ bool metadataOnly = false;
string documentationPath = null;
string errorLogPath = null;
bool parseDocumentationComments = false; //Don't just null check documentationFileName because we want to do this even if the file name is invalid.
@@ -379,6 +381,7 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable ar
}
continue;
+
case "out":
if (string.IsNullOrWhiteSpace(value))
{
@@ -391,6 +394,26 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable ar
continue;
+ case "refout":
+ value = RemoveQuotesAndSlashes(value);
+ if (string.IsNullOrEmpty(value))
+ {
+ AddDiagnostic(diagnostics, ErrorCode.ERR_NoFileSpec, arg);
+ }
+ else
+ {
+ outputRefFilePath = ParseGenericPathToFile(value, diagnostics, baseDirectory);
+ }
+
+ continue;
+
+ case "refonly":
+ if (value != null)
+ break;
+
+ metadataOnly = true;
+ continue;
+
case "t":
case "target":
if (value == null)
@@ -1141,6 +1164,16 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable ar
diagnosticOptions[o.Key] = o.Value;
}
+ if (metadataOnly && outputRefFilePath != null)
+ {
+ AddDiagnostic(diagnostics, diagnosticOptions, ErrorCode.ERR_NoRefOutWhenRefOnly);
+ }
+
+ if (outputKind == OutputKind.NetModule && (metadataOnly || outputRefFilePath != null))
+ {
+ AddDiagnostic(diagnostics, diagnosticOptions, ErrorCode.ERR_NoNetModuleOutputWhenRefOutOrRefOnly);
+ }
+
if (!IsScriptRunner && !sourceFilesSpecified && (outputKind.IsNetModule() || !resourcesOrModulesSpecified))
{
AddDiagnostic(diagnostics, diagnosticOptions, ErrorCode.WRN_NoSources);
@@ -1257,7 +1290,7 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable ar
var emitOptions = new EmitOptions
(
- metadataOnly: false,
+ metadataOnly: metadataOnly,
debugInformationFormat: debugInformationFormat,
pdbFilePath: null, // to be determined later
outputNameOverride: null, // to be determined later
@@ -1282,8 +1315,9 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable ar
Utf8Output = utf8output,
CompilationName = compilationName,
OutputFileName = outputFileName,
+ OutputRefFilePath = outputRefFilePath,
PdbPath = pdbPath,
- EmitPdb = emitPdb,
+ EmitPdb = emitPdb && !metadataOnly,
SourceLink = sourceLink,
OutputDirectory = outputDirectory,
DocumentationPath = documentationPath,
diff --git a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs
index f1c43315e2751..c6a3c6f9668f9 100644
--- a/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs
+++ b/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs
@@ -2358,8 +2358,6 @@ internal override bool GenerateResourcesAndDocumentationComments(
DiagnosticBag diagnostics,
CancellationToken cancellationToken)
{
- Debug.Assert(!moduleBuilder.EmitOptions.EmitMetadataOnly);
-
// Use a temporary bag so we don't have to refilter pre-existing diagnostics.
var resourceDiagnostics = DiagnosticBag.GetInstance();
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index 27c870578cf9c..611fdd2512c4d 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -1460,5 +1460,7 @@ internal enum ErrorCode
#endregion more stragglers for C# 7
ERR_Merge_conflict_marker_encountered = 8300,
+ ERR_NoRefOutWhenRefOnly = 8301,
+ ERR_NoNetModuleOutputWhenRefOutOrRefOnly = 8302,
}
}
\ No newline at end of file
diff --git a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs
index a698a74eb27f9..6f90b59286f47 100644
--- a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs
+++ b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs
@@ -2784,6 +2784,34 @@ public void ParseOut()
// error CS2005: Missing file specification for '/out:' option
Diagnostic(ErrorCode.ERR_NoFileSpec).WithArguments("/out:"));
+ parsedArgs = DefaultParse(new[] { @"/refout:", "a.cs" }, baseDirectory);
+ parsedArgs.Errors.Verify(
+ // error CS2005: Missing file specification for '/refout:' option
+ Diagnostic(ErrorCode.ERR_NoFileSpec).WithArguments("/refout:"));
+
+ parsedArgs = DefaultParse(new[] { @"/refout:ref.dll", "/refonly", "a.cs" }, baseDirectory);
+ parsedArgs.Errors.Verify(
+ // error CS8301: Do not use refout when using refonly.
+ Diagnostic(ErrorCode.ERR_NoRefOutWhenRefOnly).WithLocation(1, 1));
+
+ parsedArgs = DefaultParse(new[] { "/refonly:incorrect", "a.cs" }, baseDirectory);
+ parsedArgs.Errors.Verify(
+ // error CS2007: Unrecognized option: '/refonly:incorrect'
+ Diagnostic(ErrorCode.ERR_BadSwitch).WithArguments("/refonly:incorrect").WithLocation(1, 1)
+ );
+
+ parsedArgs = DefaultParse(new[] { @"/refout:ref.dll", "/target:module", "a.cs" }, baseDirectory);
+ parsedArgs.Errors.Verify(
+ // error CS8302: Cannot compile net modules when using /refout or /refonly.
+ Diagnostic(ErrorCode.ERR_NoNetModuleOutputWhenRefOutOrRefOnly).WithLocation(1, 1)
+ );
+
+ parsedArgs = DefaultParse(new[] { @"/refonly", "/target:module", "a.cs" }, baseDirectory);
+ parsedArgs.Errors.Verify(
+ // error CS8302: Cannot compile net modules when using /refout or /refonly.
+ Diagnostic(ErrorCode.ERR_NoNetModuleOutputWhenRefOutOrRefOnly).WithLocation(1, 1)
+ );
+
// Dev11 reports CS2007: Unrecognized option: '/out'
parsedArgs = DefaultParse(new[] { @"/out", "a.cs" }, baseDirectory);
parsedArgs.Errors.Verify(
@@ -8845,6 +8873,164 @@ public void Version()
}
}
+ [Fact]
+ public void RefOut()
+ {
+ var dir = Temp.CreateDirectory();
+ dir.CreateDirectory("ref");
+
+ var src = dir.CreateFile("a.cs");
+ src.WriteAllText(@"
+class C
+{
+ /// Main method
+ public static void Main()
+ {
+ System.Console.Write(""Hello"");
+ }
+}");
+
+ var outWriter = new StringWriter(CultureInfo.InvariantCulture);
+ var csc = new MockCSharpCompiler(null, dir.Path,
+ new[] { "/nologo", "/out:a.exe", "/refout:ref/a.dll", "/doc:doc.xml", "/deterministic", "a.cs" });
+
+ int exitCode = csc.Run(outWriter);
+ Assert.Equal(0, exitCode);
+
+ var exe = Path.Combine(dir.Path, "a.exe");
+ Assert.True(File.Exists(exe));
+
+ MetadataReaderUtils.VerifyPEMetadata(exe,
+ new[] { "TypeDef:", "TypeDef:C" },
+ new[] { "MethodDef: Void Main()", "MethodDef: Void .ctor()" },
+ new[] { "CompilationRelaxationsAttribute", "RuntimeCompatibilityAttribute", "DebuggableAttribute" }
+ );
+
+ var doc = Path.Combine(dir.Path, "doc.xml");
+ Assert.True(File.Exists(doc));
+
+ var content = File.ReadAllText(doc);
+ var expectedDoc =
+@"
+
+
+ a
+
+
+
+ Main method
+
+
+";
+ Assert.Equal(expectedDoc, content.Trim());
+
+ var output = ProcessUtilities.RunAndGetOutput(exe, startFolder: dir.Path);
+ Assert.Equal("Hello", output.Trim());
+
+ var refDll = Path.Combine(dir.Path, Path.Combine("ref", "a.dll"));
+ Assert.True(File.Exists(refDll));
+
+ // The types and members that are included needs further refinement.
+ // ReferenceAssemblyAttribute is missing.
+ // See issue https://github.com/dotnet/roslyn/issues/17612
+ MetadataReaderUtils.VerifyPEMetadata(refDll,
+ new[] { "TypeDef:", "TypeDef:C" },
+ new[] { "MethodDef: Void Main()", "MethodDef: Void .ctor()" },
+ new[] { "CompilationRelaxationsAttribute", "RuntimeCompatibilityAttribute", "DebuggableAttribute" }
+ );
+
+ output = ProcessUtilities.RunAndGetOutput(refDll, startFolder: dir.ToString(), expectedRetCode: -532462766);
+
+ // Clean up temp files
+ CleanupAllGeneratedFiles(dir.Path);
+ }
+
+ [Fact]
+ public void RefOutWithError()
+ {
+ var dir = Temp.CreateDirectory();
+ dir.CreateDirectory("ref");
+
+ var src = dir.CreateFile("a.cs");
+ src.WriteAllText(@"class C { public static void Main() { error(); } }");
+
+ var outWriter = new StringWriter(CultureInfo.InvariantCulture);
+ var csc = new MockCSharpCompiler(null, dir.Path,
+ new[] { "/nologo", "/out:a.dll", "/refout:ref/a.dll", "/deterministic", "a.cs" });
+ int exitCode = csc.Run(outWriter);
+ Assert.Equal(1, exitCode);
+
+ var dll = Path.Combine(dir.Path, "a.dll");
+ Assert.False(File.Exists(dll));
+
+ var refDll = Path.Combine(dir.Path, Path.Combine("ref", "a.dll"));
+ Assert.False(File.Exists(refDll));
+
+ Assert.Equal("a.cs(1,39): error CS0103: The name 'error' does not exist in the current context", outWriter.ToString().Trim());
+
+ // Clean up temp files
+ CleanupAllGeneratedFiles(dir.Path);
+ }
+
+ [Fact]
+ public void RefOnly()
+ {
+ var dir = Temp.CreateDirectory();
+
+ var src = dir.CreateFile("a.cs");
+ src.WriteAllText(@"
+class C
+{
+ /// Main method
+ public static void Main()
+ {
+ error(); // semantic error in method body
+ }
+}");
+
+ var outWriter = new StringWriter(CultureInfo.InvariantCulture);
+ var csc = new MockCSharpCompiler(null, dir.Path,
+ new[] { "/nologo", "/out:a.dll", "/refonly", "/debug", "/deterministic", "/doc:doc.xml", "a.cs" });
+ int exitCode = csc.Run(outWriter);
+ Assert.Equal(0, exitCode);
+
+ var refDll = Path.Combine(dir.Path, "a.dll");
+ Assert.True(File.Exists(refDll));
+
+ // The types and members that are included needs further refinement.
+ // ReferenceAssemblyAttribute is missing.
+ // See issue https://github.com/dotnet/roslyn/issues/17612
+ MetadataReaderUtils.VerifyPEMetadata(refDll,
+ new[] { "TypeDef:", "TypeDef:C" },
+ new[] { "MethodDef: Void Main()", "MethodDef: Void .ctor()" },
+ new[] { "CompilationRelaxationsAttribute", "RuntimeCompatibilityAttribute", "DebuggableAttribute" }
+ );
+
+ var pdb = Path.Combine(dir.Path, "a.pdb");
+ Assert.False(File.Exists(pdb));
+
+ var doc = Path.Combine(dir.Path, "doc.xml");
+ Assert.True(File.Exists(doc));
+
+ var content = File.ReadAllText(doc);
+ var expectedDoc =
+@"
+
+
+ a
+
+
+
+ Main method
+
+
+";
+ Assert.Equal(expectedDoc, content.Trim());
+
+ // Clean up temp files
+ CleanupAllGeneratedFiles(dir.Path);
+ }
+
public class QuotedArgumentTests
{
private void VerifyQuotedValid(string name, string value, T expected, Func getValue)
diff --git a/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs
index 222d01b278298..bd115c7776b04 100644
--- a/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/Emit/CompilationEmitTests.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -40,7 +41,7 @@ public void Main()
EmitResult emitResult;
using (var output = new MemoryStream())
{
- emitResult = compilation.Emit(output, null, null, null);
+ emitResult = compilation.Emit(output, pdbStream: null, xmlDocumentationStream: null, win32Resources: null);
}
emitResult.Diagnostics.Verify(
@@ -148,7 +149,7 @@ namespace N.Foo;
EmitResult emitResult;
using (var output = new MemoryStream())
{
- emitResult = comp.Emit(output, null, null, null);
+ emitResult = comp.Emit(output, pdbStream: null, xmlDocumentationStream: null, win32Resources: null);
}
Assert.False(emitResult.Success);
@@ -236,6 +237,194 @@ public static void Main()
}
}
+ [Theory]
+ [InlineData("public int M() { return 1; }", "public int M() { return 2; }", true)]
+ [InlineData("public int M() { return 1; }", "public int M() { error(); }", true)]
+ [InlineData("", "private void M() { }", false)] // Should be true. See follow-up issue https://github.com/dotnet/roslyn/issues/17612
+ [InlineData("internal void M() { }", "", false)]
+ [InlineData("public struct S { private int i; }", "public struct S { }", false)]
+ public void RefAssembly_InvariantToSomeChanges(string change1, string change2, bool expectMatch)
+ {
+ string sourceTemplate = @"
+public class C
+{
+ CHANGE
+}
+";
+ string name = GetUniqueName();
+ string source1 = sourceTemplate.Replace("CHANGE", change1);
+ CSharpCompilation comp1 = CreateCompilationWithMscorlib(Parse(source1),
+ options: TestOptions.DebugDll.WithDeterministic(true), assemblyName: name);
+ ImmutableArray image1 = comp1.EmitToArray(EmitOptions.Default.WithEmitMetadataOnly(true));
+
+ var source2 = sourceTemplate.Replace("CHANGE", change2);
+ Compilation comp2 = CreateCompilationWithMscorlib(Parse(source2),
+ options: TestOptions.DebugDll.WithDeterministic(true), assemblyName: name);
+ ImmutableArray image2 = comp2.EmitToArray(EmitOptions.Default.WithEmitMetadataOnly(true));
+
+ if (expectMatch)
+ {
+ AssertEx.Equal(image1, image2);
+ }
+ else
+ {
+ AssertEx.NotEqual(image1, image2);
+ }
+ }
+
+ [Theory]
+ [InlineData("public int M() { error(); }", true)]
+ [InlineData("public int M() { error() }", false)] // Should be true. See follow-up issue https://github.com/dotnet/roslyn/issues/17612
+ [InlineData("public Error M() { return null; }", false)] // This may get relaxed. See follow-up issue https://github.com/dotnet/roslyn/issues/17612
+ public void RefAssembly_IgnoresSomeDiagnostics(string change, bool expectSuccess)
+ {
+ string sourceTemplate = @"
+public class C
+{
+ CHANGE
+}
+";
+ string source = sourceTemplate.Replace("CHANGE", change);
+ string name = GetUniqueName();
+ CSharpCompilation comp1 = CreateCompilationWithMscorlib(Parse(source),
+ options: TestOptions.DebugDll.WithDeterministic(true), assemblyName: name);
+
+ using (var output = new MemoryStream())
+ {
+ var emitResult = comp1.Emit(output, options: EmitOptions.Default.WithEmitMetadataOnly(true));
+ Assert.Equal(expectSuccess, emitResult.Success);
+ Assert.Equal(!expectSuccess, emitResult.Diagnostics.Any());
+ }
+ }
+
+ [Fact]
+ public void VerifyRefAssembly()
+ {
+ string source = @"
+public abstract class PublicClass
+{
+ public void PublicMethod() { System.Console.Write(""Hello""); }
+ private void PrivateMethod() { System.Console.Write(""Hello""); }
+ protected void ProtectedMethod() { System.Console.Write(""Hello""); }
+ internal void InternalMethod() { System.Console.Write(""Hello""); }
+ public abstract void AbstractMethod();
+}
+";
+ CSharpCompilation comp = CreateCompilation(source, references: new[] { MscorlibRef },
+ options: TestOptions.DebugDll.WithDeterministic(true));
+
+ var emitRefOnly = EmitOptions.Default.WithEmitMetadataOnly(true);
+
+ var verifier = CompileAndVerify(comp, emitOptions: emitRefOnly, verify: true);
+
+ // verify metadata (types, members, attributes)
+ var image = comp.EmitToImageReference(emitRefOnly);
+ var comp2 = CreateCompilation("", references: new[] { MscorlibRef, image },
+ options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All));
+ AssemblySymbol assembly = comp2.SourceModule.GetReferencedAssemblySymbols().Last();
+ var members = assembly.GlobalNamespace.GetMembers();
+ AssertEx.SetEqual(members.Select(m => m.ToDisplayString()),
+ new[] { "", "PublicClass" });
+
+ AssertEx.SetEqual(
+ ((NamedTypeSymbol)assembly.GlobalNamespace.GetMember("PublicClass")).GetMembers()
+ .Select(m => m.ToTestDisplayString()),
+ new[] { "void PublicClass.PublicMethod()", "void PublicClass.PrivateMethod()",
+ "void PublicClass.InternalMethod()", "void PublicClass.ProtectedMethod()",
+ "void PublicClass.AbstractMethod()", "PublicClass..ctor()" });
+
+ AssertEx.SetEqual(assembly.GetAttributes().Select(a => a.AttributeClass.ToTestDisplayString()),
+ new[] { "System.Runtime.CompilerServices.CompilationRelaxationsAttribute",
+ "System.Runtime.CompilerServices.RuntimeCompatibilityAttribute",
+ "System.Diagnostics.DebuggableAttribute" });
+
+ var peImage = comp.EmitToArray(emitRefOnly);
+ MetadataReaderUtils.VerifyMethodBodies(peImage, expectEmptyOrThrowNull: true);
+ }
+ [Fact]
+ public void EmitMetadataOnly_DisallowPdbs()
+ {
+ CSharpCompilation comp = CreateCompilation("", references: new[] { MscorlibRef },
+ options: TestOptions.DebugDll.WithDeterministic(true));
+
+ using (var output = new MemoryStream())
+ using (var pdbOutput = new MemoryStream())
+ {
+ Assert.Throws(() => comp.Emit(output, pdbOutput,
+ options: EmitOptions.Default.WithEmitMetadataOnly(true)));
+ }
+ }
+
+ [Fact]
+ public void EmitMetadataOnly_DisallowMetadataPeStream()
+ {
+ CSharpCompilation comp = CreateCompilation("", references: new[] { MscorlibRef },
+ options: TestOptions.DebugDll.WithDeterministic(true));
+
+ using (var output = new MemoryStream())
+ using (var metadataPeOutput = new MemoryStream())
+ {
+ Assert.Throws(() => comp.Emit(output, metadataPeStream: metadataPeOutput,
+ options: EmitOptions.Default.WithEmitMetadataOnly(true)));
+ }
+ }
+
+ [Fact]
+ public void EmitMetadata_DisallowOutputtingNetModule()
+ {
+ CSharpCompilation comp = CreateCompilation("", references: new[] { MscorlibRef },
+ options: TestOptions.DebugDll.WithDeterministic(true).WithOutputKind(OutputKind.NetModule));
+
+ using (var output = new MemoryStream())
+ using (var metadataPeOutput = new MemoryStream())
+ {
+ Assert.Throws(() => comp.Emit(output, metadataPeStream: metadataPeOutput,
+ options: EmitOptions.Default));
+ }
+ }
+
+ [Fact]
+ public void EmitMetadataOnly_DisallowOutputtingNetModule()
+ {
+ CSharpCompilation comp = CreateCompilation("", references: new[] { MscorlibRef },
+ options: TestOptions.DebugDll.WithDeterministic(true).WithOutputKind(OutputKind.NetModule));
+
+ using (var output = new MemoryStream())
+ {
+ Assert.Throws(() => comp.Emit(output,
+ options: EmitOptions.Default.WithEmitMetadataOnly(true)));
+ }
+ }
+
+ [Fact]
+ public void EmitMetadata()
+ {
+ string source = @"
+public abstract class PublicClass
+{
+ public void PublicMethod() { System.Console.Write(""Hello""); }
+}
+";
+ CSharpCompilation comp = CreateCompilation(source, references: new[] { MscorlibRef },
+ options: TestOptions.DebugDll.WithDeterministic(true));
+
+ using (var output = new MemoryStream())
+ using (var pdbOutput = new MemoryStream())
+ using (var metadataOutput = new MemoryStream())
+ {
+ var result = comp.Emit(output, pdbOutput, metadataPeStream: metadataOutput);
+ Assert.True(result.Success);
+ Assert.NotEqual(0, output.Position);
+ Assert.NotEqual(0, pdbOutput.Position);
+ Assert.NotEqual(0, metadataOutput.Position);
+ MetadataReaderUtils.VerifyMethodBodies(ImmutableArray.CreateRange(output.GetBuffer()), expectEmptyOrThrowNull: false);
+ MetadataReaderUtils.VerifyMethodBodies(ImmutableArray.CreateRange(metadataOutput.GetBuffer()), expectEmptyOrThrowNull: true);
+ }
+
+ var peImage = comp.EmitToArray();
+ MetadataReaderUtils.VerifyMethodBodies(peImage, expectEmptyOrThrowNull: false);
+ }
+
///
/// Check that when we emit metadata only, we include metadata for
/// compiler generate methods (e.g. the ones for implicit interface
@@ -939,7 +1128,7 @@ public class Test
EmitResult emitResult;
using (var output = new MemoryStream())
{
- emitResult = compilation.Emit(output, null, null, null);
+ emitResult = compilation.Emit(output, pdbStream: null, xmlDocumentationStream: null, win32Resources: null);
}
Assert.False(emitResult.Success);
@@ -972,7 +1161,7 @@ public static void Main()
EmitResult emitResult;
using (var output = new MemoryStream())
{
- emitResult = compilation.Emit(output, null, null, null);
+ emitResult = compilation.Emit(output, pdbStream: null, xmlDocumentationStream: null, win32Resources: null);
}
Assert.True(emitResult.Success);
@@ -1010,7 +1199,7 @@ public static void Main()
EmitResult emitResult;
using (var output = new MemoryStream())
{
- emitResult = compilation.Emit(output, null, null, null);
+ emitResult = compilation.Emit(output, pdbStream: null, xmlDocumentationStream: null, win32Resources: null);
}
Assert.True(emitResult.Success);
@@ -2726,7 +2915,7 @@ public void BrokenPDBStream()
var output = new MemoryStream();
var pdb = new BrokenStream();
pdb.BreakHow = BrokenStream.BreakHowType.ThrowOnSetLength;
- var result = compilation.Emit(output, pdb);
+ var result = compilation.Emit(output, pdbStream: pdb);
// error CS0041: Unexpected error writing debug information -- 'Exception from HRESULT: 0x806D0004'
var err = result.Diagnostics.Single();
@@ -2737,7 +2926,7 @@ public void BrokenPDBStream()
Assert.Equal(ioExceptionMessage, (string)err.Arguments[0]);
pdb.Dispose();
- result = compilation.Emit(output, pdb);
+ result = compilation.Emit(output, pdbStream: pdb);
// error CS0041: Unexpected error writing debug information -- 'Exception from HRESULT: 0x806D0004'
err = result.Diagnostics.Single();
diff --git a/src/Compilers/CSharp/Test/Emit/Emit/DeterministicTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/DeterministicTests.cs
index 7af8a4edd7fee..12c92566cb4d3 100644
--- a/src/Compilers/CSharp/Test/Emit/Emit/DeterministicTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/Emit/DeterministicTests.cs
@@ -66,8 +66,8 @@ public void BanVersionWildcards()
references: new[] { MscorlibRef },
options: TestOptions.DebugDll.WithDeterministic(false));
- var resultDeterministic = compilationDeterministic.Emit(Stream.Null, Stream.Null);
- var resultNonDeterministic = compilationNonDeterministic.Emit(Stream.Null, Stream.Null);
+ var resultDeterministic = compilationDeterministic.Emit(Stream.Null, pdbStream: Stream.Null);
+ var resultNonDeterministic = compilationNonDeterministic.Emit(Stream.Null, pdbStream: Stream.Null);
Assert.False(resultDeterministic.Success);
Assert.True(resultNonDeterministic.Success);
diff --git a/src/Compilers/CSharp/Test/Emit/Emit/ResourceTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/ResourceTests.cs
index dc95a75b61541..a416a2b5979c8 100644
--- a/src/Compilers/CSharp/Test/Emit/Emit/ResourceTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/Emit/ResourceTests.cs
@@ -432,323 +432,321 @@ public void AddManagedResource()
c1 = null;
}
+
[Fact]
public void AddResourceToModule()
{
- for (int metadataOnlyIfNonzero = 0; metadataOnlyIfNonzero < 2; metadataOnlyIfNonzero++)
- {
- var metadataOnly = metadataOnlyIfNonzero != 0;
- Func emit;
- emit = (c, s, r) => c.Emit(s, manifestResources: r, options: new EmitOptions(metadataOnly: metadataOnly));
+ bool metadataOnly = false;
+ Func emit;
+ emit = (c, s, r) => c.Emit(s, manifestResources: r, options: new EmitOptions(metadataOnly: metadataOnly));
- var sourceTree = SyntaxFactory.ParseSyntaxTree("");
+ var sourceTree = SyntaxFactory.ParseSyntaxTree("");
- // Do not name the compilation, a unique guid is used as a name by default. It prevents conflicts with other assemblies loaded via Assembly.ReflectionOnlyLoad.
- var c1 = CSharpCompilation.Create(
- Guid.NewGuid().ToString(),
- new[] { sourceTree },
- new[] { MscorlibRef },
- TestOptions.ReleaseModule);
+ // Do not name the compilation, a unique guid is used as a name by default. It prevents conflicts with other assemblies loaded via Assembly.ReflectionOnlyLoad.
+ var c1 = CSharpCompilation.Create(
+ Guid.NewGuid().ToString(),
+ new[] { sourceTree },
+ new[] { MscorlibRef },
+ TestOptions.ReleaseModule);
- var resourceFileName = "RoslynResourceFile.foo";
- var output = new MemoryStream();
+ var resourceFileName = "RoslynResourceFile.foo";
+ var output = new MemoryStream();
- const string r1Name = "some.dotted.NAME";
- const string r2Name = "another.DoTtEd.NAME";
+ const string r1Name = "some.dotted.NAME";
+ const string r2Name = "another.DoTtEd.NAME";
- var arrayOfEmbeddedData = new byte[] { 1, 2, 3, 4, 5 };
- var resourceFileData = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ var arrayOfEmbeddedData = new byte[] { 1, 2, 3, 4, 5 };
+ var resourceFileData = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
- var result = emit(c1, output,
- new ResourceDescription[]
- {
- new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), true),
- new ResourceDescription(r2Name, resourceFileName, () => new MemoryStream(resourceFileData), false)
- });
+ var result = emit(c1, output,
+ new ResourceDescription[]
+ {
+ new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), true),
+ new ResourceDescription(r2Name, resourceFileName, () => new MemoryStream(resourceFileData), false)
+ });
- Assert.False(result.Success);
- Assert.NotEmpty(result.Diagnostics.Where(x => x.Code == (int)ErrorCode.ERR_CantRefResource));
+ Assert.False(result.Success);
+ Assert.NotEmpty(result.Diagnostics.Where(x => x.Code == (int)ErrorCode.ERR_CantRefResource));
- result = emit(c1, output,
- new ResourceDescription[]
- {
- new ResourceDescription(r2Name, resourceFileName, () => new MemoryStream(resourceFileData), false),
- new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), true)
- });
+ result = emit(c1, output,
+ new ResourceDescription[]
+ {
+ new ResourceDescription(r2Name, resourceFileName, () => new MemoryStream(resourceFileData), false),
+ new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), true)
+ });
- Assert.False(result.Success);
- Assert.NotEmpty(result.Diagnostics.Where(x => x.Code == (int)ErrorCode.ERR_CantRefResource));
+ Assert.False(result.Success);
+ Assert.NotEmpty(result.Diagnostics.Where(x => x.Code == (int)ErrorCode.ERR_CantRefResource));
- result = emit(c1, output,
- new ResourceDescription[]
- {
- new ResourceDescription(r2Name, resourceFileName, () => new MemoryStream(resourceFileData), false)
- });
+ result = emit(c1, output,
+ new ResourceDescription[]
+ {
+ new ResourceDescription(r2Name, resourceFileName, () => new MemoryStream(resourceFileData), false)
+ });
- Assert.False(result.Success);
- Assert.NotEmpty(result.Diagnostics.Where(x => x.Code == (int)ErrorCode.ERR_CantRefResource));
+ Assert.False(result.Success);
+ Assert.NotEmpty(result.Diagnostics.Where(x => x.Code == (int)ErrorCode.ERR_CantRefResource));
- var c_mod1 = CSharpCompilation.Create(
- Guid.NewGuid().ToString(),
- new[] { sourceTree },
- new[] { MscorlibRef },
- TestOptions.ReleaseModule);
+ var c_mod1 = CSharpCompilation.Create(
+ Guid.NewGuid().ToString(),
+ new[] { sourceTree },
+ new[] { MscorlibRef },
+ TestOptions.ReleaseModule);
- var output_mod1 = new MemoryStream();
- result = emit(c_mod1, output_mod1,
- new ResourceDescription[]
- {
- new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), true)
- });
+ var output_mod1 = new MemoryStream();
+ result = emit(c_mod1, output_mod1,
+ new ResourceDescription[]
+ {
+ new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), true)
+ });
- Assert.True(result.Success);
- var mod1 = ModuleMetadata.CreateFromImage(output_mod1.ToImmutable());
- var ref_mod1 = mod1.GetReference();
- Assert.Equal(ManifestResourceAttributes.Public, mod1.Module.GetEmbeddedResourcesOrThrow()[0].Attributes);
+ Assert.True(result.Success);
+ var mod1 = ModuleMetadata.CreateFromImage(output_mod1.ToImmutable());
+ var ref_mod1 = mod1.GetReference();
+ Assert.Equal(ManifestResourceAttributes.Public, mod1.Module.GetEmbeddedResourcesOrThrow()[0].Attributes);
- {
- var c2 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod1 }, TestOptions.ReleaseDll);
- var output2 = new MemoryStream();
- var result2 = c2.Emit(output2);
+ {
+ var c2 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod1 }, TestOptions.ReleaseDll);
+ var output2 = new MemoryStream();
+ var result2 = c2.Emit(output2);
- Assert.True(result2.Success);
- var assembly = System.Reflection.Assembly.ReflectionOnlyLoad(output2.ToArray());
+ Assert.True(result2.Success);
+ var assembly = System.Reflection.Assembly.ReflectionOnlyLoad(output2.ToArray());
- assembly.ModuleResolve += (object sender, ResolveEventArgs e) =>
+ assembly.ModuleResolve += (object sender, ResolveEventArgs e) =>
+ {
+ if (e.Name.Equals(c_mod1.SourceModule.Name))
{
- if (e.Name.Equals(c_mod1.SourceModule.Name))
- {
- return assembly.LoadModule(e.Name, output_mod1.ToArray());
- }
+ return assembly.LoadModule(e.Name, output_mod1.ToArray());
+ }
- return null;
- };
+ return null;
+ };
- string[] resourceNames = assembly.GetManifestResourceNames();
- Assert.Equal(1, resourceNames.Length);
+ string[] resourceNames = assembly.GetManifestResourceNames();
+ Assert.Equal(1, resourceNames.Length);
- var rInfo = assembly.GetManifestResourceInfo(r1Name);
- Assert.Equal(System.Reflection.ResourceLocation.Embedded, rInfo.ResourceLocation);
- Assert.Equal(c_mod1.SourceModule.Name, rInfo.FileName);
+ var rInfo = assembly.GetManifestResourceInfo(r1Name);
+ Assert.Equal(System.Reflection.ResourceLocation.Embedded, rInfo.ResourceLocation);
+ Assert.Equal(c_mod1.SourceModule.Name, rInfo.FileName);
- var rData = assembly.GetManifestResourceStream(r1Name);
- var rBytes = new byte[rData.Length];
- rData.Read(rBytes, 0, (int)rData.Length);
- Assert.Equal(arrayOfEmbeddedData, rBytes);
- }
+ var rData = assembly.GetManifestResourceStream(r1Name);
+ var rBytes = new byte[rData.Length];
+ rData.Read(rBytes, 0, (int)rData.Length);
+ Assert.Equal(arrayOfEmbeddedData, rBytes);
+ }
- var c_mod2 = CSharpCompilation.Create(
- Guid.NewGuid().ToString(),
- new[] { sourceTree },
- new[] { MscorlibRef },
- TestOptions.ReleaseModule);
+ var c_mod2 = CSharpCompilation.Create(
+ Guid.NewGuid().ToString(),
+ new[] { sourceTree },
+ new[] { MscorlibRef },
+ TestOptions.ReleaseModule);
- var output_mod2 = new MemoryStream();
- result = emit(c_mod2, output_mod2,
- new ResourceDescription[]
- {
- new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), true),
- new ResourceDescription(r2Name, () => new MemoryStream(resourceFileData), true)
- });
+ var output_mod2 = new MemoryStream();
+ result = emit(c_mod2, output_mod2,
+ new ResourceDescription[]
+ {
+ new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), true),
+ new ResourceDescription(r2Name, () => new MemoryStream(resourceFileData), true)
+ });
- Assert.True(result.Success);
- var ref_mod2 = ModuleMetadata.CreateFromImage(output_mod2.ToImmutable()).GetReference();
+ Assert.True(result.Success);
+ var ref_mod2 = ModuleMetadata.CreateFromImage(output_mod2.ToImmutable()).GetReference();
- {
- var c3 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod2 }, TestOptions.ReleaseDll);
- var output3 = new MemoryStream();
- var result3 = c3.Emit(output3);
+ {
+ var c3 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod2 }, TestOptions.ReleaseDll);
+ var output3 = new MemoryStream();
+ var result3 = c3.Emit(output3);
- Assert.True(result3.Success);
- var assembly = Assembly.ReflectionOnlyLoad(output3.ToArray());
+ Assert.True(result3.Success);
+ var assembly = Assembly.ReflectionOnlyLoad(output3.ToArray());
- assembly.ModuleResolve += (object sender, ResolveEventArgs e) =>
+ assembly.ModuleResolve += (object sender, ResolveEventArgs e) =>
+ {
+ if (e.Name.Equals(c_mod2.SourceModule.Name))
{
- if (e.Name.Equals(c_mod2.SourceModule.Name))
- {
- return assembly.LoadModule(e.Name, output_mod2.ToArray());
- }
-
- return null;
- };
-
- string[] resourceNames = assembly.GetManifestResourceNames();
- Assert.Equal(2, resourceNames.Length);
-
- var rInfo = assembly.GetManifestResourceInfo(r1Name);
- Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
- Assert.Equal(c_mod2.SourceModule.Name, rInfo.FileName);
-
- var rData = assembly.GetManifestResourceStream(r1Name);
- var rBytes = new byte[rData.Length];
- rData.Read(rBytes, 0, (int)rData.Length);
- Assert.Equal(arrayOfEmbeddedData, rBytes);
-
- rInfo = assembly.GetManifestResourceInfo(r2Name);
- Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
- Assert.Equal(c_mod2.SourceModule.Name, rInfo.FileName);
-
- rData = assembly.GetManifestResourceStream(r2Name);
- rBytes = new byte[rData.Length];
- rData.Read(rBytes, 0, (int)rData.Length);
- Assert.Equal(resourceFileData, rBytes);
- }
+ return assembly.LoadModule(e.Name, output_mod2.ToArray());
+ }
- var c_mod3 = CSharpCompilation.Create(
- Guid.NewGuid().ToString(),
- new[] { sourceTree },
- new[] { MscorlibRef },
- TestOptions.ReleaseModule);
+ return null;
+ };
- var output_mod3 = new MemoryStream();
- result = emit(c_mod3, output_mod3,
- new ResourceDescription[]
- {
- new ResourceDescription(r2Name, () => new MemoryStream(resourceFileData), false)
- });
+ string[] resourceNames = assembly.GetManifestResourceNames();
+ Assert.Equal(2, resourceNames.Length);
+
+ var rInfo = assembly.GetManifestResourceInfo(r1Name);
+ Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
+ Assert.Equal(c_mod2.SourceModule.Name, rInfo.FileName);
- Assert.True(result.Success);
- var mod3 = ModuleMetadata.CreateFromImage(output_mod3.ToImmutable());
- var ref_mod3 = mod3.GetReference();
- Assert.Equal(ManifestResourceAttributes.Private, mod3.Module.GetEmbeddedResourcesOrThrow()[0].Attributes);
+ var rData = assembly.GetManifestResourceStream(r1Name);
+ var rBytes = new byte[rData.Length];
+ rData.Read(rBytes, 0, (int)rData.Length);
+ Assert.Equal(arrayOfEmbeddedData, rBytes);
+ rInfo = assembly.GetManifestResourceInfo(r2Name);
+ Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
+ Assert.Equal(c_mod2.SourceModule.Name, rInfo.FileName);
+
+ rData = assembly.GetManifestResourceStream(r2Name);
+ rBytes = new byte[rData.Length];
+ rData.Read(rBytes, 0, (int)rData.Length);
+ Assert.Equal(resourceFileData, rBytes);
+ }
+
+ var c_mod3 = CSharpCompilation.Create(
+ Guid.NewGuid().ToString(),
+ new[] { sourceTree },
+ new[] { MscorlibRef },
+ TestOptions.ReleaseModule);
+
+ var output_mod3 = new MemoryStream();
+ result = emit(c_mod3, output_mod3,
+ new ResourceDescription[]
{
- var c4 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod3 }, TestOptions.ReleaseDll);
- var output4 = new MemoryStream();
- var result4 = c4.Emit(output4, manifestResources:
- new ResourceDescription[]
- {
- new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), false)
- });
+ new ResourceDescription(r2Name, () => new MemoryStream(resourceFileData), false)
+ });
- Assert.True(result4.Success);
- var assembly = System.Reflection.Assembly.ReflectionOnlyLoad(output4.ToArray());
+ Assert.True(result.Success);
+ var mod3 = ModuleMetadata.CreateFromImage(output_mod3.ToImmutable());
+ var ref_mod3 = mod3.GetReference();
+ Assert.Equal(ManifestResourceAttributes.Private, mod3.Module.GetEmbeddedResourcesOrThrow()[0].Attributes);
- assembly.ModuleResolve += (object sender, ResolveEventArgs e) =>
+ {
+ var c4 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod3 }, TestOptions.ReleaseDll);
+ var output4 = new MemoryStream();
+ var result4 = c4.Emit(output4, manifestResources:
+ new ResourceDescription[]
{
- if (e.Name.Equals(c_mod3.SourceModule.Name))
- {
- return assembly.LoadModule(e.Name, output_mod3.ToArray());
- }
+ new ResourceDescription(r1Name, () => new MemoryStream(arrayOfEmbeddedData), false)
+ });
- return null;
- };
+ Assert.True(result4.Success);
+ var assembly = System.Reflection.Assembly.ReflectionOnlyLoad(output4.ToArray());
- string[] resourceNames = assembly.GetManifestResourceNames();
- Assert.Equal(2, resourceNames.Length);
+ assembly.ModuleResolve += (object sender, ResolveEventArgs e) =>
+ {
+ if (e.Name.Equals(c_mod3.SourceModule.Name))
+ {
+ return assembly.LoadModule(e.Name, output_mod3.ToArray());
+ }
- var rInfo = assembly.GetManifestResourceInfo(r1Name);
- Assert.Equal(ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile, rInfo.ResourceLocation);
+ return null;
+ };
- var rData = assembly.GetManifestResourceStream(r1Name);
- var rBytes = new byte[rData.Length];
- rData.Read(rBytes, 0, (int)rData.Length);
- Assert.Equal(arrayOfEmbeddedData, rBytes);
+ string[] resourceNames = assembly.GetManifestResourceNames();
+ Assert.Equal(2, resourceNames.Length);
- rInfo = assembly.GetManifestResourceInfo(r2Name);
- Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
- Assert.Equal(c_mod3.SourceModule.Name, rInfo.FileName);
+ var rInfo = assembly.GetManifestResourceInfo(r1Name);
+ Assert.Equal(ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile, rInfo.ResourceLocation);
- rData = assembly.GetManifestResourceStream(r2Name);
- rBytes = new byte[rData.Length];
- rData.Read(rBytes, 0, (int)rData.Length);
- Assert.Equal(resourceFileData, rBytes);
- }
+ var rData = assembly.GetManifestResourceStream(r1Name);
+ var rBytes = new byte[rData.Length];
+ rData.Read(rBytes, 0, (int)rData.Length);
+ Assert.Equal(arrayOfEmbeddedData, rBytes);
- {
- var c5 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod1, ref_mod3 }, TestOptions.ReleaseDll);
- var output5 = new MemoryStream();
- var result5 = emit(c5, output5, null);
+ rInfo = assembly.GetManifestResourceInfo(r2Name);
+ Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
+ Assert.Equal(c_mod3.SourceModule.Name, rInfo.FileName);
+
+ rData = assembly.GetManifestResourceStream(r2Name);
+ rBytes = new byte[rData.Length];
+ rData.Read(rBytes, 0, (int)rData.Length);
+ Assert.Equal(resourceFileData, rBytes);
+ }
- Assert.True(result5.Success);
- var assembly = Assembly.ReflectionOnlyLoad(output5.ToArray());
+ {
+ var c5 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod1, ref_mod3 }, TestOptions.ReleaseDll);
+ var output5 = new MemoryStream();
+ var result5 = emit(c5, output5, null);
- assembly.ModuleResolve += (object sender, ResolveEventArgs e) =>
- {
- if (e.Name.Equals(c_mod1.SourceModule.Name))
- {
- return assembly.LoadModule(e.Name, output_mod1.ToArray());
- }
- else if (e.Name.Equals(c_mod3.SourceModule.Name))
- {
- return assembly.LoadModule(e.Name, output_mod3.ToArray());
- }
-
- return null;
- };
-
- string[] resourceNames = assembly.GetManifestResourceNames();
- Assert.Equal(2, resourceNames.Length);
-
- var rInfo = assembly.GetManifestResourceInfo(r1Name);
- Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
- Assert.Equal(c_mod1.SourceModule.Name, rInfo.FileName);
-
- var rData = assembly.GetManifestResourceStream(r1Name);
- var rBytes = new byte[rData.Length];
- rData.Read(rBytes, 0, (int)rData.Length);
- Assert.Equal(arrayOfEmbeddedData, rBytes);
-
- rInfo = assembly.GetManifestResourceInfo(r2Name);
- Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
- Assert.Equal(c_mod3.SourceModule.Name, rInfo.FileName);
-
- rData = assembly.GetManifestResourceStream(r2Name);
- rBytes = new byte[rData.Length];
- rData.Read(rBytes, 0, (int)rData.Length);
- Assert.Equal(resourceFileData, rBytes);
- }
+ Assert.True(result5.Success);
+ var assembly = Assembly.ReflectionOnlyLoad(output5.ToArray());
+ assembly.ModuleResolve += (object sender, ResolveEventArgs e) =>
{
- var c6 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod1, ref_mod2 }, TestOptions.ReleaseDll);
- var output6 = new MemoryStream();
- var result6 = emit(c6, output6, null);
-
- if (metadataOnly)
+ if (e.Name.Equals(c_mod1.SourceModule.Name))
{
- Assert.True(result6.Success);
+ return assembly.LoadModule(e.Name, output_mod1.ToArray());
}
- else
+ else if (e.Name.Equals(c_mod3.SourceModule.Name))
{
- Assert.False(result6.Success);
- result6.Diagnostics.Verify(
- // error CS1508: Resource identifier 'some.dotted.NAME' has already been used in this assembly
- Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("some.dotted.NAME")
- );
+ return assembly.LoadModule(e.Name, output_mod3.ToArray());
}
- result6 = emit(c6, output6,
- new ResourceDescription[]
- {
- new ResourceDescription(r2Name, () => new MemoryStream(resourceFileData), false)
- });
+ return null;
+ };
- if (metadataOnly)
- {
- Assert.True(result6.Success);
- }
- else
- {
- Assert.False(result6.Success);
- result6.Diagnostics.Verify(
- // error CS1508: Resource identifier 'some.dotted.NAME' has already been used in this assembly
- Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("some.dotted.NAME"),
- // error CS1508: Resource identifier 'another.DoTtEd.NAME' has already been used in this assembly
- Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("another.DoTtEd.NAME")
- );
- }
+ string[] resourceNames = assembly.GetManifestResourceNames();
+ Assert.Equal(2, resourceNames.Length);
+
+ var rInfo = assembly.GetManifestResourceInfo(r1Name);
+ Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
+ Assert.Equal(c_mod1.SourceModule.Name, rInfo.FileName);
+
+ var rData = assembly.GetManifestResourceStream(r1Name);
+ var rBytes = new byte[rData.Length];
+ rData.Read(rBytes, 0, (int)rData.Length);
+ Assert.Equal(arrayOfEmbeddedData, rBytes);
+
+ rInfo = assembly.GetManifestResourceInfo(r2Name);
+ Assert.Equal(ResourceLocation.Embedded, rInfo.ResourceLocation);
+ Assert.Equal(c_mod3.SourceModule.Name, rInfo.FileName);
+
+ rData = assembly.GetManifestResourceStream(r2Name);
+ rBytes = new byte[rData.Length];
+ rData.Read(rBytes, 0, (int)rData.Length);
+ Assert.Equal(resourceFileData, rBytes);
+ }
- c6 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod1, ref_mod2 }, TestOptions.ReleaseModule);
+ {
+ var c6 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod1, ref_mod2 }, TestOptions.ReleaseDll);
+ var output6 = new MemoryStream();
+ var result6 = emit(c6, output6, null);
+
+ if (metadataOnly)
+ {
+ Assert.True(result6.Success);
+ }
+ else
+ {
+ Assert.False(result6.Success);
+ result6.Diagnostics.Verify(
+ // error CS1508: Resource identifier 'some.dotted.NAME' has already been used in this assembly
+ Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("some.dotted.NAME")
+ );
+ }
- result6 = emit(c6, output6,
- new ResourceDescription[]
- {
- new ResourceDescription(r2Name, () => new MemoryStream(resourceFileData), false)
- });
+ result6 = emit(c6, output6,
+ new ResourceDescription[]
+ {
+ new ResourceDescription(r2Name, () => new MemoryStream(resourceFileData), false)
+ });
+ if (metadataOnly)
+ {
Assert.True(result6.Success);
}
+ else
+ {
+ Assert.False(result6.Success);
+ result6.Diagnostics.Verify(
+ // error CS1508: Resource identifier 'some.dotted.NAME' has already been used in this assembly
+ Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("some.dotted.NAME"),
+ // error CS1508: Resource identifier 'another.DoTtEd.NAME' has already been used in this assembly
+ Diagnostic(ErrorCode.ERR_ResourceNotUnique).WithArguments("another.DoTtEd.NAME")
+ );
+ }
+
+ c6 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod1, ref_mod2 }, TestOptions.ReleaseModule);
+
+ result6 = emit(c6, output6,
+ new ResourceDescription[]
+ {
+ new ResourceDescription(r2Name, () => new MemoryStream(resourceFileData), false)
+ });
+
+ Assert.True(result6.Success);
}
}
diff --git a/src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs b/src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs
index a0fa5bba7f79f..97817fcf5278a 100644
--- a/src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs
@@ -133,6 +133,7 @@ public void SymWriterErrors()
{
var result = compilation.Emit(
peStream: peStream,
+ metadataPeStream: null,
pdbStream: pdbStream,
xmlDocumentationStream: null,
cancellationToken: default(CancellationToken),
@@ -166,6 +167,7 @@ public void SymWriterErrors2()
{
var result = compilation.Emit(
peStream: peStream,
+ metadataPeStream: null,
pdbStream: pdbStream,
xmlDocumentationStream: null,
cancellationToken: default(CancellationToken),
@@ -199,6 +201,7 @@ public void SymWriterErrors3()
{
var result = compilation.Emit(
peStream: peStream,
+ metadataPeStream: null,
pdbStream: pdbStream,
xmlDocumentationStream: null,
cancellationToken: default(CancellationToken),
diff --git a/src/Compilers/Core/MSBuildTask/ManagedCompiler.cs b/src/Compilers/Core/MSBuildTask/ManagedCompiler.cs
index b137cf9c561e6..a72cdd6b1281c 100644
--- a/src/Compilers/Core/MSBuildTask/ManagedCompiler.cs
+++ b/src/Compilers/Core/MSBuildTask/ManagedCompiler.cs
@@ -227,6 +227,13 @@ public ITaskItem OutputAssembly
get { return (ITaskItem)_store[nameof(OutputAssembly)]; }
}
+ [Output]
+ public ITaskItem OutputRefAssembly
+ {
+ set { _store[nameof(OutputRefAssembly)] = value; }
+ get { return (ITaskItem)_store[nameof(OutputRefAssembly)]; }
+ }
+
public string Platform
{
set { _store[nameof(Platform)] = value; }
@@ -251,6 +258,12 @@ public ITaskItem[] References
get { return (ITaskItem[])_store[nameof(References)]; }
}
+ public bool RefOnly
+ {
+ set { _store[nameof(RefOnly)] = value; }
+ get { return _store.GetOrDefault(nameof(RefOnly), false); }
+ }
+
public bool ReportAnalyzer
{
set { _store[nameof(ReportAnalyzer)] = value; }
@@ -705,6 +718,8 @@ protected internal virtual void AddResponseFileCommands(CommandLineBuilderExtens
commandLine.AppendPlusOrMinusSwitch("/optimize", _store, nameof(Optimize));
commandLine.AppendSwitchIfNotNull("/pathmap:", PathMap);
commandLine.AppendSwitchIfNotNull("/out:", OutputAssembly);
+ commandLine.AppendSwitchIfNotNull("/refout:", OutputRefAssembly);
+ commandLine.AppendWhenTrue("/refonly", _store, nameof(RefOnly));
commandLine.AppendSwitchIfNotNull("/ruleset:", CodeAnalysisRuleSet);
commandLine.AppendSwitchIfNotNull("/errorlog:", ErrorLog);
commandLine.AppendSwitchIfNotNull("/subsystemversion:", SubsystemVersion);
diff --git a/src/Compilers/Core/MSBuildTaskTests/CscTests.cs b/src/Compilers/Core/MSBuildTaskTests/CscTests.cs
index 3f538e72d9d7e..bd3e3dd55c145 100644
--- a/src/Compilers/Core/MSBuildTaskTests/CscTests.cs
+++ b/src/Compilers/Core/MSBuildTaskTests/CscTests.cs
@@ -286,5 +286,23 @@ public void Embed()
csc.EmbeddedFiles = MSBuildUtil.CreateTaskItems();
Assert.Equal(@"/debug:portable /out:test.exe test.cs", csc.GenerateResponseFileContents());
}
+
+ [Fact]
+ public void RefOut()
+ {
+ var csc = new Csc();
+ csc.Sources = MSBuildUtil.CreateTaskItems("test.cs");
+ csc.OutputRefAssembly = MSBuildUtil.CreateTaskItem("ref\\test.dll");
+ Assert.Equal("/out:test.exe /refout:ref\\test.dll test.cs", csc.GenerateResponseFileContents());
+ }
+
+ [Fact]
+ public void RefOnly()
+ {
+ var csc = new Csc();
+ csc.Sources = MSBuildUtil.CreateTaskItems("test.cs");
+ csc.RefOnly = true;
+ Assert.Equal("/out:test.exe /refonly test.cs", csc.GenerateResponseFileContents());
+ }
}
}
diff --git a/src/Compilers/Core/MSBuildTaskTests/VbcTests.cs b/src/Compilers/Core/MSBuildTaskTests/VbcTests.cs
index 554cc2b11043e..dd0b5ca23fca7 100644
--- a/src/Compilers/Core/MSBuildTaskTests/VbcTests.cs
+++ b/src/Compilers/Core/MSBuildTaskTests/VbcTests.cs
@@ -283,5 +283,23 @@ public void Embed()
vbc.EmbeddedFiles = MSBuildUtil.CreateTaskItems();
Assert.Equal(@"/optionstrict:custom /debug:portable /out:test.exe test.vb", vbc.GenerateResponseFileContents());
}
+
+ [Fact]
+ public void RefOut()
+ {
+ var vbc = new Vbc();
+ vbc.Sources = MSBuildUtil.CreateTaskItems("test.vb");
+ vbc.OutputRefAssembly = MSBuildUtil.CreateTaskItem("ref\\test.dll");
+ Assert.Equal("/optionstrict:custom /out:test.exe /refout:ref\\test.dll test.vb", vbc.GenerateResponseFileContents());
+ }
+
+ [Fact]
+ public void RefOnly()
+ {
+ var vbc = new Vbc();
+ vbc.Sources = MSBuildUtil.CreateTaskItems("test.vb");
+ vbc.RefOnly = true;
+ Assert.Equal("/optionstrict:custom /out:test.exe /refonly test.vb", vbc.GenerateResponseFileContents());
+ }
}
}
diff --git a/src/Compilers/Core/Portable/CodeAnalysisResources.Designer.cs b/src/Compilers/Core/Portable/CodeAnalysisResources.Designer.cs
index f7d3bbd3e231d..7dd8597b0b3b5 100644
--- a/src/Compilers/Core/Portable/CodeAnalysisResources.Designer.cs
+++ b/src/Compilers/Core/Portable/CodeAnalysisResources.Designer.cs
@@ -269,6 +269,15 @@ internal static string CannotEmbedInteropTypesFromModule {
}
}
+ ///
+ /// Looks up a localized string similar to Cannot target net module when emitting ref assembly..
+ ///
+ internal static string CannotTargetNetModuleWhenEmittingRefAssembly {
+ get {
+ return ResourceManager.GetString("CannotTargetNetModuleWhenEmittingRefAssembly", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Can't create a module reference to an assembly..
///
@@ -847,6 +856,15 @@ internal static string KeyInPathMapEndsWithSeparator {
}
}
+ ///
+ /// Looks up a localized string similar to Metadata PE stream should not be given when emitting metadata only..
+ ///
+ internal static string MetadataPeStreamUnexpectedWhenEmittingMetadataOnly {
+ get {
+ return ResourceManager.GetString("MetadataPeStreamUnexpectedWhenEmittingMetadataOnly", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to MetadataReference '{0}' not found to remove..
///
@@ -1027,6 +1045,15 @@ internal static string PdbStreamUnexpectedWhenEmbedding {
}
}
+ ///
+ /// Looks up a localized string similar to PDB stream should not be given when emitting metadata only..
+ ///
+ internal static string PdbStreamUnexpectedWhenEmittingMetadataOnly {
+ get {
+ return ResourceManager.GetString("PdbStreamUnexpectedWhenEmittingMetadataOnly", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to PE image doesn't contain managed metadata..
///
diff --git a/src/Compilers/Core/Portable/CodeAnalysisResources.resx b/src/Compilers/Core/Portable/CodeAnalysisResources.resx
index 3af8d6f2de563..928a36ef445d3 100644
--- a/src/Compilers/Core/Portable/CodeAnalysisResources.resx
+++ b/src/Compilers/Core/Portable/CodeAnalysisResources.resx
@@ -330,6 +330,15 @@
PDB stream should not be given when embedding PDB into the PE stream.
+
+ PDB stream should not be given when emitting metadata only.
+
+
+ Metadata PE stream should not be given when emitting metadata only.
+
+
+ Cannot target net module when emitting ref assembly.
+
Invalid hash.
diff --git a/src/Compilers/Core/Portable/CommandLine/CommonCommandLineArguments.cs b/src/Compilers/Core/Portable/CommandLine/CommonCommandLineArguments.cs
index 75c37feaf7c6e..ee5f34e2d4b71 100644
--- a/src/Compilers/Core/Portable/CommandLine/CommonCommandLineArguments.cs
+++ b/src/Compilers/Core/Portable/CommandLine/CommonCommandLineArguments.cs
@@ -85,6 +85,11 @@ public abstract class CommandLineArguments
///
public string OutputFileName { get; internal set; }
+ ///
+ /// Path of the output ref assembly or null if not specified.
+ ///
+ public string OutputRefFilePath { get; internal set; }
+
///
/// Path of the PDB file or null if same as output binary path with .pdb extension.
///
diff --git a/src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs b/src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs
index 8aeb8b3515313..21702d732cdd5 100644
--- a/src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs
+++ b/src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs
@@ -238,7 +238,7 @@ private static FileStream OpenFileForReadWithSmallBufferOptimization(string file
// size, FileStream.Read still allocates the internal buffer.
return new FileStream(
filePath,
- FileMode.Open,
+ FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite,
bufferSize: 1,
@@ -546,7 +546,7 @@ internal int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, Cancella
{
return Failed;
}
-
+
bool reportAnalyzer = false;
CancellationTokenSource analyzerCts = null;
AnalyzerManager analyzerManager = null;
@@ -736,11 +736,15 @@ internal int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, Cancella
var peStreamProvider = new CompilerEmitStreamProvider(this, finalPeFilePath);
var pdbStreamProviderOpt = emitPdbFile ? new CompilerEmitStreamProvider(this, finalPdbFilePath) : null;
+ string finalRefPeFilePath = Arguments.OutputRefFilePath;
+ var refPeStreamProviderOpt = finalRefPeFilePath != null ? new CompilerEmitStreamProvider(this, finalRefPeFilePath) : null;
+
try
{
success = compilation.SerializeToPeStream(
moduleBeingBuilt,
peStreamProvider,
+ refPeStreamProviderOpt,
pdbStreamProviderOpt,
testSymWriterFactory: null,
diagnostics: diagnosticBag,
@@ -750,6 +754,7 @@ internal int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, Cancella
finally
{
peStreamProvider.Close(diagnosticBag);
+ refPeStreamProviderOpt?.Close(diagnosticBag);
pdbStreamProviderOpt?.Close(diagnosticBag);
}
@@ -759,6 +764,10 @@ internal int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, Cancella
{
touchedFilesLogger.AddWritten(finalPdbFilePath);
}
+ if (refPeStreamProviderOpt != null)
+ {
+ touchedFilesLogger.AddWritten(finalRefPeFilePath);
+ }
touchedFilesLogger.AddWritten(finalPeFilePath);
}
}
@@ -803,48 +812,9 @@ internal int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, Cancella
}
cancellationToken.ThrowIfCancellationRequested();
-
- if (Arguments.TouchedFilesPath != null)
+ if (!WriteTouchedFiles(consoleOutput, touchedFilesLogger, finalXmlFilePath))
{
- Debug.Assert(touchedFilesLogger != null);
-
- if (finalXmlFilePath != null)
- {
- touchedFilesLogger.AddWritten(finalXmlFilePath);
- }
-
- string readFilesPath = Arguments.TouchedFilesPath + ".read";
- string writtenFilesPath = Arguments.TouchedFilesPath + ".write";
-
- var readStream = OpenFile(readFilesPath, consoleOutput, mode: FileMode.OpenOrCreate);
- var writtenStream = OpenFile(writtenFilesPath, consoleOutput, mode: FileMode.OpenOrCreate);
-
- if (readStream == null || writtenStream == null)
- {
- return Failed;
- }
-
- string filePath = null;
- try
- {
- filePath = readFilesPath;
- using (var writer = new StreamWriter(readStream))
- {
- touchedFilesLogger.WriteReadPaths(writer);
- }
-
- filePath = writtenFilesPath;
- using (var writer = new StreamWriter(writtenStream))
- {
- touchedFilesLogger.WriteWrittenPaths(writer);
- }
- }
- catch (Exception e)
- {
- Debug.Assert(filePath != null);
- MessageProvider.ReportStreamWriteException(e, filePath, consoleOutput);
- return Failed;
- }
+ return Failed;
}
}
finally
@@ -873,6 +843,54 @@ internal int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, Cancella
return Succeeded;
}
+ private bool WriteTouchedFiles(TextWriter consoleOutput, TouchedFileLogger touchedFilesLogger, string finalXmlFilePath)
+ {
+ if (Arguments.TouchedFilesPath != null)
+ {
+ Debug.Assert(touchedFilesLogger != null);
+
+ if (finalXmlFilePath != null)
+ {
+ touchedFilesLogger.AddWritten(finalXmlFilePath);
+ }
+
+ string readFilesPath = Arguments.TouchedFilesPath + ".read";
+ string writtenFilesPath = Arguments.TouchedFilesPath + ".write";
+
+ var readStream = OpenFile(readFilesPath, consoleOutput, mode: FileMode.OpenOrCreate);
+ var writtenStream = OpenFile(writtenFilesPath, consoleOutput, mode: FileMode.OpenOrCreate);
+
+ if (readStream == null || writtenStream == null)
+ {
+ return false;
+ }
+
+ string filePath = null;
+ try
+ {
+ filePath = readFilesPath;
+ using (var writer = new StreamWriter(readStream))
+ {
+ touchedFilesLogger.WriteReadPaths(writer);
+ }
+
+ filePath = writtenFilesPath;
+ using (var writer = new StreamWriter(writtenStream))
+ {
+ touchedFilesLogger.WriteWrittenPaths(writer);
+ }
+ }
+ catch (Exception e)
+ {
+ Debug.Assert(filePath != null);
+ MessageProvider.ReportStreamWriteException(e, filePath, consoleOutput);
+ return false;
+ }
+ }
+
+ return true;
+ }
+
protected virtual ImmutableArray ResolveAdditionalFilesFromArguments(List diagnostics, CommonMessageProvider messageProvider, TouchedFileLogger touchedFilesLogger)
{
var builder = ImmutableArray.CreateBuilder();
diff --git a/src/Compilers/Core/Portable/Compilation/Compilation.cs b/src/Compilers/Core/Portable/Compilation/Compilation.cs
index 4eeb2bfd0298b..a9ffb9d65fe35 100644
--- a/src/Compilers/Core/Portable/Compilation/Compilation.cs
+++ b/src/Compilers/Core/Portable/Compilation/Compilation.cs
@@ -1964,10 +1964,38 @@ public EmitResult Emit(
cancellationToken);
}
+ // 2.0 BACKCOMPAT OVERLOAD -- DO NOT TOUCH
+ public EmitResult Emit(
+ Stream peStream,
+ Stream pdbStream,
+ Stream xmlDocumentationStream,
+ Stream win32Resources,
+ IEnumerable manifestResources,
+ EmitOptions options,
+ IMethodSymbol debugEntryPoint,
+ Stream sourceLinkStream,
+ IEnumerable embeddedTexts,
+ CancellationToken cancellationToken)
+ {
+ return Emit(
+ peStream,
+ pdbStream,
+ xmlDocumentationStream,
+ win32Resources,
+ manifestResources,
+ options,
+ debugEntryPoint,
+ sourceLinkStream,
+ embeddedTexts,
+ metadataPeStream: null,
+ cancellationToken: cancellationToken);
+ }
+
///
/// Emit the IL for the compiled source code into the specified stream.
///
/// Stream to which the compilation will be written.
+ /// Stream to which the metadata-only output will be written.
/// Stream to which the compilation's debug info will be written. Null to forego PDB generation.
/// Stream to which the compilation's XML documentation will be written. Null to forego XML generation.
/// Stream from which the compilation's Win32 resources will be read (in RES format).
@@ -2008,6 +2036,7 @@ public EmitResult Emit(
IMethodSymbol debugEntryPoint = null,
Stream sourceLinkStream = null,
IEnumerable embeddedTexts = null,
+ Stream metadataPeStream = null,
CancellationToken cancellationToken = default(CancellationToken))
{
if (peStream == null)
@@ -2031,6 +2060,28 @@ public EmitResult Emit(
{
throw new ArgumentException(CodeAnalysisResources.StreamMustSupportWrite, nameof(pdbStream));
}
+
+ if (options?.EmitMetadataOnly == true)
+ {
+ throw new ArgumentException(CodeAnalysisResources.PdbStreamUnexpectedWhenEmittingMetadataOnly, nameof(pdbStream));
+ }
+ }
+
+ if (metadataPeStream != null && options?.EmitMetadataOnly == true)
+ {
+ throw new ArgumentException(CodeAnalysisResources.MetadataPeStreamUnexpectedWhenEmittingMetadataOnly, nameof(metadataPeStream));
+ }
+
+ if (this.Options.OutputKind == OutputKind.NetModule)
+ {
+ if (metadataPeStream != null)
+ {
+ throw new ArgumentException(CodeAnalysisResources.CannotTargetNetModuleWhenEmittingRefAssembly, nameof(metadataPeStream));
+ }
+ else if (options?.EmitMetadataOnly == true)
+ {
+ throw new ArgumentException(CodeAnalysisResources.CannotTargetNetModuleWhenEmittingRefAssembly, nameof(options.EmitMetadataOnly));
+ }
}
if (win32Resources != null)
@@ -2055,6 +2106,7 @@ public EmitResult Emit(
throw new ArgumentException(CodeAnalysisResources.StreamMustSupportRead, nameof(sourceLinkStream));
}
}
+
if (embeddedTexts != null && !embeddedTexts.IsEmpty())
{
if (options == null ||
@@ -2067,6 +2119,7 @@ public EmitResult Emit(
return Emit(
peStream,
+ metadataPeStream,
pdbStream,
xmlDocumentationStream,
win32Resources,
@@ -2085,6 +2138,7 @@ public EmitResult Emit(
///
internal EmitResult Emit(
Stream peStream,
+ Stream metadataPeStream,
Stream pdbStream,
Stream xmlDocumentationStream,
Stream win32Resources,
@@ -2152,6 +2206,7 @@ internal EmitResult Emit(
success = SerializeToPeStream(
moduleBeingBuilt,
new SimpleEmitStreamProvider(peStream),
+ (metadataPeStream != null) ? new SimpleEmitStreamProvider(metadataPeStream) : null,
(pdbStream != null) ? new SimpleEmitStreamProvider(pdbStream) : null,
testData?.SymWriterFactory,
diagnostics,
@@ -2318,6 +2373,7 @@ internal CommonPEModuleBuilder CheckOptionsAndCreateModuleBuilder(
internal bool SerializeToPeStream(
CommonPEModuleBuilder moduleBeingBuilt,
EmitStreamProvider peStreamProvider,
+ EmitStreamProvider metadataPeStreamProvider,
EmitStreamProvider pdbStreamProvider,
Func