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();
        }
Beispiel #3
0
        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());
            }
        }
Beispiel #5
0
        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();
            }
        }
Beispiel #6
0
        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);
                }
            }
        }
Beispiel #7
0
        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;
            }
        }
Beispiel #11
0
        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);
            }
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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);
            }
        }
Beispiel #14
0
        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());
            }
        }
Beispiel #16
0
        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;
                    }
                }
            }
        }
Beispiel #18
0
        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;
            }
        }