@@ -400,7 +400,7 @@ private string stubAccessibility(Member m) {
400
400
if
401
401
m .getDeclaringType ( ) instanceof Interface
402
402
or
403
- exists ( getSingleSpecificImplementedInterface ( m ) )
403
+ exists ( useExplicitImplementedInterface ( m ) )
404
404
or
405
405
m instanceof Constructor and m .isStatic ( )
406
406
then result = ""
@@ -713,13 +713,49 @@ private string stubEventAccessors(Event e) {
713
713
else result = ";"
714
714
}
715
715
716
- private Interface getSingleSpecificImplementedInterface ( Member c ) {
717
- result = unique( Interface i | i = c .( Virtualizable ) .getExplicitlyImplementedInterface ( ) )
716
+ /**
717
+ * Returns an interface that `c` explicitly implements, if either or the
718
+ * following holds.
719
+ * (1) `c` is not static.
720
+ * (2) `c` is static and an implementation of a generic with type constraints.
721
+ * (3) `c` is static and there is another member with the same name
722
+ * but different return types.
723
+ *
724
+ * We use these rules, as explicit interfaces are needed in some cases, eg.
725
+ * for compilation purposes (both to distinguish members but also to ensure
726
+ * type constraints are satisfied). We can't always use the explicit interface
727
+ * due to the generic math support, because then in some cases we will only be
728
+ * able to access a static via a type variable with type
729
+ * constraints (C# 11 language feature).
730
+ */
731
+ private Interface useExplicitImplementedInterface ( Virtualizable c ) {
732
+ result = unique( Interface i | i = c .getExplicitlyImplementedInterface ( ) ) and
733
+ (
734
+ not c .isStatic ( )
735
+ or
736
+ c .isStatic ( ) and
737
+ (
738
+ not c instanceof Method
739
+ or
740
+ c instanceof Method and
741
+ (
742
+ exists ( TypeParameter t | t = c .getImplementee ( ) .( UnboundGeneric ) .getATypeParameter ( ) |
743
+ exists ( t .getConstraints ( ) .getATypeConstraint ( ) )
744
+ )
745
+ or
746
+ exists ( Member m |
747
+ ( not m .isStatic ( ) or m .( Method ) .getReturnType ( ) != c .( Method ) .getReturnType ( ) ) and
748
+ m .getName ( ) = c .getName ( ) and
749
+ m .getDeclaringType ( ) = c .getDeclaringType ( )
750
+ )
751
+ )
752
+ )
753
+ )
718
754
}
719
755
720
756
private string stubExplicitImplementation ( Member c ) {
721
- if exists ( getSingleSpecificImplementedInterface ( c ) )
722
- then result = stubClassName ( getSingleSpecificImplementedInterface ( c ) ) + "."
757
+ if exists ( useExplicitImplementedInterface ( c ) )
758
+ then result = stubClassName ( useExplicitImplementedInterface ( c ) ) + "."
723
759
else result = ""
724
760
}
725
761
0 commit comments