Example #1
0
        public override List <Change> PerformChanges(RefactoringOptions options, object prop)
        {
            IResolver              resolver = options.GetResolver();
            List <Change>          result   = new List <Change> ();
            INRefactoryASTProvider provider = options.GetASTProvider();

            if (resolver == null || provider == null)
            {
                return(result);
            }

            TypeDeclaration newType = new TypeDeclaration(ICSharpCode.NRefactory.Ast.Modifiers.None, null);

            newType.Name = createExpression.CreateType.Type;
            newType.Type = GetNewTypeType();

            ConstructorDeclaration constructor = new ConstructorDeclaration(newType.Name, ICSharpCode.NRefactory.Ast.Modifiers.Public, null, null);

            constructor.Body = new BlockStatement();
            int i = 0;

            foreach (Expression expression in createExpression.Parameters)
            {
                i++;
                string output = provider.OutputNode(options.Dom, expression);
                string parameterName;
                if (Char.IsLetter(output[0]) || output[0] == '_')
                {
                    parameterName = output;
                }
                else
                {
                    parameterName = "par" + i;
                }

                ResolveResult resolveResult2 = resolver.Resolve(new ExpressionResult(output), options.ResolveResult.ResolvedExpression.Region.Start);
                TypeReference typeReference  = new TypeReference(resolveResult2.ResolvedType.ToInvariantString());
                typeReference.IsKeyword = true;
                ParameterDeclarationExpression pde = new ParameterDeclarationExpression(typeReference, parameterName);
                constructor.Parameters.Add(pde);
            }
            ICSharpCode.NRefactory.Ast.INode node = newType;
            IType curType = options.Document.CompilationUnit.GetTypeAt(options.Document.Editor.Caret.Line, options.Document.Editor.Caret.Column);

            if (curType != null && !string.IsNullOrEmpty(curType.Namespace))
            {
                NamespaceDeclaration namespaceDeclaration = new NamespaceDeclaration(curType.Namespace);
                namespaceDeclaration.Children.Add(newType);
                node = namespaceDeclaration;
            }
            newType.Children.Add(constructor);
            string fileName = GetName(Path.Combine(Path.GetDirectoryName(options.Document.FileName), newType.Name + Path.GetExtension(options.Document.FileName)));
            string header   = options.Dom.Project is DotNetProject?StandardHeaderService.GetHeader(options.Dom.Project, fileName, true) + Environment.NewLine : "";

            CreateFileChange createFile = new CreateFileChange(fileName, header + provider.OutputNode(options.Dom, node));

            result.Add(createFile);
            result.Add(new OpenFileChange(fileName));
            return(result);
        }
            protected override IEnumerable <string> GenerateCode(INRefactoryASTProvider astProvider, string indent, List <IBaseMember> includedMembers)
            {
                foreach (IMember member in includedMembers)
                {
                    MethodDeclaration methodDeclaration = new MethodDeclaration();
                    methodDeclaration.Name          = "On" + member.Name;
                    methodDeclaration.TypeReference = DomReturnType.Void.ConvertToTypeReference();
                    methodDeclaration.Modifier      = ICSharpCode.NRefactory.Ast.Modifiers.Protected | ICSharpCode.NRefactory.Ast.Modifiers.Virtual;
                    methodDeclaration.Body          = new BlockStatement();

                    IType   type         = Options.Dom.SearchType(Options.Document.ParsedDocument.CompilationUnit, member.DeclaringType, member.Location, member.ReturnType);
                    IMethod invokeMethod = type.Methods.First();

                    methodDeclaration.Parameters.Add(new ParameterDeclarationExpression(Options.ShortenTypeName(invokeMethod.Parameters[1].ReturnType.ConvertToTypeReference()), invokeMethod.Parameters[1].Name));
                    const string handlerName = "handler";

                    LocalVariableDeclaration handlerVariable = new LocalVariableDeclaration(new VariableDeclaration(handlerName, new MemberReferenceExpression(new ThisReferenceExpression(), member.Name)));
                    handlerVariable.TypeReference = Options.ShortenTypeName(member.ReturnType.ConvertToTypeReference());
                    methodDeclaration.Body.AddChild(handlerVariable);

                    IfElseStatement ifStatement = new IfElseStatement(null);
                    ifStatement.Condition = new BinaryOperatorExpression(new IdentifierExpression(handlerName), BinaryOperatorType.InEquality, new PrimitiveExpression(null));
                    List <Expression> arguments = new List <Expression> ();
                    arguments.Add(new ThisReferenceExpression());
                    arguments.Add(new IdentifierExpression(invokeMethod.Parameters[1].Name));
                    ifStatement.TrueStatement.Add(new ExpressionStatement(new InvocationExpression(new IdentifierExpression(handlerName), arguments)));
                    methodDeclaration.Body.AddChild(ifStatement);
                    yield return(astProvider.OutputNode(this.Options.Dom, methodDeclaration, indent));
                }
            }
Example #3
0
            protected override IEnumerable <string> GenerateCode(INRefactoryASTProvider astProvider, string indent, List <IBaseMember> includedMembers)
            {
                StringBuilder format = new StringBuilder();
                int           i      = 0;

                foreach (IBaseMember member in includedMembers)
                {
                    if (i > 0)
                    {
                        format.Append(", ");
                    }
                    format.Append(member.Name);
                    format.Append("={");
                    format.Append(i++);
                    format.Append("}");
                }

                InvocationExpression invocationExpression = new InvocationExpression(new MemberReferenceExpression(new IdentifierExpression("Console"), "WriteLine"));

                invocationExpression.Arguments.Add(new PrimitiveExpression(format.ToString()));
                foreach (IBaseMember member in includedMembers)
                {
                    invocationExpression.Arguments.Add(new IdentifierExpression(member.Name));
                }
                yield return(indent + astProvider.OutputNode(this.Options.Dom, new ExpressionStatement(invocationExpression), indent));
            }
Example #4
0
        public override bool IsValid(RefactoringOptions options)
        {
            INRefactoryASTProvider provider = options.GetASTProvider();
            IResolver resolver = options.GetResolver();

            if (provider == null || resolver == null)
            {
                return(false);
            }
            if (invoke == null)
            {
                invoke = GetInvocationExpression(options);
            }
            if (invoke == null)
            {
                return(false);
            }
            returnType      = DomReturnType.Void;
            modifiers       = ICSharpCode.NRefactory.Ast.Modifiers.None;
            resolvePosition = new DomLocation(options.Document.TextEditor.CursorLine, options.Document.TextEditor.CursorColumn);
            ResolveResult resolveResult = resolver.Resolve(new ExpressionResult(provider.OutputNode(options.Dom, invoke)), resolvePosition);

            if (resolveResult is MethodResolveResult)
            {
                MethodResolveResult mrr = (MethodResolveResult)resolveResult;
                if (mrr.ExactMethodMatch)
                {
                    return(false);
                }
                returnType = mrr.MostLikelyMethod.ReturnType;
                modifiers  = (ICSharpCode.NRefactory.Ast.Modifiers)mrr.MostLikelyMethod.Modifiers;
            }

            if (invoke.TargetObject is MemberReferenceExpression)
            {
                string callingObject = provider.OutputNode(options.Dom, ((MemberReferenceExpression)invoke.TargetObject).TargetObject);
                resolveResult = resolver.Resolve(new ExpressionResult(callingObject), resolvePosition);
                if (resolveResult == null || resolveResult.ResolvedType == null || resolveResult.CallingType == null)
                {
                    return(false);
                }
                IType type = options.Dom.GetType(resolveResult.ResolvedType);
                return(type != null && type.CompilationUnit != null && File.Exists(type.CompilationUnit.FileName) && RefactoringService.GetASTProvider(DesktopService.GetMimeTypeForUri(type.CompilationUnit.FileName)) != null);
            }
            return(invoke.TargetObject is IdentifierExpression);
        }
            Change ReplaceExpression(Expression toReplace, Expression replaceWith, IntegrateTemporaryVariableVisitorOptions options)
            {
//				Console.WriteLine ("Replace");
                TextReplaceChange change = new TextReplaceChange();

                change.Description = string.Format(GettextCatalog.GetString("Substitute variable {0} with the Initializeexpression"), options.GetName());
                change.FileName    = options.Options.Document.FileName;

                change.Offset       = options.Options.Document.Editor.Document.LocationToOffset(toReplace.StartLocation.Line + ((LocalVariable)options.Options.SelectedItem).DeclaringMember.BodyRegion.Start.Line, toReplace.StartLocation.Column);
                change.RemovedChars = options.GetName().Length;

                INRefactoryASTProvider provider = options.Options.GetASTProvider();

                change.InsertedText = provider.OutputNode(options.Options.Dom, replaceWith);

//				Console.WriteLine ("Replace done");
                return(change);
            }
Example #6
0
 protected override IEnumerable <string> GenerateCode(INRefactoryASTProvider astProvider, string indent, List <IBaseMember> includedMembers)
 {
     foreach (var member in includedMembers)
     {
         yield return(indent + astProvider.OutputNode(this.Options.Dom, new IfElseStatement(
                                                          new BinaryOperatorExpression(
                                                              new IdentifierExpression(member.Name),
                                                              BinaryOperatorType.Equality,
                                                              new PrimitiveExpression(null)
                                                              ), new ThrowStatement(
                                                              new ObjectCreateExpression(
                                                                  Options.ShortenTypeName(new TypeReference("System.ArgumentNullException")),
                                                                  new List <Expression> {
             new PrimitiveExpression(member.Name)
         }
                                                                  )
                                                              )
                                                          ), indent));
     }
 }
            protected override IEnumerable <string> GenerateCode(INRefactoryASTProvider astProvider, string indent, List <IBaseMember> includedMembers)
            {
                List <ParameterDeclarationExpression> parameters = new List <ParameterDeclarationExpression> ();

                foreach (IMember member in includedMembers)
                {
                    parameters.Add(new ParameterDeclarationExpression(member.ReturnType.ConvertToTypeReference(), CreateParameterName(member)));
                }

                ConstructorDeclaration constructorDeclaration = new ConstructorDeclaration(Options.EnclosingType.Name, ICSharpCode.NRefactory.Ast.Modifiers.Public, parameters, null, null);

                constructorDeclaration.Body = new BlockStatement();
                foreach (IMember member in includedMembers)
                {
                    MemberReferenceExpression memberReference = new MemberReferenceExpression(new ThisReferenceExpression(), member.Name);
                    AssignmentExpression      assign          = new AssignmentExpression(memberReference, AssignmentOperatorType.Assign, new IdentifierExpression(CreateParameterName(member)));
                    constructorDeclaration.Body.AddChild(new ExpressionStatement(assign));
                }
                yield return(astProvider.OutputNode(this.Options.Dom, constructorDeclaration, indent));
            }
            protected override IEnumerable <string> GenerateCode(INRefactoryASTProvider astProvider, string indent, List <IBaseMember> includedMembers)
            {
                StringBuilder format = new StringBuilder();

                format.Append("[");
                format.Append(Options.EnclosingType.Name);
                format.Append(": ");
                int i = 0;

                foreach (IMember member in includedMembers)
                {
                    if (i > 0)
                    {
                        format.Append(", ");
                    }
                    format.Append(member.Name);
                    format.Append("={");
                    format.Append(i++);
                    format.Append("}");
                }
                format.Append("]");

                MethodDeclaration methodDeclaration = new MethodDeclaration();

                methodDeclaration.Name          = "ToString";
                methodDeclaration.TypeReference = DomReturnType.String.ConvertToTypeReference();
                methodDeclaration.Modifier      = ICSharpCode.NRefactory.Ast.Modifiers.Public | ICSharpCode.NRefactory.Ast.Modifiers.Override;
                methodDeclaration.Body          = new BlockStatement();
                MemberReferenceExpression formatReference = new MemberReferenceExpression(new TypeReferenceExpression(methodDeclaration.TypeReference), "Format");
                List <Expression>         arguments       = new List <Expression> ();

                arguments.Add(new PrimitiveExpression(format.ToString()));

                foreach (IMember member in includedMembers)
                {
                    arguments.Add(new IdentifierExpression(member.Name));
                }

                methodDeclaration.Body.AddChild(new ReturnStatement(new InvocationExpression(formatReference, arguments)));
                yield return(astProvider.OutputNode(this.Options.Dom, methodDeclaration, indent));
            }
Example #9
0
        public override List <Change> PerformChanges(RefactoringOptions options, object prop)
        {
            List <Change>          result   = new List <Change> ();
            IResolver              resolver = options.GetResolver();
            INRefactoryASTProvider provider = options.GetASTProvider();

            if (resolver == null || provider == null)
            {
                return(result);
            }
            TextEditorData    data            = options.GetTextEditorData();
            TextReplaceChange insertNewMethod = new TextReplaceChange();

            insertNewMethod.FileName     = fileName;
            insertNewMethod.RemovedChars = insertionPoint.LineBefore == NewLineInsertion.Eol ? 0 : insertionPoint.Location.Column;
            insertNewMethod.Offset       = insertionOffset - insertNewMethod.RemovedChars;
            MethodDeclaration methodDecl = new MethodDeclaration();
            bool isInInterface           = false;

            methodDecl.Modifier      = modifiers;
            methodDecl.TypeReference = HelperMethods.ConvertToTypeReference(returnType);
            methodDecl.Name          = newMethodName;
            if (!isInInterface)
            {
                methodDecl.Body = new BlockStatement();
                methodDecl.Body.AddChild(new ThrowStatement(new ObjectCreateExpression(new TypeReference("System.NotImplementedException"), null)));
            }
            insertNewMethod.Description = string.Format(GettextCatalog.GetString("Create new method {0}"), methodDecl.Name);

            int i = 0;

            foreach (Expression expression in invoke.Arguments)
            {
                i++;
                string output = provider.OutputNode(options.Dom, expression);

                string parameterName = "par" + i;
                int    idx           = output.LastIndexOf('.');
                string lastName      = output.Substring(idx + 1);             // start from 0, if '.' wasn't found

                ResolveResult resolveResult2 = resolver.Resolve(new ExpressionResult(output), resolvePosition);
                TypeReference typeReference  = new TypeReference((resolveResult2 != null && resolveResult2.ResolvedType != null) ? options.Document.CompilationUnit.ShortenTypeName(resolveResult2.ResolvedType, data.Caret.Line, data.Caret.Column).ToInvariantString() : "System.Object");

                if (lastName == "this" || lastName == "base")
                {
                    idx      = typeReference.Type.LastIndexOf('.');
                    lastName = typeReference.Type.Substring(idx + 1);
                }
                if (!string.IsNullOrEmpty(lastName))
                {
                    lastName = char.ToLower(lastName[0]) + lastName.Substring(1);
                }
                if (IsValidIdentifier(lastName))
                {
                    parameterName = lastName;
                }

                typeReference.IsKeyword = true;
                ParameterDeclarationExpression pde = new ParameterDeclarationExpression(typeReference, parameterName);
                methodDecl.Parameters.Add(pde);
            }
            StringBuilder sb = new StringBuilder();

            switch (insertionPoint.LineBefore)
            {
            case NewLineInsertion.Eol:
                sb.AppendLine();
                break;

            case NewLineInsertion.BlankLine:
                sb.Append(indent);
                sb.AppendLine();
                break;
            }
            sb.Append(provider.OutputNode(options.Dom, methodDecl, indent).TrimEnd('\n', '\r'));
            switch (insertionPoint.LineAfter)
            {
            case NewLineInsertion.Eol:
                sb.AppendLine();
                break;

            case NewLineInsertion.BlankLine:
                sb.AppendLine();
                sb.AppendLine();
                sb.Append(indent);
                break;
            }
            insertNewMethod.InsertedText = sb.ToString();
            result.Add(insertNewMethod);
            if (!isInInterface)
            {
                int idx = insertNewMethod.InsertedText.IndexOf("throw");
                selectionStart = insertNewMethod.Offset + idx;
                selectionEnd   = insertNewMethod.Offset + insertNewMethod.InsertedText.IndexOf(';', idx) + 1;
            }
            else
            {
                selectionStart = selectionEnd = insertNewMethod.Offset;
            }
            return(result);
        }
Example #10
0
        public override void Run(RefactoringOptions options)
        {
            IResolver resolver = options.GetResolver();
            INRefactoryASTProvider provider = options.GetASTProvider();
            TextEditorData         data     = options.GetTextEditorData();
            IType type = options.ResolveResult.CallingType;

            if (invoke.TargetObject is IdentifierExpression)
            {
                fileName      = options.Document.FileName;
                newMethodName = ((IdentifierExpression)invoke.TargetObject).Identifier;
                indent        = options.GetIndent(options.ResolveResult.CallingMember);
                if (options.ResolveResult.CallingMember.IsStatic)
                {
                    modifiers |= ICSharpCode.NRefactory.Ast.Modifiers.Static;
                }
            }
            else
            {
                newMethodName = ((MemberReferenceExpression)invoke.TargetObject).MemberName;
                string        callingObject = provider.OutputNode(options.Dom, ((MemberReferenceExpression)invoke.TargetObject).TargetObject);
                ResolveResult resolveResult = resolver.Resolve(new ExpressionResult(callingObject), resolvePosition);
                type     = options.Dom.GetType(resolveResult.ResolvedType);
                fileName = type.CompilationUnit.FileName;
                if (resolveResult.StaticResolve)
                {
                    modifiers |= ICSharpCode.NRefactory.Ast.Modifiers.Static;
                }

                if (fileName == options.Document.FileName)
                {
                    indent = options.GetIndent(options.ResolveResult.CallingMember);
//					insertNewMethod.Offset = options.Document.TextEditor.GetPositionFromLineColumn (options.ResolveResult.CallingMember.BodyRegion.End.Line, options.ResolveResult.CallingMember.BodyRegion.End.Column);
                }
                else
                {
                    var openDocument = IdeApp.Workbench.OpenDocument(fileName);
                    data = openDocument.TextEditorData;
                    if (data == null)
                    {
                        return;
                    }
                    modifiers |= ICSharpCode.NRefactory.Ast.Modifiers.Public;
                    bool isInInterface = type.ClassType == MonoDevelop.Projects.Dom.ClassType.Interface;
                    if (isInInterface)
                    {
                        modifiers = ICSharpCode.NRefactory.Ast.Modifiers.None;
                    }
                    if (data == null)
                    {
                        throw new InvalidOperationException("Can't open file:" + modifiers);
                    }
                    try {
                        indent = data.Document.GetLine(type.Location.Line - 1).GetIndentation(data.Document) ?? "";
                    } catch (Exception) {
                        indent = "";
                    }
                    indent += "\t";
//					insertNewMethod.Offset = otherFile.Document.LocationToOffset (type.BodyRegion.End.Line - 1, 0);
                }
            }

            InsertionCursorEditMode mode = new InsertionCursorEditMode(data.Parent, HelperMethods.GetInsertionPoints(data.Document, type));

            if (fileName == options.Document.FileName)
            {
                for (int i = 0; i < mode.InsertionPoints.Count; i++)
                {
                    var point = mode.InsertionPoints[i];
                    if (point.Location < data.Caret.Location)
                    {
                        mode.CurIndex = i;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            ModeHelpWindow helpWindow = new ModeHelpWindow();

            helpWindow.TransientFor = IdeApp.Workbench.RootWindow;
            helpWindow.TitleText    = GettextCatalog.GetString("<b>Create Method -- Targeting</b>");
            helpWindow.Items.Add(new KeyValuePair <string, string> (GettextCatalog.GetString("<b>Key</b>"), GettextCatalog.GetString("<b>Behavior</b>")));
            helpWindow.Items.Add(new KeyValuePair <string, string> (GettextCatalog.GetString("<b>Up</b>"), GettextCatalog.GetString("Move to <b>previous</b> target point.")));
            helpWindow.Items.Add(new KeyValuePair <string, string> (GettextCatalog.GetString("<b>Down</b>"), GettextCatalog.GetString("Move to <b>next</b> target point.")));
            helpWindow.Items.Add(new KeyValuePair <string, string> (GettextCatalog.GetString("<b>Enter</b>"), GettextCatalog.GetString("<b>Declare new method</b> at target point.")));
            helpWindow.Items.Add(new KeyValuePair <string, string> (GettextCatalog.GetString("<b>Esc</b>"), GettextCatalog.GetString("<b>Cancel</b> this refactoring.")));
            mode.HelpWindow = helpWindow;
            mode.StartMode();
            mode.Exited += delegate(object s, InsertionCursorEventArgs args) {
                if (args.Success)
                {
                    insertionPoint  = args.InsertionPoint;
                    insertionOffset = data.Document.LocationToOffset(args.InsertionPoint.Location);
                    base.Run(options);
                    if (string.IsNullOrEmpty(fileName))
                    {
                        return;
                    }
                    MonoDevelop.Ide.Gui.Document document = IdeApp.Workbench.OpenDocument(fileName);
                    TextEditorData docData = document.TextEditorData;
                    if (docData != null)
                    {
                        docData.ClearSelection();
                        docData.Caret.Offset = selectionEnd;
                        docData.SetSelection(selectionStart, selectionEnd);
                    }
                }
            };
        }
			protected override IEnumerable<string> GenerateCode (INRefactoryASTProvider astProvider, string indent, List<IBaseMember> includedMembers)
			{
				foreach (var member in includedMembers) {
					yield return indent + astProvider.OutputNode (this.Options.Dom, new IfElseStatement (
						new BinaryOperatorExpression (
					    	new IdentifierExpression (member.Name),
					        BinaryOperatorType.Equality,
					        new PrimitiveExpression (null)
					    ), new ThrowStatement (
					    	new ObjectCreateExpression (
					        	Options.ShortenTypeName (new SimpleType ("System.ArgumentNullException")),
					            new List<Expression> { new PrimitiveExpression (member.Name) }
							)
					    )
					), indent);
				}
			}
Example #12
0
			protected override IEnumerable<string> GenerateCode (INRefactoryASTProvider astProvider, string indent, List<IBaseMember> includedMembers)
			{
				StringBuilder format = new StringBuilder ();
				int i = 0;
				foreach (IBaseMember member in includedMembers) {
					if (i > 0)
						format.Append (", ");
					format.Append (member.Name);
					format.Append ("={");
					format.Append (i++);
					format.Append ("}");
				}

				InvocationExpression invocationExpression = new InvocationExpression (new MemberReferenceExpression (new IdentifierExpression ("Console"), "WriteLine"));
				invocationExpression.Arguments.Add (new PrimitiveExpression (format.ToString ()));
				foreach (IBaseMember member in includedMembers) {
					invocationExpression.Arguments.Add (new IdentifierExpression (member.Name));
				}
				yield return indent + astProvider.OutputNode (this.Options.Dom, new ExpressionStatement (invocationExpression), indent);
			}
        public override List <Change> PerformChanges(RefactoringOptions options, object properties)
        {
            List <Change> result = new List <Change> ();
            IType         type   = options.SelectedItem as IType;

            if (type == null)
            {
                return(result);
            }
            string newName = GetCorrectFileName(type);

            if (type.CompilationUnit.Types.Count == 1)
            {
                result.Add(new RenameFileChange(type.CompilationUnit.FileName, newName));
            }
            else
            {
                StringBuilder content = new StringBuilder();

                if (options.Dom.Project is DotNetProject)
                {
                    content.Append(StandardHeaderService.GetHeader(options.Dom.Project, newName, true) + Environment.NewLine);
                }

                INRefactoryASTProvider                     provider = options.GetASTProvider();
                Mono.TextEditor.TextEditorData             data     = options.GetTextEditorData();
                ICSharpCode.NRefactory.Ast.CompilationUnit unit     = provider.ParseFile(options.Document.Editor.Text);

                TypeFilterTransformer typeFilterTransformer = new TypeFilterTransformer((type is InstantiatedType) ? ((InstantiatedType)type).UninstantiatedType.DecoratedFullName : type.DecoratedFullName);
                unit.AcceptVisitor(typeFilterTransformer, null);
                if (typeFilterTransformer.TypeDeclaration == null)
                {
                    return(result);
                }
                Mono.TextEditor.Document generatedDocument = new Mono.TextEditor.Document();
                generatedDocument.Text = provider.OutputNode(options.Dom, unit);

                int startLine = 0;
                int minLine   = typeFilterTransformer.TypeDeclaration.StartLocation.Line;
                foreach (var attr in typeFilterTransformer.TypeDeclaration.Attributes)
                {
                    minLine = Math.Min(minLine, attr.StartLocation.Line);
                }
                for (int i = minLine - 1; i >= 1; i--)
                {
                    string lineText = data.Document.GetTextAt(data.Document.GetLine(i)).Trim();
                    if (string.IsNullOrEmpty(lineText))
                    {
                        continue;
                    }
                    if (lineText.StartsWith("///"))
                    {
                        startLine = i;
                    }
                    else
                    {
                        break;
                    }
                }

                int start;
                if (startLine >= 1)
                {
                    start = data.Document.GetLine(startLine).Offset;
                }
                else
                {
                    var startLocation = typeFilterTransformer.TypeDeclaration.StartLocation;
                    startLocation.Column = 1;
                    foreach (var attr in typeFilterTransformer.TypeDeclaration.Attributes)
                    {
                        if (attr.StartLocation < startLocation)
                        {
                            startLocation = attr.StartLocation;
                        }
                    }

                    start = data.Document.LocationToOffset(startLocation.Line, 1);
                }
                int length = data.Document.LocationToOffset(typeFilterTransformer.TypeDeclaration.EndLocation.Line, typeFilterTransformer.TypeDeclaration.EndLocation.Column) - start;

                ICSharpCode.NRefactory.Ast.CompilationUnit generatedCompilationUnit = provider.ParseFile(generatedDocument.Text);
                TypeSearchVisitor typeSearchVisitor = new TypeSearchVisitor();
                generatedCompilationUnit.AcceptVisitor(typeSearchVisitor, null);

                int genStart = generatedDocument.LocationToOffset(typeSearchVisitor.Types[0].StartLocation.Line, 0);
                foreach (var attr in typeSearchVisitor.Types[0].Attributes)
                {
                    genStart = Math.Min(genStart, generatedDocument.LocationToOffset(attr.StartLocation.Line, 0));
                }

                int genEnd = generatedDocument.LocationToOffset(typeSearchVisitor.Types[0].EndLocation.Line, typeSearchVisitor.Types[0].EndLocation.Column);
                ((Mono.TextEditor.IBuffer)generatedDocument).Replace(genStart, genEnd - genStart, data.Document.GetTextAt(start, length));
                content.Append(generatedDocument.Text);

                result.Add(new CreateFileChange(newName, content.ToString()));

                TextReplaceChange removeDeclaration = new TextReplaceChange();
                removeDeclaration.Description  = "Remove type declaration";
                removeDeclaration.FileName     = type.CompilationUnit.FileName;
                removeDeclaration.Offset       = start;
                removeDeclaration.RemovedChars = length;
                result.Add(removeDeclaration);
            }
            result.Add(new SaveProjectChange(options.Document.Project));

            return(result);
        }
Example #14
0
        public override List <Change> PerformChanges(RefactoringOptions options, object properties)
        {
            TextEditorData data = options.GetTextEditorData();
            int            start, end;

            MonoDevelop.Refactoring.IntroduceConstant.IntroduceConstantRefactoring.SearchString(data, '"', out start, out end);
            LineSegment line = data.Document.GetLineByOffset(start);

            int closingTagLength = 1;                    // length of the closing "

            if (end > line.Offset + line.EditableLength) // assume missing closing tag
            {
                end = line.Offset + line.EditableLength;
                closingTagLength = 0;
            }

            INRefactoryASTProvider provider = options.GetASTProvider();

            List <Expression> args             = new List <Expression> ();
            IExpressionFinder expressionFinder = options.GetParser().CreateExpressionFinder(options.Dom);
            int expressionStart = start - 1;

            while (expressionStart > 0)
            {
                if (data.Document.GetCharAt(expressionStart) == '(')
                {
                    expressionStart--;
                    break;
                }
                expressionStart--;
            }
            // Add parameter to existing string.format call
            ExpressionResult     expressionResult = expressionFinder.FindFullExpression(options.Document.TextEditor.Text, expressionStart);
            InvocationExpression formatCall       = null;

            if (expressionResult != null)
            {
                InvocationExpression possibleFormatCall = provider.ParseExpression(expressionResult.Expression) as InvocationExpression;
                if (possibleFormatCall != null && possibleFormatCall.TargetObject is MemberReferenceExpression && ((MemberReferenceExpression)possibleFormatCall.TargetObject).MemberName == "Format")
                {
                    PrimitiveExpression expr = possibleFormatCall.Arguments[0] as PrimitiveExpression;
                    if (expr != null)
                    {
                        string str = data.Document.GetTextBetween(start + 1, data.SelectionRange.Offset) +
                                     "{" + (possibleFormatCall.Arguments.Count - 1) + "}" +
                                     data.Document.GetTextBetween(data.SelectionRange.EndOffset, end);
                        expr.Value       = str;
                        expr.StringValue = '"' + str + '"';
                        possibleFormatCall.Arguments.Add(new PrimitiveExpression(data.Document.GetTextAt(data.SelectionRange)));
                        formatCall = possibleFormatCall;
                        start      = data.Document.LocationToOffset(expressionResult.Region.Start.Line - 1, expressionResult.Region.Start.Column - 1);
                        end        = data.Document.LocationToOffset(expressionResult.Region.End.Line - 1, expressionResult.Region.End.Column - 1) - 1;
                    }
                }
            }

            // insert new format call
            if (formatCall == null)
            {
                string formattedString = UnescapeString(data.Document.GetTextBetween(start + 1, data.SelectionRange.Offset) + "{0}" + data.Document.GetTextBetween(data.SelectionRange.EndOffset, end));

                args.Add(new PrimitiveExpression(formattedString));
                args.Add(new PrimitiveExpression(data.Document.GetTextAt(data.SelectionRange)));

                TypeReference typeRef = new TypeReference("System.String");
                typeRef.IsKeyword = true;
                MemberReferenceExpression stringFormat = new MemberReferenceExpression(new TypeReferenceExpression(typeRef), "Format");
                formatCall = new InvocationExpression(stringFormat, args);
            }

            List <Change>     changes = new List <Change> ();
            TextReplaceChange change  = new TextReplaceChange();

            change.FileName           = options.Document.FileName;
            change.Offset             = start;
            change.RemovedChars       = end - start + closingTagLength;
            change.InsertedText       = provider.OutputNode(options.Dom, formatCall);
            change.MoveCaretToReplace = true;
            changes.Add(change);
            return(changes);
        }
Example #15
0
        public override List <Change> PerformChanges(RefactoringOptions options, object prop)
        {
            List <Change> result = new List <Change> ();

            MemberResolveResult    resolveResult = options.ResolveResult as MemberResolveResult;
            IProperty              property      = resolveResult.ResolvedMember as IProperty;
            TextEditorData         data          = options.GetTextEditorData();
            INRefactoryASTProvider astProvider   = options.GetASTProvider();

            backingStoreName = GetBackingStoreName(property);

            FieldDeclaration backingStore = new FieldDeclaration(null);

            backingStore.TypeReference = options.Document.CompilationUnit.ShortenTypeName(property.ReturnType, property.Location).ConvertToTypeReference();
            backingStore.Fields.Add(new VariableDeclaration(backingStoreName));
            DocumentLocation location = property.Location.ToDocumentLocation(data.Document);

            location.Column        = 1;
            refactoringStartOffset = data.Document.LocationToOffset(location);

            result.Add(new TextReplaceChange()
            {
                FileName     = options.Document.FileName,
                Offset       = refactoringStartOffset,
                InsertedText = astProvider.OutputNode(options.Dom, backingStore, options.GetIndent(property))
            });

            if (property.HasGet)
            {
                int startOffset = data.Document.LocationToOffset(property.GetRegion.Start.ToDocumentLocation(data.Document));
                int endOffset   = data.Document.LocationToOffset(property.GetRegion.End.ToDocumentLocation(data.Document));

                BlockStatement getBlock = new BlockStatement();
                getBlock.AddChild(new ReturnStatement(new IdentifierExpression(backingStoreName)));
                string text = astProvider.OutputNode(options.Dom, new PropertyGetRegion(getBlock, null), options.GetIndent(property) + "\t").Trim();
                result.Add(new TextReplaceChange()
                {
                    FileName     = options.Document.FileName,
                    Offset       = startOffset,
                    RemovedChars = endOffset - startOffset,
                    InsertedText = text
                });
            }

            if (property.HasSet)
            {
                int            startOffset = data.Document.LocationToOffset(property.SetRegion.Start.ToDocumentLocation(data.Document));
                int            endOffset   = data.Document.LocationToOffset(property.SetRegion.End.ToDocumentLocation(data.Document));
                BlockStatement setBlock    = new BlockStatement();
                setBlock.AddChild(new ExpressionStatement(new AssignmentExpression(new IdentifierExpression(backingStoreName), AssignmentOperatorType.Assign, new IdentifierExpression("value"))));
                string text = astProvider.OutputNode(options.Dom, new PropertySetRegion(setBlock, null), options.GetIndent(property) + "\t").Trim();
                result.Add(new TextReplaceChange()
                {
                    FileName     = options.Document.FileName,
                    Offset       = startOffset,
                    RemovedChars = endOffset - startOffset,
                    InsertedText = text
                });
            }

            return(result);
        }
        public override List <Change> PerformChanges(RefactoringOptions options, object prop)
        {
            varCount       = 0;
            selectionStart = selectionEnd = -1;

            List <Change>          result   = new List <Change> ();
            IResolver              resolver = options.GetResolver();
            INRefactoryASTProvider provider = options.GetASTProvider();
            TextEditorData         data     = options.GetTextEditorData();

            if (resolver == null || provider == null || data == null)
            {
                return(result);
            }

            DocumentLocation endPoint;

            if (data.IsSomethingSelected)
            {
                endPoint = data.MainSelection.Anchor < data.MainSelection.Lead ? data.MainSelection.Lead : data.MainSelection.Anchor;
            }
            else
            {
                endPoint = data.Caret.Location;
            }
            ResolveResult resolveResult;
            LineSegment   lineSegment;
            var           unit = provider.ParseFile(data.Document.Text);

            if (unit == null)
            {
                LoggingService.LogError("Declare local error: parese file == null");
                return(result);
            }
            var visitor = new VariableLookupVisitor(resolver, new DomLocation(endPoint.Line, endPoint.Column));

            if (options.ResolveResult == null)
            {
                LoggingService.LogError("Declare local error: resolve result == null");
                return(result);
            }
            IMember callingMember = options.ResolveResult.CallingMember;

            if (callingMember != null)
            {
                visitor.MemberLocation = new AstLocation(callingMember.Location.Column, callingMember.Location.Line);
            }
            unit.AcceptVisitor(visitor, null);

            ExpressionResult expressionResult = new ExpressionResult(data.SelectedText.Trim());

            if (expressionResult.Expression.Contains(" ") || expressionResult.Expression.Contains("\t"))
            {
                expressionResult.Expression = "(" + expressionResult.Expression + ")";
            }
            resolveResult = resolver.Resolve(expressionResult, new DomLocation(endPoint.Line, endPoint.Column));
            if (resolveResult == null)
            {
                return(result);
            }
            IReturnType resolvedType = GetResolvedType(options, resolveResult);

            AstType returnType;

            if (resolveResult.ResolvedType == null || string.IsNullOrEmpty(resolveResult.ResolvedType.Name))
            {
                returnType = new SimpleType("var");
            }
            else
            {
                returnType = options.ShortenTypeName(resolvedType).ConvertToTypeReference();
            }

            varName = CreateVariableName(resolvedType, visitor);
            options.ParseMember(resolveResult.CallingMember);

            // insert local variable declaration
            TextReplaceChange insert = new TextReplaceChange();

            insert.FileName    = options.Document.FileName;
            insert.Description = GettextCatalog.GetString("Insert variable declaration");

            var varDecl = new VariableDeclarationStatement(returnType, varName, provider.ParseExpression(data.SelectedText));

            var node = unit.GetNodeAt(endPoint.Line, endPoint.Column);

            var containing = node.Parent;

            while (!(containing.Parent is BlockStatement))
            {
                containing = containing.Parent;
            }

            if (containing is BlockStatement)
            {
                lineSegment = data.Document.GetLine(data.Caret.Line);
            }
            else
            {
                lineSegment = data.Document.GetLine(containing.StartLocation.Line);
            }
            insert.Offset       = lineSegment.Offset;
            insert.InsertedText = options.GetWhitespaces(lineSegment.Offset) + provider.OutputNode(options.Dom, varDecl);
            var insertOffset = insert.Offset + options.GetWhitespaces(lineSegment.Offset).Length + provider.OutputNode(options.Dom, varDecl.Type).Length + " ".Length;

            offsets.Add(insertOffset);
            result.Add(insert);
            varCount++;

            // replace main selection
            TextReplaceChange replace = new TextReplaceChange();

            replace.FileName     = options.Document.FileName;
            replace.Offset       = data.SelectionRange.Offset;
            replace.RemovedChars = data.SelectionRange.Length;
            replace.InsertedText = varName;
            result.Add(replace);
            int delta = insert.InsertedText.Length - insert.RemovedChars;

            offsets.Add(replace.Offset + delta);
            Console.WriteLine(replace.Offset);
            delta += varName.Length - replace.RemovedChars;
            varCount++;
            selectionStart = insert.Offset;

            if (replaceAll)
            {
                matches.Sort((x, y) => x.StartLocation.CompareTo(y.StartLocation));
                foreach (var match in matches)
                {
                    replace          = new TextReplaceChange();
                    replace.FileName = options.Document.FileName;
                    int start = data.LocationToOffset(match.StartLocation.Line, match.StartLocation.Column);
                    int end   = data.LocationToOffset(match.EndLocation.Line, match.EndLocation.Column);

                    replace.Offset       = start;
                    replace.RemovedChars = end - start;
                    replace.InsertedText = varName;
                    result.Add(replace);
                    offsets.Add(start + delta);
                    delta += varName.Length - replace.RemovedChars;
                }
            }
            return(result);
        }
            public override object VisitLocalVariableDeclaration(LocalVariableDeclaration localVariableDeclaration, object data)
            {
                //				Console.WriteLine ("LocalVariableDeclaration: " + localVariableDeclaration.StartLocation.ToString () + " - " + localVariableDeclaration.EndLocation.ToString ());
                localVariableDeclaration.TypeReference.AcceptVisitor(this, data);
                foreach (VariableDeclaration o in localVariableDeclaration.Variables)
                {
                    if (o.Name == ((IntegrateTemporaryVariableVisitorOptions)data).GetName())
                    {
                        IntegrateTemporaryVariableVisitorOptions options = (IntegrateTemporaryVariableVisitorOptions)data;
                        options.Initializer = localVariableDeclaration.GetVariableDeclaration(((LocalVariable)options.Options.SelectedItem).Name).Initializer;
                        if (localVariableDeclaration.Variables.Count == 1)
                        {
                            TextReplaceChange change = new TextReplaceChange();
                            change.Description = string.Format(GettextCatalog.GetString("Deleting local variable declaration {0}"), options.GetName());
                            change.FileName    = options.Options.Document.FileName;
                            int lineNumber = localVariableDeclaration.StartLocation.Line + ((LocalVariable)options.Options.SelectedItem).DeclaringMember.BodyRegion.Start.Line;
                            change.Offset = options.Options.Document.Editor.Document.LocationToOffset(lineNumber, localVariableDeclaration.StartLocation.Column);
                            int end = options.Options.Document.Editor.Document.LocationToOffset(localVariableDeclaration.EndLocation.Line + ((LocalVariable)options.Options.SelectedItem).DeclaringMember.BodyRegion.Start.Line, localVariableDeclaration.EndLocation.Column);
                            change.RemovedChars = end - change.Offset;
                            // check if whole line can be removed.
                            var line = options.Options.Document.Editor.GetLine(lineNumber);
                            if (line.GetIndentation(options.Options.Document.Editor.Document).Length == localVariableDeclaration.StartLocation.Column - 1)
                            {
                                bool isEmpty = true;
                                for (int i = end; i < line.EndOffset; i++)
                                {
                                    if (!char.IsWhiteSpace(options.Options.Document.Editor.GetCharAt(i)))
                                    {
                                        isEmpty = false;
                                        break;
                                    }
                                }
                                if (isEmpty)
                                {
                                    change.Offset       = line.Offset;
                                    change.RemovedChars = line.Length;
                                }
                            }
                            change.InsertedText = "";
                            ((IntegrateTemporaryVariableVisitorOptions)data).Changes.Add(change);
                        }
                        else
                        {
                            TextReplaceChange change = new TextReplaceChange();
                            change.Description = string.Format(GettextCatalog.GetString("Deleting local variable declaration {0}"), options.GetName());
                            change.FileName    = options.Options.Document.FileName;

                            change.Offset = options.Options.Document.Editor.Document.LocationToOffset(localVariableDeclaration.StartLocation.Line + ((LocalVariable)options.Options.SelectedItem).DeclaringMember.BodyRegion.Start.Line, localVariableDeclaration.StartLocation.Column);
                            int end = options.Options.Document.Editor.Document.LocationToOffset(localVariableDeclaration.EndLocation.Line + ((LocalVariable)options.Options.SelectedItem).DeclaringMember.BodyRegion.Start.Line, localVariableDeclaration.EndLocation.Column);

                            change.RemovedChars = end - change.Offset;
                            localVariableDeclaration.Variables.Remove(localVariableDeclaration.GetVariableDeclaration(options.GetName()));
                            INRefactoryASTProvider provider = options.Options.GetASTProvider();
                            change.InsertedText = options.Options.GetWhitespaces(change.Offset) + provider.OutputNode(options.Options.Dom, localVariableDeclaration);
                            ((IntegrateTemporaryVariableVisitorOptions)data).Changes.Add(change);
                        }
                    }
                    else
                    {
                        o.AcceptVisitor(this, data);
                    }
                }
                return(null);
            }
Example #18
0
        public override List <Change> PerformChanges(RefactoringOptions options, object properties)
        {
            List <Change>    result          = new List <Change> ();
            ICompilationUnit compilationUnit = options.ParseDocument().CompilationUnit;

            Mono.TextEditor.TextEditorData textEditorData = options.GetTextEditorData();
            int minOffset = int.MaxValue;

            foreach (IUsing u in compilationUnit.Usings)
            {
                if (u.IsFromNamespace)
                {
                    continue;
                }
                int offset = textEditorData.Document.LocationToOffset(u.Region.Start.Line, u.Region.Start.Column);
                TextReplaceChange change = new TextReplaceChange()
                {
                    FileName     = options.Document.FileName,
                    Offset       = offset,
                    RemovedChars = textEditorData.Document.LocationToOffset(u.Region.End.Line, u.Region.End.Column) - offset
                };
                Mono.TextEditor.LineSegment line = textEditorData.Document.GetLineByOffset(change.Offset);
                if (line != null && line.EditableLength == change.RemovedChars)
                {
                    change.RemovedChars += line.DelimiterLength;
                }
                result.Add(change);
                minOffset = Math.Min(minOffset, offset);
            }
            StringBuilder output = new StringBuilder();
            List <IUsing> usings = new List <IUsing> (compilationUnit.Usings);

            usings.Sort(UsingComparer);
            INRefactoryASTProvider astProvider = options.GetASTProvider();

            foreach (IUsing u in usings)
            {
                AstNode declaration;
                if (u.IsFromNamespace)
                {
                    continue;
                }
                if (u.Aliases.Any())
                {
                    KeyValuePair <string, IReturnType> alias = u.Aliases.First();
                    declaration = new UsingAliasDeclaration(alias.Key, alias.Value.ConvertToTypeReference());
                }
                else
                {
                    declaration = new UsingDeclaration(u.Namespaces.First());
                }
                output.Append(astProvider.OutputNode(options.Dom, declaration));
            }
            TextReplaceChange insertSortedUsings = new TextReplaceChange()
            {
                FileName     = options.Document.FileName,
                Offset       = minOffset,
                InsertedText = output.ToString()
            };

            result.Add(insertSortedUsings);
            return(result);
        }
Example #19
0
        public override List <Change> PerformChanges(RefactoringOptions options, object prop)
        {
            List <Change>           result   = new List <Change> ();
            ExtractMethodParameters param    = (ExtractMethodParameters)prop;
            TextEditorData          data     = options.GetTextEditorData();
            INRefactoryASTProvider  provider = options.GetASTProvider();
            IResolver resolver = options.GetResolver();

            ICSharpCode.NRefactory.Ast.INode node = Analyze(options, param, false);
            if (param.VariablesToGenerate.Count > 0)
            {
                TextReplaceChange varGen = new TextReplaceChange();
                varGen.Description = GettextCatalog.GetString("Generate some temporary variables");
                varGen.FileName    = options.Document.FileName;
                LineSegment line = data.Document.GetLine(Math.Max(0, data.Document.OffsetToLineNumber(data.SelectionRange.Offset) - 1));
                varGen.Offset       = line.Offset + line.EditableLength;
                varGen.InsertedText = Environment.NewLine + options.GetWhitespaces(line.Offset);
                foreach (VariableDescriptor var in param.VariablesToGenerate)
                {
                    TypeReference tr = options.ShortenTypeName(var.ReturnType).ConvertToTypeReference();
                    varGen.InsertedText += provider.OutputNode(options.Dom, new LocalVariableDeclaration(new VariableDeclaration(var.Name, null, tr))).Trim();
                }
                result.Add(varGen);
            }
            InvocationExpression invocation = new InvocationExpression(new IdentifierExpression(param.Name));

            foreach (VariableDescriptor var in param.Parameters)
            {
                if (!param.OneChangedVariable && param.ChangedVariables.Contains(var.Name))
                {
                    FieldDirection     fieldDirection = FieldDirection.Ref;
                    VariableDescriptor outsideVar     = null;
                    if (param.VariablesOutside.TryGetValue(var.Name, out outsideVar) && (var.GetsAssigned || param.VariablesToGenerate.Where(v => v.Name == var.Name).Any()))
                    {
                        if (!outsideVar.GetsAssigned)
                        {
                            fieldDirection = FieldDirection.Out;
                        }
                    }
                    invocation.Arguments.Add(new DirectionExpression(fieldDirection, new IdentifierExpression(var.Name)));
                }
                else
                {
                    invocation.Arguments.Add(new IdentifierExpression(var.Name));
                }
            }
            //	string mimeType = DesktopService.GetMimeTypeForUri (options.Document.FileName);
            TypeReference returnType = new TypeReference("System.Void", true);

            ICSharpCode.NRefactory.Ast.INode outputNode;
            if (param.OneChangedVariable)
            {
                string name = param.ChangedVariables.First();
                returnType = options.ShortenTypeName(param.Variables.Find(v => v.Name == name).ReturnType).ConvertToTypeReference();
                if (param.OutsideVariableList.Any(v => v.Name == name && !v.IsDefined))
                {
                    LocalVariableDeclaration varDecl = new LocalVariableDeclaration(returnType);
                    varDecl.Variables.Add(new VariableDeclaration(name, invocation));
                    outputNode = varDecl;
                }
                else
                {
                    outputNode = new ExpressionStatement(new AssignmentExpression(new IdentifierExpression(name), ICSharpCode.NRefactory.Ast.AssignmentOperatorType.Assign, invocation));
                }
            }
            else
            {
                outputNode = node is BlockStatement ? (ICSharpCode.NRefactory.Ast.INode) new ExpressionStatement(invocation) : invocation;
            }
            TextReplaceChange replacement = new TextReplaceChange();

            replacement.Description        = string.Format(GettextCatalog.GetString("Substitute selected statement(s) with call to {0}"), param.Name);
            replacement.FileName           = options.Document.FileName;
            replacement.Offset             = options.Document.TextEditor.SelectionStartPosition;
            replacement.RemovedChars       = options.Document.TextEditor.SelectionEndPosition - options.Document.TextEditor.SelectionStartPosition;
            replacement.MoveCaretToReplace = true;

            LineSegment line1 = data.Document.GetLineByOffset(options.Document.TextEditor.SelectionEndPosition);

            if (options.Document.TextEditor.SelectionEndPosition == line1.Offset)
            {
                if (line1.Offset > 0)
                {
                    LineSegment line2 = data.Document.GetLineByOffset(line1.Offset - 1);
                    replacement.RemovedChars -= line2.DelimiterLength;
                }
            }

            replacement.InsertedText = options.GetWhitespaces(options.Document.TextEditor.SelectionStartPosition) + provider.OutputNode(options.Dom, outputNode).Trim();

            result.Add(replacement);

            TextReplaceChange insertNewMethod = new TextReplaceChange();

            insertNewMethod.FileName     = options.Document.FileName;
            insertNewMethod.Description  = string.Format(GettextCatalog.GetString("Create new method {0} from selected statement(s)"), param.Name);
            insertNewMethod.RemovedChars = param.InsertionPoint.LineBefore == NewLineInsertion.Eol ? 0 : param.InsertionPoint.Location.Column;
            insertNewMethod.Offset       = data.Document.LocationToOffset(param.InsertionPoint.Location) - insertNewMethod.RemovedChars;

            ExtractMethodAstTransformer transformer = new ExtractMethodAstTransformer(param.VariablesToGenerate);

            node.AcceptVisitor(transformer, null);
            if (!param.OneChangedVariable && node is Expression)
            {
                ResolveResult resolveResult = resolver.Resolve(new ExpressionResult("(" + provider.OutputNode(options.Dom, node) + ")"), new DomLocation(options.Document.TextEditor.CursorLine, options.Document.TextEditor.CursorColumn));
                if (resolveResult.ResolvedType != null)
                {
                    returnType = options.ShortenTypeName(resolveResult.ResolvedType).ConvertToTypeReference();
                }
            }

            MethodDeclaration methodDecl = new MethodDeclaration();

            methodDecl.Name          = param.Name;
            methodDecl.Modifier      = param.Modifiers;
            methodDecl.TypeReference = returnType;

            if (!param.ReferencesMember)
            {
                methodDecl.Modifier |= ICSharpCode.NRefactory.Ast.Modifiers.Static;
            }
            if (node is BlockStatement)
            {
                methodDecl.Body = new BlockStatement();
                methodDecl.Body.AddChild(new EmptyStatement());
                if (param.OneChangedVariable)
                {
                    methodDecl.Body.AddChild(new ReturnStatement(new IdentifierExpression(param.ChangedVariables.First())));
                }
            }
            else if (node is Expression)
            {
                methodDecl.Body = new BlockStatement();
                methodDecl.Body.AddChild(new ReturnStatement(node as Expression));
            }

            foreach (VariableDescriptor var in param.VariablesToDefine)
            {
                BlockStatement           block   = methodDecl.Body;
                LocalVariableDeclaration varDecl = new LocalVariableDeclaration(options.ShortenTypeName(var.ReturnType).ConvertToTypeReference());
                varDecl.Variables.Add(new VariableDeclaration(var.Name));
                block.Children.Insert(0, varDecl);
            }

            foreach (VariableDescriptor var in param.Parameters)
            {
                TypeReference typeReference        = options.ShortenTypeName(var.ReturnType).ConvertToTypeReference();
                ParameterDeclarationExpression pde = new ParameterDeclarationExpression(typeReference, var.Name);
                if (!param.OneChangedVariable)
                {
                    if (param.ChangedVariables.Contains(var.Name))
                    {
                        pde.ParamModifier = ICSharpCode.NRefactory.Ast.ParameterModifiers.Ref;
                    }
                    if (param.VariablesToGenerate.Where(v => v.Name == var.Name).Any())
                    {
                        pde.ParamModifier = ICSharpCode.NRefactory.Ast.ParameterModifiers.Out;
                    }
                    VariableDescriptor outsideVar = null;
                    if (var.GetsAssigned && param.VariablesOutside.TryGetValue(var.Name, out outsideVar))
                    {
                        if (!outsideVar.GetsAssigned)
                        {
                            pde.ParamModifier = ICSharpCode.NRefactory.Ast.ParameterModifiers.Out;
                        }
                    }
                }

                methodDecl.Parameters.Add(pde);
            }

            string        indent     = options.GetIndent(param.DeclaringMember);
            StringBuilder methodText = new StringBuilder();

            switch (param.InsertionPoint.LineBefore)
            {
            case NewLineInsertion.Eol:
                methodText.AppendLine();
                break;

            case NewLineInsertion.BlankLine:
                methodText.Append(indent);
                methodText.AppendLine();
                break;
            }
            if (param.GenerateComment)
            {
                methodText.Append(indent);
                methodText.AppendLine("/// <summary>");
                methodText.Append(indent);
                methodText.AppendLine("/// TODO: write a comment.");
                methodText.Append(indent);
                methodText.AppendLine("/// </summary>");
                Ambience ambience = AmbienceService.GetAmbienceForFile(options.Document.FileName);
                foreach (ParameterDeclarationExpression pde in methodDecl.Parameters)
                {
                    methodText.Append(indent);
                    methodText.Append("/// <param name=\"");
                    methodText.Append(pde.ParameterName);
                    methodText.Append("\"> A ");
                    methodText.Append(ambience.GetString(pde.TypeReference.ConvertToReturnType(), OutputFlags.IncludeGenerics | OutputFlags.UseFullName));
                    methodText.Append(" </param>");
                    methodText.AppendLine();
                }
                if (methodDecl.TypeReference.Type != "System.Void")
                {
                    methodText.Append(indent);
                    methodText.AppendLine("/// <returns>");
                    methodText.Append(indent);
                    methodText.Append("/// A ");
                    methodText.AppendLine(ambience.GetString(methodDecl.TypeReference.ConvertToReturnType(), OutputFlags.IncludeGenerics | OutputFlags.UseFullName));
                    methodText.Append(indent);
                    methodText.AppendLine("/// </returns>");
                }
            }

            methodText.Append(indent);

            if (node is BlockStatement)
            {
                string text = provider.OutputNode(options.Dom, methodDecl, indent).Trim();
                int    emptyStatementMarker = text.LastIndexOf(';');
                if (param.OneChangedVariable)
                {
                    emptyStatementMarker = text.LastIndexOf(';', emptyStatementMarker - 1);
                }
                StringBuilder sb = new StringBuilder();
                sb.Append(text.Substring(0, emptyStatementMarker));
                sb.Append(AddIndent(param.Text, indent + "\t"));
                sb.Append(text.Substring(emptyStatementMarker + 1));

                methodText.Append(sb.ToString());
            }
            else
            {
                methodText.Append(provider.OutputNode(options.Dom, methodDecl, options.GetIndent(param.DeclaringMember)).Trim());
            }

            switch (param.InsertionPoint.LineAfter)
            {
            case NewLineInsertion.Eol:
                methodText.AppendLine();
                break;

            case NewLineInsertion.BlankLine:
                methodText.AppendLine();
                methodText.AppendLine();
                methodText.Append(indent);
                break;
            }
            insertNewMethod.InsertedText = methodText.ToString();
            result.Add(insertNewMethod);

            return(result);
        }
			protected override IEnumerable<string> GenerateCode (INRefactoryASTProvider astProvider, string indent, List<IBaseMember> includedMembers)
			{
				foreach (IMember member in includedMembers) {
					MethodDeclaration methodDeclaration = new MethodDeclaration ();
					methodDeclaration.Name = "On" + member.Name;
					methodDeclaration.TypeReference = DomReturnType.Void.ConvertToTypeReference ();
					methodDeclaration.Modifier = ICSharpCode.NRefactory.Ast.Modifiers.Protected | ICSharpCode.NRefactory.Ast.Modifiers.Virtual;
					methodDeclaration.Body = new BlockStatement ();

					IType type = Options.Dom.SearchType (Options.Document.ParsedDocument.CompilationUnit, member.DeclaringType, member.Location, member.ReturnType);
					IMethod invokeMethod = type.Methods.First ();

					methodDeclaration.Parameters.Add (new ParameterDeclarationExpression (Options.ShortenTypeName (invokeMethod.Parameters[1].ReturnType.ConvertToTypeReference ()), invokeMethod.Parameters[1].Name));
					const string handlerName = "handler";
					
					LocalVariableDeclaration handlerVariable = new LocalVariableDeclaration (new VariableDeclaration (handlerName, new MemberReferenceExpression (new ThisReferenceExpression (), member.Name)));
					handlerVariable.TypeReference = Options.ShortenTypeName (member.ReturnType.ConvertToTypeReference ());
					methodDeclaration.Body.AddChild (handlerVariable);
					
					IfElseStatement ifStatement = new IfElseStatement (null);
					ifStatement.Condition = new BinaryOperatorExpression (new IdentifierExpression (handlerName), BinaryOperatorType.InEquality, new PrimitiveExpression (null));
					List<Expression> arguments = new List<Expression> ();
					arguments.Add (new ThisReferenceExpression ());
					arguments.Add (new IdentifierExpression (invokeMethod.Parameters[1].Name));
					ifStatement.TrueStatement.Add (new ExpressionStatement (new InvocationExpression (new IdentifierExpression (handlerName), arguments)));
					methodDeclaration.Body.AddChild (ifStatement);
					yield return astProvider.OutputNode (this.Options.Dom, methodDeclaration, indent);
				}
			}
Example #21
0
            public override object VisitLocalVariableDeclaration(LocalVariableDeclaration localVariableDeclaration, object data)
            {
                //				Console.WriteLine ("LocalVariableDeclaration: " + localVariableDeclaration.StartLocation.ToString () + " - " + localVariableDeclaration.EndLocation.ToString ());
                localVariableDeclaration.TypeReference.AcceptVisitor(this, data);
                foreach (VariableDeclaration o in localVariableDeclaration.Variables)
                {
                    if (o.Name == ((IntegrateTemporaryVariableVisitorOptions)data).GetName())
                    {
                        IntegrateTemporaryVariableVisitorOptions options = (IntegrateTemporaryVariableVisitorOptions)data;
                        options.Initializer = localVariableDeclaration.GetVariableDeclaration(((LocalVariable)options.Options.SelectedItem).Name).Initializer;
                        if (localVariableDeclaration.Variables.Count == 1)
                        {
                            TextReplaceChange change = new TextReplaceChange();
                            change.Description = string.Format(GettextCatalog.GetString("Deleting local variable declaration {0}"), options.GetName());
                            change.FileName    = options.Options.Document.FileName;

                            change.Offset = options.Options.Document.TextEditor.GetPositionFromLineColumn(localVariableDeclaration.StartLocation.Line + ((LocalVariable)options.Options.SelectedItem).DeclaringMember.BodyRegion.Start.Line, localVariableDeclaration.StartLocation.Column);
                            int end = options.Options.Document.TextEditor.GetPositionFromLineColumn(localVariableDeclaration.EndLocation.Line + ((LocalVariable)options.Options.SelectedItem).DeclaringMember.BodyRegion.Start.Line, localVariableDeclaration.EndLocation.Column);

                            change.RemovedChars = end - change.Offset;
                            change.InsertedText = "";
                            ((IntegrateTemporaryVariableVisitorOptions)data).Changes.Add(change);
                        }
                        else
                        {
                            TextReplaceChange change = new TextReplaceChange();
                            change.Description = string.Format(GettextCatalog.GetString("Deleting local variable declaration {0}"), options.GetName());
                            change.FileName    = options.Options.Document.FileName;

                            change.Offset = options.Options.Document.TextEditor.GetPositionFromLineColumn(localVariableDeclaration.StartLocation.Line + ((LocalVariable)options.Options.SelectedItem).DeclaringMember.BodyRegion.Start.Line, localVariableDeclaration.StartLocation.Column);
                            int end = options.Options.Document.TextEditor.GetPositionFromLineColumn(localVariableDeclaration.EndLocation.Line + ((LocalVariable)options.Options.SelectedItem).DeclaringMember.BodyRegion.Start.Line, localVariableDeclaration.EndLocation.Column);

                            change.RemovedChars = end - change.Offset;
                            localVariableDeclaration.Variables.Remove(localVariableDeclaration.GetVariableDeclaration(options.GetName()));
                            INRefactoryASTProvider provider = options.Options.GetASTProvider();
                            change.InsertedText = options.Options.GetWhitespaces(change.Offset) + provider.OutputNode(options.Options.Dom, localVariableDeclaration);
                            ((IntegrateTemporaryVariableVisitorOptions)data).Changes.Add(change);
                        }
                    }
                    else
                    {
                        o.AcceptVisitor(this, data);
                    }
                }
                return(null);
            }
        public override List <Change> PerformChanges(RefactoringOptions options, object prop)
        {
            List <Change>          result        = new List <Change> ();
            TextEditorData         data          = options.GetTextEditorData();
            MemberResolveResult    resolveResult = options.ResolveResult as MemberResolveResult;
            IProperty              property      = resolveResult.ResolvedMember as IProperty;
            INRefactoryASTProvider astProvider   = options.GetASTProvider();
            string backingStoreName = RetrieveBackingStore(options, astProvider, property);

            int    backinStoreStart;
            int    backinStoreEnd;
            IField backingStore = GetBackingStoreField(options, backingStoreName, out backinStoreStart, out backinStoreEnd);

            if (backingStore != null)
            {
                foreach (MemberReference memberRef in GetReferences(options, backingStore))
                {
                    result.Add(new TextReplaceChange()
                    {
                        FileName     = memberRef.FileName,
                        Offset       = memberRef.Position,
                        RemovedChars = memberRef.Name.Length,
                        InsertedText = property.Name
                    });
                }

                result.RemoveAll(c => backinStoreStart <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset <= backinStoreEnd);
                result.Add(new TextReplaceChange()
                {
                    FileName     = options.Document.FileName,
                    Offset       = backinStoreStart,
                    RemovedChars = backinStoreEnd - backinStoreStart
                });
            }

            if (property.HasGet)
            {
                int startOffset = data.Document.LocationToOffset(property.GetRegion.Start.ToDocumentLocation(data.Document));
                int endOffset   = data.Document.LocationToOffset(property.GetRegion.End.ToDocumentLocation(data.Document));

                string text = astProvider.OutputNode(options.Dom, new PropertyGetRegion(null, null), options.GetIndent(property) + "\t").Trim();

                result.RemoveAll(c => startOffset <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset <= endOffset);
                result.Add(new TextReplaceChange()
                {
                    FileName     = options.Document.FileName,
                    Offset       = startOffset,
                    RemovedChars = endOffset - startOffset,
                    InsertedText = text
                });
            }

            int setStartOffset;
            int setEndOffset;
            PropertySetRegion setRegion = new PropertySetRegion(null, null);
            string            setText;

            if (property.HasSet)
            {
                setStartOffset = data.Document.LocationToOffset(property.SetRegion.Start.ToDocumentLocation(data.Document));
                setEndOffset   = data.Document.LocationToOffset(property.SetRegion.End.ToDocumentLocation(data.Document));
                setText        = astProvider.OutputNode(options.Dom, setRegion, options.GetIndent(property) + "\t").Trim();
            }
            else
            {
                setEndOffset       = setStartOffset = data.Document.LocationToOffset(property.GetRegion.End.ToDocumentLocation(data.Document));
                setRegion.Modifier = ICSharpCode.NRefactory.Ast.Modifiers.Private;
                setText            = Environment.NewLine + astProvider.OutputNode(options.Dom, setRegion, options.GetIndent(property) + "\t").TrimEnd();
            }
            result.RemoveAll(c => setStartOffset <= ((TextReplaceChange)c).Offset && ((TextReplaceChange)c).Offset <= setEndOffset);
            result.Add(new TextReplaceChange()
            {
                FileName     = options.Document.FileName,
                Offset       = setStartOffset,
                RemovedChars = setEndOffset - setStartOffset,
                InsertedText = setText
            });
            return(result);
        }
        public override List <Change> PerformChanges(RefactoringOptions options, object properties)
        {
            List <Change> result = new List <Change> ();
            Parameters    param  = properties as Parameters;

            if (param == null)
            {
                return(result);
            }
            TextEditorData data          = options.GetTextEditorData();
            IResolver      resolver      = options.GetResolver();
            IMember        curMember     = options.Document.CompilationUnit.GetMemberAt(data.Caret.Line, data.Caret.Column);
            ResolveResult  resolveResult = options.ResolveResult;
            int            start         = 0;
            int            end           = 0;

            if (resolveResult == null)
            {
                LineSegment line = data.Document.GetLine(data.Caret.Line);
                if (line != null)
                {
                    Stack <Span> stack = line.StartSpan != null ? new Stack <Span> (line.StartSpan) : new Stack <Span> ();
                    Mono.TextEditor.Highlighting.SyntaxModeService.ScanSpans(data.Document, data.Document.SyntaxMode, data.Document.SyntaxMode, stack, line.Offset, data.Caret.Offset);
                    foreach (Span span in stack)
                    {
                        if (span.Color == "string.single" || span.Color == "string.double")
                        {
                            resolveResult = resolver.Resolve(new ExpressionResult(SearchString(data, span.Color == "string.single" ? '\'' : '"', out start, out end)), DomLocation.Empty);
                            end++;
                        }
                    }
                }
                if (end == 0)
                {
                    resolveResult = resolver.Resolve(new ExpressionResult(SearchNumber(data, out start, out end)), DomLocation.Empty);
                }
            }
            else
            {
                start = data.Document.LocationToOffset(resolveResult.ResolvedExpression.Region.Start.Line - 1, resolveResult.ResolvedExpression.Region.Start.Column - 1);
                end   = data.Document.LocationToOffset(resolveResult.ResolvedExpression.Region.End.Line - 1, resolveResult.ResolvedExpression.Region.End.Column - 1);
            }
            if (start == 0 && end == 0)
            {
                return(result);
            }
            INRefactoryASTProvider provider = options.GetASTProvider();

            FieldDeclaration    fieldDeclaration = new FieldDeclaration(null);
            VariableDeclaration varDecl          = new VariableDeclaration(param.Name);

            varDecl.Initializer = provider.ParseExpression(resolveResult.ResolvedExpression.Expression);
            fieldDeclaration.Fields.Add(varDecl);
            fieldDeclaration.Modifier                = param.Modifiers;
            fieldDeclaration.Modifier               |= ICSharpCode.NRefactory.Ast.Modifiers.Const;
            fieldDeclaration.TypeReference           = resolveResult.ResolvedType.ConvertToTypeReference();
            fieldDeclaration.TypeReference.IsKeyword = true;

            TextReplaceChange insertConstant = new TextReplaceChange();

            insertConstant.FileName     = options.Document.FileName;
            insertConstant.Description  = string.Format(GettextCatalog.GetString("Generate constant '{0}'"), param.Name);
            insertConstant.Offset       = data.Document.LocationToOffset(curMember.Location.Line - 1, 0);
            insertConstant.InsertedText = provider.OutputNode(options.Dom, fieldDeclaration, options.GetIndent(curMember)) + Environment.NewLine;
            result.Add(insertConstant);

            TextReplaceChange replaceConstant = new TextReplaceChange();

            replaceConstant.FileName     = options.Document.FileName;
            replaceConstant.Description  = string.Format(GettextCatalog.GetString("Replace expression with constant '{0}'"), param.Name);
            replaceConstant.Offset       = start;
            replaceConstant.RemovedChars = end - start;
            replaceConstant.InsertedText = param.Name;
            result.Add(replaceConstant);

            return(result);
        }
        public override List <Change> PerformChanges(RefactoringOptions options, object prop)
        {
            varCount       = 0;
            selectionStart = selectionEnd = -1;
            List <Change>          result   = new List <Change> ();
            IResolver              resolver = options.GetResolver();
            INRefactoryASTProvider provider = options.GetASTProvider();

            if (resolver == null || provider == null)
            {
                return(result);
            }
            TextEditorData data = options.GetTextEditorData();

            if (data == null)
            {
                return(result);
            }
            ResolveResult resolveResult;
            LineSegment   lineSegment;

            ICSharpCode.NRefactory.Ast.CompilationUnit unit = provider.ParseFile(data.Document.Text);
            MonoDevelop.Refactoring.ExtractMethod.VariableLookupVisitor visitor = new MonoDevelop.Refactoring.ExtractMethod.VariableLookupVisitor(resolver, new DomLocation(data.Caret.Line, data.Caret.Column));
            if (options.ResolveResult == null)
            {
                LoggingService.LogError("resolve result == null:" + options.ResolveResult);
                return(result);
            }
            IMember callingMember = options.ResolveResult.CallingMember;

            if (callingMember != null)
            {
                visitor.MemberLocation = new Location(callingMember.Location.Column, callingMember.Location.Line);
            }
            unit.AcceptVisitor(visitor, null);

            if (data.IsSomethingSelected)
            {
                ExpressionResult expressionResult = new ExpressionResult(data.SelectedText.Trim());
                if (expressionResult.Expression.Contains(" ") || expressionResult.Expression.Contains("\t"))
                {
                    expressionResult.Expression = "(" + expressionResult.Expression + ")";
                }
                resolveResult = resolver.Resolve(expressionResult, new DomLocation(data.Caret.Line, data.Caret.Column));
                if (resolveResult == null)
                {
                    return(result);
                }
                IReturnType resolvedType = resolveResult.ResolvedType;
                if (resolvedType == null || string.IsNullOrEmpty(resolvedType.Name))
                {
                    resolvedType = DomReturnType.Object;
                }
                varName = CreateVariableName(resolvedType, visitor);
                TypeReference returnType;
                if (resolveResult.ResolvedType == null || string.IsNullOrEmpty(resolveResult.ResolvedType.Name))
                {
                    returnType           = new TypeReference("var");
                    returnType.IsKeyword = true;
                }
                else
                {
                    returnType = options.ShortenTypeName(resolveResult.ResolvedType).ConvertToTypeReference();
                }
                options.ParseMember(resolveResult.CallingMember);

                TextReplaceChange insert = new TextReplaceChange();
                insert.FileName    = options.Document.FileName;
                insert.Description = GettextCatalog.GetString("Insert variable declaration");

                LocalVariableDeclaration varDecl = new LocalVariableDeclaration(returnType);
                varDecl.Variables.Add(new VariableDeclaration(varName, provider.ParseExpression(data.SelectedText)));

                GetContainingEmbeddedStatementVisitor blockVisitor = new GetContainingEmbeddedStatementVisitor();
                blockVisitor.LookupLocation = new Location(data.Caret.Column + 1, data.Caret.Line + 1);

                unit.AcceptVisitor(blockVisitor, null);

                StatementWithEmbeddedStatement containing = blockVisitor.ContainingStatement as StatementWithEmbeddedStatement;

                if (containing != null && !(containing.EmbeddedStatement is BlockStatement))
                {
                    insert.Offset       = data.Document.LocationToOffset(containing.StartLocation.Line - 1, containing.StartLocation.Column - 1);
                    lineSegment         = data.Document.GetLineByOffset(insert.Offset);
                    insert.RemovedChars = data.Document.LocationToOffset(containing.EndLocation.Line - 1, containing.EndLocation.Column - 1) - insert.Offset;
                    BlockStatement insertedBlock = new BlockStatement();
                    insertedBlock.AddChild(varDecl);
                    insertedBlock.AddChild(containing.EmbeddedStatement);

                    containing.EmbeddedStatement = insertedBlock;
                    insert.InsertedText          = provider.OutputNode(options.Dom, containing, options.GetWhitespaces(lineSegment.Offset)).TrimStart();
                    int offset, length;
                    if (SearchSubExpression(insert.InsertedText, data.SelectedText, 0, out offset, out length))
                    {
                        if (SearchSubExpression(insert.InsertedText, data.SelectedText, offset + 1, out offset, out length))
                        {
                            insert.InsertedText = insert.InsertedText.Substring(0, offset) + varName + insert.InsertedText.Substring(offset + length);
                            insertOffset        = insert.Offset + offset;
                        }
                    }
                }
                else if (blockVisitor.ContainingStatement is IfElseStatement)
                {
                    IfElseStatement ifElse = blockVisitor.ContainingStatement as IfElseStatement;

                    insert.Offset       = data.Document.LocationToOffset(blockVisitor.ContainingStatement.StartLocation.Line - 1, blockVisitor.ContainingStatement.StartLocation.Column - 1);
                    lineSegment         = data.Document.GetLineByOffset(insert.Offset);
                    insert.RemovedChars = data.Document.LocationToOffset(blockVisitor.ContainingStatement.EndLocation.Line - 1, blockVisitor.ContainingStatement.EndLocation.Column - 1) - insert.Offset;
                    BlockStatement insertedBlock = new BlockStatement();
                    insertedBlock.AddChild(varDecl);
                    if (blockVisitor.ContainsLocation(ifElse.TrueStatement[0]))
                    {
                        insertedBlock.AddChild(ifElse.TrueStatement[0]);
                        ifElse.TrueStatement[0] = insertedBlock;
                    }
                    else
                    {
                        insertedBlock.AddChild(ifElse.FalseStatement[0]);
                        ifElse.FalseStatement[0] = insertedBlock;
                    }

                    insert.InsertedText = provider.OutputNode(options.Dom, blockVisitor.ContainingStatement, options.GetWhitespaces(lineSegment.Offset));
                    int offset, length;

                    if (SearchSubExpression(insert.InsertedText, provider.OutputNode(options.Dom, insertedBlock), 0, out offset, out length))
                    {
                        if (SearchSubExpression(insert.InsertedText, data.SelectedText, offset + 1, out offset, out length))
                        {
                            if (SearchSubExpression(insert.InsertedText, data.SelectedText, offset + 1, out offset, out length))
                            {
                                insert.InsertedText = insert.InsertedText.Substring(0, offset) + varName + insert.InsertedText.Substring(offset + length);
                                insertOffset        = insert.Offset + offset;
                            }
                        }
                    }
                }
                else
                {
                    lineSegment         = data.Document.GetLine(data.Caret.Line);
                    insert.Offset       = lineSegment.Offset;
                    insert.InsertedText = options.GetWhitespaces(lineSegment.Offset) + provider.OutputNode(options.Dom, varDecl) + Environment.NewLine;
                    insertOffset        = insert.Offset + options.GetWhitespaces(lineSegment.Offset).Length + provider.OutputNode(options.Dom, varDecl.TypeReference).Length + " ".Length;

                    TextReplaceChange replace = new TextReplaceChange();
                    replace.FileName     = options.Document.FileName;
                    replace.Offset       = data.SelectionRange.Offset;
                    replace.RemovedChars = data.SelectionRange.Length;
                    replace.InsertedText = varName;
                    result.Add(replace);
                    replaceOffset = replace.Offset;
                    if (insert.Offset < replaceOffset)
                    {
                        replaceOffset += insert.InsertedText.Length - insert.RemovedChars;
                    }
                    varCount++;
                }
                result.Add(insert);
                varCount++;
                selectionStart = insert.Offset;
                return(result);
            }

            lineSegment = data.Document.GetLine(data.Caret.Line);
            string line = data.Document.GetTextAt(lineSegment);

            Expression expression = provider.ParseExpression(line);

            if (expression == null)
            {
                return(result);
            }

            resolveResult = resolver.Resolve(new ExpressionResult(line), new DomLocation(options.Document.TextEditor.CursorLine, options.Document.TextEditor.CursorColumn));

            if (resolveResult.ResolvedType != null && !string.IsNullOrEmpty(resolveResult.ResolvedType.FullName))
            {
                TextReplaceChange insert = new TextReplaceChange();
                insert.FileName    = options.Document.FileName;
                insert.Description = GettextCatalog.GetString("Insert variable declaration");
                insert.Offset      = lineSegment.Offset + options.GetWhitespaces(lineSegment.Offset).Length;
                varName            = CreateVariableName(resolveResult.ResolvedType, visitor);
                LocalVariableDeclaration varDecl = new LocalVariableDeclaration(options.ShortenTypeName(resolveResult.ResolvedType).ConvertToTypeReference());
                varDecl.Variables.Add(new VariableDeclaration(varName, expression));
                insert.RemovedChars = expression.EndLocation.Column - 1;
                insert.InsertedText = provider.OutputNode(options.Dom, varDecl);
                insertOffset        = insert.Offset + provider.OutputNode(options.Dom, varDecl.TypeReference).Length + " ".Length;

                result.Add(insert);
                varCount++;

                int idx = 0;
                while (idx < insert.InsertedText.Length - varName.Length)
                {
                    if (insert.InsertedText.Substring(idx, varName.Length) == varName && (idx == 0 || insert.InsertedText[idx - 1] == ' ') && (idx == insert.InsertedText.Length - varName.Length - 1 || insert.InsertedText[idx + varName.Length] == ' '))
                    {
                        selectionStart = insert.Offset + idx;
                        selectionEnd   = selectionStart + varName.Length;
                        break;
                    }
                    idx++;
                }
            }

            return(result);
        }
			protected override IEnumerable<string> GenerateCode (INRefactoryASTProvider astProvider, string indent, List<IBaseMember> includedMembers)
			{
				// Genereate Equals
				MethodDeclaration methodDeclaration = new MethodDeclaration ();
				methodDeclaration.Name = "Equals";

				methodDeclaration.TypeReference = DomReturnType.Bool.ConvertToTypeReference ();
				methodDeclaration.Modifier = ICSharpCode.NRefactory.Ast.Modifiers.Public | ICSharpCode.NRefactory.Ast.Modifiers.Override;
				methodDeclaration.Body = new BlockStatement ();
				methodDeclaration.Parameters.Add (new ParameterDeclarationExpression (DomReturnType.Object.ConvertToTypeReference (), "obj"));
				IdentifierExpression paramId = new IdentifierExpression ("obj");
				IfElseStatement ifStatement = new IfElseStatement (null);
				ifStatement.Condition = new BinaryOperatorExpression (paramId, BinaryOperatorType.Equality, new PrimitiveExpression (null));
				ifStatement.TrueStatement.Add (new ReturnStatement (new PrimitiveExpression (false)));
				methodDeclaration.Body.AddChild (ifStatement);

				ifStatement = new IfElseStatement (null);
				List<Expression> arguments = new List<Expression> ();
				arguments.Add (new ThisReferenceExpression ());
				arguments.Add (paramId);
				ifStatement.Condition = new InvocationExpression (new IdentifierExpression ("ReferenceEquals"), arguments);
				ifStatement.TrueStatement.Add (new ReturnStatement (new PrimitiveExpression (true)));
				methodDeclaration.Body.AddChild (ifStatement);

				ifStatement = new IfElseStatement (null);
				ifStatement.Condition = new BinaryOperatorExpression (new InvocationExpression (new MemberReferenceExpression (paramId, "GetType")), BinaryOperatorType.InEquality, new TypeOfExpression (new TypeReference (Options.EnclosingType.Name)));
				ifStatement.TrueStatement.Add (new ReturnStatement (new PrimitiveExpression (false)));
				methodDeclaration.Body.AddChild (ifStatement);

				LocalVariableDeclaration varDecl = new LocalVariableDeclaration (new DomReturnType (Options.EnclosingType).ConvertToTypeReference ());
				varDecl.Variables.Add (new VariableDeclaration ("other", new CastExpression (varDecl.TypeReference, paramId, CastType.Cast)));
				methodDeclaration.Body.AddChild (varDecl);
				
				IdentifierExpression otherId = new IdentifierExpression ("other");
				Expression binOp = null;
				foreach (IMember member in includedMembers) {
					Expression right = new BinaryOperatorExpression (new IdentifierExpression (member.Name), BinaryOperatorType.Equality, new MemberReferenceExpression (otherId, member.Name));
					if (binOp == null) {
						binOp = right;
					} else {
						binOp = new BinaryOperatorExpression (binOp, BinaryOperatorType.LogicalAnd, right);
					}
				}

				methodDeclaration.Body.AddChild (new ReturnStatement (binOp));
				yield return astProvider.OutputNode (this.Options.Dom, methodDeclaration, indent);

				methodDeclaration = new MethodDeclaration ();
				methodDeclaration.Name = "GetHashCode";

				methodDeclaration.TypeReference = DomReturnType.Int32.ConvertToTypeReference ();
				methodDeclaration.Modifier = ICSharpCode.NRefactory.Ast.Modifiers.Public | ICSharpCode.NRefactory.Ast.Modifiers.Override;
				methodDeclaration.Body = new BlockStatement ();

				binOp = null;
				foreach (IMember member in includedMembers) {
					Expression right;
					right = new InvocationExpression (new MemberReferenceExpression (new IdentifierExpression (member.Name), "GetHashCode"));

					IType type = Options.Dom.SearchType (Options.Document.ParsedDocument.CompilationUnit, member, member.ReturnType);
					if (type != null && type.ClassType != MonoDevelop.Projects.Dom.ClassType.Struct&& type.ClassType != MonoDevelop.Projects.Dom.ClassType.Enum)
						right = new ParenthesizedExpression (new ConditionalExpression (new BinaryOperatorExpression (new IdentifierExpression (member.Name), BinaryOperatorType.InEquality, new PrimitiveExpression (null)), right, new PrimitiveExpression (0)));

					if (binOp == null) {
						binOp = right;
					} else {
						binOp = new BinaryOperatorExpression (binOp, BinaryOperatorType.ExclusiveOr, right);
					}
				}
				BlockStatement uncheckedBlock = new BlockStatement ();
				uncheckedBlock.AddChild (new ReturnStatement (binOp));

				methodDeclaration.Body.AddChild (new UncheckedStatement (uncheckedBlock));
				yield return astProvider.OutputNode (this.Options.Dom, methodDeclaration, indent);
			}
            protected override IEnumerable <string> GenerateCode(INRefactoryASTProvider astProvider, string indent, List <IBaseMember> includedMembers)
            {
                // Genereate Equals
                MethodDeclaration methodDeclaration = new MethodDeclaration();

                methodDeclaration.Name = "Equals";

                methodDeclaration.ReturnType = DomReturnType.Bool.ConvertToTypeReference();
                methodDeclaration.Modifiers  = ICSharpCode.NRefactory.CSharp.Modifiers.Public | ICSharpCode.NRefactory.CSharp.Modifiers.Override;
                methodDeclaration.Body       = new BlockStatement();
                methodDeclaration.Parameters.Add(new ParameterDeclaration(DomReturnType.Object.ConvertToTypeReference(), "obj"));
                IdentifierExpression paramId     = new IdentifierExpression("obj");
                IfElseStatement      ifStatement = new IfElseStatement();

                ifStatement.Condition     = new BinaryOperatorExpression(paramId, BinaryOperatorType.Equality, new PrimitiveExpression(null));
                ifStatement.TrueStatement = new ReturnStatement(new PrimitiveExpression(false));
                methodDeclaration.Body.Statements.Add(ifStatement);

                ifStatement = new IfElseStatement();
                List <Expression> arguments = new List <Expression> ();

                arguments.Add(new ThisReferenceExpression());
                arguments.Add(paramId.Clone());
                ifStatement.Condition     = new InvocationExpression(new IdentifierExpression("ReferenceEquals"), arguments);
                ifStatement.TrueStatement = new ReturnStatement(new PrimitiveExpression(true));
                methodDeclaration.Body.Statements.Add(ifStatement);

                ifStatement               = new IfElseStatement();
                ifStatement.Condition     = new BinaryOperatorExpression(new InvocationExpression(new MemberReferenceExpression(paramId.Clone(), "GetType")), BinaryOperatorType.InEquality, new TypeOfExpression(new SimpleType(Options.EnclosingType.Name)));
                ifStatement.TrueStatement = new ReturnStatement(new PrimitiveExpression(false));
                methodDeclaration.Body.Statements.Add(ifStatement);

                AstType varType = new DomReturnType(Options.EnclosingType).ConvertToTypeReference();
                var     varDecl = new VariableDeclarationStatement(varType, "other", new CastExpression(varType.Clone(), paramId.Clone()));

                methodDeclaration.Body.Statements.Add(varDecl);

                IdentifierExpression otherId = new IdentifierExpression("other");
                Expression           binOp   = null;

                foreach (IMember member in includedMembers)
                {
                    Expression right = new BinaryOperatorExpression(new IdentifierExpression(member.Name), BinaryOperatorType.Equality, new MemberReferenceExpression(otherId, member.Name));
                    if (binOp == null)
                    {
                        binOp = right;
                    }
                    else
                    {
                        binOp = new BinaryOperatorExpression(binOp, BinaryOperatorType.ConditionalAnd, right);
                    }
                }

                methodDeclaration.Body.Statements.Add(new ReturnStatement(binOp));
                yield return(astProvider.OutputNode(this.Options.Dom, methodDeclaration, indent));

                methodDeclaration      = new MethodDeclaration();
                methodDeclaration.Name = "GetHashCode";

                methodDeclaration.ReturnType = DomReturnType.Int32.ConvertToTypeReference();
                methodDeclaration.Modifiers  = ICSharpCode.NRefactory.CSharp.Modifiers.Public | ICSharpCode.NRefactory.CSharp.Modifiers.Override;
                methodDeclaration.Body       = new BlockStatement();

                binOp = null;
                foreach (IMember member in includedMembers)
                {
                    Expression right;
                    right = new InvocationExpression(new MemberReferenceExpression(new IdentifierExpression(member.Name), "GetHashCode"));

                    IType type = Options.Dom.SearchType(Options.Document.ParsedDocument.CompilationUnit, member is IType ? ((IType)member) : member.DeclaringType, member.Location, member.ReturnType);
                    if (type != null && type.ClassType != MonoDevelop.Projects.Dom.ClassType.Struct && type.ClassType != MonoDevelop.Projects.Dom.ClassType.Enum)
                    {
                        right = new ParenthesizedExpression(new ConditionalExpression(new BinaryOperatorExpression(new IdentifierExpression(member.Name), BinaryOperatorType.InEquality, new PrimitiveExpression(null)), right, new PrimitiveExpression(0)));
                    }

                    if (binOp == null)
                    {
                        binOp = right;
                    }
                    else
                    {
                        binOp = new BinaryOperatorExpression(binOp, BinaryOperatorType.ExclusiveOr, right);
                    }
                }
                BlockStatement uncheckedBlock = new BlockStatement();

                uncheckedBlock.Statements.Add(new ReturnStatement(binOp));

                methodDeclaration.Body.Statements.Add(new UncheckedStatement(uncheckedBlock));
                yield return(astProvider.OutputNode(this.Options.Dom, methodDeclaration, indent));
            }
			protected override IEnumerable<string> GenerateCode (INRefactoryASTProvider astProvider, string indent, List<IBaseMember> includedMembers)
			{
				StringBuilder format = new StringBuilder ();
				format.Append ("[");
				format.Append (Options.EnclosingType.Name);
				format.Append (": ");
				int i = 0;
				foreach (IMember member in includedMembers) {
					if (i > 0)
						format.Append (", ");
					format.Append (member.Name);
					format.Append ("={");
					format.Append (i++);
					format.Append ("}");
				}
				format.Append ("]");

				MethodDeclaration methodDeclaration = new MethodDeclaration ();
				methodDeclaration.Name = "ToString";
				methodDeclaration.TypeReference = DomReturnType.String.ConvertToTypeReference ();
				methodDeclaration.Modifier = ICSharpCode.NRefactory.Ast.Modifiers.Public | ICSharpCode.NRefactory.Ast.Modifiers.Override;
				methodDeclaration.Body = new BlockStatement ();
				MemberReferenceExpression formatReference = new MemberReferenceExpression (new TypeReferenceExpression (methodDeclaration.TypeReference), "Format");
				List<Expression> arguments = new List<Expression> ();
				arguments.Add (new PrimitiveExpression (format.ToString ()));

				foreach (IMember member in includedMembers) {
					arguments.Add (new IdentifierExpression (member.Name));
				}

				methodDeclaration.Body.AddChild (new ReturnStatement (new InvocationExpression (formatReference, arguments)));
				yield return astProvider.OutputNode (this.Options.Dom, methodDeclaration, indent);
			}
			protected override IEnumerable<string> GenerateCode (INRefactoryASTProvider astProvider, string indent, List<IBaseMember> includedMembers)
			{
				var parameters = new List<ParameterDeclaration> ();
				foreach (IMember member in includedMembers) {
					parameters.Add (new ParameterDeclaration (member.ReturnType.ConvertToTypeReference (), CreateParameterName (member)));
				}

				var constructorDeclaration = new ConstructorDeclaration ();
				constructorDeclaration.Name = Options.EnclosingType.Name;
				constructorDeclaration.Modifiers = ICSharpCode.NRefactory.CSharp.Modifiers.Public;
				constructorDeclaration.Parameters.AddRange (parameters);
				constructorDeclaration.Body = new BlockStatement ();
				foreach (IMember member in includedMembers) {
					MemberReferenceExpression memberReference = new MemberReferenceExpression (new ThisReferenceExpression (), member.Name);
					AssignmentExpression assign = new AssignmentExpression (memberReference, AssignmentOperatorType.Assign, new IdentifierExpression (CreateParameterName (member)));
					constructorDeclaration.Body.Statements.Add (new ExpressionStatement (assign));
				}
				yield return astProvider.OutputNode (this.Options.Dom, constructorDeclaration, indent);
			}