Browse Source

Fix #532: 'Go to base method' is missing from entity context menu.

pull/505/merge
Andreas Weizel 11 years ago
parent
commit
2b85ce40ad
  1. 10
      data/resources/StringResources.resx
  2. 12
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.addin
  3. 54
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/FindBaseClasses.cs
  4. 2
      src/Main/Base/Project/Src/Internal/ConditionEvaluators/SymbolTypeAtCaretConditionEvaluator.cs

10
data/resources/StringResources.resx

@ -3789,6 +3789,10 @@ Please configure the NAnt executable's location in the SharpDevelop Options.</va
<value>Could not find type definition at the cursor position.</value> <value>Could not find type definition at the cursor position.</value>
<comment>Error message when using Search&gt;Find Base Classes when the cursor is not on a type reference.</comment> <comment>Error message when using Search&gt;Find Base Classes when the cursor is not on a type reference.</comment>
</data> </data>
<data name="ICSharpCode.Refactoring.NoClassOrMemberUnderCursorError" xml:space="preserve">
<value>Could not find type definition or type member at the cursor position.</value>
<comment>Error message when using Search&gt;Find Base Classes when the cursor is not on a type reference or type member.</comment>
</data>
<data name="ICSharpCode.RubyBinding.SendLineToRubyConsole" xml:space="preserve"> <data name="ICSharpCode.RubyBinding.SendLineToRubyConsole" xml:space="preserve">
<value>Send Line to Ruby Console</value> <value>Send Line to Ruby Console</value>
</data> </data>
@ -6473,6 +6477,9 @@ Removed the end part of the original message ", reason '${Message}'" since this
<data name="SharpDevelop.Refactoring.BaseClassesOf" xml:space="preserve"> <data name="SharpDevelop.Refactoring.BaseClassesOf" xml:space="preserve">
<value>Base classes of ${Name}</value> <value>Base classes of ${Name}</value>
</data> </data>
<data name="SharpDevelop.Refactoring.BaseMembersOf" xml:space="preserve">
<value>Base members of ${Name}</value>
</data>
<data name="SharpDevelop.Refactoring.CannotPerformOperationBecauseOfSyntaxErrors" xml:space="preserve"> <data name="SharpDevelop.Refactoring.CannotPerformOperationBecauseOfSyntaxErrors" xml:space="preserve">
<value>The operation cannot be performed because your source code contains errors:</value> <value>The operation cannot be performed because your source code contains errors:</value>
</data> </data>
@ -6525,6 +6532,9 @@ Removed the end part of the original message ", reason '${Message}'" since this
<data name="SharpDevelop.Refactoring.FindBaseClassesCommand" xml:space="preserve"> <data name="SharpDevelop.Refactoring.FindBaseClassesCommand" xml:space="preserve">
<value>Find base classes</value> <value>Find base classes</value>
</data> </data>
<data name="SharpDevelop.Refactoring.FindBaseClassesOrMembersCommand" xml:space="preserve">
<value>Find base symbols</value>
</data>
<data name="SharpDevelop.Refactoring.FindDerivedClassesCommand" xml:space="preserve"> <data name="SharpDevelop.Refactoring.FindDerivedClassesCommand" xml:space="preserve">
<value>Find &amp;derived classes</value> <value>Find &amp;derived classes</value>
</data> </data>

12
src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.addin

@ -149,20 +149,20 @@
icon="Icons.16x16.Class" icon="Icons.16x16.Class"
class = "ICSharpCode.AvalonEdit.AddIn.ContextActions.FindDerivedClassesOrOverrides"/> class = "ICSharpCode.AvalonEdit.AddIn.ContextActions.FindDerivedClassesOrOverrides"/>
<MenuItem id = "FindBaseClasses" <MenuItem id = "FindBaseClassesOrMembers"
label = "${res:SharpDevelop.Refactoring.FindBaseClassesCommand}" label = "${res:SharpDevelop.Refactoring.FindBaseClassesOrMembersCommand}"
icon="Icons.16x16.Interface" icon="Icons.16x16.Interface"
class = "ICSharpCode.AvalonEdit.AddIn.ContextActions.FindBaseClasses"/> class = "ICSharpCode.AvalonEdit.AddIn.ContextActions.FindBaseClassesOrMembers"/>
</Path> </Path>
<Path name = "/SharpDevelop/EntityContextMenu"> <Path name = "/SharpDevelop/EntityContextMenu">
<Condition name="SymbolTypeAtCaret" type="type" action="Exclude"> <Condition name="SymbolTypeAtCaret" type="type,member" action="Exclude">
<Include id="FindDerivedOrOverridesClasses" <Include id="FindDerivedOrOverridesClasses"
insertafter="FindReferences" insertafter="FindReferences"
item="/SharpDevelop/Workbench/MainMenu/Search/FindDerivedOrOverridesClasses" /> item="/SharpDevelop/Workbench/MainMenu/Search/FindDerivedOrOverridesClasses" />
<Include id="FindBaseClasses" <Include id="FindBaseClassesOrMembers"
insertafter="FindDerivedOrOverridesClasses" insertafter="FindDerivedOrOverridesClasses"
item="/SharpDevelop/Workbench/MainMenu/Search/FindBaseClasses" /> item="/SharpDevelop/Workbench/MainMenu/Search/FindBaseClassesOrMembers" />
</Condition> </Condition>
</Path> </Path>

54
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/FindBaseClasses.cs

@ -31,16 +31,20 @@ using ICSharpCode.SharpDevelop.Editor.ContextActions;
namespace ICSharpCode.AvalonEdit.AddIn.ContextActions namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
{ {
public class FindBaseClasses : ResolveResultMenuCommand public class FindBaseClassesOrMembers : ResolveResultMenuCommand
{ {
public override void Run(ResolveResult symbol) public override void Run(ResolveResult symbol)
{ {
IEntity entityUnderCaret = GetSymbol(symbol) as IEntity; IEntity entityUnderCaret = GetSymbol(symbol) as IEntity;
if (entityUnderCaret is ITypeDefinition) { if (entityUnderCaret is ITypeDefinition) {
MakePopupWithBaseClasses((ITypeDefinition)entityUnderCaret).OpenAtCaretAndFocus(); MakePopupWithBaseClasses((ITypeDefinition)entityUnderCaret).OpenAtCaretAndFocus();
} else { return;
MessageService.ShowError("${res:ICSharpCode.Refactoring.NoClassUnderCursorError}");
} }
if (entityUnderCaret is IMember) {
MakePopupWithBaseMembers((IMember)entityUnderCaret).OpenAtCaretAndFocus();
return;
}
MessageService.ShowError("${res:ICSharpCode.Refactoring.NoClassOrMemberUnderCursorError}");
} }
static ContextActionsPopup MakePopupWithBaseClasses(ITypeDefinition @class) static ContextActionsPopup MakePopupWithBaseClasses(ITypeDefinition @class)
@ -49,14 +53,54 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
var popupViewModel = new ContextActionsPopupViewModel(); var popupViewModel = new ContextActionsPopupViewModel();
popupViewModel.Title = MenuService.ConvertLabel(StringParser.Parse( popupViewModel.Title = MenuService.ConvertLabel(StringParser.Parse(
"${res:SharpDevelop.Refactoring.BaseClassesOf}", new StringTagPair("Name", @class.Name))); "${res:SharpDevelop.Refactoring.BaseClassesOf}", new StringTagPair("Name", @class.Name)));
popupViewModel.Actions = BuildListViewModel(baseClassList); popupViewModel.Actions = BuildBaseClassListViewModel(baseClassList);
return new ContextActionsPopup { Actions = popupViewModel }; return new ContextActionsPopup { Actions = popupViewModel };
} }
static ObservableCollection<ContextActionViewModel> BuildListViewModel(IEnumerable<ITypeDefinition> classList) static ObservableCollection<ContextActionViewModel> BuildBaseClassListViewModel(IEnumerable<ITypeDefinition> classList)
{ {
return new ObservableCollection<ContextActionViewModel>( return new ObservableCollection<ContextActionViewModel>(
classList.Select(@class => GoToEntityAction.MakeViewModel(@class, null))); classList.Select(@class => GoToEntityAction.MakeViewModel(@class, null)));
} }
#region Base (overridden) members
static ContextActionsPopup MakePopupWithBaseMembers(IMember member)
{
var baseClassList = member.DeclaringTypeDefinition.GetAllBaseTypeDefinitions().Where(
baseClass => baseClass != member.DeclaringTypeDefinition).ToList();
var popupViewModel = new ContextActionsPopupViewModel {
Title = MenuService.ConvertLabel(StringParser.Parse(
"${res:SharpDevelop.Refactoring.BaseMembersOf}",
new StringTagPair("Name", member.FullName))
)};
popupViewModel.Actions = BuildBaseMemberListViewModel(member);
return new ContextActionsPopup { Actions = popupViewModel };
}
static ObservableCollection<ContextActionViewModel> BuildBaseMemberListViewModel(IMember member)
{
var c = new ObservableCollection<ContextActionViewModel>();
ObservableCollection<ContextActionViewModel> lastBase = c;
IMember thisMember = member;
while (thisMember != null) {
IMember baseMember = InheritanceHelper.GetBaseMembers(thisMember, true).FirstOrDefault();
if (baseMember != null) {
// Only allow this base member, if overriding a virtual/abstract member of a class
// or implementing a member of an interface.
if ((baseMember.DeclaringTypeDefinition.Kind == TypeKind.Interface) || (baseMember.IsOverridable && thisMember.IsOverride)) {
var newChild = new ObservableCollection<ContextActionViewModel>();
lastBase.Add(GoToEntityAction.MakeViewModel(baseMember, newChild));
lastBase = newChild;
} else {
thisMember = null;
}
}
thisMember = baseMember;
}
return c;
}
#endregion
} }
} }

2
src/Main/Base/Project/Src/Internal/ConditionEvaluators/SymbolTypeAtCaretConditionEvaluator.cs

@ -44,7 +44,7 @@ namespace ICSharpCode.SharpDevelop.Internal.ConditionEvaluators
string typesList = condition.Properties["type"]; string typesList = condition.Properties["type"];
if (typesList != null) { if (typesList != null) {
foreach (string type in typesList.Split(',')) { foreach (string type in typesList.Split(',')) {
switch (type) { switch (type.Trim()) {
case "*": case "*":
// Wildcard -> allow any type // Wildcard -> allow any type
return true; return true;

Loading…
Cancel
Save