Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.

Commit 2b85ce4

Browse files
committed
Fix #532: 'Go to base method' is missing from entity context menu.
1 parent d4ff35e commit 2b85ce4

4 files changed

Lines changed: 66 additions & 12 deletions

File tree

data/resources/StringResources.resx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3789,6 +3789,10 @@ Please configure the NAnt executable's location in the SharpDevelop Options.</va
37893789
<value>Could not find type definition at the cursor position.</value>
37903790
<comment>Error message when using Search&gt;Find Base Classes when the cursor is not on a type reference.</comment>
37913791
</data>
3792+
<data name="ICSharpCode.Refactoring.NoClassOrMemberUnderCursorError" xml:space="preserve">
3793+
<value>Could not find type definition or type member at the cursor position.</value>
3794+
<comment>Error message when using Search&gt;Find Base Classes when the cursor is not on a type reference or type member.</comment>
3795+
</data>
37923796
<data name="ICSharpCode.RubyBinding.SendLineToRubyConsole" xml:space="preserve">
37933797
<value>Send Line to Ruby Console</value>
37943798
</data>
@@ -6473,6 +6477,9 @@ Removed the end part of the original message ", reason '${Message}'" since this
64736477
<data name="SharpDevelop.Refactoring.BaseClassesOf" xml:space="preserve">
64746478
<value>Base classes of ${Name}</value>
64756479
</data>
6480+
<data name="SharpDevelop.Refactoring.BaseMembersOf" xml:space="preserve">
6481+
<value>Base members of ${Name}</value>
6482+
</data>
64766483
<data name="SharpDevelop.Refactoring.CannotPerformOperationBecauseOfSyntaxErrors" xml:space="preserve">
64776484
<value>The operation cannot be performed because your source code contains errors:</value>
64786485
</data>
@@ -6525,6 +6532,9 @@ Removed the end part of the original message ", reason '${Message}'" since this
65256532
<data name="SharpDevelop.Refactoring.FindBaseClassesCommand" xml:space="preserve">
65266533
<value>Find base classes</value>
65276534
</data>
6535+
<data name="SharpDevelop.Refactoring.FindBaseClassesOrMembersCommand" xml:space="preserve">
6536+
<value>Find base symbols</value>
6537+
</data>
65286538
<data name="SharpDevelop.Refactoring.FindDerivedClassesCommand" xml:space="preserve">
65296539
<value>Find &amp;derived classes</value>
65306540
</data>

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,20 +149,20 @@
149149
icon="Icons.16x16.Class"
150150
class = "ICSharpCode.AvalonEdit.AddIn.ContextActions.FindDerivedClassesOrOverrides"/>
151151

152-
<MenuItem id = "FindBaseClasses"
153-
label = "${res:SharpDevelop.Refactoring.FindBaseClassesCommand}"
152+
<MenuItem id = "FindBaseClassesOrMembers"
153+
label = "${res:SharpDevelop.Refactoring.FindBaseClassesOrMembersCommand}"
154154
icon="Icons.16x16.Interface"
155-
class = "ICSharpCode.AvalonEdit.AddIn.ContextActions.FindBaseClasses"/>
155+
class = "ICSharpCode.AvalonEdit.AddIn.ContextActions.FindBaseClassesOrMembers"/>
156156
</Path>
157157

158158
<Path name = "/SharpDevelop/EntityContextMenu">
159-
<Condition name="SymbolTypeAtCaret" type="type" action="Exclude">
159+
<Condition name="SymbolTypeAtCaret" type="type,member" action="Exclude">
160160
<Include id="FindDerivedOrOverridesClasses"
161161
insertafter="FindReferences"
162162
item="/SharpDevelop/Workbench/MainMenu/Search/FindDerivedOrOverridesClasses" />
163-
<Include id="FindBaseClasses"
163+
<Include id="FindBaseClassesOrMembers"
164164
insertafter="FindDerivedOrOverridesClasses"
165-
item="/SharpDevelop/Workbench/MainMenu/Search/FindBaseClasses" />
165+
item="/SharpDevelop/Workbench/MainMenu/Search/FindBaseClassesOrMembers" />
166166
</Condition>
167167
</Path>
168168

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

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,20 @@
3131

3232
namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
3333
{
34-
public class FindBaseClasses : ResolveResultMenuCommand
34+
public class FindBaseClassesOrMembers : ResolveResultMenuCommand
3535
{
3636
public override void Run(ResolveResult symbol)
3737
{
3838
IEntity entityUnderCaret = GetSymbol(symbol) as IEntity;
3939
if (entityUnderCaret is ITypeDefinition) {
4040
MakePopupWithBaseClasses((ITypeDefinition)entityUnderCaret).OpenAtCaretAndFocus();
41-
} else {
42-
MessageService.ShowError("${res:ICSharpCode.Refactoring.NoClassUnderCursorError}");
41+
return;
4342
}
43+
if (entityUnderCaret is IMember) {
44+
MakePopupWithBaseMembers((IMember)entityUnderCaret).OpenAtCaretAndFocus();
45+
return;
46+
}
47+
MessageService.ShowError("${res:ICSharpCode.Refactoring.NoClassOrMemberUnderCursorError}");
4448
}
4549

4650
static ContextActionsPopup MakePopupWithBaseClasses(ITypeDefinition @class)
@@ -49,14 +53,54 @@ static ContextActionsPopup MakePopupWithBaseClasses(ITypeDefinition @class)
4953
var popupViewModel = new ContextActionsPopupViewModel();
5054
popupViewModel.Title = MenuService.ConvertLabel(StringParser.Parse(
5155
"${res:SharpDevelop.Refactoring.BaseClassesOf}", new StringTagPair("Name", @class.Name)));
52-
popupViewModel.Actions = BuildListViewModel(baseClassList);
56+
popupViewModel.Actions = BuildBaseClassListViewModel(baseClassList);
5357
return new ContextActionsPopup { Actions = popupViewModel };
5458
}
5559

56-
static ObservableCollection<ContextActionViewModel> BuildListViewModel(IEnumerable<ITypeDefinition> classList)
60+
static ObservableCollection<ContextActionViewModel> BuildBaseClassListViewModel(IEnumerable<ITypeDefinition> classList)
5761
{
5862
return new ObservableCollection<ContextActionViewModel>(
5963
classList.Select(@class => GoToEntityAction.MakeViewModel(@class, null)));
6064
}
65+
66+
#region Base (overridden) members
67+
static ContextActionsPopup MakePopupWithBaseMembers(IMember member)
68+
{
69+
var baseClassList = member.DeclaringTypeDefinition.GetAllBaseTypeDefinitions().Where(
70+
baseClass => baseClass != member.DeclaringTypeDefinition).ToList();
71+
var popupViewModel = new ContextActionsPopupViewModel {
72+
Title = MenuService.ConvertLabel(StringParser.Parse(
73+
"${res:SharpDevelop.Refactoring.BaseMembersOf}",
74+
new StringTagPair("Name", member.FullName))
75+
)};
76+
popupViewModel.Actions = BuildBaseMemberListViewModel(member);
77+
return new ContextActionsPopup { Actions = popupViewModel };
78+
}
79+
80+
static ObservableCollection<ContextActionViewModel> BuildBaseMemberListViewModel(IMember member)
81+
{
82+
var c = new ObservableCollection<ContextActionViewModel>();
83+
ObservableCollection<ContextActionViewModel> lastBase = c;
84+
85+
IMember thisMember = member;
86+
while (thisMember != null) {
87+
IMember baseMember = InheritanceHelper.GetBaseMembers(thisMember, true).FirstOrDefault();
88+
if (baseMember != null) {
89+
// Only allow this base member, if overriding a virtual/abstract member of a class
90+
// or implementing a member of an interface.
91+
if ((baseMember.DeclaringTypeDefinition.Kind == TypeKind.Interface) || (baseMember.IsOverridable && thisMember.IsOverride)) {
92+
var newChild = new ObservableCollection<ContextActionViewModel>();
93+
lastBase.Add(GoToEntityAction.MakeViewModel(baseMember, newChild));
94+
lastBase = newChild;
95+
} else {
96+
thisMember = null;
97+
}
98+
}
99+
thisMember = baseMember;
100+
}
101+
102+
return c;
103+
}
104+
#endregion
61105
}
62106
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public bool IsValid(object parameter, Condition condition)
4444
string typesList = condition.Properties["type"];
4545
if (typesList != null) {
4646
foreach (string type in typesList.Split(',')) {
47-
switch (type) {
47+
switch (type.Trim()) {
4848
case "*":
4949
// Wildcard -> allow any type
5050
return true;

0 commit comments

Comments
 (0)