-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathConfusingOverridesNames.ql
More file actions
76 lines (71 loc) · 2.28 KB
/
ConfusingOverridesNames.ql
File metadata and controls
76 lines (71 loc) · 2.28 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
71
72
73
74
75
76
/**
* @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() + "."