void RemoveSingleEmptyConstructor(TypeDeclaration typeDeclaration) { var instanceCtors = typeDeclaration.Members.OfType <ConstructorDeclaration>().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray(); if (instanceCtors.Length == 1) { ConstructorDeclaration emptyCtor = new ConstructorDeclaration(); emptyCtor.Modifiers = ((typeDeclaration.Modifiers & Modifiers.Abstract) == Modifiers.Abstract ? Modifiers.Protected : Modifiers.Public); emptyCtor.Body = new BlockStatement(); if (emptyCtor.IsMatch(instanceCtors[0])) { instanceCtors[0].Remove(); } } }
internal void RemoveSingleEmptyConstructor(IEnumerable <AstNode> members, ITypeDefinition contextTypeDefinition) { if (contextTypeDefinition == null) { return; } var instanceCtors = members.OfType <ConstructorDeclaration>().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray(); if (instanceCtors.Length == 1) { ConstructorDeclaration emptyCtor = new ConstructorDeclaration(); emptyCtor.Modifiers = contextTypeDefinition.IsAbstract ? Modifiers.Protected : Modifiers.Public; emptyCtor.Body = new BlockStatement(); if (emptyCtor.IsMatch(instanceCtors[0])) { instanceCtors[0].Remove(); } } }
void RemoveSingleEmptyConstructor(IEnumerable <AstNode> members, ITypeDefinition contextTypeDefinition) { // if we're outside of a type definition skip this altogether if (contextTypeDefinition == null) { return; } // first get non-static constructor declarations from the AST var instanceCtors = members.OfType <ConstructorDeclaration>().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray(); // if there's exactly one ctor and it's part of a type declaration or there's more than one member in the current selection // we can remove the constructor. (We do not want to hide the constructor if the user explicitly selected it in the tree view.) if (instanceCtors.Length == 1 && (instanceCtors[0].Parent is TypeDeclaration || members.Skip(1).Any())) { var ctor = instanceCtors[0]; // dynamically create a pattern of an empty ctor ConstructorDeclaration emptyCtorPattern = new ConstructorDeclaration(); emptyCtorPattern.Modifiers = contextTypeDefinition.IsAbstract ? Modifiers.Protected : Modifiers.Public; if (ctor.HasModifier(Modifiers.Unsafe)) { emptyCtorPattern.Modifiers |= Modifiers.Unsafe; } emptyCtorPattern.Body = new BlockStatement(); if (emptyCtorPattern.IsMatch(ctor)) { bool retainBecauseOfDocumentation = ctor.GetSymbol() is IMethod ctorMethod && context.Settings.ShowXmlDocumentation && context.DecompileRun.DocumentationProvider?.GetDocumentation(ctorMethod) != null; if (!retainBecauseOfDocumentation) { ctor.Remove(); } } } }
public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data) { var instanceCtors = typeDeclaration.Members.OfType <ConstructorDeclaration>().Where(c => (c.Modifiers & Modifiers.Static) == 0).ToArray(); var instanceCtorsNotChainingWithThis = instanceCtors.Where(ctor => !thisCallPattern.IsMatch(ctor.Body.Statements.FirstOrDefault())).ToArray(); if (instanceCtorsNotChainingWithThis.Length > 0 && typeDeclaration.ClassType == NRefactory.TypeSystem.ClassType.Class) { // Recognize field initializers: // Convert first statement in all ctors (if all ctors have the same statement) into a field initializer. bool allSame; do { Match m = fieldInitializerPattern.Match(instanceCtorsNotChainingWithThis[0].Body.FirstOrDefault()); if (!m.Success) { break; } FieldDefinition fieldDef = m.Get <AstNode>("fieldAccess").Single().Annotation <FieldReference>().ResolveWithinSameModule(); if (fieldDef == null) { break; } AttributedNode fieldOrEventDecl = typeDeclaration.Members.FirstOrDefault(f => f.Annotation <FieldDefinition>() == fieldDef); if (fieldOrEventDecl == null) { break; } allSame = true; for (int i = 1; i < instanceCtorsNotChainingWithThis.Length; i++) { if (!instanceCtors[0].Body.First().IsMatch(instanceCtorsNotChainingWithThis[i].Body.FirstOrDefault())) { allSame = false; } } if (allSame) { foreach (var ctor in instanceCtorsNotChainingWithThis) { ctor.Body.First().Remove(); } fieldOrEventDecl.GetChildrenByRole(AstNode.Roles.Variable).Single().Initializer = m.Get <Expression>("initializer").Single().Detach(); } } while (allSame); } // Now convert base constructor calls to initializers: base.VisitTypeDeclaration(typeDeclaration, data); // Remove single empty constructor: if (instanceCtors.Length == 1) { ConstructorDeclaration emptyCtor = new ConstructorDeclaration(); emptyCtor.Modifiers = ((typeDeclaration.Modifiers & Modifiers.Abstract) == Modifiers.Abstract ? Modifiers.Protected : Modifiers.Public); emptyCtor.Body = new BlockStatement(); if (emptyCtor.IsMatch(instanceCtors[0])) { instanceCtors[0].Remove(); } } // Convert static constructor into field initializers if the class is BeforeFieldInit var staticCtor = typeDeclaration.Members.OfType <ConstructorDeclaration>().FirstOrDefault(c => (c.Modifiers & Modifiers.Static) == Modifiers.Static); if (staticCtor != null) { TypeDefinition typeDef = typeDeclaration.Annotation <TypeDefinition>(); if (typeDef != null && typeDef.IsBeforeFieldInit) { while (true) { ExpressionStatement es = staticCtor.Body.Statements.FirstOrDefault() as ExpressionStatement; if (es == null) { break; } AssignmentExpression assignment = es.Expression as AssignmentExpression; if (assignment == null || assignment.Operator != AssignmentOperatorType.Assign) { break; } FieldDefinition fieldDef = assignment.Left.Annotation <FieldReference>().ResolveWithinSameModule(); if (fieldDef == null || !fieldDef.IsStatic) { break; } FieldDeclaration fieldDecl = typeDeclaration.Members.OfType <FieldDeclaration>().FirstOrDefault(f => f.Annotation <FieldDefinition>() == fieldDef); if (fieldDecl == null) { break; } fieldDecl.Variables.Single().Initializer = assignment.Right.Detach(); es.Remove(); } if (staticCtor.Body.Statements.Count == 0) { staticCtor.Remove(); } } } return(null); }