diff --git a/CHANGELOG.md b/CHANGELOG.md index 5697bca..03748a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/README.md b/README.md index 554f336..b8af297 100644 --- a/README.md +++ b/README.md @@ -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. @@ -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. diff --git a/src/Analyze/VariableAnalyzer.php b/src/Analyze/VariableAnalyzer.php index 523f5d6..2ff387e 100644 --- a/src/Analyze/VariableAnalyzer.php +++ b/src/Analyze/VariableAnalyzer.php @@ -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)); } } \ No newline at end of file diff --git a/test/VariableAnalizerTest.php b/test/VariableAnalizerTest.php index f0573ab..77ba6d2 100644 --- a/test/VariableAnalizerTest.php +++ b/test/VariableAnalizerTest.php @@ -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 @@ -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 @@ -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'); } } \ No newline at end of file