28
28
using System.Collections.Generic;
30
using MonoDevelop.Projects.CodeGeneration;
31
30
using MonoDevelop.Core;
32
using MonoDevelop.Projects.Dom.Parser;
33
31
using MonoDevelop.Ide.Gui;
34
using MonoDevelop.CodeGeneration;
35
using MonoDevelop.Projects.Dom;
37
33
using MonoDevelop.AnalysisCore;
38
using MonoDevelop.Inspection;
34
using ICSharpCode.NRefactory;
35
using System.Threading.Tasks;
36
using System.Threading;
37
using MonoDevelop.CodeActions;
38
using MonoDevelop.CodeIssues;
39
using Mono.TextEditor;
40
41
namespace MonoDevelop.Refactoring
42
using MonoDevelop.ContextAction;
44
43
public static class RefactoringService
46
45
static List<RefactoringOperation> refactorings = new List<RefactoringOperation>();
47
static List<INRefactoryASTProvider> astProviders = new List<INRefactoryASTProvider>();
48
static List<ICodeGenerator> codeGenerators = new List<ICodeGenerator>();
49
static List<ContextActionAddinNode> contextActions = new List<ContextActionAddinNode> ();
50
static List<InspectorAddinNode> inspectors = new List<InspectorAddinNode> ();
46
static List<CodeActionProvider> contextActions = new List<CodeActionProvider> ();
47
static List<CodeIssueProvider> inspectors = new List<CodeIssueProvider> ();
52
public static IEnumerable<ContextActionAddinNode> ContextAddinNodes {
49
public static IEnumerable<CodeActionProvider> ContextAddinNodes {
54
51
return contextActions;
55
public static void AddProvider (CodeActionProvider provider)
57
contextActions.Add (provider);
60
public static void AddProvider (CodeIssueProvider provider)
62
inspectors.Add (provider);
65
public static List<CodeIssueProvider> Inspectors {
58
71
static RefactoringService ()
60
73
AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Refactoring/Refactorings", delegate(object sender, ExtensionNodeEventArgs args) {
71
AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Refactoring/ASTProvider", delegate(object sender, ExtensionNodeEventArgs args) {
85
AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Refactoring/CodeActions", delegate(object sender, ExtensionNodeEventArgs args) {
72
86
switch (args.Change) {
73
87
case ExtensionChange.Add:
74
astProviders.Add ((INRefactoryASTProvider)args.ExtensionObject);
88
contextActions.Add (((CodeActionAddinNode)args.ExtensionNode).Action);
76
90
case ExtensionChange.Remove:
77
astProviders.Remove ((INRefactoryASTProvider)args.ExtensionObject);
91
contextActions.Remove (((CodeActionAddinNode)args.ExtensionNode).Action);
96
AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Refactoring/CodeActionSource", delegate(object sender, ExtensionNodeEventArgs args) {
97
switch (args.Change) {
98
case ExtensionChange.Add:
99
contextActions.AddRange (((ICodeActionProviderSource)args.ExtensionObject).GetProviders ());
82
AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Refactoring/CodeGenerators", delegate(object sender, ExtensionNodeEventArgs args) {
104
AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Refactoring/CodeIssues", delegate(object sender, ExtensionNodeEventArgs args) {
83
105
switch (args.Change) {
84
106
case ExtensionChange.Add:
85
codeGenerators.Add ((ICodeGenerator)args.ExtensionObject);
107
inspectors.Add (((CodeIssueAddinNode)args.ExtensionNode).Inspector);
87
109
case ExtensionChange.Remove:
88
codeGenerators.Remove ((ICodeGenerator)args.ExtensionObject);
110
inspectors.Remove (((CodeIssueAddinNode)args.ExtensionNode).Inspector);
93
// AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Refactoring/ContextActions", delegate(object sender, ExtensionNodeEventArgs args) {
94
// switch (args.Change) {
95
// case ExtensionChange.Add:
96
// contextActions.Add ((ContextActionAddinNode)args.ExtensionNode);
98
// case ExtensionChange.Remove:
99
// contextActions.Remove ((ContextActionAddinNode)args.ExtensionNode);
104
AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Refactoring/Inspectors", delegate(object sender, ExtensionNodeEventArgs args) {
115
AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Refactoring/CodeIssueSource", delegate(object sender, ExtensionNodeEventArgs args) {
105
116
switch (args.Change) {
106
117
case ExtensionChange.Add:
107
inspectors.Add ((InspectorAddinNode)args.ExtensionNode);
109
case ExtensionChange.Remove:
110
inspectors.Remove ((InspectorAddinNode)args.ExtensionNode);
118
inspectors.AddRange (((ICodeIssueProviderSource)args.ExtensionObject).GetProviders ());
150
public static void AcceptChanges (IProgressMonitor monitor, ProjectDom dom, List<Change> changes)
152
public static void AcceptChanges (IProgressMonitor monitor, List<Change> changes)
152
AcceptChanges (monitor, dom, changes, MonoDevelop.Ide.TextFileProvider.Instance);
154
AcceptChanges (monitor, changes, MonoDevelop.Ide.TextFileProvider.Instance);
155
public static void AcceptChanges (IProgressMonitor monitor, ProjectDom dom, List<Change> changes, MonoDevelop.Projects.Text.ITextFileProvider fileProvider)
157
public static void AcceptChanges (IProgressMonitor monitor, List<Change> changes, MonoDevelop.Projects.Text.ITextFileProvider fileProvider)
157
var rctx = new RefactorerContext (dom, fileProvider, null);
159
var rctx = new RefactoringOptions (null);
158
160
var handler = new RenameHandler (changes);
159
161
FileService.FileRenamed += handler.FileRename;
160
162
for (int i = 0; i < changes.Count; i++) {
182
184
TextReplaceChange.FinishRefactoringOperation ();
185
public static INRefactoryASTProvider GetASTProvider (string mimeType)
187
foreach (INRefactoryASTProvider provider in astProviders) {
188
if (provider.CanGenerateASTFrom (mimeType)) {
187
public static IEnumerable<CodeIssueProvider> GetInspectors (string mimeType)
189
return inspectors.Where (i => i.MimeType == mimeType);
192
public static Task<IEnumerable<MonoDevelop.CodeActions.CodeAction>> GetValidActions (MonoDevelop.Ide.Gui.Document doc, TextLocation loc, CancellationToken cancellationToken = default (CancellationToken))
194
return Task.Factory.StartNew (delegate {
195
var result = new List<MonoDevelop.CodeActions.CodeAction> ();
197
var editor = doc.Editor;
198
if (editor != null) {
199
string disabledNodes = PropertyService.Get ("ContextActions." + editor.Document.MimeType, "") ?? "";
200
foreach (var provider in contextActions.Where (fix => disabledNodes.IndexOf (fix.IdString) < 0)) {
202
result.AddRange (provider.GetActions (doc, loc, cancellationToken));
203
} catch (Exception ex) {
204
LoggingService.LogError ("Error in context action provider " + provider.Title, ex);
208
} catch (Exception ex) {
209
LoggingService.LogError ("Error in analysis service", ex);
195
public static IEnumerable<InspectorAddinNode> GetInspectors (string mimeTye)
197
return inspectors.Where (i => i.MimeType == mimeTye);
200
public static void QueueQuickFixAnalysis (MonoDevelop.Ide.Gui.Document doc, DomLocation loc, Action<List<ContextAction>> callback)
211
return (IEnumerable<MonoDevelop.CodeActions.CodeAction>)result;
212
}, cancellationToken);
215
public static void QueueQuickFixAnalysis (MonoDevelop.Ide.Gui.Document doc, TextLocation loc, Action<List<MonoDevelop.CodeActions.CodeAction>> callback)
202
217
System.Threading.ThreadPool.QueueUserWorkItem (delegate {
204
string disabledNodes = PropertyService.Get ("ContextActions." + doc.Editor.Document.MimeType, "") ?? "";
206
var availableFixes = new List<ContextAction> (contextActions.Where (fix => disabledNodes.IndexOf (fix.Type.FullName) < 0 && fix.Action.IsValid (doc, loc)).Select (fix => fix.Action));
219
var result = new List<MonoDevelop.CodeActions.CodeAction> ();
207
221
var ext = doc.GetContent<MonoDevelop.AnalysisCore.Gui.ResultsEditorExtension> ();
208
222
if (ext != null) {
209
foreach (var result in ext.GetResultsAtOffset (doc.Editor.LocationToOffset (loc.Line, loc.Column))) {
210
var fresult = result as FixableResult;
223
foreach (var r in ext.GetResultsAtOffset (doc.Editor.LocationToOffset (loc)).OrderBy (r => r.Level)) {
224
var fresult = r as FixableResult;
211
225
if (fresult == null)
213
227
foreach (var action in FixOperationsHandler.GetActions (doc, fresult)) {
214
availableFixes.Add (new AnalysisContextAction (result, action));
228
result.Add (new AnalysisContextActionProvider.AnalysisCodeAction (action, r));
219
callback (availableFixes);
232
result.AddRange (GetValidActions (doc, loc).Result);
220
234
} catch (Exception ex) {
221
235
LoggingService.LogError ("Error in analysis service", ex);
240
public static DocumentLocation GetCorrectResolveLocation (Document doc, DocumentLocation location)
243
throw new ArgumentNullException ("doc");
244
var editor = doc.Editor;
245
if (editor == null || location.Column == 1)
248
var line = editor.GetLine (location.Line);
249
if (line == null || location.Column >= line.Length)
252
int offset = editor.LocationToOffset (location);
253
if (offset > 0 && !char.IsLetterOrDigit (doc.Editor.GetCharAt (offset)) && char.IsLetterOrDigit (doc.Editor.GetCharAt (offset - 1)))
254
return new DocumentLocation (location.Line, location.Column - 1);