Пример #1
0
        public void CorLibWithAssemblyReferences_Pdb()
        {
            string sourceLib =
                @"namespace Namespace
{
    public class Private { }
}";
            var compLib = CreateStandardCompilation(sourceLib, assemblyName: "System.Private.Library");

            compLib.VerifyDiagnostics();
            var refLib = compLib.EmitToImageReference(aliases: ImmutableArray.Create("A"));

            string sourceCorLib =
                @"extern alias A;
#pragma warning disable 8019
using N = A::Namespace;
namespace System
{
    public class Object
    {
        public void F()
        {
        }
    }
#pragma warning disable 0436
    public class Void : Object { }
#pragma warning restore 0436
}";
            // Create a custom corlib with a reference to compilation
            // above and a reference to the actual mscorlib.
            var compCorLib = CreateCompilation(sourceCorLib, assemblyName: CorLibAssemblyName, references: new[] { MscorlibRef, refLib });

            compCorLib.VerifyDiagnostics();
            var objectType = compCorLib.SourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("System.Object");

            Assert.NotNull(objectType.BaseType);

            var pdbPath = Temp.CreateDirectory().Path;
            ImmutableArray <byte> peBytes;
            ImmutableArray <byte> pdbBytes;

            ExpressionCompilerTestHelpers.EmitCorLibWithAssemblyReferences(
                compCorLib,
                pdbPath,
                (moduleBuilder, emitOptions) => new PEAssemblyBuilderWithAdditionalReferences(moduleBuilder, emitOptions, objectType),
                out peBytes,
                out pdbBytes);
            var symReader = SymReaderFactory.CreateReader(pdbBytes);

            using (var reader = new PEReader(peBytes))
            {
                var metadata       = reader.GetMetadata();
                var module         = metadata.ToModuleMetadata(ignoreAssemblyRefs: true);
                var metadataReader = metadata.ToMetadataReader();
                var moduleInstance = ModuleInstance.Create(metadata, metadataReader.GetModuleVersionIdOrThrow(), symReader);

                // Verify the module declares System.Object.
                Assert.True(metadataReader.DeclaresTheObjectClass());
                // Verify the PEModule has no assembly references.
                Assert.Equal(0, module.Module.ReferencedAssemblies.Length);
                // Verify the underlying metadata has the expected assembly references.
                var actualReferences = metadataReader.AssemblyReferences.Select(r => metadataReader.GetString(metadataReader.GetAssemblyReference(r).Name)).ToImmutableArray();
                AssertEx.Equal(new[] { "mscorlib", "System.Private.Library" }, actualReferences);

                using (var runtime = RuntimeInstance.Create(new[] { moduleInstance }))
                {
                    string error;
                    var    context  = CreateMethodContext(runtime, "System.Object.F");
                    var    testData = new CompilationTestData();
                    // Invalid import: "using N = A::Namespace;".
                    context.CompileExpression(
                        "new N.Private()",
                        out error,
                        testData);
                    Assert.Equal("error CS0246: The type or namespace name 'N' could not be found (are you missing a using directive or an assembly reference?)", error);
                }
            }
        }
Пример #2
0
        public void CorLibWithAssemblyReferences()
        {
            string sourceLib =
                @"public class Private1
{
}
public class Private2
{
}";
            var compLib = CreateStandardCompilation(sourceLib, assemblyName: "System.Private.Library");

            compLib.VerifyDiagnostics();
            var refLib = compLib.EmitToImageReference();

            string sourceCorLib =
                @"using System.Runtime.CompilerServices;
[assembly: TypeForwardedTo(typeof(Private2))]
namespace System
{
    public class Object
    {
        public Private1 F() => null;
    }
#pragma warning disable 0436
    public class Void : Object { }
#pragma warning restore 0436
}";
            // Create a custom corlib with a reference to compilation
            // above and a reference to the actual mscorlib.
            var compCorLib = CreateCompilation(sourceCorLib, assemblyName: CorLibAssemblyName, references: new[] { MscorlibRef, refLib });

            compCorLib.VerifyDiagnostics();
            var objectType = compCorLib.SourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("System.Object");

            Assert.NotNull(objectType.BaseType);

            ImmutableArray <byte> peBytes;
            ImmutableArray <byte> pdbBytes;

            ExpressionCompilerTestHelpers.EmitCorLibWithAssemblyReferences(
                compCorLib,
                null,
                (moduleBuilder, emitOptions) => new PEAssemblyBuilderWithAdditionalReferences(moduleBuilder, emitOptions, objectType),
                out peBytes,
                out pdbBytes);

            using (var reader = new PEReader(peBytes))
            {
                var metadata       = reader.GetMetadata();
                var module         = metadata.ToModuleMetadata(ignoreAssemblyRefs: true);
                var metadataReader = metadata.ToMetadataReader();
                var moduleInstance = ModuleInstance.Create(metadata, metadataReader.GetModuleVersionIdOrThrow());

                // Verify the module declares System.Object.
                Assert.True(metadataReader.DeclaresTheObjectClass());
                // Verify the PEModule has no assembly references.
                Assert.Equal(0, module.Module.ReferencedAssemblies.Length);
                // Verify the underlying metadata has the expected assembly references.
                var actualReferences = metadataReader.AssemblyReferences.Select(r => metadataReader.GetString(metadataReader.GetAssemblyReference(r).Name)).ToImmutableArray();
                AssertEx.Equal(new[] { "mscorlib", "System.Private.Library" }, actualReferences);

                var source =
                    @"class C
{
    static void M()
    {
    }
}";
                var comp = CreateCompilation(source, options: TestOptions.DebugDll, references: new[] { refLib, AssemblyMetadata.Create(module).GetReference() });
                comp.VerifyDiagnostics();

                using (var runtime = RuntimeInstance.Create(new[] { comp.ToModuleInstance(), moduleInstance }))
                {
                    string error;
                    var    context = CreateMethodContext(runtime, "C.M");

                    // Valid expression.
                    var testData = new CompilationTestData();
                    context.CompileExpression(
                        "new object()",
                        out error,
                        testData);
                    Assert.Null(error);
                    testData.GetMethodData("<>x.<>m0").VerifyIL(
                        @"{
  // Code size        6 (0x6)
  .maxstack  1
  IL_0000:  newobj     ""object..ctor()""
  IL_0005:  ret
}");

                    // Invalid expression: System.Int32 is not defined in corlib above.
                    testData = new CompilationTestData();
                    context.CompileExpression(
                        "1",
                        out error,
                        testData);
                    Assert.Equal("error CS0518: Predefined type 'System.Int32' is not defined or imported", error);

                    // Invalid expression: type in method signature from missing referenced assembly.
                    testData = new CompilationTestData();
                    context.CompileExpression(
                        "(new object()).F()",
                        out error,
                        testData);
                    Assert.Equal("error CS0570: 'object.F()' is not supported by the language", error);

                    // Invalid expression: type forwarded to missing referenced assembly.
                    testData = new CompilationTestData();
                    context.CompileExpression(
                        "new Private2()",
                        out error,
                        testData);
                    Assert.Equal("error CS0246: The type or namespace name 'Private2' could not be found (are you missing a using directive or an assembly reference?)", error);
                }
            }
        }