@@ -136,12 +136,41 @@ public TypeAnalysisContext ReturnType
136136
137137 protected Memory < byte > ? rawMethodBody ;
138138
139- public MethodAnalysisContext ? BaseMethod => Overrides . FirstOrDefault ( m => m . DeclaringType ? . IsInterface is false ) ;
139+ public MethodAnalysisContext ? BaseMethod
140+ {
141+ get
142+ {
143+ if ( Definition == null )
144+ return null ;
145+
146+ var vtable = DeclaringType ? . Definition ? . VTable ;
147+ if ( vtable == null )
148+ return null ;
149+
150+ for ( var i = 0 ; i < vtable . Length ; ++ i )
151+ {
152+ var vtableEntry = vtable [ i ] ;
153+ if ( vtableEntry is null or { Type : not MetadataUsageType . MethodDef } || vtableEntry . AsMethod ( ) != Definition )
154+ continue ;
155+
156+ var baseType = DeclaringType ? . DefaultBaseType ;
157+ while ( baseType is not null )
158+ {
159+ if ( TryGetMethodForSlot ( baseType , i , out var method ) )
160+ {
161+ return method ;
162+ }
163+ baseType = baseType . DefaultBaseType ;
164+ }
165+ }
166+ return null ;
167+ }
168+ }
140169
141170 private List < MethodAnalysisContext > ? _overrides ;
142171
143172 /// <summary>
144- /// The set of methods which this method overrides.
173+ /// The set of interface methods which this method explicitly overrides.
145174 /// </summary>
146175 public List < MethodAnalysisContext > Overrides
147176 {
@@ -167,31 +196,6 @@ private IEnumerable<MethodAnalysisContext> GetOverrides()
167196
168197 return GetOverriddenMethods ( declaringTypeDefinition , vtable ) ;
169198
170- bool TryGetMethodForSlot ( TypeAnalysisContext declaringType , int slot , [ NotNullWhen ( true ) ] out MethodAnalysisContext ? method )
171- {
172- if ( declaringType is GenericInstanceTypeAnalysisContext genericInstanceType )
173- {
174- var genericMethod = genericInstanceType . GenericType . Methods . FirstOrDefault ( m => m . Slot == slot ) ;
175- if ( genericMethod is not null )
176- {
177- method = new ConcreteGenericMethodAnalysisContext ( genericMethod , genericInstanceType . GenericArguments , [ ] ) ;
178- return true ;
179- }
180- }
181- else
182- {
183- var baseMethod = declaringType . Methods . FirstOrDefault ( m => m . Slot == slot ) ;
184- if ( baseMethod is not null )
185- {
186- method = baseMethod ;
187- return true ;
188- }
189- }
190-
191- method = null ;
192- return false ;
193- }
194-
195199 IEnumerable < MethodAnalysisContext > GetOverriddenMethods ( Il2CppTypeDefinition declaringTypeDefinition , MetadataUsage ? [ ] vtable )
196200 {
197201 for ( var i = 0 ; i < vtable . Length ; ++ i )
@@ -203,18 +207,6 @@ IEnumerable<MethodAnalysisContext> GetOverriddenMethods(Il2CppTypeDefinition dec
203207 if ( vtableEntry . AsMethod ( ) != Definition )
204208 continue ;
205209
206- // Normal inheritance
207- var baseType = DeclaringType ? . DefaultBaseType ;
208- while ( baseType is not null )
209- {
210- if ( TryGetMethodForSlot ( baseType , i , out var method ) )
211- {
212- yield return method ;
213- break ; // We only want direct overrides, not the entire inheritance chain.
214- }
215- baseType = baseType . DefaultBaseType ;
216- }
217-
218210 // Interface inheritance
219211 foreach ( var interfaceOffset in declaringTypeDefinition . InterfaceOffsets )
220212 {
@@ -231,6 +223,31 @@ IEnumerable<MethodAnalysisContext> GetOverriddenMethods(Il2CppTypeDefinition dec
231223 }
232224 }
233225
226+ private static bool TryGetMethodForSlot ( TypeAnalysisContext declaringType , int slot , [ NotNullWhen ( true ) ] out MethodAnalysisContext ? method )
227+ {
228+ if ( declaringType is GenericInstanceTypeAnalysisContext genericInstanceType )
229+ {
230+ var genericMethod = genericInstanceType . GenericType . Methods . FirstOrDefault ( m => m . Slot == slot ) ;
231+ if ( genericMethod is not null )
232+ {
233+ method = new ConcreteGenericMethodAnalysisContext ( genericMethod , genericInstanceType . GenericArguments , [ ] ) ;
234+ return true ;
235+ }
236+ }
237+ else
238+ {
239+ var baseMethod = declaringType . Methods . FirstOrDefault ( m => m . Slot == slot ) ;
240+ if ( baseMethod is not null )
241+ {
242+ method = baseMethod ;
243+ return true ;
244+ }
245+ }
246+
247+ method = null ;
248+ return false ;
249+ }
250+
234251 private static readonly List < IBlockProcessor > blockProcessors =
235252 [
236253 new MetadataProcessor ( ) ,
0 commit comments