diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin
index 4bb5ccc90c..2465327880 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin
@@ -140,79 +140,54 @@
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs
index 1c8f08be47..a26fb3a993 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs
@@ -33,8 +33,8 @@ namespace CSharpBinding
ITextEditor editor;
CSharpSemanticHighlighter semanticHighlighter;
- InspectionManager inspectionManager;
- IList contextActionProviders;
+ //InspectionManager inspectionManager;
+ IList contextActionProviders;
public override void Attach(ITextEditor editor)
{
@@ -45,11 +45,11 @@ namespace CSharpBinding
semanticHighlighter = new CSharpSemanticHighlighter(editor, highlighter);
highlighter.AddAdditionalHighlighter(semanticHighlighter);
}
- inspectionManager = new InspectionManager(editor);
+ //inspectionManager = new InspectionManager(editor);
//codeManipulation = new CodeManipulation(editor);
if (!editor.ContextActionProviders.IsReadOnly) {
- contextActionProviders = AddInTree.BuildItems("/SharpDevelop/ViewContent/TextEditor/C#/ContextActions", null);
+ contextActionProviders = AddInTree.BuildItems("/SharpDevelop/ViewContent/TextEditor/C#/ContextActions", null);
editor.ContextActionProviders.AddRange(contextActionProviders);
}
}
@@ -63,10 +63,10 @@ namespace CSharpBinding
semanticHighlighter.Dispose();
semanticHighlighter = null;
}
- if (inspectionManager != null) {
- inspectionManager.Dispose();
- inspectionManager = null;
- }
+// if (inspectionManager != null) {
+// inspectionManager.Dispose();
+// inspectionManager = null;
+// }
if (contextActionProviders != null) {
editor.ContextActionProviders.RemoveWhere(contextActionProviders.Contains);
}
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpContextActionDoozer.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpContextActionDoozer.cs
index 505708c037..de2cb57854 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpContextActionDoozer.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpContextActionDoozer.cs
@@ -3,18 +3,19 @@
using System;
using System.IO;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CSharpBinding.Parser;
using ICSharpCode.Core;
+using ICSharpCode.NRefactory.CSharp;
+using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Refactoring;
namespace CSharpBinding.Refactoring
{
- using NR5ContextAction = ICSharpCode.NRefactory.CSharp.Refactoring.IContextAction;
-
///
/// Doozer for C# context actions.
/// Expects a 'class' referencing an NR5 context action and provides an SD IContextActionsProvider.
@@ -27,34 +28,55 @@ namespace CSharpBinding.Refactoring
public object BuildItem(BuildItemArgs args)
{
- return new CSharpContextActionWrapper(args.AddIn, args.Codon.Properties);
+ Type providerType = args.AddIn.FindType(args.Codon.Properties["class"]);
+ if (providerType == null)
+ return null;
+ var attributes = providerType.GetCustomAttributes(typeof(ContextActionAttribute), true);
+ if (attributes.Length == 0) {
+ LoggingService.Error("[ContextAction] attribute is missing on " + providerType.FullName);
+ return null;
+ }
+ if (!typeof(ICodeActionProvider).IsAssignableFrom(providerType)) {
+ LoggingService.Error(providerType.FullName + " does nto implement ICodeActionProvider");
+ return null;
+ }
+ return new CSharpContextActionProviderWrapper((ContextActionAttribute)attributes[0], providerType);
}
- sealed class CSharpContextActionWrapper : ContextAction
+ sealed class CSharpContextActionProviderWrapper : IContextActionProvider
{
- readonly AddIn addIn;
- readonly string className;
- readonly string displayName;
+ readonly ContextActionAttribute attribute;
+ readonly Type type;
- public CSharpContextActionWrapper(AddIn addIn, Properties properties)
+ public CSharpContextActionProviderWrapper(ContextActionAttribute attribute, Type type)
{
- this.addIn = addIn;
- this.className = properties["class"];
- this.displayName = properties["displayName"];
+ this.attribute = attribute;
+ this.type = type;
}
- bool contextActionCreated;
- NR5ContextAction contextAction;
+ ICodeActionProvider codeActionProvider;
+
+ bool CreateCodeActionProvider()
+ {
+ lock (this) {
+ if (codeActionProvider == null) {
+ codeActionProvider = (ICodeActionProvider)Activator.CreateInstance(type);
+ }
+ return true;
+ }
+ }
- public override string ID {
- get { return className; }
+ public string ID {
+ get { return type.FullName; }
}
- public override string DisplayName {
- get { return StringParser.Parse(displayName); }
+ public bool AllowHiding {
+ get { return true; }
}
- public override Task IsAvailableAsync(EditorRefactoringContext context, CancellationToken cancellationToken)
+ public bool IsVisible { get; set; }
+
+ public Task GetAvailableActionsAsync(EditorRefactoringContext context, CancellationToken cancellationToken)
{
ITextEditor editor = context.Editor;
// grab SelectionStart/SelectionLength while we're still on the main thread
@@ -62,32 +84,66 @@ namespace CSharpBinding.Refactoring
int selectionLength = editor.SelectionLength;
return Task.Run(
async delegate {
- CreateContextAction();
- if (contextAction == null)
- return false;
+ if (!CreateCodeActionProvider())
+ return new IContextAction[0];
CSharpAstResolver resolver = await context.GetAstResolverAsync().ConfigureAwait(false);
var refactoringContext = new SDRefactoringContext(context.TextSource, resolver, context.CaretLocation, selectionStart, selectionLength, cancellationToken);
- return contextAction.IsValid(refactoringContext);
+ return codeActionProvider.GetActions(refactoringContext)
+ .Select((action, index) => new CSharpContextActionWrapper(this, action, index)).ToArray();
}, cancellationToken);
}
- void CreateContextAction()
+ internal CodeAction GetCodeAction(RefactoringContext refactoringContext, int index, string description)
{
- lock (this) {
- if (!contextActionCreated) {
- contextActionCreated = true;
- contextAction = (NR5ContextAction)addIn.CreateObject(className);
- }
+ if (!CreateCodeActionProvider())
+ return null;
+ var actions = codeActionProvider.GetActions(refactoringContext).ToList();
+ if (index < actions.Count) {
+ var action = actions[index];
+ if (action.Description == description)
+ return action;
}
+ return null;
}
+ }
+
+ sealed class CSharpContextActionWrapper : IContextAction
+ {
+ readonly CSharpContextActionProviderWrapper provider;
+ readonly int index;
+ readonly string description;
- public override void Execute(EditorRefactoringContext context)
+ public CSharpContextActionWrapper(CSharpContextActionProviderWrapper provider, CodeAction codeAction, int index)
{
- AnalyticsMonitorService.TrackFeature(className);
+ if (provider == null)
+ throw new ArgumentNullException("provider");
+ if (codeAction == null)
+ throw new ArgumentNullException("codeAction");
+ this.provider = provider;
+ this.description = codeAction.Description;
+ this.index = index;
+ // Don't maintain a reference to 'action', it indirectly references the compilation etc.
+ }
+
+ public IContextActionProvider Provider {
+ get { return provider; }
+ }
+
+ public string DisplayName {
+ get { return description; }
+ }
+
+ public void Execute(EditorRefactoringContext context)
+ {
+ AnalyticsMonitorService.TrackFeature(provider.ID);
var resolver = context.GetAstResolverAsync().Result;
var refactoringContext = new SDRefactoringContext(context.Editor, resolver, context.CaretLocation);
- CreateContextAction();
- contextAction.Run(refactoringContext);
+ var action = provider.GetCodeAction(refactoringContext, index, description);
+ if (action != null) {
+ using (var script = refactoringContext.StartScript()) {
+ action.Run(script);
+ }
+ }
}
}
}
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InspectionManager.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InspectionManager.cs
index 3662ae153d..64f6ca082e 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InspectionManager.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InspectionManager.cs
@@ -18,6 +18,7 @@ using ICSharpCode.SharpDevelop.Parser;
namespace CSharpBinding.Refactoring
{
+ /*
///
/// Performs code analysis in the background and creates text markers to show warnings.
///
@@ -153,4 +154,5 @@ namespace CSharpBinding.Refactoring
cancellationTokenSource = null;
}
}
+ */
}
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs
index 9b341c0960..7590829ae0 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs
@@ -86,7 +86,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
}
}
- public override IList ContextActionProviders {
+ public override IList ContextActionProviders {
get { return ((CodeEditorView)TextEditor).ContextActionProviders; }
}
}
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs
index 38e69ef807..fbc893f53e 100755
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorView.cs
@@ -84,7 +84,7 @@ namespace ICSharpCode.AvalonEdit.AddIn
hiddenDefinitionRenderer.Dispose();
}
- public IList ContextActionProviders {
+ public IList ContextActionProviders {
get { return contextActionsRenderer.Providers; }
}
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionsRenderer.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionsRenderer.cs
index 35fd4676e4..4561af7c1c 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionsRenderer.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/ContextActionsRenderer.cs
@@ -23,7 +23,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
public sealed class ContextActionsRenderer : IDisposable
{
readonly CodeEditorView editorView;
- ObservableCollection providers = new ObservableCollection();
+ ObservableCollection providers = new ObservableCollection();
ITextEditor Editor { get { return this.editorView.Adapter; } }
@@ -62,7 +62,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
ClosePopup();
}
- public IList Providers {
+ public IList Providers {
get { return providers; }
}
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/EditorActionsProvider.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/EditorActionsProvider.cs
index a6a1ca75fc..c3bbc9faca 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/EditorActionsProvider.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/EditorActionsProvider.cs
@@ -29,20 +29,20 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
return PropertyService.Get(PropertyServiceKey, new List());
}
- static void SaveProviderVisibilities(IEnumerable providers)
+ static void SaveProviderVisibilities(IEnumerable providers)
{
List disabledProviders = providers.Where(p => !p.IsVisible).Select(p => p.ID).ToList();
PropertyService.Set(PropertyServiceKey, disabledProviders);
}
- readonly IList providers;
+ readonly IList providers;
readonly EditorRefactoringContext editorContext;
public EditorRefactoringContext EditorContext {
get { return editorContext; }
}
- public EditorActionsProvider(EditorRefactoringContext editorContext, IList providers)
+ public EditorActionsProvider(EditorRefactoringContext editorContext, IList providers)
{
if (editorContext == null)
throw new ArgumentNullException("editorContext");
@@ -69,7 +69,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
public void SetVisible(IContextAction action, bool isVisible)
{
- IContextActionsProvider provider;
+ IContextActionProvider provider;
if (providerForAction.TryGetValue(action, out provider)) {
provider.IsVisible = isVisible;
}
@@ -79,12 +79,12 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
///
/// For every returned action remembers its provider for so that SetVisible can work.
///
- Dictionary providerForAction = new Dictionary();
+ Dictionary providerForAction = new Dictionary();
///
/// Gets actions available for current caret position in the editor.
///
- async Task> GetActionsAsync(IEnumerable providers, CancellationToken cancellationToken)
+ async Task> GetActionsAsync(IEnumerable providers, CancellationToken cancellationToken)
{
if (ParserService.LoadSolutionProjectsThreadRunning)
return EmptyList.Instance;
diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/GoToEntityAction.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/GoToEntityAction.cs
index ceca94092a..61a908d69c 100644
--- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/GoToEntityAction.cs
+++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/GoToEntityAction.cs
@@ -43,5 +43,9 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
{
NavigationService.NavigateTo(this.Entity);
}
+
+ IContextActionProvider IContextAction.Provider {
+ get { return null; }
+ }
}
}
diff --git a/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/ContextActionAttribute.cs b/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/ContextActionAttribute.cs
index 4d989e61fe..24c479a191 100644
--- a/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/ContextActionAttribute.cs
+++ b/src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/Refactoring/ContextActionAttribute.cs
@@ -1,4 +1,4 @@
-//
+//
// ProviderDescriptionAttribute.cs
//
// Author:
diff --git a/src/Main/Base/Project/Src/Editor/AvalonEdit/AvalonEditTextEditorAdapter.cs b/src/Main/Base/Project/Src/Editor/AvalonEdit/AvalonEditTextEditorAdapter.cs
index ccd0c3a52e..0b838307ac 100755
--- a/src/Main/Base/Project/Src/Editor/AvalonEdit/AvalonEditTextEditorAdapter.cs
+++ b/src/Main/Base/Project/Src/Editor/AvalonEdit/AvalonEditTextEditorAdapter.cs
@@ -239,8 +239,8 @@ namespace ICSharpCode.SharpDevelop.Editor.AvalonEdit
return Enumerable.Empty();
}
- public virtual IList ContextActionProviders {
- get { return EmptyList.Instance; }
+ public virtual IList ContextActionProviders {
+ get { return EmptyList.Instance; }
}
public virtual ITextEditor PrimaryView {
diff --git a/src/Main/Base/Project/Src/Editor/ITextEditor.cs b/src/Main/Base/Project/Src/Editor/ITextEditor.cs
index 5106852c67..46b50ca2f6 100644
--- a/src/Main/Base/Project/Src/Editor/ITextEditor.cs
+++ b/src/Main/Base/Project/Src/Editor/ITextEditor.cs
@@ -123,7 +123,7 @@ namespace ICSharpCode.SharpDevelop.Editor
///
/// Gets the list of context action providers.
///
- IList ContextActionProviders { get; }
+ IList ContextActionProviders { get; }
}
public interface ITextEditorOptions : INotifyPropertyChanged
diff --git a/src/Main/Base/Project/Src/Refactoring/ContextAction.cs b/src/Main/Base/Project/Src/Refactoring/ContextAction.cs
index 0736c5b155..0a8ab495f6 100644
--- a/src/Main/Base/Project/Src/Refactoring/ContextAction.cs
+++ b/src/Main/Base/Project/Src/Refactoring/ContextAction.cs
@@ -14,7 +14,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
/// Base class for implementing one context action.
/// Useful for implementing that provides just one action - common scenario.
///
- public abstract class ContextAction : IContextActionsProvider, IContextAction
+ public abstract class ContextAction : IContextActionProvider, IContextAction
{
public virtual string ID {
get { return GetType().FullName; }
@@ -36,7 +36,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
public abstract void Execute(EditorRefactoringContext context);
- async Task IContextActionsProvider.GetAvailableActionsAsync(EditorRefactoringContext context, CancellationToken cancellationToken)
+ async Task IContextActionProvider.GetAvailableActionsAsync(EditorRefactoringContext context, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
if (await IsAvailableAsync(context, cancellationToken).ConfigureAwait(false))
@@ -44,5 +44,9 @@ namespace ICSharpCode.SharpDevelop.Refactoring
else
return new IContextAction[0];
}
+
+ IContextActionProvider IContextAction.Provider {
+ get { return this; }
+ }
}
}
diff --git a/src/Main/Base/Project/Src/Refactoring/IContextAction.cs b/src/Main/Base/Project/Src/Refactoring/IContextAction.cs
index a0ecb5f3c2..0cdc85852a 100644
--- a/src/Main/Base/Project/Src/Refactoring/IContextAction.cs
+++ b/src/Main/Base/Project/Src/Refactoring/IContextAction.cs
@@ -12,6 +12,11 @@ namespace ICSharpCode.SharpDevelop.Refactoring
///
public interface IContextAction
{
+ ///
+ /// Gets the provider that was used to create this action.
+ ///
+ IContextActionProvider Provider { get; }
+
///
/// Name displayed in the context actions popup.
///
diff --git a/src/Main/Base/Project/Src/Refactoring/IContextActionsProvider.cs b/src/Main/Base/Project/Src/Refactoring/IContextActionsProvider.cs
index 0560f87ade..acda86f708 100644
--- a/src/Main/Base/Project/Src/Refactoring/IContextActionsProvider.cs
+++ b/src/Main/Base/Project/Src/Refactoring/IContextActionsProvider.cs
@@ -11,7 +11,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
///
/// Provides a set of refactoring s.
///
- public interface IContextActionsProvider
+ public interface IContextActionProvider
{
///
/// Unique identifier for the context actions provider; used to hide context actions