(On the infeasibility of) Model/Code CoRefactoring Friedrich Steimann Lehrgebiet Programmiersysteme Fernuniversität in Hagen, Germany Programmiersysteme Refactoring Meaning-preserving change of a software artefact with the aim of improving one or more of its nonfunctional properties. (extended definition) F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme Problem I b class A { b private A a; B public void setA(A a) { … } public A getA() { … } } B a A Rename a class AImpl extends A { private Object b; public void setB(Object b) { … } } AImpl aImpl = new AImpl(); aImpl.setB(aImpl); F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme Problem II A B x : int y : int C x : int Pull Up Field x public class A {} public class B extends A { private int x; private int y; … @not_generated public void init() { x = 10; y = 10; } } public class C extends A { private int x; … } F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme Problem III A B x : int = 1 y : int C x : int = 2 Pull Up Field y public class A {} public class B extends A { private int x = 1; private int y; … @not_generated public void init() { y = x; } } public class C extends A { private int x = 2; … } F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme Constraint-based refactoring proven successful for programs one of the few developed theories of refactoring encodes refactoring invariants as CSPs originally applied to type refactorings (like Extract Superclass) recently generalized to other programming constructs (names, accessibilities, etc.) F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme Constraint rules query constraints r d : bindsr, d r.name d.name constraint variables F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme Example b A a; a = new A(); b r d : bindsra, da bindsr, d r.name d.name ra.name = da.name F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme Refacola refactoring definitions refactoring refactoringdefinitions definitions programs to be refactored programs programs to tobe berefactored refactored Eclipse AST Xtext / Xpand / Xtend Refacola Compiler IDE Refacola Framework program queries writing back Generated Refactoring Tools constraint generator Constraint Solver = component dependencies F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme language UML kinds Class <: ENTITY { name } Feature <: ENTITY { name, type, owner } Attribute <: Feature Operation <: Feature properties name: Identifier type: ClassDomain owner: ClassDomain domains ClassDomain = [ Class ] queries superclass(c: Class, super: Class) rules uniqueFeatureNames for all F1: Feature F2: Feature if F1!=F2 then superclass*(F1.owner, F2.owner) -> F1.name != F2.name refactoring renameFeature forced name of Feature allowed name of Feature refactoring pullupFeature forced owner of Feature allowed name of Feature, of Refactorings Featurewithout Names ASE 2012 F Steimann, owner J von Pilgrim Programmiersysteme From refactoring to corefactoring record transformation traces as facts transformation of attribute to field + getter + setter: attribute2field(a, f) attribute2getter(a, g) attribute2setter(a, s) generate constraints from trace facts F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. language Generation imports Java, UML queries class2class(cU : UML.Class, cJ : Java.Class) attribute2field(a : UML.Attribute, f : Java.Field) attribute2getter(a : UML.Attribute, g : Java.Method) attribute2setter(a : UML.Attribute, s : Java.Method) rules attributeToFieldNames for all a : UML.Attribute f : Java.Field g, s : Java.Method if attribute2field(a, f) and attribute2getter(a, g) and attribute2setter(a, s) then f.name = a.name f.accessibility = private g.name = "get" + a.name g.accessibility = public s.name = "set" + a.name s.accessibility = public F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme Model/Code Co-Refactoring Instrumentation MOF Layer Code Generation M3 transformation language Refactoring Refacola Refacola Refacola M2 UML transformation model & rules Java UML refactorings trace rules Java refactorings M1 model transformation trace code model constraints trace constraints code constraints factbase CSP query engine instance of data flow F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme Research Questions 1. How often is an intended model refactoring inhibited by implied changes of the code which would break its wellformedness or change its meaning and hence cannot be performed? 2. For the model refactorings implying code changes that can be performed: How many changes are implied in the code? 3. How often do implied changes performed in the code propagate back as necessary changes of the model? 4. For the necessary changes propagated back to the model: How often do they inhibit the refactoring? 5. If they do not inhibit the refactoring: How many are they? F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme Evaluation 10 open source java programs reversely engineered class diagrams 3309 classes, 3667 fields, 13196 methods 1036 classes, 878 attributes, 5975 operations internal representation 30627 elements, 143287 facts for model 360694 elements, 534239 facts for code 14579 elements, 26006 facts for trace F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme Research Questions 1. How often is an intended model refactoring inhibited by implied changes of the code? In 50% of all cases! 2. For the model refactorings implying code changes that can be performed: How many changes are implied in the code? 8.5 changes per refactoring! 3. How often do implied changes performed in the code propagate back as necessary changes of the model? In 46% of these cases! 4. For the necessary changes propagated back to the model: How often do they inhibit the refactoring? 14% 5. If they do not inhibit the refactoring: How many are they? 5.6 on average! F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme Chaotic transformations Transformations may react to very small changes by generating largely different code. Even if meaning-preserving, we have no means of synchronizing extensions. Co-refactoring is a dead-end road. F Steimann, J von Pilgrim Refactorings without Names ASE 2012 Programmiersysteme Vielen Dank! Fragen? F Steimann, J von Pilgrim Refactorings without Names ASE 2012