示例#1
0
 public override void VisitConstructorDeclaration(ConstructorDeclaration d)
 {
     if (d.Modifiers.HasFlag(Modifiers.Private) || d.Modifiers.HasFlag(Modifiers.Static) || d.Modifiers.HasFlag(Modifiers.Internal))
     {
         d.Remove();
     }
     else
     {
         RemoveAttributes(d.Attributes);
         base.VisitConstructorDeclaration(d);
     }
 }
示例#2
0
 public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
 {
     if (constructorDeclaration.IsPublic())
     {
         base.VisitConstructorDeclaration(constructorDeclaration);
         constructorDeclaration.Body = null;
     }
     else
     {
         constructorDeclaration.Remove();
     }
 }
            public void Run(AstNode compilationUnit)
            {
                ConstructorDeclaration ctorDecl = null;

                foreach (var node in compilationUnit.Children)
                {
                    ConstructorDeclaration ctor = node as ConstructorDeclaration;
                    if (ctor != null)
                    {
                        if (ctor.Annotation <MethodDefinition>() == ctorDef)
                        {
                            ctorDecl = ctor;
                        }
                        else
                        {
                            // remove other ctors
                            ctor.Remove();
                        }
                    }


                    // Remove any fields without initializers
                    FieldDeclaration fd = node as FieldDeclaration;
                    if (fd != null && fd.Variables.All(v => v.Initializer.IsNull))
                    {
                        fd.Remove();
                    }
                }
                if (ctorDecl.Initializer.ConstructorInitializerType == ConstructorInitializerType.This)
                {
                    // remove all fields
                    foreach (var node in compilationUnit.Children)
                    {
                        if (node is FieldDeclaration)
                        {
                            node.Remove();
                        }
                    }
                }
            }
        public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
        {
            if (!(constructorDeclaration.Body.Statements.FirstOrDefault() is ExpressionStatement stmt))
            {
                return;
            }
            var currentCtor = (IMethod)constructorDeclaration.GetSymbol();
            ConstructorInitializer ci;

            switch (stmt.Expression)
            {
            // Pattern for reference types:
            // this..ctor(...);
            case InvocationExpression invocation:
                if (!(invocation.Target is MemberReferenceExpression mre) || mre.MemberName != ".ctor")
                {
                    return;
                }
                if (!(invocation.GetSymbol() is IMethod ctor && ctor.IsConstructor))
                {
                    return;
                }
                ci = new ConstructorInitializer();
                var target = mre.Target;
                // Ignore casts, those might be added if references are missing.
                if (target is CastExpression cast)
                {
                    target = cast.Expression;
                }
                if (target is ThisReferenceExpression)
                {
                    ci.ConstructorInitializerType = ConstructorInitializerType.This;
                }
                else if (target is BaseReferenceExpression)
                {
                    ci.ConstructorInitializerType = ConstructorInitializerType.Base;
                }
                else
                {
                    return;
                }
                // Move arguments from invocation to initializer:
                invocation.Arguments.MoveTo(ci.Arguments);
                // Add the initializer: (unless it is the default 'base()')
                if (!(ci.ConstructorInitializerType == ConstructorInitializerType.Base && ci.Arguments.Count == 0))
                {
                    constructorDeclaration.Initializer = ci.CopyAnnotationsFrom(invocation);
                }
                // Remove the statement:
                stmt.Remove();
                break;

            // Pattern for value types:
            // this = new TSelf(...);
            case AssignmentExpression assignment:
                if (!(assignment.Right is ObjectCreateExpression oce && oce.GetSymbol() is IMethod ctor2 && ctor2.DeclaringTypeDefinition == currentCtor.DeclaringTypeDefinition))
                {
                    return;
                }
                ci = new ConstructorInitializer();
                if (assignment.Left is ThisReferenceExpression)
                {
                    ci.ConstructorInitializerType = ConstructorInitializerType.This;
                }
                else
                {
                    return;
                }
                // Move arguments from invocation to initializer:
                oce.Arguments.MoveTo(ci.Arguments);
                // Add the initializer: (unless it is the default 'base()')
                if (!(ci.ConstructorInitializerType == ConstructorInitializerType.Base && ci.Arguments.Count == 0))
                {
                    constructorDeclaration.Initializer = ci.CopyAnnotationsFrom(oce);
                }
                // Remove the statement:
                stmt.Remove();
                break;

            default:
                return;
            }
            if (context.DecompileRun.RecordDecompilers.TryGetValue(currentCtor.DeclaringTypeDefinition, out var record) &&
                currentCtor.Equals(record.PrimaryConstructor) &&
                ci.ConstructorInitializerType == ConstructorInitializerType.Base)
            {
                if (constructorDeclaration.Parent is TypeDeclaration {
                    BaseTypes : { Count : >= 1 }
                } typeDecl)
                {
                    var baseType    = typeDecl.BaseTypes.First();
                    var newBaseType = new InvocationAstType();
                    baseType.ReplaceWith(newBaseType);
                    newBaseType.BaseType = baseType;
                    ci.Arguments.MoveTo(newBaseType.Arguments);
                }
                constructorDeclaration.Remove();
            }
        }