Ejemplo n.º 1
0
        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();
                }
            }
        }
Ejemplo n.º 2
0
        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();
                    }
                }
            }
        }
Ejemplo n.º 4
0
        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);
        }