Skip to content
This repository was archived by the owner on Jul 12, 2020. It is now read-only.

Commit bc9285c

Browse files
author
Tom Oram
committed
Break EditingSession down into individual editing action classes.
1 parent 21027f3 commit bc9285c

28 files changed

+1905
-258
lines changed

src/main/QafooLabs/Refactoring/Application/ConvertLocalToInstanceVariable.php

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,56 +13,50 @@
1313
use QafooLabs\Refactoring\Domain\Services\VariableScanner;
1414
use QafooLabs\Refactoring\Domain\Services\CodeAnalysis;
1515
use QafooLabs\Refactoring\Domain\Services\Editor;
16+
use QafooLabs\Refactoring\Domain\Model\EditingAction\AddProperty;
17+
use QafooLabs\Refactoring\Domain\Model\EditingAction\LocalVariableToInstance;
1618

17-
class ConvertLocalToInstanceVariable
19+
class ConvertLocalToInstanceVariable extends SingleFileRefactoring
1820
{
1921
/**
20-
* @var \QafooLabs\Refactoring\Domain\Services\VariableScanner
22+
* @var Variable
2123
*/
22-
private $variableScanner;
24+
private $convertVariable;
2325

2426
/**
25-
* @var \QafooLabs\Refactoring\Domain\Services\CodeAnalysis
27+
* @param int $line
2628
*/
27-
private $codeAnalysis;
29+
public function refactor(File $file, $line, Variable $convertVariable)
30+
{
31+
$this->file = $file;
32+
$this->line = $line;
33+
$this->convertVariable = $convertVariable;
2834

29-
/**
30-
* @var \QafooLabs\Refactoring\Domain\Services\Editor
31-
*/
32-
private $editor;
35+
$this->assertIsInsideMethod();
3336

34-
public function __construct(VariableScanner $variableScanner, CodeAnalysis $codeAnalysis, Editor $editor)
35-
{
36-
$this->variableScanner = $variableScanner;
37-
$this->codeAnalysis = $codeAnalysis;
38-
$this->editor = $editor;
37+
$this->startEditingSession();
38+
$this->addProperty();
39+
$this->convertVariablesToInstanceVariables();
40+
$this->completeEditingSession();
3941
}
4042

41-
public function refactor(File $file, $line, Variable $convertVariable)
43+
private function addProperty()
4244
{
43-
if ( ! $this->codeAnalysis->isInsideMethod($file, LineRange::fromSingleLine($line))) {
44-
throw RefactoringException::rangeIsNotInsideMethod(LineRange::fromSingleLine($line));
45-
}
45+
$line = $this->codeAnalysis->getLineOfLastPropertyDefinedInScope($this->file, $this->line);
4646

47-
$instanceVariable = $convertVariable->convertToInstance();
48-
$lastPropertyLine = $this->codeAnalysis->getLineOfLastPropertyDefinedInScope($file, $line);
49-
50-
$selectedMethodLineRange = $this->codeAnalysis->findMethodRange($file, LineRange::fromSingleLine($line));
51-
$definedVariables = $this->variableScanner->scanForVariables(
52-
$file, $selectedMethodLineRange
47+
$this->session->addEdit(
48+
new AddProperty($line, $this->convertVariable->getName())
5349
);
50+
}
5451

55-
if ( ! $definedVariables->contains($convertVariable)) {
56-
throw RefactoringException::variableNotInRange($convertVariable, $selectedMethodLineRange);
57-
}
58-
59-
$buffer = $this->editor->openBuffer($file);
52+
private function convertVariablesToInstanceVariables()
53+
{
54+
$definedVariables = $this->getDefinedVariables();
6055

61-
$session = new EditingSession($buffer);
62-
$session->addProperty($lastPropertyLine, $convertVariable->getName());
63-
$session->replaceString($definedVariables, $convertVariable, $instanceVariable);
56+
if ( ! $definedVariables->contains($this->convertVariable)) {
57+
throw RefactoringException::variableNotInRange($this->convertVariable, $selectedMethodLineRange);
58+
}
6459

65-
$this->editor->save();
60+
$this->session->addEdit(new LocalVariableToInstance($definedVariables, $this->convertVariable));
6661
}
6762
}
68-

src/main/QafooLabs/Refactoring/Application/ExtractMethod.php

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,60 +11,91 @@
1111
use QafooLabs\Refactoring\Domain\Services\VariableScanner;
1212
use QafooLabs\Refactoring\Domain\Services\CodeAnalysis;
1313
use QafooLabs\Refactoring\Domain\Services\Editor;
14+
use QafooLabs\Refactoring\Domain\Model\LineCollection;
15+
use QafooLabs\Refactoring\Domain\Model\EditingAction\AddMethod;
16+
use QafooLabs\Refactoring\Domain\Model\EditingAction\ReplaceWithMethodCall;
1417

1518
/**
1619
* Extract Method Refactoring
1720
*/
18-
class ExtractMethod
21+
class ExtractMethod extends SingleFileRefactoring
1922
{
2023
/**
21-
* @var \QafooLabs\Refactoring\Domain\Services\VariableScanner
24+
* @var LineRange
2225
*/
23-
private $variableScanner;
26+
private $extractRange;
2427

2528
/**
26-
* @var \QafooLabs\Refactoring\Domain\Services\CodeAnalysis
29+
* @var MethodSignature
2730
*/
28-
private $codeAnalysis;
31+
private $newMethod;
2932

3033
/**
31-
* @var \QafooLabs\Refactoring\Domain\Services\Editor
34+
* @param string $newMethodName
3235
*/
33-
private $editor;
34-
35-
public function __construct(VariableScanner $variableScanner, CodeAnalysis $codeAnalysis, Editor $editor)
36+
public function refactor(File $file, LineRange $extractRange, $newMethodName)
3637
{
37-
$this->variableScanner = $variableScanner;
38-
$this->codeAnalysis = $codeAnalysis;
39-
$this->editor = $editor;
38+
$this->file = $file;
39+
$this->extractRange = $extractRange;
40+
41+
$this->assertIsInsideMethod();
42+
43+
$this->createNewMethodSignature($newMethodName);
44+
45+
$this->startEditingSession();
46+
$this->replaceCodeWithMethodCall();
47+
$this->addNewMethod();
48+
$this->completeEditingSession();
4049
}
4150

42-
public function refactor(File $file, LineRange $extractRange, $newMethodName)
51+
protected function assertIsInsideMethod()
4352
{
44-
if ( ! $this->codeAnalysis->isInsideMethod($file, $extractRange)) {
45-
throw RefactoringException::rangeIsNotInsideMethod($extractRange);
53+
if ( ! $this->codeAnalysis->isInsideMethod($this->file, $this->extractRange)) {
54+
throw RefactoringException::rangeIsNotInsideMethod($this->extractRange);
4655
}
56+
}
4757

48-
$isStatic = $this->codeAnalysis->isMethodStatic($file, $extractRange);
49-
$methodRange = $this->codeAnalysis->findMethodRange($file, $extractRange);
50-
$selectedCode = $extractRange->sliceCode($file->getCode());
51-
52-
$extractVariables = $this->variableScanner->scanForVariables($file, $extractRange);
53-
$methodVariables = $this->variableScanner->scanForVariables($file, $methodRange);
58+
private function createNewMethodSignature($newMethodName)
59+
{
60+
$extractVariables = $this->variableScanner->scanForVariables($this->file, $this->extractRange);
61+
$methodVariables = $this->variableScanner->scanForVariables($this->file, $this->findMethodRange());
5462

55-
$buffer = $this->editor->openBuffer($file);
63+
$isStatic = $this->codeAnalysis->isMethodStatic($this->file, $this->extractRange);
5664

57-
$newMethod = new MethodSignature(
65+
$this->newMethod = new MethodSignature(
5866
$newMethodName,
5967
$isStatic ? MethodSignature::IS_STATIC : 0,
6068
$methodVariables->variablesFromSelectionUsedBefore($extractVariables),
6169
$methodVariables->variablesFromSelectionUsedAfter($extractVariables)
6270
);
71+
}
6372

64-
$session = new EditingSession($buffer);
65-
$session->replaceRangeWithMethodCall($extractRange, $newMethod);
66-
$session->addMethod($methodRange->getEnd(), $newMethod, $selectedCode);
73+
private function addNewMethod()
74+
{
75+
$this->session->addEdit(new AddMethod(
76+
$this->findMethodRange()->getEnd(),
77+
$this->newMethod,
78+
$this->getSelectedCode()
79+
));
80+
}
81+
82+
private function replaceCodeWithMethodCall()
83+
{
84+
$this->session->addEdit(new ReplaceWithMethodCall(
85+
$this->extractRange,
86+
$this->newMethod
87+
));
88+
}
6789

68-
$this->editor->save();
90+
private function findMethodRange()
91+
{
92+
return $this->codeAnalysis->findMethodRange($this->file, $this->extractRange);
93+
}
94+
95+
private function getSelectedCode()
96+
{
97+
return LineCollection::createFromArray(
98+
$this->extractRange->sliceCode($this->file->getCode())
99+
);
69100
}
70101
}

src/main/QafooLabs/Refactoring/Application/RenameLocalVariable.php

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,63 +12,58 @@
1212
use QafooLabs\Refactoring\Domain\Services\VariableScanner;
1313
use QafooLabs\Refactoring\Domain\Services\CodeAnalysis;
1414
use QafooLabs\Refactoring\Domain\Services\Editor;
15+
use QafooLabs\Refactoring\Domain\Model\EditingAction\RenameVariable;
1516

1617
/**
1718
* Rename Local Variable Refactoring
1819
*/
19-
class RenameLocalVariable
20+
class RenameLocalVariable extends SingleFileRefactoring
2021
{
2122
/**
22-
* @var \QafooLabs\Refactoring\Domain\Services\VariableScanner
23+
* @var Variable
2324
*/
24-
private $variableScanner;
25+
private $oldName;
2526

2627
/**
27-
* @var \QafooLabs\Refactoring\Domain\Services\CodeAnalysis
28+
* @var Variable
2829
*/
29-
private $codeAnalysis;
30+
private $newName;
3031

3132
/**
32-
* @var \QafooLabs\Refactoring\Domain\Services\Editor
33+
* @param int $line
3334
*/
34-
private $editor;
35-
36-
public function __construct(VariableScanner $variableScanner, CodeAnalysis $codeAnalysis, Editor $editor)
37-
{
38-
$this->variableScanner = $variableScanner;
39-
$this->codeAnalysis = $codeAnalysis;
40-
$this->editor = $editor;
41-
}
42-
4335
public function refactor(File $file, $line, Variable $oldName, Variable $newName)
4436
{
45-
if ( ! $this->codeAnalysis->isInsideMethod($file, LineRange::fromSingleLine($line))) {
46-
throw RefactoringException::rangeIsNotInsideMethod(LineRange::fromSingleLine($line));
47-
}
37+
$this->file = $file;
38+
$this->line = $line;
39+
$this->newName = $newName;
40+
$this->oldName = $oldName;
4841

49-
if ( ! $oldName->isLocal()) {
50-
throw RefactoringException::variableNotLocal($oldName);
51-
}
42+
$this->assertIsInsideMethod();
5243

53-
if ( ! $newName->isLocal()) {
54-
throw RefactoringException::variableNotLocal($newName);
55-
}
44+
$this->assertVariableIsLocal($this->oldName);
45+
$this->assertVariableIsLocal($this->newName);
5646

57-
$selectedMethodLineRange = $this->codeAnalysis->findMethodRange($file, LineRange::fromSingleLine($line));
58-
$definedVariables = $this->variableScanner->scanForVariables(
59-
$file, $selectedMethodLineRange
60-
);
47+
$this->startEditingSession();
48+
$this->renameLocalVariable();
49+
$this->completeEditingSession();
50+
}
6151

62-
if ( ! $definedVariables->contains($oldName)) {
63-
throw RefactoringException::variableNotInRange($oldName, $selectedMethodLineRange);
52+
private function assertVariableIsLocal(Variable $variable)
53+
{
54+
if ( ! $variable->isLocal()) {
55+
throw RefactoringException::variableNotLocal($variable);
6456
}
57+
}
6558

66-
$buffer = $this->editor->openBuffer($file);
59+
private function renameLocalVariable()
60+
{
61+
$definedVariables = $this->getDefinedVariables();
6762

68-
$session = new EditingSession($buffer);
69-
$session->replaceString($definedVariables, $oldName, $newName);
63+
if ( ! $definedVariables->contains($this->oldName)) {
64+
throw RefactoringException::variableNotInRange($this->oldName, $selectedMethodLineRange);
65+
}
7066

71-
$this->editor->save();
67+
$this->session->addEdit(new RenameVariable($definedVariables, $this->oldName, $this->newName));
7268
}
7369
}
74-
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
namespace QafooLabs\Refactoring\Application;
4+
5+
use QafooLabs\Refactoring\Domain\Services\VariableScanner;
6+
use QafooLabs\Refactoring\Domain\Services\CodeAnalysis;
7+
use QafooLabs\Refactoring\Domain\Services\Editor;
8+
use QafooLabs\Refactoring\Domain\Model\EditingSession;
9+
use QafooLabs\Refactoring\Domain\Model\File;
10+
use QafooLabs\Refactoring\Domain\Model\LineRange;
11+
12+
abstract class SingleFileRefactoring
13+
{
14+
/**
15+
* @var VariableScanner
16+
*/
17+
protected $variableScanner;
18+
19+
/**
20+
* @var CodeAnalysis
21+
*/
22+
protected $codeAnalysis;
23+
24+
/**
25+
* @var Editor
26+
*/
27+
protected $editor;
28+
29+
/**
30+
* @var EditingSession
31+
*/
32+
protected $session;
33+
34+
/**
35+
* @var File
36+
*/
37+
protected $file;
38+
39+
/**
40+
* @var int
41+
*/
42+
protected $line;
43+
44+
public function __construct(
45+
VariableScanner $variableScanner,
46+
CodeAnalysis $codeAnalysis,
47+
Editor $editor
48+
) {
49+
$this->variableScanner = $variableScanner;
50+
$this->codeAnalysis = $codeAnalysis;
51+
$this->editor = $editor;
52+
}
53+
54+
protected function assertIsInsideMethod()
55+
{
56+
if ( ! $this->codeAnalysis->isInsideMethod($this->file, LineRange::fromSingleLine($this->line))) {
57+
throw RefactoringException::rangeIsNotInsideMethod(LineRange::fromSingleLine($this->line));
58+
}
59+
}
60+
61+
protected function startEditingSession()
62+
{
63+
$buffer = $this->editor->openBuffer($this->file);
64+
65+
$this->session = new EditingSession($buffer);
66+
}
67+
68+
protected function completeEditingSession()
69+
{
70+
$this->session->performEdits();
71+
72+
$this->editor->save();
73+
}
74+
75+
protected function getDefinedVariables()
76+
{
77+
$selectedMethodLineRange = $this->codeAnalysis->findMethodRange($this->file, LineRange::fromSingleLine($this->line));
78+
79+
$definedVariables = $this->variableScanner->scanForVariables(
80+
$this->file, $selectedMethodLineRange
81+
);
82+
83+
return $definedVariables;
84+
}
85+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace QafooLabs\Refactoring\Domain\Model;
4+
5+
interface EditingAction
6+
{
7+
public function performEdit(EditorBuffer $buffer);
8+
}

0 commit comments

Comments
 (0)