提交 9faaab10 编写于 作者: L Llewellyn Pritchard

Fix #7878 for interfaces

上级 71d47927
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities; using Roslyn.Utilities;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.CodeAnalysis.Collections;
namespace Microsoft.CodeAnalysis.CSharp.Symbols namespace Microsoft.CodeAnalysis.CSharp.Symbols
{ {
...@@ -226,6 +227,7 @@ internal override ImmutableArray<NamedTypeSymbol> GetDeclaredInterfaces(ConsList ...@@ -226,6 +227,7 @@ internal override ImmutableArray<NamedTypeSymbol> GetDeclaredInterfaces(ConsList
NamedTypeSymbol baseType = null; NamedTypeSymbol baseType = null;
SourceLocation baseTypeLocation = null; SourceLocation baseTypeLocation = null;
var interfaceLocations = PooledDictionary<NamedTypeSymbol, SourceLocation>.GetInstance();
foreach (var decl in this.declaration.Declarations) foreach (var decl in this.declaration.Declarations)
{ {
...@@ -258,34 +260,32 @@ internal override ImmutableArray<NamedTypeSymbol> GetDeclaredInterfaces(ConsList ...@@ -258,34 +260,32 @@ internal override ImmutableArray<NamedTypeSymbol> GetDeclaredInterfaces(ConsList
} }
} }
int n = baseInterfaces.Count; foreach (var t in partInterfaces)
foreach (var t in partInterfaces) // this could probably be done more efficiently with a side hash table if it proves necessary
{ {
for (int i = 0; i < n; i++) if (!interfaceLocations.ContainsKey(t))
{ {
if (t == baseInterfaces[i]) baseInterfaces.Add(t);
{ interfaceLocations.Add(t, decl.NameLocation);
goto alreadyInInterfaceList;
}
} }
baseInterfaces.Add(t);
alreadyInInterfaceList:;
} }
} }
if ((object)baseType != null && baseType.IsStatic)
{
// '{1}': cannot derive from static class '{0}'
diagnostics.Add(ErrorCode.ERR_StaticBaseClass, baseTypeLocation ?? Locations[0], baseType, this);
}
HashSet<DiagnosticInfo> useSiteDiagnostics = null; HashSet<DiagnosticInfo> useSiteDiagnostics = null;
if ((object)baseType != null && !this.IsNoMoreVisibleThan(baseType, ref useSiteDiagnostics)) if ((object)baseType != null)
{ {
// Inconsistent accessibility: base class '{1}' is less accessible than class '{0}' Debug.Assert(baseTypeLocation != null);
diagnostics.Add(ErrorCode.ERR_BadVisBaseClass, baseTypeLocation ?? Locations[0], this, baseType); if (baseType.IsStatic)
{
// '{1}': cannot derive from static class '{0}'
diagnostics.Add(ErrorCode.ERR_StaticBaseClass, baseTypeLocation, baseType, this);
}
if (!this.IsNoMoreVisibleThan(baseType, ref useSiteDiagnostics))
{
// Inconsistent accessibility: base class '{1}' is less accessible than class '{0}'
diagnostics.Add(ErrorCode.ERR_BadVisBaseClass, baseTypeLocation, this, baseType);
}
} }
var baseInterfacesRO = baseInterfaces.ToImmutableAndFree(); var baseInterfacesRO = baseInterfaces.ToImmutableAndFree();
...@@ -296,11 +296,13 @@ internal override ImmutableArray<NamedTypeSymbol> GetDeclaredInterfaces(ConsList ...@@ -296,11 +296,13 @@ internal override ImmutableArray<NamedTypeSymbol> GetDeclaredInterfaces(ConsList
if (!i.IsAtLeastAsVisibleAs(this, ref useSiteDiagnostics)) if (!i.IsAtLeastAsVisibleAs(this, ref useSiteDiagnostics))
{ {
// Inconsistent accessibility: base interface '{1}' is less accessible than interface '{0}' // Inconsistent accessibility: base interface '{1}' is less accessible than interface '{0}'
diagnostics.Add(ErrorCode.ERR_BadVisBaseInterface, Locations[0], this, i); diagnostics.Add(ErrorCode.ERR_BadVisBaseInterface, interfaceLocations[i], this, i);
} }
} }
} }
interfaceLocations.Free();
diagnostics.Add(Locations[0], useSiteDiagnostics); diagnostics.Add(Locations[0], useSiteDiagnostics);
return new Tuple<NamedTypeSymbol, ImmutableArray<NamedTypeSymbol>>(baseType, baseInterfacesRO); return new Tuple<NamedTypeSymbol, ImmutableArray<NamedTypeSymbol>>(baseType, baseInterfacesRO);
......
...@@ -395,6 +395,54 @@ public partial class C1 ...@@ -395,6 +395,54 @@ public partial class C1
Diagnostic(ErrorCode.ERR_BadVisBaseClass, "C1").WithArguments("C1", "NV").WithLocation(10, 15)); 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 IFoo
{
void Moo();
}
interface IBaz
{
void Noo();
}
interface IBam
{
void Zoo();
}
public partial interface IBar
{
}
partial interface IBar : IFoo, IBam
{
}
partial interface IBar : IBaz, IBaz
{
}
";
var comp = CreateCompilationWithMscorlib(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 'IFoo' is less accessible than interface 'IBar'
// partial interface IBar : IFoo, IBam
Diagnostic(ErrorCode.ERR_BadVisBaseInterface, "IBar").WithArguments("IBar", "IFoo").WithLocation(21, 19),
// (21,19): error CS0061: Inconsistent accessibility: base interface 'IBam' is less accessible than interface 'IBar'
// partial interface IBar : IFoo, 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] [Fact]
public void EricLiCase1() public void EricLiCase1()
{ {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册