public void MetadataImageReference_Module_WithXxx()
        {
            var doc    = new TestDocumentationProvider();
            var module = ModuleMetadata.CreateFromImage(TestResources.SymbolsTests.General.C1);
            var r      = new MetadataImageReference(module, fullPath: @"c:\temp", display: "hello", documentation: doc);

            Assert.Same(doc, r.DocumentationProvider);
            Assert.Same(doc, r.DocumentationProvider);
            Assert.NotNull(r.GetMetadata());
            Assert.Equal(false, r.Properties.EmbedInteropTypes);
            Assert.Equal(MetadataImageKind.Module, r.Properties.Kind);
            Assert.True(r.Properties.Aliases.IsDefault);
            Assert.Equal(@"c:\temp", r.FullPath);

            var r1 = r.WithAliases(default(ImmutableArray <string>));

            Assert.Same(r, r1);

            var r2 = r.WithEmbedInteropTypes(false);

            Assert.Same(r, r2);

            var r3 = r.WithDocumentationProvider(doc);

            Assert.Same(r, r3);

            Assert.Throws <ArgumentException>(() => r.WithAliases(new[] { "bar" }));
            Assert.Throws <ArgumentException>(() => r.WithEmbedInteropTypes(true));
        }
        public void MetadataImageReference_Module_WithXxx()
        {
            var doc = new TestDocumentationProvider();
            var module = ModuleMetadata.CreateFromImage(TestResources.SymbolsTests.General.C1);
            var r = new MetadataImageReference(module, filePath: @"c:\temp", display: "hello", documentation: doc);
            Assert.Same(doc, r.DocumentationProvider);
            Assert.Same(doc, r.DocumentationProvider);
            Assert.NotNull(r.GetMetadata());
            Assert.Equal(false, r.Properties.EmbedInteropTypes);
            Assert.Equal(MetadataImageKind.Module, r.Properties.Kind);
            Assert.True(r.Properties.Aliases.IsDefault);
            Assert.Equal(@"c:\temp", r.FilePath);

            var r1 = r.WithAliases(default(ImmutableArray<string>));
            Assert.Same(r, r1);

            var r2 = r.WithEmbedInteropTypes(false);
            Assert.Same(r, r2);

            var r3 = r.WithDocumentationProvider(doc);
            Assert.Same(r, r3);
            
            Assert.Throws<ArgumentException>(() => r.WithAliases(new[] { "bar" }));
            Assert.Throws<ArgumentException>(() => r.WithEmbedInteropTypes(true));
        }
        public void MetadataImageReference_Assembly_WithXxx()
        {
            var doc      = new TestDocumentationProvider();
            var assembly = AssemblyMetadata.CreateFromImage(TestResources.SymbolsTests.General.C1);

            var r = new MetadataImageReference(
                assembly,
                documentation: doc,
                aliases: ImmutableArray.Create("a"),
                embedInteropTypes: true,
                fullPath: @"c:\temp",
                display: "hello");

            Assert.Same(doc, r.DocumentationProvider);
            Assert.Same(doc, r.DocumentationProvider);
            Assert.NotNull(r.GetMetadata());
            Assert.Equal(true, r.Properties.EmbedInteropTypes);
            Assert.Equal(MetadataImageKind.Assembly, r.Properties.Kind);
            AssertEx.Equal(new[] { "a" }, r.Properties.Aliases);
            Assert.Equal(@"c:\temp", r.FullPath);

            var r2 = r.WithEmbedInteropTypes(true);

            Assert.Equal(r, r2);

            var r3 = r.WithAliases(ImmutableArray.Create("b", "c"));

            Assert.Same(r.DocumentationProvider, r3.DocumentationProvider);
            Assert.Same(r.GetMetadata(), r3.GetMetadata());
            Assert.Equal(r.Properties.EmbedInteropTypes, r3.Properties.EmbedInteropTypes);
            Assert.Equal(r.Properties.Kind, r3.Properties.Kind);
            AssertEx.Equal(new[] { "b", "c" }, r3.Properties.Aliases);
            Assert.Equal(r.FullPath, r3.FullPath);

            var r4 = r.WithEmbedInteropTypes(false);

            Assert.Same(r.DocumentationProvider, r4.DocumentationProvider);
            Assert.Same(r.GetMetadata(), r4.GetMetadata());
            Assert.Equal(false, r4.Properties.EmbedInteropTypes);
            Assert.Equal(r.Properties.Kind, r4.Properties.Kind);
            AssertEx.Equal(r.Properties.Aliases, r4.Properties.Aliases);
            Assert.Equal(r.FullPath, r4.FullPath);

            Assert.Throws <ArgumentNullException>(() => r.WithDocumentationProvider(null));
            Assert.Same(r, r.WithDocumentationProvider(r.DocumentationProvider));

            var doc2 = new TestDocumentationProvider();
            var r5   = r.WithDocumentationProvider(doc2);

            Assert.Same(doc2, r5.DocumentationProvider);

            Assert.Same(r.GetMetadata(), r5.GetMetadata());
            Assert.Equal(r.Properties.EmbedInteropTypes, r5.Properties.EmbedInteropTypes);
            Assert.Equal(r.Properties.Kind, r5.Properties.Kind);
            AssertEx.Equal(r.Properties.Aliases, r5.Properties.Aliases);
            Assert.Equal(r.FullPath, r5.FullPath);
        }
        public void MetadataImageReference_Assembly_WithXxx()
        {
            var doc = new TestDocumentationProvider();
            var assembly = AssemblyMetadata.CreateFromImage(TestResources.SymbolsTests.General.C1);
         
            var r = new MetadataImageReference(
                assembly,
                documentation: doc, 
                aliases: ImmutableArray.Create("a"), 
                embedInteropTypes: true, 
                filePath: @"c:\temp", 
                display: "hello");

            Assert.Same(doc, r.DocumentationProvider);
            Assert.Same(doc, r.DocumentationProvider);
            Assert.NotNull(r.GetMetadata());
            Assert.Equal(true, r.Properties.EmbedInteropTypes);
            Assert.Equal(MetadataImageKind.Assembly, r.Properties.Kind);
            AssertEx.Equal(new[] { "a" }, r.Properties.Aliases);
            Assert.Equal(@"c:\temp", r.FilePath);

            var r2 = r.WithEmbedInteropTypes(true);
            Assert.Equal(r, r2);

            var r3 = r.WithAliases(ImmutableArray.Create("b", "c"));
            Assert.Same(r.DocumentationProvider, r3.DocumentationProvider);
            Assert.Same(r.GetMetadata(), r3.GetMetadata());
            Assert.Equal(r.Properties.EmbedInteropTypes, r3.Properties.EmbedInteropTypes);
            Assert.Equal(r.Properties.Kind, r3.Properties.Kind);
            AssertEx.Equal(new[] { "b", "c" }, r3.Properties.Aliases);
            Assert.Equal(r.FilePath, r3.FilePath);

            var r4 = r.WithEmbedInteropTypes(false);
            Assert.Same(r.DocumentationProvider, r4.DocumentationProvider);
            Assert.Same(r.GetMetadata(), r4.GetMetadata());
            Assert.Equal(false, r4.Properties.EmbedInteropTypes);
            Assert.Equal(r.Properties.Kind, r4.Properties.Kind);
            AssertEx.Equal(r.Properties.Aliases, r4.Properties.Aliases);
            Assert.Equal(r.FilePath, r4.FilePath);

            Assert.Throws<ArgumentNullException>(() => r.WithDocumentationProvider(null));
            Assert.Same(r, r.WithDocumentationProvider(r.DocumentationProvider));

            var doc2 = new TestDocumentationProvider();
            var r5 = r.WithDocumentationProvider(doc2);
            Assert.Same(doc2, r5.DocumentationProvider);

            Assert.Same(r.GetMetadata(), r5.GetMetadata());
            Assert.Equal(r.Properties.EmbedInteropTypes, r5.Properties.EmbedInteropTypes);
            Assert.Equal(r.Properties.Kind, r5.Properties.Kind);
            AssertEx.Equal(r.Properties.Aliases, r5.Properties.Aliases);
            Assert.Equal(r.FilePath, r5.FilePath);
        }
        public void DuplicateReferences()
        {
            CSharpCompilation c;
            string source;

            var r1 = new MetadataImageReference(TestResources.SymbolsTests.General.C1, fullPath: @"c:\temp\a.dll", display: "R1");
            var r2 = new MetadataImageReference(TestResources.SymbolsTests.General.C1, fullPath: @"c:\temp\a.dll", display: "R2");
            var rFoo = r2.WithAliases(new[] { "foo" });
            var rBar = r2.WithAliases(new[] { "bar" });
            var rEmbed = r1.WithEmbedInteropTypes(true);

            source = @"
class D { }
";



            c = CreateCompilationWithMscorlib(source, new[] { r1, r2 });
            Assert.Null(c.GetReferencedAssemblySymbol(r1));
            Assert.NotNull(c.GetReferencedAssemblySymbol(r2));
            c.VerifyDiagnostics();

            source = @"
class D : C { }
            ";

            c = CreateCompilationWithMscorlib(source, new[] { r1, r2 });
            Assert.Null(c.GetReferencedAssemblySymbol(r1));
            Assert.NotNull(c.GetReferencedAssemblySymbol(r2));
            c.VerifyDiagnostics();

            c = CreateCompilationWithMscorlib(source, new[] { rFoo, r2 });
            Assert.Null(c.GetReferencedAssemblySymbol(rFoo));
            Assert.NotNull(c.GetReferencedAssemblySymbol(r2));
            AssertEx.SetEqual(new[] { "foo", "global" }, c.ExternAliases);
            c.VerifyDiagnostics();

            // 2 aliases for the same path, aliases not used to qualify name
            c = CreateCompilationWithMscorlib(source, new[] { rFoo, rBar });
            Assert.Null(c.GetReferencedAssemblySymbol(rFoo));
            Assert.NotNull(c.GetReferencedAssemblySymbol(rBar));
            AssertEx.SetEqual(new[] { "foo", "bar" }, c.ExternAliases);

            c.VerifyDiagnostics(
                // (2,11): error CS0246: The type or namespace name 'C' could not be found (are you missing a using directive or an assembly reference?)
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "C").WithArguments("C"));

            source = @"
class D : C { }
            ";

            // /l and /r with the same path
            c = CreateCompilationWithMscorlib(source, new[] { rFoo, rEmbed });
            Assert.Null(c.GetReferencedAssemblySymbol(rFoo));
            Assert.NotNull(c.GetReferencedAssemblySymbol(rEmbed));

            c.VerifyDiagnostics(
                // error CS1760: Assemblies 'R1' and 'R2' refer to the same metadata but only one is a linked reference (specified using /link option); consider removing one of the references.
                Diagnostic(ErrorCode.ERR_AssemblySpecifiedForLinkAndRef).WithArguments("R1", "R2"),
                // error CS1747: Cannot embed interop types from assembly 'C, Version=1.0.0.0, Culture=neutral, PublicKeyToken=374d0c2befcd8cc9' because it is missing the 'System.Runtime.InteropServices.GuidAttribute' attribute.
                Diagnostic(ErrorCode.ERR_NoPIAAssemblyMissingAttribute).WithArguments("C, Version=1.0.0.0, Culture=neutral, PublicKeyToken=374d0c2befcd8cc9", "System.Runtime.InteropServices.GuidAttribute"),
                // error CS1759: Cannot embed interop types from assembly 'C, Version=1.0.0.0, Culture=neutral, PublicKeyToken=374d0c2befcd8cc9' because it is missing either the 'System.Runtime.InteropServices.ImportedFromTypeLibAttribute' attribute or the 'System.Runtime.InteropServices.PrimaryInteropAssemblyAttribute' attribute.
                Diagnostic(ErrorCode.ERR_NoPIAAssemblyMissingAttributes).WithArguments("C, Version=1.0.0.0, Culture=neutral, PublicKeyToken=374d0c2befcd8cc9", "System.Runtime.InteropServices.ImportedFromTypeLibAttribute", "System.Runtime.InteropServices.PrimaryInteropAssemblyAttribute"),
                // (2,11): error CS1752: Interop type 'C' cannot be embedded. Use the applicable interface instead.
                // class D : C { }
                Diagnostic(ErrorCode.ERR_NewCoClassOnLink, "C").WithArguments("C"));

            source = @"
extern alias foo;
extern alias bar;

public class D : foo::C { }
public class E : bar::C { }
";
            // 2 aliases for the same path, aliases used
            c = CreateCompilationWithMscorlib(source, new[] { rFoo, rBar });
            Assert.Null(c.GetReferencedAssemblySymbol(rFoo));
            Assert.NotNull(c.GetReferencedAssemblySymbol(rBar));
            c.VerifyDiagnostics();
        }