Browse Source

Add C# context actions to AddInTree.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
cf8da3c94d
  1. 94
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin
  2. 2
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
  3. 84
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpContextActionDoozer.cs
  4. 41
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/ExtensionMethods.cs
  5. 4
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  6. 11
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextAction.cs
  7. 2
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionViewModel.cs
  8. 13
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsBulbControl.xaml.cs
  9. 4
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsHelper.cs
  10. 42
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs
  11. 59
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs
  12. 4
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/IContextAction.cs
  13. 15
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/IContextActionCache.cs
  14. 10
      src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/IContextActionsProvider.cs
  15. 29
      src/Main/Base/Project/Src/Services/RefactoringService/GoToClassAction.cs
  16. 18
      src/Main/Base/Project/Src/Services/RefactoringService/GoToEntityAction.cs

94
src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin

@ -9,8 +9,11 @@ @@ -9,8 +9,11 @@
</Manifest>
<Runtime>
<Import assembly = "CSharpBinding.dll"/>
<Import assembly = "CSharpBinding.dll">
<Doozer name="CSharpContextAction" class="CSharpBinding.CSharpContextActionDoozer"/>
</Import>
<Import assembly = ":ICSharpCode.SharpDevelop"/>
<Import assembly = ":ICSharpCode.NRefactory.CSharp"/>
</Runtime>
<Path name = "/SharpDevelop/Workbench/Ambiences">
@ -94,14 +97,6 @@ @@ -94,14 +97,6 @@
<Include id = "AllManaged" path="/SharpDevelop/BackendBindings/ProjectOptions/AllManaged"/>
</Path>
<!--
depreciated, use LanguageBinding instead
<Path name = "/AddIns/DefaultTextEditor/Formatter/C#">
<Class id ="CSharpFormatter" class = "CSharpBinding.FormattingStrategy.CSharpFormattingStrategy"/>
</Path>
-->
<Path name = "/Workspace/Icons">
<!-- C# -->
<Icon id = "C#Prj"
@ -120,6 +115,83 @@ @@ -120,6 +115,83 @@
projectfileextension = ".csproj"
class = "CSharpBinding.CSharpProjectBinding" />
</Path>
</AddIn>
<Path path = "/SharpDevelop/ViewContent/AvalonEdit/ContextActions">
<!-- TODO: translate -->
<CSharpContextAction id = "AddAnotherAccessor"
displayName = "Add another accessor"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.AddAnotherAccessor" />
<CSharpContextAction id = "CheckIfParameterIsNull"
displayName = "${res:AddIns.SharpRefactoring.InsertCtor.AddCheckForNullLabel}"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CheckIfParameterIsNull" />
<CSharpContextAction id = "ConvertDecToHex"
displayName = "Convert to hexadecimal"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.ConvertDecToHex" />
<CSharpContextAction id = "ConvertHexToDec"
displayName = "Convert to decimal"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.ConvertHexToDec" />
<CSharpContextAction id = "ConvertForeachToFor"
displayName = "Convert to for loop"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.ConvertForeachToFor" />
<CSharpContextAction id = "CreateBackingStore"
displayName = "${res:SharpDevelop.Refactoring.ExpandAutomaticProperty}"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreateBackingStore" />
<CSharpContextAction id = "CreateEventInvocator"
displayName = "${res:SharpDevelop.Refactoring.CreateOnEventMethod}"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreateEventInvocator" />
<CSharpContextAction id = "CreateField"
displayName = "Introduce field"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreateField" />
<CSharpContextAction id = "CreateLocalVariable"
displayName = "Introduce local variable"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreateLocalVariable" />
<CSharpContextAction id = "CreateProperty"
displayName = "Create property"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.CreateProperty" />
<CSharpContextAction id = "FlipOperatorArguments"
displayName = "Flip operands"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.FlipOperatorArguments" />
<CSharpContextAction id = "GenerateGetter"
displayName = "Generate getter"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.GenerateGetter" />
<!--<CSharpContextAction id = "GenerateProperty"
displayName = "Generate property"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.GenerateProperty" />
<CSharpContextAction id = "GenerateSwitchLabels"
displayName = "Generate switch labels"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.GenerateSwitchLabels" />
<CSharpContextAction id = "InsertAnonymousMethodSignature"
displayName = "Create anonymous method"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.InsertAnonymousMethodSignature" />
<CSharpContextAction id = "IntroduceFormatItem"
displayName = "Introduce string.Format call"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.IntroduceFormatItem" />
<CSharpContextAction id = "InvertIf"
displayName = "Invert if"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.InvertIf" />
<CSharpContextAction id = "RemoveBackingStore"
displayName = "${res:SharpDevelop.Refactoring.ConvertToAutomaticProperty}"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.RemoveBackingStore" />
<CSharpContextAction id = "RemoveBraces"
displayName = "Remove braces"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.RemoveBraces" />
<CSharpContextAction id = "RemoveRegion"
displayName = "Remove #region"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.RemoveRegion" />
<CSharpContextAction id = "ReplaceEmptyString"
displayName = "Use string.Empty"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.ReplaceEmptyString" />
<CSharpContextAction id = "SplitDeclarationAndAssignment"
displayName = "Split declaration and assignment"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.SplitDeclarationAndAssignment" />
<CSharpContextAction id = "SplitString"
displayName = "Split string literal"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.SplitString" />
<CSharpContextAction id = "UseExplicitType"
displayName = "Use explicit type"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.UseExplicitType" />
<CSharpContextAction id = "UseVarKeyword"
displayName = "Use 'var' keyword"
class = "ICSharpCode.NRefactory.CSharp.Refactoring.UseVarKeyword" />-->
</Path>
</AddIn>

2
src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj

@ -74,9 +74,11 @@ @@ -74,9 +74,11 @@
<Compile Include="Src\Completion\CSharpCompletionDataFactory.cs" />
<Compile Include="Src\Completion\EntityCompletionData.cs" />
<Compile Include="Src\CSharpBracketSearcher.cs" />
<Compile Include="Src\CSharpContextActionDoozer.cs" />
<Compile Include="Src\CSharpLanguageBinding.cs" />
<Compile Include="Src\CSharpProjectBinding.cs" />
<Compile Include="Src\CSharpSemanticHighlighter.cs" />
<Compile Include="Src\ExtensionMethods.cs" />
<Compile Include="Src\FormattingStrategy\CSharpFormattingStrategy.cs" />
<Compile Include="Src\FormattingStrategy\DocumentAccessor.cs" />
<Compile Include="Src\OptionPanels\BuildOptions.cs">

84
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpContextActionDoozer.cs

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using CSharpBinding.Parser;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.SharpDevelop.Refactoring;
namespace CSharpBinding
{
using NR5ContextAction = ICSharpCode.NRefactory.CSharp.Refactoring.IContextAction;
/// <summary>
/// Doozer for C# context actions.
/// Expects a 'class' referencing an NR5 context action and provides an SD IContextActionsProvider.
/// </summary>
public class CSharpContextActionDoozer : IDoozer
{
public bool HandleConditions {
get { return false; }
}
public object BuildItem(BuildItemArgs args)
{
return new CSharpContextActionWrapper(args.AddIn, args.Codon.Properties);
}
sealed class CSharpContextActionWrapper : ContextAction
{
readonly AddIn addIn;
readonly string className;
readonly string displayName;
public CSharpContextActionWrapper(AddIn addIn, Properties properties)
{
this.addIn = addIn;
this.className = properties["class"];
this.displayName = properties["displayName"];
}
bool contextActionCreated;
NR5ContextAction contextAction;
public override string ID {
get { return className; }
}
public override string DisplayName {
get { return StringParser.Parse(displayName); }
}
public override Task<bool> IsAvailableAsync(EditorContext context, CancellationToken cancellationToken)
{
if (!string.Equals(Path.GetExtension(context.FileName), ".cs", StringComparison.OrdinalIgnoreCase))
return Task.FromResult(false);
return Task.Run(
async delegate {
var parseInfo = (await context.GetParseInformationAsync().ConfigureAwait(false)) as CSharpFullParseInformation;
if (parseInfo == null)
return false;
lock (this) {
if (!contextActionCreated) {
contextActionCreated = true;
contextAction = (NR5ContextAction)addIn.CreateObject(className);
}
}
if (contextAction == null)
return false;
CSharpAstResolver resolver = await context.GetAstResolverAsync().ConfigureAwait(false);
return true;
}, cancellationToken);
}
public override void Execute(EditorContext context)
{
throw new NotImplementedException();
}
}
}
}

41
src/AddIns/BackendBindings/CSharpBinding/Project/Src/ExtensionMethods.cs

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Threading.Tasks;
using CSharpBinding.Parser;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.SharpDevelop.Refactoring;
namespace CSharpBinding
{
/// <summary>
/// C#-specific extension methods.
/// </summary>
public static class ExtensionMethods
{
public static async Task<CompilationUnit> GetCompilationUnitAsync(this EditorContext editorContext)
{
var parseInfo = (await editorContext.GetParseInformationAsync().ConfigureAwait(false)) as CSharpFullParseInformation;
if (parseInfo != null)
return parseInfo.CompilationUnit;
else
return new CompilationUnit();
}
public static Task<CSharpAstResolver> GetAstResolverAsync(this EditorContext editorContext)
{
return editorContext.GetCachedAsync(
async ec => {
var parseInfo = (await ec.GetParseInformationAsync().ConfigureAwait(false)) as CSharpFullParseInformation;
var compilation = await ec.GetCompilationAsync().ConfigureAwait(false);
if (parseInfo != null)
return new CSharpAstResolver(compilation, parseInfo.CompilationUnit, parseInfo.ParsedFile);
else
return new CSharpAstResolver(compilation, new CompilationUnit(), new CSharpParsedFile(ec.FileName));
});
}
}
}

4
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -421,12 +421,10 @@ @@ -421,12 +421,10 @@
<Compile Include="Src\Services\RefactoringService\ContextActions\ContextActionsPopup.cs" />
<Compile Include="Src\Services\RefactoringService\ContextActions\ContextActionsViewModel.cs" />
<Compile Include="Src\Services\RefactoringService\ContextActions\ContextActionViewModel.cs" />
<Compile Include="Src\Services\RefactoringService\ContextActions\IContextActionCache.cs" />
<Compile Include="Src\Services\RefactoringService\ContextActions\IContextActionsProvider.cs" />
<Compile Include="Src\Services\RefactoringService\ExtractInterfaceOptions.cs" />
<Compile Include="Src\Services\RefactoringService\FindReferenceService.cs" />
<Compile Include="Src\Services\RefactoringService\GoToClassAction.cs" />
<Compile Include="Src\Services\RefactoringService\GoToMemberAction.cs" />
<Compile Include="Src\Services\RefactoringService\GoToEntityAction.cs" />
<Compile Include="Src\Services\RefactoringService\TypeGraphNode.cs" />
<Compile Include="Src\Services\RefactoringService\TypeName.cs" />
<Compile Include="Src\Services\Tasks\ErrorPainter.cs" />

11
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextAction.cs

@ -16,16 +16,25 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -16,16 +16,25 @@ namespace ICSharpCode.SharpDevelop.Refactoring
/// </summary>
public abstract class ContextAction : IContextActionsProvider, IContextAction
{
public abstract string Title { get; }
public virtual string ID {
get { return GetType().FullName; }
}
public abstract string DisplayName { get; }
public bool IsVisible { get; set; }
/// <summary>
/// Gets whether this context action is available in the given context.
/// </summary>
/// <remarks><inheritdoc cref="IContextActionsProvider.GetAvailableActionsAsync"/></remarks>
public abstract Task<bool> IsAvailableAsync(EditorContext context, CancellationToken cancellationToken);
public abstract void Execute(EditorContext context);
async Task<IContextAction[]> IContextActionsProvider.GetAvailableActionsAsync(EditorContext context, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
if (await IsAvailableAsync(context, cancellationToken).ConfigureAwait(false))
return new IContextAction[] { this };
else

2
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionViewModel.cs

@ -32,7 +32,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -32,7 +32,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
}
public string Name {
get { return this.action != null ? this.action.Title : string.Empty; }
get { return this.action != null ? this.action.DisplayName : string.Empty; }
}
public string Comment { get; set; }

13
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsBulbControl.xaml.cs

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
@ -30,14 +31,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -30,14 +31,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring
remove { this.ActionsTreeView.ActionExecuted -= value; }
}
/*
public new ContextActionsBulbViewModel DataContext
{
get { return (ContextActionsBulbViewModel)base.DataContext; }
set { base.DataContext = value; }
}
*/
bool isOpen;
public bool IsOpen {
get { return isOpen; }
@ -70,9 +63,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -70,9 +63,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
void Expander_Expanded(object sender, RoutedEventArgs e)
{
throw new NotImplementedException();
#warning NotImplementedException
//this.DataContext.LoadHiddenActions();
((ContextActionsBulbViewModel)this.DataContext).LoadHiddenActionsAsync(CancellationToken.None).FireAndForget();
}
void CheckBox_Click(object sender, RoutedEventArgs e)

4
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsHelper.cs

@ -61,7 +61,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -61,7 +61,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
protected ContextActionViewModel MakeGoToClassAction(ITypeDefinition @class, ObservableCollection<ContextActionViewModel> childActions)
{
return new ContextActionViewModel {
Action = new GoToClassAction(@class, this.LabelAmbience.ConvertEntity(@class)),
Action = new GoToEntityAction(@class, this.LabelAmbience),
Image = CompletionImage.GetImage(@class),
Comment = string.Format("(in {0})", @class.Namespace),
ChildActions = childActions
@ -106,7 +106,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -106,7 +106,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
return null;
return new ContextActionViewModel {
Action = new GoToMemberAction(derivedMember, this.LabelAmbience),
Action = new GoToEntityAction(derivedMember, this.LabelAmbience),
Image = CompletionImage.GetImage(derivedMember),
Comment = string.Format("(in {0})", containingClass.FullName),
ChildActions = childActions

42
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsService.cs

@ -22,8 +22,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -22,8 +22,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring
{
static readonly ContextActionsService instance = new ContextActionsService();
static ContextActionsService() {}
/// <summary>
/// Key for storing the names of disabled providers in PropertyService.
/// </summary>
@ -33,20 +31,19 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -33,20 +31,19 @@ namespace ICSharpCode.SharpDevelop.Refactoring
get { return instance; }
}
List<IContextActionsProvider> providers;
private ContextActionsService()
{
this.providers = AddInTree.BuildItems<IContextActionsProvider>("/SharpDevelop/ViewContent/AvalonEdit/ContextActions", null, false);
var disabledActions = LoadProviderVisibilities().ToLookup(s => s);
foreach (var provider in providers) {
provider.IsVisible = !disabledActions.Contains(provider.GetType().FullName);
}
}
public EditorActionsProvider CreateActionsProvider(ITextEditor editor)
{
return new EditorActionsProvider(editor, this.providers);
var editorContext = new EditorContext(editor);
var providers = AddInTree.BuildItems<IContextActionsProvider>("/SharpDevelop/ViewContent/AvalonEdit/ContextActions", editorContext, false);
var disabledActions = new HashSet<string>(LoadProviderVisibilities());
foreach (var provider in providers) {
provider.IsVisible = !disabledActions.Contains(provider.ID);
}
return new EditorActionsProvider(editorContext, providers);
}
static List<string> LoadProviderVisibilities()
@ -54,9 +51,9 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -54,9 +51,9 @@ namespace ICSharpCode.SharpDevelop.Refactoring
return PropertyService.Get(PropertyServiceKey, new List<string>());
}
public void SaveProviderVisibilities()
public void SaveProviderVisibilities(IEnumerable<IContextActionsProvider> providers)
{
List<string> disabledProviders = this.providers.Where(p => !p.IsVisible).Select(p => p.GetType().FullName).ToList();
List<string> disabledProviders = providers.Where(p => !p.IsVisible).Select(p => p.ID).ToList();
PropertyService.Set(PropertyServiceKey, disabledProviders);
}
}
@ -67,17 +64,20 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -67,17 +64,20 @@ namespace ICSharpCode.SharpDevelop.Refactoring
public class EditorActionsProvider
{
readonly IList<IContextActionsProvider> providers;
public EditorContext EditorContext { get; set; }
readonly EditorContext editorContext;
public EditorContext EditorContext {
get { return editorContext; }
}
public EditorActionsProvider(ITextEditor editor, IList<IContextActionsProvider> providers)
public EditorActionsProvider(EditorContext editorContext, IList<IContextActionsProvider> providers)
{
if (editor == null)
throw new ArgumentNullException("editor");
if (editorContext == null)
throw new ArgumentNullException("editorContext");
if (providers == null)
throw new ArgumentNullException("providers");
this.providers = providers;
this.EditorContext = new EditorContext(editor);
this.editorContext = editorContext;
}
public Task<IEnumerable<IContextAction>> GetVisibleActionsAsync(CancellationToken cancellationToken)
@ -96,7 +96,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -96,7 +96,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
if (providerForAction.TryGetValue(action, out provider)) {
provider.IsVisible = isVisible;
}
ContextActionsService.Instance.SaveProviderVisibilities();
ContextActionsService.Instance.SaveProviderVisibilities(providers);
}
/// <summary>
@ -114,11 +114,13 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -114,11 +114,13 @@ namespace ICSharpCode.SharpDevelop.Refactoring
var providerList = providers.ToList();
var actions = await Task.WhenAll(providerList.Select(p => p.GetAvailableActionsAsync(this.EditorContext, cancellationToken)));
for (int i = 0; i < actions.Length; i++) {
if (actions[i] != null) {
foreach (var action in actions[i]) {
providerForAction[action] = providerList[i];
}
}
return actions.SelectMany(_ => _);
}
return actions.Where(a => a != null).SelectMany(a => a);
}
}
}

59
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@ -25,7 +26,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -25,7 +26,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
/// </summary>
public class EditorContext
{
object syncRoot;
readonly object syncRoot = new object();
readonly ITextEditor editor;
/// <summary>
@ -49,6 +50,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -49,6 +50,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
public ITextSource TextSource { get; private set; }
readonly int caretOffset;
readonly TextLocation caretLocation;
/// <summary>
/// Gets the offset of the caret, at the time when this editor context was created.
@ -58,7 +60,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -58,7 +60,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
}
Task<ParseInformation> parseInformation;
ICompilation compilation;
Task<ICompilation> compilation;
/// <summary>
/// Gets the ParseInformation for the file.
@ -78,14 +80,17 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -78,14 +80,17 @@ namespace ICSharpCode.SharpDevelop.Refactoring
/// </summary>
public Task<ICompilation> GetCompilationAsync()
{
var c = LazyInitializer.EnsureInitialized(ref compilation, () => ParserService.GetCompilationForFile(this.FileName));
return Task.FromResult(c);
lock (syncRoot) {
if (compilation == null)
compilation = Task.FromResult(ParserService.GetCompilationForFile(this.FileName));
return compilation;
}
}
/// <summary>
/// Caches values shared by Context actions. Used in <see cref="GetCached"/>.
/// </summary>
readonly Dictionary<Type, object> cachedValues = new Dictionary<Type, object>();
readonly ConcurrentDictionary<Type, Task> cachedValues = new ConcurrentDictionary<Type, Task>();
/// <summary>
/// Fully initializes the EditorContext.
@ -96,36 +101,52 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -96,36 +101,52 @@ namespace ICSharpCode.SharpDevelop.Refactoring
throw new ArgumentNullException("editor");
this.editor = editor;
caretOffset = editor.Caret.Offset;
caretLocation = editor.Caret.Location;
this.FileName = editor.FileName;
this.TextSource = editor.Document.CreateSnapshot();
}
Task<ResolveResult> currentSymbol;
/// <summary>
/// The resolved symbol at editor caret.
/// </summary>
public ResolveResult CurrentSymbol {
get {
throw new NotImplementedException();
public Task<ResolveResult> GetCurrentSymbolAsync()
{
lock (syncRoot) {
if (currentSymbol == null)
currentSymbol = ResolveCurrentSymbolAsync();
return currentSymbol;
}
}
async Task<ResolveResult> ResolveCurrentSymbolAsync()
{
var parser = ParserService.GetParser(this.FileName);
if (parser == null)
return null;
var parseInfo = await GetParseInformationAsync().ConfigureAwait(false);
if (parseInfo == null)
return null;
var compilation = await GetCompilationAsync().ConfigureAwait(false);
return await Task.Run(() => ParserService.ResolveAsync(this.FileName, caretLocation, this.TextSource, CancellationToken.None)).ConfigureAwait(false);
}
/// <summary>
/// Gets cached value shared by context actions. Initializes a new value if not present.
/// </summary>
public T GetCached<T>() where T : IContextActionCache, new()
public Task<T> GetCachedAsync<T>(Func<EditorContext, T> initializationFunc)
{
lock (cachedValues) {
Type t = typeof(T);
if (cachedValues.ContainsKey(t)) {
return (T)cachedValues[t];
} else {
T cached = new T();
cached.Initialize(this);
cachedValues[t] = cached;
return cached;
}
return (Task<T>)cachedValues.GetOrAdd(typeof(T), _ => Task.FromResult(initializationFunc(this)));
}
/// <summary>
/// Gets cached value shared by context actions. Initializes a new value if not present.
/// </summary>
public Task<T> GetCachedAsync<T>(Func<EditorContext, Task<T>> initializationFunc)
{
return (Task<T>)cachedValues.GetOrAdd(typeof(T), _ => initializationFunc(this));
}
}
}

4
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/IContextAction.cs

@ -12,9 +12,9 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -12,9 +12,9 @@ namespace ICSharpCode.SharpDevelop.Refactoring
public interface IContextAction
{
/// <summary>
/// Title displayed in the context actions popup.
/// Name displayed in the context actions popup.
/// </summary>
string Title { get; }
string DisplayName { get; }
/// <summary>
/// Executes this action. Called when this action is selected from the context actions popup.
/// </summary>

15
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/IContextActionCache.cs

@ -1,15 +0,0 @@ @@ -1,15 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
namespace ICSharpCode.SharpDevelop.Refactoring
{
/// <summary>
/// Temporary data shared by multiple Context actions. Stored in EditorContext.GetCached().
/// </summary>
public interface IContextActionCache
{
void Initialize(EditorContext context);
}
}

10
src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/IContextActionsProvider.cs

@ -13,9 +13,19 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -13,9 +13,19 @@ namespace ICSharpCode.SharpDevelop.Refactoring
/// </summary>
public interface IContextActionsProvider
{
/// <summary>
/// Unique identifier for the context actions provider; used to hide context actions
/// that were disabled by the user.
/// </summary>
string ID { get; }
/// <summary>
/// Gets actions available for current line of the editor.
/// </summary>
/// <remarks>
/// This method gets called on the GUI thread. The method implementation should use
/// 'Task.Run()' to move the implementation onto a background thread.
/// </remarks>
Task<IContextAction[]> GetAvailableActionsAsync(EditorContext context, CancellationToken cancellationToken);
/// <summary>

29
src/Main/Base/Project/Src/Services/RefactoringService/GoToClassAction.cs

@ -1,29 +0,0 @@ @@ -1,29 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.SharpDevelop.Refactoring
{
public class GoToClassAction : IContextAction
{
public string Title { get; private set; }
public ITypeDefinition Class { get; private set; }
public GoToClassAction(ITypeDefinition c, string title)
{
if (c == null)
throw new ArgumentNullException("c");
if (title == null)
throw new ArgumentNullException("title");
this.Class = c;
this.Title = title;
}
public void Execute(EditorContext context)
{
NavigationService.NavigateTo(this.Class);
}
}
}

18
src/Main/Base/Project/Src/Services/RefactoringService/GoToMemberAction.cs → src/Main/Base/Project/Src/Services/RefactoringService/GoToEntityAction.cs

@ -7,24 +7,24 @@ using ICSharpCode.SharpDevelop.Parser; @@ -7,24 +7,24 @@ using ICSharpCode.SharpDevelop.Parser;
namespace ICSharpCode.SharpDevelop.Refactoring
{
public class GoToMemberAction : IContextAction
public class GoToEntityAction : IContextAction
{
public string Title { get; private set; }
public IMember Member { get; private set; }
public string DisplayName { get; private set; }
public IEntity Entity { get; private set; }
public GoToMemberAction(IMember member, IAmbience ambience)
public GoToEntityAction(IEntity entity, IAmbience ambience)
{
if (ambience == null)
throw new ArgumentNullException("ambience");
if (member == null)
throw new ArgumentNullException("member");
this.Member = member;
this.Title = ambience.ConvertEntity(member);
if (entity == null)
throw new ArgumentNullException("entity");
this.Entity = entity;
this.DisplayName = ambience.ConvertEntity(entity);
}
public void Execute(EditorContext context)
{
NavigationService.NavigateTo(this.Member);
NavigationService.NavigateTo(this.Entity);
}
}
}
Loading…
Cancel
Save