Exemple #1
0
        public void TestArrayParameterLocation()
        {
            var source = @"
public class C 
{ 
    public void M(params C[] c) { }
}
";
            var tree   = Parse(source, "file.cs");

            var libRef = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata").EmitToImageReference();
            var comp   = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly     = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceParameter     = sourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C").GetMember <MethodSymbol>("M").Parameters.Single();
            var referencedParameter = referencedAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C").GetMember <MethodSymbol>("M").Parameters.Single();
            var distinguisher       = new SymbolDistinguisher(comp, sourceParameter, referencedParameter);

            // NOTE: Locations come from parameter element types.
            // NOTE: 'params' retained.
            Assert.Equal("params C[] [file.cs(2)]", distinguisher.First.ToString());
            Assert.Equal("params C[] [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());
        }
        public void TestSerialization()
        {
            var tree   = Parse("public class C { }", "file.cs");
            var libRef = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata").EmitToImageReference();
            var comp   = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly     = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType    = sourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var referenedType = referencedAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");

            var distinguisher = new SymbolDistinguisher(comp, sourceType, referenedType);
            var diagnostic    = new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_NoImplicitConv, distinguisher.First, distinguisher.Second), Location.None);

            var before = diagnostic.GetMessage();

            Assert.Equal("Cannot implicitly convert type 'C [file.cs(1)]' to 'C [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]'", before);

            using (var stream = new MemoryStream())
            {
                var formatter = new BinaryFormatter();
                formatter.Serialize(stream, diagnostic);
                stream.Position = 0;
                diagnostic      = (CSDiagnostic)formatter.Deserialize(stream);
                var after = diagnostic.GetMessage();
                Assert.Equal(before, after);
            }
        }
        public void TestFileReferenceLocation()
        {
            var source = @"public class C { }";

            var tree = Parse(source, "file.cs");

            var libFile = Temp.CreateFile(extension: ".dll");
            var libPath = libFile.Path;

            var libComp = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata");

            libComp.Emit(libPath).Diagnostics.Verify();

            var libRef = new MetadataFileReference(libPath, MetadataReferenceProperties.Assembly);
            var comp   = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly     = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType     = sourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var distinguisher  = new SymbolDistinguisher(comp, sourceType, referencedType);

            Assert.Equal("C [file.cs(1)]", distinguisher.First.ToString());
            Assert.Equal(string.Format("C [{0}]", libPath), distinguisher.Second.ToString());
        }
        public void TestPathLocationsWithoutCompilation()
        {
            var source = @"public class C { }";

            var tree = Parse(source, @"a\..\file.cs");

            var libFile = Temp.CreateFile(extension: ".dll");
            var libPath = libFile.Path;

            var libComp = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata");

            libComp.Emit(libPath).Diagnostics.Verify();

            var libRef = new MetadataFileReference(libPath, MetadataReferenceProperties.Assembly);
            var comp   = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly     = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType     = sourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");

            var distinguisher = new SymbolDistinguisher(null, sourceType, referencedType);

            Assert.Equal(@"C [a\..\file.cs(1)]", distinguisher.First.ToString()); // File path comes out of tree.
            Assert.Equal("C [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());
        }
        public void TestPointerLocation()
        {
            var source  = @"
unsafe public struct S
{ 
    public S* F;
}
";
            var tree    = Parse(source, "file.cs");
            var options = OptionsDll.WithAllowUnsafe(true);

            var libRef = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata", compOptions: options).EmitToImageReference();
            var comp   = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source", compOptions: options);

            var sourceAssembly     = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType     = sourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("S").GetMember <FieldSymbol>("F").Type;
            var referencedType = referencedAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("S").GetMember <FieldSymbol>("F").Type;
            var distinguisher  = new SymbolDistinguisher(comp, sourceType, referencedType);

            // NOTE: Locations come from element types.
            Assert.Equal("S* [file.cs(2)]", distinguisher.First.ToString());
            Assert.Equal("S* [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());
        }
Exemple #6
0
        public void TestTypeParameterLocation()
        {
            var source = @"public class C<T> { }";

            var tree = Parse(source, "file.cs");

            var libRef = CreateCompilation(tree, assemblyName: "Metadata").EmitToImageReference();
            var comp   = CreateCompilation(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly     = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType = sourceAssembly.GlobalNamespace
                             .GetMember <NamedTypeSymbol>("C")
                             .TypeParameters.Single();
            var referencedType = referencedAssembly.GlobalNamespace
                                 .GetMember <NamedTypeSymbol>("C")
                                 .TypeParameters.Single();
            var distinguisher = new SymbolDistinguisher(comp, sourceType, referencedType);

            // NOTE: Locations come from element types.
            Assert.Equal("T [file.cs(1)]", distinguisher.First.ToString());
            Assert.Equal(
                "T [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]",
                distinguisher.Second.ToString()
                );
        }
Exemple #7
0
        public void TestPathLocationsWithoutCompilation()
        {
            var source = @"public class C { }";

            var tree = Parse(source, @"a\..\file.cs");

            var libComp = CreateCompilation(tree, assemblyName: "Metadata");
            var libRef  = MetadataReference.CreateFromImage(
                libComp.EmitToArray(),
                filePath: "Metadata.dll"
                );

            var comp = CreateCompilation(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly     = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType     = sourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");

            var distinguisher = new SymbolDistinguisher(null, sourceType, referencedType);

            Assert.Equal(@"C [a\..\file.cs(1)]", distinguisher.First.ToString()); // File path comes out of tree.
            Assert.Equal(
                "C [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]",
                distinguisher.Second.ToString()
                );
        }
Exemple #8
0
        public void TestDistinctSymbolsWithSameLocation()
        {
            var source = @"public class C { }";
            var tree   = Parse(source, "file.cs");

            var libRef = new CSharpCompilationReference(
                CreateCompilation(tree, assemblyName: "Metadata")
                );
            var comp = CreateCompilation(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly     = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType     = sourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var distinguisher  = new SymbolDistinguisher(comp, sourceType, referencedType);

            Assert.Equal(
                "C [Source, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]",
                distinguisher.First.ToString()
                );
            Assert.Equal(
                "C [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]",
                distinguisher.Second.ToString()
                );
        }
Exemple #9
0
        public void TestSimpleDeclarations()
        {
            var source = @"
public class C
{
    public void M() { }
    public int P { get; set; }
    public int F;
    public event System.Action E { add { } remove { } }
}
";

            var tree = Parse(source, "file.cs");

            var libRef = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata").EmitToImageReference();
            var comp   = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source");

            SymbolDistinguisher distinguisher;

            var sourceAssembly     = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType     = sourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");

            distinguisher = new SymbolDistinguisher(comp, sourceType, referencedType);
            Assert.Equal("C [file.cs(2)]", distinguisher.First.ToString());
            Assert.Equal("C [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());

            var sourceMethod     = sourceType.GetMember <MethodSymbol>("M");
            var referencedMethod = referencedType.GetMember <MethodSymbol>("M");

            distinguisher = new SymbolDistinguisher(comp, sourceMethod, referencedMethod);
            Assert.Equal("C.M() [file.cs(4)]", distinguisher.First.ToString());
            Assert.Equal("C.M() [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());

            var sourceProperty     = sourceType.GetMember <PropertySymbol>("P");
            var referencedProperty = referencedType.GetMember <PropertySymbol>("P");

            distinguisher = new SymbolDistinguisher(comp, sourceProperty, referencedProperty);
            Assert.Equal("C.P [file.cs(5)]", distinguisher.First.ToString());
            Assert.Equal("C.P [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());

            var sourceField     = sourceType.GetMember <FieldSymbol>("F");
            var referencedField = referencedType.GetMember <FieldSymbol>("F");

            distinguisher = new SymbolDistinguisher(comp, sourceField, referencedField);
            Assert.Equal("C.F [file.cs(6)]", distinguisher.First.ToString());
            Assert.Equal("C.F [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());

            var sourceEvent     = sourceType.GetMember <EventSymbol>("E");
            var referencedEvent = referencedType.GetMember <EventSymbol>("E");

            distinguisher = new SymbolDistinguisher(comp, sourceEvent, referencedEvent);
            Assert.Equal("C.E [file.cs(7)]", distinguisher.First.ToString());
            Assert.Equal("C.E [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());
        }
        public void TestSimpleDeclarations()
        {
            var source = @"
public class C
{
    public void M() { }
    public int P { get; set; }
    public int F;
    public event System.Action E { add { } remove { } }
}
";

            var tree = Parse(source, "file.cs");

            var libRef = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata").EmitToImageReference();
            var comp = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source");

            SymbolDistinguisher distinguisher;

            var sourceAssembly = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType = sourceAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            distinguisher = new SymbolDistinguisher(comp, sourceType, referencedType);
            Assert.Equal("C [file.cs(2)]", distinguisher.First.ToString());
            Assert.Equal("C [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());

            var sourceMethod = sourceType.GetMember<MethodSymbol>("M");
            var referencedMethod = referencedType.GetMember<MethodSymbol>("M");
            distinguisher = new SymbolDistinguisher(comp, sourceMethod, referencedMethod);
            Assert.Equal("C.M() [file.cs(4)]", distinguisher.First.ToString());
            Assert.Equal("C.M() [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());

            var sourceProperty = sourceType.GetMember<PropertySymbol>("P");
            var referencedProperty = referencedType.GetMember<PropertySymbol>("P");
            distinguisher = new SymbolDistinguisher(comp, sourceProperty, referencedProperty);
            Assert.Equal("C.P [file.cs(5)]", distinguisher.First.ToString());
            Assert.Equal("C.P [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());

            var sourceField = sourceType.GetMember<FieldSymbol>("F");
            var referencedField = referencedType.GetMember<FieldSymbol>("F");
            distinguisher = new SymbolDistinguisher(comp, sourceField, referencedField);
            Assert.Equal("C.F [file.cs(6)]", distinguisher.First.ToString());
            Assert.Equal("C.F [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());

            var sourceEvent = sourceType.GetMember<EventSymbol>("E");
            var referencedEvent = referencedType.GetMember<EventSymbol>("E");
            distinguisher = new SymbolDistinguisher(comp, sourceEvent, referencedEvent);
            Assert.Equal("C.E [file.cs(7)]", distinguisher.First.ToString());
            Assert.Equal("C.E [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());
        }
Exemple #11
0
        public void TestMissingTypeLocation()
        {
            var dummyComp = CreateCompilation("", assemblyName: "Error");
            var errorType = dummyComp.GetSpecialType(SpecialType.System_Int32);
            var validType = CreateCompilationWithMscorlib("").GetSpecialType(SpecialType.System_Int32);

            Assert.NotEqual(TypeKind.Error, validType.TypeKind);
            Assert.Equal(TypeKind.Error, errorType.TypeKind);

            var distinguisher = new SymbolDistinguisher(dummyComp, errorType, validType);

            Assert.Equal("int [Error, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.First.ToString());
            Assert.Equal("int [mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]", distinguisher.Second.ToString());
        }
Exemple #12
0
        public void TestDynamicLocation()
        {
            var libRef = CreateCompilationWithMscorlib("public class dynamic { }", assemblyName: "Metadata").EmitToImageReference();
            var comp   = CreateCompilationWithMscorlib("", new[] { libRef }, assemblyName: "Source");

            var sourceAssembly     = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            // I don't see how these types be reported as ambiguous, but we shouldn't blow up.
            var sourceType     = DynamicTypeSymbol.Instance;
            var referencedType = referencedAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("dynamic");
            var distinguisher  = new SymbolDistinguisher(comp, sourceType, referencedType);

            Assert.Equal("dynamic", distinguisher.First.ToString());
            Assert.Equal("dynamic [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());
        }
        public void TestCompilationReferenceLocation()
        {
            var source = @"public class C { }";

            var libRef = new CSharpCompilationReference(CreateCompilationWithMscorlib(Parse(source, "file1.cs"), assemblyName: "Metadata"));
            var comp = CreateCompilationWithMscorlib(Parse(source, "file2.cs"), new[] { libRef }, assemblyName: "Source");

            var sourceAssembly = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType = sourceAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            var distinguisher = new SymbolDistinguisher(comp, sourceType, referencedType);
            Assert.Equal("C [file2.cs(1)]", distinguisher.First.ToString());
            Assert.Equal("C [file1.cs(1)]", distinguisher.Second.ToString());
        }
Exemple #14
0
        public void TestCompilationReferenceLocation()
        {
            var source = @"public class C { }";

            var libRef = new CSharpCompilationReference(CreateCompilationWithMscorlib(Parse(source, "file1.cs"), assemblyName: "Metadata"));
            var comp   = CreateCompilationWithMscorlib(Parse(source, "file2.cs"), new[] { libRef }, assemblyName: "Source");

            var sourceAssembly     = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType     = sourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var distinguisher  = new SymbolDistinguisher(comp, sourceType, referencedType);

            Assert.Equal("C [file2.cs(1)]", distinguisher.First.ToString());
            Assert.Equal("C [file1.cs(1)]", distinguisher.Second.ToString());
        }
Exemple #15
0
        public void TestSourceLocationWithoutPath()
        {
            var source = @"public class C { }";

            var libRef = CreateCompilationWithMscorlib(source, assemblyName: "Metadata").EmitToImageReference();
            var comp   = CreateCompilationWithMscorlib(source, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly     = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType     = sourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var distinguisher  = new SymbolDistinguisher(comp, sourceType, referencedType);

            Assert.Equal("C [Source, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.First.ToString());
            Assert.Equal("C [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());
        }
Exemple #16
0
        public void DescriptionNoCompilation()
        {
            var source =
                @"class A { }
class B { }";
            var compilation    = CreateCompilationWithMscorlib(source);
            var typeA          = compilation.GetMember <NamedTypeSymbol>("A");
            var typeB          = compilation.GetMember <NamedTypeSymbol>("B");
            var distinguisher1 = new SymbolDistinguisher(compilation, typeA, typeB);
            var distinguisher2 = new SymbolDistinguisher(null, typeA, typeB);
            var arg1A          = distinguisher1.First;
            var arg2A          = distinguisher2.First;

            Assert.False(arg1A.Equals(arg2A));
            Assert.False(arg2A.Equals(arg1A));
            int hashCode1A = arg1A.GetHashCode();
            int hashCode2A = arg2A.GetHashCode();
        }
Exemple #17
0
        public void TestFileReferenceLocation()
        {
            var source = @"public class C { }";

            var tree = Parse(source, "file.cs");

            var libComp = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata");
            var libRef  = MetadataReference.CreateFromImage(libComp.EmitToArray(), filePath: "Metadata.dll");
            var comp    = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly     = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType     = sourceAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember <NamedTypeSymbol>("C");
            var distinguisher  = new SymbolDistinguisher(comp, sourceType, referencedType);

            Assert.Equal("C [file.cs(1)]", distinguisher.First.ToString());
            Assert.Equal(string.Format("C [Metadata.dll]"), distinguisher.Second.ToString());
        }
        public void TestFileReferenceLocation()
        {
            var source = @"public class C { }";

            var tree = Parse(source, "file.cs");

            var libComp = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata");
            var libRef = MetadataReference.CreateFromImage(libComp.EmitToArray(), filePath: "Metadata.dll");
            var comp = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType = sourceAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            var distinguisher = new SymbolDistinguisher(comp, sourceType, referencedType);
            Assert.Equal("C [file.cs(1)]", distinguisher.First.ToString());
            Assert.Equal(string.Format("C [Metadata.dll]"), distinguisher.Second.ToString());
        }
        public void DescriptionNoCompilation()
        {
            var source =
@"class A { }
class B { }";
            var compilation = CreateCompilationWithMscorlib(source);
            var typeA = compilation.GetMember<NamedTypeSymbol>("A");
            var typeB = compilation.GetMember<NamedTypeSymbol>("B");
            var distinguisher1 = new SymbolDistinguisher(compilation, typeA, typeB);
            var distinguisher2 = new SymbolDistinguisher(null, typeA, typeB);
            var arg1A = distinguisher1.First;
            var arg2A = distinguisher2.First;
            Assert.False(arg1A.Equals(arg2A));
            Assert.False(arg2A.Equals(arg1A));
            int hashCode1A = arg1A.GetHashCode();
            int hashCode2A = arg2A.GetHashCode();
        }
 private static bool AreEqual(SymbolDistinguisher a, SymbolDistinguisher b)
 {
     return a.First.Equals(b.First) && a.Second.Equals(b.Second);
 }
        public void TestSerialization()
        {
            var tree = Parse("public class C { }", "file.cs");
            var libRef = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata").EmitToImageReference();
            var comp = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType = sourceAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            var referenedType = referencedAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");

            var distinguisher = new SymbolDistinguisher(comp, sourceType, referenedType);
            var diagnostic = new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_NoImplicitConv, distinguisher.First, distinguisher.Second), Location.None);

            var before = diagnostic.GetMessage();
            Assert.Equal("Cannot implicitly convert type 'C [file.cs(1)]' to 'C [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]'", before);

            using (var stream = new MemoryStream())
            {
                var formatter = new BinaryFormatter();
                formatter.Serialize(stream, diagnostic);
                stream.Position = 0;
                diagnostic = (CSDiagnostic)formatter.Deserialize(stream);
                var after = diagnostic.GetMessage();
                Assert.Equal(before, after);
            }
        }
        public void TestMissingTypeLocation()
        {
            var dummyComp = CreateCompilation("", assemblyName: "Error");
            var errorType = dummyComp.GetSpecialType(SpecialType.System_Int32);
            var validType = CreateCompilationWithMscorlib("").GetSpecialType(SpecialType.System_Int32);

            Assert.NotEqual(TypeKind.Error, validType.TypeKind);
            Assert.Equal(TypeKind.Error, errorType.TypeKind);

            var distinguisher = new SymbolDistinguisher(dummyComp, errorType, validType);
            Assert.Equal("int [Error, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.First.ToString());
            Assert.Equal("int [mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]", distinguisher.Second.ToString());
        }
        public void TestDynamicLocation()
        {
            var libRef = CreateCompilationWithMscorlib("public class dynamic { }", assemblyName: "Metadata").EmitToImageReference();
            var comp = CreateCompilationWithMscorlib("", new[] { libRef }, assemblyName: "Source");

            var sourceAssembly = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            // I don't see how these types be reported as ambiguous, but we shouldn't blow up.
            var sourceType = DynamicTypeSymbol.Instance;
            var referencedType = referencedAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("dynamic");
            var distinguisher = new SymbolDistinguisher(comp, sourceType, referencedType);
            Assert.Equal("dynamic", distinguisher.First.ToString());
            Assert.Equal("dynamic [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());
        }
        public void TestTypeParameterLocation()
        {
            var source = @"public class C<T> { }";

            var tree = Parse(source, "file.cs");

            var libRef = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata").EmitToImageReference();
            var comp = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType = sourceAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C").TypeParameters.Single();
            var referencedType = referencedAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C").TypeParameters.Single();
            var distinguisher = new SymbolDistinguisher(comp, sourceType, referencedType);
            // NOTE: Locations come from element types.
            Assert.Equal("T [file.cs(1)]", distinguisher.First.ToString());
            Assert.Equal("T [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());
        }
        public void TestPointerLocation()
        {
            var source = @"
unsafe public struct S
{ 
    public S* F;
}
";
            var tree = Parse(source, "file.cs");

            var libRef = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata", options: TestOptions.UnsafeReleaseDll).EmitToImageReference();
            var comp = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source", options: TestOptions.UnsafeReleaseDll);

            var sourceAssembly = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType = sourceAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("S").GetMember<FieldSymbol>("F").Type;
            var referencedType = referencedAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("S").GetMember<FieldSymbol>("F").Type;
            var distinguisher = new SymbolDistinguisher(comp, sourceType, referencedType);
            // NOTE: Locations come from element types.
            Assert.Equal("S* [file.cs(2)]", distinguisher.First.ToString());
            Assert.Equal("S* [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());
        }
        public void TestParameterLocation()
        {
            var source = @"
public class C 
{ 
    public void M(ref C c) { }
}
";
            var tree = Parse(source, "file.cs");

            var libRef = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata").EmitToImageReference();
            var comp = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceParameter = sourceAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C").GetMember<MethodSymbol>("M").Parameters.Single();
            var referencedParameter = referencedAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C").GetMember<MethodSymbol>("M").Parameters.Single();
            var distinguisher = new SymbolDistinguisher(comp, sourceParameter, referencedParameter);
            // NOTE: Locations come from parameter *types*.
            // NOTE: RefKind retained.
            Assert.Equal("ref C [file.cs(2)]", distinguisher.First.ToString());
            Assert.Equal("ref C [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());
        }
        public void TestSourceLocationWithoutPath()
        {
            var source = @"public class C { }";

            var libRef = CreateCompilationWithMscorlib(source, assemblyName: "Metadata").EmitToImageReference();
            var comp = CreateCompilationWithMscorlib(source, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType = sourceAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            var distinguisher = new SymbolDistinguisher(comp, sourceType, referencedType);
            Assert.Equal("C [Source, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.First.ToString());
            Assert.Equal("C [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());
        }
        public void TestFileReferenceLocation()
        {
            var source = @"public class C { }";

            var tree = Parse(source, "file.cs");

            var libFile = Temp.CreateFile(extension: ".dll");
            var libPath = libFile.Path;

            var libComp = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata");
            libComp.Emit(libPath).Diagnostics.Verify();

            var libRef = new MetadataFileReference(libPath, MetadataReferenceProperties.Assembly);
            var comp = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType = sourceAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            var distinguisher = new SymbolDistinguisher(comp, sourceType, referencedType);
            Assert.Equal("C [file.cs(1)]", distinguisher.First.ToString());
            Assert.Equal(string.Format("C [{0}]", libPath), distinguisher.Second.ToString());
        }
        public void TestPathLocationsWithoutCompilation()
        {
            var source = @"public class C { }";

            var tree = Parse(source, @"a\..\file.cs");

            var libComp = CreateCompilationWithMscorlib(tree, assemblyName: "Metadata");
            var libRef = MetadataReference.CreateFromImage(libComp.EmitToArray(), filePath: "Metadata.dll");

            var comp = CreateCompilationWithMscorlib(tree, new[] { libRef }, assemblyName: "Source");

            var sourceAssembly = comp.SourceAssembly;
            var referencedAssembly = (AssemblySymbol)comp.GetAssemblyOrModuleSymbol(libRef);

            var sourceType = sourceAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            var referencedType = referencedAssembly.GlobalNamespace.GetMember<NamedTypeSymbol>("C");

            var distinguisher = new SymbolDistinguisher(null, sourceType, referencedType);
            Assert.Equal(@"C [a\..\file.cs(1)]", distinguisher.First.ToString()); // File path comes out of tree.
            Assert.Equal("C [Metadata, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]", distinguisher.Second.ToString());
        }
        // See TypeBind::CheckSingleConstraint.
        private static bool CheckConstraints(
            Symbol containingSymbol,
            ConversionsBase conversions,
            TypeMap substitution,
            TypeParameterSymbol typeParameter,
            TypeSymbol typeArgument,
            Compilation currentCompilation,
            ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder,
            ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder,
            HashSet<TypeParameterSymbol> ignoreTypeConstraintsDependentOnTypeParametersOpt)
        {
            Debug.Assert(substitution != null);
            // The type parameters must be original definitions of type parameters from the containing symbol.
            Debug.Assert(ReferenceEquals(typeParameter.ContainingSymbol, containingSymbol.OriginalDefinition));

            if (typeArgument.IsErrorType())
            {
                return true;
            }

            if (typeArgument.IsPointerType() || typeArgument.IsRestrictedType() || typeArgument.SpecialType == SpecialType.System_Void)
            {
                // "The type '{0}' may not be used as a type argument"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_BadTypeArgument, typeArgument)));
                return false;
            }

            if (typeArgument.IsStatic)
            {
                // "'{0}': static types cannot be used as type arguments"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_GenericArgIsStaticClass, typeArgument)));
                return false;
            }

            if (typeParameter.HasReferenceTypeConstraint && !typeArgument.IsReferenceType)
            {
                // "The type '{2}' must be a reference type in order to use it as parameter '{1}' in the generic type or method '{0}'"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_RefConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
                return false;
            }

            if (typeParameter.HasValueTypeConstraint && !typeArgument.IsNonNullableValueType())
            {
                // "The type '{2}' must be a non-nullable value type in order to use it as parameter '{1}' in the generic type or method '{0}'"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_ValConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
                return false;
            }

            // The type parameters for a constructed type/method are the type parameters of
            // the ConstructedFrom type/method, so the constraint types are not substituted.
            // For instance with "class C<T, U> where T : U", the type parameter for T in "C<object, int>"
            // has constraint "U", not "int". We need to substitute the constraints from the
            // original definition of the type parameters using the map from the constructed symbol.
            var constraintTypes = ArrayBuilder<TypeSymbol>.GetInstance();
            HashSet<DiagnosticInfo> useSiteDiagnostics = null;
            substitution.SubstituteTypesDistinctWithoutModifiers(typeParameter.ConstraintTypesWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics), constraintTypes, 
                                                                 ignoreTypeConstraintsDependentOnTypeParametersOpt);

            bool hasError = false;

            foreach (var constraintType in constraintTypes)
            {
                if (SatisfiesConstraintType(conversions, typeArgument, constraintType, ref useSiteDiagnostics))
                {
                    continue;
                }

                ErrorCode errorCode;
                if (typeArgument.IsReferenceType)
                {
                    errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedRefType;
                }
                else if (typeArgument.IsNullableType())
                {
                    errorCode = constraintType.IsInterfaceType() ? ErrorCode.ERR_GenericConstraintNotSatisfiedNullableInterface : ErrorCode.ERR_GenericConstraintNotSatisfiedNullableEnum;
                }
                else if (typeArgument.TypeKind == TypeKind.TypeParameter)
                {
                    errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedTyVar;
                }
                else
                {
                    errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedValType;
                }

                SymbolDistinguisher distinguisher = new SymbolDistinguisher(currentCompilation, constraintType, typeArgument);
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(errorCode, containingSymbol.ConstructedFrom(), distinguisher.First, typeParameter, distinguisher.Second)));
                hasError = true;
            }

            if (AppendUseSiteDiagnostics(useSiteDiagnostics, typeParameter, ref useSiteDiagnosticsBuilder))
            {
                hasError = true;
            }

            constraintTypes.Free();

            // Check the constructor constraint.
            if (typeParameter.HasConstructorConstraint && !SatisfiesConstructorConstraint(typeArgument))
            {
                // "'{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}'"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_NewConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
                return false;
            }

            return !hasError;
        }
        // See TypeBind::CheckSingleConstraint.
        private static bool CheckConstraints(
            Symbol containingSymbol,
            ConversionsBase conversions,
            TypeMap substitution,
            TypeParameterSymbol typeParameter,
            TypeSymbol typeArgument,
            Compilation currentCompilation,
            ArrayBuilder <TypeParameterDiagnosticInfo> diagnosticsBuilder,
            ref ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder)
        {
            Debug.Assert(substitution != null);
            // The type parameters must be original definitions of type parameters from the containing symbol.
            Debug.Assert(ReferenceEquals(typeParameter.ContainingSymbol, containingSymbol.OriginalDefinition));

            if (typeArgument.IsErrorType())
            {
                return(true);
            }

            if (typeArgument.IsPointerType() || typeArgument.IsRestrictedType() || typeArgument.SpecialType == SpecialType.System_Void)
            {
                // "The type '{0}' may not be used as a type argument"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_BadTypeArgument, typeArgument)));
                return(false);
            }

            if (typeArgument.IsStatic)
            {
                // "'{0}': static types cannot be used as type arguments"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_GenericArgIsStaticClass, typeArgument)));
                return(false);
            }

            if (typeParameter.HasReferenceTypeConstraint && !typeArgument.IsReferenceType)
            {
                // "The type '{2}' must be a reference type in order to use it as parameter '{1}' in the generic type or method '{0}'"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_RefConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
                return(false);
            }

            if (typeParameter.HasValueTypeConstraint && !typeArgument.IsNonNullableValueType())
            {
                // "The type '{2}' must be a non-nullable value type in order to use it as parameter '{1}' in the generic type or method '{0}'"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_ValConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
                return(false);
            }

            // The type parameters for a constructed type/method are the type parameters of
            // the ConstructedFrom type/method, so the constraint types are not substituted.
            // For instance with "class C<T, U> where T : U", the type parameter for T in "C<object, int>"
            // has constraint "U", not "int". We need to substitute the constraints from the
            // original definition of the type parameters using the map from the constructed symbol.
            var constraintTypes = ArrayBuilder <TypeSymbol> .GetInstance();

            HashSet <DiagnosticInfo> useSiteDiagnostics = null;

            substitution.SubstituteTypesDistinctWithoutModifiers(typeParameter.ConstraintTypesWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics), constraintTypes);

            bool hasError = false;

            foreach (var constraintType in constraintTypes)
            {
                if (SatisfiesConstraintType(conversions, typeArgument, constraintType, ref useSiteDiagnostics))
                {
                    continue;
                }

                ErrorCode errorCode;
                if (typeArgument.IsReferenceType)
                {
                    errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedRefType;
                }
                else if (typeArgument.IsNullableType())
                {
                    errorCode = constraintType.IsInterfaceType() ? ErrorCode.ERR_GenericConstraintNotSatisfiedNullableInterface : ErrorCode.ERR_GenericConstraintNotSatisfiedNullableEnum;
                }
                else if (typeArgument.TypeKind == TypeKind.TypeParameter)
                {
                    errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedTyVar;
                }
                else
                {
                    errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedValType;
                }

                SymbolDistinguisher distinguisher = new SymbolDistinguisher(currentCompilation, constraintType, typeArgument);
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(errorCode, containingSymbol.ConstructedFrom(), distinguisher.First, typeParameter, distinguisher.Second)));
                hasError = true;
            }

            if (AppendUseSiteDiagnostics(useSiteDiagnostics, typeParameter, ref useSiteDiagnosticsBuilder))
            {
                hasError = true;
            }

            constraintTypes.Free();

            // Check the constructor constraint.
            if (typeParameter.HasConstructorConstraint && !SatisfiesConstructorConstraint(typeArgument))
            {
                // "'{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}'"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_NewConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
                return(false);
            }

            return(!hasError);
        }
Exemple #32
0
 private static bool AreEqual(SymbolDistinguisher a, SymbolDistinguisher b)
 {
     return(a.First.Equals(b.First) && a.Second.Equals(b.Second));
 }