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()); }
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() ); }
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() ); }
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() ); }
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()); }
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 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()); }
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()); }
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 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(); }
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 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); }
private static bool AreEqual(SymbolDistinguisher a, SymbolDistinguisher b) { return(a.First.Equals(b.First) && a.Second.Equals(b.Second)); }