2. Agenda
• What are code critics?
• Motivation:Why are we analyzing them?
• Approach: How are we analyzing them?
• Results so far
3. What are code critics?
• Recommendation facility of the Pharo
Smalltalk IDE.
• Signal controversial implementation choices
(such as code smells) at class- and method-
level.
10. GodMethod:= Long methods + Long Parameter List + Switch Statements
Motivation
• Current approaches to detect code smells:
Lines Of Code (LOC):
Number Of Parameters (NOP):
Number Of Local Variables (NOLV):
Maximum Number Of Branches (MNOB):
number of lines of code in a method, including comments and white-lines................
number of parameters in the signature of a method...................................
number of local variables are declared within a method...................
number of nested branches (if-else and/or case) in a method
God Method:= (LOC, TopValues(20%)) butnotin (LOC, LowerThan(70)) and
((NOP, HigherThan(4) or (NOLV, HigherThan(4))) and
(MNOB, HIgherThan(4))
12. Motivation
• Current approaches to detect code smells:
• top - down = right aggregation strategy?
• depend on metrics
• absolute = subjective
• relative = depend on application + version
• not reliable = different results for different tools +
might not assess what you want
• use heuristics = incomplete
• GOAL: go bottom-up!
13. Approach
• ∀ critics*, ∀ methods / classes, ∀ packages
• Find pairs of critics that tend to co-occur
• Filter [obvious | noisy | uninteresting]
• Analyze these pairs
• Classify pairs by the nature of their relation
* We eliminated spelling critics (non native speakers are more likely to violate these rules = noise)
14. CC09. Instc variables !read & written
CC16. Sends ‘questionable’ message
CC7. Excessive number of variables
CC6. Excessive number of methods
CC20.Variables not referenced AmbiguousSelector
BlockNode
Encoder
LiteralVariableNode
VariableNode
CommentNode
UndVariableReference
MessageNode
AssignmentNode
ParseNode
MethodNode
Decompiler
Compiler
Parser
BytecodeEncoder
TempVariableNode
distance between rules
=5/6=0.83
17. Results
Graphs of relations between critics
• Nodes
• color: current category of the critic
• shape: type of rule (box = transformation)
• thickness: number of relations
• Edges:
• color: frequency of the relation (in terms of packages where it occurs)
• Frequent | Rare
• thickness: distance between the rules (ratio of coincidence in the same
SCEs)
• Similar (d-->0) | Different (d-->1)
Bug
Pot. Bug
Des. Flaw
Optimization
Idiom
Style
Unclassified
18. 1 2
7
9
11
16
20
3 4 56
8
10
14
15
17
19
18
12 13
1 A metamodel class does not override a method that
2 Class not referenced
3 Class variable capitalization
4 Defines = but not hash
5 Excessive inheritance depth
6 Excessive number of methods
7 Excessive number of variables
8 Instance variables defined in all subclasses
9 Instance variables not read AND written
10 Method defined in all subclasses, but not in supercl
11 No class comment
12 Number of addDependent: messages > removeDep
13 Overrides a 'special' message
14 References an abstract class
15 Refers to class name instead of 'self class'
16 Sends 'questionable' message
17 Subclass responsibility not defined
18Variable is only assigned a single literal value
19Variable referenced in only one method and always
20Variables not referenced
1
2
3
4
5
6
7
8
9
10
11
Results
Co-occurring Class Critics
19. Results
Co-occurring Method Critics
2 = nil -> isNil AND ~= nil -> notNil
4 add translations to strings in menus
6 Debugging code left in methods
8 Eliminate guarding clauses
10 Excessive number of arguments
11 Guarding clauses
12 ifTrue:/ifFalse: returns instead of and:/or:'s
13 Inconsistent method classification
14 Inspect instances of A + B * C might be A + (B * C)
16 Law of demeter
19 Long methods
20 Menus missing translations
21 Messages sent but not implemented
22 Method has no timeStamp
24 Methods implemented but not sent
25 Move assignment out of unwind blocks
26 Move variable assignment outside of single statement ifTrue:ifFalse: blocks
27 Possible missing ; yourself
30 Rewrite ifTrue:ifFalse: using min:/max:
34 Sends unknown message to global
35 String concatenation instead of streams
36 Temporaries read before written
38 Temporary variables not read AND writte
39 Unclassified methods
42 Unnecessary assignment or return in bloc
43 Use cascaded nextPutAll:'s instead of #, in
44 Uses (a and: [b]) and: [c] instead of a and: [
48 Uses do: instead of collect: or select:'s
50 Uses size = 0, = nil, or at: 1 instead of isEm
55 Utility methods
1
47 2
12
16
19
26
30
50
3
4
5
6
21
36
43
78
11
9
10
27
13
22
39
14
15
2435
44
55
17
40
2038
48
34
25
42
5 7 9
13
15 17
40
18 23 28
49
29 31
33
32 37 41 45 46 51 52 53 54
20. Results
Refactorings suggested for code critics
• CIC-1: Misleading name
!
• CIC-2:Too general
!
• CIC-3:Too tolerant
!
• CIC-4:Too restrictive
!
• CIC-5:Too many results
!
• CIC-6: Missing critics
!
• CIC-7: Good critics
References an abstract class
Instance variables not read AND written
Overrides a ‘special’ message
Sends questionable messages
Refers to classname instead of self
anObject isKindOf: X
X allSubclasses
X new
self class == X
Excessive inheritance Depth
Excessive inheritance Depth
Inheritance Smells
Not overridden
self superMessage
super superMessage
Defines = but not hash
Method defined in all subclasses, but not in superclasses
21. Due to evolution: deprecated or refactoring critics
Results
PCC-1 Redundant critics
1
47 2
16
19
26
30
3 5
6
36
8
11
10
14
35
44
38
25
#detect:ifNone: -> anySatisfy:
Uses detect:ifNone: instead of contains:
19
3 5
21
7 9
10
27
13
22
39
15
24
55
17
40
18
2038
8
34
23 28
49
29
Uses do: instead of contains: or detect:'s
Replace with #allSatisfy:, #anySatisfy: or #noneSatisfy:
28
49
29 31
33
32 37 41 45 46 51 52 53 54Rewrite super messages to self messages when both refer to same method
Sends different super message
22. Critics positively contribute to another one, without being
an implication
Results
PCC-2 Accidental correlation
1 2
7
9
11
16
20
3 4 56
8
10
14
15
17
19
18
12 131 2
7
9
11
16
20
3 4 56
8
10
14
15
17
19
18
12 13
Excessive number of variables
Excessive number of methods
Sends questionable message
No common root cause
Kind-of-correlation but no causal link
Solving one does not fix the other
Trial-and-error code
23. Part of Critic1 = Part of Critic 2
Both rules need refactoring
Results
PCC-3: Requires splitting
7
9
11
16
20
8
19
18
Variables not referenced
Instance variables not read AND written
Instc. var notReferenced
Class var notReferenced
Instc. var only read
Instc. var only written
Instc. var notReferenced
24. Rule1 + Rule2 are more useful (as it is more
specific)
Results
PCC-4: Requires merging
21
27
13
22
39
40
20
34
49 33Inconsistent method classification
Unclassified methods
Inconsistently unclassified methods
25. Correlation due to specific kind of source
entity targeted
Results
PCC-5: Same niche
1
7
9
11
16
20
6
8
10
14
15
17
19
18
Subclass responsibility not defined
References an abstract class
26. In practice, the majority of results for one are
also results for the other
Results
PCC-6:Almost subset
2
7
9
11
16
20
3 4 5
8
10 19
18
12 13
Variable referenced in only one method and always assigned first
Instance variables not read AND written
results CC19
results CC09
Restructure
CC09
27. If the ill-defined critic were fixed, the
correlation would probably disappear
Results
PCC-7: Ill defined
Restructure
CC15
7
9
11
16
20
8
10
14
15
17
19
18
Refers to classname instead of self class
Sends questionable message
anObject isKindOf: X
X allSubclasses
X new
self class == X
28. One of the pair generates many results
Results
PCC-8: Noisy correlation
1 2
7
9
11
16
20
3 4 56
8
10
14
15
17
19
18
Excessive number of methods
29. Meaningful correlations
Results
PCC-9: High level critic
16
19
50 4
6
21
36
43
11
10
27
13
22
14
24
44
55
2038
48
34
25
42
Law of Demeter
Utility methods
Methods implemented but not sent
30. Future work
• Analyze other low-level controversial
implementation choices: FindBugs, PMD,
CheckStyle
• Check if the same critiques apply.
• Repeat the analysis iteratively
• Propose high-level groupings for the
controversial implementation choices