mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Add way of getting changes in a given file
This commit is contained in:
parent
ff893a3fb2
commit
71b7c70eb1
@ -20,6 +20,7 @@
|
||||
<directory name="src/Psalm/Stubs" />
|
||||
<directory name="tests/stubs" />
|
||||
<file name="vendor/phpunit/phpunit/src/Framework/TestCase.php" />
|
||||
<file name="src/Psalm/Diff/Differ.php" />
|
||||
</ignoreFiles>
|
||||
</projectFiles>
|
||||
|
||||
|
148
src/Psalm/Diff/ClassStatementsDiffer.php
Normal file
148
src/Psalm/Diff/ClassStatementsDiffer.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
namespace Psalm\Diff;
|
||||
|
||||
use PhpParser;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class ClassStatementsDiffer extends Differ
|
||||
{
|
||||
/** @var PhpParser\PrettyPrinter\Standard|null */
|
||||
private static $pretty_printer;
|
||||
|
||||
/**
|
||||
* Calculate diff (edit script) from $a to $b.
|
||||
*
|
||||
* @param PhpParser\Node\Stmt[] $a
|
||||
* @param PhpParser\Node\Stmt[] $b New array
|
||||
*
|
||||
* @return array{0:array<int, string>, 1:array<int, string>}
|
||||
*/
|
||||
public static function diff(string $name, array $a, array $b, string $a_code, string $b_code)
|
||||
{
|
||||
list($trace, $x, $y, $bc) = self::calculateTrace(
|
||||
function (
|
||||
PhpParser\Node\Stmt $a,
|
||||
PhpParser\Node\Stmt $b,
|
||||
string $a_code,
|
||||
string $b_code,
|
||||
bool &$body_change = false
|
||||
) : bool {
|
||||
if (get_class($a) !== get_class($b)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$a_start = (int)$a->getAttribute('startFilePos');
|
||||
$a_end = (int)$a->getAttribute('endFilePos');
|
||||
|
||||
$b_start = (int)$b->getAttribute('startFilePos');
|
||||
$b_end = (int)$b->getAttribute('endFilePos');
|
||||
|
||||
$a_comments_end = $a_start;
|
||||
$b_comments_end = $b_start;
|
||||
|
||||
$a_comments = $a->getComments();
|
||||
$b_comments = $b->getComments();
|
||||
|
||||
$signature_change = false;
|
||||
$body_change = false;
|
||||
|
||||
if ($a_comments) {
|
||||
if (!$b_comments) {
|
||||
$signature_change = true;
|
||||
}
|
||||
|
||||
$a_start = $a_comments[0]->getFilePos();
|
||||
}
|
||||
|
||||
if ($b_comments) {
|
||||
if (!$a_comments) {
|
||||
$signature_change = true;
|
||||
}
|
||||
|
||||
$b_start = $b_comments[0]->getFilePos();
|
||||
}
|
||||
|
||||
$a_size = $a_end - $a_start;
|
||||
$b_size = $b_end - $b_start;
|
||||
|
||||
if (substr($a_code, $a_start, $a_size) === substr($b_code, $b_start, $b_size)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$signature_change
|
||||
&& substr($a_code, $a_start, $a_comments_end - $a_start)
|
||||
!== substr($b_code, $b_start, $b_comments_end - $b_start)
|
||||
) {
|
||||
$signature_change = true;
|
||||
}
|
||||
|
||||
if (!self::$pretty_printer) {
|
||||
self::$pretty_printer = new PhpParser\PrettyPrinter\Standard;
|
||||
}
|
||||
|
||||
if ($a instanceof PhpParser\Node\Stmt\ClassMethod && $b instanceof PhpParser\Node\Stmt\ClassMethod) {
|
||||
if ((string) $a->name !== (string) $b->name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$a_stmts = $a->stmts;
|
||||
$a->stmts = [];
|
||||
$b_stmts = $b->stmts;
|
||||
$b->stmts = [];
|
||||
|
||||
$body_change = $a_stmts !== $b_stmts
|
||||
&& self::$pretty_printer->prettyPrint($a_stmts ?: [])
|
||||
!== self::$pretty_printer->prettyPrint($b_stmts ?: []);
|
||||
$signature_change = $signature_change
|
||||
|| self::$pretty_printer->prettyPrint([$a]) !== self::$pretty_printer->prettyPrint([$b]);
|
||||
|
||||
$a->stmts = $a_stmts;
|
||||
$b->stmts = $b_stmts;
|
||||
} else {
|
||||
$signature_change = $signature_change
|
||||
|| self::$pretty_printer->prettyPrint([$a]) !== self::$pretty_printer->prettyPrint([$b]);
|
||||
}
|
||||
|
||||
return !$signature_change;
|
||||
},
|
||||
$a,
|
||||
$b,
|
||||
$a_code,
|
||||
$b_code
|
||||
);
|
||||
|
||||
$diff = self::extractDiff($trace, $x, $y, $a, $b, $bc);
|
||||
|
||||
$keep = [];
|
||||
$keep_signature = [];
|
||||
|
||||
foreach ($diff as $diff_elem) {
|
||||
if ($diff_elem->type === DiffElem::TYPE_KEEP) {
|
||||
if ($diff_elem->old instanceof PhpParser\Node\Stmt\ClassMethod) {
|
||||
$keep[] = strtolower($name) . '::' . strtolower((string) $diff_elem->old->name);
|
||||
} elseif ($diff_elem->old instanceof PhpParser\Node\Stmt\Property) {
|
||||
foreach ($diff_elem->old->props as $prop) {
|
||||
$keep[] = strtolower($name) . '::$' . $prop->name;
|
||||
}
|
||||
} elseif ($diff_elem->old instanceof PhpParser\Node\Stmt\ClassConst) {
|
||||
foreach ($diff_elem->old->consts as $const) {
|
||||
$keep[] = strtolower($name) . '::' . $const->name;
|
||||
}
|
||||
}
|
||||
} elseif ($diff_elem->type === DiffElem::TYPE_KEEP_SIGNATURE) {
|
||||
if ($diff_elem->old instanceof PhpParser\Node\Stmt\ClassMethod) {
|
||||
$keep_signature[] = strtolower($name) . '::' . strtolower((string) $diff_elem->old->name);
|
||||
} elseif ($diff_elem->old instanceof PhpParser\Node\Stmt\Property) {
|
||||
foreach ($diff_elem->old->props as $prop) {
|
||||
$keep_signature[] = strtolower($name) . '::$' . $prop->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return [$keep, $keep_signature];
|
||||
}
|
||||
}
|
34
src/Psalm/Diff/DiffElem.php
Normal file
34
src/Psalm/Diff/DiffElem.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Psalm\Diff;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class DiffElem
|
||||
{
|
||||
const TYPE_KEEP = 0;
|
||||
const TYPE_REMOVE = 1;
|
||||
const TYPE_ADD = 2;
|
||||
const TYPE_REPLACE = 3;
|
||||
const TYPE_KEEP_SIGNATURE = 4;
|
||||
|
||||
/** @var int One of the TYPE_* constants */
|
||||
public $type;
|
||||
/** @var mixed Is null for add operations */
|
||||
public $old;
|
||||
/** @var mixed Is null for remove operations */
|
||||
public $new;
|
||||
|
||||
/**
|
||||
* @param int $type
|
||||
* @param mixed $old
|
||||
* @param mixed $new
|
||||
*/
|
||||
public function __construct(int $type, $old, $new)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->old = $old;
|
||||
$this->new = $new;
|
||||
}
|
||||
}
|
110
src/Psalm/Diff/Differ.php
Normal file
110
src/Psalm/Diff/Differ.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Psalm\Diff;
|
||||
|
||||
use PhpParser;
|
||||
|
||||
/**
|
||||
* Borrows from https://github.com/nikic/PHP-Parser/blob/master/lib/PhpParser/Internal/Differ.php
|
||||
*
|
||||
* Implements the Myers diff algorithm.
|
||||
*
|
||||
* Myers, Eugene W. "An O (ND) difference algorithm and its variations."
|
||||
* Algorithmica 1.1 (1986): 251-266.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class Differ
|
||||
{
|
||||
/**
|
||||
* @param \Closure $is_equal
|
||||
* @param array $a
|
||||
* @param array $b
|
||||
* @return array{0:array, 1: int, 2: int, 3: array<int, true>}
|
||||
*/
|
||||
protected static function calculateTrace(
|
||||
\Closure $is_equal,
|
||||
array $a,
|
||||
array $b,
|
||||
string $a_code,
|
||||
string $b_code
|
||||
) : array {
|
||||
$n = \count($a);
|
||||
$m = \count($b);
|
||||
$max = $n + $m;
|
||||
$v = [1 => 0];
|
||||
$bc = [];
|
||||
$trace = [];
|
||||
$body_change = false;
|
||||
for ($d = 0; $d <= $max; $d++) {
|
||||
$trace[] = $v;
|
||||
for ($k = -$d; $k <= $d; $k += 2) {
|
||||
if ($k === -$d || ($k !== $d && $v[$k-1] < $v[$k+1])) {
|
||||
$x = $v[$k+1];
|
||||
} else {
|
||||
$x = $v[$k-1] + 1;
|
||||
}
|
||||
|
||||
$y = $x - $k;
|
||||
|
||||
while ($x < $n && $y < $m && ($is_equal)($a[$x], $b[$y], $a_code, $b_code, $body_change)) {
|
||||
$bc[$x] = $body_change;
|
||||
$x++;
|
||||
$y++;
|
||||
}
|
||||
|
||||
$v[$k] = $x;
|
||||
if ($x >= $n && $y >= $m) {
|
||||
return [$trace, $x, $y, $bc];
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new \Exception('Should not happen');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DiffElem[]
|
||||
*/
|
||||
protected static function extractDiff(array $trace, int $x, int $y, array $a, array $b, array $bc) : array
|
||||
{
|
||||
$result = [];
|
||||
for ($d = \count($trace) - 1; $d >= 0; $d--) {
|
||||
$v = $trace[$d];
|
||||
$k = $x - $y;
|
||||
|
||||
if ($k === -$d || ($k !== $d && $v[$k-1] < $v[$k+1])) {
|
||||
$prevK = $k + 1;
|
||||
} else {
|
||||
$prevK = $k - 1;
|
||||
}
|
||||
|
||||
$prevX = $v[$prevK];
|
||||
$prevY = $prevX - $prevK;
|
||||
|
||||
while ($x > $prevX && $y > $prevY) {
|
||||
$result[] = new DiffElem(
|
||||
$bc[$x-1] ? DiffElem::TYPE_KEEP_SIGNATURE : DiffElem::TYPE_KEEP,
|
||||
$a[$x-1],
|
||||
$b[$y-1]
|
||||
);
|
||||
$x--;
|
||||
$y--;
|
||||
}
|
||||
|
||||
if ($d === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
while ($x > $prevX) {
|
||||
$result[] = new DiffElem(DiffElem::TYPE_REMOVE, $a[$x-1], null);
|
||||
$x--;
|
||||
}
|
||||
|
||||
while ($y > $prevY) {
|
||||
$result[] = new DiffElem(DiffElem::TYPE_ADD, null, $b[$y-1]);
|
||||
$y--;
|
||||
}
|
||||
}
|
||||
return array_reverse($result);
|
||||
}
|
||||
}
|
84
src/Psalm/Diff/FileStatementsDiffer.php
Normal file
84
src/Psalm/Diff/FileStatementsDiffer.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace Psalm\Diff;
|
||||
|
||||
use PhpParser;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class FileStatementsDiffer extends Differ
|
||||
{
|
||||
/**
|
||||
* Calculate diff (edit script) from $a to $b.
|
||||
*
|
||||
* @param PhpParser\Node\Stmt[] $a
|
||||
* @param PhpParser\Node\Stmt[] $b New array
|
||||
*
|
||||
* @return array{0:array<int, string>, 1:array<int, string>}
|
||||
*/
|
||||
public static function diff(array $a, array $b, string $a_code, string $b_code)
|
||||
{
|
||||
list($trace, $x, $y, $bc) = self::calculateTrace(
|
||||
function (PhpParser\Node\Stmt $a, PhpParser\Node\Stmt $b, string $a_code, string $b_code) : bool {
|
||||
if (get_class($a) !== get_class($b)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (($a instanceof PhpParser\Node\Stmt\Namespace_ && $b instanceof PhpParser\Node\Stmt\Namespace_)
|
||||
|| ($a instanceof PhpParser\Node\Stmt\Class_ && $b instanceof PhpParser\Node\Stmt\Class_)
|
||||
|| ($a instanceof PhpParser\Node\Stmt\Interface_ && $b instanceof PhpParser\Node\Stmt\Interface_)
|
||||
) {
|
||||
return (string)$a->name === (string)$b->name;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
$a,
|
||||
$b,
|
||||
$a_code,
|
||||
$b_code
|
||||
);
|
||||
|
||||
$diff = self::extractDiff($trace, $x, $y, $a, $b, $bc);
|
||||
|
||||
$keep = [];
|
||||
$keep_signature = [];
|
||||
|
||||
foreach ($diff as $diff_elem) {
|
||||
if ($diff_elem->type === DiffElem::TYPE_KEEP) {
|
||||
if ($diff_elem->old instanceof PhpParser\Node\Stmt\Namespace_
|
||||
&& $diff_elem->new instanceof PhpParser\Node\Stmt\Namespace_
|
||||
) {
|
||||
$namespace_keep = NamespaceStatementsDiffer::diff(
|
||||
(string) $diff_elem->old->name,
|
||||
$diff_elem->old->stmts,
|
||||
$diff_elem->new->stmts,
|
||||
$a_code,
|
||||
$b_code
|
||||
);
|
||||
|
||||
$keep = array_merge($keep, $namespace_keep[0]);
|
||||
$keep_signature = array_merge($keep_signature, $namespace_keep[1]);
|
||||
} elseif (($diff_elem->old instanceof PhpParser\Node\Stmt\Class_
|
||||
&& $diff_elem->new instanceof PhpParser\Node\Stmt\Class_)
|
||||
|| ($diff_elem->old instanceof PhpParser\Node\Stmt\Interface_
|
||||
&& $diff_elem->new instanceof PhpParser\Node\Stmt\Interface_)
|
||||
) {
|
||||
$class_keep = ClassStatementsDiffer::diff(
|
||||
(string) $diff_elem->old->name,
|
||||
$diff_elem->old->stmts,
|
||||
$diff_elem->new->stmts,
|
||||
$a_code,
|
||||
$b_code
|
||||
);
|
||||
|
||||
$keep = array_merge($keep, $class_keep[0]);
|
||||
$keep_signature = array_merge($keep_signature, $class_keep[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [$keep, $keep_signature];
|
||||
}
|
||||
}
|
68
src/Psalm/Diff/NamespaceStatementsDiffer.php
Normal file
68
src/Psalm/Diff/NamespaceStatementsDiffer.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Psalm\Diff;
|
||||
|
||||
use PhpParser;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class NamespaceStatementsDiffer extends Differ
|
||||
{
|
||||
/**
|
||||
* Calculate diff (edit script) from $a to $b.
|
||||
*
|
||||
* @param PhpParser\Node\Stmt[] $a
|
||||
* @param PhpParser\Node\Stmt[] $b New array
|
||||
*
|
||||
* @return array{0:array<int, string>, 1:array<int, string>}
|
||||
*/
|
||||
public static function diff(string $name, array $a, array $b, string $a_code, string $b_code)
|
||||
{
|
||||
list($trace, $x, $y, $bc) = self::calculateTrace(
|
||||
function (PhpParser\Node\Stmt $a, PhpParser\Node\Stmt $b, string $a_code, string $b_code) : bool {
|
||||
if (($a instanceof PhpParser\Node\Stmt\Class_ && $b instanceof PhpParser\Node\Stmt\Class_)
|
||||
|| ($a instanceof PhpParser\Node\Stmt\Interface_ && $b instanceof PhpParser\Node\Stmt\Interface_)
|
||||
) {
|
||||
// @todo add check for comments comparison
|
||||
|
||||
return (string)$a->name === (string)$b->name;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
$a,
|
||||
$b,
|
||||
$a_code,
|
||||
$b_code
|
||||
);
|
||||
|
||||
$diff = self::extractDiff($trace, $x, $y, $a, $b, $bc);
|
||||
|
||||
$keep = [];
|
||||
$keep_signature = [];
|
||||
|
||||
foreach ($diff as $diff_elem) {
|
||||
if ($diff_elem->type === DiffElem::TYPE_KEEP) {
|
||||
if (($diff_elem->old instanceof PhpParser\Node\Stmt\Class_
|
||||
&& $diff_elem->new instanceof PhpParser\Node\Stmt\Class_)
|
||||
|| ($diff_elem->old instanceof PhpParser\Node\Stmt\Interface_
|
||||
&& $diff_elem->new instanceof PhpParser\Node\Stmt\Interface_)
|
||||
) {
|
||||
$class_keep = ClassStatementsDiffer::diff(
|
||||
($name ? $name . '\\' : '') . $diff_elem->old->name,
|
||||
$diff_elem->old->stmts,
|
||||
$diff_elem->new->stmts,
|
||||
$a_code,
|
||||
$b_code
|
||||
);
|
||||
|
||||
$keep = array_merge($keep, $class_keep[0]);
|
||||
$keep_signature = array_merge($keep_signature, $class_keep[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [$keep, $keep_signature];
|
||||
}
|
||||
}
|
547
tests/FileDiffTest.php
Normal file
547
tests/FileDiffTest.php
Normal file
@ -0,0 +1,547 @@
|
||||
<?php
|
||||
namespace Psalm\Tests;
|
||||
|
||||
class FileDiffTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider getChanges
|
||||
*
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
* @param string[] $same_methods
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCode(string $a, string $b, array $same_methods, array $same_signatures = [])
|
||||
{
|
||||
if (strpos($this->getTestName(), 'SKIPPED-') !== false) {
|
||||
$this->markTestSkipped();
|
||||
}
|
||||
|
||||
$a_stmts = \Psalm\Provider\StatementsProvider::parseStatements($a);
|
||||
$b_stmts = \Psalm\Provider\StatementsProvider::parseStatements($b);
|
||||
|
||||
$diff = \Psalm\Diff\FileStatementsDiffer::diff($a_stmts, $b_stmts, $a, $b);
|
||||
|
||||
$this->assertSame(
|
||||
$same_methods,
|
||||
$diff[0]
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
$same_signatures,
|
||||
$diff[1]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getChanges()
|
||||
{
|
||||
return [
|
||||
'sameFile' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public $aB = 5;
|
||||
|
||||
const F = 1;
|
||||
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public $aB = 5;
|
||||
|
||||
const F = 1;
|
||||
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
['foo\a::$aB', 'foo\a::F', 'foo\a::foo', 'foo\a::bar']
|
||||
],
|
||||
'simpleBodyChange' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 2;
|
||||
}
|
||||
}',
|
||||
['foo\a::foo'],
|
||||
['foo\a::bar']
|
||||
],
|
||||
'simpleBodyChangeWithSignatureChange' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar(string $a) {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
['foo\a::foo'],
|
||||
[]
|
||||
],
|
||||
'propertyChange' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public $a;
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public $b;
|
||||
}',
|
||||
[]
|
||||
],
|
||||
'propertyDefaultChange' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public $a = 1;
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public $a = 2;
|
||||
}',
|
||||
[]
|
||||
],
|
||||
'propertyDefaultAddition' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public $a;
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public $a = 2;
|
||||
}',
|
||||
[]
|
||||
],
|
||||
'propertySignatureChange' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
/** @var ?string */
|
||||
public $a;
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
/** @var ?int */
|
||||
public $a;
|
||||
}',
|
||||
[]
|
||||
],
|
||||
'addDocblock' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 2;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function bar() {
|
||||
$b = 2;
|
||||
}
|
||||
}',
|
||||
['foo\a::foo']
|
||||
],
|
||||
'removeDocblock' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function bar() {
|
||||
$b = 2;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 2;
|
||||
}
|
||||
}',
|
||||
['foo\a::foo']
|
||||
],
|
||||
'changeDocblock' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function bar() {
|
||||
$b = 2;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function bar() {
|
||||
$b = 2;
|
||||
}
|
||||
}',
|
||||
['foo\a::foo']
|
||||
],
|
||||
'removeFunctionAtEnd' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
public function bat() {
|
||||
$c = 1;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
['foo\a::foo', 'foo\a::bar']
|
||||
],
|
||||
'removeFunctionAtBeginning' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
public function bat() {
|
||||
$c = 1;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
public function bat() {
|
||||
$c = 1;
|
||||
}
|
||||
}',
|
||||
['foo\a::bar', 'foo\a::bat']
|
||||
],
|
||||
'removeFunctionInMiddle' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
public function bat() {
|
||||
$c = 1;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bat() {
|
||||
$c = 1;
|
||||
}
|
||||
}',
|
||||
['foo\a::foo', 'foo\a::bat']
|
||||
],
|
||||
'changeNamespace' => [
|
||||
'<?php
|
||||
namespace Bar;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function bar() {
|
||||
$b = 2;
|
||||
}
|
||||
}',
|
||||
[]
|
||||
],
|
||||
'removeNamespace' => [
|
||||
'<?php
|
||||
namespace Bar;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
class A {
|
||||
public function bar() {
|
||||
$b = 2;
|
||||
}
|
||||
}',
|
||||
[],
|
||||
],
|
||||
'newFunctionAtEnd' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
public function bat() {
|
||||
$c = 1;
|
||||
}
|
||||
}',
|
||||
['foo\a::foo', 'foo\a::bar']
|
||||
],
|
||||
'newFunctionAtBeginning' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function bat() {
|
||||
$c = 1;
|
||||
}
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
['foo\a::foo', 'foo\a::bar']
|
||||
],
|
||||
'newFunctionInMiddle' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bat() {
|
||||
$c = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
['foo\a::foo', 'foo\a::bar']
|
||||
],
|
||||
'whiteSpaceOnly' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function foo() {
|
||||
$a = 1;
|
||||
}
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
}
|
||||
}',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
class A {
|
||||
public function foo() {
|
||||
|
||||
$a = 1 ;
|
||||
}
|
||||
|
||||
public function bar() {
|
||||
$b = 1;
|
||||
|
||||
}
|
||||
}',
|
||||
['foo\a::foo', 'foo\a::bar']
|
||||
],
|
||||
'changeDeclaredMethodId' => [
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function __construct() {}
|
||||
public static function bar() : void {}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
public static function bat() : void {}
|
||||
}
|
||||
|
||||
class C extends B { }',
|
||||
'<?php
|
||||
namespace Foo;
|
||||
|
||||
class A {
|
||||
public function __construct() {}
|
||||
public static function bar() : void {}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
public function __construct() {}
|
||||
public static function bar() : void {}
|
||||
public static function bat() : void {}
|
||||
}
|
||||
|
||||
class C extends B { }',
|
||||
['foo\a::__construct', 'foo\a::bar', 'foo\b::bat']
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user