1
using System.Collections.Generic;
3
using ICSharpCode.NRefactory.Semantics;
4
using ICSharpCode.NRefactory.TypeSystem;
5
using ICSharpCode.NRefactory.CSharp.Resolver;
7
namespace ICSharpCode.NRefactory.CSharp.Refactoring
9
[IssueDescription ("CS1729: Base class does not contain a 0 argument constructor",
10
Description = "CS1729: Base class does not contain a 0 argument constructor",
11
Category = IssueCategories.CompilerErrors,
12
Severity = Severity.Error,
13
IssueMarker = IssueMarker.Underline)]
14
public class NoDefaultConstructorIssue : ICodeIssueProvider
16
public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
18
return new GatherVisitor(context).GetIssues();
21
private class GatherVisitor : GatherVisitorBase<NoDefaultConstructorIssue>
23
private bool initializerInvoked;
24
private ConstructorInitializer initializer;
26
public GatherVisitor(BaseRefactoringContext context)
31
public override void VisitTypeDeclaration(TypeDeclaration declaration)
33
var result = ctx.Resolve(declaration) as TypeResolveResult;
34
var baseType = result.Type.DirectBaseTypes.FirstOrDefault(t => !t.IsKnownType(KnownTypeCode.Object) && t.Kind != TypeKind.Interface);
38
var baseConstructor = baseType.GetConstructors(c => c.Parameters.Count == 0).FirstOrDefault();
39
var memberLookup = new MemberLookup(result.Type.GetDefinition(), ctx.Compilation.MainAssembly, false);
41
if (baseConstructor == null || !memberLookup.IsAccessible(baseConstructor, true)) {
42
var constructor = result.Type.GetConstructors(f => !f.IsSynthetic).FirstOrDefault();
44
if (constructor == null) {
45
// If there are no constructors declared then the base constructor isn't being invoked
46
this.AddIssue(declaration, baseType);
51
base.VisitTypeDeclaration(declaration);
54
public override void VisitConstructorDeclaration(ConstructorDeclaration declaration)
56
var result = ctx.Resolve(declaration) as MemberResolveResult;
57
if (result == null || result.IsError)
60
var baseType = result.Member.DeclaringType.DirectBaseTypes.FirstOrDefault(t => !t.IsKnownType(KnownTypeCode.Object) && t.Kind != TypeKind.Interface);
62
if (baseType != null) {
63
var baseConstructor = baseType.GetConstructors(c => c.Parameters.Count == 0).FirstOrDefault();
64
var memberLookup = new MemberLookup(result.Member.DeclaringType.GetDefinition(), ctx.Compilation.MainAssembly, false);
66
if (baseConstructor == null || !memberLookup.IsAccessible(baseConstructor, true)) {
67
this.initializerInvoked = false;
68
this.initializer = null;
70
base.VisitConstructorDeclaration(declaration);
72
if (!this.initializerInvoked) {
73
int argumentCount = initializer != null ? initializer.Arguments.Count : 0;
74
this.AddIssue(declaration, baseType, argumentCount);
80
public override void VisitConstructorInitializer(ConstructorInitializer initializer)
82
var result = ctx.Resolve(initializer);
84
if (!result.IsError) {
85
this.initializerInvoked = true;
87
this.initializer = initializer;
91
private void AddIssue(AstNode node, IType baseType, int argumentCount = 0)
93
var identifier = node.GetChildByRole(Roles.Identifier);
96
string.Format(ctx.TranslateString("CS1729: The type '{0}' does not contain a constructor that takes '{1}' arguments"), baseType.Name, argumentCount));