@@ -572,6 +572,16 @@ public override MethodDesc ResolveVariantInterfaceMethodToVirtualMethodOnType(Me
572
572
return ResolveVariantInterfaceMethodToVirtualMethodOnType ( interfaceMethod , ( MetadataType ) currentType ) ;
573
573
}
574
574
575
+ public override MethodDesc ResolveInterfaceMethodToStaticVirtualMethodOnType ( MethodDesc interfaceMethod , TypeDesc currentType )
576
+ {
577
+ return ResolveInterfaceMethodToStaticVirtualMethodOnType ( interfaceMethod , ( MetadataType ) currentType ) ;
578
+ }
579
+
580
+ public override MethodDesc ResolveVariantInterfaceMethodToStaticVirtualMethodOnType ( MethodDesc interfaceMethod , TypeDesc currentType )
581
+ {
582
+ return ResolveVariantInterfaceMethodToStaticVirtualMethodOnType ( interfaceMethod , ( MetadataType ) currentType ) ;
583
+ }
584
+
575
585
//////////////////////// INTERFACE RESOLUTION
576
586
//Interface function resolution
577
587
// Interface function resolution follows the following rules
@@ -588,6 +598,8 @@ public override MethodDesc ResolveVariantInterfaceMethodToVirtualMethodOnType(Me
588
598
// See current interface call resolution for details on how that happens.
589
599
private static MethodDesc ResolveInterfaceMethodToVirtualMethodOnType ( MethodDesc interfaceMethod , MetadataType currentType )
590
600
{
601
+ Debug . Assert ( ! interfaceMethod . Signature . IsStatic ) ;
602
+
591
603
if ( currentType . IsInterface )
592
604
return null ;
593
605
@@ -657,6 +669,8 @@ private static MethodDesc ResolveInterfaceMethodToVirtualMethodOnType(MethodDesc
657
669
658
670
public static MethodDesc ResolveVariantInterfaceMethodToVirtualMethodOnType ( MethodDesc interfaceMethod , MetadataType currentType )
659
671
{
672
+ Debug . Assert ( ! interfaceMethod . Signature . IsStatic ) ;
673
+
660
674
MetadataType interfaceType = ( MetadataType ) interfaceMethod . OwningType ;
661
675
bool foundInterface = IsInterfaceImplementedOnType ( currentType , interfaceType ) ;
662
676
MethodDesc implMethod ;
@@ -841,5 +855,108 @@ public static IEnumerable<MethodDesc> EnumAllVirtualSlots(MetadataType type)
841
855
} while ( type != null ) ;
842
856
}
843
857
}
858
+
859
+ /// <summary>
860
+ /// Try to resolve a given virtual static interface method on a given constrained type and its base types.
861
+ /// </summary>
862
+ /// <param name="interfaceMethod">Interface method to resolve</param>
863
+ /// <param name="currentType">Type to attempt virtual static method resolution on</param>
864
+ /// <returns>MethodDesc of the resolved virtual static method, null when not found (runtime lookup must be used)</returns>
865
+ public static MethodDesc ResolveInterfaceMethodToStaticVirtualMethodOnType ( MethodDesc interfaceMethod , MetadataType currentType )
866
+ {
867
+ TypeDesc interfaceType = interfaceMethod . OwningType ;
868
+
869
+ // Search for match on a per-level in the type hierarchy
870
+ for ( MetadataType typeToCheck = currentType ; typeToCheck != null ; typeToCheck = typeToCheck . MetadataBaseType )
871
+ {
872
+ MethodDesc resolvedMethodOnType = TryResolveVirtualStaticMethodOnThisType ( typeToCheck , interfaceMethod ) ;
873
+ if ( resolvedMethodOnType != null )
874
+ {
875
+ return resolvedMethodOnType ;
876
+ }
877
+ }
878
+ return null ;
879
+ }
880
+
881
+ /// <summary>
882
+ /// Try to resolve a given virtual static interface method on a given constrained type and its base types.
883
+ /// </summary>
884
+ /// <param name="interfaceMethod">Interface method to resolve</param>
885
+ /// <param name="currentType">Type to attempt virtual static method resolution on</param>
886
+ /// <returns>MethodDesc of the resolved virtual static method, null when not found (runtime lookup must be used)</returns>
887
+ public static MethodDesc ResolveVariantInterfaceMethodToStaticVirtualMethodOnType ( MethodDesc interfaceMethod , MetadataType currentType )
888
+ {
889
+ TypeDesc interfaceType = interfaceMethod . OwningType ;
890
+
891
+ // Search for match on a per-level in the type hierarchy
892
+ for ( MetadataType typeToCheck = currentType ; typeToCheck != null ; typeToCheck = typeToCheck . MetadataBaseType )
893
+ {
894
+ MethodDesc resolvedMethodOnType = TryResolveVirtualStaticMethodOnThisType ( typeToCheck , interfaceMethod ) ;
895
+ if ( resolvedMethodOnType != null )
896
+ {
897
+ return resolvedMethodOnType ;
898
+ }
899
+
900
+ // Variant interface dispatch
901
+ foreach ( DefType runtimeInterfaceType in typeToCheck . RuntimeInterfaces )
902
+ {
903
+ if ( runtimeInterfaceType == interfaceType )
904
+ {
905
+ // This is the variant interface check logic, skip this
906
+ continue ;
907
+ }
908
+
909
+ if ( ! runtimeInterfaceType . HasSameTypeDefinition ( interfaceType ) )
910
+ {
911
+ // Variance matches require a typedef match
912
+ // Equivalence isn't sufficient, and is uninteresting as equivalent interfaces cannot have static virtuals.
913
+ continue ;
914
+ }
915
+
916
+ if ( runtimeInterfaceType . CanCastTo ( interfaceType ) )
917
+ {
918
+ // Attempt to resolve on variance matched interface
919
+ MethodDesc runtimeInterfaceMethod = runtimeInterfaceType . FindMethodOnExactTypeWithMatchingTypicalMethod ( interfaceMethod ) ;
920
+ resolvedMethodOnType = TryResolveVirtualStaticMethodOnThisType ( typeToCheck , runtimeInterfaceMethod ) ;
921
+ if ( resolvedMethodOnType != null )
922
+ {
923
+ return resolvedMethodOnType ;
924
+ }
925
+ }
926
+ }
927
+ }
928
+ return null ;
929
+ }
930
+
931
+ /// <summary>
932
+ /// Try to resolve a given virtual static interface method on a given constrained type and return the resolved method or null when not found.
933
+ /// </summary>
934
+ /// <param name="constrainedType">Type to attempt method resolution on</param>
935
+ /// <param name="interfaceMethod">Method to resolve</param>
936
+ /// <returns>MethodDesc of the resolved method or null when not found (runtime lookup must be used)</returns>
937
+ private static MethodDesc TryResolveVirtualStaticMethodOnThisType ( MetadataType constrainedType , MethodDesc interfaceMethod )
938
+ {
939
+ Debug . Assert ( interfaceMethod . Signature . IsStatic ) ;
940
+
941
+ MethodImplRecord [ ] possibleImpls = constrainedType . FindMethodsImplWithMatchingDeclName ( interfaceMethod . Name ) ;
942
+ if ( possibleImpls == null )
943
+ return null ;
944
+
945
+ MethodDesc interfaceMethodDefinition = interfaceMethod . GetMethodDefinition ( ) ;
946
+ foreach ( MethodImplRecord methodImpl in possibleImpls )
947
+ {
948
+ if ( methodImpl . Decl == interfaceMethodDefinition )
949
+ {
950
+ MethodDesc resolvedMethodImpl = methodImpl . Body ;
951
+ if ( interfaceMethod != interfaceMethodDefinition )
952
+ {
953
+ resolvedMethodImpl = resolvedMethodImpl . MakeInstantiatedMethod ( interfaceMethod . Instantiation ) ;
954
+ }
955
+ return resolvedMethodImpl ;
956
+ }
957
+ }
958
+
959
+ return null ;
960
+ }
844
961
}
845
962
}
0 commit comments