/// <summary> /// Our Run override is used to perform an action. /// /// Here we take the previously selected translation menu item and generate a translation for the string literal /// that is under the users cursor. /// /// We then create a TextReplaceChange and apply it using the RefactoringService. This will write new text (source code) /// at the location that we specify and add an undo operation into the undo buffer for us. /// </summary> /// <param name="dataItem">Data item.</param> protected override void Run(object dataItem) { var doc = IdeApp.Workbench.ActiveDocument; var editor = doc.Editor; if (doc != null && editor != null) { var loc = editor.CaretLocation; var setting = dataItem as TranslationSetting; var language = setting.TargetLanguage; var token = setting.Token; var text = token.Text.Substring(1, token.Text.Length - 2); // Grab the text without the "" characters. var translation = TranslationHelper.Translate(text, language); if (!string.IsNullOrEmpty(translation)) { TextReplaceChange translateChange = new TextReplaceChange(); translateChange.RemovedChars = token.Text.Length; translateChange.InsertedText = "\"" + translation + "\""; translateChange.Description = "Translate the existin string content to " + language; translateChange.Offset = token.SpanStart; translateChange.FileName = doc.FileName; var monitor = IdeApp.Workbench.ProgressMonitors.GetBackgroundProgressMonitor("Apply translation", null); RefactoringService.AcceptChanges(monitor, new List <Change> () { translateChange }); } } }
public override List <Change> PerformChanges(RefactoringOptions options, object prop) { if (data == null) { data = options.GetTextEditorData(); } List <Change> result = new List <Change> (); TextReplaceChange insertNewMethod = new TextReplaceChange(); insertNewMethod.FileName = fileName; insertNewMethod.RemovedChars = 0; //insertionPoint.LineBefore == NewLineInsertion.Eol ? 0 : insertionPoint.Location.Column - 1; int insertionOffset = data.Document.LocationToOffset(insertionPoint.Location); insertNewMethod.Offset = insertionOffset /*- insertNewMethod.RemovedChars*/; StringBuilder sb = new StringBuilder(); switch (insertionPoint.LineBefore) { case NewLineInsertion.Eol: sb.Append(data.EolMarker); break; case NewLineInsertion.BlankLine: sb.Append(data.EolMarker); sb.Append(indent); sb.Append(data.EolMarker); break; } var generator = options.Document.CreateCodeGenerator(); sb.Append(generator.CreateMemberImplementation(declaringType, ConstructMethod(options), false).Code); sb.Append(data.EolMarker); switch (insertionPoint.LineAfter) { case NewLineInsertion.Eol: break; case NewLineInsertion.BlankLine: sb.Append(indent); sb.Append(data.EolMarker); break; } insertNewMethod.InsertedText = sb.ToString(); result.Add(insertNewMethod); selectionStart = selectionEnd = insertNewMethod.Offset; int idx = insertNewMethod.InsertedText.IndexOf("throw"); if (idx >= 0) { selectionStart = insertNewMethod.Offset + idx; selectionEnd = insertNewMethod.Offset + insertNewMethod.InsertedText.IndexOf(';', idx) + 1; } else { selectionStart = selectionEnd = insertNewMethod.Offset; } return(result); }
public static void Rename(IEntity entity, string newName) { if (newName == null) { var options = new RefactoringOptions() { SelectedItem = entity }; new RenameRefactoring().Run(options); return; } using (var monitor = new NullProgressMonitor()) { var col = ReferenceFinder.FindReferences(entity, true, monitor); List <Change> result = new List <Change> (); foreach (var memberRef in col) { var change = new TextReplaceChange(); change.FileName = memberRef.FileName; change.Offset = memberRef.Offset; change.RemovedChars = memberRef.Length; change.InsertedText = newName; change.Description = string.Format(GettextCatalog.GetString("Replace '{0}' with '{1}'"), memberRef.GetName(), newName); result.Add(change); } if (result.Count > 0) { RefactoringService.AcceptChanges(monitor, result); } } }
public override List <Change> PerformChanges(RefactoringOptions options, object properties) { List <Change> result = new List <Change> (); ICSharpCode.NRefactory.CSharp.CompilationUnit unit = options.GetASTProvider().ParseFile(options.Document.Editor.Text); FindTypeReferencesVisitor visitor = new FindTypeReferencesVisitor(options.GetTextEditorData(), options.GetResolver()); visitor.VisitCompilationUnit(unit, null); ProjectDom dom = options.Dom; ICompilationUnit compilationUnit = options.ParseDocument().CompilationUnit; HashSet <string> usedUsings = new HashSet <string> (); foreach (var r in visitor.PossibleTypeReferences) { if (r is PrimitiveType) { continue; } IType type = dom.SearchType(compilationUnit, options.ResolveResult != null ? options.ResolveResult.CallingType : null, new DomLocation(options.Document.Editor.Caret.Line, options.Document.Editor.Caret.Column), r.ConvertToReturnType()); if (type != null) { usedUsings.Add(type.Namespace); } } Mono.TextEditor.TextEditorData textEditorData = options.GetTextEditorData(); HashSet <string> currentUsings = new HashSet <string> (); foreach (IUsing u in compilationUnit.Usings) { if (u.IsFromNamespace) { continue; } if (!u.Aliases.Any() && u.Namespaces.All(name => currentUsings.Contains(name) || !usedUsings.Contains(name))) { TextReplaceChange change = new TextReplaceChange(); change.FileName = options.Document.FileName; change.Offset = textEditorData.Document.LocationToOffset(u.Region.Start.Line, u.Region.Start.Column); change.RemovedChars = textEditorData.Document.LocationToOffset(u.Region.End.Line, u.Region.End.Column) - change.Offset; Mono.TextEditor.LineSegment line = textEditorData.Document.GetLineByOffset(change.Offset); if (line != null && line.EditableLength == change.RemovedChars) { change.RemovedChars += line.DelimiterLength; } result.Add(change); } foreach (string nspace in u.Namespaces) { currentUsings.Add(nspace); } } 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; 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 static TextReplaceChange GetRemoveNodeChange(this TextEditorData editor, AstNode n) { var change = new TextReplaceChange(); change.FileName = editor.FileName; change.Offset = editor.LocationToOffset(n.StartLocation); change.RemovedChars = editor.LocationToOffset(n.EndLocation) - change.Offset; // remove EOL, when line is empty var line = editor.GetLineByOffset(change.Offset); if (line != null && line.Length == change.RemovedChars) { change.RemovedChars += line.DelimiterLength; } return(change); }
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; }
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); }
public override List<Change> PerformChanges (RefactoringOptions options, object properties) { List<Change> result = new List<Change> (); ICSharpCode.NRefactory.Ast.CompilationUnit unit = options.GetASTProvider ().ParseFile (options.Document.Editor.Text); FindTypeReferencesVisitor visitor = new FindTypeReferencesVisitor (options.GetTextEditorData (), options.GetResolver ()); visitor.VisitCompilationUnit (unit, null); ProjectDom dom = options.Dom; ICompilationUnit compilationUnit = options.ParseDocument ().CompilationUnit; HashSet<string> usedUsings = new HashSet<string> (); foreach (TypeReference r in visitor.PossibleTypeReferences) { if (r.IsKeyword) continue; IType type = dom.SearchType (compilationUnit, compilationUnit, r.ConvertToReturnType ()); if (type != null) { usedUsings.Add (type.Namespace); } } Mono.TextEditor.TextEditorData textEditorData = options.GetTextEditorData (); HashSet<string> currentUsings = new HashSet<string> (); foreach (IUsing u in compilationUnit.Usings) { if (u.IsFromNamespace) continue; if (!u.Aliases.Any () && u.Namespaces.All (name => currentUsings.Contains (name) || !usedUsings.Contains (name)) ) { TextReplaceChange change = new TextReplaceChange (); change.FileName = options.Document.FileName; change.Offset = textEditorData.Document.LocationToOffset (u.Region.Start.Line, u.Region.Start.Column); change.RemovedChars = textEditorData.Document.LocationToOffset (u.Region.End.Line, u.Region.End.Column) - change.Offset; Mono.TextEditor.LineSegment line = textEditorData.Document.GetLineByOffset (change.Offset); if (line != null && line.EditableLength == change.RemovedChars) change.RemovedChars += line.DelimiterLength; result.Add (change); } foreach (string nspace in u.Namespaces) currentUsings.Add (nspace); } return result; }
public static void RenameNamespace(INamespace ns, string newName) { using (var monitor = new NullProgressMonitor()) { var col = ReferenceFinder.FindReferences(ns, true, monitor); List <Change> result = new List <Change> (); foreach (var memberRef in col) { var change = new TextReplaceChange(); change.FileName = memberRef.FileName; change.Offset = memberRef.Offset; change.RemovedChars = memberRef.Length; change.InsertedText = newName; change.Description = string.Format(GettextCatalog.GetString("Replace '{0}' with '{1}'"), memberRef.GetName(), newName); result.Add(change); } if (result.Count > 0) { RefactoringService.AcceptChanges(monitor, result); } } }
public override List <Change> PerformChanges(RefactoringOptions options, object properties) { List <Change> changes = new List <Change>(); var textReplaceChange = new TextReplaceChange(); textReplaceChange.FileName = context.GetCurrentFilePath(); textReplaceChange.RemovedChars = 0; int num = data.Document.LocationToOffset(insertionPoint.Location); textReplaceChange.Offset = num; var resolveResult = context.GetResolvedTypeNameResult(); if (resolveResult == null) { throw new InvalidOperationException("Cannot generate class here"); } var nspace = resolveResult.CallingType.Namespace; string newTypeName = resolveResult.ResolvedExpression.Expression; StringBuilder contentBuilder = new StringBuilder(); if (insertionPoint.LineBefore == NewLineInsertion.Eol) { contentBuilder.Append(data.EolMarker); } contentBuilder.Append(data.EolMarker); contentBuilder.Append(data.EolMarker); var content = fileFormatResolver.GetNewTypeContent(newTypeName, indent, data.EolMarker); contentBuilder.Append(content); if (insertionPoint.LineAfter == NewLineInsertion.None) { contentBuilder.Append(data.EolMarker); } textReplaceChange.InsertedText = contentBuilder.ToString(); changes.Add(textReplaceChange); return(changes); }
public override List <Change> PerformChanges(RefactoringOptions options, object properties) { List <Change> changes = new List <Change>(); var resolveResult = options.ResolveResult; if (resolveResult == null) { throw new InvalidOperationException("Cannot generate class here"); } var resType = resolveResult.ResolvedType; var doc = options.Document; var editor = doc.Editor; var currentDir = doc.FileName.ParentDirectory; var nspace = resType.Namespace; string typeName = resolveResult.ResolvedExpression.Expression; var body = resType.Type.BodyRegion; var content = editor.GetTextBetween(body.Start.Line, 1, body.End.Line, body.End.Column); var contentLength = content.Length; content = fileFormatResolver.GetNewTypeFileContent(content, nspace, editor.EolMarker); CreateFileChange createFileChange = new CreateFileChange(@"{0}\{1}.cs".ToFormat(currentDir, typeName), content); changes.Add(createFileChange); TextReplaceChange textReplaceChange = new TextReplaceChange(); textReplaceChange.FileName = context.GetCurrentFilePath(); textReplaceChange.RemovedChars = contentLength + 1; int num = editor.Document.LocationToOffset(body.Start.Line, 1); textReplaceChange.Offset = num - 1; textReplaceChange.InsertedText = string.Empty; changes.Add(textReplaceChange); return(changes); }
public override List <Change> PerformChanges(RefactoringOptions options, object prop) { string newName = (string)prop; List <Change> changes = new List <Change>(); using (var dialogProgressMonitor = new MessageDialogProgressMonitor(true, false, false, true)) { var references = finder.FindReferences((NamespaceResolveResult)options.ResolveResult, dialogProgressMonitor); if (references == null) { return(changes); } foreach (MemberReference memberReference in references) { TextReplaceChange textReplaceChange = new TextReplaceChange(); textReplaceChange.FileName = (string)memberReference.FileName; textReplaceChange.Offset = memberReference.Position; textReplaceChange.RemovedChars = memberReference.Name.Length; textReplaceChange.InsertedText = newName; textReplaceChange.Description = string.Format(GettextCatalog.GetString("Replace '{0}' with '{1}'"), (object)memberReference.Name, (object)newName); changes.Add((Change)textReplaceChange); } } return(changes); }
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); }
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; }
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); }
public List <Change> PerformChanges(ISymbol symbol, RenameProperties properties) { var solution = IdeApp.ProjectOperations.CurrentSelectedSolution; var ws = TypeSystemService.GetWorkspace(solution); var newSolution = Renamer.RenameSymbolAsync(ws.CurrentSolution, symbol, properties.NewName, ws.Options).Result; var result = new List <Change> (); foreach (var change in ws.CurrentSolution.GetChanges(newSolution).GetProjectChanges()) { foreach (var changedDocument in change.GetChangedDocuments()) { var oldDoc = change.OldProject.GetDocument(changedDocument); var newDoc = change.NewProject.GetDocument(changedDocument); foreach (var textChange in oldDoc.GetTextChangesAsync(newDoc).Result.OrderByDescending(ts => ts.Span.Start)) { var trChange = new TextReplaceChange(); trChange.FileName = oldDoc.FilePath; trChange.Offset = textChange.Span.Start; trChange.RemovedChars = textChange.Span.Length; trChange.InsertedText = textChange.NewText; trChange.Description = string.Format(GettextCatalog.GetString("Replace '{0}' with '{1}'"), symbol.Name, properties.NewName); result.Add(trChange); } } } if (properties.RenameFile && symbol.Kind == SymbolKind.NamedType) { int currentPart = 1; var alreadyRenamed = new HashSet <string> (); foreach (var part in symbol.Locations) { var filePath = part.SourceTree.FilePath; if (alreadyRenamed.Contains(filePath)) { continue; } alreadyRenamed.Add(filePath); string oldFileName = System.IO.Path.GetFileNameWithoutExtension(filePath); string newFileName; if (oldFileName.ToUpper() == properties.NewName.ToUpper() || oldFileName.ToUpper().EndsWith("." + properties.NewName.ToUpper(), StringComparison.Ordinal)) { continue; } int idx = oldFileName.IndexOf(symbol.Name, StringComparison.Ordinal); if (idx >= 0) { newFileName = oldFileName.Substring(0, idx) + properties.NewName + oldFileName.Substring(idx + symbol.Name.Length); } else { newFileName = currentPart != 1 ? properties.NewName + currentPart : properties.NewName; currentPart++; } int t = 0; while (System.IO.File.Exists(GetFullFileName(newFileName, filePath, t))) { t++; } result.Add(new RenameFileChange(filePath, GetFullFileName(newFileName, filePath, t))); } } 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 List<Change> PerformChanges (RefactoringOptions options, object prop) { RenameProperties properties = (RenameProperties)prop; List<Change> result = new List<Change> (); IEnumerable<MemberReference> col = null; using (var monitor = new MessageDialogProgressMonitor (true, false, false, true)) { col = ReferenceFinder.FindReferences (options.SelectedItem, true, monitor); if (col == null) return result; if (properties.RenameFile && options.SelectedItem is IType) { var cls = ((IType)options.SelectedItem).GetDefinition (); int currentPart = 1; HashSet<string> alreadyRenamed = new HashSet<string> (); foreach (var part in cls.Parts) { if (alreadyRenamed.Contains (part.Region.FileName)) continue; alreadyRenamed.Add (part.Region.FileName); string oldFileName = System.IO.Path.GetFileNameWithoutExtension (part.Region.FileName); string newFileName; if (oldFileName.ToUpper () == properties.NewName.ToUpper () || oldFileName.ToUpper ().EndsWith ("." + properties.NewName.ToUpper ())) continue; int idx = oldFileName.IndexOf (cls.Name); if (idx >= 0) { newFileName = oldFileName.Substring (0, idx) + properties.NewName + oldFileName.Substring (idx + cls.Name.Length); } else { newFileName = currentPart != 1 ? properties.NewName + currentPart : properties.NewName; currentPart++; } int t = 0; while (System.IO.File.Exists (GetFullFileName (newFileName, part.Region.FileName, t))) { t++; } result.Add (new RenameFileChange (part.Region.FileName, GetFullFileName (newFileName, part.Region.FileName, t))); } } foreach (var memberRef in col) { TextReplaceChange change = new TextReplaceChange (); change.FileName = memberRef.FileName; change.Offset = memberRef.Offset; change.RemovedChars = memberRef.Length; change.InsertedText = properties.NewName; change.Description = string.Format (GettextCatalog.GetString ("Replace '{0}' with '{1}'"), memberRef.GetName (), properties.NewName); result.Add (change); } } 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); }
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) { List <Change> result = new List <Change> (); ExtractMethodParameters param = (ExtractMethodParameters)prop; var data = options.GetTextEditorData(); // IResolver resolver = options.GetResolver (); 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 = param.StartOffset; replacement.RemovedChars = param.EndOffset - param.StartOffset; replacement.MoveCaretToReplace = true; replacement.InsertedText = GenerateMethodCall(options, param); 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); var insertionPoint = param.InsertionPoint; if (insertionPoint == null) { var points = CodeGenerationService.GetInsertionPoints(options.Document, param.DeclaringMember.DeclaringType); insertionPoint = points.LastOrDefault(p => p.Location.Line < param.DeclaringMember.Location.Line); if (insertionPoint == null) { insertionPoint = points.FirstOrDefault(); } } insertNewMethod.RemovedChars = 0; //insertionPoint.LineBefore == NewLineInsertion.Eol ? 0 : insertionPoint.Location.Column - 1; insertNewMethod.Offset = data.Document.LocationToOffset(insertionPoint.Location) - insertNewMethod.RemovedChars; insertNewMethod.InsertedText = GenerateMethodDeclaration(options, param); result.Add(insertNewMethod); /* * * 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.Editor.Caret.Line, options.Document.Editor.Caret.Column)); * 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 (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); * } * * * * 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 ()); * } * */ return(result); }
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; }
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); }
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); }
public static void RenameVariable (IVariable variable, string newName) { using (var monitor = new NullProgressMonitor ()) { var col = ReferenceFinder.FindReferences (variable, true, monitor); List<Change> result = new List<Change> (); foreach (var memberRef in col) { var change = new TextReplaceChange (); change.FileName = memberRef.FileName; change.Offset = memberRef.Offset; change.RemovedChars = memberRef.Length; change.InsertedText = newName; change.Description = string.Format (GettextCatalog.GetString ("Replace '{0}' with '{1}'"), memberRef.GetName (), newName); result.Add (change); } if (result.Count > 0) { RefactoringService.AcceptChanges (monitor, result); } } }
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; }
public static void Rename (IEntity entity, string newName) { if (newName == null) { var options = new RefactoringOptions () { SelectedItem = entity }; new RenameRefactoring ().Run (options); return; } using (var monitor = new NullProgressMonitor ()) { var col = ReferenceFinder.FindReferences (entity, true, monitor); List<Change> result = new List<Change> (); foreach (var memberRef in col) { var change = new TextReplaceChange (); change.FileName = memberRef.FileName; change.Offset = memberRef.Offset; change.RemovedChars = memberRef.Length; change.InsertedText = newName; change.Description = string.Format (GettextCatalog.GetString ("Replace '{0}' with '{1}'"), memberRef.GetName (), newName); result.Add (change); } if (result.Count > 0) { RefactoringService.AcceptChanges (monitor, result); } } }
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.Editor.SelectionRange.Offset; replacement.RemovedChars = options.Document.Editor.SelectionRange.Length; replacement.MoveCaretToReplace = true; LineSegment line1 = data.Document.GetLineByOffset (options.Document.Editor.SelectionRange.EndOffset); if (options.Document.Editor.SelectionRange.EndOffset == line1.Offset) { if (line1.Offset > 0) { LineSegment line2 = data.Document.GetLineByOffset (line1.Offset - 1); replacement.RemovedChars -= line2.DelimiterLength; } } replacement.InsertedText = options.GetWhitespaces (options.Document.Editor.SelectionRange.Offset) + 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.Editor.Caret.Line, options.Document.Editor.Caret.Column)); 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; }
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); }
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, data.Caret.Line ); 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, containing.StartLocation.Column); lineSegment = data.Document.GetLineByOffset (insert.Offset); insert.RemovedChars = data.Document.LocationToOffset (containing.EndLocation.Line, containing.EndLocation.Column) - 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, blockVisitor.ContainingStatement.StartLocation.Column); lineSegment = data.Document.GetLineByOffset (insert.Offset); insert.RemovedChars = data.Document.LocationToOffset (blockVisitor.ContainingStatement.EndLocation.Line, blockVisitor.ContainingStatement.EndLocation.Column) - 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.Editor.Caret.Line, options.Document.Editor.Caret.Column)); 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; }
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); }
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, type.CompilationUnit.FileName, true) + Environment.NewLine); INRefactoryASTProvider provider = options.GetASTProvider (); Mono.TextEditor.TextEditorData data = options.GetTextEditorData (); ICSharpCode.NRefactory.Ast.CompilationUnit unit = provider.ParseFile (options.Document.TextEditor.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 = -1; int minLine = typeFilterTransformer.TypeDeclaration.StartLocation.Line; foreach (var attr in typeFilterTransformer.TypeDeclaration.Attributes) { minLine = Math.Min (minLine, attr.StartLocation.Line); } for (int i = minLine - 2; i >= 0; 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 >= 0) { start = data.Document.GetLine (startLine).Offset; } else { var startLocation = typeFilterTransformer.TypeDeclaration.StartLocation; startLocation.Column = 0; foreach (var attr in typeFilterTransformer.TypeDeclaration.Attributes) { if (attr.StartLocation < startLocation) startLocation = attr.StartLocation; } start = data.Document.LocationToOffset (startLocation.Line - 1, 0); } int length = data.Document.LocationToOffset (typeFilterTransformer.TypeDeclaration.EndLocation.Line - 1, 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 - 1, 0); foreach (var attr in typeSearchVisitor.Types[0].Attributes) { genStart = Math.Min (genStart, generatedDocument.LocationToOffset (attr.StartLocation.Line - 1, 0)); } int genEnd = generatedDocument.LocationToOffset (typeSearchVisitor.Types[0].EndLocation.Line - 1, typeSearchVisitor.Types[0].EndLocation.Column - 1); ((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; }
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.InsertedText = ""; string indent = ""; MethodDeclaration methodDecl = new MethodDeclaration (); bool isInInterface = false; if (invoke.TargetObject is IdentifierExpression) { insertNewMethod.FileName = options.Document.FileName; insertNewMethod.Offset = options.Document.TextEditor.GetPositionFromLineColumn (options.ResolveResult.CallingMember.BodyRegion.End.Line, options.ResolveResult.CallingMember.BodyRegion.End.Column); methodDecl.Name = ((IdentifierExpression)invoke.TargetObject).Identifier; indent = options.GetIndent (options.ResolveResult.CallingMember); insertNewMethod.InsertedText = Environment.NewLine; if (options.ResolveResult.CallingMember.IsStatic) methodDecl.Modifier |= ICSharpCode.NRefactory.Ast.Modifiers.Static; } else { methodDecl.Name = ((MemberReferenceExpression)invoke.TargetObject).MemberName; string callingObject = provider.OutputNode (options.Dom, ((MemberReferenceExpression)invoke.TargetObject).TargetObject); ResolveResult resolveResult = resolver.Resolve (new ExpressionResult (callingObject), resolvePosition); IType type = options.Dom.GetType (resolveResult.ResolvedType); insertNewMethod.FileName = type.CompilationUnit.FileName; if (resolveResult.StaticResolve) methodDecl.Modifier |= ICSharpCode.NRefactory.Ast.Modifiers.Static; if (insertNewMethod.FileName == options.Document.FileName) { indent = options.GetIndent (options.ResolveResult.CallingMember); insertNewMethod.InsertedText = Environment.NewLine; insertNewMethod.Offset = options.Document.TextEditor.GetPositionFromLineColumn (options.ResolveResult.CallingMember.BodyRegion.End.Line, options.ResolveResult.CallingMember.BodyRegion.End.Column); } else { TextEditorData otherFile = TextReplaceChange.GetTextEditorData (insertNewMethod.FileName); if (otherFile == null) { IdeApp.Workbench.OpenDocument (insertNewMethod.FileName); otherFile = TextReplaceChange.GetTextEditorData (insertNewMethod.FileName); } methodDecl.Modifier |= ICSharpCode.NRefactory.Ast.Modifiers.Public; isInInterface = type.ClassType == MonoDevelop.Projects.Dom.ClassType.Interface; if (isInInterface) methodDecl.Modifier = ICSharpCode.NRefactory.Ast.Modifiers.None; if (otherFile == null) throw new InvalidOperationException ("Can't open file:" + insertNewMethod.FileName); try { indent = otherFile.Document.GetLine (type.Location.Line - 1).GetIndentation (otherFile.Document) ?? ""; } catch (Exception) { indent = ""; } indent += "\t"; insertNewMethod.Offset = otherFile.Document.LocationToOffset (type.BodyRegion.End.Line - 1, 0); } } methodDecl.Modifier = modifiers; methodDecl.TypeReference = HelperMethods.ConvertToTypeReference (returnType); 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 if (IsValidIdentifier (lastName)) parameterName = lastName; 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"); typeReference.IsKeyword = true; ParameterDeclarationExpression pde = new ParameterDeclarationExpression (typeReference, parameterName); methodDecl.Parameters.Add (pde); } insertNewMethod.InsertedText += Environment.NewLine + provider.OutputNode (options.Dom, methodDecl, indent); result.Add (insertNewMethod); fileName = insertNewMethod.FileName; 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; }
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) { var stack = line.StartSpan.Clone (); 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, resolveResult.ResolvedExpression.Region.Start.Column); end = data.Document.LocationToOffset (resolveResult.ResolvedExpression.Region.End.Line, resolveResult.ResolvedExpression.Region.End.Column); } 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); 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) { 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; }
public override List<Change> PerformChanges (RefactoringOptions options, object prop) { RenameProperties properties = (RenameProperties)prop; List<Change> result = new List<Change> (); MemberReferenceCollection col = GetReferences (options); if (col == null) return result; if (properties.RenameFile && options.SelectedItem is IType) { IType cls = (IType)options.SelectedItem; int currentPart = 1; HashSet<string> alreadyRenamed = new HashSet<string> (); foreach (IType part in cls.Parts) { if (part.CompilationUnit.FileName != options.Document.FileName && System.IO.Path.GetFileNameWithoutExtension (part.CompilationUnit.FileName) != System.IO.Path.GetFileNameWithoutExtension (options.Document.FileName)) continue; if (alreadyRenamed.Contains (part.CompilationUnit.FileName)) continue; alreadyRenamed.Add (part.CompilationUnit.FileName); string oldFileName = System.IO.Path.GetFileNameWithoutExtension (part.CompilationUnit.FileName); string newFileName; int idx = oldFileName.IndexOf (cls.Name); if (idx >= 0) { newFileName = oldFileName.Substring (0, idx) + properties.NewName + oldFileName.Substring (idx + cls.Name.Length); } else { newFileName = currentPart != 1 ? properties.NewName + currentPart : properties.NewName; currentPart++; } int t = 0; while (System.IO.File.Exists (GetFullFileName (newFileName, part.CompilationUnit.FileName, t))) { t++; } result.Add (new RenameFileChange (part.CompilationUnit.FileName, GetFullFileName (newFileName, part.CompilationUnit.FileName, t))); } } foreach (MemberReference memberRef in col) { TextReplaceChange change = new TextReplaceChange (); change.FileName = memberRef.FileName; change.Offset = memberRef.Position; change.RemovedChars = memberRef.Name.Length; change.InsertedText = properties.NewName; change.Description = string.Format (GettextCatalog.GetString ("Replace '{0}' with '{1}'"), memberRef.Name, properties.NewName); result.Add (change); } 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; 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; 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; }
public override List <Change> PerformChanges(RefactoringOptions options, object prop) { RenameProperties properties = (RenameProperties)prop; List <Change> result = new List <Change> (); IEnumerable <MemberReference> col = null; using (var monitor = new MessageDialogProgressMonitor(true, false, false, true)) { col = ReferenceFinder.FindReferences(options.SelectedItem, properties.IncludeOverloads, monitor); if (col == null) { return(result); } if (properties.RenameFile && options.SelectedItem is IType) { var cls = ((IType)options.SelectedItem).GetDefinition(); int currentPart = 1; var alreadyRenamed = new HashSet <string> (); foreach (var part in cls.Parts) { if (alreadyRenamed.Contains(part.Region.FileName)) { continue; } alreadyRenamed.Add(part.Region.FileName); string oldFileName = System.IO.Path.GetFileNameWithoutExtension(part.Region.FileName); string newFileName; var newName = properties.NewName; if (string.IsNullOrEmpty(oldFileName) || string.IsNullOrEmpty(newName)) { continue; } if (oldFileName.ToUpper() == newName.ToUpper() || oldFileName.ToUpper().EndsWith("." + newName.ToUpper(), StringComparison.Ordinal)) { continue; } int idx = oldFileName.IndexOf(cls.Name, StringComparison.Ordinal); if (idx >= 0) { newFileName = oldFileName.Substring(0, idx) + newName + oldFileName.Substring(idx + cls.Name.Length); } else { newFileName = currentPart != 1 ? newName + currentPart : newName; currentPart++; } int t = 0; while (System.IO.File.Exists(GetFullFileName(newFileName, part.Region.FileName, t))) { t++; } result.Add(new RenameFileChange(part.Region.FileName, GetFullFileName(newFileName, part.Region.FileName, t))); } } foreach (var memberRef in col) { TextReplaceChange change = new TextReplaceChange(); change.FileName = memberRef.FileName; change.Offset = memberRef.Offset; change.RemovedChars = memberRef.Length; change.InsertedText = properties.NewName; change.Description = string.Format(GettextCatalog.GetString("Replace '{0}' with '{1}'"), memberRef.GetName(), properties.NewName); result.Add(change); } } return(result); }
public List<Change> PerformChanges (ISymbol symbol, RenameProperties properties) { var solution = IdeApp.ProjectOperations.CurrentSelectedSolution; var ws = TypeSystemService.GetWorkspace (solution); var newSolution = Renamer.RenameSymbolAsync (ws.CurrentSolution, symbol, properties.NewName, ws.Options).Result; var result = new List<Change> (); foreach (var change in ws.CurrentSolution.GetChanges (newSolution).GetProjectChanges ()) { foreach (var changedDocument in change.GetChangedDocuments ()) { var oldDoc = change.OldProject.GetDocument (changedDocument); var newDoc = change.NewProject.GetDocument (changedDocument); foreach (var textChange in oldDoc.GetTextChangesAsync (newDoc).Result.OrderByDescending(ts => ts.Span.Start)) { var trChange = new TextReplaceChange (); trChange.FileName = oldDoc.FilePath; trChange.Offset = textChange.Span.Start; trChange.RemovedChars = textChange.Span.Length; trChange.InsertedText = textChange.NewText; trChange.Description = string.Format (GettextCatalog.GetString ("Replace '{0}' with '{1}'"), symbol.Name, properties.NewName); result.Add (trChange); } } } if (properties.RenameFile && symbol.Kind == SymbolKind.NamedType) { int currentPart = 1; var alreadyRenamed = new HashSet<string> (); foreach (var part in symbol.Locations) { var filePath = part.SourceTree.FilePath; if (alreadyRenamed.Contains (filePath)) continue; alreadyRenamed.Add (filePath); string oldFileName = System.IO.Path.GetFileNameWithoutExtension (filePath); string newFileName; if (oldFileName.ToUpper () == properties.NewName.ToUpper () || oldFileName.ToUpper ().EndsWith ("." + properties.NewName.ToUpper (), StringComparison.Ordinal)) continue; int idx = oldFileName.IndexOf (symbol.Name, StringComparison.Ordinal); if (idx >= 0) { newFileName = oldFileName.Substring (0, idx) + properties.NewName + oldFileName.Substring (idx + symbol.Name.Length); } else { newFileName = currentPart != 1 ? properties.NewName + currentPart : properties.NewName; currentPart++; } int t = 0; while (System.IO.File.Exists (GetFullFileName (newFileName, filePath, t))) { t++; } result.Add (new RenameFileChange (filePath, GetFullFileName (newFileName, filePath, t))); } } return result; }
public override List <Change> PerformChanges(RefactoringOptions options, object prop) { RenameProperties properties = (RenameProperties)prop; List <Change> result = new List <Change> (); MemberReferenceCollection col = GetReferences(options); if (col == null) { return(result); } if (properties.RenameFile && options.SelectedItem is IType) { IType cls = (IType)options.SelectedItem; int currentPart = 1; HashSet <string> alreadyRenamed = new HashSet <string> (); foreach (IType part in cls.Parts) { if (part.CompilationUnit.FileName != options.Document.FileName && System.IO.Path.GetFileNameWithoutExtension(part.CompilationUnit.FileName) != System.IO.Path.GetFileNameWithoutExtension(options.Document.FileName)) { continue; } if (alreadyRenamed.Contains(part.CompilationUnit.FileName)) { continue; } alreadyRenamed.Add(part.CompilationUnit.FileName); string oldFileName = System.IO.Path.GetFileNameWithoutExtension(part.CompilationUnit.FileName); string newFileName; int idx = oldFileName.IndexOf(cls.Name); if (idx >= 0) { newFileName = oldFileName.Substring(0, idx) + properties.NewName + oldFileName.Substring(idx + cls.Name.Length); } else { newFileName = currentPart != 1 ? properties.NewName + currentPart : properties.NewName; currentPart++; } int t = 0; while (System.IO.File.Exists(GetFullFileName(newFileName, part.CompilationUnit.FileName, t))) { t++; } result.Add(new RenameFileChange(part.CompilationUnit.FileName, GetFullFileName(newFileName, part.CompilationUnit.FileName, t))); } } foreach (MemberReference memberRef in col) { TextReplaceChange change = new TextReplaceChange(); change.FileName = memberRef.FileName; change.Offset = memberRef.Position; change.RemovedChars = memberRef.Name.Length; change.InsertedText = properties.NewName; change.Description = string.Format(GettextCatalog.GetString("Replace '{0}' with '{1}'"), memberRef.Name, properties.NewName); result.Add(change); } return(result); }