Exemple #1
0
        private static Imports[] GetImports(params string[] sources)
        {
            var trees            = sources.Select(source => Parse(source)).ToArray();
            var compilationUnits = trees.Select(tree => (CompilationUnitSyntax)tree.GetRoot());
            var externAliases    = compilationUnits
                                   .SelectMany(cu => cu.Externs)
                                   .Select(e => e.Identifier.ValueText)
                                   .Distinct();

            var comp = CreateCompilation(
                trees,
                targetFramework: TargetFramework.Mscorlib40,
                references: new[] { SystemCoreRef.WithAliases(externAliases) }
                );

            comp.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error).Verify();

            var factories = trees.Select(tree => comp.GetBinderFactory(tree));
            var binders   = factories.Select(
                factory =>
                factory.GetImportsBinder(
                    (CSharpSyntaxNode)factory.SyntaxTree.GetRoot(),
                    inUsing: false
                    )
                );
            var imports = binders.Select(binder => binder.GetImports(basesBeingResolved: null));

            Assert.DoesNotContain(Imports.Empty, imports);
            return(imports.ToArray());
        }
Exemple #2
0
        public void ConcatCollidingExternAliases()
        {
            var comp = CreateCompilation(
                "extern alias A; extern alias B;",
                targetFramework: TargetFramework.Mscorlib40,
                references: new[]
            {
                SystemCoreRef.WithAliases(new[] { "A" }),
                SystemDataRef.WithAliases(new[] { "B" }),
            }
                );

            var tree   = comp.SyntaxTrees.Single();
            var binder = comp.GetBinderFactory(tree)
                         .GetImportsBinder((CSharpSyntaxNode)tree.GetRoot(), inUsing: false);
            var scratchImports       = binder.GetImports(basesBeingResolved: null);
            var scratchExternAliases = scratchImports.ExternAliases;

            Assert.Equal(2, scratchExternAliases.Length);

            var externAlias1 = scratchExternAliases[0];
            var externAlias2 = new AliasAndExternAliasDirective(
                AliasSymbol.CreateCustomDebugInfoAlias(
                    scratchExternAliases[1].Alias.Target,
                    externAlias1.ExternAliasDirective.Identifier,
                    binder
                    ),
                externAlias1.ExternAliasDirective
                );

            var imports1 = Imports.FromCustomDebugInfo(
                comp,
                ImmutableDictionary <string, AliasAndUsingDirective> .Empty,
                ImmutableArray <NamespaceOrTypeAndUsingDirective> .Empty,
                ImmutableArray.Create(externAlias1)
                );

            var imports2 = Imports.FromCustomDebugInfo(
                comp,
                ImmutableDictionary <string, AliasAndUsingDirective> .Empty,
                ImmutableArray <NamespaceOrTypeAndUsingDirective> .Empty,
                ImmutableArray.Create(externAlias2)
                );

            var concat1 = imports1.Concat(imports2);

            Assert.Equal(externAlias2.Alias.Target, concat1.ExternAliases.Single().Alias.Target);

            var concat2 = imports2.Concat(imports1);

            Assert.Equal(externAlias1.Alias.Target, concat2.ExternAliases.Single().Alias.Target);
        }
        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 #4
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 #5
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 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);
        }