mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
C#: Narrow the set of declarations where we make explicit interface implementations.
This commit is contained in:
@@ -400,7 +400,7 @@ private string stubAccessibility(Member m) {
|
||||
if
|
||||
m.getDeclaringType() instanceof Interface
|
||||
or
|
||||
exists(getSingleSpecificImplementedInterface(m))
|
||||
exists(useExplicitImplementedInterface(m))
|
||||
or
|
||||
m instanceof Constructor and m.isStatic()
|
||||
then result = ""
|
||||
@@ -713,13 +713,49 @@ private string stubEventAccessors(Event e) {
|
||||
else result = ";"
|
||||
}
|
||||
|
||||
private Interface getSingleSpecificImplementedInterface(Member c) {
|
||||
result = unique(Interface i | i = c.(Virtualizable).getExplicitlyImplementedInterface())
|
||||
/**
|
||||
* Returns an interface that `c` explicitly implements, if either or the
|
||||
* following holds.
|
||||
* (1) `c` is not static.
|
||||
* (2) `c` is static and an implementation of a generic with type constraints.
|
||||
* (3) `c` is static and there is another member with the same name
|
||||
* but different return types.
|
||||
*
|
||||
* We use these rules, as explicit interfaces are needed in some cases, eg.
|
||||
* for compilation purposes (both to distinguish members but also to ensure
|
||||
* type constraints are satisfied). We can't always use the explicit interface
|
||||
* due to the generic math support, because then in some cases we will only be
|
||||
* able to access a static via a type variable with type
|
||||
* constraints (C# 11 language feature).
|
||||
*/
|
||||
private Interface useExplicitImplementedInterface(Virtualizable c) {
|
||||
result = unique(Interface i | i = c.getExplicitlyImplementedInterface()) and
|
||||
(
|
||||
not c.isStatic()
|
||||
or
|
||||
c.isStatic() and
|
||||
(
|
||||
not c instanceof Method
|
||||
or
|
||||
c instanceof Method and
|
||||
(
|
||||
exists(TypeParameter t | t = c.getImplementee().(UnboundGeneric).getATypeParameter() |
|
||||
exists(t.getConstraints().getATypeConstraint())
|
||||
)
|
||||
or
|
||||
exists(Member m |
|
||||
(not m.isStatic() or m.(Method).getReturnType() != c.(Method).getReturnType()) and
|
||||
m.getName() = c.getName() and
|
||||
m.getDeclaringType() = c.getDeclaringType()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private string stubExplicitImplementation(Member c) {
|
||||
if exists(getSingleSpecificImplementedInterface(c))
|
||||
then result = stubClassName(getSingleSpecificImplementedInterface(c)) + "."
|
||||
if exists(useExplicitImplementedInterface(c))
|
||||
then result = stubClassName(useExplicitImplementedInterface(c)) + "."
|
||||
else result = ""
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user