internal static ImmutableArray<byte> EmitToArray( this Compilation compilation, bool metadataOnly = false, CompilationTestData testData = null, DiagnosticDescription[] expectedWarnings = null) { var stream = new MemoryStream(); var emitResult = compilation.Emit( peStream: stream, outputName: null, pdbFilePath: null, pdbStream: null, xmlDocumentationStream: null, cancellationToken: default(CancellationToken), win32Resources: null, manifestResources: null, metadataOnly: metadataOnly, testData: testData); Assert.True(emitResult.Success, "Diagnostics:\r\n" + string.Join("\r\n, ", emitResult.Diagnostics.Select(d => d.ToString()))); if (expectedWarnings != null) { emitResult.Diagnostics.Verify(expectedWarnings); } return stream.ToImmutable(); }
internal static ImmutableArray<byte> EmitToArray( this Compilation compilation, EmitOptions options = null, CompilationTestData testData = null, DiagnosticDescription[] expectedWarnings = null) { var stream = new MemoryStream(); MemoryStream pdbStream = (compilation.Options.OptimizationLevel == OptimizationLevel.Debug) && !CLRHelpers.IsRunningOnMono() ? new MemoryStream() : null; var emitResult = compilation.Emit( peStream: stream, pdbStream: pdbStream, xmlDocumentationStream: null, win32Resources: null, manifestResources: null, options: options, testData: testData, getHostDiagnostics: null, cancellationToken: default(CancellationToken)); Assert.True(emitResult.Success, "Diagnostics:\r\n" + string.Join("\r\n", emitResult.Diagnostics.Select(d => d.ToString()))); if (expectedWarnings != null) { emitResult.Diagnostics.Verify(expectedWarnings); } return stream.ToImmutable(); }
internal static ImmutableArray<byte> EmitToArray( this Compilation compilation, EmitOptions options = null, CompilationTestData testData = null, DiagnosticDescription[] expectedWarnings = null, Stream pdbStream = null, IMethodSymbol debugEntryPoint = null, Stream sourceLinkStream = null, IEnumerable<EmbeddedText> embeddedTexts = null) { var peStream = new MemoryStream(); if (pdbStream == null && compilation.Options.OptimizationLevel == OptimizationLevel.Debug && options?.DebugInformationFormat != DebugInformationFormat.Embedded) { if (MonoHelpers.IsRunningOnMono()) { options = (options ?? EmitOptions.Default).WithDebugInformationFormat(DebugInformationFormat.PortablePdb); } pdbStream = new MemoryStream(); } var emitResult = compilation.Emit( peStream: peStream, pdbStream: pdbStream, xmlDocumentationStream: null, win32Resources: null, manifestResources: null, options: options, debugEntryPoint: debugEntryPoint, sourceLinkStream: sourceLinkStream, embeddedTexts: embeddedTexts, testData: testData, cancellationToken: default(CancellationToken)); Assert.True(emitResult.Success, "Diagnostics:\r\n" + string.Join("\r\n", emitResult.Diagnostics.Select(d => d.ToString()))); if (expectedWarnings != null) { emitResult.Diagnostics.Verify(expectedWarnings); } return peStream.ToImmutable(); }
internal static CompilationDifference EmitDifference( this Compilation compilation, EmitBaseline baseline, ImmutableArray<SemanticEdit> edits, CompilationTestData testData = null) { testData = testData ?? new CompilationTestData(); var pdbName = Path.ChangeExtension(compilation.SourceModule.Name, "pdb"); // keep the stream open, it's passed to CompilationDifference var pdbStream = new MemoryStream(); using (MemoryStream mdStream = new MemoryStream(), ilStream = new MemoryStream()) { var updatedMethodTokens = new List<uint>(); var result = compilation.EmitDifference( baseline, edits, mdStream, ilStream, pdbStream, updatedMethodTokens, testData, default(CancellationToken)); pdbStream.Seek(0, SeekOrigin.Begin); return new CompilationDifference( mdStream.ToImmutable(), ilStream.ToImmutable(), pdbStream, result.Baseline, testData, result, updatedMethodTokens.ToImmutableArray()); } }
private static ImmutableArray<byte> CreateSnPublicKeyBlob(BlobHeader header, RsaPubKey rsa, byte[] pubKeyData) { var snPubKey = new SnPublicKeyBlob() { SigAlgId = AlgorithmId.RsaSign, HashAlgId = AlgorithmId.Sha, PublicKeySize = (UInt32)(s_offsetToKeyData + pubKeyData.Length) }; using (var ms = new MemoryStream(160)) using (var binaryWriter = new BinaryWriter(ms)) { binaryWriter.Write(snPubKey.SigAlgId); binaryWriter.Write(snPubKey.HashAlgId); binaryWriter.Write(snPubKey.PublicKeySize); binaryWriter.Write(header.Type); binaryWriter.Write(header.Version); binaryWriter.Write(header.Reserved); binaryWriter.Write(header.AlgId); binaryWriter.Write(rsa.Magic); binaryWriter.Write(rsa.BitLen); binaryWriter.Write(rsa.PubExp); binaryWriter.Write(pubKeyData); return ms.ToImmutable(); } }
public void AddResourceToModule() { for (int metadataOnlyIfNonzero = 0; metadataOnlyIfNonzero < 2; metadataOnlyIfNonzero++) { var metadataOnly = metadataOnlyIfNonzero != 0; Func<Compilation, Stream, ResourceDescription[], CodeAnalysis.Emit.EmitResult> emit; emit = (c, s, r) => c.Emit(s, manifestResources: r, options: new EmitOptions(metadataOnly: metadataOnly)); 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); var resourceFileName = "RoslynResourceFile.foo"; var output = new MemoryStream(); 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 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)); 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)); 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)); 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) }); 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); Assert.True(result2.Success); var assembly = System.Reflection.Assembly.ReflectionOnlyLoad(output2.ToArray()); assembly.ModuleResolve += (object sender, ResolveEventArgs e) => { if (e.Name.Equals(c_mod1.SourceModule.Name)) { return assembly.LoadModule(e.Name, output_mod1.ToArray()); } return null; }; 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 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 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(); { 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()); assembly.ModuleResolve += (object sender, ResolveEventArgs e) => { 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); } 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[] { new ResourceDescription(r2Name, () => new MemoryStream(resourceFileData), false) }); 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 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) }); Assert.True(result4.Success); var assembly = System.Reflection.Assembly.ReflectionOnlyLoad(output4.ToArray()); assembly.ModuleResolve += (object sender, ResolveEventArgs e) => { 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 | ResourceLocation.ContainedInManifestFile, rInfo.ResourceLocation); 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); } { var c5 = CreateCompilationWithMscorlib(sourceTree, new[] { ref_mod1, ref_mod3 }, TestOptions.ReleaseDll); var output5 = new MemoryStream(); var result5 = emit(c5, output5, null); Assert.True(result5.Success); var assembly = Assembly.ReflectionOnlyLoad(output5.ToArray()); 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); } { 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) }); 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); } } }
public void ImportScopeEquality() { var sources = new[] { @" extern alias A; using System; using C = System; namespace N.M { using System.Collections; class C1 { void F() {} } } namespace N.M { using System.Collections; class C2 { void F() {} } } ", @" extern alias A; using System; using C = System; namespace N.M { using System.Collections; class C3 { void F() {} } } namespace N.M { using System.Collections.Generic; class C4 { void F() {} } } ", @" extern alias A; using System; using D = System; namespace N.M { using System.Collections; class C5 { void F() {} } } ", @" extern alias A; using System; class C6 { void F() {} } " }; var c = CreateCompilationWithMscorlib(sources, new[] { SystemCoreRef.WithAliases(ImmutableArray.Create("A")) }); var pdbStream = new MemoryStream(); c.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.PortablePdb), pdbStream: pdbStream); var pdbImage = pdbStream.ToImmutable(); using (var metadata = new PinnedMetadata(pdbImage)) { var mdReader = metadata.Reader; var writer = new StringWriter(); var mdVisualizer = new MetadataVisualizer(mdReader, writer); mdVisualizer.WriteImportScope(); AssertEx.AssertEqualToleratingWhitespaceDifferences(@" ImportScope (index: 0x35, size: 36): ============================================================================================= Parent Imports ============================================================================================= 1: nil (ImportScope) 'A' (#1) = 0x23000002 (AssemblyRef) 2: 0x35000001 (ImportScope) Extern Alias 'A' (#1), 'System' (#7) 3: 0x35000001 (ImportScope) Extern Alias 'A' (#1), 'System' (#7), 'C' (#1d) = 'System' (#7) 4: 0x35000003 (ImportScope) nil 5: 0x35000004 (ImportScope) 'System.Collections' (#27) 6: 0x35000004 (ImportScope) 'System.Collections.Generic' (#4b) 7: 0x35000001 (ImportScope) Extern Alias 'A' (#1), 'System' (#7), 'D' (#69) = 'System' (#7) 8: 0x35000007 (ImportScope) nil 9: 0x35000008 (ImportScope) 'System.Collections' (#27) ", writer.ToString()); } }
public void OverloadResolutionWithStaticType() { var vbSource = @" Imports System Namespace Microsoft.VisualBasic.CompilerServices <System.AttributeUsage(System.AttributeTargets.Class, Inherited:=False, AllowMultiple:=False)> Public NotInheritable Class StandardModuleAttribute Inherits System.Attribute Public Sub New() MyBase.New() End Sub End Class End Namespace Public Module M Sub Foo(x as Action(Of String)) End Sub Sub Foo(x as Action(Of GC)) End Sub End Module "; var vbProject = VisualBasic.VisualBasicCompilation.Create( "VBProject", references: new[] { MscorlibRef }, syntaxTrees: new[] { VisualBasic.VisualBasicSyntaxTree.ParseText(vbSource) }); var csSource = @" class Program { static void Main() { M.Foo(x => { }); } } "; var metadataStream = new MemoryStream(); var emitResult = vbProject.EmitMetadataOnly(metadataStream); Assert.True(emitResult.Success); var csProject = CreateCompilationWithMscorlib( Parse(csSource), new[] { new MetadataImageReference(metadataStream.ToImmutable()) }); Assert.Equal(0, csProject.GetDiagnostics().Count()); }
public void GetSymAttributeByVersion() { var source1 = @" public class C { public static void M() { int x = 1; } }"; var source2 = @" public class C { public static void M() { int x = 1; string y = ""a""; } }"; var comp1 = CreateCompilationWithMscorlib(source1, options: TestOptions.DebugDll); var comp2 = CreateCompilationWithMscorlib(source2, options: TestOptions.DebugDll); using (MemoryStream peStream1Unused = new MemoryStream(), peStream2 = new MemoryStream(), pdbStream1 = new MemoryStream(), pdbStream2 = new MemoryStream()) { Assert.True(comp1.Emit(peStream1Unused, pdbStream1).Success); Assert.True(comp2.Emit(peStream2, pdbStream2).Success); pdbStream1.Position = 0; pdbStream2.Position = 0; peStream2.Position = 0; var symReader = SymReaderFactory.CreateReader(pdbStream1); symReader.UpdateSymbolStore(pdbStream2); var module = ModuleInstance.Create(peStream2.ToImmutable(), symReader); var runtime = CreateRuntimeInstance(module, new[] { MscorlibRef, ExpressionCompilerTestHelpers.IntrinsicAssemblyReference }); ImmutableArray<MetadataBlock> blocks; Guid moduleVersionId; ISymUnmanagedReader symReader2; int methodToken; int localSignatureToken; GetContextState(runtime, "C.M", out blocks, out moduleVersionId, out symReader2, out methodToken, out localSignatureToken); Assert.Same(symReader, symReader2); AssertEx.SetEqual(symReader.GetLocalNames(methodToken, methodVersion: 1), "x"); AssertEx.SetEqual(symReader.GetLocalNames(methodToken, methodVersion: 2), "x", "y"); var context1 = EvaluationContext.CreateMethodContext( default(CSharpMetadataContext), blocks, symReader, moduleVersionId, methodToken: methodToken, methodVersion: 1, ilOffset: 0, localSignatureToken: localSignatureToken); var locals = ArrayBuilder<LocalAndMethod>.GetInstance(); string typeName; context1.CompileGetLocals( locals, argumentsOnly: false, typeName: out typeName, testData: null); AssertEx.SetEqual(locals.Select(l => l.LocalName), "x"); var context2 = EvaluationContext.CreateMethodContext( default(CSharpMetadataContext), blocks, symReader, moduleVersionId, methodToken: methodToken, methodVersion: 2, ilOffset: 0, localSignatureToken: localSignatureToken); locals.Clear(); context2.CompileGetLocals( locals, argumentsOnly: false, typeName: out typeName, testData: null); AssertEx.SetEqual(locals.Select(l => l.LocalName), "x", "y"); } }
internal static bool EmitCompilation( Compilation c, IEnumerable<ResourceDescription> manifestResources, List<ModuleData> dependencies, DiagnosticBag diagnostics, bool emitPdb, CompilationTestData testData, out ImmutableArray<byte> assembly, out ImmutableArray<byte> pdb ) { assembly = default(ImmutableArray<byte>); pdb = default(ImmutableArray<byte>); EmitReferences(c, dependencies, diagnostics, emitPdb); using (var executableStream = new MemoryStream()) { EmitResult result; MemoryStream pdbStream; string pdbFilePath; if (emitPdb) { pdbStream = new MemoryStream(); pdbFilePath = c.AssemblyName + ".pdb"; } else { pdbStream = null; pdbFilePath = null; } try { result = c.Emit( executableStream, outputName: null, pdbFilePath: pdbFilePath, pdbStream: pdbStream, xmlDocStream: null, cancellationToken: default(CancellationToken), win32Resources: null, manifestResources: manifestResources, metadataOnly: false, testData: testData); } finally { if (pdbStream != null) { pdb = pdbStream.ToImmutable(); pdbStream.Dispose(); } } diagnostics.AddRange(result.Diagnostics); assembly = executableStream.ToImmutable(); return result.Success; } }
private static void VerifyEmitWithNoResources(CSharpCompilation comp, Platform platform) { var options = TestOptions.ReleaseExe.WithPlatform(platform); using (var outputStream = new MemoryStream()) { var success = comp.WithOptions(options).Emit(outputStream).Success; Assert.True(success); var peVerifyOutput = CLRHelpers.PeVerify(outputStream.ToImmutable()).Join(Environment.NewLine); Assert.Equal(string.Empty, peVerifyOutput); } }
public void AssemblyRefs_DuplicateRows() { var compilation = CreateCompilationWithMscorlib( "class C : C1 { }; class D { }", new[] { TestReferences.SymbolsTests.Methods.CSMethods }); PEAssemblyBuilder assembly = new PEAssemblyBuilder( (SourceAssemblySymbol)compilation.Assembly, EmitOptions.Default, compilation.Options.OutputKind, GetDefaultModulePropertiesForSerialization(), Enumerable.Empty<ResourceDescription>(), // map all references to a single name: assembylSymbol => new AssemblyIdentity("foo") ); // Don't attempt to emit if there were any syntax, declaration, semantic, or emitted errors previously. DiagnosticBag diagnostics = new DiagnosticBag(); MethodCompiler.CompileMethodBodies( compilation: compilation, moduleBeingBuiltOpt: assembly, generateDebugInfo: false, hasDeclarationErrors: false, diagnostics: diagnostics, filterOpt: null, cancellationToken: default(CancellationToken)); diagnostics.Verify(); var context = new EmitContext(assembly, null, new DiagnosticBag()); ImmutableArray<byte> image; using (var stream = new MemoryStream()) { Cci.PeWriter.WritePeToStream( context, compilation.MessageProvider, stream, nativePdbWriterOpt: null, allowMissingMethodBodies: false, deterministic: false, cancellationToken: CancellationToken.None); image = stream.ToImmutable(); } context.Diagnostics.Verify(); // check that there are no duplicate rows in AssemblyRef table: PEAssembly emittedAssembly = AssemblyMetadata.CreateFromImage(image).GetAssembly(); var emittedReferences = emittedAssembly.Modules[0].ReferencedAssemblies; Assert.Equal(1, emittedReferences.Length); Assert.Equal("foo", emittedReferences[0].Name); }
private static void VerifyEmitWithNoResources(CSharpCompilation comp, Platform platform) { var options = new CSharpCompilationOptions( OutputKind.ConsoleApplication, optimize: true, platform: platform, debugInformationKind: DebugInformationKind.None); using (var outputStream = new MemoryStream()) { var success = comp.WithOptions(options).Emit(outputStream).Success; Assert.True(success); var peVerifyOutput = CLRHelpers.PeVerify(outputStream.ToImmutable()).Join(Environment.NewLine); Assert.Equal(string.Empty, peVerifyOutput); } }
public void EmitModuleWithDifferentName() { var name = "a"; var extension = ".netmodule"; var outputName = "b"; var compilation = CreateCompilationWithMscorlib("class A { }", compOptions: TestOptions.NetModule.WithModuleName(name + extension), assemblyName: null); compilation.VerifyDiagnostics(); var assembly = compilation.Assembly; Assert.Equal("?", assembly.Name); var module = assembly.Modules.Single(); Assert.Equal(name + extension, module.Name); var stream = new MemoryStream(); Assert.True(compilation.Emit(stream, outputName + extension).Success); using (ModuleMetadata metadata = ModuleMetadata.CreateFromImage(stream.ToImmutable())) { var peReader = metadata.Module.GetMetadataReader(); Assert.False(peReader.IsAssembly); Assert.Equal(outputName + extension, peReader.GetString(peReader.GetModuleDefinition().Name)); } }
internal static CompilationDifference EmitDifference( this Compilation compilation, EmitBaseline baseline, ImmutableArray<SemanticEdit> edits, IEnumerable<ISymbol> allAddedSymbols = null, CompilationTestData testData = null) { testData = testData ?? new CompilationTestData(); var isAddedSymbol = new Func<ISymbol, bool>(s => allAddedSymbols?.Contains(s) ?? false); var pdbName = Path.ChangeExtension(compilation.SourceModule.Name, "pdb"); // keep the stream open, it's passed to CompilationDifference var pdbStream = new MemoryStream(); using (MemoryStream mdStream = new MemoryStream(), ilStream = new MemoryStream()) { var updatedMethods = new List<MethodDefinitionHandle>(); var result = compilation.EmitDifference( baseline, edits, isAddedSymbol, mdStream, ilStream, pdbStream, updatedMethods, testData, default(CancellationToken)); pdbStream.Seek(0, SeekOrigin.Begin); return new CompilationDifference( mdStream.ToImmutable(), ilStream.ToImmutable(), pdbStream, testData, result, updatedMethods.ToImmutableArray()); } }
public void EmitAssemblyWithDifferentName4() { var name = "a"; var extension = ".dll"; var nameOverride = "b"; var compilation = CreateCompilationWithMscorlib("class A { }", compOptions: TestOptions.Dll, assemblyName: name); compilation.VerifyDiagnostics(); var assembly = compilation.Assembly; Assert.Equal(name, assembly.Name); var module = assembly.Modules.Single(); Assert.Equal(name + extension, module.Name); var stream = new MemoryStream(); Assert.True(compilation.Emit(stream, nameOverride).Success); using (ModuleMetadata metadata = ModuleMetadata.CreateFromImage(stream.ToImmutable())) { var peReader = metadata.Module.GetMetadataReader(); Assert.True(peReader.IsAssembly); Assert.Equal(nameOverride, peReader.GetString(peReader.GetAssemblyDefinition().Name)); Assert.Equal(nameOverride, peReader.GetString(peReader.GetModuleDefinition().Name)); } }
public void SequencePointBlob() { string source = @" class C { public static void Main() { if (F()) { System.Console.WriteLine(1); } } public static bool F() => false; } "; var c = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); var pdbStream = new MemoryStream(); var peBlob = c.EmitToArray(EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.PortablePdb), pdbStream: pdbStream); using (var peReader = new PEReader(peBlob)) using (var pdbMetadata = new PinnedMetadata(pdbStream.ToImmutable())) { var mdReader = peReader.GetMetadataReader(); var pdbReader = pdbMetadata.Reader; foreach (var methodHandle in mdReader.MethodDefinitions) { var method = mdReader.GetMethodDefinition(methodHandle); var methodDebugInfo = pdbReader.GetMethodDebugInformation(methodHandle); var name = mdReader.GetString(method.Name); TextWriter writer = new StringWriter(); foreach (var sp in methodDebugInfo.GetSequencePoints()) { if (sp.IsHidden) { writer.WriteLine($"{sp.Offset}: <hidden>"); } else { writer.WriteLine($"{sp.Offset}: ({sp.StartLine},{sp.StartColumn})-({sp.EndLine},{sp.EndColumn})"); } } var spString = writer.ToString(); var spBlob = pdbReader.GetBlobBytes(methodDebugInfo.SequencePointsBlob); switch (name) { case "Main": AssertEx.AssertEqualToleratingWhitespaceDifferences(@" 0: (5,5)-(5,6) 1: (6,9)-(6,17) 7: <hidden> 10: (7,9)-(7,10) 11: (8,13)-(8,41) 18: (9,9)-(9,10) 19: (10,5)-(10,6) ", spString); AssertEx.Equal(new byte[] { 0x01, // local signature 0x00, // IL offset 0x00, // Delta Lines 0x01, // Delta Columns 0x05, // Start Line 0x05, // Start Column 0x01, // delta IL offset 0x00, // Delta Lines 0x08, // Delta Columns 0x02, // delta Start Line (signed compressed) 0x08, // delta Start Column (signed compressed) 0x06, // delta IL offset 0x00, // hidden 0x00, // hidden 0x03, // delta IL offset 0x00, // Delta Lines 0x01, // Delta Columns 0x02, // delta Start Line (signed compressed) 0x00, // delta Start Column (signed compressed) 0x01, // delta IL offset 0x00, // Delta Lines 0x1C, // Delta Columns 0x02, // delta Start Line (signed compressed) 0x08, // delta Start Column (signed compressed) 0x07, // delta IL offset 0x00, // Delta Lines 0x01, // Delta Columns 0x02, // delta Start Line (signed compressed) 0x79, // delta Start Column (signed compressed) 0x01, // delta IL offset 0x00, // Delta Lines 0x01, // Delta Columns 0x02, // delta Start Line (signed compressed) 0x79, // delta Start Column (signed compressed) }, spBlob); break; case "F": AssertEx.AssertEqualToleratingWhitespaceDifferences("0: (12,31)-(12,36)", spString); AssertEx.Equal(new byte[] { 0x00, // local signature 0x00, // delta IL offset 0x00, // Delta Lines 0x05, // Delta Columns 0x0C, // Start Line 0x1F // Start Column }, spBlob); break; } } } }
internal static EmitOutput? EmitCompilationCore( Compilation compilation, IEnumerable<ResourceDescription> manifestResources, DiagnosticBag diagnostics, CompilationTestData testData ) { using (var executableStream = new MemoryStream()) { var pdb = default(ImmutableArray<byte>); var assembly = default(ImmutableArray<byte>); var pdbStream = MonoHelpers.IsRunningOnMono() ? null : new MemoryStream(); EmitResult result; try { result = compilation.Emit( executableStream, pdbStream: pdbStream, xmlDocumentationStream: null, win32Resources: null, manifestResources: manifestResources, options: EmitOptions.Default, debugEntryPoint: null, testData: testData, cancellationToken: default(CancellationToken)); } finally { if (pdbStream != null) { pdb = pdbStream.ToImmutable(); pdbStream.Dispose(); } } diagnostics.AddRange(result.Diagnostics); assembly = executableStream.ToImmutable(); if (result.Success) { return new EmitOutput(assembly, pdb); } return null; } }
internal static bool EmitCompilation( Compilation compilation, IEnumerable<ResourceDescription> manifestResources, List<ModuleData> dependencies, DiagnosticBag diagnostics, CompilationTestData testData, out ImmutableArray<byte> assembly, out ImmutableArray<byte> pdb ) { assembly = default(ImmutableArray<byte>); pdb = default(ImmutableArray<byte>); EmitReferences(compilation, dependencies, diagnostics); using (var executableStream = new MemoryStream()) { MemoryStream pdbStream = new MemoryStream(); EmitResult result; try { result = compilation.Emit( executableStream, pdbStream: pdbStream, xmlDocumentationStream: null, win32Resources: null, manifestResources: manifestResources, options: EmitOptions.Default, testData: testData, cancellationToken: default(CancellationToken)); } finally { if (pdbStream != null) { pdb = pdbStream.ToImmutable(); pdbStream.Dispose(); } } diagnostics.AddRange(result.Diagnostics); assembly = executableStream.ToImmutable(); return result.Success; } }