]> git.uio.no Git - ifi-stolz-refaktor.git/commitdiff
Thesis: about disqualifying a selection
authorErlend Kristiansen <erlenkr@ifi.uio.no>
Mon, 14 Apr 2014 10:33:36 +0000 (12:33 +0200)
committerErlend Kristiansen <erlenkr@ifi.uio.no>
Mon, 14 Apr 2014 10:33:36 +0000 (12:33 +0200)
thesis/master-thesis-erlenkr.tex

index 98921d0ef722bc0adad6d7829365492a1683b78d..fcdd39cbe9d3bce220c445095a7d577083656d00 100644 (file)
@@ -73,7 +73,7 @@
 \newcommand{\MoveMethod}{\refa{Move Method}\xspace}
 \newcommand{\ExtractAndMoveMethod}{\refa{Extract and Move Method}\xspace}
 
-\newcommand{\mathvar}[1]{$#1$}
+\newcommand{\m}[1]{$#1$}
 
 \newcommand\todoin[2][]{\todo[inline, caption={#2}, #1]{
 \begin{minipage}{\textwidth-4pt}#2\end{minipage}}}
@@ -126,6 +126,12 @@ the old class via a reference to the new class}
 identifies its participators and how they collaborate},
   plural={design patterns}
 }
+\newglossaryentry{enclosingClass}
+{
+  name={enclosing class},
+  description={An enclosing class is the class that surrounds any specific piece 
+  of code that is written in the inner scope of this class},
+}
 %\newglossaryentry{extractMethod}
 %{
 %  name=\refa{Extract Method},
@@ -1577,24 +1583,24 @@ for a concrete criterion, the selections are evaluated by the next criterion.
 
 \begin{enumerate}
   \item The first criterion that is evaluated is whether a selection contains 
-    any unfixes or not.  If selection \mathvar{A} contains no unfixes, while 
-    selection \mathvar{B} does, selection \mathvar{A} is favored over selection 
-    \mathvar{B}.  This is done under the assumption that, if possible, avoiding 
+    any unfixes or not.  If selection \m{A} contains no unfixes, while 
+    selection \m{B} does, selection \m{A} is favored over selection 
+    \m{B}.  This is done under the assumption that, if possible, avoiding 
     selections containing unfixes will make the code moved a little 
     cleaner.\todoin{more arguments?}
 
   \item The second criterion that is evaluated is how many possible targets a 
-    selection contains. If selection \mathvar{A} has only one possible target, and 
-    selection \mathvar{B} has multiple, selection \mathvar{A} is favored. If both 
+    selection contains. If selection \m{A} has only one possible target, and 
+    selection \m{B} has multiple, selection \m{A} is favored. If both 
     selections have multiple possible targets, they are considered equal with 
     respect to this criterion. The rationale for this heuristic is that we would 
     prefer not to introduce new couplings between classes when performing the 
     \ExtractAndMoveMethod refactoring. 
 
   \item When evaluating the last criterion, this is with the knowledge that
-    selection \mathvar{A} and \mathvar{B} both have one possible target. Then, if 
-    the move target candidate of selection \mathvar{A} has a higher reference count 
-    than the target candidate of selection \mathvar{B}, selection \mathvar{A} is 
+    selection \m{A} and \m{B} both have one possible target. Then, if 
+    the move target candidate of selection \m{A} has a higher reference count 
+    than the target candidate of selection \m{B}, selection \m{A} is 
     favored. The reason for this is that we would like to move the selection that 
     gets rid of the most references to another class. 
 
@@ -1605,7 +1611,56 @@ selections are considered to be equally good candidates for the
 \ExtractAndMoveMethod refactoring.
 
 \section{Disqualifying a selection}
-Some text selections\todo{\ldots}
+Certain text selections would lead to broken code if used as input to the 
+\ExtractAndMoveMethod refactoring. To avoid this, we have to check all text 
+selections for such conditions before they are further analyzed. Now follows 
+some properties that makes a selection unsuitable for the refactoring.
+
+\subsection{A call to a protected or package-private method}
+If a text selection contains such a call, it would not be safe to move it to 
+another class. The reason for this, is that we cannot know if the called method 
+is being overridden by some subclass of the \gloss{enclosingClass}, or not.
+
+Imagine that the protected method \method{foo} is declared in class \m{A}, 
+and overridden in class \m{B}. The method \method{foo} is called from within a 
+selection done to a method in \m{A}. We want to extract and move this selection 
+to another class. The method \method{foo} is not public, so the \MoveMethod 
+refactoring must make it public, making the extracted method able to call it 
+from the extracted method's new location. The problem is that the, now public, 
+method \method{foo} is overridden in a subclass, where it has a protected 
+status.  This makes the compiler complain that the subclass \m{B} is trying to 
+reduce the visibility of a method declared in its superclass \m{A}. This is not 
+allowed in Java, and for good reasons.  It would make it possible to make a 
+subclass that could not be a substitute for its superclass.
+\todoin{Code example?}
+
+\subsection{Instantiation of non-static inner class}
+When a non-static inner class is instantiated, this must happen in the scope of 
+its declaring class. This is because it must have access to the members of the 
+declaring class. If the inner class is public, it is possible to instantiate it 
+through an instance of its declaring class, but this is not handled by the 
+underlying \MoveMethod refactoring.
+
+Performing a move on a method that instantiates a non-static inner class, will 
+break the code if the instantiation is not handled properly. For this reason, 
+selections that contains instantiations of non-static inner classes are deemed 
+unsuitable for the \ExtractAndMoveMethod refactoring.
+
+\subsection{References to enclosing instances of the enclosing class}
+The title of this section may be a little hard to grasp at first. What it means 
+is that there is a (non-static) class \m{C} that is declared in the scope of 
+possibly multiple other classes. And there is a statement in a method declared 
+in class \m{C} that contains a reference to one or more instances of these 
+enclosing classes of \m{C}.
+
+The problem with this, is that these references may not be valid if they are 
+moved to another class. Theoretically, some situations could easily be solved by 
+passing, to the moved method, a reference to the instance where the problematic 
+referenced member is declared, in the case where this member is public. This is 
+not done in the underlying \MoveMethod refactoring, so it cannot be allowed in 
+the \ExtractAndMoveMethod refactoring either.
+
+
 
 \chapter{Refactorings in Eclipse JDT: Design, Shortcomings and Wishful 
 Thinking}\label{ch:jdt_refactorings}
@@ -2828,18 +2883,11 @@ This checker is designed to prevent an error that can occur in situations where
 a method is declared in one class, but overridden in another. If a text 
 selection contains a call to a method like this, and the seletion is extracted 
 to a new method, the subsequent movement of this method could cause the code to 
-break. 
+break.  
 
 The code breaks in situations where the method call in the selection is to a 
 method that has the \code{protected} modifier, or it does not have any access 
-modifiers, i.e. it is package-private. The method is not public, so the 
-\MoveMethod refactoring must make it public, making the moved method able to 
-call it from its new location. The problem is that the, now public, method is 
-overridden in a subclass, where it has a protected or package-private status.  
-This makes the compiler complain that the subclass is trying to reduce the 
-visibility of a method declared in its superclass. This is not allowed in Java, 
-and for good reasons. It would make it possible to make a subclass that could 
-not be a substitute for its superclass.
+modifiers, i.e. it is package-private.
 
 The workings of the \type{CallToProtectedOrPackagePrivateMethod\-Checker} is 
 therefore very simple. It looks for calls to methods that are either protected 
@@ -2853,6 +2901,7 @@ introducing errors in the context of automated refactoring. This is also shown
 in bug\ldots \todoin{File Eclipse bug report}
 
 \subsection{The InstantiationOfNonStaticInnerClassChecker}
+\todoin{Contains duplicate text from semantic section}
 When a non-static inner class is instatiated, this must happen in the scope of 
 its declaring class. This is because it must have access to the members of the 
 declaring class. If the inner class is public, it is possible to instantiate it 
@@ -2865,7 +2914,8 @@ selections that contains instantiations of non-static inner classes. This
 problem is also related to bug\ldots \todoin{File Eclipse bug report}
 
 \subsection{The EnclosingInstanceReferenceChecker}
-The purpose of this checker is to verify that the names in a selection is not 
+\todoin{Contains duplicate text from semantic section}
+The purpose of this checker is to verify that the names in a selection are not 
 referencing any enclosing instances. This is for making sure that all references 
 is legal in a method that is to be moved. Theoretically, some situations could 
 be easily solved my passing a reference to the referenced class with the moved 
@@ -2883,7 +2933,7 @@ checker throws a \type{CheckerException}.
 It works by first finding all of the enclosing types of a selection. Thereafter 
 it visits all its simple names to check that they are not references to 
 variables or methods declared in any of the enclosing types. In addition the 
-checker visits \var{this}-expressions to verify that no such expressions is 
+checker visits \var{this}-expressions to verify that no such expressions are 
 qualified with any name.
 
 \subsection{The ReturnStatementsChecker}\label{returnStatementsChecker}