Recording Finer-Grained Software Evolution with IDE: An Annotation-Based Approach
1. Recording Finer-Grained
Software Evolution
with IDE:
An Annotation-Based Approach
Shinpei Hayashi and
Motoshi Saeki
Dept. of Computer Science,
Tokyo Institute of Technology
Japan
IWPSE-EVOL 2010
2. Abstract
Recording Finer-Grained SE
− Avoiding to commit mixed changesets
Annotation-Based Approach
− Developers perform edit operations of source
code together with classifying them
− Restructuring source code delta
Results: It works well!
− Defined algorithms for automation
− Implemented a prototyping tool
2
4. Background
Task Level Commit [SCM Patterns]
− We should avoid to commit mixed changesets
Why?
− Reuse (e.g. backport): separation required if we
apply a part of a changeset to another branch
− Reverting: extraction needed if we revert a part
of a changeset
− Understanding: the relations are unclear if the
commit log of a changeset describes multiple
changes
4
5. Problems
Mixed changesets occur in practice
− Bug-fix + logging
− Large refactorings (via transitional state)
5
6. Example: bug-fix + logging
int foo() {
int state = ……;
……
state = bar(state, false);
……
}
6
7. Example: bug-fix + logging
int foo() {
int state = ……;
log.trace(”state = ” + state);
……
state = bar(state, false);
log.trace(”state = ” + state);
……
}
1. Insertion of logging function calls (LFCs) +
finding the bug by executing the program and
confirming outputs of LFCs
7
8. Example: bug-fix + logging
int foo() {
int state = ……; false
log.trace(”state = ” + state);
…… true
state = bar(state, true);
log.trace(”state = ” + state);
……
}
1. Insertion of LFCs + finding the bug
2. Fixing the bug
8
9. Example: bug-fix + logging
int foo() {
int state = ……;
log.trace(”state = ” + state);
……
state = bar(state, true);
log.trace(”state = ” + state);
……
}
1. Insertion of LFCs + finding the bug
2. Fixing the bug
3. Execution again for confirming correct output
4. Commit
9
10. Example: bug-fix + logging
int foo() {
int state = ……;
log.trace(”state = ” + state);
……
state = bar(state, true);
log.trace(”state = ” + state);
……
}
Depends
1. Insertion of LFCs + finding the bug each other
2. Fixing the bug
3. Execution again for confirming correct output
4. Commit
Difficult to commit each of them independently in advance 10
11. Example: large refactoring
Involved with basic refactorings
Reverting needed if we commit each of
basic refactorings
revert
commit commit commit
Refactoring 1 Refactoring 2 Refactoring 3
Large refactoring
commit
11
12. Our Solution
Mixed changesets exist in practice
− Bug-fix + logging
− Large refactorings (via transitional state)
Changes should be managed on IDE
− Hypothesis: developers can identify the
timing of switching their editing intentions
12
13. Proposed Approach
Edit + mode changes Modes
1: fixing bug #5
Structuring edits 2: correcting a typo
according to modes 3: Move Method refactoring
: mode changes
time
<<annotate>>
<<edit>>
Developer Structuring
r1: r2: r3:
"fixed bug #5 ..." "refactored ..." “typo ..." Version
Archive
IDE
13
14. Example: bug-fix + logging
int foo() {
int state = ……;
……
state = bar(state, false);
……
}
14
15. Example: bug-fix + logging
int foo() {
int state = ……; Editing
log.trace(”state = ” + state); by mode 1
……
state = bar(state, false);
log.trace(”state = ” + state);
……
}
1. Insertion of logging function calls (LFCs) +
finding the bug by executing the program and
confirming outputs of LFCs
15
16. Example: bug-fix + logging
int foo() {
int state = ……;
log.trace(”state = ” + state); Editing
……
state = bar(state, true);
by mode 2
log.trace(”state = ” + state);
……
}
1. Insertion of LFCs + finding the bug
2. Fixing the bug
16
17. Example: bug-fix + logging
int foo() {
int state = ……;
log.trace(”state = ” + state);
……
state = bar(state, true);
log.trace(”state = ” + state); Committing
…… as revisions
}
1 and 2
1. Insertion of LFCs + finding the bug
2. Fixing the bug
3. Execution again for confirming correct output
4. Commit
17
18. Example: large refactoring
Use individual mode for each refactoring
commit commit commit
By mode 2 By mode 3
Mode 1
Refactoring 1 Refactoring 2 Refactoring 3
Large refactoring
18
19. Automation
Ordering edit operations Modes
1: fixing bug #5
Deciding the group order 2: correcting a typo
3: Move Method refactoring
: mode changes
time
<<annotate>>
<<edit>>
Developer Structuring
r1: r2: r3:
"fixed bug #5 ..." "refactored ..." “typo ..." Version
Archive
IDE
19
20. Automation < <
< <
Ordering edit operations Modes
< < Which orders #5
1: fixing bug
Deciding the patch order
< < are feasible? a typo
2: correcting
3: Move Method refactoring
< <
: mode changes
< < time
<<annotate>>
<<edit>>
Developer Structuring
r1: r2: r3:
"fixed bug #5 ..." "refactored ..." “typo ..." Version
Archive
IDE
20
21. Proposed System
Inputs Outputs
Edit history
(Seq. of
edit operations) Source code
deltas for each
Mode switching intentional changes
information
• when
• which mode
21
22. Edit Operations (EOs)
int foo() {
int state = 1;
return state;
}
A code fragment is added
• to file f
pi = (add, f, 29, 20)
• begins with 29th character
int foo() {
int state = 1; • Its length is 20
log.trace(state);
return state;
}
pj = (add, f, 63, 2)
int foo() {
int state = 1;
log.trace(state);
return state+1;
}
22
23. Commutations of EOs
Modifying the offsets
int foo() {
int state = 1;
of EOs
return state;
}
pi = (add, f, 29, 20) pj' = (add, f, 43, 2)
int foo() { int foo() {
int state = 1; int state = 1;
log.trace(state); return state+1;
return state; }
}
pj = (add, f, 63, 2) pi' = (add, f, 29, 20)
int foo() { int foo() {
int state = 1; int state = 1;
log.trace(state); log.trace(state);
return state+1; return state+1;
} }
23
24. Ordering EOs
Bubble sort based time
on group orders
− E.g. < <
EOs are commutated
when they are swapped
sorting criteria needed
for achieving that
all commutations
succeed
24
25. When Commutations Fail
3 cases
pi pj pi pj pi pj
(a) add; remove (b) add; add (c) remove; remove
25
26. Deciding Group Order
Possible group order: |G|! cases
< < time
< < Impossible
< <
< <
< < Impossible
< < Impossible
Deciding candidates based
on commutability of EOs Impossible
26
27. Tann: Prototype Implementation
ModeManager: As an Eclipse plug-in
Automating the reordering mechanism
OperationRecorder Edit history commute.rb
[Omori 08] (XML)
• Reordering EOs
• Collecting EOs based on modes
ModeManager
• UI of mode switching
• Collecting switch info. Switching
Information
Eclipse
Outputs:
Deltas for each mode 27
32. Pros and Cons
Positive points
− Not depend on programming languages
− Fully-automated (except for classification)
− High affinity to traditional SCMs
(current) Negative points
− Not considering syntaxes/semantics of
programming languages
− Classifications have to be done correctly
32
33. Future Work
Improving maturity of implementation
− Collaborating with UI of underlying SCM
− Warning when the structuring fails
New UI for reclassifying EOs
− Changing the group of past EOs
Other applications
− Large (group-level) undo on IDE
33
34. Background Proposed Approach
Task Level Commit [SCM Patterns]
Edit + mode changes Modes
1: fixing bug #5
− We should avoid to commit mixed changesets Structuring edits 2: correcting a typo
according to modes 3: Move Method refactoring
: mode changes
+
+
- time
-
Revision: 1 <<annotate>>
+
Log: fixed bug #5 diff +
+
-
-
-
Revision: 1 <<edit>>
Revision: 2 +
+
+
-
+
Log: fixed bug #5, Developer Structuring
Log: refactored + refactored, and
diff diff corrected a typo
r1: r2: r3:
+ "fixed bug #5 ..." "refactored ..." “typo ..." Version
-
Archive
Revision: 3 +
- Mixed
Log: corrected a typo IDE
diff changeset
3 13
Deciding Group Order Tann: Prototype Implementation
Possible group order: |G|! cases ModeManager: As an Eclipse plug-in
< < time Automating the reordering mechanism
< < Impossible
OperationRecorder Edit history commute.rb
< < [Omori 08] (XML)
[Omori 08]
•Reordering EOs
< < •Collecting EOs based on modes
< < Impossible
ModeManager
< < Impossible ed
fail •UI of mode switching
Switching
Deciding candidates based •Collecting switch info.
Information
on commutability of EOs Impossible Eclipse
Outputs:
26
Deltas for each mode 27
35. Credits
Photo by tokyofoodcast
http://www.flickr.com/photos/tokyofoodcast/92537891/
35