Tool Support for Refactoring Haskell Programs
Total Page:16
File Type:pdf, Size:1020Kb
TOOL SUPPORT FOR REFACTORING HASKELL PROGRAMS a thesis submitted to The University of Kent in the subject of computer science for the degree of doctor of philosophy By Christopher Mark Brown September 2008 Contents List of Tables xi List of Figures xiv Publication xv Abstract xvi Acknowledgements xvii 1 Introduction 1 1.1 Refactoring . 1 1.2 Refactoring Functional Languages . 6 1.2.1 The Haskell Programming Language . 6 1.2.2 The Refactoring Functional Programs Project . 11 1.3 Refactoring Outline . 13 1.4 Contributions of this Research . 13 1.5 Thesis Outline . 16 2 Tools for refactoring 19 ii 2.1 Introduction . 19 2.2 The Programatica Toolset . 22 2.2.1 The Lexer . 22 2.2.2 The Parser . 23 2.2.3 The Abstract Syntax Tree . 25 2.2.4 The Module System . 27 2.2.5 The Pretty Printer . 28 2.2.6 The Advantages and Disadvantages of Using Programatica 28 2.3 Strafunski - Generic Tree Traversal . 29 2.3.1 Strategy Types and Application . 30 2.3.2 Integrating Strafunski with Programatica . 31 2.3.3 Advantages and Disadvantages of Using Strafunski . 34 2.4 The Glasgow Haskell Compiler . 35 2.5 HaRe: The Haskell Refactorer . 36 2.5.1 Gathering Information . 37 2.5.2 Transforming and Analysing . 37 2.5.3 Preserving Appearance . 37 2.5.4 Interfacing HaRe to Text Editors . 38 2.5.5 An Example of HaRe . 38 2.5.6 An API for Defining Refactorings . 43 2.5.7 Refactoring Unit Testing . 43 2.6 Preserving Correctness . 45 2.6.1 The Left and Right Inverse of Refactorings . 48 iii 2.7 Implementing Refactorings . 49 2.8 Summary . 57 3 Program Slicing 60 3.1 Introduction . 60 3.2 Code Elimination . 63 3.2.1 Dead Code Elimination . 63 3.2.2 Irrelevant Code Elimination . 67 3.2.3 Summary . 68 3.3 Slicing Based Refactorings . 69 3.3.1 Splitting . 69 3.3.2 Merging . 72 3.3.3 Design and Implementation Issues . 74 3.4 Summary . 75 4 Structural Refactorings 76 4.1 Folding . 78 4.1.1 Example . 78 4.1.2 Comments . 79 4.1.3 Conditions . 79 4.1.4 Design Issues . 79 4.2 Generative Folding . 82 4.2.1 Example . 83 4.2.2 Comments . 83 iv 4.2.3 Conditions . 83 4.2.4 Design Issues . 84 4.3 Folding As-patterns . 85 4.3.1 Comments . 87 4.3.2 Example . 87 4.3.3 Conditions . 88 4.3.4 Design Issues . 91 4.4 Unfolding As-patterns . 91 4.4.1 Comments . 92 4.4.2 Example . 92 4.4.3 Conditions . 92 4.5 Converting from let to where .................... 95 4.5.1 Example . 95 4.5.2 Conditions . 96 4.6 Converting from where to let .................... 97 4.6.1 Example . 97 4.6.2 Conditions . 98 4.6.3 Design Issues . 99 4.7 Case Analysis Simplification . 100 4.7.1 Example . 100 4.7.2 Conditions . 102 4.7.3 Design Issues . 103 4.8 Bound Variables . 103 v 4.9 Symbolic Evaluation . 104 4.9.1 Case Expression Elimination . 105 4.9.2 Symbolic Evaluation Infrastructure . 106 4.9.3 Where and Let Clauses . 106 4.10 Summary . 108 5 Data Type Based Refactorings 109 5.1 Type Checking . 110 5.2 Adding a Constructor . 111 5.2.1 Example . 111 5.2.2 Conditions . 111 5.2.3 Design Rationale . 111 5.2.4 Design Issues . 114 5.3 Removing a Constructor . 115 5.3.1 Example . 115 5.3.2 Design Issues . 115 5.4 Adding a Field to a Constructor of a Data Type . 118 5.4.1 Example . 118 5.4.2 Conditions . 118 5.4.3 Design Issues . 118 5.4.4 Comments . 119 5.5 Removing a Field . 119 5.5.1 Example . 119 vi 5.5.2 Design Issues . 120 5.6 Introducing Pattern Matches Over an Argument Position . 122 5.6.1 Introduction of Pattern Matches . 124 5.6.2 Introduction of Pattern Matches for Sub-patterns . 126 5.6.3 Introduction of Case Analysis . 127 5.7 Summary . 128 6 Clone Detection and Removal 129 6.1 Introduction . 129 6.2 Related Work . 131 6.2.1 Text-based Techniques . 132 6.2.2 Token-based Techniques . 132 6.2.3 Tree-based Techniques . 133 6.3 The HaRe Clone Detector . 134 6.3.1 AST-Level Clone Analysis . 135 6.3.2 Abstract Syntax Tree Comparison . 139 6.4 Refactoring Support for Clone Removal . 142 6.4.1 General Function Abstraction . 143 6.4.2 Step-by-step Clone Detection . 144 6.4.3 Choosing the Location of the Abstracted Function . 146 6.4.4 Calculating the Abstraction . 149 6.4.5 Abstracting Monadic Sequences . 149 6.5 Summary . 151 vii 7 A Refactoring Case Study 153 7.1 Refactoring Sequence . 154 7.1.1 Stage 1 . 155 7.1.2 Stage 2 . 160 7.1.3 Stage 3 - Clone Removal . 166 7.2 Future Refactorings . 169 7.2.1 Name a type ......................... 169 7.2.2 Transforming Between Guards and if..then..else . 170 7.2.3 Nested Case Expression Elimination . 173 7.3 Refactoring an Expression Processing Example . 175 7.3.1 Step 1: Initial Implementation . 178 7.3.2 Step 2: Introduce Binary Operators . 179 7.3.3 Stage 3: House Keeping . 180 7.3.4 Stage 4: Generalisation . 182 7.3.5 Stage 5: Introduce Variables . 184 7.3.6 Stage 6: Merging . 185 7.3.7 Stage 7: Splitting . 187 7.4 Summary . 190 8 Related Work 191 8.1 Behaviour Preservation and Refactoring . 191 8.2 Refactoring Tools . ..