public override object VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, object data)
        {
            ExpressionStatement stmt = constructorDeclaration.Body.Statements.FirstOrDefault() as ExpressionStatement;

            if (stmt == null)
            {
                return(null);
            }
            InvocationExpression invocation = stmt.Expression as InvocationExpression;

            if (invocation == null)
            {
                return(null);
            }
            MemberReferenceExpression mre = invocation.Target as MemberReferenceExpression;

            if (mre != null && mre.MemberName == ".ctor")
            {
                ConstructorInitializer ci = new ConstructorInitializer();
                if (mre.Target is ThisReferenceExpression)
                {
                    ci.ConstructorInitializerType = ConstructorInitializerType.This;
                }
                else if (mre.Target is BaseReferenceExpression)
                {
                    ci.ConstructorInitializerType = ConstructorInitializerType.Base;
                }
                else
                {
                    return(null);
                }
                // Move arguments from invocation to initializer:
                invocation.Arguments.MoveTo(ci.Arguments);
                var ilRanges = stmt.GetAllRecursiveILRanges();
                // Add the initializer: (unless it is the default 'base()')
                if (!(ci.ConstructorInitializerType == ConstructorInitializerType.Base && ci.Arguments.Count == 0))
                {
                    constructorDeclaration.Initializer = ci.WithAnnotation(invocation.Annotation <IMethod>());
                    ci.AddAnnotation(ilRanges);
                }
                else
                {
                    constructorDeclaration.Body.HiddenStart = NRefactoryExtensions.CreateHidden(ilRanges, constructorDeclaration.Body.HiddenStart);
                }
                // Remove the statement:
                stmt.Remove();
            }
            return(null);
        }
Ejemplo n.º 2
0
 public void Run(AstNode node)
 {
     Run(node, null);
     // Declare all the variables at the end, after all the logic has run.
     // This is done so that definite assignment analysis can work on a single representation and doesn't have to be updated
     // when we change the AST.
     foreach (var v in variablesToDeclare)
     {
         if (v.ReplacedAssignment == null)
         {
             BlockStatement block = (BlockStatement)v.InsertionPoint.Parent;
             var            decl  = new VariableDeclarationStatement(v.ILVariable != null && v.ILVariable.IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local, (AstType)v.Type.Clone(), v.Name);
             if (v.ILVariable != null)
             {
                 decl.Variables.Single().AddAnnotation(v.ILVariable);
             }
             block.Statements.InsertBefore(
                 v.InsertionPoint,
                 decl);
         }
     }
     // First do all the insertions, then do all the replacements. This is necessary because a replacement might remove our reference point from the AST.
     foreach (var v in variablesToDeclare)
     {
         if (v.ReplacedAssignment != null)
         {
             // We clone the right expression so that it doesn't get removed from the old ExpressionStatement,
             // which might be still in use by the definite assignment graph.
             VariableInitializer          initializer = new VariableInitializer(v.ILVariable != null && v.ILVariable.IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local, v.Name, v.ReplacedAssignment.Right.Detach()).CopyAnnotationsFrom(v.ReplacedAssignment).WithAnnotation(v.ILVariable);
             VariableDeclarationStatement varDecl     = new VariableDeclarationStatement {
                 Type      = (AstType)v.Type.Clone(),
                 Variables = { initializer }
             };
             ExpressionStatement es = v.ReplacedAssignment.Parent as ExpressionStatement;
             if (es != null)
             {
                 // Note: if this crashes with 'Cannot replace the root node', check whether two variables were assigned the same name
                 es.ReplaceWith(varDecl.CopyAnnotationsFrom(es));
                 varDecl.AddAnnotation(es.GetAllRecursiveILRanges());
             }
             else
             {
                 varDecl.AddAnnotation(v.ReplacedAssignment.GetAllRecursiveILRanges());
                 v.ReplacedAssignment.ReplaceWith(varDecl);
             }
         }
     }
     variablesToDeclare.Clear();
 }