Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Recording Finer-Grained Software Evolution with IDE: An Annotation-Based Approach

0 views

Published on

Presented at IWPSE-EVOL 2010
http://dx.doi.org/10.1145/1862372.1862378

  • Be the first to comment

  • Be the first to like this

Recording Finer-Grained Software Evolution with IDE: An Annotation-Based Approach

  1. 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. 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
  3. 3. Background  Task Level Commit [SCM Patterns] − We should avoid to commit mixed changesets + - + - Revision: 1 + Log: fixed bug #5 diff + + - - - + Revision: 1 Revision: 2 + + - + Log: fixed bug #5, Log: refactored + refactored, and diff diff corrected a typo + - Revision: 3 + - Mixed Log: corrected a typo diff changeset 3
  4. 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. 5. Problems  Mixed changesets occur in practice − Bug-fix + logging − Large refactorings (via transitional state) 5
  6. 6. Example: bug-fix + logging int foo() { int state = ……; …… state = bar(state, false); …… } 6
  7. 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. 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. 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. 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. 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. 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. 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. 14. Example: bug-fix + logging int foo() { int state = ……; …… state = bar(state, false); …… } 14
  15. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 25. When Commutations Fail  3 cases pi pj pi pj pi pj (a) add; remove (b) add; add (c) remove; remove 25
  26. 26. Deciding Group Order  Possible group order: |G|! cases < < time < < Impossible < < < < < < Impossible < < Impossible  Deciding candidates based on commutability of EOs Impossible 26
  27. 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
  28. 28. 28
  29. 29. The current The title of mode the current mode The number of available modes 29
  30. 30. Application Example import node.Directory; import node.Entry; import node.File; 1 import node.FileTreatmentException; import node.Link; import observer.SizeObserver; import visitor.ListVisitor; Adding method invocations public class Main { public static void main(String[] args) { try { Directory rootDir = new Directory("rootDir"); Directory dir1 = new Directory("dir1"); File file1 = new File("file1", 100); 2 Adding comments file1.addObserver(new SizeObserver()); rootDir.add(file1); rootDir.add(dir1); dir1.add(new File("file2", 200)); dir1.add(new File("file3", 300)); Link link1 = new Link(file1); dir1.add(link1); Link link2 = new Link(file1); dir1.add(link2); // for debugging System.out.println("total size : " + rootDir.getSize()); rootDir.accept(new ListVisitor()); // executing Observer file1.setSize(50); ((Entry)file1).setContent("this is file1"); System.out.println(file1.getContent()); ((Entry)link1).setContent("this is link1"); System.out.println(link1.getContent()); ((Entry)link2).setContent("this is link2"); System.out.println(link2.getContent()); } catch (FileTreatmentException e) { // FIXME e.printStackTrace(); } } } 30
  31. 31. Application Example @@ -21,4 +21,8 @@ @@ -21,4 +21,7 @@ dir1.add(link1); dir1.add(link1); + Link link2 = new Link(file1); + Link link2 = new Link(file1); + dir1.add(link2); + dir1.add(link2); + + + // for debugging System.out.println("total size : " + rootDir.getSize()); System.out.println("total size : " + rootDir.getSize()); rootDir.accept(new ListVisitor()); rootDir.accept(new ListVisitor()); @@ -31,4 +34,6 @@ @@ -31,5 +35,8 @@ ((Entry)link1).setContent("this is link1"); ((Entry)link1).setContent("this is link1"); System.out.println(file1.getContent()); System.out.println(file1.getContent()); + ((Entry)link2).setContent("this is link2"); + ((Entry)link2).setContent("this is link2"); + System.out.println(file1.getContent()); + System.out.println(file1.getContent()); } catch (FileTreatmentException e) { } catch (FileTreatmentException e) { e.printStackTrace(); + // FIXME e.printStackTrace(); @@ -24,4 +24,5 @@ } dir1.add(link2); + // for debugging Raw delta System.out.println("total size : " + rootDir.getSize()); rootDir.accept(new ListVisitor()); @@ -37,4 +38,5 @@ System.out.println(file1.getContent()); } catch (FileTreatmentException e) { Delta by Tann + } // FIXME e.printStackTrace(); 31
  32. 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. 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. 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. 35. Credits  Photo by tokyofoodcast http://www.flickr.com/photos/tokyofoodcast/92537891/ 35

×