|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Emit;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
using Retargeting = Microsoft.CodeAnalysis.CSharp.Symbols.Retargeting;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public class BaseClassTests : CSharpTestBase
{
[Fact]
public void CyclicBases1()
{
var text =
@"
class X : Y {}
class Y : X {}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var x = global.GetTypeMembers("X", 0).Single();
var y = global.GetTypeMembers("Y", 0).Single();
Assert.NotEqual(y, x.BaseType());
Assert.NotEqual(x, y.BaseType());
Assert.Equal(SymbolKind.ErrorType, x.BaseType().Kind);
Assert.Equal(SymbolKind.ErrorType, y.BaseType().Kind);
Assert.Equal("Y", x.BaseType().Name);
Assert.Equal("X", y.BaseType().Name);
}
[Fact]
public void CyclicBases2()
{
var text =
@"
class X : Y.n {}
class Y : X.n {}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var x = global.GetTypeMembers("X", 0).Single();
var y = global.GetTypeMembers("Y", 0).Single();
Assert.NotEqual(y, x.BaseType());
Assert.NotEqual(x, y.BaseType());
Assert.Equal(SymbolKind.ErrorType, x.BaseType().Kind);
Assert.Equal(SymbolKind.ErrorType, y.BaseType().Kind);
Assert.Equal("n", x.BaseType().Name);
Assert.Equal("n", y.BaseType().Name);
}
[Fact]
public void CyclicBases3()
{
var C1 = TestReferences.SymbolsTests.CyclicInheritance.Class1;
var C2 = TestReferences.SymbolsTests.CyclicInheritance.Class2;
var text =
@"
class C4 : C1 {}
";
var comp = CreateCompilation(text, new[] { C1, C2 });
var global = comp.GlobalNamespace;
var x = global.GetTypeMembers("C4", 0).Single();
var x_base_base = x.BaseType().BaseType() as ErrorTypeSymbol;
var er = x_base_base.ErrorInfo;
Assert.Equal("error CS0268: Imported type 'C2' is invalid. It contains a circular base type dependency.",
er.ToString(EnsureEnglishUICulture.PreferredOrNull));
}
[WorkItem(538506, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538506")]
[Fact]
public void CyclicBasesRegress4140()
{
var text =
@"
class A<T>
{
class B : A<E> { }
class E : B.E { }
}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var a = global.GetTypeMembers("A", 1).Single();
var b = a.GetTypeMembers("B", 0).Single();
var e = a.GetTypeMembers("E", 0).Single();
Assert.NotEqual(e, e.BaseType());
var x_base = e.BaseType() as ErrorTypeSymbol;
var er = x_base.ErrorInfo;
Assert.Equal("error CS0146: Circular base type dependency involving 'A<A<T>.E>.E' and 'A<T>.E'",
er.ToString(EnsureEnglishUICulture.PreferredOrNull));
}
[WorkItem(538526, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538526")]
[Fact]
public void CyclicBasesRegress4166()
{
var text =
@"
class A<T> {
public class C : B.D { }
}
class B {
public class D : A<int>.C { }
}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var a = global.GetTypeMembers("A", 1).Single();
var b = global.GetTypeMembers("B", 0).Single();
var d = b.GetTypeMembers("D", 0).Single();
Assert.NotEqual(d, d.BaseType());
var x_base = d.BaseType() as ErrorTypeSymbol;
var er = x_base.ErrorInfo;
Assert.Equal("error CS0146: Circular base type dependency involving 'A<int>.C' and 'B.D'",
er.ToString(EnsureEnglishUICulture.PreferredOrNull));
}
[WorkItem(4169, "DevDiv_Projects/Roslyn")]
[Fact]
public void CyclicBasesRegress4169()
{
var text =
@"
class A : object, A.IC
{
protected interface IC { }
}
";
var comp = CreateCompilation(text);
var global = comp.GlobalNamespace;
var a = global.GetTypeMembers("A", 0).Single();
var ic = a.GetTypeMembers("IC", 0).Single();
Assert.Equal(a.Interfaces()[0], ic);
var diagnostics = comp.GetDeclarationDiagnostics();
Assert.Equal(0, diagnostics.Count());
}
[WorkItem(527551, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527551")]
[Fact]
public void CyclicBasesRegress4168()
{
var text =
@"
class A : object, A.B.B.IC
{
public class B : A {
public interface IC { }
}
}
";
var comp = CreateCompilation(text);
var global = comp.GlobalNamespace;
var a = global.GetTypeMembers("A", 0).Single();
var b = a.GetTypeMembers("B", 0).Single();
var ic = b.GetTypeMembers("IC", 0).Single();
Assert.NotEqual(b, b.BaseType());
Assert.NotEqual(a, b.BaseType());
Assert.Equal(SymbolKind.ErrorType, a.Interfaces()[0].Kind);
Assert.NotEqual(ic, a.Interfaces()[0]);
var diagnostics = comp.GetDeclarationDiagnostics();
Assert.Equal(2, diagnostics.Count());
}
[Fact]
public void CyclicBases4()
{
var text =
@"
class A<T> : B<A<T>> { }
class B<T> : A<B<T>> {
A<T> F() { return null; }
}
";
var comp = CreateCompilation(text);
comp.GetDeclarationDiagnostics().Verify(
// (2,7): error CS0146: Circular base type dependency involving 'B<A<T>>' and 'A<T>'
// class A<T> : B<A<T>> { }
Diagnostic(ErrorCode.ERR_CircularBase, "A").WithArguments("B<A<T>>", "A<T>"),
// (3,7): error CS0146: Circular base type dependency involving 'A<B<T>>' and 'B<T>'
// class B<T> : A<B<T>> {
Diagnostic(ErrorCode.ERR_CircularBase, "B").WithArguments("A<B<T>>", "B<T>")
);
}
[Fact]
public void CyclicBases5()
{
// bases are cyclic, but you can still find members when binding bases
var text =
@"
class A : B {
public class X { }
}
class B : A {
public class Y { }
}
class Z : A.Y { }
class W : B.X { }
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var z = global.GetTypeMembers("Z", 0).Single();
var w = global.GetTypeMembers("W", 0).Single();
var zBase = z.BaseType();
Assert.Equal("Y", zBase.Name);
var wBase = w.BaseType();
Assert.Equal("X", wBase.Name);
}
[Fact]
public void CyclicBases6()
{
// bases are cyclic, but you can still search for members w/o infinite looping in binder
var text =
@"
class A : B {
public class X {}
}
class B : C {
public class Y {}
}
class C : A {
public class Z {}
}
";
var comp = (Compilation)CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var a = global.GetTypeMembers("A", 0).Single();
//var aBase = a.BaseType();
//Assert.True(aBase.IsErrorType());
//Assert.Equal("B", aBase.Name);
var tree = comp.SyntaxTrees.First();
var model = comp.GetSemanticModel(tree);
var classA = (TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0];
var someMemberInA = classA.Members[0];
int positionInA = someMemberInA.SpanStart;
var members = model.LookupSymbols(positionInA, a, "Z");
Assert.Equal(1, members.Length);
Assert.False(((ITypeSymbol)members[0]).IsErrorType());
Assert.Equal("C.Z", members[0].ToTestDisplayString());
var members2 = model.LookupSymbols(positionInA, a, "Q");
Assert.Equal(0, members2.Length);
}
[Fact]
public void CyclicBases7()
{
// bases are cyclic, but you can still search for members w/o infinite looping in binder
var text =
@"
class A : B<A.Y> {
public class X {}
}
class B<T> : A {
public class Y {}
}
";
var comp = (Compilation)CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var a = global.GetTypeMembers("A", 0).Single();
//var aBase = a.BaseType();
//Assert.True(aBase.IsErrorType());
//Assert.Equal("B", aBase.Name);
var tree = comp.SyntaxTrees.First();
var model = comp.GetSemanticModel(tree);
var classA = (TypeDeclarationSyntax)tree.GetCompilationUnitRoot().Members[0];
var someMemberInA = classA.Members[0];
int positionInA = someMemberInA.SpanStart;
var members = model.LookupSymbols(positionInA, a, "Q");
Assert.Equal(0, members.Length);
}
[Fact]
public void CyclicBases8()
{
var text = @"
public class A
{
protected class B
{
protected class C
{
public class X { }
}
}
}
internal class F : A
{
private class D : B
{
public class E : C.X { }
}
}";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics(
// (16,22): error CS0060: Inconsistent accessibility: base type 'A.B.C.X' is less accessible than class 'F.D.E'
// public class E : C.X { }
Diagnostic(ErrorCode.ERR_BadVisBaseClass, "E").WithArguments("F.D.E", "A.B.C.X")
);
}
[Fact, WorkItem(7878, "https://github.com/dotnet/roslyn/issues/7878")]
public void BadVisibilityPartial()
{
var text = @"
internal class NV
{
}
public partial class C1
{
}
partial class C1 : NV
{
}
public partial class C1
{
}
";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics(
// (10,15): error CS0060: Inconsistent accessibility: base type 'NV' is less accessible than class 'C1'
// partial class C1 : NV
Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C1").WithArguments("C1", "NV").WithLocation(10, 15));
}
[Fact, WorkItem(7878, "https://github.com/dotnet/roslyn/issues/7878")]
public void StaticBasePartial()
{
var text = @"
static class NV
{
}
public partial class C1
{
}
partial class C1 : NV
{
}
public partial class C1
{
}
";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics(
// (10,15): error CS0709: 'C1': cannot derive from static class 'NV'
// partial class C1 : NV
Diagnostic(ErrorCode.ERR_StaticBaseClass, "C1").WithArguments("NV", "C1").WithLocation(10, 15),
// (10,15): error CS0060: Inconsistent accessibility: base type 'NV' is less accessible than class 'C1'
// partial class C1 : NV
Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C1").WithArguments("C1", "NV").WithLocation(10, 15));
}
[Fact, WorkItem(7878, "https://github.com/dotnet/roslyn/issues/7878")]
public void BadVisInterfacePartial()
{
var text = @"
interface IGoo
{
void Moo();
}
interface IBaz
{
void Noo();
}
interface IBam
{
void Zoo();
}
public partial interface IBar
{
}
partial interface IBar : IGoo, IBam
{
}
partial interface IBar : IBaz, IBaz
{
}
";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics(
// (25,32): error CS0528: 'IBaz' is already listed in interface list
// partial interface IBar : IBaz, IBaz
Diagnostic(ErrorCode.ERR_DuplicateInterfaceInBaseList, "IBaz").WithArguments("IBaz").WithLocation(25, 32),
// (21,19): error CS0061: Inconsistent accessibility: base interface 'IGoo' is less accessible than interface 'IBar'
// partial interface IBar : IGoo, IBam
Diagnostic(ErrorCode.ERR_BadVisBaseInterface, "IBar").WithArguments("IBar", "IGoo").WithLocation(21, 19),
// (21,19): error CS0061: Inconsistent accessibility: base interface 'IBam' is less accessible than interface 'IBar'
// partial interface IBar : IGoo, IBam
Diagnostic(ErrorCode.ERR_BadVisBaseInterface, "IBar").WithArguments("IBar", "IBam").WithLocation(21, 19),
// (25,19): error CS0061: Inconsistent accessibility: base interface 'IBaz' is less accessible than interface 'IBar'
// partial interface IBar : IBaz, IBaz
Diagnostic(ErrorCode.ERR_BadVisBaseInterface, "IBar").WithArguments("IBar", "IBaz").WithLocation(25, 19));
}
[Fact]
public void EricLiCase1()
{
// should not be cyclic
var text =
@"
interface I<T> {}
class A {
public class B {}
}
class C : A, I<C.B> {}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var c = global.GetTypeMembers("C", 0).Single();
var cBase = c.BaseType();
Assert.False(cBase.IsErrorType());
Assert.Equal("A", cBase.Name);
Assert.True(c.Interfaces().Single().TypeArguments().Single().IsErrorType()); //can't see base of C while evaluating C.B
}
[Fact]
public void EricLiCase2()
{
// should not be cyclic
var text =
@"
interface I<T> {}
class E : I<E> {}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var e = global.GetTypeMembers("E", 0).Single();
Assert.Equal(1, e.Interfaces().Length);
Assert.Equal("I<E>", e.Interfaces()[0].ToTestDisplayString());
}
[Fact]
public void EricLiCase3()
{
// should not be cyclic
var text =
@"
interface I<T> {}
class G : I<G.H> {
public class H {}
}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var g = global.GetTypeMembers("G", 0).Single();
Assert.Equal(1, g.Interfaces().Length);
Assert.Equal("I<G.H>", g.Interfaces()[0].ToTestDisplayString());
}
[Fact]
public void EricLiCase4()
{
// should not be cyclic
var text =
@"
interface I<T> {}
class J : I<J.K.L> {
public class K {
public class L {}
}
}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var j = global.GetTypeMembers("J", 0).Single();
Assert.Equal(1, j.Interfaces().Length);
Assert.Equal("I<J.K.L>", j.Interfaces()[0].ToTestDisplayString());
}
[Fact]
public void EricLiCase5()
{
// should be cyclic
var text =
@"class M : M {}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var m = global.GetTypeMembers("M", 0).Single();
Assert.True(m.BaseType().IsErrorType());
}
[Fact]
public void EricLiCase6()
{
// should not be cyclic
var text =
@"
class N<T> {}
class O : N<O> {}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var o = global.GetTypeMembers("O", 0).Single();
Assert.False(o.BaseType().IsErrorType());
Assert.Equal("N<O>", o.BaseType().ToTestDisplayString());
}
[Fact]
public void EricLiCase7()
{
// should not be cyclic
var text =
@"
class N<T> {}
class P : N<P.Q> {
public class Q {}
}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var p = global.GetTypeMembers("P", 0).Single();
Assert.False(p.BaseType().IsErrorType());
Assert.Equal("N<P.Q>", p.BaseType().ToTestDisplayString());
}
[Fact]
public void EricLiCase8()
{
// should not be cyclic
var text =
@"
class N<T> {}
class R : N<R.S.T>{
public class S {
public class T {}
}
}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var r = global.GetTypeMembers("R", 0).Single();
var rBase = r.BaseType();
Assert.False(rBase.IsErrorType());
Assert.Equal("N<R.S.T>", rBase.ToTestDisplayString());
}
[Fact]
public void EricLiCase9()
{
// should not be cyclic, legal to implement an inner interface
var text =
@"
class U : U.I
{
public interface I {};
}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var u = global.GetTypeMembers("U", 0).Single();
var ifaces = u.Interfaces();
Assert.Equal(1, ifaces.Length);
Assert.False(ifaces[0].IsErrorType());
Assert.Equal("U.I", ifaces[0].ToTestDisplayString());
}
[Fact]
public void EricLiCase10()
{
// should not be cyclic, legal to implement an inner interface
var text =
@"
interface IX : C.IY {}
class C : IX {
public interface IY {}
}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var c = global.GetTypeMembers("C", 0).Single();
var ifaces = c.Interfaces();
Assert.Equal(1, ifaces.Length);
Assert.False(ifaces[0].IsErrorType());
Assert.Equal("IX", ifaces[0].ToTestDisplayString());
var ix = ifaces[0];
var ixFaces = ix.Interfaces();
Assert.Equal(1, ixFaces.Length);
Assert.False(ixFaces[0].IsErrorType());
Assert.Equal("C.IY", ixFaces[0].ToTestDisplayString());
}
[Fact]
public void EricLiCase11()
{
// should not be cyclic, legal to implement an inner interface
var text =
@"
class X : Y.I {}
class Y : X {
public interface I {}
}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var x = global.GetTypeMembers("X", 0).Single();
var ifaces = x.Interfaces();
Assert.Equal(1, ifaces.Length);
Assert.False(ifaces[0].IsErrorType());
Assert.Equal("Y.I", ifaces[0].ToTestDisplayString());
}
[Fact]
public void EricLiCase12()
{
// G should not be in scope
var text =
@"
class B : G {
public class G {}
}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var b = global.GetTypeMembers("B", 0).Single();
Assert.True(b.BaseType().IsErrorType());
}
[Fact]
public void EricLiCase14()
{
// this should be cyclic
var text =
@"
class B {}
class D {}
class Z<T> : E<B> {}
class E<U> : Z<D> {}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var z = global.GetTypeMembers("Z", 1).Single();
Assert.True(z.BaseType().IsErrorType());
}
[Fact]
public void VladResCase01()
{
var text = @"
class A : A { }
";
CreateCompilation(text).VerifyDiagnostics(
// (2,7): error CS0146: Circular base type dependency involving 'A' and 'A'
Diagnostic(ErrorCode.ERR_CircularBase, "A").WithArguments("A", "A"));
}
[Fact]
public void VladResCase02()
{
var text = @"
class A : B { }
class B : A { }
";
CreateCompilation(text).VerifyDiagnostics(
// (2,7): error CS0146: Circular base type dependency involving 'B' and 'A'
Diagnostic(ErrorCode.ERR_CircularBase, "A").WithArguments("B", "A"),
// (3,7): error CS0146: Circular base type dependency involving 'A' and 'B'
Diagnostic(ErrorCode.ERR_CircularBase, "B").WithArguments("A", "B"));
}
[Fact]
public void VladResCase03()
{
var text = @"
class A : A.B
{
public class B { }
}
";
CreateCompilation(text).VerifyDiagnostics(
// (2,7): error CS0146: Circular base type dependency involving 'A.B' and 'A'
Diagnostic(ErrorCode.ERR_CircularBase, "A").WithArguments("A.B", "A"));
}
[Fact]
public void VladResCase04()
{
var text = @"
class A : A.I
{
public interface I { }
}
";
CreateCompilation(text).VerifyDiagnostics();
}
[Fact]
public void VladResCase05()
{
var text = @"
class A : A.I
{
private interface I { }
}
";
CreateCompilation(text).VerifyDiagnostics();
}
[Fact]
public void VladResCase06()
{
var text = @"
class A : A.B.I
{
private class B : A
{
public interface I { }
}
}
";
CreateCompilation(text).VerifyDiagnostics();
}
[Fact]
public void VladResCase07()
{
var text = @"
class A : A.B.B.I
{
private class B : A
{
public interface I { }
}
}
";
CreateCompilation(text).VerifyDiagnostics(
Diagnostic(ErrorCode.ERR_CircularBase, "A").WithArguments("A", "A.B"),
Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInAgg, "B").WithArguments("B", "A.B"));
}
[Fact]
public void VladResCase08()
{
var text = @"
class A : C<A.B>
{
public class B
{
}
}
class C<T> { }
";
CreateCompilation(text).VerifyDiagnostics();
}
[Fact]
public void VladResCase09()
{
var text = @"
class A : C<A.B.D>
{
public class B
{
public class D { }
}
}
class C<T> { }
";
CreateCompilation(text).VerifyDiagnostics();
}
[Fact]
public void VladResCase10()
{
var text = @"
class A : C<A.B.B>
{
public class B : A { }
}
class C<T> { }
";
CreateCompilation(text).VerifyDiagnostics(
Diagnostic(ErrorCode.ERR_CircularBase, "A").WithArguments("A", "A.B"),
Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInAgg, "B").WithArguments("B", "A.B"));
}
[Fact]
public void VladResCase11()
{
var text = @"
class A : C<E>
{
public class B
{
public class D { }
}
}
class C<T> { }
class E : A.B.D { }
";
CreateCompilation(text).VerifyDiagnostics();
}
[Fact]
public void VladResCase12()
{
var text = @"
class A : C<E.F>
{
public class B
{
public class D
{
public class F { }
}
}
}
class C<T> { }
class E : A.B.D { }
";
CreateCompilation(text).VerifyDiagnostics();
}
[Fact]
public void VladResCase13()
{
var text = @"
class A<T>
{
public class B { }
}
class C : A<D.B> { }
class D : C { }
";
CreateCompilation(text).VerifyDiagnostics(
// (7,15): error CS0426: The type name 'B' does not exist in the type 'D'
Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInAgg, "B").WithArguments("B", "D"));
}
[Fact]
public void VladResCase14()
{
var text = @"
class A<T>
{
public class B { }
}
class C : A<C>, I<C.B> { }
interface I<T> { }
";
CreateCompilation(text).VerifyDiagnostics(
// (7,21): error CS0146: Circular base type dependency involving 'C' and 'C'
Diagnostic(ErrorCode.ERR_CircularBase, "B").WithArguments("C", "C"));
}
[Fact]
public void VladResCase15()
{
var text = @"
class X
{
public interface Z { }
}
class A
{
public class X
{
public class V { }
}
}
class B : A, B.Y.Z
{
public class Y : X { }
public class C : B.Y.V { }
}
";
CreateCompilation(text).VerifyDiagnostics(
Diagnostic(ErrorCode.ERR_CircularBase, "X").WithArguments("B", "B.Y"),
Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInAgg, "Z").WithArguments("Z", "B.Y"),
Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInAgg, "V").WithArguments("V", "B.Y"));
}
[Fact]
public void VladResCase16()
{
var text = @"
class X
{
public interface Z { }
}
class A<T>
{
public class X
{
public class V { }
}
}
class B : A<B.Y.Z>
{
public class Y : X { }
public class C : B.Y.V { }
}
";
CreateCompilation(text).VerifyDiagnostics(
// (15,17): error CS0146: Circular base type dependency involving 'B.Y' and 'B'
Diagnostic(ErrorCode.ERR_CircularBase, "X").WithArguments("B", "B.Y"),
Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInAgg, "Z").WithArguments("Z", "B.Y"),
Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInAgg, "V").WithArguments("V", "B.Y"));
}
[Fact]
public void CyclicInterfaces3()
{
var C1 = TestReferences.SymbolsTests.CyclicInheritance.Class1;
var C2 = TestReferences.SymbolsTests.CyclicInheritance.Class2;
var text =
@"
interface I4 : I1 {}
";
var comp = CreateCompilation(text, new[] { C1, C2 });
var global = comp.GlobalNamespace;
var x = global.GetTypeMembers("I4", 0).Single();
var x_base_base = x.Interfaces().First().Interfaces().First() as ErrorTypeSymbol;
var er = x_base_base.ErrorInfo;
Assert.Equal("error CS0268: Imported type 'I2' is invalid. It contains a circular base type dependency.",
er.ToString(EnsureEnglishUICulture.PreferredOrNull));
}
[Fact]
public void CyclicRetargeted4()
{
var ClassAv1 = TestReferences.SymbolsTests.RetargetingCycle.V1.ClassA.dll;
var text =
@"
public class ClassB : ClassA {}
";
var comp = CreateCompilation(text, new[] { ClassAv1 }, assemblyName: "ClassB");
var global1 = comp.GlobalNamespace;
var B1 = global1.GetTypeMembers("ClassB", 0).Single();
var A1 = global1.GetTypeMembers("ClassA", 0).Single();
var B_base = B1.BaseType();
var A_base = A1.BaseType();
Assert.True(B1.IsFromCompilation(comp));
Assert.IsAssignableFrom<PENamedTypeSymbol>(B_base);
Assert.IsAssignableFrom<PENamedTypeSymbol>(A_base);
var ClassAv2 = TestReferences.SymbolsTests.RetargetingCycle.V2.ClassA.dll;
text =
@"
public class ClassC : ClassB {}
";
var comp2 = CreateCompilation(text, new MetadataReference[] { ClassAv2, new CSharpCompilationReference(comp) });
var global = comp2.GlobalNamespace;
var B2 = global.GetTypeMembers("ClassB", 0).Single();
var C = global.GetTypeMembers("ClassC", 0).Single();
Assert.IsType<Retargeting.RetargetingNamedTypeSymbol>(B2);
Assert.Same(B1, ((Retargeting.RetargetingNamedTypeSymbol)B2).UnderlyingNamedType);
Assert.Same(C.BaseType(), B2);
Assert.False(B2.IsSerializable);
var errorBase = B2.BaseType() as ErrorTypeSymbol;
var er = errorBase.ErrorInfo;
Assert.Equal("error CS0268: Imported type 'ClassA' is invalid. It contains a circular base type dependency.",
er.ToString(EnsureEnglishUICulture.PreferredOrNull));
var A2 = global.GetTypeMembers("ClassA", 0).Single();
var errorBase1 = A2.BaseType() as ErrorTypeSymbol;
er = errorBase1.ErrorInfo;
Assert.Equal("error CS0268: Imported type 'ClassB' is invalid. It contains a circular base type dependency.",
er.ToString(EnsureEnglishUICulture.PreferredOrNull));
}
[Fact]
public void CyclicRetargeted5()
{
var ClassAv1 = TestReferences.SymbolsTests.RetargetingCycle.V1.ClassA.dll;
var ClassBv1 = TestReferences.SymbolsTests.RetargetingCycle.V1.ClassB.netmodule;
var text = @"// hi";
var comp = CreateCompilation(text, new[]
{
ClassAv1,
ClassBv1
},
assemblyName: "ClassB");
var global1 = comp.GlobalNamespace;
var B1 = global1.GetTypeMembers("ClassB", 0).Distinct().Single();
var A1 = global1.GetTypeMembers("ClassA", 0).Single();
var B_base = B1.BaseType();
var A_base = A1.BaseType();
Assert.IsAssignableFrom<PENamedTypeSymbol>(B1);
Assert.IsAssignableFrom<PENamedTypeSymbol>(B_base);
Assert.IsAssignableFrom<PENamedTypeSymbol>(A_base);
var ClassAv2 = TestReferences.SymbolsTests.RetargetingCycle.V2.ClassA.dll;
text =
@"
public class ClassC : ClassB {}
";
var comp2 = CreateCompilation(text, new MetadataReference[]
{
ClassAv2,
new CSharpCompilationReference(comp)
});
var global = comp2.GlobalNamespace;
var B2 = global.GetTypeMembers("ClassB", 0).Single();
var C = global.GetTypeMembers("ClassC", 0).Single();
Assert.IsAssignableFrom<PENamedTypeSymbol>(B2);
Assert.NotEqual(B1, B2);
Assert.Same(((PEModuleSymbol)B1.ContainingModule).Module, ((PEModuleSymbol)B2.ContainingModule).Module);
Assert.Equal(((PENamedTypeSymbol)B1).Handle, ((PENamedTypeSymbol)B2).Handle);
Assert.Same(C.BaseType(), B2);
var errorBase = B2.BaseType() as ErrorTypeSymbol;
var er = errorBase.ErrorInfo;
Assert.Equal("error CS0268: Imported type 'ClassA' is invalid. It contains a circular base type dependency.",
er.ToString(EnsureEnglishUICulture.PreferredOrNull));
var A2 = global.GetTypeMembers("ClassA", 0).Single();
var errorBase1 = A2.BaseType() as ErrorTypeSymbol;
er = errorBase1.ErrorInfo;
Assert.Equal("error CS0268: Imported type 'ClassB' is invalid. It contains a circular base type dependency.",
er.ToString(EnsureEnglishUICulture.PreferredOrNull));
}
[Fact]
public void CyclicRetargeted6()
{
var ClassAv2 = TestReferences.SymbolsTests.RetargetingCycle.V2.ClassA.dll;
var text =
@"
public class ClassB : ClassA {}
";
var comp = CreateCompilation(text, new[] { ClassAv2 }, assemblyName: "ClassB");
var global1 = comp.GlobalNamespace;
var B1 = global1.GetTypeMembers("ClassB", 0).Single();
var A1 = global1.GetTypeMembers("ClassA", 0).Single();
var B_base = B1.BaseType();
var A_base = A1.BaseType();
Assert.True(B1.IsFromCompilation(comp));
var errorBase = B_base as ErrorTypeSymbol;
var er = errorBase.ErrorInfo;
Assert.Equal("error CS0146: Circular base type dependency involving 'ClassA' and 'ClassB'",
er.ToString(EnsureEnglishUICulture.PreferredOrNull));
var errorBase1 = A_base as ErrorTypeSymbol;
er = errorBase1.ErrorInfo;
Assert.Equal("error CS0268: Imported type 'ClassB' is invalid. It contains a circular base type dependency.",
er.ToString(EnsureEnglishUICulture.PreferredOrNull));
var ClassAv1 = TestReferences.SymbolsTests.RetargetingCycle.V1.ClassA.dll;
text =
@"
public class ClassC : ClassB {}
";
var comp2 = CreateCompilation(text, new MetadataReference[]
{
ClassAv1,
new CSharpCompilationReference(comp),
});
var global = comp2.GlobalNamespace;
var A2 = global.GetTypeMembers("ClassA", 0).Single();
var B2 = global.GetTypeMembers("ClassB", 0).Single();
var C = global.GetTypeMembers("ClassC", 0).Single();
Assert.IsType<Retargeting.RetargetingNamedTypeSymbol>(B2);
Assert.Same(B1, ((Retargeting.RetargetingNamedTypeSymbol)B2).UnderlyingNamedType);
Assert.Same(C.BaseType(), B2);
Assert.Same(B2.BaseType(), A2);
}
[Fact]
public void CyclicRetargeted7()
{
var ClassAv2 = TestReferences.SymbolsTests.RetargetingCycle.V2.ClassA.dll;
var ClassBv1 = TestReferences.SymbolsTests.RetargetingCycle.V1.ClassB.netmodule;
var text = @"// hi";
var comp = CreateCompilation(text, new MetadataReference[]
{
ClassAv2,
ClassBv1,
},
assemblyName: "ClassB");
var global1 = comp.GlobalNamespace;
var B1 = global1.GetTypeMembers("ClassB", 0).Distinct().Single();
var A1 = global1.GetTypeMembers("ClassA", 0).Single();
var B_base = B1.BaseType();
var A_base = A1.BaseType();
Assert.IsAssignableFrom<PENamedTypeSymbol>(B1);
var errorBase = B_base as ErrorTypeSymbol;
var er = errorBase.ErrorInfo;
Assert.Equal("error CS0268: Imported type 'ClassA' is invalid. It contains a circular base type dependency.",
er.ToString(EnsureEnglishUICulture.PreferredOrNull));
var errorBase1 = A_base as ErrorTypeSymbol;
er = errorBase1.ErrorInfo;
Assert.Equal("error CS0268: Imported type 'ClassB' is invalid. It contains a circular base type dependency.",
er.ToString(EnsureEnglishUICulture.PreferredOrNull));
var ClassAv1 = TestReferences.SymbolsTests.RetargetingCycle.V1.ClassA.dll;
text =
@"
public class ClassC : ClassB {}
";
var comp2 = CreateCompilation(text, new MetadataReference[]
{
ClassAv1,
new CSharpCompilationReference(comp)
});
var global = comp2.GlobalNamespace;
var B2 = global.GetTypeMembers("ClassB", 0).Single();
var C = global.GetTypeMembers("ClassC", 0).Single();
Assert.IsAssignableFrom<PENamedTypeSymbol>(B2);
Assert.NotEqual(B1, B2);
Assert.Same(((PEModuleSymbol)B1.ContainingModule).Module, ((PEModuleSymbol)B2.ContainingModule).Module);
Assert.Equal(((PENamedTypeSymbol)B1).Handle, ((PENamedTypeSymbol)B2).Handle);
Assert.Same(C.BaseType(), B2);
var A2 = global.GetTypeMembers("ClassA", 0).Single();
Assert.IsAssignableFrom<PENamedTypeSymbol>(A2.BaseType());
Assert.IsAssignableFrom<PENamedTypeSymbol>(B2.BaseType());
}
[Theory, MemberData(nameof(FileScopedOrBracedNamespace))]
public void NestedNames1(string ob, string cb)
{
var text =
@"
namespace N
" + ob + @"
static class C
{
class A<T>
{
class B<U> : A<B<U>>.D { }
private class D { }
}
}
" + cb + @"
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var n = global.GetMembers("N").OfType<NamespaceSymbol>().Single();
var c = n.GetTypeMembers("C", 0).Single();
var a = c.GetTypeMembers("A", 1).Single();
var b = a.GetTypeMembers("B", 1).Single();
var d = a.GetTypeMembers("D", 0).Single();
Assert.Equal(Accessibility.Private, d.DeclaredAccessibility);
Assert.Equal(d.OriginalDefinition, b.BaseType().OriginalDefinition);
Assert.NotEqual(d, b.BaseType());
}
[Fact]
public void Using1()
{
var text =
@"
namespace N1 {
class A {}
}
namespace N2 {
using N1; // bring N1.A into scope
class B : A {}
}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var n1 = global.GetMembers("N1").Single() as NamespaceSymbol;
var n2 = global.GetMembers("N2").Single() as NamespaceSymbol;
var a = n1.GetTypeMembers("A", 0).Single();
var b = n2.GetTypeMembers("B", 0).Single();
Assert.Equal(a, b.BaseType());
}
[Fact]
public void Using2()
{
var text =
@"
namespace N1 {
class A<T> {}
}
namespace N2 {
using X = N1.A<B>; // bring N1.A into scope
class B : X {}
}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var n1 = global.GetMembers("N1").Single() as NamespaceSymbol;
var n2 = global.GetMembers("N2").Single() as NamespaceSymbol;
var a = n1.GetTypeMembers("A", 1).Single();
var b = n2.GetTypeMembers("B", 0).Single();
var bt = b.BaseType();
Assert.Equal(a, b.BaseType().OriginalDefinition);
Assert.Equal(b, (b.BaseType() as NamedTypeSymbol).TypeArguments()[0]);
}
[Fact]
public void Using3()
{
var text =
@"
using @global = N;
namespace N { class C {} }
class D : global::N.C {}";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var d = global.GetMembers("D").Single() as NamedTypeSymbol;
Assert.NotEqual(SymbolKind.ErrorType, d.BaseType().Kind);
}
[Fact]
public void Arrays1()
{
var text =
@"
class G<T> { }
class C : G<C[,][]>
{
}
";
var comp = CreateEmptyCompilation(text);
var global = comp.GlobalNamespace;
var g = global.GetTypeMembers("G", 1).Single();
var c = global.GetTypeMembers("C", 0).Single();
Assert.Equal(g, c.BaseType().OriginalDefinition);
var garg = c.BaseType().TypeArguments()[0];
Assert.Equal(SymbolKind.ArrayType, garg.Kind);
var carr1 = garg as ArrayTypeSymbol;
var carr2 = carr1.ElementType as ArrayTypeSymbol;
Assert.Equal(c, carr2.ElementType);
Assert.Equal(2, carr1.Rank);
Assert.Equal(1, carr2.Rank);
Assert.True(carr2.IsSZArray);
}
[Fact]
public void MultiSource()
{
var text1 =
@"
using N2;
namespace N1 {
class A {}
}
partial class X {
class B1 : B {}
}
partial class Broken {
class A2 : A {} // error: A not found
}
";
var text2 =
@"
using N1;
namespace N2 {
class B {}
}
partial class X {
class A1 : A {}
}
partial class Broken {
class B2 : B {} // error: B not found
}
";
var comp = CreateEmptyCompilation(new[] { text1, text2 });
var global = comp.GlobalNamespace;
var n1 = global.GetMembers("N1").Single() as NamespaceSymbol;
var n2 = global.GetMembers("N2").Single() as NamespaceSymbol;
var a = n1.GetTypeMembers("A", 0).Single();
var b = n2.GetTypeMembers("B", 0).Single();
var x = global.GetTypeMembers("X", 0).Single();
var a1 = x.GetTypeMembers("A1", 0).Single();
Assert.Equal(a, a1.BaseType());
var b1 = x.GetTypeMembers("B1", 0).Single();
Assert.Equal(b, b1.BaseType());
var broken = global.GetTypeMembers("Broken", 0).Single();
var a2 = broken.GetTypeMembers("A2", 0).Single();
Assert.NotEqual(a, a2.BaseType());
Assert.Equal(SymbolKind.ErrorType, a2.BaseType().Kind);
var b2 = broken.GetTypeMembers("B2", 0).Single();
Assert.NotEqual(b, b2.BaseType());
Assert.Equal(SymbolKind.ErrorType, b2.BaseType().Kind);
}
[Fact]
public void CyclicUsing1()
{
var text =
@"
using M = B.X;
using N = A.Y;
public class A : M { }
public class B : N { }
";
var tree = Parse(text);
var comp = CreateCompilation(tree);
var global = comp.GlobalNamespace;
var a = global.GetTypeMembers("A", 0).Single();
var b = global.GetTypeMembers("B", 0).Single();
var abase = a.BaseType();
Assert.Equal(SymbolKind.ErrorType, abase.Kind);
var bbase = b.BaseType();
Assert.Equal(SymbolKind.ErrorType, bbase.Kind);
}
[Fact]
public void BaseError()
{
var text = "class C : Bar { }";
var tree = Parse(text);
var comp = CreateCompilation(tree);
Assert.Equal(1, comp.GetDeclarationDiagnostics().Count());
}
[Fact, WorkItem(537401, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537401")]
public void NamespaceClassInterfaceEscapedIdentifier1()
{
var text = @"
namespace @if
{
public interface @break { }
public class @int<@string> { }
public class @float : @int<@break>, @if.@break { }
}";
var comp = CreateCompilation(Parse(text));
NamespaceSymbol nif = (NamespaceSymbol)comp.SourceModule.GlobalNamespace.GetMembers("if").Single();
Assert.Equal("if", nif.Name);
Assert.Equal("@if", nif.ToString());
NamedTypeSymbol cfloat = (NamedTypeSymbol)nif.GetMembers("float").Single();
Assert.Equal("float", cfloat.Name);
Assert.Equal("@if.@float", cfloat.ToString());
NamedTypeSymbol cint = cfloat.BaseType();
Assert.Equal("int", cint.Name);
Assert.Equal("@if.@int<@if.@break>", cint.ToString());
NamedTypeSymbol ibreak = cfloat.Interfaces().Single();
Assert.Equal("break", ibreak.Name);
Assert.Equal("@if.@break", ibreak.ToString());
}
[Fact, WorkItem(537401, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537401")]
public void NamespaceClassInterfaceEscapedIdentifier2()
{
var text = @"
namespace @if
{
public interface @break { }
public class @int<@string> { }
public class @float : @int<@break> : @if.@break { }
}";
var comp = CreateCompilation(Parse(text));
NamespaceSymbol nif = (NamespaceSymbol)comp.SourceModule.GlobalNamespace.GetMembers("if").Single();
Assert.Equal("if", nif.Name);
Assert.Equal("@if", nif.ToString());
NamedTypeSymbol cfloat = (NamedTypeSymbol)nif.GetMembers("float").Single();
Assert.Equal("float", cfloat.Name);
Assert.Equal("@if.@float", cfloat.ToString());
NamedTypeSymbol cint = cfloat.BaseType();
Assert.Equal("int", cint.Name);
Assert.Equal("@if.@int<@if.@break>", cint.ToString());
// No interfaces as the above doesn't parse due to the errant : in the base list.
Assert.Empty(cfloat.Interfaces());
}
[WorkItem(539328, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539328")]
[WorkItem(539789, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539789")]
[Fact]
public void AccessInBaseClauseCheckedWithRespectToContainer()
{
var text = @"
class X
{
protected class A { }
}
class Y : X
{
private class C : X.A { }
private class B { }
}";
var comp = CreateCompilation(Parse(text));
var diags = comp.GetDeclarationDiagnostics();
Assert.Empty(diags);
}
/// <summary>
/// The base type of a nested type should not change depending on
/// whether or not the base type of the containing type has been
/// evaluated.
/// </summary>
[WorkItem(539744, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539744")]
[Fact]
public void BaseTypeEvaluationOrder()
{
var text = @"
class A<T>
{
public class X { }
}
class B : A<B.Y.Error>
{
public class Y : X { }
}
";
//B.BaseType(), B.Y.BaseType
{
var comp = CreateCompilation(text);
var classB = (NamedTypeSymbol)comp.SourceModule.GlobalNamespace.GetMembers("B")[0];
var classY = (NamedTypeSymbol)classB.GetMembers("Y")[0];
var baseB = classB.BaseType();
Assert.Equal("A<B.Y.Error>", baseB.ToTestDisplayString());
Assert.False(baseB.IsErrorType());
var baseY = classY.BaseType();
Assert.Equal("X", baseY.ToTestDisplayString());
Assert.True(baseY.IsErrorType());
}
//B.Y.BaseType(), B.BaseType
{
var comp = CreateCompilation(text);
var classB = (NamedTypeSymbol)comp.SourceModule.GlobalNamespace.GetMembers("B")[0];
var classY = (NamedTypeSymbol)classB.GetMembers("Y")[0];
var baseY = classY.BaseType();
Assert.Equal("X", baseY.ToTestDisplayString());
Assert.True(baseY.IsErrorType());
var baseB = classB.BaseType();
Assert.Equal("A<B.Y.Error>", baseB.ToTestDisplayString());
Assert.False(baseB.IsErrorType());
}
}
[Fact]
public void BaseInterfacesInMetadata()
{
var text = @"
interface I1 { }
interface I2 : I1 { }
class C : I2 { }
";
var comp = CreateCompilation(text);
var global = comp.GlobalNamespace;
var baseInterface = global.GetMember<NamedTypeSymbol>("I1");
var derivedInterface = global.GetMember<NamedTypeSymbol>("I2");
var @class = global.GetMember<NamedTypeSymbol>("C");
var bothInterfaces = ImmutableArray.Create(baseInterface, derivedInterface);
Assert.Equal(baseInterface, derivedInterface.AllInterfaces().Single());
Assert.Equal(derivedInterface, @class.Interfaces().Single());
Assert.True(@class.AllInterfaces().SetEquals(bothInterfaces, EqualityComparer<NamedTypeSymbol>.Default));
var typeDef = (Cci.ITypeDefinition)@class.GetCciAdapter();
var module = new PEAssemblyBuilder((SourceAssemblySymbol)@class.ContainingAssembly, EmitOptions.Default, OutputKind.DynamicallyLinkedLibrary,
GetDefaultModulePropertiesForSerialization(), SpecializedCollections.EmptyEnumerable<ResourceDescription>());
var context = new EmitContext(module, null, new DiagnosticBag(), metadataOnly: false, includePrivateMembers: true);
var cciInterfaces = typeDef.Interfaces(context)
.Select(impl => impl.TypeRef.GetInternalSymbol()).Cast<NamedTypeSymbol>().AsImmutable();
Assert.True(cciInterfaces.SetEquals(bothInterfaces, EqualityComparer<NamedTypeSymbol>.Default));
context.Diagnostics.Verify();
}
[Fact(), WorkItem(544454, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544454")]
public void InterfaceImplementedWithPrivateType()
{
var textA = @"
using System;
using System.Collections;
using System.Collections.Generic;
public class A: IEnumerable<A.MyPrivateType>
{
private class MyPrivateType {}
IEnumerator<MyPrivateType> IEnumerable<A.MyPrivateType>.GetEnumerator()
{ throw new NotImplementedException(); }
IEnumerator IEnumerable.GetEnumerator()
{ throw new NotImplementedException(); }
}";
var textB = @"
using System.Collections.Generic;
class Z
{
public IEnumerable<object> goo(A a)
{
return a;
}
}";
CSharpCompilation c1 = CreateCompilation(textA);
CSharpCompilation c2 = CreateCompilation(textB, new[] { new CSharpCompilationReference(c1) });
//Works this way, but doesn't when compilation is supplied as metadata
Assert.Equal(0, c1.GetDiagnostics().Count());
Assert.Equal(0, c2.GetDiagnostics().Count());
var metadata1 = c1.EmitToArray(options: new EmitOptions(metadataOnly: true));
c2 = CreateCompilation(textB, new[] { MetadataReference.CreateFromImage(metadata1) });
Assert.Equal(0, c2.GetDiagnostics().Count());
}
[WorkItem(545365, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545365")]
[Fact()]
public void ProtectedInternalNestedBaseClass()
{
var source1 = @"
public class PublicClass
{
protected internal class ProtectedInternalClass
{
public ProtectedInternalClass()
{
}
}
}
";
var source2 = @"
class C : PublicClass.ProtectedInternalClass
{
}
";
var compilation1 = CreateCompilation(source1, assemblyName: "One");
compilation1.VerifyDiagnostics();
var compilation2 = CreateCompilation(source2, new[] { new CSharpCompilationReference(compilation1) }, assemblyName: "Two");
compilation2.VerifyDiagnostics(
// (2,23): error CS0122: 'PublicClass.ProtectedInternalClass' is inaccessible due to its protection level
// class C : PublicClass.ProtectedInternalClass
Diagnostic(ErrorCode.ERR_BadAccess, "ProtectedInternalClass").WithArguments("PublicClass.ProtectedInternalClass").WithLocation(2, 23)
);
}
[WorkItem(545365, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545365")]
[ClrOnlyFact(ClrOnlyReason.Ilasm)]
public void ProtectedAndInternalNestedBaseClass()
{
// Note: the problem was with the "protected" check so we use InternalsVisibleTo to make
// the "internal" check succeed.
var il = @"
.assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
.assembly '<<GeneratedFileName>>'
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.InternalsVisibleToAttribute::.ctor(string)
= {string('Test')}
}
.class public auto ansi beforefieldinit PublicClass
extends [mscorlib]System.Object
{
.class auto ansi nested famandassem beforefieldinit ProtectedAndInternalClass
extends [mscorlib]System.Object
{
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
}
} // end of class ProtectedAndInternalClass
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
}
} // end of class PublicClass
";
var csharp = @"
class C : PublicClass.ProtectedAndInternalClass
{
}
";
CreateCompilationWithILAndMscorlib40(csharp, il, appendDefaultHeader: false).VerifyDiagnostics(
// (2,23): error CS0122: 'PublicClass.ProtectedAndInternalClass' is inaccessible due to its protection level
// class C : PublicClass.ProtectedAndInternalClass
Diagnostic(ErrorCode.ERR_BadAccess, "ProtectedAndInternalClass").WithArguments("PublicClass.ProtectedAndInternalClass").WithLocation(2, 23)
);
}
[WorkItem(530144, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530144")]
[Fact()]
public void UnifyingBaseInterfaces01()
{
var il = @"
.assembly extern mscorlib
{
}
.assembly a
{
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module a.dll
.class interface public abstract auto ansi J`1<T>
{
}
.class interface public abstract auto ansi I`1<T>
implements class J`1<int32>,
class J`1<!T>
{
}";
var csharp =
@"public class C
{
public static I<int> x;
static void F(I<int> x)
{
I<int> t = C.x;
}
}
public class D : I<int> {}
public interface I2 : I<int> {}";
CreateCompilationWithILAndMscorlib40(csharp, il, appendDefaultHeader: false).VerifyDiagnostics(
// (4,26): error CS0648: 'I<int>' is a type not supported by the language
// static void F(I<int> x)
Diagnostic(ErrorCode.ERR_BogusType, "x").WithArguments("I<int>").WithLocation(4, 26),
// (3,26): error CS0648: 'I<int>' is a type not supported by the language
// public static I<int> x;
Diagnostic(ErrorCode.ERR_BogusType, "x").WithArguments("I<int>").WithLocation(3, 26),
// (10,14): error CS0648: 'I<int>' is a type not supported by the language
// public class D : I<int> {}
Diagnostic(ErrorCode.ERR_BogusType, "D").WithArguments("I<int>").WithLocation(10, 14),
// (11,18): error CS0648: 'I<int>' is a type not supported by the language
// public interface I2 : I<int> {}
Diagnostic(ErrorCode.ERR_BogusType, "I2").WithArguments("I<int>").WithLocation(11, 18),
// (6,9): error CS0648: 'I<int>' is a type not supported by the language
// I<int> t = C.x;
Diagnostic(ErrorCode.ERR_BogusType, "I<int>").WithArguments("I<int>").WithLocation(6, 9)
);
}
[WorkItem(530144, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530144")]
[Fact()]
public void UnifyingBaseInterfaces02()
{
var il = @"
.assembly extern mscorlib
{
}
.assembly a
{
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module a.dll
.class interface public abstract auto ansi J`1<T>
{
}
.class interface public abstract auto ansi I`1<T>
implements class J`1<object>,
class J`1<!T>
{
}";
var csharp =
@"public class C
{
public static I<dynamic> x;
static void F(I<dynamic> x)
{
I<dynamic> t = C.x;
}
}";
CreateCompilationWithILAndMscorlib40(csharp, il, appendDefaultHeader: false, targetFramework: TargetFramework.Standard).VerifyDiagnostics(
// (4,30): error CS0648: 'I<dynamic>' is a type not supported by the language
// static void F(I<dynamic> x)
Diagnostic(ErrorCode.ERR_BogusType, "x").WithArguments("I<dynamic>").WithLocation(4, 30),
// (3,30): error CS0648: 'I<dynamic>' is a type not supported by the language
// public static I<dynamic> x;
Diagnostic(ErrorCode.ERR_BogusType, "x").WithArguments("I<dynamic>").WithLocation(3, 30),
// (6,9): error CS0648: 'I<dynamic>' is a type not supported by the language
// I<dynamic> t = C.x;
Diagnostic(ErrorCode.ERR_BogusType, "I<dynamic>").WithArguments("I<dynamic>").WithLocation(6, 9)
);
}
[WorkItem(545365, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545365")]
[Fact()]
public void ProtectedNestedBaseClass()
{
var source1 = @"
public class PublicClass
{
protected class ProtectedClass
{
public ProtectedClass()
{
}
}
}
";
var source2 = @"
class C : PublicClass.ProtectedClass
{
}
";
var compilation1 = CreateCompilation(source1, assemblyName: "One");
compilation1.VerifyDiagnostics();
var compilation2 = CreateCompilation(source2, new[] { new CSharpCompilationReference(compilation1) }, assemblyName: "Two");
compilation2.VerifyDiagnostics(
// (2,23): error CS0122: 'PublicClass.ProtectedClass' is inaccessible due to its protection level
// class C : PublicClass.ProtectedClass
Diagnostic(ErrorCode.ERR_BadAccess, "ProtectedClass").WithArguments("PublicClass.ProtectedClass"));
}
[WorkItem(545589, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545589")]
[Fact]
public void MissingTypeArgumentInBase()
{
var text =
@"interface I<out T> { }
class B : I<object>
{
public static void Goo<T>(I<T> x)
{
}
public static void Goo<T>() where T : I<>
{
}
static void Main()
{
Goo(new B());
}
}";
var comp = CreateCompilation(Parse(text));
comp.VerifyDiagnostics(
// (9,43): error CS7003: Unexpected use of an unbound generic name
// public static void Goo<T>() where T : I<>
Diagnostic(ErrorCode.ERR_UnexpectedUnboundGenericName, "I<>")
);
}
[WorkItem(792711, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/792711")]
[Fact]
public void Repro792711()
{
var source = @"
public class Base<T>
{
}
public class Derived<T> : Base<Derived<T>>
{
}
";
var metadataRef = CreateCompilation(source).EmitToImageReference(embedInteropTypes: true);
var comp = CreateCompilation("", new[] { metadataRef });
var derived = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("Derived");
Assert.Equal(TypeKind.Class, derived.TypeKind);
}
[WorkItem(872825, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/872825")]
[Fact]
public void InaccessibleStructInterface()
{
var source =
@"class C
{
protected interface I
{
}
}
struct S : C.I
{
}";
var compilation = CreateCompilation(source);
compilation.VerifyDiagnostics(
// (7,14): error CS0122: 'C.I' is inaccessible due to its protection level
// struct S : C.I
Diagnostic(ErrorCode.ERR_BadAccess, "I").WithArguments("C.I").WithLocation(7, 14));
}
[WorkItem(872948, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/872948")]
[Fact]
public void MissingNestedMemberInStructImplementsClause()
{
var source =
@"struct S : S.I
{
}";
var compilation = CreateCompilation(source);
// Ideally report "CS0426: The type name 'I' does not exist in the type 'S'"
// instead. Bug #896959.
compilation.VerifyDiagnostics(
// (1,14): error CS0146: Circular base type dependency involving 'S' and 'S'
// struct S : S.I
Diagnostic(ErrorCode.ERR_CircularBase, "I").WithArguments("S", "S").WithLocation(1, 14));
}
[WorkItem(896959, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/896959")]
[Fact(Skip = "896959")]
public void MissingNestedMemberInClassImplementsClause()
{
var source =
@"class C : C.I
{
}";
var compilation = CreateCompilation(source);
compilation.VerifyDiagnostics(
// (1,13): error CS0426: The type name 'I' does not exist in the type 'C'
// class C : C.I
Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInAgg, "I").WithArguments("I", "C").WithLocation(1, 13));
}
[Fact, WorkItem(1085632, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1085632")]
public void BaseLookupRecursionWithStaticImport01()
{
const string source =
@"using A<int>.B;
using D;
class A<T> : C
{
public static class B { }
}
class D
{
public class C { }
}";
var compilation = CreateCompilation(source);
compilation.VerifyDiagnostics(
// (4,14): error CS0246: The type or namespace name 'C' could not be found (are you missing a using directive or an assembly reference?)
// class A<T> : C
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "C").WithArguments("C").WithLocation(4, 14),
// (1,7): error CS0138: A 'using namespace' directive can only be applied to namespaces; 'A<int>.B' is a type not a namespace. Consider a 'using static' directive instead
// using A<int>.B;
Diagnostic(ErrorCode.ERR_BadUsingNamespace, "A<int>.B").WithArguments("A<int>.B").WithLocation(1, 7),
// (2,7): error CS0138: A 'using namespace' directive can only be applied to namespaces; 'D' is a type not a namespace. Consider a 'using static' directive instead
// using D;
Diagnostic(ErrorCode.ERR_BadUsingNamespace, "D").WithArguments("D").WithLocation(2, 7),
// (2,1): hidden CS8019: Unnecessary using directive.
// using D;
Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using D;").WithLocation(2, 1),
// (1,1): hidden CS8019: Unnecessary using directive.
// using A<int>.B;
Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using A<int>.B;").WithLocation(1, 1)
);
}
[Fact, WorkItem(1085632, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1085632")]
public void BaseLookupRecursionWithStaticImport02()
{
const string source =
@"using static A<int>.B;
using static D;
class A<T> : C
{
public static class B { }
}
class D
{
public class C { }
}";
var compilation = CreateCompilation(source);
compilation.VerifyDiagnostics(
// (1,1): hidden CS8019: Unnecessary using directive.
// using static A<int>.B;
Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using static A<int>.B;").WithLocation(1, 1)
);
}
[Fact]
public void BindBases()
{
// Ensure good semantic model data even in error scenarios
var text =
@"
class B {
public B(long x) {}
}
class D : B {
extern D(int x) : base(y) {}
static int y;
}";
var comp = CreateCompilationWithMscorlib461(text);
var tree = comp.SyntaxTrees[0];
var model = comp.GetSemanticModel(tree);
var baseY = tree.GetRoot().DescendantNodes().Where(n => n.ToString() == "y").OfType<ExpressionSyntax>().First();
var typeInfo = model.GetTypeInfo(baseY);
Assert.Equal(SpecialType.System_Int32, typeInfo.Type.SpecialType);
Assert.Equal(SpecialType.System_Int64, typeInfo.ConvertedType.SpecialType);
}
[Fact, WorkItem(5697, "https://github.com/dotnet/roslyn/issues/5697")]
public void InheritThroughStaticImportOfGenericTypeWithConstraint_01()
{
var text =
@"
using static CrashTest.Crash<CrashTest.Class2>;
namespace CrashTest
{
class Class2 : AbstractClass
{
}
public static class Crash<T>
where T: Crash<T>.AbstractClass
{
public abstract class AbstractClass
{
public int Id { get; set; }
}
}
}";
var comp = CreateCompilation(text);
CompileAndVerify(comp);
}
[Fact, WorkItem(5697, "https://github.com/dotnet/roslyn/issues/5697")]
public void InheritThroughStaticImportOfGenericTypeWithConstraint_02()
{
var text =
@"
using static CrashTest.Crash<object>;
namespace CrashTest
{
class Class2 : AbstractClass
{
}
public static class Crash<T>
where T: Crash<T>.AbstractClass
{
public abstract class AbstractClass
{
public int Id { get; set; }
}
}
class Class3
{
AbstractClass Test()
{
return null;
}
}
}";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics(
// (2,14): error CS0311: The type 'object' cannot be used as type parameter 'T' in the generic type or method 'Crash<T>'. There is no implicit reference conversion from 'object' to 'CrashTest.Crash<object>.AbstractClass'.
// using static CrashTest.Crash<object>;
Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedRefType, "CrashTest.Crash<object>").WithArguments("CrashTest.Crash<T>", "CrashTest.Crash<object>.AbstractClass", "T", "object").WithLocation(2, 14),
// (6,11): error CS0311: The type 'object' cannot be used as type parameter 'T' in the generic type or method 'Crash<T>'. There is no implicit reference conversion from 'object' to 'CrashTest.Crash<object>.AbstractClass'.
// class Class2 : AbstractClass
Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedRefType, "Class2").WithArguments("CrashTest.Crash<T>", "CrashTest.Crash<object>.AbstractClass", "T", "object").WithLocation(6, 11),
// (21,23): error CS0311: The type 'object' cannot be used as type parameter 'T' in the generic type or method 'Crash<T>'. There is no implicit reference conversion from 'object' to 'CrashTest.Crash<object>.AbstractClass'.
// AbstractClass Test()
Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedRefType, "Test").WithArguments("CrashTest.Crash<T>", "CrashTest.Crash<object>.AbstractClass", "T", "object").WithLocation(21, 23)
);
}
[Fact, WorkItem(5697, "https://github.com/dotnet/roslyn/issues/5697")]
public void InheritThroughStaticImportOfGenericTypeWithConstraint_03()
{
var text =
@"
using static CrashTest.Crash<CrashTest.Class2>;
namespace CrashTest
{
[System.Obsolete]
class Class2 : AbstractClass
{
}
[System.Obsolete]
public static class Crash<T>
where T: Crash<T>.AbstractClass
{
public abstract class AbstractClass
{
public int Id { get; set; }
}
}
}";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics(
// (2,30): warning CS0612: 'Class2' is obsolete
// using static CrashTest.Crash<CrashTest.Class2>;
Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "CrashTest.Class2").WithArguments("CrashTest.Class2").WithLocation(2, 30),
// (2,14): warning CS0612: 'Crash<Class2>' is obsolete
// using static CrashTest.Crash<CrashTest.Class2>;
Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "CrashTest.Crash<CrashTest.Class2>").WithArguments("CrashTest.Crash<CrashTest.Class2>").WithLocation(2, 14));
}
[Fact, WorkItem(5697, "https://github.com/dotnet/roslyn/issues/5697")]
public void InheritThroughStaticImportOfGenericTypeWithConstraint_04()
{
var text =
@"
using static CrashTest.Crash<CrashTest.Class2>;
namespace CrashTest
{
class Class2 : AbstractClass
{
}
public static class Crash<T>
where T: Crash<T>.AbstractClass
{
[System.Obsolete]
public abstract class AbstractClass
{
public int Id { get; set; }
}
}
}";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics(
// (11,18): warning CS0612: 'Crash<T>.AbstractClass' is obsolete
// where T: Crash<T>.AbstractClass
Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "Crash<T>.AbstractClass").WithArguments("CrashTest.Crash<T>.AbstractClass").WithLocation(11, 18),
// (6,20): warning CS0612: 'Crash<Class2>.AbstractClass' is obsolete
// class Class2 : AbstractClass
Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "AbstractClass").WithArguments("CrashTest.Crash<CrashTest.Class2>.AbstractClass").WithLocation(6, 20)
);
}
[Fact, WorkItem(5697, "https://github.com/dotnet/roslyn/issues/5697")]
public void InheritThroughStaticImportOfGenericTypeWithConstraint_05()
{
var text =
@"
using CrashTest.Crash<CrashTest.Class2>;
namespace CrashTest
{
class Class2 : AbstractClass
{
}
public static class Crash<T>
where T: Crash<T>.AbstractClass
{
public abstract class AbstractClass
{
public int Id { get; set; }
}
}
}";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics(
// (2,7): error CS0138: A 'using namespace' directive can only be applied to namespaces; 'Crash<Class2>' is a type not a namespace. Consider a 'using static' directive instead
// using CrashTest.Crash<CrashTest.Class2>;
Diagnostic(ErrorCode.ERR_BadUsingNamespace, "CrashTest.Crash<CrashTest.Class2>").WithArguments("CrashTest.Crash<CrashTest.Class2>").WithLocation(2, 7),
// (6,20): error CS0246: The type or namespace name 'AbstractClass' could not be found (are you missing a using directive or an assembly reference?)
// class Class2 : AbstractClass
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "AbstractClass").WithArguments("AbstractClass").WithLocation(6, 20),
// (2,1): hidden CS8019: Unnecessary using directive.
// using CrashTest.Crash<CrashTest.Class2>;
Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using CrashTest.Crash<CrashTest.Class2>;").WithLocation(2, 1)
);
}
[Fact]
[WorkItem(174789, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?_a=edit&id=174789")]
public void CycleTypeArgument()
{
var text =
@"class A<T>
{
internal class B { }
}
class Base
{
protected class C { }
private class D { }
}
class Derived : Base
{
class E : A<C>.B { }
class F : A<D>.B { }
}";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics(
// (13,17): error CS0122: 'Base.D' is inaccessible due to its protection level
// class F : A<D>.B { }
Diagnostic(ErrorCode.ERR_BadAccess, "D").WithArguments("Base.D").WithLocation(13, 17));
}
[Fact]
[WorkItem(174789, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?_a=edit&id=174789")]
public void CycleArray()
{
var text =
@"class A<T>
{
internal class B { }
}
class Base
{
protected class C { }
private class D { }
}
class Derived : Base
{
class E : A<C[]>.B { }
class F : A<D[]>.B { }
}";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics(
// (13,17): error CS0122: 'Base.D' is inaccessible due to its protection level
// class F : A<D>.B { }
Diagnostic(ErrorCode.ERR_BadAccess, "D").WithArguments("Base.D").WithLocation(13, 17));
}
[Fact, WorkItem("https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?_a=edit&id=174789")]
public void CyclePointer()
{
var text =
@"class A<T>
{
internal class B { }
}
class Base
{
protected class C { }
private class D { }
}
class Derived : Base
{
class E : A<C*>.B { }
class F : A<D*>.B { }
}";
var comp = CreateCompilation(text, parseOptions: TestOptions.Regular11);
comp.VerifyDiagnostics(
// (13,17): error CS0122: 'Base.D' is inaccessible due to its protection level
// class F : A<D*>.B { }
Diagnostic(ErrorCode.ERR_BadAccess, "D").WithArguments("Base.D").WithLocation(13, 17),
// (13,11): error CS0306: The type 'Base.D*' may not be used as a type argument
// class F : A<D*>.B { }
Diagnostic(ErrorCode.ERR_BadTypeArgument, "F").WithArguments("Base.D*").WithLocation(13, 11),
// (13,11): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('Base.D')
// class F : A<D*>.B { }
Diagnostic(ErrorCode.WRN_ManagedAddr, "F").WithArguments("Base.D").WithLocation(13, 11),
// (12,11): error CS0306: The type 'Base.C*' may not be used as a type argument
// class E : A<C*>.B { }
Diagnostic(ErrorCode.ERR_BadTypeArgument, "E").WithArguments("Base.C*").WithLocation(12, 11),
// (12,11): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('Base.C')
// class E : A<C*>.B { }
Diagnostic(ErrorCode.WRN_ManagedAddr, "E").WithArguments("Base.C").WithLocation(12, 11));
}
[Fact, WorkItem("https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?_a=edit&id=174789")]
public void CyclePointer_UnsafeContext()
{
var text =
@"class A<T>
{
internal class B { }
}
class Base
{
protected class C { }
private class D { }
}
unsafe class Derived : Base
{
class E : A<C*>.B { }
class F : A<D*>.B { }
}";
var comp = CreateCompilation(text, parseOptions: TestOptions.Regular12);
comp.VerifyDiagnostics(
// (10,14): error CS0227: Unsafe code may only appear if compiling with /unsafe
// unsafe class Derived : Base
Diagnostic(ErrorCode.ERR_IllegalUnsafe, "Derived").WithLocation(10, 14),
// (13,17): error CS0122: 'Base.D' is inaccessible due to its protection level
// class F : A<D*>.B { }
Diagnostic(ErrorCode.ERR_BadAccess, "D").WithArguments("Base.D").WithLocation(13, 17),
// (13,11): error CS0306: The type 'Base.D*' may not be used as a type argument
// class F : A<D*>.B { }
Diagnostic(ErrorCode.ERR_BadTypeArgument, "F").WithArguments("Base.D*").WithLocation(13, 11),
// (13,11): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('Base.D')
// class F : A<D*>.B { }
Diagnostic(ErrorCode.WRN_ManagedAddr, "F").WithArguments("Base.D").WithLocation(13, 11),
// (12,11): error CS0306: The type 'Base.C*' may not be used as a type argument
// class E : A<C*>.B { }
Diagnostic(ErrorCode.ERR_BadTypeArgument, "E").WithArguments("Base.C*").WithLocation(12, 11),
// (12,11): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('Base.C')
// class E : A<C*>.B { }
Diagnostic(ErrorCode.WRN_ManagedAddr, "E").WithArguments("Base.C").WithLocation(12, 11));
comp = CreateCompilation(text, options: TestOptions.UnsafeDebugDll, parseOptions: TestOptions.Regular12);
comp.VerifyDiagnostics(
// (13,17): error CS0122: 'Base.D' is inaccessible due to its protection level
// class F : A<D*>.B { }
Diagnostic(ErrorCode.ERR_BadAccess, "D").WithArguments("Base.D").WithLocation(13, 17),
// (13,11): error CS0306: The type 'Base.D*' may not be used as a type argument
// class F : A<D*>.B { }
Diagnostic(ErrorCode.ERR_BadTypeArgument, "F").WithArguments("Base.D*").WithLocation(13, 11),
// (13,11): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('Base.D')
// class F : A<D*>.B { }
Diagnostic(ErrorCode.WRN_ManagedAddr, "F").WithArguments("Base.D").WithLocation(13, 11),
// (12,11): error CS0306: The type 'Base.C*' may not be used as a type argument
// class E : A<C*>.B { }
Diagnostic(ErrorCode.ERR_BadTypeArgument, "E").WithArguments("Base.C*").WithLocation(12, 11),
// (12,11): warning CS8500: This takes the address of, gets the size of, or declares a pointer to a managed type ('Base.C')
// class E : A<C*>.B { }
Diagnostic(ErrorCode.WRN_ManagedAddr, "E").WithArguments("Base.C").WithLocation(12, 11));
}
[Fact]
[WorkItem(1107185, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1107185")]
public void Tuple_MissingNestedTypeArgument_01()
{
var source =
@"interface I<T>
{
}
class A : I<(object, A.B)>
{
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (4,24): error CS0146: Circular base type dependency involving 'A' and 'A'
// class A : I<(object, A.B)>
Diagnostic(ErrorCode.ERR_CircularBase, "B").WithArguments("A", "A").WithLocation(4, 24));
}
[Fact]
[WorkItem(1107185, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1107185")]
public void Tuple_MissingNestedTypeArgument_02()
{
var source =
@"class A<T>
{
}
class B : A<(object, B.C)>
{
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (4,24): error CS0146: Circular base type dependency involving 'B' and 'B'
// class B : A<(object, B.C)>
Diagnostic(ErrorCode.ERR_CircularBase, "C").WithArguments("B", "B").WithLocation(4, 24));
}
[Fact]
public void Tuple_MissingNestedTypeArgument_03()
{
var source =
@"interface I<T>
{
}
class A : I<System.ValueTuple<object, A.B>>
{
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (4,41): error CS0146: Circular base type dependency involving 'A' and 'A'
// class A : I<System.ValueTuple<object, A.B>>
Diagnostic(ErrorCode.ERR_CircularBase, "B").WithArguments("A", "A").WithLocation(4, 41));
}
}
}
|