3131
3232namespace 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}
0 commit comments