private static void TupleContextNoSystemRuntime(string source, string methodName, string expression, string expectedIL,
                                                        LanguageVersion languageVersion = LanguageVersion.CSharp7)
        {
            var comp = CreateCompilationWithMscorlib40(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion),
                                                       references: new[] { SystemRuntimeFacadeRef, ValueTupleRef }, options: TestOptions.DebugDll);

            using (var systemRuntime = SystemRuntimeFacadeRef.ToModuleInstance())
            {
                WithRuntimeInstance(comp, new[] { MscorlibRef, ValueTupleRef }, runtime =>
                {
                    ImmutableArray <MetadataBlock> blocks;
                    Guid moduleVersionId;
                    ISymUnmanagedReader symReader;
                    int methodToken;
                    int localSignatureToken;
                    GetContextState(runtime, methodName, out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);
                    string errorMessage;
                    CompilationTestData testData;
                    int retryCount    = 0;
                    var compileResult = ExpressionCompilerTestHelpers.CompileExpressionWithRetry(
                        runtime.Modules.Select(m => m.MetadataBlock).ToImmutableArray(),
                        expression,
                        ImmutableArray <Alias> .Empty,
                        (b, u) => EvaluationContext.CreateMethodContext(
                            b.ToCompilation(default(Guid), MakeAssemblyReferencesKind.AllAssemblies),
                            symReader,
                            moduleVersionId,
                            methodToken,
                            methodVersion: 1,
                            ilOffset: 0,
                            localSignatureToken: localSignatureToken),
                        (AssemblyIdentity assemblyIdentity, out uint uSize) =>
                    {
                        retryCount++;
                        Assert.Equal("System.Runtime", assemblyIdentity.Name);
                        var block = systemRuntime.MetadataBlock;
                        uSize     = (uint)block.Size;
                        return(block.Pointer);
                    },
                        errorMessage: out errorMessage,
                        testData: out testData);
                    Assert.Equal(1, retryCount);
                    testData.GetMethodData("<>x.<>m0").VerifyIL(expectedIL);
                });
            }
        }
Exemple #2
0
        public void SucceedOnRetry()
        {
            var source  = @" 
class C 
{ 
    void M() 
    { 
    } 
}";
            var comp    = CreateCompilationWithMscorlib(source);
            var runtime = CreateRuntimeInstance(comp);
            var context = CreateMethodContext(runtime, "C.M");

            var missingModule   = runtime.Modules.First();
            var missingIdentity = missingModule.MetadataReader.ReadAssemblyIdentityOrThrow();

            var    shouldSucceed = false;
            string errorMessage;
            var    compileResult = ExpressionCompilerTestHelpers.CompileExpressionWithRetry(
                runtime.Modules.Select(m => m.MetadataBlock).ToImmutableArray(),
                context,
                (_, diagnostics) =>
            {
                if (shouldSucceed)
                {
                    return(TestCompileResult.Instance);
                }
                else
                {
                    shouldSucceed = true;
                    diagnostics.Add(new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_NoTypeDef, "MissingType", missingIdentity), Location.None));
                    return(null);
                }
            },
                (AssemblyIdentity assemblyIdentity, out uint uSize) =>
            {
                uSize = (uint)missingModule.MetadataLength;
                return(missingModule.MetadataAddress);
            },
                out errorMessage);

            Assert.Same(TestCompileResult.Instance, compileResult);
            Assert.Null(errorMessage);
        }
        public void WinMdAssemblyReferenceRequiresRedirect()
        {
            var source =
                @"class C : Windows.UI.Xaml.Controls.UserControl
{
    static void M(C c)
    {
    }
}";
            var compilation = CreateEmptyCompilation(source, WinRtRefs, TestOptions.DebugDll);

            WithRuntimeInstance(compilation, new[] { MscorlibRef }.Concat(ExpressionCompilerTestHelpers.GetRuntimeWinMds("Windows.UI", "Windows.UI.Xaml")), runtime =>
            {
                string errorMessage;
                var testData = new CompilationTestData();
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(
                    runtime.Modules.SelectAsArray(m => m.MetadataBlock),
                    "c.Dispatcher",
                    ImmutableArray <Alias> .Empty,
                    (metadataBlocks, _) =>
                {
                    return(CreateMethodContext(runtime, "C.M"));
                },
                    (AssemblyIdentity assembly, out uint size) =>
                {
                    // Compilation should succeed without retry if we redirect assembly refs correctly.
                    // Throwing so that we don't loop forever (as we did before fix)...
                    throw ExceptionUtilities.Unreachable;
                },
                    out errorMessage,
                    out testData);
                Assert.Null(errorMessage);
                testData.GetMethodData("<>x.<>m0").VerifyIL(
                    @"{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  callvirt   ""Windows.UI.Core.CoreDispatcher Windows.UI.Xaml.DependencyObject.Dispatcher.get""
  IL_0006:  ret
}");
            });
        }
        public void CompileWithRetrySameErrorReported()
        {
            var source = @" 
class C 
{ 
    void M() 
    { 
    } 
}";
            var comp   = CreateStandardCompilation(source);

            WithRuntimeInstance(comp, runtime =>
            {
                var context = CreateMethodContext(runtime, "C.M");

                var missingModule   = runtime.Modules.First();
                var missingIdentity = missingModule.GetMetadataReader().ReadAssemblyIdentityOrThrow();

                var numRetries = 0;
                string errorMessage;
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(
                    runtime.Modules.Select(m => m.MetadataBlock).ToImmutableArray(),
                    context,
                    (_, diagnostics) =>
                {
                    numRetries++;
                    Assert.InRange(numRetries, 0, 2);     // We don't want to loop forever...
                    diagnostics.Add(new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_NoTypeDef, "MissingType", missingIdentity), Location.None));
                    return(null);
                },
                    (AssemblyIdentity assemblyIdentity, out uint uSize) =>
                {
                    uSize = (uint)missingModule.MetadataLength;
                    return(missingModule.MetadataAddress);
                },
                    out errorMessage);

                Assert.Equal(2, numRetries); // Ensure that we actually retried and that we bailed out on the second retry if the same identity was seen in the diagnostics.
                Assert.Equal($"error CS0012: The type 'MissingType' is defined in an assembly that is not referenced. You must add a reference to assembly '{missingIdentity}'.", errorMessage);
            });
        }
        public void TryDifferentLinqLibraryOnRetry()
        {
            var source = @"
using System.Linq;
class C 
{ 
    void M(string[] args) 
    {
    } 
}
class UseLinq
{
    bool b = Enumerable.Any<int>(null);
}";

            var compilation = CreateCompilation(source, new[] { MscorlibRef, SystemCoreRef });

            WithRuntimeInstance(compilation, new[] { MscorlibRef }, runtime =>
            {
                var context = CreateMethodContext(runtime, "C.M");

                var systemCore     = SystemCoreRef.ToModuleInstance();
                var fakeSystemLinq = CreateCompilationWithMscorlib45("", assemblyName: "System.Linq").
                                     EmitToImageReference().ToModuleInstance();

                string errorMessage;
                CompilationTestData testData;
                int retryCount    = 0;
                var compileResult = ExpressionCompilerTestHelpers.CompileExpressionWithRetry(
                    runtime.Modules.Select(m => m.MetadataBlock).ToImmutableArray(),
                    "args.Where(a => a.Length > 0)",
                    ImmutableArray <Alias> .Empty,
                    (_1, _2) => context, // ignore new blocks and just keep using the same failed context...
                    (AssemblyIdentity assemblyIdentity, out uint uSize) =>
                {
                    retryCount++;
                    MetadataBlock block;
                    switch (retryCount)
                    {
                    case 1:
                        Assert.Equal(EvaluationContextBase.SystemLinqIdentity, assemblyIdentity);
                        block = fakeSystemLinq.MetadataBlock;
                        break;

                    case 2:
                        Assert.Equal(EvaluationContextBase.SystemCoreIdentity, assemblyIdentity);
                        block = systemCore.MetadataBlock;
                        break;

                    default:
                        throw ExceptionUtilities.Unreachable;
                    }
                    uSize = (uint)block.Size;
                    return(block.Pointer);
                },
                    errorMessage: out errorMessage,
                    testData: out testData);

                Assert.Equal(2, retryCount);
            });
        }
Exemple #6
0
        public void MissingMscorlib()
        {
            var sourceA =
                @"public class A
{
}
class B
{
}
class C
{
}";
            var sourceB =
                @"public class B : A
{
}";
            var assemblyNameA = ExpressionCompilerUtilities.GenerateUniqueName();
            var compilationA  = CreateCompilation(
                sourceA,
                references: new MetadataReference[] { SystemRuntimePP7Ref },
                options: TestOptions.DebugDll,
                assemblyName: assemblyNameA);

            byte[] exeBytesA;
            byte[] pdbBytesA;
            ImmutableArray <MetadataReference> referencesA;

            compilationA.EmitAndGetReferences(out exeBytesA, out pdbBytesA, out referencesA);
            var referenceA = AssemblyMetadata.CreateFromImage(exeBytesA).GetReference(display: assemblyNameA);
            var identityA  = referenceA.GetAssemblyIdentity();
            var moduleA    = referenceA.ToModuleInstance(exeBytesA, new SymReader(pdbBytesA));

            var assemblyNameB = ExpressionCompilerUtilities.GenerateUniqueName();
            var compilationB  = CreateCompilation(
                sourceB,
                references: new MetadataReference[] { SystemRuntimePP7Ref, referenceA },
                options: TestOptions.DebugDll,
                assemblyName: assemblyNameB);

            byte[] exeBytesB;
            byte[] pdbBytesB;
            ImmutableArray <MetadataReference> referencesB;

            compilationB.EmitAndGetReferences(out exeBytesB, out pdbBytesB, out referencesB);
            var referenceB = AssemblyMetadata.CreateFromImage(exeBytesB).GetReference(display: assemblyNameB);
            var moduleB    = referenceB.ToModuleInstance(exeBytesB, new SymReader(pdbBytesB));

            // At runtime System.Runtime.dll contract assembly is replaced
            // by mscorlib.dll and System.Runtime.dll facade assemblies.
            var moduleBuilder = ArrayBuilder <ModuleInstance> .GetInstance();

            moduleBuilder.Add(MscorlibFacadeRef.ToModuleInstance(null, null));
            moduleBuilder.Add(SystemRuntimeFacadeRef.ToModuleInstance(null, null));
            moduleBuilder.Add(moduleA);
            moduleBuilder.Add(moduleB);
            var modules = moduleBuilder.ToImmutableAndFree();

            using (var runtime = new RuntimeInstance(modules))
            {
                ImmutableArray <MetadataBlock> blocks;
                Guid moduleVersionId;
                ISymUnmanagedReader symReader;
                int typeToken;
                int localSignatureToken;
                GetContextState(runtime, "C", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken);
                string errorMessage;
                CompilationTestData testData;
                int attempts = 0;
                ExpressionCompiler.CreateContextDelegate contextFactory = (b, u) =>
                {
                    attempts++;
                    return(EvaluationContext.CreateTypeContext(
                               ToCompilation(b, u, moduleVersionId),
                               moduleVersionId,
                               typeToken));
                };

                // Compile: [DebuggerDisplay("{new B()}")]
                const string expr = "new B()";
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, expr, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.Null(errorMessage);
                Assert.Equal(2, attempts);
                var methodData = testData.GetMethodData("<>x.<>m0");
                methodData.VerifyIL(
                    @"{
  // Code size        6 (0x6)
  .maxstack  1
  IL_0000:  newobj     ""B..ctor()""
  IL_0005:  ret
}");
            }
        }
Exemple #7
0
        public void DuplicateTypesAndMethodsDifferentAssemblies()
        {
            var sourceA =
                @"using N;
namespace N
{
    class C1 { }
    public static class E
    {
        public static A F(this A o) { return o; }
    }
}
class C2 { }
public class A
{
    public static void M()
    {
        var x = new A();
        var y = x.F();
    }
}";
            var sourceB =
                @"using N;
namespace N
{
    class C1 { }
    public static class E
    {
        public static int F(this A o) { return 2; }
    }
}
class C2 { }
public class B
{
    static void M()
    {
        var x = new A();
    }
}";
            var assemblyNameA = ExpressionCompilerUtilities.GenerateUniqueName();
            var compilationA  = CreateCompilationWithMscorlibAndSystemCore(sourceA, options: TestOptions.DebugDll, assemblyName: assemblyNameA);

            byte[] exeBytesA;
            byte[] pdbBytesA;
            ImmutableArray <MetadataReference> referencesA;

            compilationA.EmitAndGetReferences(out exeBytesA, out pdbBytesA, out referencesA);
            var referenceA = AssemblyMetadata.CreateFromImage(exeBytesA).GetReference(display: assemblyNameA);
            var identityA  = referenceA.GetAssemblyIdentity();
            var moduleA    = referenceA.ToModuleInstance(exeBytesA, new SymReader(pdbBytesA));

            var assemblyNameB = ExpressionCompilerUtilities.GenerateUniqueName();
            var compilationB  = CreateCompilationWithMscorlibAndSystemCore(sourceB, options: TestOptions.DebugDll, assemblyName: assemblyNameB, references: new[] { referenceA });

            byte[] exeBytesB;
            byte[] pdbBytesB;
            ImmutableArray <MetadataReference> referencesB;

            compilationB.EmitAndGetReferences(out exeBytesB, out pdbBytesB, out referencesB);
            var referenceB = AssemblyMetadata.CreateFromImage(exeBytesB).GetReference(display: assemblyNameB);
            var moduleB    = referenceB.ToModuleInstance(exeBytesB, new SymReader(pdbBytesB));

            var moduleBuilder = ArrayBuilder <ModuleInstance> .GetInstance();

            moduleBuilder.AddRange(referencesA.Select(r => r.ToModuleInstance(null, null)));
            moduleBuilder.Add(moduleA);
            moduleBuilder.Add(moduleB);
            var modules = moduleBuilder.ToImmutableAndFree();

            using (var runtime = new RuntimeInstance(modules))
            {
                ImmutableArray <MetadataBlock> blocks;
                Guid moduleVersionId;
                ISymUnmanagedReader symReader;
                int typeToken;
                int methodToken;
                int localSignatureToken;
                GetContextState(runtime, "B", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken);
                string errorMessage;
                CompilationTestData testData;
                var contextFactory = CreateTypeContextFactory(moduleVersionId, typeToken);

                // Duplicate type in namespace, at type scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new N.C1()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.True(errorMessage.StartsWith("error CS0433: The type 'C1' exists in both "));

                GetContextState(runtime, "B.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);
                contextFactory = CreateMethodContextFactory(moduleVersionId, symReader, methodToken, localSignatureToken);

                // Duplicate type in namespace, at method scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C1()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.True(errorMessage.StartsWith("error CS0433: The type 'C1' exists in both "));

                // Duplicate type in global namespace, at method scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C2()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.True(errorMessage.StartsWith("error CS0433: The type 'C2' exists in both "));

                // Duplicate extension method, at method scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "x.F()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.Equal(errorMessage, "(1,3): error CS0121: The call is ambiguous between the following methods or properties: 'N.E.F(A)' and 'N.E.F(A)'");

                // Same tests as above but in library that does not directly reference duplicates.
                GetContextState(runtime, "A", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken);
                contextFactory = CreateTypeContextFactory(moduleVersionId, typeToken);

                // Duplicate type in namespace, at type scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new N.C1()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.Null(errorMessage);
                var methodData = testData.GetMethodData("<>x.<>m0");
                methodData.VerifyIL(
                    @"{
  // Code size        6 (0x6)
  .maxstack  1
  IL_0000:  newobj     ""N.C1..ctor()""
  IL_0005:  ret
}");
                Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName());

                GetContextState(runtime, "A.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);
                contextFactory = CreateMethodContextFactory(moduleVersionId, symReader, methodToken, localSignatureToken);

                // Duplicate type in global namespace, at method scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C2()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.Null(errorMessage);
                methodData = testData.GetMethodData("<>x.<>m0");
                methodData.VerifyIL(
                    @"{
  // Code size        6 (0x6)
  .maxstack  1
  .locals init (A V_0, //x
                A V_1) //y
  IL_0000:  newobj     ""C2..ctor()""
  IL_0005:  ret
}");
                Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName());

                // Duplicate extension method, at method scope.
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "x.F()", contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
                Assert.Null(errorMessage);
                methodData = testData.GetMethodData("<>x.<>m0");
                methodData.VerifyIL(
                    @"{
  // Code size        7 (0x7)
  .maxstack  1
  .locals init (A V_0, //x
                A V_1) //y
  IL_0000:  ldloc.0
  IL_0001:  call       ""A N.E.F(A)""
  IL_0006:  ret
}");
                Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName());
            }
        }
Exemple #8
0
        public void IntrinsicMethods()
        {
            var sourceA =
                @"public class A { }";
            var sourceB =
                @"public class A { }
public class B
{
    static void M(A a)
    {
    }
}";
            var compilationA = CreateCompilationWithMscorlibAndSystemCore(sourceA, options: TestOptions.DebugDll);
            var moduleA      = compilationA.ToModuleInstance();

            var compilationB = CreateCompilationWithMscorlibAndSystemCore(sourceB, options: TestOptions.DebugDll, references: new[] { moduleA.GetReference() });
            var moduleB      = compilationB.ToModuleInstance();

            var runtime = CreateRuntimeInstance(new[]
            {
                MscorlibRef.ToModuleInstance(),
                SystemCoreRef.ToModuleInstance(),
                moduleA,
                moduleB,
                ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance()
            });

            ImmutableArray <MetadataBlock> blocks;
            Guid moduleVersionId;
            ISymUnmanagedReader symReader;
            int methodToken;
            int localSignatureToken;

            GetContextState(runtime, "B.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);

            var aliases = ImmutableArray.Create(
                ExceptionAlias(typeof(ArgumentException)),
                ReturnValueAlias(2, typeof(string)),
                ObjectIdAlias(1, typeof(object)));

            int attempts = 0;

            EvaluationContextBase contextFactory(ImmutableArray <MetadataBlock> b, bool u)
            {
                attempts++;
                return(EvaluationContext.CreateMethodContext(
                           ToCompilation(b, u, moduleVersionId),
                           symReader,
                           moduleVersionId,
                           methodToken,
                           methodVersion: 1,
                           ilOffset: 0,
                           localSignatureToken: localSignatureToken));
            }

            string errorMessage;
            CompilationTestData testData;

            ExpressionCompilerTestHelpers.CompileExpressionWithRetry(
                blocks,
                "(object)new A() ?? $exception ?? $1 ?? $ReturnValue2",
                aliases,
                contextFactory,
                getMetaDataBytesPtr: null,
                errorMessage: out errorMessage,
                testData: out testData);

            Assert.Null(errorMessage);
            Assert.Equal(2, attempts);
            var methodData = testData.GetMethodData("<>x.<>m0");

            methodData.VerifyIL(
                @"{
// Code size       49 (0x31)
.maxstack  2
IL_0000:  newobj     ""A..ctor()""
IL_0005:  dup
IL_0006:  brtrue.s   IL_0030
IL_0008:  pop
IL_0009:  call       ""System.Exception Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetException()""
IL_000e:  castclass  ""System.ArgumentException""
IL_0013:  dup
IL_0014:  brtrue.s   IL_0030
IL_0016:  pop
IL_0017:  ldstr      ""$1""
IL_001c:  call       ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)""
IL_0021:  dup
IL_0022:  brtrue.s   IL_0030
IL_0024:  pop
IL_0025:  ldc.i4.2
IL_0026:  call       ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetReturnValue(int)""
IL_002b:  castclass  ""string""
IL_0030:  ret
}");
        }
Exemple #9
0
        public void MissingMscorlib()
        {
            var sourceA =
                @"public class A
{
}
class B
{
}
class C
{
}";
            var sourceB =
                @"public class B : A
{
}";
            var moduleA = CreateCompilation(
                sourceA,
                references: new[] { SystemRuntimePP7Ref },
                options: TestOptions.DebugDll).ToModuleInstance();

            var moduleB = CreateCompilation(
                sourceB,
                references: new[] { SystemRuntimePP7Ref, moduleA.GetReference() },
                options: TestOptions.DebugDll).ToModuleInstance();

            // Include an empty assembly to verify that not all assemblies
            // with no references are treated as mscorlib.
            var referenceC = AssemblyMetadata.CreateFromImage(CommonResources.Empty).GetReference();

            // At runtime System.Runtime.dll contract assembly is replaced
            // by mscorlib.dll and System.Runtime.dll facade assemblies.
            var runtime = CreateRuntimeInstance(new[]
            {
                MscorlibFacadeRef.ToModuleInstance(),
                SystemRuntimeFacadeRef.ToModuleInstance(),
                moduleA,
                moduleB,
                referenceC.ToModuleInstance()
            });

            ImmutableArray <MetadataBlock> blocks;
            Guid moduleVersionId;
            ISymUnmanagedReader symReader;
            int typeToken;
            int localSignatureToken;

            GetContextState(runtime, "C", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken);
            string errorMessage;
            CompilationTestData testData;
            int attempts = 0;

            EvaluationContextBase contextFactory(ImmutableArray <MetadataBlock> b, bool u)
            {
                attempts++;
                return(EvaluationContext.CreateTypeContext(
                           ToCompilation(b, u, moduleVersionId),
                           moduleVersionId,
                           typeToken));
            }

            // Compile: [DebuggerDisplay("{new B()}")]
            const string expr = "new B()";

            ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, expr, ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
            Assert.Null(errorMessage);
            Assert.Equal(2, attempts);
            var methodData = testData.GetMethodData("<>x.<>m0");

            methodData.VerifyIL(
                @"{
// Code size        6 (0x6)
.maxstack  1
IL_0000:  newobj     ""B..ctor()""
IL_0005:  ret
}");
        }
Exemple #10
0
        public void DuplicateTypesAndMethodsDifferentAssemblies()
        {
            var sourceA =
                @"using N;
namespace N
{
    class C1 { }
    public static class E
    {
        public static A F(this A o) { return o; }
    }
}
class C2 { }
public class A
{
    public static void M()
    {
        var x = new A();
        var y = x.F();
    }
}";
            var sourceB =
                @"using N;
namespace N
{
    class C1 { }
    public static class E
    {
        public static int F(this A o) { return 2; }
    }
}
class C2 { }
public class B
{
    static void M()
    {
        var x = new A();
    }
}";
            var compilationA = CreateCompilationWithMscorlibAndSystemCore(sourceA, options: TestOptions.DebugDll);
            var identityA    = compilationA.Assembly.Identity;
            var moduleA      = compilationA.ToModuleInstance();

            var compilationB = CreateCompilationWithMscorlibAndSystemCore(sourceB, options: TestOptions.DebugDll, references: new[] { moduleA.GetReference() });
            var moduleB      = compilationB.ToModuleInstance();

            var runtime = CreateRuntimeInstance(new[] { MscorlibRef.ToModuleInstance(), SystemCoreRef.ToModuleInstance(), moduleA, moduleB });
            ImmutableArray <MetadataBlock> blocks;
            Guid moduleVersionId;
            ISymUnmanagedReader symReader;
            int typeToken;
            int methodToken;
            int localSignatureToken;

            GetContextState(runtime, "B", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken);
            string errorMessage;
            CompilationTestData testData;
            var contextFactory = CreateTypeContextFactory(moduleVersionId, typeToken);

            // Duplicate type in namespace, at type scope.
            ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new N.C1()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
            Assert.True(errorMessage.StartsWith("error CS0433: The type 'C1' exists in both "));

            GetContextState(runtime, "B.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);
            contextFactory = CreateMethodContextFactory(moduleVersionId, symReader, methodToken, localSignatureToken);

            // Duplicate type in namespace, at method scope.
            ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C1()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
            Assert.True(errorMessage.StartsWith("error CS0433: The type 'C1' exists in both "));

            // Duplicate type in global namespace, at method scope.
            ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C2()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
            Assert.True(errorMessage.StartsWith("error CS0433: The type 'C2' exists in both "));

            // Duplicate extension method, at method scope.
            ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "x.F()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
            Assert.Equal(errorMessage, "error CS0121: The call is ambiguous between the following methods or properties: 'N.E.F(A)' and 'N.E.F(A)'");

            // Same tests as above but in library that does not directly reference duplicates.
            GetContextState(runtime, "A", out blocks, out moduleVersionId, out symReader, out typeToken, out localSignatureToken);
            contextFactory = CreateTypeContextFactory(moduleVersionId, typeToken);

            // Duplicate type in namespace, at type scope.
            ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new N.C1()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
            Assert.Null(errorMessage);
            var methodData = testData.GetMethodData("<>x.<>m0");

            methodData.VerifyIL(
                @"{
// Code size        6 (0x6)
.maxstack  1
IL_0000:  newobj     ""N.C1..ctor()""
IL_0005:  ret
}");
            Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName());

            GetContextState(runtime, "A.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);
            contextFactory = CreateMethodContextFactory(moduleVersionId, symReader, methodToken, localSignatureToken);

            // Duplicate type in global namespace, at method scope.
            ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "new C2()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
            Assert.Null(errorMessage);
            methodData = testData.GetMethodData("<>x.<>m0");
            methodData.VerifyIL(
                @"{
// Code size        6 (0x6)
.maxstack  1
.locals init (A V_0, //x
            A V_1) //y
IL_0000:  newobj     ""C2..ctor()""
IL_0005:  ret
}");
            Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName());

            // Duplicate extension method, at method scope.
            ExpressionCompilerTestHelpers.CompileExpressionWithRetry(blocks, "x.F()", ImmutableArray <Alias> .Empty, contextFactory, getMetaDataBytesPtr: null, errorMessage: out errorMessage, testData: out testData);
            Assert.Null(errorMessage);
            methodData = testData.GetMethodData("<>x.<>m0");
            methodData.VerifyIL(
                @"{
// Code size        7 (0x7)
.maxstack  1
.locals init (A V_0, //x
            A V_1) //y
IL_0000:  ldloc.0
IL_0001:  call       ""A N.E.F(A)""
IL_0006:  ret
}");
            Assert.Equal(methodData.Method.ReturnType.ContainingAssembly.ToDisplayString(), identityA.GetDisplayName());
        }
        public void IntrinsicMethods()
        {
            var sourceA =
                @"public class A { }";
            var sourceB =
                @"public class A { }
public class B
{
    static void M(A a)
    {
    }
}";
            var assemblyNameA = ExpressionCompilerUtilities.GenerateUniqueName();
            var compilationA  = CreateCompilationWithMscorlibAndSystemCore(sourceA, options: TestOptions.DebugDll, assemblyName: assemblyNameA);

            byte[] exeBytesA;
            byte[] pdbBytesA;
            ImmutableArray <MetadataReference> referencesA;

            compilationA.EmitAndGetReferences(out exeBytesA, out pdbBytesA, out referencesA);
            var referenceA = AssemblyMetadata.CreateFromImage(exeBytesA).GetReference(display: assemblyNameA);
            var identityA  = referenceA.GetAssemblyIdentity();
            var moduleA    = referenceA.ToModuleInstance(exeBytesA, new SymReader(pdbBytesA));

            var assemblyNameB = ExpressionCompilerUtilities.GenerateUniqueName();
            var compilationB  = CreateCompilationWithMscorlibAndSystemCore(sourceB, options: TestOptions.DebugDll, assemblyName: assemblyNameB, references: new[] { referenceA });

            byte[] exeBytesB;
            byte[] pdbBytesB;
            ImmutableArray <MetadataReference> referencesB;

            compilationB.EmitAndGetReferences(out exeBytesB, out pdbBytesB, out referencesB);
            var referenceB = AssemblyMetadata.CreateFromImage(exeBytesB).GetReference(display: assemblyNameB);
            var moduleB    = referenceB.ToModuleInstance(exeBytesB, new SymReader(pdbBytesB));

            var moduleBuilder = ArrayBuilder <ModuleInstance> .GetInstance();

            moduleBuilder.AddRange(referencesA.Select(r => r.ToModuleInstance(null, null)));
            moduleBuilder.Add(moduleA);
            moduleBuilder.Add(moduleB);
            moduleBuilder.Add(ExpressionCompilerTestHelpers.IntrinsicAssemblyReference.ToModuleInstance(fullImage: null, symReader: null));
            var modules = moduleBuilder.ToImmutableAndFree();

            using (var runtime = new RuntimeInstance(modules))
            {
                ImmutableArray <MetadataBlock> blocks;
                Guid moduleVersionId;
                ISymUnmanagedReader symReader;
                int methodToken;
                int localSignatureToken;
                GetContextState(runtime, "B.M", out blocks, out moduleVersionId, out symReader, out methodToken, out localSignatureToken);
                var aliases = ImmutableArray.Create(
                    ExceptionAlias(typeof(ArgumentException)),
                    ReturnValueAlias(2, typeof(string)),
                    ObjectIdAlias(1, typeof(object)));
                int attempts = 0;
                ExpressionCompiler.CreateContextDelegate contextFactory = (b, u) =>
                {
                    attempts++;
                    return(EvaluationContext.CreateMethodContext(
                               ToCompilation(b, u, moduleVersionId),
                               symReader,
                               moduleVersionId,
                               methodToken,
                               methodVersion: 1,
                               ilOffset: 0,
                               localSignatureToken: localSignatureToken));
                };
                string errorMessage;
                CompilationTestData testData;
                ExpressionCompilerTestHelpers.CompileExpressionWithRetry(
                    blocks,
                    "(object)new A() ?? $exception ?? $1 ?? $ReturnValue2",
                    aliases,
                    contextFactory,
                    getMetaDataBytesPtr: null,
                    errorMessage: out errorMessage,
                    testData: out testData);
                Assert.Null(errorMessage);
                Assert.Equal(2, attempts);
                var methodData = testData.GetMethodData("<>x.<>m0");
                methodData.VerifyIL(
                    @"{
  // Code size       49 (0x31)
  .maxstack  2
  IL_0000:  newobj     ""A..ctor()""
  IL_0005:  dup
  IL_0006:  brtrue.s   IL_0030
  IL_0008:  pop
  IL_0009:  call       ""System.Exception Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetException()""
  IL_000e:  castclass  ""System.ArgumentException""
  IL_0013:  dup
  IL_0014:  brtrue.s   IL_0030
  IL_0016:  pop
  IL_0017:  ldstr      ""$1""
  IL_001c:  call       ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetObjectByAlias(string)""
  IL_0021:  dup
  IL_0022:  brtrue.s   IL_0030
  IL_0024:  pop
  IL_0025:  ldc.i4.2
  IL_0026:  call       ""object Microsoft.VisualStudio.Debugger.Clr.IntrinsicMethods.GetReturnValue(int)""
  IL_002b:  castclass  ""string""
  IL_0030:  ret
}");
            }
        }
        public void TryDifferentLinqLibraryOnRetry()
        {
            var source = @"
using System.Linq;
class C 
{ 
    void M(string[] args) 
    {
    } 
}
class UseLinq
{
    bool b = Enumerable.Any<int>(null);
}";

            var compilation = CreateCompilationWithMscorlibAndSystemCore(source);

            byte[] exeBytes, pdbBytes;
            ImmutableArray <MetadataReference> references;

            compilation.EmitAndGetReferences(out exeBytes, out pdbBytes, out references);
            var systemCore = SystemCoreRef.ToModuleInstance(fullImage: null, symReader: null);
            var referencesWithoutSystemCore = references.Where(r => r != SystemCoreRef).ToImmutableArray();
            var runtime        = CreateRuntimeInstance(ExpressionCompilerUtilities.GenerateUniqueName(), referencesWithoutSystemCore.AddIntrinsicAssembly(), exeBytes, symReader: null);
            var context        = CreateMethodContext(runtime, "C.M");
            var fakeSystemLinq = CreateCompilationWithMscorlib45("", assemblyName: "System.Linq").EmitToImageReference().ToModuleInstance(fullImage: null, symReader: null);

            string errorMessage;
            CompilationTestData testData;
            int retryCount    = 0;
            var compileResult = ExpressionCompilerTestHelpers.CompileExpressionWithRetry(
                runtime.Modules.Select(m => m.MetadataBlock).ToImmutableArray(),
                "args.Where(a => a.Length > 0)",
                (_1, _2) => context, // ignore new blocks and just keep using the same failed context...
                (AssemblyIdentity assemblyIdentity, out uint uSize) =>
            {
                retryCount++;
                MetadataBlock block;
                switch (retryCount)
                {
                case 1:
                    Assert.Equal(EvaluationContextBase.SystemLinqIdentity, assemblyIdentity);
                    block = fakeSystemLinq.MetadataBlock;
                    break;

                case 2:
                    Assert.Equal(EvaluationContextBase.SystemCoreIdentity, assemblyIdentity);
                    block = systemCore.MetadataBlock;
                    break;

                default:
                    throw ExceptionUtilities.Unreachable;
                }
                uSize = (uint)block.Size;
                return(block.Pointer);
            },
                errorMessage: out errorMessage,
                testData: out testData);

            Assert.Equal(2, retryCount);
        }