Browse Source

[CodeIssues] Updating the NoDefaultConstructorIssue to take into account multiple constructors in the child class. If no constructors are defined in the child, the issue is put against the class identifier, whereas if constructors are defined, the issue is put against each constructor that has an issue.

pull/32/merge
Adam Connelly 13 years ago
parent
commit
aba167fa4c
  1. 39
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/NoDefaultConstructorIssue.cs
  2. 18
      ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/NoDefaultConstructorIssueTests.cs

39
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/NoDefaultConstructorIssue.cs

@ -26,34 +26,53 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -26,34 +26,53 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
}
public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
public override void VisitTypeDeclaration(TypeDeclaration declaration)
{
var result = ctx.Resolve(typeDeclaration) as TypeResolveResult;
var result = ctx.Resolve(declaration) as TypeResolveResult;
var baseType = result.Type.GetNonInterfaceBaseTypes().FirstOrDefault(t => !t.IsKnownType(KnownTypeCode.Object) && !object.Equals(t, result.Type));
if (baseType != null)
{
var constructor = baseType.GetConstructors(c => c.Parameters.Count == 0).FirstOrDefault();
var baseConstructor = baseType.GetConstructors(c => c.Parameters.Count == 0).FirstOrDefault();
if (constructor == null) {
base.VisitTypeDeclaration(typeDeclaration);
if (baseConstructor == null) {
var constructor = result.Type.GetConstructors(f => !f.IsSynthetic).FirstOrDefault();
if (!this.initializerInvoked) {
var identifier = typeDeclaration.GetChildByRole(Roles.Identifier);
this.AddIssue(identifier, ctx.TranslateString("There is no default constructor in the base class"));
if (constructor == null) {
// If there are no constructors declared then the base constructor isn't being invoked
this.AddIssue(declaration);
} else {
base.VisitTypeDeclaration(declaration);
}
}
}
}
public override void VisitConstructorInitializer(ConstructorInitializer constructorInitializer)
public override void VisitConstructorDeclaration(ConstructorDeclaration declaration)
{
var result = ctx.Resolve(constructorInitializer);
this.initializerInvoked = false;
base.VisitConstructorDeclaration(declaration);
if (!this.initializerInvoked) {
this.AddIssue(declaration);
}
}
public override void VisitConstructorInitializer(ConstructorInitializer initializer)
{
var result = ctx.Resolve(initializer);
if (!result.IsError) {
this.initializerInvoked = true;
}
}
private void AddIssue(AstNode node)
{
var identifier = node.GetChildByRole(Roles.Identifier);
this.AddIssue(identifier, ctx.TranslateString("There is no default constructor in the base class"));
}
}
}
}

18
ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/NoDefaultConstructorIssueTests.cs

@ -82,6 +82,24 @@ class ChildClass : BaseClass @@ -82,6 +82,24 @@ class ChildClass : BaseClass
Test<NoDefaultConstructorIssue>(testInput, 0);
}
[Test]
public void ShouldMakeSureAllConstructorsInvokeBaseConstructor()
{
var testInput =
@"class BaseClass
{
public BaseClass(string test) {}
}
class ChildClass : BaseClass
{
public ChildClass() : base(""test"") {}
public ChildClass(string test) {}
}";
Test<NoDefaultConstructorIssue>(testInput, 1);
}
}
}

Loading…
Cancel
Save