Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# CHANGELOG

### Features

* The base of deviation of local variable abuse has been changed from the average number of rows to the first number of rows.


## v0.0.2 (2025-03-19)

### Features
Expand Down
30 changes: 14 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ $ vendor/bin/php-variable-hard-usage somewhere/your-php-file.php
}
```


## How to calculate VariableHardUsage

VariableHardUsage is an index used to evaluate the frequency of use and scope of local variables within a function. This measure is calculated based on the variance of the line number of references to the same variable and the frequency with which the variable is assigned.
Expand All @@ -95,31 +94,30 @@ VariableHardUsage is an index used to evaluate the frequency of use and scope of

* For each variable used in the function, retrieve all line numbers where the variable is referenced.

2. Calculate the average of the line numbers.

* Calculates the average of the line numbers obtained. This is obtained by dividing the sum of the line numbers by the number of references.
2. Calculate deviation based on first occurrence.

3. Calculate VariableHardUsage.
* For each reference, computes the difference between the line number and the line number of the first occurrence of the variable.

* Calculates the absolute difference between the line number and the average line number for each reference.
* If a variable is assigned, the difference is multiplied by a factor (2 by default).
* Sum all these values to obtain VariableHardUsage.
3. Applying coefficients by assignment.
* When a variable is assigned, the difference is multiplied by a coefficient (2 by default). This is to account for the effect of the assignment on the frequency of use of the variable.
* Calculation of VariableHardUsage:.
* The VariableHardUsage is obtained by summing all these deviation values.

### Example

For example, suppose there are three reference points in a function, each with line numbers 10, 20, and 30, where some assignments are made and some are not made. In this case, the average row number is 20.
Suppose, for example, that there are three reference points in a function, each with line numbers 10, 20, and 30, and that some assignments are made and some are not made. In this case, the line number of the first occurrence is 10.

* Reference A: Row 10, with assignment
* Reference B: Row 20, no assignment
* Reference C: Row 30, with assignment
* Reference A: line 10, with assignment
* Reference B: line 20, no assignment
* Reference C: line 30, with assignment

In this case, VariableHardUsage is calculated as follows

* Reference A: |10 - 20| * 2 = 20
* Reference B: |20 - 20| * 1 = 0
* Reference C: |30 - 20| * 2 = 20
* Reference A: (10 - 10) * 2 = 0
* Reference B: (20 - 10) * 1 = 10
* Reference C: (30 - 10) * 2 = 40

Summing these, VariableHardUsage is 20 + 0 + 20 = 40.
Summing these, VariableHardUsage is 0 + 10 + 40 = 50.

VariableHardUsage is thus calculated as a measure of the frequency of use and scope of a variable. This metric can be used to quantitatively evaluate the usage of local variables within a function and help improve code readability and maintainability.

6 changes: 2 additions & 4 deletions src/Analyze/VariableAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ private function analyzeFunction(Func $function): Scope
*/
private function calcVariableHardUsage(array $vars): int
{
$lineNumbers = array_map(fn($var) => $var->lineNumber, $vars);
$avarageLinuNumber = intval(array_sum($lineNumbers) / count($lineNumbers));
$variableHardUsage = array_sum(array_map(fn(VarReference $var) => abs($var->lineNumber - $avarageLinuNumber) * ($var->assigned ? self::ASSIGNED_VARIABLE_COEFFICIENT : 1), $vars));
return $variableHardUsage;
$firstLineNumber = $vars[0]->lineNumber;
return array_sum(array_map(fn(VarReference $var) => ($var->lineNumber - $firstLineNumber) * ($var->assigned ? self::ASSIGNED_VARIABLE_COEFFICIENT : 1), $vars));
}
}
26 changes: 19 additions & 7 deletions test/VariableAnalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function testAnalyzeFunctionSimple(): void

$this->assertCount(1, $scopes);
$this->assertSame('testFunction', $scopes[0]->name);
$this->assertSame(2, $scopes[0]->getAnalyzedVariables()[0]->variableHardUsage);
$this->assertSame(3, $scopes[0]->getAnalyzedVariables()[0]->variableHardUsage, '0 + 1 + 2');
}

public function testAnalyzeFunctionLong(): void
Expand All @@ -38,9 +38,7 @@ public function testAnalyzeFunctionLong(): void

$this->assertCount(1, $scopes);
$this->assertSame('testFunction', $scopes[0]->name);
// (1 + 2 + 100) / 3 = 34
// abs(34 - 1) + abs(34 - 2) + abs(34 - 100) = 33 + 32 + 66 = 131
$this->assertSame(131, $scopes[0]->getAnalyzedVariables()[0]->variableHardUsage);
$this->assertSame(100, $scopes[0]->getAnalyzedVariables()[0]->variableHardUsage, '(1 - 1) + (2 - 1) + (100 - 1)');
}

public function testAnalyzeFunctionLongAssignedVariable(): void
Expand All @@ -56,8 +54,22 @@ public function testAnalyzeFunctionLongAssignedVariable(): void

$this->assertCount(1, $scopes);
$this->assertSame('testFunction', $scopes[0]->name);
// (1 + 2 + 100) / 3 = 34
// abs(34 - 1) * 2 + abs(34 - 2) + abs(34 - 100) = 66 + 32 + 66 = 164
$this->assertSame(164, $scopes[0]->getAnalyzedVariables()[0]->variableHardUsage);
$this->assertSame(100, $scopes[0]->getAnalyzedVariables()[0]->variableHardUsage, '(1 - 1) * 2 + (2 - 1) + (100 - 1)');
}

public function testAnalyzeFunctionLongMultipleAssignedVariable(): void
{
$func = new Func(null, 'testFunction');
$func->addVariable(new VarReference('a', 1, true));
$func->addVariable(new VarReference('a', 2));
$func->addVariable(new VarReference('a', 100, true));

$sut = new VariableAnalyzer([$func]);
$result = $sut->analyze();
$scopes = $result->scopes;

$this->assertCount(1, $scopes);
$this->assertSame('testFunction', $scopes[0]->name);
$this->assertSame(199, $scopes[0]->getAnalyzedVariables()[0]->variableHardUsage, '(1 - 1) * 2 + (2 - 1) + (100 - 1) * 2');
}
}