Skip to content

Commit dc50b6b

Browse files
committed
C#: Support for operators in implements relations.
1 parent 8c2931c commit dc50b6b

File tree

2 files changed

+30
-13
lines changed

2 files changed

+30
-13
lines changed

csharp/ql/lib/semmle/code/csharp/Implements.qll

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ pragma[nomagic]
129129
private Virtualizable getACompatibleInterfaceMemberAux(Virtualizable m) {
130130
result = getACompatibleInterfaceAccessor(m) or
131131
result = getACompatibleInterfaceIndexer(m) or
132-
result = getACompatibleInterfaceMethod(m)
132+
result = getACompatibleRelevantInterfaceMember(m)
133133
}
134134

135135
/**
@@ -210,11 +210,13 @@ private predicate getACompatibleInterfaceIndexerAux(Indexer i, ValueOrRefType t)
210210
t = getAPossibleImplementor(i.getDeclaringType())
211211
}
212212

213-
private Method getACompatibleInterfaceMethod0(Method m, int i) {
214-
result = getAnInterfaceMethodCandidate(m) and
213+
private RelevantInterfaceMember getACompatibleRelevantInterfaceMember0(
214+
RelevantInterfaceMember m, int i
215+
) {
216+
result = getARelevantInterfaceMemberCandidate(m) and
215217
i = -1
216218
or
217-
result = getACompatibleInterfaceMethod0(m, i - 1) and
219+
result = getACompatibleRelevantInterfaceMember0(m, i - 1) and
218220
exists(Type t1, Type t2 |
219221
t1 = getArgumentOrReturnType(m, i) and
220222
t2 = getArgumentOrReturnType(result, i)
@@ -223,32 +225,47 @@ private Method getACompatibleInterfaceMethod0(Method m, int i) {
223225
)
224226
}
225227

226-
private Method getACompatibleInterfaceMethod(Method m) {
227-
result = getACompatibleInterfaceMethod0(m, m.getNumberOfParameters())
228+
/**
229+
* A class of callables relevant for interface member compatibility.
230+
*/
231+
private class RelevantInterfaceMember extends Callable {
232+
RelevantInterfaceMember() {
233+
this instanceof Method or
234+
this instanceof Operator
235+
}
236+
237+
predicate isPublic() {
238+
this.(Method).isPublic() or
239+
this.(Operator).isPublic()
240+
}
241+
}
242+
243+
private RelevantInterfaceMember getACompatibleRelevantInterfaceMember(RelevantInterfaceMember m) {
244+
result = getACompatibleRelevantInterfaceMember0(m, m.getNumberOfParameters())
228245
}
229246

230247
/**
231-
* Gets an interface method that may potentially be implemented by `m`.
248+
* Gets an interface method or operator that may potentially be implemented by `m`.
232249
*
233250
* That is, a method with the same name, same number of parameters, and declared
234251
* in a type that is a possible implementor type for the interface type.
235252
*/
236-
private Method getAnInterfaceMethodCandidate(Method m) {
237-
getAPotentialInterfaceMethodAux(result, m.getDeclaringType(), m.getUndecoratedName(),
253+
private RelevantInterfaceMember getARelevantInterfaceMemberCandidate(RelevantInterfaceMember m) {
254+
getAPotentialRelevantInterfaceMemberAux(result, m.getDeclaringType(), m.getUndecoratedName(),
238255
m.getNumberOfParameters()) and
239256
m.isPublic()
240257
}
241258

242259
pragma[nomagic]
243-
private predicate getAPotentialInterfaceMethodAux(
244-
Method m, ValueOrRefType t, string name, int params
260+
private predicate getAPotentialRelevantInterfaceMemberAux(
261+
RelevantInterfaceMember m, ValueOrRefType t, string name, int params
245262
) {
246263
t = getAPossibleImplementor(m.getDeclaringType()) and
247264
name = m.getUndecoratedName() and
248265
params = m.getNumberOfParameters()
249266
}
250267

251-
private Type getArgumentOrReturnType(Method m, int i) {
268+
private Type getArgumentOrReturnType(RelevantInterfaceMember m, int i) {
252269
i = 0 and result = m.getReturnType()
253270
or
254271
result = m.getParameter(i - 1).getType()

csharp/ql/lib/semmle/code/csharp/Member.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ class Overridable extends Declaration, TOverridable {
360360

361361
/**
362362
* A member where the `virtual` modifier is valid. That is, a method,
363-
* a property, an indexer, an event or an operator.
363+
* a property, an indexer, an event, or an operator.
364364
*
365365
* Equivalently, these are the members that can be defined in an interface.
366366
*

0 commit comments

Comments
 (0)