-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathConfusingOverridesNames.ql
More file actions
70 lines (65 loc) · 2.35 KB
/
ConfusingOverridesNames.ql
File metadata and controls
70 lines (65 loc) · 2.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/**
* @name Confusing method names because of overriding
* @description Finds methods m1 and m2, where m1 would override m2, except that
* their names differ in capitalization.
* @kind problem
* @problem.severity recommendation
* @precision medium
* @id cs/confusing-override-name
* @tags reliability
* readability
* naming
*/
import csharp
predicate hasSubtypeStar(RefType t, RefType u) {
t = u
or u.getABaseType+() = t
}
/** for each class, get all methods from this class or its
superclasses, with their names in lowercase */
predicate methodNames(RefType t, Method m, string lowercase) {
exists(RefType t2 |
m.getDeclaringType() = t2 and
hasSubtypeStar(t2, t)
) and
lowercase = m.getName().toLowerCase() and
lowercase.length() > 1
}
/** For each class, find the pairs of methods that
are candidates for being confusing in this class */
predicate confusing(Method m1, Method m2) {
exists(RefType t, string lower |
methodNames(t, m1, lower) and
methodNames(t, m2, lower) and
m1.getName() != m2.getName()
)
}
/* Two method names are confusing if all of the following conditions hold:
* They are both static methods or both instance methods.
* They are not declared in the same class, and the superclass method is
* not overridden in an intermediate class
* They have different names.
* They have the same names if case is ignored.
* There is no method in the subclass that has the same name as
* the superclass method
There is an additional check that only methods with names longer than one character
can be considered confusing. */
from Method m1, Method m2
where confusing(m1,m2) and
m1.getDeclaringType() != m2.getDeclaringType() and
(
m1.isStatic() and m2.isStatic()
or
not m1.isStatic() and not m2.isStatic()
) and
not exists(Method mid |
confusing(m1, mid) and
mid.getDeclaringType().getABaseType+() = m2.getDeclaringType()
) and
not exists(Method notConfusing |
notConfusing.getDeclaringType() = m1.getDeclaringType() and
notConfusing.getName() = m2.getName()
) and
m1.fromSource()
select m1, "confusing to have methods " + m1.getName() + " in " + m1.getDeclaringType().getName() + " and "
+ m2.getName() + " in " + m2.getDeclaringType().getName() + "."