コード例 #1
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);
        }