~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/addins/MonoDevelop.Refactoring/MonoDevelop.Refactoring.Rename/RenameRefactoring.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
using System.Text;
35
35
using MonoDevelop.Ide;
36
36
using System.Linq;
 
37
using Mono.TextEditor.PopupWindow;
 
38
using MonoDevelop.Ide.FindInFiles;
 
39
using MonoDevelop.Ide.ProgressMonitoring;
37
40
 
38
41
namespace MonoDevelop.Refactoring.Rename
39
42
{
41
44
        {
42
45
                public override string AccelKey {
43
46
                        get {
44
 
                                var key = IdeApp.CommandService.GetCommandInfo (RefactoryCommands.Rename).AccelKey;
 
47
                                var key = IdeApp.CommandService.GetCommandInfo (MonoDevelop.Ide.Commands.EditCommands.Rename).AccelKey;
45
48
                                return key == null ? null : key.Replace ("dead_circumflex", "^");
46
49
                        }
47
50
                }
68
71
                
69
72
                public override string GetMenuDescription (RefactoringOptions options)
70
73
                {
71
 
                        return IdeApp.CommandService.GetCommandInfo (RefactoryCommands.Rename).Text;
 
74
                        return IdeApp.CommandService.GetCommandInfo (MonoDevelop.Ide.Commands.EditCommands.Rename).Text;
72
75
                }
73
76
                
74
77
                public override void Run (RefactoringOptions options)
75
78
                {
76
79
                        if (options.SelectedItem is LocalVariable || options.SelectedItem is IParameter) {
77
 
                                MemberReferenceCollection col = GetReferences (options);
 
80
                                var col = ReferenceFinder.FindReferences (options.SelectedItem);
78
81
                                if (col == null)
79
82
                                        return;
80
83
                                TextEditorData data = options.GetTextEditorData ();
83
86
                                        MessageService.ShowCustomDialog (new RenameItemDialog (options, this));
84
87
                                        return;
85
88
                                }
86
 
 
87
89
                                
88
90
                                List<TextLink> links = new List<TextLink> ();
89
91
                                TextLink link = new TextLink ("name");
90
92
                                int baseOffset = Int32.MaxValue;
91
93
                                foreach (MemberReference r in col) {
92
 
                                        baseOffset = Math.Min (baseOffset, data.Document.LocationToOffset (r.Line - 1, r.Column - 1));
 
94
                                        baseOffset = Math.Min (baseOffset, data.Document.LocationToOffset (r.Line, r.Column));
93
95
                                }
94
96
                                foreach (MemberReference r in col) {
95
 
                                        Segment segment = new Segment (data.Document.LocationToOffset (r.Line - 1, r.Column - 1) - baseOffset, r.Name.Length);
 
97
                                        Segment segment = new Segment (data.Document.LocationToOffset (r.Line, r.Column) - baseOffset, r.Name.Length);
96
98
                                        if (segment.Offset <= data.Caret.Offset - baseOffset && data.Caret.Offset - baseOffset <= segment.EndOffset) {
97
99
                                                link.Links.Insert (0, segment); 
98
100
                                        } else {
101
103
                                }
102
104
                                
103
105
                                links.Add (link);
 
106
                                if (editor.CurrentMode is TextLinkEditMode)
 
107
                                        ((TextLinkEditMode)editor.CurrentMode).ExitTextLinkMode ();
104
108
                                TextLinkEditMode tle = new TextLinkEditMode (editor, baseOffset, links);
105
109
                                tle.SetCaretPosition = false;
106
110
                                tle.SelectPrimaryLink = true;
107
111
                                if (tle.ShouldStartTextLinkMode) {
 
112
                                        ModeHelpWindow helpWindow = new ModeHelpWindow ();
 
113
                                        helpWindow.TransientFor = IdeApp.Workbench.RootWindow;
 
114
                                        helpWindow.TitleText = options.SelectedItem is LocalVariable ? GettextCatalog.GetString ("<b>Local Variable -- Renaming</b>") : GettextCatalog.GetString ("<b>Parameter -- Renaming</b>");
 
115
                                        helpWindow.Items.Add (new KeyValuePair<string, string> (GettextCatalog.GetString ("<b>Key</b>"), GettextCatalog.GetString ("<b>Behavior</b>")));
 
116
                                        helpWindow.Items.Add (new KeyValuePair<string, string> (GettextCatalog.GetString ("<b>Return</b>"), GettextCatalog.GetString ("<b>Accept</b> this refactoring.")));
 
117
                                        helpWindow.Items.Add (new KeyValuePair<string, string> (GettextCatalog.GetString ("<b>Esc</b>"), GettextCatalog.GetString ("<b>Cancel</b> this refactoring.")));
 
118
                                        tle.HelpWindow = helpWindow;
 
119
                                        tle.Cancel += delegate {
 
120
                                                if (tle.HasChangedText)
 
121
                                                        editor.Document.Undo ();
 
122
                                        };
108
123
                                        tle.OldMode = data.CurrentMode;
109
124
                                        tle.StartMode ();
110
125
                                        data.CurrentMode = tle;
131
146
                {
132
147
                        RenameProperties properties = (RenameProperties)prop;
133
148
                        List<Change> result = new List<Change> ();
134
 
 
135
 
                        MemberReferenceCollection col = GetReferences (options);
136
 
                        if (col == null)
137
 
                                return result;
138
 
                        
139
 
                        if (properties.RenameFile && options.SelectedItem is IType) {
140
 
                                IType cls = (IType)options.SelectedItem;
141
 
                                int currentPart = 1;
142
 
                                HashSet<string> alreadyRenamed = new HashSet<string> ();
143
 
                                foreach (IType part in cls.Parts) {
144
 
                                        if (part.CompilationUnit.FileName != options.Document.FileName && System.IO.Path.GetFileNameWithoutExtension (part.CompilationUnit.FileName) != System.IO.Path.GetFileNameWithoutExtension (options.Document.FileName))
145
 
                                                continue;
146
 
                                        if (alreadyRenamed.Contains (part.CompilationUnit.FileName))
147
 
                                                continue;
148
 
                                        alreadyRenamed.Add (part.CompilationUnit.FileName);
149
 
                                        
150
 
                                        string oldFileName = System.IO.Path.GetFileNameWithoutExtension (part.CompilationUnit.FileName);
151
 
                                        string newFileName;
152
 
                                        
153
 
                                        int idx = oldFileName.IndexOf (cls.Name);
154
 
                                        if (idx >= 0) {
155
 
                                                newFileName = oldFileName.Substring (0, idx) + properties.NewName + oldFileName.Substring (idx + cls.Name.Length);
156
 
                                        } else {
157
 
                                                newFileName = currentPart != 1 ? properties.NewName + currentPart : properties.NewName;
158
 
                                                currentPart++;
159
 
                                        }
160
 
                                        
161
 
                                        int t = 0;
162
 
                                        while (System.IO.File.Exists (GetFullFileName (newFileName, part.CompilationUnit.FileName, t))) {
163
 
                                                t++;
164
 
                                        }
165
 
                                        result.Add (new RenameFileChange (part.CompilationUnit.FileName, GetFullFileName (newFileName, part.CompilationUnit.FileName, t)));
166
 
                                }
167
 
                        }
168
 
                        
169
 
                        foreach (MemberReference memberRef in col) {
170
 
                                TextReplaceChange change = new TextReplaceChange ();
171
 
                                change.FileName = memberRef.FileName;
172
 
                                change.Offset = memberRef.Position;
173
 
                                change.RemovedChars = memberRef.Name.Length;
174
 
                                change.InsertedText = properties.NewName;
175
 
                                change.Description = string.Format (GettextCatalog.GetString ("Replace '{0}' with '{1}'"), memberRef.Name, properties.NewName);
176
 
                                result.Add (change);
 
149
                        IEnumerable<MemberReference> col = null;
 
150
                        using (var monitor = new MessageDialogProgressMonitor (true, false, false, true)) {
 
151
                                col = ReferenceFinder.FindReferences (options.SelectedItem, monitor);
 
152
                                if (col == null)
 
153
                                        return result;
 
154
                                        
 
155
                                if (properties.RenameFile && options.SelectedItem is IType) {
 
156
                                        IType cls = (IType)options.SelectedItem;
 
157
                                        int currentPart = 1;
 
158
                                        HashSet<string> alreadyRenamed = new HashSet<string> ();
 
159
                                        foreach (IType part in cls.Parts) {
 
160
                                                if (part.CompilationUnit.FileName != options.Document.FileName && System.IO.Path.GetFileNameWithoutExtension (part.CompilationUnit.FileName) != System.IO.Path.GetFileNameWithoutExtension (options.Document.FileName))
 
161
                                                        continue;
 
162
                                                if (alreadyRenamed.Contains (part.CompilationUnit.FileName))
 
163
                                                        continue;
 
164
                                                alreadyRenamed.Add (part.CompilationUnit.FileName);
 
165
                                                        
 
166
                                                string oldFileName = System.IO.Path.GetFileNameWithoutExtension (part.CompilationUnit.FileName);
 
167
                                                string newFileName;
 
168
                                                if (oldFileName.ToUpper () == properties.NewName.ToUpper () || oldFileName.ToUpper ().EndsWith ("." + properties.NewName.ToUpper ()))
 
169
                                                        continue;
 
170
                                                int idx = oldFileName.IndexOf (cls.Name);
 
171
                                                if (idx >= 0) {
 
172
                                                        newFileName = oldFileName.Substring (0, idx) + properties.NewName + oldFileName.Substring (idx + cls.Name.Length);
 
173
                                                } else {
 
174
                                                        newFileName = currentPart != 1 ? properties.NewName + currentPart : properties.NewName;
 
175
                                                        currentPart++;
 
176
                                                }
 
177
                                                        
 
178
                                                int t = 0;
 
179
                                                while (System.IO.File.Exists (GetFullFileName (newFileName, part.CompilationUnit.FileName, t))) {
 
180
                                                        t++;
 
181
                                                }
 
182
                                                result.Add (new RenameFileChange (part.CompilationUnit.FileName, GetFullFileName (newFileName, part.CompilationUnit.FileName, t)));
 
183
                                        }
 
184
                                }
 
185
                                
 
186
                                foreach (MemberReference memberRef in col) {
 
187
                                        TextReplaceChange change = new TextReplaceChange ();
 
188
                                        change.FileName = memberRef.FileName;
 
189
                                        change.Offset = memberRef.Position;
 
190
                                        change.RemovedChars = memberRef.Name.Length;
 
191
                                        change.InsertedText = properties.NewName;
 
192
                                        change.Description = string.Format (GettextCatalog.GetString ("Replace '{0}' with '{1}'"), memberRef.Name, properties.NewName);
 
193
                                        result.Add (change);
 
194
                                }
177
195
                        }
178
196
                        return result;
179
197
                }
190
208
                        
191
209
                        return System.IO.Path.Combine (System.IO.Path.GetDirectoryName (oldFullFileName), name.ToString ());
192
210
                }
193
 
                
194
 
                MemberReferenceCollection GetReferences (RefactoringOptions options)
195
 
                {
196
 
                        CodeRefactorer refactorer = IdeApp.Workspace.GetCodeRefactorer (IdeApp.ProjectOperations.CurrentSelectedSolution);
197
 
                        IProgressMonitor monitor = IdeApp.Workbench.ProgressMonitors.GetBackgroundProgressMonitor (this.Name, null);
198
 
                        if (options.SelectedItem is IType) {
199
 
                                IType cls = (IType)options.SelectedItem;
200
 
                                return refactorer.FindClassReferences (monitor, cls, RefactoryScope.Solution, true);
201
 
                        } else if (options.SelectedItem is LocalVariable) {
202
 
                                return refactorer.FindVariableReferences (monitor, (LocalVariable)options.SelectedItem);
203
 
                        } else if (options.SelectedItem is IParameter) {
204
 
                                return refactorer.FindParameterReferences (monitor, (IParameter)options.SelectedItem, true);
205
 
                        } else if (options.SelectedItem is IMember) {
206
 
                                IMember member = (IMember)options.SelectedItem;
207
 
                                Dictionary<string, HashSet<DomLocation>> foundLocations = new Dictionary <string, HashSet<DomLocation>> ();
208
 
                                MemberReferenceCollection result = new MemberReferenceCollection ();
209
 
                                foreach (IMember m in CollectMembers (member.DeclaringType.SourceProjectDom, member)) {
210
 
                                        foreach (MemberReference r in refactorer.FindMemberReferences (monitor, m.DeclaringType, m, true)) {
211
 
                                                DomLocation location = new DomLocation (r.Line, r.Column);
212
 
                                                if (!foundLocations.ContainsKey (r.FileName))
213
 
                                                        foundLocations[r.FileName] = new HashSet<DomLocation> ();
214
 
                                                if (foundLocations[r.FileName].Contains (location))
215
 
                                                        continue;
216
 
                                                foundLocations[r.FileName].Add (location);
217
 
                                                result.Add (r);
218
 
                                        }
219
 
                                }
220
 
                                return result;
221
 
                        }
222
 
                        return null;
223
 
                }
224
 
                
225
 
                internal static IEnumerable<IMember> CollectMembers (ProjectDom dom, IMember member)
226
 
                {
227
 
                        if (member is IMethod && ((IMethod)member).IsConstructor) {
228
 
                                yield return member;
229
 
                        } else {
230
 
                                bool isOverrideable = member.DeclaringType.ClassType == ClassType.Interface || member.IsOverride || member.IsVirtual || member.IsAbstract;
231
 
                                bool isLastMember = false;
232
 
                                // for members we need to collect the whole 'class' of members (overloads & implementing types)
233
 
                                HashSet<string> alreadyVisitedTypes = new HashSet<string> ();
234
 
                                foreach (IType type in dom.GetInheritanceTree (member.DeclaringType)) {
235
 
                                        if (type.ClassType == ClassType.Interface || isOverrideable || type.DecoratedFullName == member.DeclaringType.DecoratedFullName) {
236
 
                                                // search in the class for the member
237
 
                                                foreach (IMember interfaceMember in type.SearchMember (member.Name, true)) {
238
 
                                                        if (interfaceMember.MemberType == member.MemberType)
239
 
                                                                yield return interfaceMember;
240
 
                                                }
241
 
                                                
242
 
                                                // now search in all subclasses of this class for the member
243
 
                                                isLastMember = !member.IsOverride;
244
 
                                                foreach (IType implementingType in dom.GetSubclasses (type)) {
245
 
                                                        string name = implementingType.DecoratedFullName;
246
 
                                                        if (alreadyVisitedTypes.Contains (name))
247
 
                                                                continue;
248
 
                                                        alreadyVisitedTypes.Add (name);
249
 
                                                        foreach (IMember typeMember in implementingType.SearchMember (member.Name, true)) {
250
 
                                                                if (typeMember.MemberType == member.MemberType) {
251
 
                                                                        isLastMember = type.ClassType != ClassType.Interface && (typeMember.IsVirtual || typeMember.IsAbstract || !typeMember.IsOverride);
252
 
                                                                        yield return typeMember;
253
 
                                                                }
254
 
                                                        }
255
 
                                                        if (!isOverrideable)
256
 
                                                                break;
257
 
                                                }
258
 
                                                if (isLastMember)
259
 
                                                        break;
260
 
                                        }
261
 
                                }
262
 
                        }
263
 
                }
264
211
        }
265
212
}