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

Commit 7d07f9d

Browse files
committed
Finished prototype of refactoring rename local variable.
1 parent 78ee890 commit 7d07f9d

File tree

12 files changed

+164
-5
lines changed

12 files changed

+164
-5
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ The refactoring browser is used with:
2020
List of Refactorings to implement:
2121

2222
* Extract Method (Prototype Done)
23-
* Rename Local Variable
23+
* Rename Local Variable (Prototype Done)
2424
* Rename Method
2525
* Private Methods Only first
2626
* Rename Instance Variable

features/bootstrap/FeatureContext.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public function iUseRefactoringWith($refactoringName, TableNode $table)
6464
if (isset($data['file'])) {
6565
$data['file'] = vfsStream::url('project/' . $data['file']);
6666
}
67+
$data['--verbose'] = true;
6768

6869
$fh = fopen("php://memory", "rw");
6970
$input = new ArrayInput($data);
@@ -82,6 +83,9 @@ public function iUseRefactoringWith($refactoringName, TableNode $table)
8283
*/
8384
public function thePhpFileShouldBeRefactored($file, PyStringNode $expectedPatch)
8485
{
85-
assertEquals(rtrim((string)$expectedPatch), rtrim($this->output), "Refactored File:\n" . rtrim($this->output));
86+
$output = implode("\n", array_map('trim', explode("\n", rtrim($this->output))));
87+
$expectedPatch = implode("\n", array_map('trim', explode("\n", rtrim((string)$expectedPatch))));
88+
89+
assertEquals($expectedPatch, $output, "Refactored File:\n" . $output);
8690
}
8791
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace QafooLabs\Patches;
4+
5+
class ChangeTokenOperation implements Operation
6+
{
7+
private $originalLine;
8+
private $oldToken;
9+
private $newToken;
10+
11+
public function __construct($originalLine, $oldToken, $newToken)
12+
{
13+
$this->originalLine = $originalLine;
14+
$this->oldToken = $oldToken;
15+
$this->newToken = $newToken;
16+
}
17+
18+
public function perform(Hunk $hunk)
19+
{
20+
return $hunk->changeToken($this->originalLine, $this->oldToken, $this->newToken);
21+
}
22+
}

src/main/QafooLabs/Patches/Hunk.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,27 @@ public function changeLines($originalLine, array $newLines)
159159
));
160160
}
161161

162+
public function changeToken($originalLine, $oldToken, $newToken)
163+
{
164+
$relativeLine = $this->getRelativeLine($originalLine);
165+
$beforeLines = array_slice($this->lines, 0, $relativeLine);
166+
$afterLines = array_slice($this->lines, $relativeLine + 1);
167+
168+
$newLine = substr($this->lines[$relativeLine], 1);
169+
$newLine = preg_replace(
170+
'(([^a-zA-Z0-9]?)(' . preg_quote($oldToken) . ')([^[a-zA-Z0-9]?))',
171+
'\1' . $newToken . '\3',
172+
$newLine
173+
);
174+
175+
return $this->newLines(array_merge(
176+
$beforeLines,
177+
array('-' . substr($this->lines[$relativeLine], 1)),
178+
array('+' . $newLine),
179+
$afterLines
180+
));
181+
}
182+
162183
private function newLines(array $newLines)
163184
{
164185
return new Hunk($this->before, $this->after, $newLines, $this->start, $this->size);

src/main/QafooLabs/Patches/Operation.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,12 @@
44

55
interface Operation
66
{
7+
/**
8+
* Perform opertaion on the hunk and return a new modified hunk.
9+
*
10+
* @param Hunk $hunk
11+
*
12+
* @return Hunk
13+
*/
714
public function perform(Hunk $hunk);
815
}

src/main/QafooLabs/Patches/PatchBuilder.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,22 @@ public function __construct($contents)
3131
}
3232
}
3333

34+
/**
35+
* Change Token in given line from old to new.
36+
*
37+
* @param int $originalLine
38+
* @param string $oldToken
39+
* @param string $newToken
40+
*
41+
* @return void
42+
*/
43+
public function changeToken($originalLine, $oldToken, $newToken)
44+
{
45+
$this->assertValidOriginalLine($originalLine);
46+
47+
$this->operations[$originalLine] = new ChangeTokenOperation($originalLine, $oldToken, $newToken);
48+
}
49+
3450
/**
3551
* Append new lines to an original line of the file.
3652
*
@@ -166,7 +182,7 @@ private function getLineGroups()
166182
$currentLineGroup = array(array_shift($affectedLines));
167183

168184
foreach ($affectedLines as $affectedLine) {
169-
if ($affectedLine - max($currentLineGroup) < 3) {
185+
if ($affectedLine - max($currentLineGroup) < 4) {
170186
$currentLineGroup[] = $affectedLine;
171187
} else {
172188
$lineGroups[] = $currentLineGroup;

src/main/QafooLabs/Refactoring/Adapters/PHPParser/Visitor/LocalVariableClassifier.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ public function getUsedLocalVariables()
6363

6464
public function getAssignments()
6565
{
66-
return $this->assignments;
66+
$assignments = $this->assignments;
67+
68+
foreach ($this->localVariables as $localVariable => $lines) {
69+
if (isset($assignments[$localVariable])) {
70+
$assignments[$localVariable] = array_unique($lines);
71+
}
72+
}
73+
74+
return $assignments;
6775
}
6876
}

src/main/QafooLabs/Refactoring/Adapters/Patches/PatchBuffer.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,9 @@ public function append($line, array $newLines)
2727
{
2828
$this->builder->appendToLine($line, $newLines);
2929
}
30+
31+
public function replaceString($line, $oldToken, $newToken)
32+
{
33+
$this->builder->changeToken($line, $oldToken, $newToken);
34+
}
3035
}

src/main/QafooLabs/Refactoring/Adapters/Symfony/Commands/RenameLocalVariableCommand.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010

1111
use QafooLabs\Refactoring\Domain\Model\File;
1212

13+
use QafooLabs\Refactoring\Application\RenameLocalVariable;
14+
use QafooLabs\Refactoring\Adapters\PHPParser\ParserVariableScanner;
15+
use QafooLabs\Refactoring\Adapters\TokenReflection\StaticCodeAnalysis;
16+
use QafooLabs\Refactoring\Adapters\Patches\PatchEditor;
17+
use QafooLabs\Refactoring\Adapters\Symfony\OutputPatchCommand;
18+
1319
class RenameLocalVariableCommand extends Command
1420
{
1521
protected function configure()
@@ -27,8 +33,15 @@ protected function configure()
2733
protected function execute(InputInterface $input, OutputInterface $output)
2834
{
2935
$file = File::createFromPath($input->getArgument('file'), getcwd());
30-
$line = $input->getArgument('line');
36+
$line = (int)$input->getArgument('line');
3137
$name = $input->getArgument('name');
3238
$newName = $input->getArgument('new-name');
39+
40+
$scanner = new ParserVariableScanner();
41+
$codeAnalysis = new StaticCodeAnalysis();
42+
$editor = new PatchEditor(new OutputPatchCommand($output));
43+
44+
$renameLocalVariable = new RenameLocalVariable($scanner, $codeAnalysis, $editor);
45+
$renameLocalVariable->refactor($file, $line, $name, $newName);
3346
}
3447
}

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,32 @@ public function __construct(VariableScanner $variableScanner, CodeAnalysis $code
3838

3939
public function refactor(File $file, $line, $oldName, $newName)
4040
{
41+
$oldName = ltrim($oldName, '$');
42+
$newName = ltrim($newName, '$');
43+
4144
$methodRange = $this->findMethodRange($file, $line);
4245
$declaredVariables = $this->variableScanner->scanForVariables($file, $methodRange);
4346

47+
if ( ! isset($declaredVariables->localVariables[$oldName]) &&
48+
! isset($declaredVariables->assignments[$oldName])) {
49+
50+
return;
51+
}
52+
4453
$buffer = $this->editor->openBuffer($file);
4554

55+
if (isset($declaredVariables->localVariables[$oldName])) {
56+
foreach ($declaredVariables->localVariables[$oldName] as $line) {
57+
$buffer->replaceString($line, '$' . $oldName, '$' . $newName);
58+
}
59+
}
60+
61+
if (isset($declaredVariables->assignments[$oldName])) {
62+
foreach ($declaredVariables->assignments[$oldName] as $line) {
63+
$buffer->replaceString($line, '$' . $oldName, '$' . $newName);
64+
}
65+
}
66+
4667
$this->editor->save();
4768
}
4869

src/main/QafooLabs/Refactoring/Domain/Model/EditorBuffer.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,35 @@
77
*/
88
interface EditorBuffer
99
{
10+
/**
11+
* Replace LineRange with new lines.
12+
*
13+
* @param LineRange $range
14+
* @param array $newLines
15+
*
16+
* @return void
17+
*/
1018
public function replace(LineRange $range, array $newLines);
19+
20+
/**
21+
* Append new lines to a given line.
22+
*
23+
* @param integer $line
24+
* @param array $newLines
25+
*
26+
* @return void
27+
*/
1128
public function append($line, array $newLines);
29+
30+
/**
31+
* Replace a token in in a line with another token.
32+
*
33+
* @param integer $line
34+
* @param string $oldToken
35+
* @param string $newToken
36+
*
37+
* @return void
38+
*/
39+
public function replaceString($line, $oldToken, $newToken);
1240
}
41+

src/test/QafooLabs/Patches/HunkTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,17 @@ public function testForLinesAppend()
132132
HUNK
133133
, (string)$hunk);
134134
}
135+
136+
public function testChangeToken()
137+
{
138+
$hunk = Hunk::forLine(1, array('$foo = $foo;'));
139+
$newHunk = $hunk->changeToken(1, '$foo', '$bar');
140+
141+
$this->assertEquals(<<<'HUNK'
142+
@@ -1,1 +1,1 @@
143+
-$foo = $foo;
144+
+$bar = $bar;
145+
HUNK
146+
, (string)$newHunk);
147+
}
135148
}

0 commit comments

Comments
 (0)