Skip to content

Commit 24af332

Browse files
committed
implement Analyze.
1 parent 276c66e commit 24af332

11 files changed

+232
-70
lines changed

src/Analyze/AnalysisResult.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Smeghead\PhpVariableHardUsage\Analyze;
6+
7+
final class AnalysisResult
8+
{
9+
public readonly int $maxVariableHardUsage;
10+
public readonly float $avarageVariableHardUsage;
11+
12+
/**
13+
* @param list<Scope> $scopes
14+
*/
15+
public function __construct(
16+
public readonly array $scopes
17+
)
18+
{
19+
$maxVariableHardUsage = 0;
20+
$avarageVariableHardUsage = 0;
21+
foreach ($scopes as $scope) {
22+
foreach ($scope->getAnalyzedVariables() as $analyzedVariable) {
23+
$maxVariableHardUsage = max($maxVariableHardUsage, $analyzedVariable->variableHardUsage);
24+
$avarageVariableHardUsage += $analyzedVariable->variableHardUsage;
25+
}
26+
}
27+
$this->maxVariableHardUsage = $maxVariableHardUsage;
28+
$this->avarageVariableHardUsage = $avarageVariableHardUsage / count($scopes);
29+
}
30+
}

src/Analyze/AnalyzedVariable.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Smeghead\PhpVariableHardUsage\Analyze;
6+
7+
final class AnalyzedVariable
8+
{
9+
public function __construct(
10+
public readonly string $name,
11+
public readonly int $variableHardUsage
12+
)
13+
{
14+
}
15+
}

src/Analyze/FunctionScope.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Smeghead\PhpVariableHardUsage\Analyze;
6+
7+
final class FunctionScope implements Scope
8+
{
9+
private array $analyzedVariables;
10+
11+
public function __construct(private string $name, array $analyzedVariables)
12+
{
13+
$this->analyzedVariables = $analyzedVariables;
14+
}
15+
16+
public function getName(): string
17+
{
18+
return $this->name;
19+
}
20+
21+
/**
22+
* @return list<AlalyzedVariable>
23+
*/
24+
public function getAnalyzedVariables(): array
25+
{
26+
return $this->analyzedVariables;
27+
}
28+
}

src/Analyze/Scope.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Smeghead\PhpVariableHardUsage\Analyze;
6+
7+
interface Scope
8+
{
9+
public function getName(): string;
10+
11+
/**
12+
* @return list<AnalyzedVariable>
13+
*/
14+
public function getAnalyzedVariables(): array;
15+
}

src/Analyze/VariableAnalyzer.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Smeghead\PhpVariableHardUsage\Analyze;
6+
7+
use Smeghead\PhpVariableHardUsage\Parse\Func;
8+
9+
final class VariableAnalyzer
10+
{
11+
private array $functions;
12+
13+
/**
14+
* @param array<Func> $functions
15+
*/
16+
public function __construct(array $functions)
17+
{
18+
$this->functions = $functions;
19+
}
20+
21+
public function analyze(): AnalysisResult
22+
{
23+
return new AnalysisResult(array_map(fn($f) => $this->analyzeFunction($f), $this->functions));
24+
}
25+
26+
private function analyzeFunction(Func $function): Scope
27+
{
28+
$variables = $function->getVariables();
29+
$variableNames = array_unique(array_map(fn($variable) => $variable->name, $variables));
30+
31+
$analyzedVars = [];
32+
33+
foreach ($variableNames as $variableName) {
34+
$vars = array_filter($variables, fn($variable) => $variable->name === $variableName);
35+
$variableHardUsage = $this->calc($vars);
36+
$analyzedVars[] = new AnalyzedVariable($variableName, $variableHardUsage);
37+
}
38+
39+
return new FunctionScope($function->name, $analyzedVars);
40+
}
41+
42+
private function calc(array $vars): int
43+
{
44+
$lineNumbers = array_map(fn($var) => $var->lineNumber, $vars);
45+
$avarageLinuNumber = intval(array_sum($lineNumbers) / count($lineNumbers));
46+
$variableHardUsage = array_sum(array_map(fn($lineNumber) => abs($lineNumber - $avarageLinuNumber), $lineNumbers));
47+
return $variableHardUsage;
48+
}
49+
}

src/Parse/Func.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,12 @@
66

77
final class Func
88
{
9-
private string $name;
109
/** @var list<VarReference> */
1110
private array $variables;
1211

13-
public function __construct(string $name)
12+
public function __construct(public readonly string $name)
1413
{
15-
$this->name = $name;
16-
}
17-
18-
public function getName(): string
19-
{
20-
return $this->name;
14+
$this->variables = [];
2115
}
2216

2317
/**

src/Parse/ParseResult.php

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,10 @@
66

77
final class ParseResult
88
{
9-
/** @var list<Func> */
10-
private array $functions;
11-
129
/**
1310
* @param array<Func> $functions
1411
*/
15-
public function __construct(array $functions)
16-
{
17-
$this->functions = $functions;
18-
}
19-
20-
/**
21-
* @return array<Valiable>
22-
*/
23-
public function getfunctions(): array
12+
public function __construct(public readonly array $functions)
2413
{
25-
return $this->functions;
2614
}
2715
}

src/Parse/VarReference.php

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,11 @@
66

77
final class VarReference
88
{
9-
private string $name;
10-
private int $lineNumber;
11-
private bool $updated;
12-
13-
public function __construct(string $name, int $lineNumber, bool $updated = false)
14-
{
15-
$this->name = $name;
16-
$this->lineNumber = $lineNumber;
17-
$this->updated = $updated;
18-
}
19-
20-
public function getName(): string
21-
{
22-
return $this->name;
23-
}
24-
25-
public function getLineNumber(): int
26-
{
27-
return $this->lineNumber;
28-
}
29-
30-
public function isUpdated(): bool
9+
public function __construct(
10+
public readonly string $name,
11+
public readonly int $lineNumber,
12+
public readonly bool $updated = false
13+
)
3114
{
32-
return $this->updated;
3315
}
3416
}

src/Parse/VariableParser.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ public function __construct()
2323
}
2424

2525
/**
26-
* @param Stmt[] $stmt
27-
* @return Function_[]
26+
* @param list<Stmt> $stmt
27+
* @return List<Function_>
2828
*/
2929
private function getFunctions(array $stmt): array
3030
{
@@ -38,6 +38,10 @@ private function getFunctions(array $stmt): array
3838
return $functionVisitor->getFoundNodes();
3939
}
4040

41+
/**
42+
* @param Function_|ClassMethod $function
43+
* @return list<Variable>
44+
*/
4145
private function getVariables(Function_|ClassMethod $function): array
4246
{
4347
$variableVisitor = new FindingVisitor(function ($node) {
@@ -50,6 +54,10 @@ private function getVariables(Function_|ClassMethod $function): array
5054
return $variableVisitor->getFoundNodes();
5155
}
5256

57+
/**
58+
* @param list<Stmt> $stmts
59+
* @return list<Func>
60+
*/
5361
private function parseFunctions(array $stmts): array
5462
{
5563
$foundFunctions = $this->getFunctions($stmts);
@@ -66,6 +74,10 @@ private function parseFunctions(array $stmts): array
6674
return $functions;
6775
}
6876

77+
/**
78+
* @param list<Stmt> $stmt
79+
* @return List<Class_>
80+
*/
6981
private function getClasses(array $stmt): array
7082
{
7183
$classVisitor = new FindingVisitor(function ($node) {
@@ -78,6 +90,10 @@ private function getClasses(array $stmt): array
7890
return $classVisitor->getFoundNodes();
7991
}
8092

93+
/**
94+
* @param list<Stmt> $stmts
95+
* @return list<Func>
96+
*/
8197
private function parseClasses(array $stmts): array
8298
{
8399
$foundClasses = $this->getClasses($stmts);

test/VariableAnalizerTest.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Smeghead\PhpVariableHardUsage\Analyze\VariableAnalyzer;
7+
use Smeghead\PhpVariableHardUsage\Parse\Func;
8+
use Smeghead\PhpVariableHardUsage\Parse\VarReference;
9+
10+
class VariableAnalizerTest extends TestCase
11+
{
12+
public function testAnalyzeFunctionSimple(): void
13+
{
14+
$func = new Func('testFunction');
15+
$func->addVariable(new VarReference('a', 1));
16+
$func->addVariable(new VarReference('a', 2));
17+
$func->addVariable(new VarReference('a', 3));
18+
19+
$sut = new VariableAnalyzer([$func]);
20+
$result = $sut->analyze();
21+
$scopes = $result->scopes;
22+
23+
$this->assertCount(1, $scopes);
24+
$this->assertSame('testFunction', $scopes[0]->getName());
25+
$this->assertSame(2, $scopes[0]->getAnalyzedVariables()[0]->variableHardUsage);
26+
}
27+
28+
public function testAnalyzeFunctionLong(): void
29+
{
30+
$func = new Func('testFunction');
31+
$func->addVariable(new VarReference('a', 1));
32+
$func->addVariable(new VarReference('a', 2));
33+
$func->addVariable(new VarReference('a', 100));
34+
35+
$sut = new VariableAnalyzer([$func]);
36+
$result = $sut->analyze();
37+
$scopes = $result->scopes;
38+
39+
$this->assertCount(1, $scopes);
40+
$this->assertSame('testFunction', $scopes[0]->getName());
41+
// (1 + 2 + 100) / 3 = 34
42+
// abs(34 - 1) + abs(34 - 2) + abs(34 - 100) = 33 + 32 + 66 = 131
43+
$this->assertSame(131, $scopes[0]->getAnalyzedVariables()[0]->variableHardUsage);
44+
}
45+
}

0 commit comments

Comments
 (0)