提交 560736db 编写于 作者: A AlekseyTs

Report an error if an argument list is provided for an implemented interface....

Report an error if an argument list is provided for an implemented interface. Fixes https://roslyn.codeplex.com/workitem/4. This is a port of https://roslyn.codeplex.com/SourceControl/changeset/f930b49714dc268a0e9df96d213d5516634a6450. (changeset 1250419)
上级 2c899e44
......@@ -4452,6 +4452,15 @@ internal class CSharpResources {
}
}
/// <summary>
/// Looks up a localized string similar to Implemented interface cannot have arguments..
/// </summary>
internal static string ERR_ImplementedInterfaceWithArguments {
get {
return ResourceManager.GetString("ERR_ImplementedInterfaceWithArguments", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to No best type found for implicitly-typed array.
/// </summary>
......
......@@ -3813,4 +3813,7 @@
<data name="ERR_RefOutParameterWithFieldModifier" xml:space="preserve">
<value>A ref or out parameter cannot have any field modifiers.</value>
</data>
<data name="ERR_ImplementedInterfaceWithArguments" xml:space="preserve">
<value>Implemented interface cannot have arguments.</value>
</data>
</root>
\ No newline at end of file
......@@ -1242,40 +1242,41 @@ private static BoundBlock BindMethodBody(MethodSymbol method, TypeCompilationSta
var blockSyntax = sourceMethod.BlockSyntax;
if (blockSyntax != null)
{
var factory = compilation.GetBinderFactory(sourceMethod.SyntaxTree);
var inMethodBinder = factory.GetBinder(blockSyntax);
var binder = new ExecutableCodeBinder(blockSyntax, sourceMethod, inMethodBinder);
body = binder.BindBlock(blockSyntax, diagnostics);
if (generateDebugInfo)
{
debugImports = binder.ImportsList;
}
if (inMethodBinder.IsDirectlyInIterator)
{
foreach (var parameter in method.Parameters)
var factory = compilation.GetBinderFactory(sourceMethod.SyntaxTree);
var inMethodBinder = factory.GetBinder(blockSyntax);
var binder = new ExecutableCodeBinder(blockSyntax, sourceMethod, inMethodBinder);
body = binder.BindBlock(blockSyntax, diagnostics);
if (generateDebugInfo)
{
if (parameter.RefKind != RefKind.None)
debugImports = binder.ImportsList;
}
if (inMethodBinder.IsDirectlyInIterator)
{
foreach (var parameter in method.Parameters)
{
diagnostics.Add(ErrorCode.ERR_BadIteratorArgType, parameter.Locations[0]);
if (parameter.RefKind != RefKind.None)
{
diagnostics.Add(ErrorCode.ERR_BadIteratorArgType, parameter.Locations[0]);
}
else if (parameter.Type.IsUnsafe())
{
diagnostics.Add(ErrorCode.ERR_UnsafeIteratorArgType, parameter.Locations[0]);
}
}
else if (parameter.Type.IsUnsafe())
if (sourceMethod.IsUnsafe && compilation.Options.AllowUnsafe) // Don't cascade
{
diagnostics.Add(ErrorCode.ERR_UnsafeIteratorArgType, parameter.Locations[0]);
diagnostics.Add(ErrorCode.ERR_IllegalInnerUnsafe, sourceMethod.Locations[0]);
}
}
if (sourceMethod.IsUnsafe && compilation.Options.AllowUnsafe) // Don't cascade
{
diagnostics.Add(ErrorCode.ERR_IllegalInnerUnsafe, sourceMethod.Locations[0]);
}
if (sourceMethod.IsVararg)
{
// error CS1636: __arglist is not allowed in the parameter list of iterators
diagnostics.Add(ErrorCode.ERR_VarargsIterator, sourceMethod.Locations[0]);
if (sourceMethod.IsVararg)
{
// error CS1636: __arglist is not allowed in the parameter list of iterators
diagnostics.Add(ErrorCode.ERR_VarargsIterator, sourceMethod.Locations[0]);
}
}
}
}
else // for [if (blockSyntax != null)]
{
var property = sourceMethod.AssociatedSymbol as SourcePropertySymbol;
......@@ -1426,8 +1427,18 @@ private static BoundExpression BindConstructorInitializer(MethodSymbol construct
TypeSyntax baseTypeSyntax = classDecl.BaseList.Types[0];
if (baseTypeSyntax.Kind == SyntaxKind.BaseClassWithArguments)
{
initializerArgumentListOpt = ((BaseClassWithArgumentsSyntax)baseTypeSyntax).ArgumentList;
}
var baseBinder = compilation.GetBinder(classDecl.BaseList);
baseBinder = baseBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, constructor.ContainingType);
var baseClassWithArguments = (BaseClassWithArgumentsSyntax)baseTypeSyntax;
TypeSymbol targetType = baseBinder.BindType(baseClassWithArguments.BaseClass, new DiagnosticBag());
// If types are different, an error has been reported elsewhere.
if (!targetType.IsErrorType() && baseType == targetType)
{
initializerArgumentListOpt = baseClassWithArguments.ArgumentList;
}
}
}
}
else
......
......@@ -1275,6 +1275,8 @@ internal enum ErrorCode
ERR_DeclarationExpressionOutsideOfAMethodBody = 8047,
ERR_VariableUsedInTheSameArgumentList = 8048,
ERR_ImplementedInterfaceWithArguments = 8049,
// Values in the range 10000-14000 are used for "Code Analysis" issues previously reported by FXCop
WRN_CA2000_DisposeObjectsBeforeLosingScope1 = 10000,
WRN_CA2000_DisposeObjectsBeforeLosingScope2 = 10001,
......
......@@ -342,6 +342,11 @@ private static BaseListSyntax GetBaseListOpt(SingleTypeDeclaration decl)
TypeSyntax baseClass = ((BaseClassWithArgumentsSyntax)typeSyntax).BaseClass;
location = new SourceLocation(baseClass);
baseType = baseBinder.BindType(baseClass, diagnostics, newBasesBeingResolved);
if (baseType.TypeKind == TypeKind.Interface)
{
diagnostics.Add(ErrorCode.ERR_ImplementedInterfaceWithArguments, ((BaseClassWithArgumentsSyntax)typeSyntax).ArgumentList.GetLocation());
}
}
else
{
......
......@@ -731,7 +731,7 @@ static class Derived(int x)
}
[Fact]
public void Class8()
public void Class8_01()
{
var comp = CreateCompilationWithMscorlib(@"
class Base(int x)
......@@ -749,10 +749,43 @@ partial class Derived(int x) : Base(y)
comp.VerifyDiagnostics(
// (6,15): error CS0263: Partial declarations of 'Derived' must not specify different base classes
// partial class Derived : object
Diagnostic(ErrorCode.ERR_PartialMultipleBases, "Derived").WithArguments("Derived"),
// (9,37): error CS0103: The name 'y' does not exist in the current context
// partial class Derived(int x) : Base(y)
Diagnostic(ErrorCode.ERR_NameNotInContext, "y").WithArguments("y")
Diagnostic(ErrorCode.ERR_PartialMultipleBases, "Derived").WithArguments("Derived")
);
}
[Fact]
public void Class8_02()
{
var comp = CreateCompilationWithMscorlib(@"
class Base1(int x)
{
}
class Base2
{}
partial class Derived1(int x) : Base1(y)
{
}
partial class Derived1 : Base2
{}
partial class Derived2 : Base2
{}
partial class Derived2(int x) : Base1(y)
{
}
", parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.Experimental));
comp.VerifyDiagnostics(
// (16,15): error CS0263: Partial declarations of 'Derived2' must not specify different base classes
// partial class Derived2 : Base2
Diagnostic(ErrorCode.ERR_PartialMultipleBases, "Derived2").WithArguments("Derived2").WithLocation(16, 15),
// (9,15): error CS0263: Partial declarations of 'Derived1' must not specify different base classes
// partial class Derived1(int x) : Base1(y)
Diagnostic(ErrorCode.ERR_PartialMultipleBases, "Derived1").WithArguments("Derived1").WithLocation(9, 15)
);
}
......@@ -3977,5 +4010,63 @@ class Derived<T>(private int v)
Assert.Equal(parameter, field.AssociatedSymbol);
}
[Fact, WorkItem(4)]
public void ArgumentsOnImplementedInterface_01()
{
var comp = CreateCompilationWithMscorlib(@"
using System;
class C1() : IDisposable()
{
public void Dispose() { }
}
class C2() : IDisposable(2)
{
public void Dispose() { }
}
", parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.Experimental));
comp.VerifyDiagnostics(
// (4,25): error CS9013: Implemented interface cannot have arguments.
// class C1() : IDisposable()
Diagnostic(ErrorCode.ERR_ImplementedInterfaceWithArguments, "()").WithLocation(4, 25),
// (9,25): error CS9013: Implemented interface cannot have arguments.
// class C2() : IDisposable(2)
Diagnostic(ErrorCode.ERR_ImplementedInterfaceWithArguments, "(2)").WithLocation(9, 25)
);
}
[Fact, WorkItem(4)]
public void ArgumentsOnImplementedInterface_02()
{
var comp = CreateCompilationWithMscorlib(@"
using System;
class Base
{
public Base(int x){}
}
partial class Derived : Base
{
}
partial class Derived() : IDisposable(2)
{
public void Dispose() { }
}
", parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.Experimental));
comp.VerifyDiagnostics(
// (13,38): error CS9013: Implemented interface cannot have arguments.
// partial class Derived() : IDisposable(2)
Diagnostic(ErrorCode.ERR_ImplementedInterfaceWithArguments, "(2)").WithLocation(13, 38),
// (13,22): error CS7036: There is no argument given that corresponds to the required formal parameter 'x' of 'Base.Base(int)'
// partial class Derived() : IDisposable(2)
Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "()").WithArguments("x", "Base.Base(int)").WithLocation(13, 22)
);
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册