1717// DEALINGS IN THE SOFTWARE.
1818
1919using System ;
20+ using System . Collections . Generic ;
2021using System . Linq ;
2122using System . Reflection . Metadata ;
2223
2526using ICSharpCode . Decompiler . Output ;
2627using ICSharpCode . Decompiler . TypeSystem ;
2728using ICSharpCode . ILSpyX ;
28-
2929using ICSharpCode . ILSpy ;
3030using ICSharpCode . ILSpy . AppEnv ;
3131using ICSharpCode . ILSpy . AssemblyTree ;
@@ -38,6 +38,8 @@ public sealed class TypeTreeNode : ILSpyTreeNode, IMemberTreeNode
3838 readonly TypeDefinitionHandle handle ;
3939 readonly MetadataFile module ;
4040
41+ bool ? loadedInheritedMembers ;
42+
4143 public TypeDefinitionHandle Handle => handle ;
4244 public MetadataFile Module => module ;
4345
@@ -97,6 +99,11 @@ public override void Decompile(Language language, ITextOutput output, Decompilat
9799
98100 public override FilterResult Filter ( LanguageSettings settings )
99101 {
102+ if ( loadedInheritedMembers != settings . ShowBaseApi && IsVisible )
103+ {
104+ ReloadChildren ( ) ;
105+ }
106+
100107 if ( settings . ShowApiLevel == ApiVisibility . PublicOnly && ! IsPublicAPI )
101108 return FilterResult . Hidden ;
102109 var typeDef = ResolveTypeDefinition ( ) ;
@@ -163,7 +170,14 @@ protected override void LoadChildren()
163170 if ( assemblyList != null && CanHaveDerivedTypes ( typeDef ) )
164171 Children . Add ( new DerivedTypesTreeNode ( assemblyList , typeDef ) ) ;
165172
166- foreach ( var nestedType in typeDef . NestedTypes
173+ loadedInheritedMembers = CurrentLanguageSettings ? . ShowBaseApi ;
174+ IEnumerable < ITypeDefinition > nestedTypes = GetMembers ( typeDef , t => t . NestedTypes , loadedInheritedMembers ) ;
175+ IEnumerable < IField > fields = GetMembers ( typeDef , t => t . Fields , loadedInheritedMembers ) ;
176+ IEnumerable < IProperty > properties = GetMembers ( typeDef , t => t . Properties , loadedInheritedMembers ) ;
177+ IEnumerable < IEvent > events = GetMembers ( typeDef , t => t . Events , loadedInheritedMembers ) ;
178+ IEnumerable < IMethod > methods = GetMembers ( typeDef , t => t . Methods , loadedInheritedMembers ) ;
179+
180+ foreach ( var nestedType in nestedTypes
167181 . OrderBy ( t => t . Name , NaturalStringComparer . Instance ) )
168182 {
169183 Children . Add ( new TypeTreeNode ( ( TypeDefinitionHandle ) nestedType . MetadataToken , module ) ) ;
@@ -184,24 +198,40 @@ protected override void LoadChildren()
184198 }
185199
186200 // Enums look more useful in declaration order than alphabetical.
187- var fields = typeDef . Kind == TypeKind . Enum
188- ? typeDef . Fields
189- : typeDef . Fields . OrderBy ( f => f . Name , NaturalStringComparer . Instance ) ;
201+ if ( typeDef . Kind != TypeKind . Enum )
202+ fields = fields . OrderBy ( f => f . Name , NaturalStringComparer . Instance ) ;
203+
190204 foreach ( var field in fields )
191205 Children . Add ( new FieldTreeNode ( field ) ) ;
192206
193- foreach ( var prop in typeDef . Properties . OrderBy ( p => p . Name , NaturalStringComparer . Instance ) )
207+ foreach ( var prop in properties . OrderBy ( p => p . Name , NaturalStringComparer . Instance ) )
194208 Children . Add ( new PropertyTreeNode ( prop ) ) ;
195209
196- foreach ( var ev in typeDef . Events . OrderBy ( e => e . Name , NaturalStringComparer . Instance ) )
210+ foreach ( var ev in events . OrderBy ( e => e . Name , NaturalStringComparer . Instance ) )
197211 Children . Add ( new EventTreeNode ( ev ) ) ;
198212
199- foreach ( var method in typeDef . Methods . OrderBy ( m => m . Name , NaturalStringComparer . Instance ) )
213+ foreach ( var method in methods . OrderBy ( m => m . Name , NaturalStringComparer . Instance ) )
200214 {
201- if ( method . MetadataToken . IsNil || method . IsAccessor )
215+ if ( method . MetadataToken . IsNil || method . IsAccessor )
202216 continue ;
203217 Children . Add ( new MethodTreeNode ( method ) ) ;
204218 }
205219 }
220+
221+ private IEnumerable < TMember > GetMembers < TMember > ( ITypeDefinition type , Func < ITypeDefinition , IEnumerable < TMember > > selector , bool ? includeInherited )
222+ {
223+ IEnumerable < TMember > allMembers = selector ( type ) ;
224+ if ( includeInherited == true )
225+ {
226+ var typeSystem = new DecompilerTypeSystem ( module , module . GetAssemblyResolver ( ) ,
227+ TypeSystemOptions . Default | TypeSystemOptions . Uncached ) ;
228+
229+ if ( typeSystem . MainModule . ResolveEntity ( handle ) is ITypeDefinition resolvedType )
230+ foreach ( var baseType in resolvedType . GetNonInterfaceBaseTypes ( ) . Reverse ( ) . Select ( t => t . GetDefinition ( ) ) )
231+ if ( baseType != null && baseType != type )
232+ allMembers = allMembers . Concat ( selector ( baseType ) ) ;
233+ }
234+ return allMembers ;
235+ }
206236 }
207237}
0 commit comments