Permalink
Browse files

Merge pull request #48 from tomphp/refactor/editing-actions

Start breaking EditingSession down into EditingActions
  • Loading branch information...
2 parents 21027f3 + bc9285c commit c951cbf2d957b5ced0546691710c09e4fadd3723 @beberlei beberlei committed Jan 9, 2014
Showing with 1,905 additions and 258 deletions.
  1. +28 −34 src/main/QafooLabs/Refactoring/Application/ConvertLocalToInstanceVariable.php
  2. +58 −27 src/main/QafooLabs/Refactoring/Application/ExtractMethod.php
  3. +30 −35 src/main/QafooLabs/Refactoring/Application/RenameLocalVariable.php
  4. +85 −0 src/main/QafooLabs/Refactoring/Application/SingleFileRefactoring.php
  5. +8 −0 src/main/QafooLabs/Refactoring/Domain/Model/EditingAction.php
  6. +150 −0 src/main/QafooLabs/Refactoring/Domain/Model/EditingAction/AddMethod.php
  7. +37 −0 src/main/QafooLabs/Refactoring/Domain/Model/EditingAction/AddProperty.php
  8. +38 −0 src/main/QafooLabs/Refactoring/Domain/Model/EditingAction/LocalVariableToInstance.php
  9. +62 −0 src/main/QafooLabs/Refactoring/Domain/Model/EditingAction/RenameVariable.php
  10. +79 −0 src/main/QafooLabs/Refactoring/Domain/Model/EditingAction/ReplaceWithMethodCall.php
  11. +10 −111 src/main/QafooLabs/Refactoring/Domain/Model/EditingSession.php
  12. +56 −0 src/main/QafooLabs/Refactoring/Domain/Model/IndentationDetector.php
  13. +36 −0 src/main/QafooLabs/Refactoring/Domain/Model/IndentingLineCollection.php
  14. +43 −0 src/main/QafooLabs/Refactoring/Domain/Model/Line.php
  15. +82 −0 src/main/QafooLabs/Refactoring/Domain/Model/LineCollection.php
  16. +52 −0 src/main/QafooLabs/Refactoring/Utils/ToStringIterator.php
  17. +0 −51 src/test/QafooLabs/Refactoring/Application/RenameLocalVariableTest.php.orig
  18. +229 −0 src/test/QafooLabs/Refactoring/Domain/Model/EditingAction/AddMethodTest.php
  19. +50 −0 src/test/QafooLabs/Refactoring/Domain/Model/EditingAction/AddPropertyTest.php
  20. +114 −0 src/test/QafooLabs/Refactoring/Domain/Model/EditingAction/LocalVariableToInstanceTest.php
  21. +117 −0 src/test/QafooLabs/Refactoring/Domain/Model/EditingAction/RenameVariableTest.php
  22. +122 −0 src/test/QafooLabs/Refactoring/Domain/Model/EditingAction/ReplaceWithMethodCallTest.php
  23. +36 −0 src/test/QafooLabs/Refactoring/Domain/Model/EditingSessionTest.php
  24. +68 −0 src/test/QafooLabs/Refactoring/Domain/Model/IndentationDetectorTest.php
  25. +109 −0 src/test/QafooLabs/Refactoring/Domain/Model/IndentingLineCollectionTest.php
  26. +114 −0 src/test/QafooLabs/Refactoring/Domain/Model/LineCollectionTest.php
  27. +43 −0 src/test/QafooLabs/Refactoring/Domain/Model/LineTest.php
  28. +49 −0 src/test/QafooLabs/Refactoring/Utils/ToStringIteratorTest.php
@@ -13,56 +13,50 @@
use QafooLabs\Refactoring\Domain\Services\VariableScanner;
use QafooLabs\Refactoring\Domain\Services\CodeAnalysis;
use QafooLabs\Refactoring\Domain\Services\Editor;
+use QafooLabs\Refactoring\Domain\Model\EditingAction\AddProperty;
+use QafooLabs\Refactoring\Domain\Model\EditingAction\LocalVariableToInstance;
-class ConvertLocalToInstanceVariable
+class ConvertLocalToInstanceVariable extends SingleFileRefactoring
{
/**
- * @var \QafooLabs\Refactoring\Domain\Services\VariableScanner
+ * @var Variable
*/
- private $variableScanner;
+ private $convertVariable;
/**
- * @var \QafooLabs\Refactoring\Domain\Services\CodeAnalysis
+ * @param int $line
*/
- private $codeAnalysis;
+ public function refactor(File $file, $line, Variable $convertVariable)
+ {
+ $this->file = $file;
+ $this->line = $line;
+ $this->convertVariable = $convertVariable;
- /**
- * @var \QafooLabs\Refactoring\Domain\Services\Editor
- */
- private $editor;
+ $this->assertIsInsideMethod();
- public function __construct(VariableScanner $variableScanner, CodeAnalysis $codeAnalysis, Editor $editor)
- {
- $this->variableScanner = $variableScanner;
- $this->codeAnalysis = $codeAnalysis;
- $this->editor = $editor;
+ $this->startEditingSession();
+ $this->addProperty();
+ $this->convertVariablesToInstanceVariables();
+ $this->completeEditingSession();
}
- public function refactor(File $file, $line, Variable $convertVariable)
+ private function addProperty()
{
- if ( ! $this->codeAnalysis->isInsideMethod($file, LineRange::fromSingleLine($line))) {
- throw RefactoringException::rangeIsNotInsideMethod(LineRange::fromSingleLine($line));
- }
+ $line = $this->codeAnalysis->getLineOfLastPropertyDefinedInScope($this->file, $this->line);
- $instanceVariable = $convertVariable->convertToInstance();
- $lastPropertyLine = $this->codeAnalysis->getLineOfLastPropertyDefinedInScope($file, $line);
-
- $selectedMethodLineRange = $this->codeAnalysis->findMethodRange($file, LineRange::fromSingleLine($line));
- $definedVariables = $this->variableScanner->scanForVariables(
- $file, $selectedMethodLineRange
+ $this->session->addEdit(
+ new AddProperty($line, $this->convertVariable->getName())
);
+ }
- if ( ! $definedVariables->contains($convertVariable)) {
- throw RefactoringException::variableNotInRange($convertVariable, $selectedMethodLineRange);
- }
-
- $buffer = $this->editor->openBuffer($file);
+ private function convertVariablesToInstanceVariables()
+ {
+ $definedVariables = $this->getDefinedVariables();
- $session = new EditingSession($buffer);
- $session->addProperty($lastPropertyLine, $convertVariable->getName());
- $session->replaceString($definedVariables, $convertVariable, $instanceVariable);
+ if ( ! $definedVariables->contains($this->convertVariable)) {
+ throw RefactoringException::variableNotInRange($this->convertVariable, $selectedMethodLineRange);
+ }
- $this->editor->save();
+ $this->session->addEdit(new LocalVariableToInstance($definedVariables, $this->convertVariable));
}
}
-
@@ -11,60 +11,91 @@
use QafooLabs\Refactoring\Domain\Services\VariableScanner;
use QafooLabs\Refactoring\Domain\Services\CodeAnalysis;
use QafooLabs\Refactoring\Domain\Services\Editor;
+use QafooLabs\Refactoring\Domain\Model\LineCollection;
+use QafooLabs\Refactoring\Domain\Model\EditingAction\AddMethod;
+use QafooLabs\Refactoring\Domain\Model\EditingAction\ReplaceWithMethodCall;
/**
* Extract Method Refactoring
*/
-class ExtractMethod
+class ExtractMethod extends SingleFileRefactoring
{
/**
- * @var \QafooLabs\Refactoring\Domain\Services\VariableScanner
+ * @var LineRange
*/
- private $variableScanner;
+ private $extractRange;
/**
- * @var \QafooLabs\Refactoring\Domain\Services\CodeAnalysis
+ * @var MethodSignature
*/
- private $codeAnalysis;
+ private $newMethod;
/**
- * @var \QafooLabs\Refactoring\Domain\Services\Editor
+ * @param string $newMethodName
*/
- private $editor;
-
- public function __construct(VariableScanner $variableScanner, CodeAnalysis $codeAnalysis, Editor $editor)
+ public function refactor(File $file, LineRange $extractRange, $newMethodName)
{
- $this->variableScanner = $variableScanner;
- $this->codeAnalysis = $codeAnalysis;
- $this->editor = $editor;
+ $this->file = $file;
+ $this->extractRange = $extractRange;
+
+ $this->assertIsInsideMethod();
+
+ $this->createNewMethodSignature($newMethodName);
+
+ $this->startEditingSession();
+ $this->replaceCodeWithMethodCall();
+ $this->addNewMethod();
+ $this->completeEditingSession();
}
- public function refactor(File $file, LineRange $extractRange, $newMethodName)
+ protected function assertIsInsideMethod()
{
- if ( ! $this->codeAnalysis->isInsideMethod($file, $extractRange)) {
- throw RefactoringException::rangeIsNotInsideMethod($extractRange);
+ if ( ! $this->codeAnalysis->isInsideMethod($this->file, $this->extractRange)) {
+ throw RefactoringException::rangeIsNotInsideMethod($this->extractRange);
}
+ }
- $isStatic = $this->codeAnalysis->isMethodStatic($file, $extractRange);
- $methodRange = $this->codeAnalysis->findMethodRange($file, $extractRange);
- $selectedCode = $extractRange->sliceCode($file->getCode());
-
- $extractVariables = $this->variableScanner->scanForVariables($file, $extractRange);
- $methodVariables = $this->variableScanner->scanForVariables($file, $methodRange);
+ private function createNewMethodSignature($newMethodName)
+ {
+ $extractVariables = $this->variableScanner->scanForVariables($this->file, $this->extractRange);
+ $methodVariables = $this->variableScanner->scanForVariables($this->file, $this->findMethodRange());
- $buffer = $this->editor->openBuffer($file);
+ $isStatic = $this->codeAnalysis->isMethodStatic($this->file, $this->extractRange);
- $newMethod = new MethodSignature(
+ $this->newMethod = new MethodSignature(
$newMethodName,
$isStatic ? MethodSignature::IS_STATIC : 0,
$methodVariables->variablesFromSelectionUsedBefore($extractVariables),
$methodVariables->variablesFromSelectionUsedAfter($extractVariables)
);
+ }
- $session = new EditingSession($buffer);
- $session->replaceRangeWithMethodCall($extractRange, $newMethod);
- $session->addMethod($methodRange->getEnd(), $newMethod, $selectedCode);
+ private function addNewMethod()
+ {
+ $this->session->addEdit(new AddMethod(
+ $this->findMethodRange()->getEnd(),
+ $this->newMethod,
+ $this->getSelectedCode()
+ ));
+ }
+
+ private function replaceCodeWithMethodCall()
+ {
+ $this->session->addEdit(new ReplaceWithMethodCall(
+ $this->extractRange,
+ $this->newMethod
+ ));
+ }
- $this->editor->save();
+ private function findMethodRange()
+ {
+ return $this->codeAnalysis->findMethodRange($this->file, $this->extractRange);
+ }
+
+ private function getSelectedCode()
+ {
+ return LineCollection::createFromArray(
+ $this->extractRange->sliceCode($this->file->getCode())
+ );
}
}
@@ -12,63 +12,58 @@
use QafooLabs\Refactoring\Domain\Services\VariableScanner;
use QafooLabs\Refactoring\Domain\Services\CodeAnalysis;
use QafooLabs\Refactoring\Domain\Services\Editor;
+use QafooLabs\Refactoring\Domain\Model\EditingAction\RenameVariable;
/**
* Rename Local Variable Refactoring
*/
-class RenameLocalVariable
+class RenameLocalVariable extends SingleFileRefactoring
{
/**
- * @var \QafooLabs\Refactoring\Domain\Services\VariableScanner
+ * @var Variable
*/
- private $variableScanner;
+ private $oldName;
/**
- * @var \QafooLabs\Refactoring\Domain\Services\CodeAnalysis
+ * @var Variable
*/
- private $codeAnalysis;
+ private $newName;
/**
- * @var \QafooLabs\Refactoring\Domain\Services\Editor
+ * @param int $line
*/
- private $editor;
-
- public function __construct(VariableScanner $variableScanner, CodeAnalysis $codeAnalysis, Editor $editor)
- {
- $this->variableScanner = $variableScanner;
- $this->codeAnalysis = $codeAnalysis;
- $this->editor = $editor;
- }
-
public function refactor(File $file, $line, Variable $oldName, Variable $newName)
{
- if ( ! $this->codeAnalysis->isInsideMethod($file, LineRange::fromSingleLine($line))) {
- throw RefactoringException::rangeIsNotInsideMethod(LineRange::fromSingleLine($line));
- }
+ $this->file = $file;
+ $this->line = $line;
+ $this->newName = $newName;
+ $this->oldName = $oldName;
- if ( ! $oldName->isLocal()) {
- throw RefactoringException::variableNotLocal($oldName);
- }
+ $this->assertIsInsideMethod();
- if ( ! $newName->isLocal()) {
- throw RefactoringException::variableNotLocal($newName);
- }
+ $this->assertVariableIsLocal($this->oldName);
+ $this->assertVariableIsLocal($this->newName);
- $selectedMethodLineRange = $this->codeAnalysis->findMethodRange($file, LineRange::fromSingleLine($line));
- $definedVariables = $this->variableScanner->scanForVariables(
- $file, $selectedMethodLineRange
- );
+ $this->startEditingSession();
+ $this->renameLocalVariable();
+ $this->completeEditingSession();
+ }
- if ( ! $definedVariables->contains($oldName)) {
- throw RefactoringException::variableNotInRange($oldName, $selectedMethodLineRange);
+ private function assertVariableIsLocal(Variable $variable)
+ {
+ if ( ! $variable->isLocal()) {
+ throw RefactoringException::variableNotLocal($variable);
}
+ }
- $buffer = $this->editor->openBuffer($file);
+ private function renameLocalVariable()
+ {
+ $definedVariables = $this->getDefinedVariables();
- $session = new EditingSession($buffer);
- $session->replaceString($definedVariables, $oldName, $newName);
+ if ( ! $definedVariables->contains($this->oldName)) {
+ throw RefactoringException::variableNotInRange($this->oldName, $selectedMethodLineRange);
+ }
- $this->editor->save();
+ $this->session->addEdit(new RenameVariable($definedVariables, $this->oldName, $this->newName));
}
}
-
@@ -0,0 +1,85 @@
+<?php
+
+namespace QafooLabs\Refactoring\Application;
+
+use QafooLabs\Refactoring\Domain\Services\VariableScanner;
+use QafooLabs\Refactoring\Domain\Services\CodeAnalysis;
+use QafooLabs\Refactoring\Domain\Services\Editor;
+use QafooLabs\Refactoring\Domain\Model\EditingSession;
+use QafooLabs\Refactoring\Domain\Model\File;
+use QafooLabs\Refactoring\Domain\Model\LineRange;
+
+abstract class SingleFileRefactoring
+{
+ /**
+ * @var VariableScanner
+ */
+ protected $variableScanner;
+
+ /**
+ * @var CodeAnalysis
+ */
+ protected $codeAnalysis;
+
+ /**
+ * @var Editor
+ */
+ protected $editor;
+
+ /**
+ * @var EditingSession
+ */
+ protected $session;
+
+ /**
+ * @var File
+ */
+ protected $file;
+
+ /**
+ * @var int
+ */
+ protected $line;
+
+ public function __construct(
+ VariableScanner $variableScanner,
+ CodeAnalysis $codeAnalysis,
+ Editor $editor
+ ) {
+ $this->variableScanner = $variableScanner;
+ $this->codeAnalysis = $codeAnalysis;
+ $this->editor = $editor;
+ }
+
+ protected function assertIsInsideMethod()
+ {
+ if ( ! $this->codeAnalysis->isInsideMethod($this->file, LineRange::fromSingleLine($this->line))) {
+ throw RefactoringException::rangeIsNotInsideMethod(LineRange::fromSingleLine($this->line));
+ }
+ }
+
+ protected function startEditingSession()
+ {
+ $buffer = $this->editor->openBuffer($this->file);
+
+ $this->session = new EditingSession($buffer);
+ }
+
+ protected function completeEditingSession()
+ {
+ $this->session->performEdits();
+
+ $this->editor->save();
+ }
+
+ protected function getDefinedVariables()
+ {
+ $selectedMethodLineRange = $this->codeAnalysis->findMethodRange($this->file, LineRange::fromSingleLine($this->line));
+
+ $definedVariables = $this->variableScanner->scanForVariables(
+ $this->file, $selectedMethodLineRange
+ );
+
+ return $definedVariables;
+ }
+}
@@ -0,0 +1,8 @@
+<?php
+
+namespace QafooLabs\Refactoring\Domain\Model;
+
+interface EditingAction
+{
+ public function performEdit(EditorBuffer $buffer);
+}
Oops, something went wrong.

0 comments on commit c951cbf

Please sign in to comment.