1 \documentclass[USenglish,11pt]{ifimaster}
3 \usepackage[utf8]{inputenc}
4 \usepackage[T1]{fontenc,url}
5 \usepackage{lmodern} % using Latin Modern to be able to use bold typewriter font
11 \usepackage{tikz-qtree}
12 \usetikzlibrary{shapes,snakes,trees,arrows,shadows,positioning,calc}
13 \usepackage{babel,textcomp,csquotes,ifimasterforside}
16 \usepackage[hidelinks]{hyperref}
18 %\usepackage[xindy]{glossaries}
20 \usepackage[style=alphabetic,backend=bibtex]{biblatex}
22 \usepackage{mathtools}
24 % use 'disable' before printing:
25 \usepackage[]{todonotes}
32 \usepackage{perpage} %the perpage package
33 \MakePerPage{footnote} %the perpage package command
35 \theoremstyle{definition}
36 \newtheorem*{wordDef}{Definition}
37 \newtheorem*{theorem}{Theorem}
39 \graphicspath{ {./figures/} }
41 \newcommand{\citing}[1]{~\cite{#1}}
42 %\newcommand{\myref}[1]{\cref{#1} on \cpageref{#1}}
43 \newcommand{\myref}[1]{\vref{#1}}
45 \newcommand{\definition}[1]{\begin{wordDef}#1\end{wordDef}}
46 \newcommand{\see}[1]{(see \myref{#1})}
47 \newcommand{\explanation}[3]{\noindent\textbf{\textit{#1}}\\*\emph{When:}
48 #2\\*\emph{How:} #3\\*[-7px]}
50 %\newcommand{\type}[1]{\lstinline{#1}}
51 \newcommand{\code}[1]{\texttt{\textbf{#1}}}
52 \newcommand{\type}[1]{\code{#1}}
53 \newcommand{\typeref}[1]{\footnote{\type{#1}}}
54 \newcommand{\typewithref}[2]{\type{#2}\typeref{#1.#2}}
55 \newcommand{\method}[1]{\type{#1}}
56 \newcommand{\methodref}[2]{\footnote{\type{#1}\method{\##2()}}}
57 \newcommand{\methodwithref}[2]{\method{#2}\footnote{\type{#1}\method{\##2()}}}
58 \newcommand{\var}[1]{\type{#1}}
60 \newcommand{\refactoring}[1]{\emph{#1}}
61 \newcommand{\ExtractMethod}{\refactoring{Extract Method}\xspace}
62 \newcommand{\MoveMethod}{\refactoring{Move Method}\xspace}
63 \newcommand{\ExtractAndMoveMethod}{\refactoring{Extract and Move Method}\xspace}
65 \newcommand\todoin[2][]{\todo[inline, caption={#2}, #1]{
66 \begin{minipage}{\textwidth-4pt}#2\end{minipage}}}
68 \title{Automated Composition of Refactorings}
69 \subtitle{Composing the Extract and Move Method refactorings in Eclipse}
70 \author{Erlend Kristiansen}
73 %\newglossaryentry{profiling}
76 % description={is to run a computer program with a profiler attached}
79 \bibliography{bibliography/master-thesis-erlenkr-bibliography}
81 % UML comment in TikZ:
82 % ref: https://tex.stackexchange.com/questions/103688/folded-paper-shape-tikz
84 \pgfdeclareshape{umlcomment}{
85 \inheritsavedanchors[from=rectangle] % this is nearly a rectangle
86 \inheritanchorborder[from=rectangle]
87 \inheritanchor[from=rectangle]{center}
88 \inheritanchor[from=rectangle]{north}
89 \inheritanchor[from=rectangle]{south}
90 \inheritanchor[from=rectangle]{west}
91 \inheritanchor[from=rectangle]{east}
92 % ... and possibly more
93 \backgroundpath{% this is new
94 % store lower right in xa/ya and upper right in xb/yb
95 \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
96 \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
97 % compute corner of ‘‘flipped page’’
98 \pgf@xc=\pgf@xb \advance\pgf@xc by-10pt % this should be a parameter
99 \pgf@yc=\pgf@yb \advance\pgf@yc by-10pt
100 % construct main path
101 \pgfpathmoveto{\pgfpoint{\pgf@xa}{\pgf@ya}}
102 \pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
103 \pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yb}}
104 \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
105 \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@ya}}
108 \pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@yb}}
109 \pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
110 \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yc}}
111 \pgfpathlineto{\pgfpoint{\pgf@xc}{\pgf@yc}}
116 \tikzstyle{comment}=[%
129 %\interfootnotelinepenalty=10000
137 \todoin{\textbf{Remove all todos (including list) before delivery/printing!!!
138 Can be done by removing ``draft'' from documentclass.}}
139 \todoin{Write abstract}
147 The discussions in this report must be seen in the context of object oriented
148 programming languages, and Java in particular, since that is the language in
149 which most of the examples will be given. All though the techniques discussed
150 may be applicable to languages from other paradigms, they will not be the
151 subject of this report.
155 \chapter{What is Refactoring?}
157 This question is best answered by first defining the concept of a
158 \emph{refactoring}, what it is to \emph{refactor}, and then discuss what aspects
159 of programming make people want to refactor their code.
161 \section{Defining refactoring}
162 Martin Fowler, in his classic book on refactoring\citing{refactoring}, defines a
163 refactoring like this:
166 \emph{Refactoring} (noun): a change made to the internal
167 structure\footnote{The structure observable by the programmer.} of software to
168 make it easier to understand and cheaper to modify without changing its
169 observable behavior.~\cite[p.~53]{refactoring}
172 \noindent This definition assigns additional meaning to the word
173 \emph{refactoring}, beyond the composition of the prefix \emph{re-}, usually
174 meaning something like ``again'' or ``anew'', and the word \emph{factoring},
175 that can mean to isolate the \emph{factors} of something. Here a \emph{factor}
176 would be close to the mathematical definition of something that divides a
177 quantity, without leaving a remainder. Fowler is mixing the \emph{motivation}
178 behind refactoring into his definition. Instead it could be more refined, formed
179 to only consider the \emph{mechanical} and \emph{behavioral} aspects of
180 refactoring. That is to factor the program again, putting it together in a
181 different way than before, while preserving the behavior of the program. An
182 alternative definition could then be:
184 \definition{A \emph{refactoring} is a transformation
185 done to a program without altering its external behavior.}
187 From this we can conclude that a refactoring primarily changes how the
188 \emph{code} of a program is perceived by the \emph{programmer}, and not the
189 \emph{behavior} experienced by any user of the program. Although the logical
190 meaning is preserved, such changes could potentially alter the program's
191 behavior when it comes to performance gain or -penalties. So any logic depending
192 on the performance of a program could make the program behave differently after
195 In the extreme case one could argue that \emph{software obfuscation} is
196 refactoring. Software obfuscation makes source code harder to read and analyze,
197 while preserving its semantics. It is often used to protect proprietary
198 software. It restrains uninvited viewers, so they have a hard time analyzing
199 code that they are not supposed to know how works. This could be a problem when
200 using a language that is possible to decompile, such as Java.
202 Obfuscation could be done composing many, more or less randomly chosen,
203 refactorings. Then the question arises whether it can be called a
204 \emph{composite refactoring} or not \see{compositeRefactorings}? The answer is
205 not obvious. First, there is no way to describe the mechanics of software
206 obfuscation, because there are infinitely many ways to do that. Second,
207 obfuscation can be thought of as \emph{one operation}: Either the code is
208 obfuscated, or it is not. Third, it makes no sense to call software obfuscation
209 \emph{a refactoring}, since it holds different meaning to different people.
211 This last point is important, since one of the motivations behind defining
212 different refactorings, is to establish a \emph{vocabulary} for software
213 professionals to use when reasoning about and discussing programs, similar to
214 the motivation behind \emph{design patterns}\citing{designPatterns}. A design
215 pattern is a named abstraction, that is meant to solve a general design problem.
216 It describes the key aspects of a common problem and identifies its
217 participators and how they collaborate.
220 So for describing \emph{software obfuscation}, it might be more appropriate to
221 define what you do when performing it rather than precisely defining its
222 mechanics in terms of other refactorings.
225 \section{The etymology of 'refactoring'}
226 It is a little difficult to pinpoint the exact origin of the word
227 ``refactoring'', as it seems to have evolved as part of a colloquial
228 terminology, more than a scientific term. There is no authoritative source for a
229 formal definition of it.
231 According to Martin Fowler\citing{etymology-refactoring}, there may also be more
232 than one origin of the word. The most well-known source, when it comes to the
233 origin of \emph{refactoring}, is the
234 Smalltalk\footnote{\label{footNote}Programming language} community and their
235 infamous \emph{Refactoring
236 Browser}\footnote{\url{http://st-www.cs.illinois.edu/users/brant/Refactory/RefactoringBrowser.html}}
237 described in the article \emph{A Refactoring Tool for
238 Smalltalk}\citing{refactoringBrowser1997}, published in 1997.
239 Allegedly\citing{etymology-refactoring}, the metaphor of factoring programs was
240 also present in the Forth\textsuperscript{\ref{footNote}} community, and the
241 word ``refactoring'' is mentioned in a book by Leo Brodie, called \emph{Thinking
242 Forth}\citing{brodie2004}, first published in 1984\footnote{\emph{Thinking
243 Forth} was first published in 1984 by the \emph{Forth Interest Group}. Then it
244 was reprinted in 1994 with minor typographical corrections, before it was
245 transcribed into an electronic edition typeset in \LaTeX\ and published under a
246 Creative Commons licence in
247 2004. The edition cited here is the 2004 edition, but the content should
248 essentially be as in 1984.}. The exact word is only printed one
249 place~\cite[p.~232]{brodie2004}, but the term \emph{factoring} is prominent in
250 the book, that also contains a whole chapter dedicated to (re)factoring, and how
251 to keep the (Forth) code clean and maintainable.
254 \ldots good factoring technique is perhaps the most important skill for a
255 Forth programmer.~\cite[p.~172]{brodie2004}
258 \noindent Brodie also express what \emph{factoring} means to him:
261 Factoring means organizing code into useful fragments. To make a fragment
262 useful, you often must separate reusable parts from non-reusable parts. The
263 reusable parts become new definitions. The non-reusable parts become arguments
264 or parameters to the definitions.~\cite[p.~172]{brodie2004}
267 Fowler claims that the usage of the word \emph{refactoring} did not pass between
268 the \emph{Forth} and \emph{Smalltalk} communities, but that it emerged
269 independently in each of the communities.
271 \section{Motivation -- Why people refactor}
272 There are many reasons why people want to refactor their programs. They can for
273 instance do it to remove duplication, break up long methods or to introduce
274 design patterns into their software systems. The shared trait for all these are
275 that peoples' intentions are to make their programs \emph{better}, in some
276 sense. But what aspects of their programs are becoming improved?
278 As just mentioned, people often refactor to get rid of duplication. They are
279 moving identical or similar code into methods, and are pushing methods up or
280 down in their class hierarchies. They are making template methods for
281 overlapping algorithms/functionality, and so on. It is all about gathering what
282 belongs together and putting it all in one place. The resulting code is then
283 easier to maintain. When removing the implicit coupling\footnote{When
284 duplicating code, the duplicate pieces of code might not be coupled, apart
285 from representing the same functionality. So if this functionality is going to
286 change, it might need to change in more than one place, thus creating an
287 implicit coupling between multiple pieces of code.} between code snippets, the
288 location of a bug is limited to only one place, and new functionality need only
289 to be added to this one place, instead of a number of places people might not
292 A problem you often encounter when programming, is that a program contains a lot
293 of long and hard-to-grasp methods. It can then help to break the methods into
294 smaller ones, using the \ExtractMethod refactoring\citing{refactoring}. Then you
295 may discover something about a program that you were not aware of before;
296 revealing bugs you did not know about or could not find due to the complex
297 structure of your program. \todo{Proof?} Making the methods smaller and giving
298 good names to the new ones clarifies the algorithms and enhances the
299 \emph{understandability} of the program \see{magic_number_seven}. This makes
300 refactoring an excellent method for exploring unknown program code, or code that
301 you had forgotten that you wrote.
303 Most primitive refactorings are simple, and usually involves moving code
304 around\citing{kerievsky2005}. The motivation behind them may first be revealed
305 when they are combined into larger --- higher level --- refactorings, called
306 \emph{composite refactorings} \see{compositeRefactorings}. Often the goal of
307 such a series of refactorings is a design pattern. Thus the design can
308 \emph{evolve} throughout the lifetime of a program, as opposed to designing
309 up-front. It is all about being structured and taking small steps to improve a
312 Many software design pattern are aimed at lowering the coupling between
313 different classes and different layers of logic. One of the most famous is
314 perhaps the \emph{Model-View-Controller}\citing{designPatterns} pattern. It is
315 aimed at lowering the coupling between the user interface, the business logic
316 and the data representation of a program. This also has the added benefit that
317 the business logic could much easier be the target of automated tests, thus
318 increasing the productivity in the software development process.
320 Another effect of refactoring is that with the increased separation of concerns
321 coming out of many refactorings, the \emph{performance} can be improved. When
322 profiling programs, the problematic parts are narrowed down to smaller parts of
323 the code, which are easier to tune, and optimization can be performed only where
324 needed and in a more effective way\citing{refactoring}.
326 Last, but not least, and this should probably be the best reason to refactor, is
327 to refactor to \emph{facilitate a program change}. If one has managed to keep
328 one's code clean and tidy, and the code is not bloated with design patterns that
329 are not ever going to be needed, then some refactoring might be needed to
330 introduce a design pattern that is appropriate for the change that is going to
333 Refactoring program code --- with a goal in mind --- can give the code itself
334 more value. That is in the form of robustness to bugs, understandability and
335 maintainability. Having robust code is an obvious advantage, but
336 understandability and maintainability are both very important aspects of
337 software development. By incorporating refactoring in the development process,
338 bugs are found faster, new functionality is added more easily and code is easier
339 to understand by the next person exposed to it, which might as well be the
340 person who wrote it. The consequence of this, is that refactoring can increase
341 the average productivity of the development process, and thus also add to the
342 monetary value of a business in the long run. The perspective on productivity
343 and money should also be able to open the eyes of the many nearsighted managers
344 that seldom see beyond the next milestone.
346 \section{The magical number seven}\label{magic_number_seven}
347 The article \emph{The magical number seven, plus or minus two: some limits on
348 our capacity for processing information}\citing{miller1956} by George A.
349 Miller, was published in the journal \emph{Psychological Review} in 1956. It
350 presents evidence that support that the capacity of the number of objects a
351 human being can hold in its working memory is roughly seven, plus or minus two
352 objects. This number varies a bit depending on the nature and complexity of the
353 objects, but is according to Miller ``\ldots never changing so much as to be
356 Miller's article culminates in the section called \emph{Recoding}, a term he
357 borrows from communication theory. The central result in this section is that by
358 recoding information, the capacity of the amount of information that a human can
359 process at a time is increased. By \emph{recoding}, Miller means to group
360 objects together in chunks, and give each chunk a new name that it can be
364 \ldots recoding is an extremely powerful weapon for increasing the amount of
365 information that we can deal with.~\cite[p.~95]{miller1956}
368 By organizing objects into patterns of ever growing depth, one can memorize and
369 process a much larger amount of data than if it were to be represented as its
370 basic pieces. This grouping and renaming is analogous to how many refactorings
371 work, by grouping pieces of code and give them a new name. Examples are the
372 fundamental \ExtractMethod and \refactoring{Extract Class}
373 refactorings\citing{refactoring}.
375 An example from the article addresses the problem of memorizing a sequence of
376 binary digits. The example presented here is a slightly modified version of the
377 one presented in the original article\citing{miller1956}, but it preserves the
378 essence of it. Let us say we have the following sequence of
379 16 binary digits: ``1010001001110011''. Most of us will have a hard time
380 memorizing this sequence by only reading it once or twice. Imagine if we instead
381 translate it to this sequence: ``A273''. If you have a background from computer
382 science, it will be obvious that the latter sequence is the first sequence
383 recoded to be represented by digits in base 16. Most people should be able to
384 memorize this last sequence by only looking at it once.
386 Another result from the Miller article is that when the amount of information a
387 human must interpret increases, it is crucial that the translation from one code
388 to another must be almost automatic for the subject to be able to remember the
389 translation, before \heshe is presented with new information to recode. Thus
390 learning and understanding how to best organize certain kinds of data is
391 essential to efficiently handle that kind of data in the future. This is much
392 like when humans learn to read. First they must learn how to recognize letters.
393 Then they can learn distinct words, and later read sequences of words that form
394 whole sentences. Eventually, most of them will be able to read whole books and
395 briefly retell the important parts of its content. This suggest that the use of
396 design patterns is a good idea when reasoning about computer programs. With
397 extensive use of design patterns when creating complex program structures, one
398 does not always have to read whole classes of code to comprehend how they
399 function, it may be sufficient to only see the name of a class to almost fully
400 understand its responsibilities.
403 Our language is tremendously useful for repackaging material into a few chunks
404 rich in information.~\cite[p.~95]{miller1956}
407 Without further evidence, these results at least indicate that refactoring
408 source code into smaller units with higher cohesion and, when needed,
409 introducing appropriate design patterns, should aid in the cause of creating
410 computer programs that are easier to maintain and have code that is easier (and
413 \section{Notable contributions to the refactoring literature}
414 \todoin{Update with more contributions}
417 \item[1992] William F. Opdyke submits his doctoral dissertation called
418 \emph{Refactoring Object-Oriented Frameworks}\citing{opdyke1992}. This
419 work defines a set of refactorings, that are behavior preserving given that
420 their preconditions are met. The dissertation is focused on the automation
422 \item[1999] Martin Fowler et al.: \emph{Refactoring: Improving the Design of
423 Existing Code}\citing{refactoring}. This is maybe the most influential text
424 on refactoring. It bares similarities with Opdykes thesis\citing{opdyke1992}
425 in the way that it provides a catalog of refactorings. But Fowler's book is
426 more about the craft of refactoring, as he focuses on establishing a
427 vocabulary for refactoring, together with the mechanics of different
428 refactorings and when to perform them. His methodology is also founded on
429 the principles of test-driven development.
430 \item[2005] Joshua Kerievsky: \emph{Refactoring to
431 Patterns}\citing{kerievsky2005}. This book is heavily influenced by Fowler's
432 \emph{Refactoring}\citing{refactoring} and the ``Gang of Four'' \emph{Design
433 Patterns}\citing{designPatterns}. It is building on the refactoring
434 catalogue from Fowler's book, but is trying to bridge the gap between
435 \emph{refactoring} and \emph{design patterns} by providing a series of
436 higher-level composite refactorings, that makes code evolve toward or away
437 from certain design patterns. The book is trying to build up the readers
438 intuition around \emph{why} one would want to use a particular design
439 pattern, and not just \emph{how}. The book is encouraging evolutionary
440 design \see{relationToDesignPatterns}.
443 \section{Tool support (for Java)}\label{toolSupport}
444 This section will briefly compare the refactoring support of the three IDEs
445 \emph{Eclipse}\footnote{\url{http://www.eclipse.org/}}, \emph{IntelliJ
446 IDEA}\footnote{The IDE under comparison is the \emph{Community Edition},
447 \url{http://www.jetbrains.com/idea/}} and
448 \emph{NetBeans}\footnote{\url{https://netbeans.org/}}. These are the most
449 popular Java IDEs\citing{javaReport2011}.
451 All three IDEs provide support for the most useful refactorings, like the
452 different extract, move and rename refactorings. In fact, Java-targeted IDEs are
453 known for their good refactoring support, so this did not appear as a big
456 The IDEs seem to have excellent support for the \ExtractMethod refactoring, so
457 at least they have all passed the first ``refactoring
458 rubicon''\citing{fowlerRubicon2001,secondRubicon2012}.
460 Regarding the \MoveMethod refactoring, the \emph{Eclipse} and \emph{IntelliJ}
461 IDEs do the job in very similar manners. In most situations they both do a
462 satisfying job by producing the expected outcome. But they do nothing to check
463 that the result does not break the semantics of the program \see{correctness}.
464 The \emph{NetBeans} IDE implements this refactoring in a somewhat
465 unsophisticated way. For starters, the refactoring's default destination for the
466 move, is the same class as the method already resides in, although it refuses to
467 perform the refactoring if chosen. But the worst part is, that if moving the
468 method \method{f} of the class \type{C} to the class \type{X}, it will break the
469 code. The result is shown in \myref{lst:moveMethod_NetBeans}.
473 \begin{minted}[samepage]{java}
486 \begin{minted}[samepage]{java}
496 \caption{Moving method \method{f} from \type{C} to \type{X}.}
497 \label{lst:moveMethod_NetBeans}
500 NetBeans will try to create code that call the methods \method{m} and \method{n}
501 of \type{X} by accessing them through \var{c.x}, where \var{c} is a parameter of
502 type \type{C} that is added the method \method{f} when it is moved. (This is
503 seldom the desired outcome of this refactoring, but ironically, this ``feature''
504 keeps NetBeans from breaking the code in the example from \myref{correctness}.)
505 If \var{c.x} for some reason is inaccessible to \type{X}, as in this case, the
506 refactoring breaks the code, and it will not compile. NetBeans presents a
507 preview of the refactoring outcome, but the preview does not catch it if the IDE
508 is about break the program.
510 The IDEs under investigation seem to have fairly good support for primitive
511 refactorings, but what about more complex ones, such as \refactoring{Extract
512 Class}\citing{refactoring}? The \refactoring{Extract Class} refactoring works by
513 creating a class, for then to move members to that class and access them from
514 the old class via a reference to the new class. \emph{IntelliJ} handles this in
515 a fairly good manner, although, in the case of private methods, it leaves unused
516 methods behind. These are methods that delegate to a field with the type of the
517 new class, but are not used anywhere. \emph{Eclipse} has added its own quirk to
518 the Extract Class refactoring, and only allows for \emph{fields} to be moved to
519 a new class, \emph{not methods}. This makes it effectively only extracting a
520 data structure, and calling it \refactoring{Extract Class} is a little
521 misleading. One would often be better off with textual extract and paste than
522 using the Extract Class refactoring in Eclipse. When it comes to
523 \emph{NetBeans}, it does not even show an attempt on providing this refactoring.
525 \todoin{Visual Studio (C++/C\#), Smalltalk refactoring browser?,
526 second refactoring rubicon?}
528 \section{The relation to design patterns}\label{relationToDesignPatterns}
530 \emph{Refactoring} and \emph{design patterns} have at least one thing in common,
531 they are both promoted by advocates of \emph{clean code}\citing{cleanCode} as
532 fundamental tools on the road to more maintainable and extendable source code.
535 Design patterns help you determine how to reorganize a design, and they can
536 reduce the amount of refactoring you need to do
537 later.~\cite[p.~353]{designPatterns}
540 Although sometimes associated with
541 over-engineering\citing{kerievsky2005,refactoring}, design patterns are in
542 general assumed to be good for maintainability of source code. That may be
543 because many of them are designed to support the \emph{open/closed principle} of
544 object-oriented programming. The principle was first formulated by Bertrand
545 Meyer, the creator of the Eiffel programming language, like this: ``Modules
546 should be both open and closed.''\citing{meyer1988} It has been popularized,
547 with this as a common version:
550 Software entities (classes, modules, functions, etc.) should be open for
551 extension, but closed for modification.\footnote{See
552 \url{http://c2.com/cgi/wiki?OpenClosedPrinciple} or
553 \url{https://en.wikipedia.org/wiki/Open/closed_principle}}
556 Maintainability is often thought of as the ability to be able to introduce new
557 functionality without having to change too much of the old code. When
558 refactoring, the motivation is often to facilitate adding new functionality. It
559 is about factoring the old code in a way that makes the new functionality being
560 able to benefit from the functionality already residing in a software system,
561 without having to copy old code into new. Then, next time someone shall add new
562 functionality, it is less likely that the old code has to change. Assuming that
563 a design pattern is the best way to get rid of duplication and assist in
564 implementing new functionality, it is reasonable to conclude that a design
565 pattern often is the target of a series of refactorings. Having a repertoire of
566 design patterns can also help in knowing when and how to refactor a program to
567 make it reflect certain desired characteristics.
570 There is a natural relation between patterns and refactorings. Patterns are
571 where you want to be; refactorings are ways to get there from somewhere
572 else.~\cite[p.~107]{refactoring}
575 This quote is wise in many contexts, but it is not always appropriate to say
576 ``Patterns are where you want to be\ldots''. \emph{Sometimes}, patterns are
577 where you want to be, but only because it will benefit your design. It is not
578 true that one should always try to incorporate as many design patterns as
579 possible into a program. It is not like they have intrinsic value. They only add
580 value to a system when they support its design. Otherwise, the use of design
581 patterns may only lead to a program that is more complex than necessary.
584 The overuse of patterns tends to result from being patterns happy. We are
585 \emph{patterns happy} when we become so enamored of patterns that we simply
586 must use them in our code.~\cite[p.~24]{kerievsky2005}
589 This can easily happen when relying largely on up-front design. Then it is
590 natural, in the very beginning, to try to build in all the flexibility that one
591 believes will be necessary throughout the lifetime of a software system.
592 According to Joshua Kerievsky ``That sounds reasonable --- if you happen to be
593 psychic.''~\cite[p.~1]{kerievsky2005} He is advocating what he believes is a
594 better approach: To let software continually evolve. To start with a simple
595 design that meets today's needs, and tackle future needs by refactoring to
596 satisfy them. He believes that this is a more economic approach than investing
597 time and money into a design that inevitably is going to change. By relying on
598 continuously refactoring a system, its design can be made simpler without
599 sacrificing flexibility. To be able to fully rely on this approach, it is of
600 utter importance to have a reliable suit of tests to lean on \see{testing}. This
601 makes the design process more natural and less characterized by difficult
602 decisions that has to be made before proceeding in the process, and that is
603 going to define a project for all of its unforeseeable future.
607 \section{Classification of refactorings}
608 % only interesting refactorings
609 % with 2 detailed examples? One for structured and one for intra-method?
610 % Is replacing Bubblesort with Quick Sort considered a refactoring?
612 \subsection{Structural refactorings}
614 \subsubsection{Primitive refactorings}
617 \explanation{Extract Method}{You have a code fragment that can be grouped
618 together.}{Turn the fragment into a method whose name explains the purpose of
621 \explanation{Inline Method}{A method's body is just as clear as its name.}{Put
622 the method's body into the body of its callers and remove the method.}
624 \explanation{Inline Temp}{You have a temp that is assigned to once with a simple
625 expression, and the temp is getting in the way of other refactorings.}{Replace
626 all references to that temp with the expression}
628 % Moving Features Between Objects
629 \explanation{Move Method}{A method is, or will be, using or used by more
630 features of another class than the class on which it is defined.}{Create a new
631 method with a similar body in the class it uses most. Either turn the old method
632 into a simple delegation, or remove it altogether.}
634 \explanation{Move Field}{A field is, or will be, used by another class more than
635 the class on which it is defined}{Create a new field in the target class, and
636 change all its users.}
639 \explanation{Replace Magic Number with Symbolic Constant}{You have a literal
640 number with a particular meaning.}{Create a constant, name it after the meaning,
641 and replace the number with it.}
643 \explanation{Encapsulate Field}{There is a public field.}{Make it private and
646 \explanation{Replace Type Code with Class}{A class has a numeric type code that
647 does not affect its behavior.}{Replace the number with a new class.}
649 \explanation{Replace Type Code with Subclasses}{You have an immutable type code
650 that affects the behavior of a class.}{Replace the type code with subclasses.}
652 \explanation{Replace Type Code with State/Strategy}{You have a type code that
653 affects the behavior of a class, but you cannot use subclassing.}{Replace the
654 type code with a state object.}
656 % Simplifying Conditional Expressions
657 \explanation{Consolidate Duplicate Conditional Fragments}{The same fragment of
658 code is in all branches of a conditional expression.}{Move it outside of the
661 \explanation{Remove Control Flag}{You have a variable that is acting as a
662 control flag fro a series of boolean expressions.}{Use a break or return
665 \explanation{Replace Nested Conditional with Guard Clauses}{A method has
666 conditional behavior that does not make clear the normal path of
667 execution.}{Use guard clauses for all special cases.}
669 \explanation{Introduce Null Object}{You have repeated checks for a null
670 value.}{Replace the null value with a null object.}
672 \explanation{Introduce Assertion}{A section of code assumes something about the
673 state of the program.}{Make the assumption explicit with an assertion.}
675 % Making Method Calls Simpler
676 \explanation{Rename Method}{The name of a method does not reveal its
677 purpose.}{Change the name of the method}
679 \explanation{Add Parameter}{A method needs more information from its
680 caller.}{Add a parameter for an object that can pass on this information.}
682 \explanation{Remove Parameter}{A parameter is no longer used by the method
685 %\explanation{Parameterize Method}{Several methods do similar things but with
686 %different values contained in the method.}{Create one method that uses a
687 %parameter for the different values.}
689 \explanation{Preserve Whole Object}{You are getting several values from an
690 object and passing these values as parameters in a method call.}{Send the whole
693 \explanation{Remove Setting Method}{A field should be set at creation time and
694 never altered.}{Remove any setting method for that field.}
696 \explanation{Hide Method}{A method is not used by any other class.}{Make the
699 \explanation{Replace Constructor with Factory Method}{You want to do more than
700 simple construction when you create an object}{Replace the constructor with a
703 % Dealing with Generalization
704 \explanation{Pull Up Field}{Two subclasses have the same field.}{Move the field
707 \explanation{Pull Up Method}{You have methods with identical results on
708 subclasses.}{Move them to the superclass.}
710 \explanation{Push Down Method}{Behavior on a superclass is relevant only for
711 some of its subclasses.}{Move it to those subclasses.}
713 \explanation{Push Down Field}{A field is used only by some subclasses.}{Move the
714 field to those subclasses}
716 \explanation{Extract Interface}{Several clients use the same subset of a class's
717 interface, or two classes have part of their interfaces in common.}{Extract the
718 subset into an interface.}
720 \explanation{Replace Inheritance with Delegation}{A subclass uses only part of a
721 superclasses interface or does not want to inherit data.}{Create a field for the
722 superclass, adjust methods to delegate to the superclass, and remove the
725 \explanation{Replace Delegation with Inheritance}{You're using delegation and
726 are often writing many simple delegations for the entire interface}{Make the
727 delegating class a subclass of the delegate.}
729 \subsubsection{Composite refactorings}
732 % \explanation{Replace Method with Method Object}{}{}
734 % Moving Features Between Objects
735 \explanation{Extract Class}{You have one class doing work that should be done by
736 two}{Create a new class and move the relevant fields and methods from the old
737 class into the new class.}
739 \explanation{Inline Class}{A class isn't doing very much.}{Move all its features
740 into another class and delete it.}
742 \explanation{Hide Delegate}{A client is calling a delegate class of an
743 object.}{Create Methods on the server to hide the delegate.}
745 \explanation{Remove Middle Man}{A class is doing to much simple delegation.}{Get
746 the client to call the delegate directly.}
749 \explanation{Replace Data Value with Object}{You have a data item that needs
750 additional data or behavior.}{Turn the data item into an object.}
752 \explanation{Change Value to Reference}{You have a class with many equal
753 instances that you want to replace with a single object.}{Turn the object into a
756 \explanation{Encapsulate Collection}{A method returns a collection}{Make it
757 return a read-only view and provide add/remove methods.}
759 % \explanation{Replace Array with Object}{}{}
761 \explanation{Replace Subclass with Fields}{You have subclasses that vary only in
762 methods that return constant data.}{Change the methods to superclass fields and
763 eliminate the subclasses.}
765 % Simplifying Conditional Expressions
766 \explanation{Decompose Conditional}{You have a complicated conditional
767 (if-then-else) statement.}{Extract methods from the condition, then part, an
770 \explanation{Consolidate Conditional Expression}{You have a sequence of
771 conditional tests with the same result.}{Combine them into a single conditional
772 expression and extract it.}
774 \explanation{Replace Conditional with Polymorphism}{You have a conditional that
775 chooses different behavior depending on the type of an object.}{Move each leg
776 of the conditional to an overriding method in a subclass. Make the original
779 % Making Method Calls Simpler
780 \explanation{Replace Parameter with Method}{An object invokes a method, then
781 passes the result as a parameter for a method. The receiver can also invoke this
782 method.}{Remove the parameter and let the receiver invoke the method.}
784 \explanation{Introduce Parameter Object}{You have a group of parameters that
785 naturally go together.}{Replace them with an object.}
787 % Dealing with Generalization
788 \explanation{Extract Subclass}{A class has features that are used only in some
789 instances.}{Create a subclass for that subset of features.}
791 \explanation{Extract Superclass}{You have two classes with similar
792 features.}{Create a superclass and move the common features to the
795 \explanation{Collapse Hierarchy}{A superclass and subclass are not very
796 different.}{Merge them together.}
798 \explanation{Form Template Method}{You have two methods in subclasses that
799 perform similar steps in the same order, yet the steps are different.}{Get the
800 steps into methods with the same signature, so that the original methods become
801 the same. Then you can pull them up.}
804 \subsection{Functional refactorings}
806 \explanation{Substitute Algorithm}{You want to replace an algorithm with one
807 that is clearer.}{Replace the body of the method with the new algorithm.}
811 \section{The impact on software quality}
813 \subsection{What is software quality?}
814 The term \emph{software quality} has many meanings. It all depends on the
815 context we put it in. If we look at it with the eyes of a software developer, it
816 usually means that the software is easily maintainable and testable, or in other
817 words, that it is \emph{well designed}. This often correlates with the
818 management scale, where \emph{keeping the schedule} and \emph{customer
819 satisfaction} is at the center. From the customers point of view, in addition to
820 good usability, \emph{performance} and \emph{lack of bugs} is always
821 appreciated, measurements that are also shared by the software developer. (In
822 addition, such things as good documentation could be measured, but this is out
823 of the scope of this document.)
825 \subsection{The impact on performance}
827 Refactoring certainly will make software go more slowly\footnote{With todays
828 compiler optimization techniques and performance tuning of e.g. the Java
829 virtual machine, the penalties of object creation and method calls are
830 debatable.}, but it also makes the software more amenable to performance
831 tuning.~\cite[p.~69]{refactoring}
834 \noindent There is a common belief that refactoring compromises performance, due
835 to increased degree of indirection and that polymorphism is slower than
838 In a survey, Demeyer\citing{demeyer2002} disproves this view in the case of
839 polymorphism. He did an experiment on, what he calls, ``Transform Self Type
840 Checks'' where you introduce a new polymorphic method and a new class hierarchy
841 to get rid of a class' type checking of a ``type attribute``. He uses this kind
842 of transformation to represent other ways of replacing conditionals with
843 polymorphism as well. The experiment is performed on the C++ programming
844 language and with three different compilers and platforms. Demeyer concludes
845 that, with compiler optimization turned on, polymorphism beats middle to large
846 sized if-statements and does as well as case-statements. (In accordance with
847 his hypothesis, due to similarities between the way C++ handles polymorphism and
851 The interesting thing about performance is that if you analyze most programs,
852 you find that they waste most of their time in a small fraction of the
853 code.~\cite[p.~70]{refactoring}
856 \noindent So, although an increased amount of method calls could potentially
857 slow down programs, one should avoid premature optimization and sacrificing good
858 design, leaving the performance tuning until after profiling\todo{glossary}
859 the software and having isolated the actual problem areas.
861 \section{Composite refactorings}\label{compositeRefactorings}
862 \todo{motivation, examples, manual vs automated?, what about refactoring in a
863 very large code base?}
864 Generally, when thinking about refactoring, at the mechanical level, there are
865 essentially two kinds of refactorings. There are the \emph{primitive}
866 refactorings, and the \emph{composite} refactorings.
868 \definition{A \emph{primitive refactoring} is a refactoring that cannot be
869 expressed in terms of other refactorings.}
871 \noindent Examples are the \refactoring{Pull Up Field} and \refactoring{Pull Up
872 Method} refactorings\citing{refactoring}, that move members up in their class
875 \definition{A \emph{composite refactoring} is a refactoring that can be
876 expressed in terms of two or more other refactorings.}
878 \noindent An example of a composite refactoring is the \refactoring{Extract
879 Superclass} refactoring\citing{refactoring}. In its simplest form, it is composed
880 of the previously described primitive refactorings, in addition to the
881 \refactoring{Pull Up Constructor Body} refactoring\citing{refactoring}. It works
882 by creating an abstract superclass that the target class(es) inherits from, then
883 by applying \refactoring{Pull Up Field}, \refactoring{Pull Up Method} and
884 \refactoring{Pull Up Constructor Body} on the members that are to be members of
885 the new superclass. If there are multiple classes in play, their interfaces may
886 need to be united with the help of some rename refactorings, before extracting
887 the superclass. For an overview of the \refactoring{Extract Superclass}
888 refactoring, see \myref{fig:extractSuperclass}.
892 \includegraphics[angle=270,width=\linewidth]{extractSuperclassItalic.pdf}
893 \caption{The Extract Superclass refactoring, with united interfaces.}
894 \label{fig:extractSuperclass}
897 \section{Manual vs. automated refactorings}
898 Refactoring is something every programmer does, even if \heshe does not known
899 the term \emph{refactoring}. Every refinement of source code that does not alter
900 the program's behavior is a refactoring. For small refactorings, such as
901 \ExtractMethod, executing it manually is a manageable task, but is still prone
902 to errors. Getting it right the first time is not easy, considering the method
903 signature and all the other aspects of the refactoring that has to be in place.
905 Consider the renaming of classes, methods and fields. For complex programs these
906 refactorings are almost impossible to get right. Attacking them with textual
907 search and replace, or even regular expressions, will fall short on these tasks.
908 Then it is crucial to have proper tool support that can perform them
909 automatically. Tools that can parse source code and thus have semantic knowledge
910 about which occurrences of which names belong to what construct in the program.
911 For even trying to perform one of these complex task manually, one would have to
912 be very confident on the existing test suite \see{testing}.
914 \section{Correctness of refactorings}\label{correctness}
915 For automated refactorings to be truly useful, they must show a high degree of
916 behavior preservation. This last sentence might seem obvious, but there are
917 examples of refactorings in existing tools that break programs. In an ideal
918 world, every automated refactoring would be ``complete'', in the sense that it
919 would never break a program. In an ideal world, every program would also be free
920 from bugs. In modern IDEs the implemented automated refactorings are working for
921 \emph{most} cases, that is enough for making them useful.
923 I will now present an example of a \emph{corner case} where a program breaks
924 when a refactoring is applied. The example shows an \ExtractMethod refactoring
925 followed by a \MoveMethod refactoring that breaks a program in both the
926 \emph{Eclipse} and \emph{IntelliJ} IDEs\footnote{The NetBeans IDE handles this
927 particular situation without altering the program's behavior, mainly because
928 its Move Method refactoring implementation is a bit flawed in other ways
929 \see{toolSupport}.}. The target and the destination for the composed
930 refactoring is shown in \myref{lst:correctnessExtractAndMove}. Note that the
931 method \method{m(C c)} of class \type{X} assigns to the field \var{x} of the
932 argument \var{c} that has type \type{C}.
936 \begin{minted}[linenos]{java}
937 // Refactoring target
939 public X x = new X();
951 \begin{minted}[]{java}
952 // Method destination
956 // If m is called from
957 // c, then c.x no longer
964 \caption{The target and the destination for the composition of the Extract
965 Method and Move Method refactorings.}
966 \label{lst:correctnessExtractAndMove}
970 The refactoring sequence works by extracting line 6 through 8 from the original
971 class \type{C} into a method \method{f} with the statements from those lines as
972 its method body (but with the comment left out, since it will no longer hold any
973 meaning). The method is then moved to the class \type{X}. The result is shown
974 in \myref{lst:correctnessExtractAndMoveResult}.
976 Before the refactoring, the methods \method{m} and \method{n} of class \type{X}
977 are called on different object instances (see line 6 and 8 of the original class
978 \type{C} in \cref{lst:correctnessExtractAndMove}). After the refactoring, they
979 are called on the same object, and the statement on line
980 3 of class \type{X} (in \cref{lst:correctnessExtractAndMoveResult}) no longer
981 has the desired effect in our example. The method \method{f} of class \type{C}
982 is now calling the method \method{f} of class \type{X} (see line 5 of class
983 \type{C} in \cref{lst:correctnessExtractAndMoveResult}), and the program now
984 behaves different than before.
988 \begin{minted}[linenos]{java}
990 public X x = new X();
1000 \begin{minted}[linenos]{java}
1002 public void m(C c) {
1008 public void f(C c) {
1015 \caption{The result of the composed refactoring.}
1016 \label{lst:correctnessExtractAndMoveResult}
1019 The bug introduced in the previous example is of such a nature\footnote{Caused
1020 by aliasing. See \url{https://en.wikipedia.org/wiki/Aliasing_(computing)}}
1021 that it is very difficult to spot if the refactored code is not covered by
1022 tests. It does not generate compilation errors, and will thus only result in
1023 a runtime error or corrupted data, which might be hard to detect.
1025 \section{Refactoring and the importance of testing}\label{testing}
1027 If you want to refactor, the essential precondition is having solid
1028 tests.\citing{refactoring}
1031 When refactoring, there are roughly three classes of errors that can be made.
1032 The first class of errors are the ones that make the code unable to compile.
1033 These \emph{compile-time} errors are of the nicer kind. They flash up at the
1034 moment they are made (at least when using an IDE), and are usually easy to fix.
1035 The second class are the \emph{runtime} errors. Although they take a bit longer
1036 to surface, they usually manifest after some time in an illegal argument
1037 exception, null pointer exception or similar during the program execution.
1038 These kind of errors are a bit harder to handle, but at least they will show,
1039 eventually. Then there are the \emph{behavior-changing} errors. These errors are
1040 of the worst kind. They do not show up during compilation and they do not turn
1041 on a blinking red light during runtime either. The program can seem to work
1042 perfectly fine with them in play, but the business logic can be damaged in ways
1043 that will only show up over time.
1045 For discovering runtime errors and behavior changes when refactoring, it is
1046 essential to have good test coverage. Testing in this context means writing
1047 automated tests. Manual testing may have its uses, but when refactoring, it is
1048 automated unit testing that dominate. For discovering behavior changes it is
1049 especially important to have tests that cover potential problems, since these
1050 kind of errors does not reveal themselves.
1052 Unit testing is not a way to \emph{prove} that a program is correct, but it is a
1053 way to make you confident that it \emph{probably} works as desired. In the
1054 context of test driven development (commonly known as TDD), the tests are even a
1055 way to define how the program is \emph{supposed} to work. It is then, by
1056 definition, working if the tests are passing.
1058 If the test coverage for a code base is perfect, then it should, theoretically,
1059 be risk-free to perform refactorings on it. This is why automated tests and
1060 refactoring are such a great match.
1062 \subsection{Testing the code from correctness section}
1063 The worst thing that can happen when refactoring is to introduce changes to the
1064 behavior of a program, as in the example on \myref{correctness}. This example
1065 may be trivial, but the essence is clear. The only problem with the example is
1066 that it is not clear how to create automated tests for it, without changing it
1069 Unit tests, as they are known from the different xUnit frameworks around, are
1070 only suitable to test the \emph{result} of isolated operations. They can not
1071 easily (if at all) observe the \emph{history} of a program.
1073 This problem is still open.
1078 Assuming a sequential (non-concurrent) program:
1080 \begin{minted}{java}
1081 tracematch (C c, X x) {
1083 call(* X.m(C)) && args(c) && cflow(within(C));
1085 call(* X.n()) && target(x) && cflow(within(C));
1087 set(C.x) && target(c) && !cflow(m);
1091 { assert x == c.x; }
1095 %\begin{minted}{java}
1096 %tracematch (X x1, X x2) {
1098 % call(* X.m(C)) && target(x1);
1100 % call(* X.n()) && target(x2);
1102 % set(C.x) && !cflow(m) && !cflow(n);
1106 % { assert x1 != x2; }
1111 \section{The project}
1112 The aim of this master project will be to investigate the relationship between a
1113 composite refactoring composed of the \ExtractMethod and \MoveMethod
1114 refactorings, and its impact on one or more software metrics.
1116 The composition of the \ExtractMethod and \MoveMethod refactorings springs
1117 naturally out of the need to move procedures closer to the data they manipulate.
1118 This composed refactoring is not well described in the literature, but it is
1119 implemented in at least one tool called
1120 \emph{CodeRush}\footnote{\url{https://help.devexpress.com/\#CodeRush/CustomDocument3519}},
1121 that is an extension for \emph{MS Visual
1122 Studio}\footnote{\url{http://www.visualstudio.com/}}. In CodeRush it is called
1123 \emph{Extract Method to
1124 Type}\footnote{\url{https://help.devexpress.com/\#CodeRush/CustomDocument6710}},
1125 but I choose to call it \ExtractAndMoveMethod, since I feel it better
1126 communicates which primitive refactorings it is composed of.
1128 For the metrics, I will at least measure the \emph{Coupling between object
1129 classes} (CBO) metric that is described by Chidamber and Kemerer in their
1130 article \emph{A Metrics Suite for Object Oriented
1131 Design}\citing{metricsSuite1994}.
1133 The project will then consist in implementing the \ExtractAndMoveMethod
1134 refactoring, as well as executing it over a larger code base. Then the effect of
1135 the change must be measured by calculating the chosen software metrics both
1136 before and after the execution. To be able to execute the refactoring
1137 automatically I have to make it analyze code to determine the best selections to
1138 extract into new methods.
1142 %\chapter{Planning the project}
1150 \chapter{The Project}
1152 \section{The problem statement}
1155 \section{Choosing the target language}
1156 Choosing which programming language the code that shall be manipulated shall be
1157 written in, is not a very difficult task. We choose to limit the possible
1158 languages to the object-oriented programming languages, since most of the
1159 terminology and literature regarding refactoring comes from the world of
1160 object-oriented programming. In addition, the language must have existing tool
1161 support for refactoring.
1163 The \emph{Java} programming language\footnote{\url{https://www.java.com/}} is
1164 the dominating language when it comes to example code in the literature of
1165 refactoring, and is thus a natural choice. Java is perhaps, currently the most
1166 influential programming language in the world, with its \emph{Java Virtual
1167 Machine} that runs on all of the most popular architectures and also supports
1168 dozens of other programming languages\footnote{They compile to java bytecode.},
1169 with \emph{Scala}, \emph{Clojure} and \emph{Groovy} as the most prominent ones.
1170 Java is currently the language that every other programming language is compared
1171 against. It is also the primary programming language for the author of this
1174 \section{Choosing the tools}
1175 When choosing a tool for manipulating Java, there are certain criteria that
1176 have to be met. First of all, the tool should have some existing refactoring
1177 support that this thesis can build upon. Secondly it should provide some kind of
1178 framework for parsing and analyzing Java source code. Third, it should itself be
1179 open source. This is both because of the need to be able to browse the code for
1180 the existing refactorings that is contained in the tool, and also because open
1181 source projects hold value in them selves. Another important aspect to consider
1182 is that open source projects of a certain size, usually has large communities of
1183 people connected to them, that are committed to answering questions regarding the
1184 use and misuse of the products, that to a large degree is made by the community
1187 There is a certain class of tools that meet these criteria, namely the class of
1188 \emph{IDEs}\footnote{\emph{Integrated Development Environment}}. These are
1189 programs that is meant to support the whole production cycle of a computer
1190 program, and the most popular IDEs that support Java, generally have quite good
1191 refactoring support.
1193 The main contenders for this thesis is the \emph{Eclipse IDE}, with the
1194 \emph{Java development tools} (JDT), the \emph{IntelliJ IDEA Community Edition}
1195 and the \emph{NetBeans IDE} \see{toolSupport}. Eclipse and NetBeans are both
1196 free, open source and community driven, while the IntelliJ IDEA has an open
1197 sourced community edition that is free of charge, but also offer an
1198 \emph{Ultimate Edition} with an extended set of features, at additional cost.
1199 All three IDEs supports adding plugins to extend their functionality and tools
1200 that can be used to parse and analyze Java source code. But one of the IDEs
1201 stand out as a favorite, and that is the \emph{Eclipse IDE}. This is the most
1202 popular\citing{javaReport2011} among them and seems to be de facto standard IDE
1203 for Java development regardless of platform.
1205 \section{Organizing the project}
1206 All the parts of this master project is under version control with
1207 \emph{Git}\footnote{\url{http://git-scm.com/}}.
1209 The software written is organized as some Eclipse plugins. Writing a plugin is
1210 the natural way to utilize the API of Eclipse. This also makes it possible to
1211 provide a user interface to manually run operations on selections in program
1212 source code or whole projects/packages.
1214 When writing a plugin in Eclipse, one has access to resources such as the
1215 current workspace, the open editor and the current selection.
1217 \section{Continuous integration}
1218 The continuous integration server
1219 \emph{Jenkins}\footnote{\url{http://jenkins-ci.org/}} has been set up for the
1220 project\footnote{A work mostly done by the supervisor.}. It is used as a way to
1221 run tests and perform code coverage analysis.
1223 To be able to build the Eclipse plugins and run tests for them with Jenkins, the
1224 component assembly project
1225 \emph{Buckminster}\footnote{\url{http://www.eclipse.org/buckminster/}} is used,
1226 through its plugin for Jenkins. Buckminster provides for a way to specify the
1227 resources needed for building a project and where and how to find them.
1228 Buckminster also handles the setup of a target environment to run the tests in.
1229 All this is needed because the code to build depends on an Eclipse installation
1230 with various plugins.
1232 \subsection{Problems with AspectJ}
1233 The Buckminster build worked fine until introducing AspectJ into the project.
1234 When building projects using AspectJ, there are some additional steps that needs
1235 to be performed. First of all, the aspects themselves must be compiled. Then the
1236 aspects needs to be woven with the classes they affect. This demands a process
1237 that does multiple passes over the source code.
1239 When using AspectJ with Eclipse, the specialized compilation and the weaving can
1240 be handled by the \emph{AspectJ Development
1241 Tools}\footnote{\url{https://www.eclipse.org/ajdt/}}. This works all fine, but
1242 it complicates things when trying to build a project depending on Eclipse
1243 plugins outside of Eclipse. There is supposed to be a way to specify a compiler
1244 adapter for javac, together with the file extensions for the file types it shall
1245 operate. The AspectJ compiler adapter is called
1246 \typewithref{org.aspectj.tools.ant.taskdefs}{Ajc11CompilerAdapter}, and it works
1247 with files that has the extensions \code{*.java} and \code{*.aj}. I tried to
1248 setup this in the build properties file for the project containing the aspects,
1249 but to no avail. The project containing the aspects does not seem to be built at
1250 all, and the projects that depends on it complains that they cannot find certain
1253 I then managed to write an \emph{Ant}\footnote{\url{https://ant.apache.org/}}
1254 build file that utilizes the AspectJ compiler adapter, for the
1255 \code{no.uio.ifi.refaktor} plugin. The problem was then that it could no longer
1256 take advantage of the environment set up by Buckminster. The solution to this
1257 particular problem was of a ``hacky'' nature. It involves exporting the plugin
1258 dependencies for the project to an Ant build file, and copy the exported path
1259 into the existing build script. But then the Ant script needs to know where the
1260 local Eclipse installation is located. This is no problem when building on a
1261 local machine, but to utilize the setup done by Buckminster is a problem still
1262 unsolved. To get the classpath for the build setup correctly, and here comes the
1263 most ``hacky'' part of the solution, the Ant script has a target for copying the
1264 classpath elements into a directory relative to the project directory and
1265 checking it into Git. When no \code{ECLIPSE\_HOME} property is set while running
1266 Ant, the script uses the copied plugins instead of the ones provided by the
1267 Eclipse installation when building the project. This obviously creates some
1268 problems with maintaining the list of dependencies in the Ant file, as well as
1269 remembering to copy the plugins every time the list of dependencies change.
1271 The Ant script described above is run by Jenkins before the Buckminster setup
1272 and build. When setup like this, the Buckminster build succeeds for the projects
1273 not using AspectJ, and the tests are run as normal. This is all good, but it
1274 feels a little scary, since the reason for Buckminster not working with AspectJ
1277 The problems with building with AspectJ on the Jenkins server lasted for a
1278 while, before they were solved. This is reflected in the ``Test Result Trend''
1279 and ``Code Coverage Trend'' reported by Jenkins.
1282 \chapter{Refactorings in Eclipse JDT: Design, Shortcomings and Wishful
1283 Thinking}\label{ch:jdt_refactorings}
1285 This chapter will deal with some of the design behind refactoring support in
1286 Eclipse, and the JDT in specific. After which it will follow a section about
1287 shortcomings of the refactoring API in terms of composition of refactorings. The
1288 chapter will be concluded with a section telling some of the ways the
1289 implementation of refactorings in the JDT could have worked to facilitate
1290 composition of refactorings.
1293 The refactoring world of Eclipse can in general be separated into two parts: The
1294 language independent part and the part written for a specific programming
1295 language -- the language that is the target of the supported refactorings.
1296 \todo{What about the language specific part?}
1298 \subsection{The Language Toolkit}
1299 The Language Toolkit\footnote{The content of this section is a mixture of
1300 written material from
1301 \url{https://www.eclipse.org/articles/Article-LTK/ltk.html} and
1302 \url{http://www.eclipse.org/articles/article.php?file=Article-Unleashing-the-Power-of-Refactoring/index.html},
1303 the LTK source code and my own memory.}, or LTK for short, is the framework that
1304 is used to implement refactorings in Eclipse. It is language independent and
1305 provides the abstractions of a refactoring and the change it generates, in the
1306 form of the classes \typewithref{org.eclipse.ltk.core.refactoring}{Refactoring}
1307 and \typewithref{org.eclipse.ltk.core.refactoring}{Change}.
1309 There are also parts of the LTK that is concerned with user interaction, but
1310 they will not be discussed here, since they are of little value to us and our
1311 use of the framework. We are primarily interested in the parts that can be
1314 \subsubsection{The Refactoring Class}
1315 The abstract class \type{Refactoring} is the core of the LTK framework. Every
1316 refactoring that is going to be supported by the LTK have to end up creating an
1317 instance of one of its subclasses. The main responsibilities of subclasses of
1318 \type{Refactoring} is to implement template methods for condition checking
1319 (\methodwithref{org.eclipse.ltk.core.refactoring.Refactoring}{checkInitialConditions}
1321 \methodwithref{org.eclipse.ltk.core.refactoring.Refactoring}{checkFinalConditions}),
1323 \methodwithref{org.eclipse.ltk.core.refactoring.Refactoring}{createChange}
1324 method that creates and returns an instance of the \type{Change} class.
1326 If the refactoring shall support that others participate in it when it is
1327 executed, the refactoring has to be a processor-based
1328 refactoring\typeref{org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring}.
1329 It then delegates to its given
1330 \typewithref{org.eclipse.ltk.core.refactoring.participants}{RefactoringProcessor}
1331 for condition checking and change creation. Participating in a refactoring can
1332 be useful in cases where the changes done to programming source code affects
1333 other related resources in the workspace. This can be names or paths in
1334 configuration files, or maybe one would like to perform additional logging of
1335 changes done in the workspace.
1337 \subsubsection{The Change Class}
1338 This class is the base class for objects that is responsible for performing the
1339 actual workspace transformations in a refactoring. The main responsibilities for
1340 its subclasses is to implement the
1341 \methodwithref{org.eclipse.ltk.core.refactoring.Change}{perform} and
1342 \methodwithref{org.eclipse.ltk.core.refactoring.Change}{isValid} methods. The
1343 \method{isValid} method verifies that the change object is valid and thus can be
1344 executed by calling its \method{perform} method. The \method{perform} method
1345 performs the desired change and returns an undo change that can be executed to
1346 reverse the effect of the transformation done by its originating change object.
1348 \subsubsection{Executing a Refactoring}\label{executing_refactoring}
1349 The life cycle of a refactoring generally follows two steps after creation:
1350 condition checking and change creation. By letting the refactoring object be
1352 \typewithref{org.eclipse.ltk.core.refactoring}{CheckConditionsOperation} that
1353 in turn is handled by a
1354 \typewithref{org.eclipse.ltk.core.refactoring}{CreateChangeOperation}, it is
1355 assured that the change creation process is managed in a proper manner.
1357 The actual execution of a change object has to follow a detailed life cycle.
1358 This life cycle is honored if the \type{CreateChangeOperation} is handled by a
1359 \typewithref{org.eclipse.ltk.core.refactoring}{PerformChangeOperation}. If also
1360 an undo manager\typeref{org.eclipse.ltk.core.refactoring.IUndoManager} is set
1361 for the \type{PerformChangeOperation}, the undo change is added into the undo
1364 \section{Shortcomings}
1365 This section is introduced naturally with a conclusion: The JDT refactoring
1366 implementation does not facilitate composition of refactorings.
1367 \todo{refine}This section will try to explain why, and also identify other
1368 shortcomings of both the usability and the readability of the JDT refactoring
1371 I will begin at the end and work my way toward the composition part of this
1374 \subsection{Absence of Generics in Eclipse Source Code}
1375 This section is not only concerning the JDT refactoring API, but also large
1376 quantities of the Eclipse source code. The code shows a striking absence of the
1377 Java language feature of generics. It is hard to read a class' interface when
1378 methods return objects or takes parameters of raw types such as \type{List} or
1379 \type{Map}. This sometimes results in having to read a lot of source code to
1380 understand what is going on, instead of relying on the available interfaces. In
1381 addition, it results in a lot of ugly code, making the use of typecasting more
1382 of a rule than an exception.
1384 \subsection{Composite Refactorings Will Not Appear as Atomic Actions}
1386 \subsubsection{Missing Flexibility from JDT Refactorings}
1387 The JDT refactorings are not made with composition of refactorings in mind. When
1388 a JDT refactoring is executed, it assumes that all conditions for it to be
1389 applied successfully can be found by reading source files that have been
1390 persisted to disk. They can only operate on the actual source material, and not
1391 (in-memory) copies thereof. This constitutes a major disadvantage when trying to
1392 compose refactorings, since if an exception occurs in the middle of a sequence
1393 of refactorings, it can leave the project in a state where the composite
1394 refactoring was only partially executed. It makes it hard to discard the changes
1395 done without monitoring and consulting the undo manager, an approach that is not
1398 \subsubsection{Broken Undo History}
1399 When designing a composed refactoring that is to be performed as a sequence of
1400 refactorings, you would like it to appear as a single change to the workspace.
1401 This implies that you would also like to be able to undo all the changes done by
1402 the refactoring in a single step. This is not the way it appears when a sequence
1403 of JDT refactorings is executed. It leaves the undo history filled up with
1404 individual undo actions corresponding to every single JDT refactoring in the
1405 sequence. This problem is not trivial to handle in Eclipse
1406 \see{hacking_undo_history}.
1408 \section{Wishful Thinking}
1411 \chapter{Composite Refactorings in Eclipse}
1413 \section{A Simple Ad Hoc Model}
1414 As pointed out in \myref{ch:jdt_refactorings}, the Eclipse JDT refactoring model
1415 is not very well suited for making composite refactorings. Therefore a simple
1416 model using changer objects (of type \type{RefaktorChanger}) is used as an
1417 abstraction layer on top of the existing Eclipse refactorings, instead of
1418 extending the \typewithref{org.eclipse.ltk.core.refactoring}{Refactoring} class.
1420 The use of an additional abstraction layer is a deliberate choice. It is due to
1421 the problem of creating a composite
1422 \typewithref{org.eclipse.ltk.core.refactoring}{Change} that can handle text
1423 changes that interfere with each other. Thus, a \type{RefaktorChanger} may, or
1424 may not, take advantage of one or more existing refactorings, but it is always
1425 intended to make a change to the workspace.
1427 \subsection{A typical \type{RefaktorChanger}}
1428 The typical refaktor changer class has two responsibilities, checking
1429 preconditions and executing the requested changes. This is not too different
1430 from the responsibilities of an LTK refactoring, with the distinction that a
1431 refaktor changer also executes the change, while an LTK refactoring is only
1432 responsible for creating the object that can later be used to do the job.
1434 Checking of preconditions is typically done by an
1435 \typewithref{no.uio.ifi.refaktor.analyze.analyzers}{Analyzer}. If the
1436 preconditions validate, the upcoming changes are executed by an
1437 \typewithref{no.uio.ifi.refaktor.change.executors}{Executor}.
1439 \section{The Extract and Move Method Refactoring}
1440 %The Extract and Move Method Refactoring is implemented mainly using these
1443 % \item \type{ExtractAndMoveMethodChanger}
1444 % \item \type{ExtractAndMoveMethodPrefixesExtractor}
1445 % \item \type{Prefix}
1446 % \item \type{PrefixSet}
1449 \subsection{The Building Blocks}
1450 This is a composite refactoring, and hence is built up using several primitive
1451 refactorings. These basic building blocks are, as its name implies, the
1452 \ExtractMethod refactoring\citing{refactoring} and the \MoveMethod
1453 refactoring\citing{refactoring}. In Eclipse, the implementations of these
1454 refactorings are found in the classes
1455 \typewithref{org.eclipse.jdt.internal.corext.refactoring.code}{ExtractMethodRefactoring}
1457 \typewithref{org.eclipse.jdt.internal.corext.refactoring.structure}{MoveInstanceMethodProcessor},
1458 where the last class is designed to be used together with the processor-based
1459 \typewithref{org.eclipse.ltk.core.refactoring.participants}{MoveRefactoring}.
1461 \subsubsection{The ExtractMethodRefactoring Class}
1462 This class is quite simple in its use. The only parameters it requires for
1463 construction is a compilation
1464 unit\typeref{org.eclipse.jdt.core.ICompilationUnit}, the offset into the source
1465 code where the extraction shall start, and the length of the source to be
1466 extracted. Then you have to set the method name for the new method together with
1467 its visibility and some not so interesting parameters.
1469 \subsubsection{The MoveInstanceMethodProcessor Class}
1470 For the Move Method, the processor requires a little more advanced input than
1471 the class for the Extract Method. For construction it requires a method
1472 handle\typeref{org.eclipse.jdt.core.IMethod} for the method that is to be moved.
1473 Then the target for the move have to be supplied as the variable binding from a
1474 chosen variable declaration. In addition to this, one have to set some
1475 parameters regarding setters/getters, as well as delegation.
1477 To make a working refactoring from the processor, one have to create a
1478 \type{MoveRefactoring} with it.
1480 \subsection{The ExtractAndMoveMethodChanger}
1482 The \typewithref{no.uio.ifi.refaktor.changers}{ExtractAndMoveMethodChanger}
1483 class is a subclass of the class
1484 \typewithref{no.uio.ifi.refaktor.changers}{RefaktorChanger}. It is responsible
1485 for analyzing and finding the best target for, and also executing, a composition
1486 of the Extract Method and Move Method refactorings. This particular changer is
1487 the one of my changers that is closest to being a true LTK refactoring. It can
1488 be reworked to be one if the problems with overlapping changes are resolved. The
1489 changer requires a text selection and the name of the new method, or else a
1490 method name will be generated. The selection has to be of the type
1491 \typewithref{no.uio.ifi.refaktor.utils}{CompilationUnitTextSelection}. This
1492 class is a custom extension to
1493 \typewithref{org.eclipse.jface.text}{TextSelection}, that in addition to the
1494 basic offset, length and similar methods, also carry an instance of the
1495 underlying compilation unit handle for the selection.
1498 \type{ExtractAndMoveMethodAnalyzer}}\label{extractAndMoveMethodAnalyzer}
1499 The analysis and precondition checking is done by the
1500 \typewithref{no.uio.ifi.refaktor.analyze.analyzers}{ExtractAnd\-MoveMethodAnalyzer}.
1501 First is check whether the selection is a valid selection or not, with respect
1502 to statement boundaries and that it actually contains any selections. Then it
1503 checks the legality of both extracting the selection and also moving it to
1504 another class. This checking of is performed by a range of checkers
1505 \see{checkers}. If the selection is approved as legal, it is analyzed to find
1506 the presumably best target to move the extracted method to.
1508 For finding the best suitable target the analyzer is using a
1509 \typewithref{no.uio.ifi.refaktor.analyze.collectors}{PrefixesCollector} that
1510 collects all the possible candidate targets for the refactoring. All the
1511 non-candidates is found by an
1512 \typewithref{no.uio.ifi.refaktor.analyze.collectors}{UnfixesCollector} that
1513 collects all the targets that will give some kind of error if used. (For
1514 details about the property collectors, see \myref{propertyCollectors}.) All
1515 prefixes (and unfixes) are represented by a
1516 \typewithref{no.uio.ifi.refaktor.extractors}{Prefix}, and they are collected
1517 into sets of prefixes. The safe prefixes is found by subtracting from the set of
1518 candidate prefixes the prefixes that is enclosing any of the unfixes. A prefix
1519 is enclosing an unfix if the unfix is in the set of its sub-prefixes. As an
1520 example, \texttt{``a.b''} is enclosing \texttt{``a''}, as is \texttt{``a''}. The
1521 safe prefixes is unified in a \type{PrefixSet}. If a prefix has only one
1522 occurrence, and is a simple expression, it is considered unsuitable as a move
1523 target. This occurs in statements such as \texttt{``a.foo()''}. For such
1524 statements it bares no meaning to extract and move them. It only generates an
1525 extra method and the calling of it.
1527 The most suitable target for the refactoring is found by finding the prefix with
1528 the most occurrences. If two prefixes have the same occurrence count, but they
1529 differ in length, the longest of them is chosen.
1531 \todoin{Clean up sections/subsections.}
1534 \type{ExtractAndMoveMethodExecutor}}\label{extractAndMoveMethodExecutor}
1535 If the analysis finds a possible target for the composite refactoring, it is
1537 \typewithref{no.uio.ifi.refaktor.change.executors}{ExtractAndMoveMethodExecutor}.
1538 It is composed of the two executors known as
1539 \typewithref{no.uio.ifi.refaktor.change.executors}{ExtractMethodRefactoringExecutor}
1541 \typewithref{no.uio.ifi.refaktor.change.executors}{MoveMethodRefactoringExecutor}.
1542 The \type{ExtractAndMoveMethodExecutor} is responsible for gluing the two
1543 together by feeding the \type{MoveMethod\-RefactoringExecutor} with the
1544 resources needed after executing the extract method refactoring
1545 \see{postExtractExecution}.
1547 \subsubsection{The \type{ExtractMethodRefactoringExecutor}}
1548 This executor is responsible for creating and executing an instance of the
1549 \type{ExtractMethodRefactoring} class. It is also responsible for collecting
1550 some post execution resources that can be used to find the method handle for the
1551 extracted method, as well as information about its parameters, including the
1552 variable they originated from.
1554 \subsubsection{The \type{MoveMethodRefactoringExecutor}}
1555 This executor is responsible for creating and executing an instance of the
1556 \type{MoveRefactoring}. The move refactoring is a processor-based refactoring,
1557 and for the Move Method refactoring it is the \type{MoveInstanceMethodProcessor}
1560 The handle for the method to be moved is found on the basis of the information
1561 gathered after the execution of the Extract Method refactoring. The only
1562 information the \type{ExtractMethodRefactoring} is sharing after its execution,
1563 regarding find the method handle, is the textual representation of the new
1564 method signature. Therefore it must be parsed, the strings for types of the
1565 parameters must be found and translated to a form that can be used to look up
1566 the method handle from its type handle. They have to be on the unresolved
1567 form.\todo{Elaborate?} The name for the type is found from the original
1568 selection, since an extracted method must end up in the same type as the
1571 When analyzing a selection prior to performing the Extract Method refactoring, a
1572 target is chosen. It has to be a variable binding, so it is either a field or a
1573 local variable/parameter. If the target is a field, it can be used with the
1574 \type{MoveInstanceMethodProcessor} as it is, since the extracted method still is
1575 in its scope. But if the target is local to the originating method, the target
1576 that is to be used for the processor must be among its parameters. Thus the
1577 target must be found among the extracted method's parameters. This is done by
1578 finding the parameter information object that corresponds to the parameter that
1579 was declared on basis of the original target's variable when the method was
1580 extracted. (The extracted method must take one such parameter for each local
1581 variable that is declared outside the selection that is extracted.) To match the
1582 original target with the correct parameter information object, the key for the
1583 information object is compared to the key from the original target's binding.
1584 The source code must then be parsed to find the method declaration for the
1585 extracted method. The new target must be found by searching through the
1586 parameters of the declaration and choose the one that has the same type as the
1587 old binding from the parameter information object, as well as the same name that
1588 is provided by the parameter information object.
1592 SearchBasedExtractAndMoveMethodChanger}\label{searchBasedExtractAndMoveMethodChanger}
1594 \typewithref{no.uio.ifi.refaktor.change.changers}{SearchBasedExtractAndMoveMethodChanger}
1595 is a changer whose purpose is to automatically analyze a method, and execute the
1596 \ExtractAndMoveMethod refactoring on it if it is a suitable candidate for the
1599 First, the \typewithref{no.uio.ifi.refaktor.analyze.analyzers}{SearchBasedExtractAndMoveMethodAnalyzer} is used
1600 to analyze the method. If the method is found to be a candidate, the result from
1601 the analysis is fed to the \type{ExtractAndMoveMethodExecutor}, whose job is to
1602 execute the refactoring \see{extractAndMoveMethodExecutor}.
1604 \subsubsection{The SearchBasedExtractAndMoveMethodAnalyzer}
1605 This analyzer is responsible for analyzing all the possible text selections of a
1606 method and then choose the best result out of the analysis results that is, by
1607 the analyzer, considered to be the potential candidates for the Extract and Move
1610 Before the analyzer is able to work with the text selections of a method, it
1611 needs to generate them. To do this, it parses the method to obtain a
1612 \type{MethodDeclaration} for it \see{astEclipse}. Then there is a statement
1613 lists creator that creates statements lists of the different groups of
1614 statements in the body of the method declaration. A text selections generator
1615 generates text selections of all the statement lists for the analyzer to work
1618 \paragraph{The statement lists creator}
1619 is responsible for generating lists of statements for all the possible levels of
1620 statements in the method. The statement lists creator is implemented as an AST
1621 visitor \see{astVisitor}. It generates lists of statements by visiting all the
1622 blocks in the method declaration and stores their statements in a collection of
1623 statement lists. In addition, it visits all of the other statements that can
1624 have a statement as a child, such as the different control structures and the
1627 The switch statement is the only kind of statement that is not straight forward
1628 to obtain the child statements from. It stores all of its children in a flat
1629 list. Its switch case statements are included in this list. This means that
1630 there are potential statement lists between all of these case statements. The
1631 list of statements from a switch statement is therefore traversed, and the
1632 statements between the case statements are grouped as separate lists.
1634 There is an example of how the statement lists creator would generate lists for
1635 a simple method in \myref{lst:statementListsExample}.
1638 \def\charwidth{5.7pt}
1639 \def\indent{4*\charwidth}
1640 \def\lineheight{\baselineskip}
1641 \def\mintedtop{\lineheight}
1643 \begin{tikzpicture}[overlay, yscale=-1]
1644 \tikzstyle{overlaybox}=[fill=lightgray,opacity=0.2]
1645 \draw[overlaybox] (0,\mintedtop+\lineheight) rectangle
1646 +(22*\charwidth,10*\lineheight);
1647 \draw[overlaybox] (\indent,\mintedtop+2*\lineheight) rectangle
1648 +(13*\charwidth,\lineheight);
1649 \draw[overlaybox] (2*\indent,\mintedtop+6*\lineheight) rectangle
1650 +(13*\charwidth,2*\lineheight);
1651 \draw[overlaybox] (2*\indent,\mintedtop+9*\lineheight) rectangle
1652 +(13*\charwidth,\lineheight);
1654 \begin{minted}{java}
1668 \caption{Example of how the statement lists creator would group a simple method
1669 into lists of statements. Each highlighted rectangle represents a list.}
1670 \label{lst:statementListsExample}
1673 \paragraph{The text selections generator} generates text selections for each
1674 list of statements from the statement lists creator. Conceptually, the generator
1675 generates a text selection for every possible ordered \todo{make clearer}
1676 combination of statements in a list. For a list of statements, the boundary
1677 statements span out a text selection. This means that there are many different
1678 lists that could span out the same selection.
1680 In practice, the text selections are calculated by only one traversal of the
1681 statement list. There is a set of generated text selections. For each statement,
1682 there is created a temporary set of selections, in addition to a text selection
1683 based on the offset and length of the statement. This text selection is added to
1684 the temporary set. Then the new selection is added with every selection from the
1685 set of generated text selections. These new selections are added to the
1686 temporary set. Then the temporary set of selections is added to the set of
1687 generated text selections. The result of adding two text selections is a new
1688 text selection spanned out by the two addends.
1690 \paragraph{Finding the candidate} for the refactoring is done by analyzing all
1691 the generated text selection with the \type{ExtractAndMoveMethodAnalyzer}
1692 \see{extractAndMoveMethodAnalyzer}. If the analyzer generates a useful result,
1693 an \type{ExtractAndMoveMethodCandidate} is created from it, that is kept in a
1694 list of potential candidates. If no candidates are found, the
1695 \type{NoTargetFoundException} is thrown.
1697 Since only one of the candidates can be chosen, the analyzer must sort out which
1698 candidate to choose. The sorting is done by the static \method{sort} method of
1699 \type{Collections}. The comparison in this sorting is done by an
1700 \type{ExtractAndMoveMethodCandidateComparator}.
1701 \todoin{Write about the
1702 ExtractAndMoveMethodCandidateComparator/FavorNoUnfixesCandidateComparator}
1704 \paragraph{The complexity} of how many text selections that needs to be analyzed
1705 for a total of $n$ statements is bounded by $O(n^2)$.
1708 The number of text selections that need to be analyzed for each list of
1709 statements of length $n$, is exactly
1712 \sum_{i=1}^{n} i = \frac{n(n+1)}{2}
1713 \label{eq:complexityStatementList}
1715 \label{thm:numberOfTextSelection}
1719 For $n=1$ this is trivial: $\frac{1(1+1)}{2} = \frac{2}{2} = 1$. One statement
1720 equals one selection.
1722 For $n=2$, you get one text selection for the first statement. For the second,
1723 you get one selection for the statement itself, and one selection for the two
1724 of them combined. This equals three selections. $\frac{2(2+1)}{2} =
1727 For $n=3$, you get 3 selections for the two first statements, as in the case
1728 where $n=2$. In addition you get one selection for the third statement itself,
1729 and two more statements for the combinations of it with the two previous
1730 statements. This equals six selections. $\frac{3(3+1)}{2} = \frac{12}{2} = 6$.
1732 Assume that for $n=k$ there exists $\frac{k(k+1)}{2}$ text selections. Then we
1733 want to add selections for another statement, following the previous $k$
1734 statements. So, for $n=k+1$, we get one additional selection for the statement
1735 itself. Then we get one selection for each pair of the new selection and the
1736 previous $k$ statements. So the total number of selections will be the number
1737 of already generated selections, plus $k$ for every pair, plus one for the
1738 statement itself: $\frac{k(k+1)}{2} + k +
1739 1 = \frac{k(k+1)+2k+2}{2} = \frac{k(k+1)+2(k+1)}{2} = \frac{(k+1)(k+2)}{2} =
1740 \frac{(k+1)((k+1)+1)}{2} = \sum_{i=1}^{k+1} i$
1744 The number of text selections for a body of statements is maximized if all the
1745 statements are at the same level.
1746 \label{thm:textSelectionsMaximized}
1750 Assume we have a body of, in total, $k$ statements. Let
1751 $l,\cdots,m,(k-l-\cdots-m)$ be the lengths of the lists of statements in the
1752 body, with $l+\cdots+m<k \Rightarrow l,\cdots,m<k$.
1754 Then, the number of text selections that are generated for the $k$ statements
1760 \frac{(k-l-\cdots-m)((k-l-\cdots-m)+ 1)}{2} + \frac{l(l+1)}{2} + \cdots +
1761 \frac{m(m+1)}{2} = \\
1762 \frac{k^2 - 2kl - \cdots - 2km + l^2 + \cdots + m^2 + k - l - \cdots - m}{2}
1763 + \frac{l^2+l}{2} + \cdots + \frac{m^2+m}{2} = \\
1764 \frac{k^2 + k + 2l^2 - 2kl + \cdots + 2m^2 - 2km}{2}
1768 It then remains to show that this inequality holds:
1771 \frac{k^2 + k + 2l^2 - 2kl + \cdots + 2m^2 - 2km}{2} < \frac{k(k+1)}{2} =
1775 By multiplication by $2$ on both sides, and by removing the equal parts, we get
1778 2l^2 - 2kl + \cdots + 2m^2 - 2km < 0
1781 Since $l,\cdots,m<k$, we have that $\forall i \in \{l,\cdots,m\} : 2ki > 2i^2$,
1782 so all the pairs of parts on the form $2i^2-2ki$ are negative. In sum, the
1787 Therefore, the complexity for the number of selections that needs to be analyzed
1788 for a body of $n$ statements is $O\bigl(\frac{n(n+1)}{2}\bigr) = O(n^2)$.
1791 \subsection{Finding the IMethod}\label{postExtractExecution}
1792 \todoin{Rename section. Write??}
1795 \subsection{The Prefix Class}
1796 This class exists mainly for holding data about a prefix, such as the expression
1797 that the prefix represents and the occurrence count of the prefix within a
1798 selection. In addition to this, it has some functionality such as calculating
1799 its sub-prefixes and intersecting it with another prefix. The definition of the
1800 intersection between two prefixes is a prefix representing the longest common
1801 expression between the two.
1803 \subsection{The PrefixSet Class}
1804 A prefix set holds elements of type \type{Prefix}. It is implemented with the
1805 help of a \typewithref{java.util}{HashMap} and contains some typical set
1806 operations, but it does not implement the \typewithref{java.util}{Set}
1807 interface, since the prefix set does not need all of the functionality a
1808 \type{Set} requires to be implemented. In addition It needs some other
1809 functionality not found in the \type{Set} interface. So due to the relatively
1810 limited use of prefix sets, and that it almost always needs to be referenced as
1811 such, and not a \type{Set<Prefix>}, it remains as an ad hoc solution to a
1814 There are two ways adding prefixes to a \type{PrefixSet}. The first is through
1815 its \method{add} method. This works like one would expect from a set. It adds
1816 the prefix to the set if it does not already contain the prefix. The other way
1817 is to \emph{register} the prefix with the set. When registering a prefix, if the
1818 set does not contain the prefix, it is just added. If the set contains the
1819 prefix, its count gets incremented. This is how the occurrence count is handled.
1821 The prefix set also computes the set of prefixes that is not enclosing any
1822 prefixes of another set. This is kind of a set difference operation only for
1825 \subsection{Hacking the Refactoring Undo
1826 History}\label{hacking_undo_history}
1827 \todoin{Where to put this section?}
1829 As an attempt to make multiple subsequent changes to the workspace appear as a
1830 single action (i.e. make the undo changes appear as such), I tried to alter
1831 the undo changes\typeref{org.eclipse.ltk.core.refactoring.Change} in the history
1832 of the refactorings.
1834 My first impulse was to remove the, in this case, last two undo changes from the
1835 undo manager\typeref{org.eclipse.ltk.core.refactoring.IUndoManager} for the
1836 Eclipse refactorings, and then add them to a composite
1837 change\typeref{org.eclipse.ltk.core.refactoring.CompositeChange} that could be
1838 added back to the manager. The interface of the undo manager does not offer a
1839 way to remove/pop the last added undo change, so a possible solution could be to
1840 decorate\citing{designPatterns} the undo manager, to intercept and collect the
1841 undo changes before delegating to the \method{addUndo}
1842 method\methodref{org.eclipse.ltk.core.refactoring.IUndoManager}{addUndo} of the
1843 manager. Instead of giving it the intended undo change, a null change could be
1844 given to prevent it from making any changes if run. Then one could let the
1845 collected undo changes form a composite change to be added to the manager.
1847 There is a technical challenge with this approach, and it relates to the undo
1848 manager, and the concrete implementation
1849 UndoManager2\typeref{org.eclipse.ltk.internal.core.refactoring.UndoManager2}.
1850 This implementation is designed in a way that it is not possible to just add an
1851 undo change, you have to do it in the context of an active
1852 operation\typeref{org.eclipse.core.commands.operations.TriggeredOperations}.
1853 One could imagine that it might be possible to trick the undo manager into
1854 believing that you are doing a real change, by executing a refactoring that is
1855 returning a kind of null change that is returning our composite change of undo
1856 refactorings when it is performed.
1858 Apart from the technical problems with this solution, there is a functional
1859 problem: If it all had worked out as planned, this would leave the undo history
1860 in a dirty state, with multiple empty undo operations corresponding to each of
1861 the sequentially executed refactoring operations, followed by a composite undo
1862 change corresponding to an empty change of the workspace for rounding of our
1863 composite refactoring. The solution to this particular problem could be to
1864 intercept the registration of the intermediate changes in the undo manager, and
1865 only register the last empty change.
1867 Unfortunately, not everything works as desired with this solution. The grouping
1868 of the undo changes into the composite change does not make the undo operation
1869 appear as an atomic operation. The undo operation is still split up into
1870 separate undo actions, corresponding to the change done by its originating
1871 refactoring. And in addition, the undo actions has to be performed separate in
1872 all the editors involved. This makes it no solution at all, but a step toward
1875 There might be a solution to this problem, but it remains to be found. The
1876 design of the refactoring undo management is partly to be blamed for this, as it
1877 it is to complex to be easily manipulated.
1882 \chapter{Analyzing Source Code in Eclipse}
1884 \section{The Java model}\label{javaModel}
1885 The Java model of Eclipse is its internal representation of a Java project. It
1886 is light-weight, and has only limited possibilities for manipulating source
1887 code. It is typically used as a basis for the Package Explorer in Eclipse.
1889 The elements of the Java model is only handles to the underlying elements. This
1890 means that the underlying element of a handle does not need to actually exist.
1891 Hence the user of a handle must always check that it exist by calling the
1892 \method{exists} method of the handle.
1894 The handles with descriptions is listed in \myref{tab:javaModel}.
1899 \newcolumntype{L}[1]{>{\hsize=#1\hsize\raggedright\arraybackslash}X}%
1900 % sum must equal number of columns (3)
1901 \begin{tabularx}{\textwidth}{| L{0.7} | L{1.1} | L{1.2} |}
1903 \textbf{Project Element} & \textbf{Java Model element} &
1904 \textbf{Description} \\
1906 Java project & \type{IJavaProject} & The Java project which contains all other objects. \\
1908 Source folder /\linebreak[2] binary folder /\linebreak[3] external library &
1909 \type{IPackageFragmentRoot} & Hold source or binary files, can be a folder
1910 or a library (zip / jar file). \\
1912 Each package & \type{IPackageFragment} & Each package is below the
1913 \type{IPackageFragmentRoot}, sub-packages are not leaves of the package,
1914 they are listed directed under \type{IPackageFragmentRoot}. \\
1916 Java Source file & \type{ICompilationUnit} & The Source file is always below
1917 the package node. \\
1919 Types /\linebreak[2] Fields /\linebreak[3] Methods & \type{IType} /
1921 \type{IField} /\linebreak[3] \type{IMethod} & Types, fields and methods. \\
1924 \caption{The elements of the Java Model. {\footnotesize Taken from
1925 \url{http://www.vogella.com/tutorials/EclipseJDT/article.html}}}
1926 \label{tab:javaModel}
1929 The hierarchy of the Java Model is shown in \myref{fig:javaModel}.
1933 \begin{tikzpicture}[%
1934 grow via three points={one child at (0,-0.7) and
1935 two children at (0,-0.7) and (0,-1.4)},
1936 edge from parent path={(\tikzparentnode.south west)+(0.5,0) |-
1937 (\tikzchildnode.west)}]
1938 \tikzstyle{every node}=[draw=black,thick,anchor=west]
1939 \tikzstyle{selected}=[draw=red,fill=red!30]
1940 \tikzstyle{optional}=[dashed,fill=gray!50]
1941 \node {\type{IJavaProject}}
1942 child { node {\type{IPackageFragmentRoot}}
1943 child { node {\type{IPackageFragment}}
1944 child { node {\type{ICompilationUnit}}
1945 child { node {\type{IType}}
1946 child { node {\type{\{ IType \}*}}
1947 child { node {\type{\ldots}}}
1950 child { node {\type{\{ IField \}*}}}
1951 child { node {\type{IMethod}}
1952 child { node {\type{\{ IType \}*}}
1953 child { node {\type{\ldots}}}
1958 child { node {\type{\{ IMethod \}*}}}
1967 child { node {\type{\{ IType \}*}}}
1978 child { node {\type{\{ ICompilationUnit \}*}}}
1991 child { node {\type{\{ IPackageFragment \}*}}}
2006 child { node {\type{\{ IPackageFragmentRoot \}*}}}
2009 \caption{The Java model of Eclipse. ``\type{\{ SomeElement \}*}'' means
2010 \type{SomeElement} zero or more times. For recursive structures,
2011 ``\type{\ldots}'' is used.}
2012 \label{fig:javaModel}
2015 \section{The Abstract Syntax Tree}
2016 Eclipse is following the common paradigm of using an abstract syntax tree for
2017 source code analysis and manipulation.
2019 When parsing program source code into something that can be used as a foundation
2020 for analysis, the start of the process follows the same steps as in a compiler.
2021 This is all natural, because the way a compiler analyzes code is no different
2022 from how source manipulation programs would do it, except for some properties of
2023 code that is analyzed in the parser, and that they may be differing in what
2024 kinds of properties they analyze. Thus the process of translation source code
2025 into a structure that is suitable for analyzing, can be seen as a kind of
2026 interrupted compilation process \see{fig:interruptedCompilationProcess}.
2031 base/.style={anchor=north, align=center, rectangle, minimum height=1.4cm},
2032 basewithshadow/.style={base, drop shadow, fill=white},
2033 outlined/.style={basewithshadow, draw, rounded corners, minimum
2035 primary/.style={outlined, font=\bfseries},
2036 dashedbox/.style={outlined, dashed},
2037 arrowpath/.style={black, align=center, font=\small},
2038 processarrow/.style={arrowpath, ->, >=angle 90, shorten >=1pt},
2040 \begin{tikzpicture}[node distance=1.3cm and 3cm, scale=1, every
2041 node/.style={transform shape}]
2042 \node[base](AuxNode1){\small source code};
2043 \node[primary, right=of AuxNode1, xshift=-2.5cm](Scanner){Scanner};
2044 \node[primary, right=of Scanner, xshift=0.5cm](Parser){Parser};
2045 \node[dashedbox, below=of Parser](SemanticAnalyzer){Semantic\\Analyzer};
2046 \node[dashedbox, left=of SemanticAnalyzer](SourceCodeOptimizer){Source
2048 \node[dashedbox, below=of SourceCodeOptimizer
2049 ](CodeGenerator){Code\\Generator};
2050 \node[dashedbox, right=of CodeGenerator](TargetCodeOptimizer){Target
2052 \node[base, right=of TargetCodeOptimizer](AuxNode2){};
2054 \draw[processarrow](AuxNode1) -- (Scanner);
2056 \path[arrowpath] (Scanner) -- node [sloped](tokens){tokens}(Parser);
2057 \draw[processarrow](Scanner) -- (tokens) -- (Parser);
2059 \path[arrowpath] (Parser) -- node (syntax){syntax
2060 tree}(SemanticAnalyzer);
2061 \draw[processarrow](Parser) -- (syntax) -- (SemanticAnalyzer);
2063 \path[arrowpath] (SemanticAnalyzer) -- node
2064 [sloped](annotated){annotated\\tree}(SourceCodeOptimizer);
2065 \draw[processarrow, dashed](SemanticAnalyzer) -- (annotated) --
2066 (SourceCodeOptimizer);
2068 \path[arrowpath] (SourceCodeOptimizer) -- node
2069 (intermediate){intermediate code}(CodeGenerator);
2070 \draw[processarrow, dashed](SourceCodeOptimizer) -- (intermediate) --
2073 \path[arrowpath] (CodeGenerator) -- node [sloped](target1){target
2074 code}(TargetCodeOptimizer);
2075 \draw[processarrow, dashed](CodeGenerator) -- (target1) --
2076 (TargetCodeOptimizer);
2078 \path[arrowpath](TargetCodeOptimizer) -- node [sloped](target2){target
2080 \draw[processarrow, dashed](TargetCodeOptimizer) -- (target2) (AuxNode2);
2082 \caption{Interrupted compilation process. {\footnotesize (Full compilation
2083 process borrowed from \emph{Compiler construction: principles and practice}
2084 by Kenneth C. Louden\citing{louden1997}.)}}
2085 \label{fig:interruptedCompilationProcess}
2088 The process starts with a \emph{scanner}, or lexer. The job of the scanner is to
2089 read the source code and divide it into tokens for the parser. Therefore, it is
2090 also sometimes called a tokenizer. A token is a logical unit, defined in the
2091 language specification, consisting of one or more consecutive characters. In
2092 the Java language the tokens can for instance be the \var{this} keyword, a curly
2093 bracket \var{\{} or a \var{nameToken}. It is recognized by the scanner on the
2094 basis of something equivalent of a regular expression. This part of the process
2095 is often implemented with the use of a finite automata. In fact, it is common to
2096 specify the tokens in regular expressions, that in turn is translated into a
2097 finite automata lexer. This process can be automated.
2099 The program component used to translate a stream of tokens into something
2100 meaningful, is called a parser. A parser is fed tokens from the scanner and
2101 performs an analysis of the structure of a program. It verifies that the syntax
2102 is correct according to the grammar rules of a language, that is usually
2103 specified in a context-free grammar, and often in a variant of the
2105 Form}\footnote{\url{https://en.wikipedia.org/wiki/Backus-Naur\_Form}}. The
2106 result coming from the parser is in the form of an \emph{Abstract Syntax Tree},
2107 AST for short. It is called \emph{abstract}, because the structure does not
2108 contain all of the tokens produced by the scanner. It only contain logical
2109 constructs, and because it forms a tree, all kinds of parentheses and brackets
2110 are implicit in the structure. It is this AST that is used when performing the
2111 semantic analysis of the code.
2113 As an example we can think of the expression \code{(5 + 7) * 2}. The root of
2114 this tree would in Eclipse be an \type{InfixExpression} with the operator
2115 \var{TIMES}, and a left operand that is also an \type{InfixExpression} with the
2116 operator \var{PLUS}. The left operand \type{InfixExpression}, has in turn a left
2117 operand of type \type{NumberLiteral} with the value \var{``5''} and a right
2118 operand \type{NumberLiteral} with the value \var{``7''}. The root will have a
2119 right operand of type \type{NumberLiteral} and value \var{``2''}. The AST for
2120 this expression is illustrated in \myref{fig:astInfixExpression}.
2122 Contrary to the Java Model, an abstract syntax tree is a heavy-weight
2123 representation of source code. It contains information about properties like
2124 type bindings for variables and variable bindings for names.
2129 \begin{tikzpicture}[scale=0.8]
2130 \tikzset{level distance=40pt}
2131 \tikzset{sibling distance=5pt}
2132 \tikzstyle{thescale}=[scale=0.8]
2133 \tikzset{every tree node/.style={align=center}}
2134 \tikzset{edge from parent/.append style={thick}}
2135 \tikzstyle{inode}=[rectangle,rounded corners,draw,fill=lightgray,drop
2136 shadow,align=center]
2137 \tikzset{every internal node/.style={inode}}
2138 \tikzset{every leaf node/.style={draw=none,fill=none}}
2140 \Tree [.\type{InfixExpression} [.\type{InfixExpression}
2141 [.\type{NumberLiteral} \var{``5''} ] [.\type{Operator} \var{PLUS} ]
2142 [.\type{NumberLiteral} \var{``7''} ] ]
2143 [.\type{Operator} \var{TIMES} ]
2144 [.\type{NumberLiteral} \var{``2''} ]
2147 \caption{The abstract syntax tree for the expression \code{(5 + 7) * 2}.}
2148 \label{fig:astInfixExpression}
2151 \subsection{The AST in Eclipse}\label{astEclipse}
2152 In Eclipse, every node in the AST is a child of the abstract superclass
2153 \typewithref{org.eclipse.jdt.core.dom}{ASTNode}. Every \type{ASTNode}, among a
2154 lot of other things, provides information about its position and length in the
2155 source code, as well as a reference to its parent and to the root of the tree.
2157 The root of the AST is always of type \type{CompilationUnit}. It is not the same
2158 as an instance of an \type{ICompilationUnit}, which is the compilation unit
2159 handle of the Java model. The children of a \type{CompilationUnit} is an
2160 optional \type{PackageDeclaration}, zero or more nodes of type
2161 \type{ImportDecaration} and all its top-level type declarations that has node
2162 types \type{AbstractTypeDeclaration}.
2164 An \type{AbstractType\-Declaration} can be one of the types
2165 \type{AnnotationType\-Declaration}, \type{Enum\-Declaration} or
2166 \type{Type\-Declaration}. The children of an \type{AbstractType\-Declaration}
2167 must be a subtype of a \type{BodyDeclaration}. These subtypes are:
2168 \type{AnnotationTypeMember\-Declaration}, \type{EnumConstant\-Declaration},
2169 \type{Field\-Declaration}, \type{Initializer} and \type{Method\-Declaration}.
2171 Of the body declarations, the \type{Method\-Declaration} is the most interesting
2172 one. Its children include lists of modifiers, type parameters, parameters and
2173 exceptions. It has a return type node and a body node. The body, if present, is
2174 of type \type{Block}. A \type{Block} is itself a \type{Statement}, and its
2175 children is a list of \type{Statement} nodes.
2177 There are too many types of the abstract type \type{Statement} to list up, but
2178 there exists a subtype of \type{Statement} for every statement type of Java, as
2179 one would expect. This also applies to the abstract type \type{Expression}.
2180 However, the expression \type{Name} is a little special, since it is both used
2181 as an operand in compound expressions, as well as for names in type declarations
2184 There is an overview of some of the structure of an Eclipse AST in
2185 \myref{fig:astEclipse}.
2189 \begin{tikzpicture}[scale=0.8]
2190 \tikzset{level distance=50pt}
2191 \tikzset{sibling distance=5pt}
2192 \tikzstyle{thescale}=[scale=0.8]
2193 \tikzset{every tree node/.style={align=center}}
2194 \tikzset{edge from parent/.append style={thick}}
2195 \tikzstyle{inode}=[rectangle,rounded corners,draw,fill=lightgray,drop
2196 shadow,align=center]
2197 \tikzset{every internal node/.style={inode}}
2198 \tikzset{every leaf node/.style={draw=none,fill=none}}
2200 \Tree [.\type{CompilationUnit} [.\type{[ PackageDeclaration ]} [.\type{Name} ]
2201 [.\type{\{ Annotation \}*} ] ]
2202 [.\type{\{ ImportDeclaration \}*} [.\type{Name} ] ]
2203 [.\type{\{ AbstractTypeDeclaration \}+} [.\node(site){\type{\{
2204 BodyDeclaration \}*}}; ] [.\type{SimpleName} ] ]
2206 \begin{scope}[shift={(0.5,-6)}]
2207 \node[inode,thescale](root){\type{MethodDeclaration}};
2208 \node[inode,thescale](modifiers) at (4.5,-5){\type{\{ IExtendedModifier \}*}
2209 \\ {\footnotesize (Of type \type{Modifier} or \type{Annotation})}};
2210 \node[inode,thescale](typeParameters) at (-6,-3.5){\type{\{ TypeParameter
2212 \node[inode,thescale](parameters) at (-5,-5){\type{\{
2213 SingleVariableDeclaration \}*} \\ {\footnotesize (Parameters)}};
2214 \node[inode,thescale](exceptions) at (5,-3){\type{\{ Name \}*} \\
2215 {\footnotesize (Exceptions)}};
2216 \node[inode,thescale](return) at (-6.5,-2){\type{Type} \\ {\footnotesize
2218 \begin{scope}[shift={(0,-5)}]
2219 \Tree [.\node(body){\type{[ Block ]} \\ {\footnotesize (Body)}};
2220 [.\type{\{ Statement \}*} [.\type{\{ Expression \}*} ]
2221 [.\type{\{ Statement \}*} [.\type{\ldots} ]]
2226 \draw[->,>=triangle 90,shorten >=1pt](root.east)..controls +(east:2) and
2227 +(south:1)..(site.south);
2229 \draw (root.south) -- (modifiers);
2230 \draw (root.south) -- (typeParameters);
2231 \draw (root.south) -- ($ (parameters.north) + (2,0) $);
2232 \draw (root.south) -- (exceptions);
2233 \draw (root.south) -- (return);
2234 \draw (root.south) -- (body);
2237 \caption{The format of the abstract syntax tree in Eclipse.}
2238 \label{fig:astEclipse}
2240 \todoin{Add more to the AST format tree? \myref{fig:astEclipse}}
2242 \section{The ASTVisitor}\label{astVisitor}
2243 So far, the only thing that has been addressed is how the data that is going to
2244 be the basis for our analysis is structured. Another aspect of it is how we are
2245 going to traverse the AST to gather the information we need, so we can conclude
2246 about the properties we are analysing. It is of course possible to start at the
2247 top of the tree, and manually search through its nodes for the ones we are
2248 looking for, but that is a bit inconvenient. To be able to efficiently utilize
2249 such an approach, we would need to make our own framework for traversing the
2250 tree and visiting only the types of nodes we are after. Luckily, this
2251 functionality is already provided in Eclipse, by its
2252 \typewithref{org.eclipse.jdt.core.dom}{ASTVisitor}.
2254 The Eclipse AST, together with its \type{ASTVisitor}, follows the \emph{Visitor}
2255 pattern\citing{designPatterns}. The intent of this design pattern is to
2256 facilitate extending the functionality of classes without touching the classes
2259 Let us say that there is a class hierarchy of \emph{Elements}. These elements
2260 all have a method \method{accept(Visitor visitor)}. In its simplest form, the
2261 \method{accept} method just calls the \method{visit} method of the visitor with
2262 itself as an argument, like this: \code{visitor.visit(this)}. For the visitors
2263 to be able to extend the functionality of all the classes in the elements
2264 hierarchy, each \type{Visitor} must have one visit method for each concrete
2265 class in the hierarchy. Say the hierarchy consists of the concrete classes
2266 \type{ConcreteElementA} and \type{ConcreteElementB}. Then each visitor must have
2267 the (possibly empty) methods \method{visit(ConcreteElementA element)} and
2268 \method{visit(ConcreteElementB element)}. This scenario is depicted in
2269 \myref{fig:visitorPattern}.
2273 \tikzstyle{abstract}=[rectangle, draw=black, fill=white, drop shadow, text
2274 centered, anchor=north, text=black, text width=6cm, every one node
2275 part/.style={align=center, font=\bfseries\itshape}]
2276 \tikzstyle{concrete}=[rectangle, draw=black, fill=white, drop shadow, text
2277 centered, anchor=north, text=black, text width=6cm]
2278 \tikzstyle{inheritarrow}=[->, >=open triangle 90, thick]
2279 \tikzstyle{commentarrow}=[->, >=angle 90, dashed]
2280 \tikzstyle{line}=[-, thick]
2281 \tikzset{every one node part/.style={align=center, font=\bfseries}}
2282 \tikzset{every second node part/.style={align=center, font=\ttfamily}}
2284 \begin{tikzpicture}[node distance=1cm, scale=0.8, every node/.style={transform
2286 \node (Element) [abstract, rectangle split, rectangle split parts=2]
2288 \nodepart{one}{Element}
2289 \nodepart{second}{+accept(visitor: Visitor)}
2291 \node (AuxNode01) [text width=0, minimum height=2cm, below=of Element] {};
2292 \node (ConcreteElementA) [concrete, rectangle split, rectangle split
2293 parts=2, left=of AuxNode01]
2295 \nodepart{one}{ConcreteElementA}
2296 \nodepart{second}{+accept(visitor: Visitor)}
2298 \node (ConcreteElementB) [concrete, rectangle split, rectangle split
2299 parts=2, right=of AuxNode01]
2301 \nodepart{one}{ConcreteElementB}
2302 \nodepart{second}{+accept(visitor: Visitor)}
2305 \node[comment, below=of ConcreteElementA] (CommentA) {visitor.visit(this)};
2307 \node[comment, below=of ConcreteElementB] (CommentB) {visitor.visit(this)};
2309 \node (AuxNodeX) [text width=0, minimum height=1cm, below=of AuxNode01] {};
2311 \node (Visitor) [abstract, rectangle split, rectangle split parts=2,
2314 \nodepart{one}{Visitor}
2315 \nodepart{second}{+visit(ConcreteElementA)\\+visit(ConcreteElementB)}
2317 \node (AuxNode02) [text width=0, minimum height=2cm, below=of Visitor] {};
2318 \node (ConcreteVisitor1) [concrete, rectangle split, rectangle split
2319 parts=2, left=of AuxNode02]
2321 \nodepart{one}{ConcreteVisitor1}
2322 \nodepart{second}{+visit(ConcreteElementA)\\+visit(ConcreteElementB)}
2324 \node (ConcreteVisitor2) [concrete, rectangle split, rectangle split
2325 parts=2, right=of AuxNode02]
2327 \nodepart{one}{ConcreteVisitor2}
2328 \nodepart{second}{+visit(ConcreteElementA)\\+visit(ConcreteElementB)}
2332 \draw[inheritarrow] (ConcreteElementA.north) -- ++(0,0.7) -|
2334 \draw[line] (ConcreteElementA.north) -- ++(0,0.7) -|
2335 (ConcreteElementB.north);
2337 \draw[inheritarrow] (ConcreteVisitor1.north) -- ++(0,0.7) -|
2339 \draw[line] (ConcreteVisitor1.north) -- ++(0,0.7) -|
2340 (ConcreteVisitor2.north);
2342 \draw[commentarrow] (CommentA.north) -- (ConcreteElementA.south);
2343 \draw[commentarrow] (CommentB.north) -- (ConcreteElementB.south);
2347 \caption{The Visitor Pattern.}
2348 \label{fig:visitorPattern}
2351 The use of the visitor pattern can be appropriate when the hierarchy of elements
2352 is mostly stable, but the family of operations over its elements is constantly
2353 growing. This is clearly the case for the Eclipse AST, since the hierarchy of
2354 type \type{ASTNode} is very stable, but the functionality of its elements is
2355 extended every time someone needs to operate on the AST. Another aspect of the
2356 Eclipse implementation is that it is a public API, and the visitor pattern is an
2357 easy way to provide access to the nodes in the tree.
2359 The version of the visitor pattern implemented for the AST nodes in Eclipse also
2360 provides an elegant way to traverse the tree. It does so by following the
2361 convention that every node in the tree first let the visitor visit itself,
2362 before it also makes all its children accept the visitor. The children are only
2363 visited if the visit method of their parent returns \var{true}. This pattern
2364 then makes for a prefix traversal of the AST. If postfix traversal is desired,
2365 the visitors also has \method{endVisit} methods for each node type, that is
2366 called after the \method{visit} method for a node. In addition to these visit
2367 methods, there are also the methods \method{preVisit(ASTNode)},
2368 \method{postVisit(ASTNode)} and \method{preVisit2(ASTNode)}. The
2369 \method{preVisit} method is called before the type-specific \method{visit}
2370 method. The \method{postVisit} method is called after the type-specific
2371 \method{endVisit}. The type specific \method{visit} is only called if
2372 \method{preVisit2} returns \var{true}. Overriding the \method{preVisit2} is also
2373 altering the behavior of \method{preVisit}, since the default implementation is
2374 responsible for calling it.
2376 An example of a trivial \type{ASTVisitor} is shown in
2377 \myref{lst:astVisitorExample}.
2380 \begin{minted}{java}
2381 public class CollectNamesVisitor extends ASTVisitor {
2382 Collection<Name> names = new LinkedList<Name>();
2385 public boolean visit(QualifiedName node) {
2391 public boolean visit(SimpleName node) {
2397 \caption{An \type{ASTVisitor} that visits all the names in a subtree and adds
2398 them to a collection, except those names that are children of any
2399 \type{QualifiedName}.}
2400 \label{lst:astVisitorExample}
2403 \section{Property collectors}\label{propertyCollectors}
2404 The prefixes and unfixes are found by property
2405 collectors\typeref{no.uio.ifi.refaktor.extractors.collectors.PropertyCollector}.
2406 A property collector is of the \type{ASTVisitor} type, and thus visits nodes of
2407 type \type{ASTNode} of the abstract syntax tree \see{astVisitor}.
2409 \subsection{The PrefixesCollector}
2410 The \typewithref{no.uio.ifi.refaktor.extractors.collectors}{PrefixesCollector}
2411 finds prefixes that makes up the basis for calculating move targets for the
2412 Extract and Move Method refactoring. It visits expression
2413 statements\typeref{org.eclipse.jdt.core.dom.ExpressionStatement} and creates
2414 prefixes from its expressions in the case of method invocations. The prefixes
2415 found is registered with a prefix set, together with all its sub-prefixes.
2417 \subsection{The UnfixesCollector}\label{unfixes}
2418 The \typewithref{no.uio.ifi.refaktor.extractors.collectors}{UnfixesCollector}
2419 finds unfixes within a selection. That is prefixes that cannot be used as a
2420 basis for finding a move target in a refactoring.
2422 An unfix can be a name that is assigned to within a selection. The reason that
2423 this cannot be allowed, is that the result would be an assignment to the
2424 \type{this} keyword, which is not valid in Java \see{eclipse_bug_420726}.
2426 Prefixes that originates from variable declarations within the same selection
2427 are also considered unfixes. This is because when a method is moved, it needs to
2428 be called through a variable. If this variable is also within the method that is
2429 to be moved, this obviously cannot be done.
2431 Also considered as unfixes are variable references that are of types that is not
2432 suitable for moving a methods to. This can be either because it is not
2433 physically possible to move the method to the desired class or that it will
2434 cause compilation errors by doing so.
2436 If the type binding for a name is not resolved it is considered and unfix. The
2437 same applies to types that is only found in compiled code, so they have no
2438 underlying source that is accessible to us. (E.g. the \type{java.lang.String}
2441 Interfaces types are not suitable as targets. This is simply because interfaces
2442 in Java cannot contain methods with bodies. (This thesis does not deal with
2443 features of Java versions later than Java 7. Java 8 has interfaces with default
2444 implementations of methods.) Neither are local types allowed. This accounts for
2445 both local and anonymous classes. Anonymous classes are effectively the same as
2446 interface types with respect to unfixes. Local classes could in theory be used
2447 as targets, but this is not possible due to limitations of the implementation of
2448 the Extract and Move Method refactoring. The problem is that the refactoring is
2449 done in two steps, so the intermediate state between the two refactorings would
2450 not be legal Java code. In the case of local classes, the problem is that, in
2451 the intermediate step, a selection referencing a local class would need to take
2452 the local class as a parameter if it were to be extracted to a new method. This
2453 new method would need to live in the scope of the declaring class of the
2454 originating method. The local class would then not be in the scope of the
2455 extracted method, thus bringing the source code into an illegal state. One could
2456 imagine that the method was extracted and moved in one operation, without an
2457 intermediate state. Then it would make sense to include variables with types of
2458 local classes in the set of legal targets, since the local classes would then be
2459 in the scopes of the method calls. If this makes any difference for software
2460 metrics that measure coupling would be a different discussion.
2463 \begin{multicols}{2}
2464 \begin{minted}[]{java}
2466 void declaresLocalClass() {
2481 \begin{minted}[]{java}
2482 // After Extract Method
2483 void declaresLocalClass() {
2494 // Intermediate step
2495 void fooBar(LocalClass inst) {
2501 \caption{When Extract and Move Method tries to use a variable with a local type
2502 as the move target, an intermediate step is taken that is not allowed. Here:
2503 \type{LocalClass} is not in the scope of \method{fooBar} in its intermediate
2505 \label{lst:extractMethod_LocalClass}
2508 The last class of names that are considered unfixes is names used in null tests.
2509 These are tests that reads like this: if \texttt{<name>} equals \var{null} then
2510 do something. If allowing variables used in those kinds of expressions as
2511 targets for moving methods, we would end up with code containing boolean
2512 expressions like \texttt{this == null}, which would not be meaningful, since
2513 \var{this} would never be \var{null}.
2516 \subsection{The ContainsReturnStatementCollector}
2518 \typewithref{no.uio.ifi.refaktor.analyze.collectors}{ContainsReturnStatementCollector}
2519 is a very simple property collector. It only visits the return statements within
2520 a selection, and can report whether it encountered a return statement or not.
2522 \subsection{The LastStatementCollector}
2523 The \typewithref{no.uio.ifi.refaktor.analyze.collectors}{LastStatementCollector}
2524 collects the last statement of a selection. It does so by only visiting the top
2525 level statements of the selection, and compares the textual end offset of each
2526 encountered statement with the end offset of the previous statement found.
2528 \section{Checkers}\label{checkers}
2529 The checkers are a range of classes that checks that selections complies with
2530 certain criteria. If a
2531 \typewithref{no.uio.ifi.refaktor.analyze.analyzers}{Checker} fails, it throws a
2532 \type{CheckerException}. The checkers are managed by the
2533 \type{LegalStatementsChecker}, which does not, in fact, implement the
2534 \type{Checker} interface. It does, however, run all the checkers registered with
2535 it, and reports that all statements are considered legal if no
2536 \type{CheckerException} is thrown. Many of the checkers either extends the
2537 \type{PropertyCollector} or utilizes one or more property collectors to verify
2538 some criteria. The checkers registered with the \type{LegalStatementsChecker}
2539 are described next. They are run in the order presented below.
2541 \subsection{The EnclosingInstanceReferenceChecker}
2542 The purpose of this checker is to verify that the names in a selection is not
2543 referencing any enclosing instances. This is for making sure that all references
2544 is legal in a method that is to be moved. Theoretically, some situations could
2545 be easily solved my passing a reference to the referenced class with the moved
2546 method (e.g. when calling public methods), but the dependency on the
2547 \type{MoveInstanceMethodProcessor} prevents this.
2550 \typewithref{no.uio.ifi.refaktor.analyze.analyzers}{EnclosingInstanceReferenceChecker}
2551 is a modified version of the
2552 \typewithref{org.eclipse.jdt.internal.corext.refactoring.structure.MoveInstanceMethodProcessor}{EnclosingInstanceReferenceFinder}
2553 from the \type{MoveInstanceMethodProcessor}. Wherever the
2554 \type{EnclosingInstanceReferenceFinder} would create a fatal error status, the
2555 checker throws a \type{CheckerException}.
2557 It works by first finding all of the enclosing types of a selection. Thereafter
2558 it visits all its simple names to check that they are not references to
2559 variables or methods declared in any of the enclosing types. In addition the
2560 checker visits \var{this}-expressions to verify that no such expressions is
2561 qualified with any name.
2563 \subsection{The ReturnStatementsChecker}\label{returnStatementsChecker}
2564 \todoin{Write\ldots/change implementation/use control flow graph?}
2566 \subsection{The AmbiguousReturnValueChecker}
2567 This checker verifies that there are no \emph{ambiguous return statements} in a
2568 selection. The problem with ambiguous return statements arise when a selection
2569 is chosen to be extracted into a new method, but it needs to return more than
2570 one value from that method. This problem occurs in two situations. The first
2571 situation arise when there is more than one local variable that is both assigned
2572 to within a selection and also referenced after the selection. The other
2573 situation occur when there is only one such assignment, but there is also one or
2574 more return statements in the selection.
2576 First the checker needs to collect some data. Those data are the binding keys
2577 for all simple names that are assigned to within the selection, including
2578 variable declarations, but excluding fields. The checker also collects whether
2579 there exists a return statement in the selection or not. No further checks of
2580 return statements are needed, since, at this point, the selection is already
2581 checked for illegal return statements \see{returnStatementsChecker}.
2583 After the binding keys of the assignees are collected, the checker searches the
2584 part of the enclosing method that is after the selection for references whose
2585 binding keys are among the collected keys. If more than one unique referral is
2586 found, or only one referral is found, but the selection also contains a return
2587 statement, we have a situation with an ambiguous return value, and an exception
2590 %\todoin{Explain why we do not need to consider variables assigned inside
2591 %local/anonymous classes. (The referenced variables need to be final and so
2594 \subsection{The IllegalStatementsChecker}
2595 This checker is designed to check for illegal statements.
2597 Any use of the \var{super} keyword is prohibited, since its meaning is altered
2598 when moving a method to another class.
2600 For a \emph{break} statement, there is two situations to consider: A break
2601 statement with or without a label. If the break statement has a label, it is
2602 checked that whole of the labeled statement is inside the selection. Since a
2603 label does not have any binding information, we have to search upwards in the
2604 AST to find the \type{LabeledStatement} that corresponds to the label from the
2605 break statement, and check that it is contained in the selection. If the break
2606 statement does not have a label attached to it, it is checked that its innermost
2607 enclosing loop or switch statement also is inside the selection.
2609 The situation for a \emph{continue} statement is the same as for a break
2610 statement, except that it is not allowed inside switch statements.
2612 Regarding \emph{assignments}, two types of assignments is allowed: Assignment to
2613 a non-final variable and assignment to an array access. All other assignments is
2616 \todoin{Finish\ldots}
2619 \chapter{Benchmarking}
2620 \todoin{Better name than ``benchmarking''?}
2621 This part of the master project is located in the Eclipse project
2622 \code{no.uio.ifi.refaktor.benchmark}. The purpose of it is to run the equivalent
2623 of the \type{SearchBasedExtractAndMoveMethodChanger}
2624 \see{searchBasedExtractAndMoveMethodChanger} over a larger software project,
2625 both to test its robustness but also its effect on different software metrics.
2627 \section{The benchmark setup}
2628 The benchmark itself is set up as a \emph{JUnit} test case. This is a convenient
2629 setup, and utilizes the \emph{JUnit Plugin Test Launcher}. This provides us a
2630 with a fully functional Eclipse workbench. Most importantly, this gives us
2631 access to the Java Model of Eclipse \see{javaModel}.
2633 \subsection{The ProjectImporter}
2634 The Java project that is going to be used as the data for the benchmark, must be
2635 imported into the JUnit workspace. This is done by the
2636 \typewithref{no.uio.ifi.refaktor.benchmark}{ProjectImporter}. The importer
2637 require the absolute path to the project description file. It is named
2638 \code{.project} and is located at the root of the project directory.
2640 The project description is loaded to find the name of the project to be
2641 imported. The project that shall be the destination for the import is created in
2642 the workspace, on the base of the name from the description. Then an import
2643 operation is created, based on both the source and destination information. The
2644 import operation is run to perform the import.
2646 I have found no simple API call to accomplish what the importer does, which
2647 tells me that it may not be too many people performing this particular action.
2648 The solution to the problem was found on \emph{Stack
2649 Overflow}\footnote{\url{https://stackoverflow.com/questions/12401297}}. It
2650 contains enough dirty details to be considered inconvenient to use, if not
2651 wrapping it in a class like my \type{ProjectImporter}. One would probably have
2652 to delve into the source code for the import wizard to find out how the import
2653 operation works, if no one had already done it.
2655 \section{Statistics}
2656 Statistics for the analysis and changes is captured by the
2657 \typewithref{no.uio.ifi.refaktor.aspects}{StatisticsAspect}. This an
2658 \emph{aspect} written in \emph{AspectJ}.
2660 \subsection{AspectJ}
2661 \emph{AspectJ}\footnote{\url{http://eclipse.org/aspectj/}} is an extension to
2662 the Java language, and facilitates combining aspect-oriented programming with
2663 the object-oriented programming in Java.
2665 Aspect-oriented programming is a programming paradigm that is meant to isolate
2666 so-called \emph{cross-cutting concerns} into their own modules. These
2667 cross-cutting concerns are functionalities that spans over multiple classes, but
2668 may not belong naturally in any of them. It can be functionality that does not
2669 concern the business logic of an application, and thus may be a burden when
2670 entangled with parts of the source code it does not really belong. Examples
2671 include logging, debugging, optimization and security.
2673 Aspects are interacting with other modules by defining advices. The concept of
2674 an \emph{advice} is known from both aspect-oriented and functional
2675 programming\citing{wikiAdvice2014}. It is a function that modifies another
2676 function when the latter is run. An advice in AspectJ is somewhat similar to a
2677 method in Java. It is meant to alter the behavior of other methods, and contains
2678 a body that is executed when it is applied.
2680 An advice can be applied at a defined \emph{pointcut}. A pointcut picks out one
2681 or more \emph{join points}. A join point is a well-defined point in the
2682 execution of a program. It can occur when calling a method defined for a
2683 particular class, when calling all methods with the same name,
2684 accessing/assigning to a particular field of a given class and so on. An advice
2685 can be declared to run both before, after returning from a pointcut, when there
2686 is thrown an exception in the pointcut or after the pointcut either returns or
2687 throws an exception. In addition to picking out join points, a pointcut can
2688 also bind variables from its context, so they can be accessed in the body of an
2689 advice. An example of a pointcut and an advice is found in
2690 \myref{lst:aspectjExample}.
2693 \begin{minted}{aspectj}
2694 pointcut methodAnalyze(
2695 SearchBasedExtractAndMoveMethodAnalyzer analyzer) :
2696 call(* SearchBasedExtractAndMoveMethodAnalyzer.analyze())
2697 && target(analyzer);
2699 after(SearchBasedExtractAndMoveMethodAnalyzer analyzer) :
2700 methodAnalyze(analyzer) {
2701 statistics.methodCount++;
2702 debugPrintMethodAnalysisProgress(analyzer.method);
2705 \caption{An example of a pointcut named \method{methodAnalyze},
2706 and an advice defined to be applied after it has occurred.}
2707 \label{lst:aspectjExample}
2710 \subsection{The Statistics class}
2711 The statistics aspect stores statistical information in an object of type
2712 \type{Statistics}. As of now, the aspect needs to be initialized at the point in
2713 time where it is desired that it starts its data gathering. At any point in time
2714 the statistics aspect can be queried for a snapshot of the current statistics.
2716 The \type{Statistics} class also include functionality for generating a report
2717 of its gathered statistics. The report can be given either as a string or it can
2718 be written to a file.
2720 \subsection{Advices}
2721 The statistics aspect contains advices for gathering statistical data from
2722 different parts of the benchmarking process. It captures statistics from both
2723 the analysis part and the execution part of the composite \ExtractAndMoveMethod
2726 For the analysis part, there are advices to count the number of text selections
2727 analyzed and the number of methods, types, compilation units and packages
2728 analyzed. There are also advices that counts for how many of the methods there
2729 is found a selection that is a candidate for the refactoring, and for how many
2730 methods there is not.
2732 There exists advices for counting both the successful and unsuccessful
2733 executions of all the refactorings. Both for the \ExtractMethod and \MoveMethod
2734 refactorings in isolation, as well as for the combination of them.
2736 \section{Optimizations}
2737 When looking for optimizations to make for the benchmarking process, I used the
2738 \emph{VisualVM}\footnote{\url{http://visualvm.java.net/}} for the Java Virtual
2739 Machine to both profile the application and also to make memory dumps of its
2742 \subsection{Caching}
2743 When profiling the benchmark process before making any optimizations, it early
2744 became apparent that the parsing of source code was a place to direct attention
2745 towards. This discovery was done when only \emph{analyzing} source code, before
2746 trying to do any \emph{manipulation} of it. Caching of the parsed ASTs seemed
2747 like the best way to save some time, as expected. With only a simple cache of
2748 the most recently used AST, the analysis time was speeded up by a factor of
2750 20. This number depends a little upon which type of system the analysis was
2753 The caching is managed by a cache manager, that now, by default, utilizes the
2754 not so well known feature of Java called a \emph{soft reference}. Soft
2755 references are best explained in the context of weak references. A \emph{weak
2756 reference} is a reference to an object instance that is only guaranteed to
2757 persist as long as there is a \emph{strong reference} or a soft reference
2758 referring the same object. If no such reference is found, its referred object is
2759 garbage collected. A strong reference is basically the same as a regular Java
2760 reference. A soft reference has the same guarantees as a week reference when it
2761 comes to its relation to strong references, but it is not necessarily garbage
2762 collected whenever there exists no strong references to it. A soft reference
2763 \emph{may} reside in memory as long as the JVM has enough free memory in the
2764 heap. A soft reference will therefore usually perform better than a weak
2765 reference when used for simple caching and similar tasks. The way to use a
2766 soft/weak reference is to as it for its referent. The return value then has to
2767 be tested to check that it is not \var{null}. For the basic usage of soft
2768 references, see \myref{lst:softReferenceExample}. For a more thorough
2769 explanation of weak references in general, see\citing{weakRef2006}.
2772 \begin{minted}{java}
2774 Object strongRef = new Object();
2777 SoftReference<Object> softRef =
2778 new SoftReference<Object>(new Object());
2780 // Using the soft reference
2781 Object obj = softRef.get();
2786 \caption{Showing the basic usage of soft references. Weak references is used the
2787 same way. {\footnotesize (The references are part of the \code{java.lang.ref}
2789 \label{lst:softReferenceExample}
2792 The cache based on soft references has no limit for how many ASTs it caches. It
2793 is generally not advisable to keep references to ASTs for prolonged periods of
2794 time, since they are expensive structures to hold on to. For regular plugin
2795 development, Eclipse recommends not creating more than one AST at a time to
2796 limit memory consumption. Since the benchmarking has nothing to do with user
2797 experience, and throughput is everything, these advices are intentionally
2798 ignored. This means that during the benchmarking process, the target Eclipse
2799 application may very well work close to its memory limit for the heap space for
2800 long periods during the benchmark.
2802 \subsection{Memento}
2804 \chapter{Eclipse Bugs Found}
2805 \todoin{Add other things and change headline?}
2807 \section{Eclipse bug 420726: Code is broken when moving a method that is
2808 assigning to the parameter that is also the move
2809 destination}\label{eclipse_bug_420726}
2810 This bug\footnote{\url{https://bugs.eclipse.org/bugs/show\_bug.cgi?id=420726}}
2811 was found when analyzing what kinds of names that was to be considered as
2812 \emph{unfixes} \see{unfixes}.
2814 \subsection{The bug}
2815 The bug emerges when trying to move a method from one class to another, and when
2816 the target for the move (must be a variable, local or field) is both a parameter
2817 variable and also is assigned to within the method body. Eclipse allows this to
2818 happen, although it is the sure path to a compilation error. This is because we
2819 would then have an assignment to a \var{this} expression, which is not allowed
2822 \subsection{The solution}
2823 The solution to this problem is to add all simple names that are assigned to in
2824 a method body to the set of unfixes.
2826 \section{Eclipse bug 429416: IAE when moving method from anonymous class}
2828 discovered\footnote{\url{https://bugs.eclipse.org/bugs/show\_bug.cgi?id=429416}}
2829 this bug during a batch change on the \type{org.eclipse.jdt.ui} project.
2831 \subsection{The bug}
2832 This bug surfaces when trying to use the Move Method refactoring to move a
2833 method from an anonymous class to another class. This happens both for my
2834 simulation as well as in Eclipse, through the user interface. It only occurs
2835 when Eclipse analyzes the program and finds it necessary to pass an instance of
2836 the originating class as a parameter to the moved method. I.e. it want to pass a
2837 \var{this} expression. The execution ends in an
2838 \typewithref{java.lang}{IllegalArgumentException} in
2839 \typewithref{org.eclipse.jdt.core.dom}{SimpleName} and its
2840 \method{setIdentifier(String)} method. The simple name is attempted created in
2842 \methodwithref{org.eclipse.jdt.internal.corext.refactoring.structure.\\MoveInstanceMethodProcessor}{createInlinedMethodInvocation}
2843 so the \type{MoveInstanceMethodProcessor} was early a clear suspect.
2845 The \method{createInlinedMethodInvocation} is the method that creates a method
2846 invocation where the previous invocation to the method that was moved was. From
2847 its code it can be read that when a \var{this} expression is going to be passed
2848 in to the invocation, it shall be qualified with the name of the original
2849 method's declaring class, if the declaring class is either an anonymous class or
2850 a member class. The problem with this, is that an anonymous class does not have
2851 a name, hence the term \emph{anonymous} class! Therefore, when its name, an
2852 empty string, is passed into
2853 \methodwithref{org.eclipse.jdt.core.dom.AST}{newSimpleName} it all ends in an
2854 \type{IllegalArgumentException}.
2856 \subsection{How I solved the problem}
2857 Since the \type{MoveInstanceMethodProcessor} is instantiated in the
2858 \typewithref{no.uio.ifi.refaktor.change.executors}{MoveMethod\-RefactoringExecutor},
2859 and only need to be a
2860 \typewithref{org.eclipse.ltk.core.refactoring.participants}{MoveProcessor}, I
2861 was able to copy the code for the original move processor and modify it so that
2862 it works better for me. It is now called
2863 \typewithref{no.uio.ifi.refaktor.refactorings.processors}{ModifiedMoveInstanceMethodProcessor}.
2864 The only modification done (in addition to some imports and suppression of
2865 warnings), is in the \method{createInlinedMethodInvocation}. When the declaring
2866 class of the method to move is anonymous, the \var{this} expression in the
2867 parameter list is not qualified with the declaring class' (empty) name.
2869 \section{Eclipse bug 429954: Extracting statement with reference to local type
2870 breaks code}\label{eclipse_bug_429954}
2871 The bug\footnote{\url{https://bugs.eclipse.org/bugs/show\_bug.cgi?id=429954}}
2872 was discovered when doing some changes to the way unfixes is computed.
2874 \subsection{The bug}
2875 The problem is that Eclipse is allowing selections that references variables of
2876 local types to be extracted. When this happens the code is broken, since the
2877 extracted method must take a parameter of a local type that is not in the
2878 methods scope. The problem is illustrated in
2879 \myref{lst:extractMethod_LocalClass}, but there in another setting.
2881 \subsection{Actions taken}
2882 There are no actions directly springing out of this bug, since the Extract
2883 Method refactoring cannot be meant to be this way. This is handled on the
2884 analysis stage of our Extract and Move Method refactoring. So names representing
2885 variables of local types is considered unfixes \see{unfixes}.
2886 \todoin{write more when fixing this in legal statements checker}
2888 \chapter{Related Work}
2890 \section{The compositional paradigm of refactoring}
2891 This paradigm builds upon the observation of Vakilian et
2892 al.\citing{vakilian2012}, that of the many automated refactorings existing in
2893 modern IDEs, the simplest ones are dominating the usage statistics. The report
2894 mainly focuses on \emph{Eclipse} as the tool under investigation.
2896 The paradigm is described almost as the opposite of automated composition of
2897 refactorings \see{compositeRefactorings}. It works by providing the programmer
2898 with easily accessible primitive refactorings. These refactorings shall be
2899 accessed via keyboard shortcuts or quick-assist menus\footnote{Think
2900 quick-assist with Ctrl+1 in Eclipse} and be promptly executed, opposed to in the
2901 currently dominating wizard-based refactoring paradigm. They are meant to
2902 stimulate composing smaller refactorings into more complex changes, rather than
2903 doing a large upfront configuration of a wizard-based refactoring, before
2904 previewing and executing it. The compositional paradigm of refactoring is
2905 supposed to give control back to the programmer, by supporting \himher with an
2906 option of performing small rapid changes instead of large changes with a lesser
2907 degree of control. The report authors hope this will lead to fewer unsuccessful
2908 refactorings. It also could lower the bar for understanding the steps of a
2909 larger composite refactoring and thus also help in figuring out what goes wrong
2910 if one should choose to op in on a wizard-based refactoring.
2912 Vakilian and his associates have performed a survey of the effectiveness of the
2913 compositional paradigm versus the wizard-based one. They claim to have found
2914 evidence of that the \emph{compositional paradigm} outperforms the
2915 \emph{wizard-based}. It does so by reducing automation, which seem
2916 counterintuitive. Therefore they ask the question ``What is an appropriate level
2917 of automation?'', and thus questions what they feel is a rush toward more
2918 automation in the software engineering community.