Ответ 1
Приводя пример еще проще, этот класс имеет значение nPath 2. Он должен быть довольно очевидным, почему это два - через код явно есть два пути выполнения.
package test;
import java.util.*;
public class Test {
private static final long UNKNWOWN = -1;
public void method(Date a) {
long aTime;
if (a == null) {
aTime = UNKNWOWN;
} else {
aTime = a.getTime();
}
}
}
И этот класс имеет значение nPath 5. Вопрос в том, почему - через код есть еще два логических пути.
package test;
import java.util.*;
public class Test {
private static final long UNKNWOWN = -1;
public void method(Date a) {
final long aTime = a == null ? UNKNWOWN : a.getTime();
}
}
Однако используемый алгоритм:
int npath = complexitySumOf(node, 0, data);
npath += 2;
Он добавляет сложность всех детей, а затем добавляет два для тройки. Минимальная сложность, возвращаемая для простых узлов Java: 1. AbstractSyntaxTree показывает, что есть три ребенка. Следовательно, 3 + 2 равно 5.
<ConditionalExpression beginColumn="36" beginLine="11" endColumn="69" endLine="11" ternary="true">
<EqualityExpression beginColumn="36" beginLine="11" endColumn="44" endLine="11" image="==">
<PrimaryExpression beginColumn="36" beginLine="11" endColumn="36" endLine="11">
<PrimaryPrefix beginColumn="36" beginLine="11" endColumn="36" endLine="11">
<Name beginColumn="36" beginLine="11" endColumn="36" endLine="11" image="a"/>
</PrimaryPrefix>
</PrimaryExpression>
<PrimaryExpression beginColumn="41" beginLine="11" endColumn="44" endLine="11">
<PrimaryPrefix beginColumn="41" beginLine="11" endColumn="44" endLine="11">
<Literal beginColumn="41" beginLine="11" charLiteral="false" endColumn="44" endLine="11" floatLiteral="false" intLiteral="false" singleCharacterStringLiteral="false" stringLiteral="false">
<NullLiteral beginColumn="41" beginLine="11" endColumn="44" endLine="11"/>
</Literal>
</PrimaryPrefix>
</PrimaryExpression>
</EqualityExpression>
<Expression beginColumn="48" beginLine="11" endColumn="55" endLine="11">
<PrimaryExpression beginColumn="48" beginLine="11" endColumn="55" endLine="11">
<PrimaryPrefix beginColumn="48" beginLine="11" endColumn="55" endLine="11">
<Name beginColumn="48" beginLine="11" endColumn="55" endLine="11" image="UNKNWOWN"/>
</PrimaryPrefix>
</PrimaryExpression>
</Expression>
<PrimaryExpression beginColumn="59" beginLine="11" endColumn="69" endLine="11">
<PrimaryPrefix beginColumn="59" beginLine="11" endColumn="67" endLine="11">
<Name beginColumn="59" beginLine="11" endColumn="67" endLine="11" image="a.getTime"/>
</PrimaryPrefix>
<PrimarySuffix argumentCount="0" arguments="true" arrayDereference="false" beginColumn="68" beginLine="11" endColumn="69" endLine="11">
<Arguments argumentCount="0" beginColumn="68" beginLine="11" endColumn="69" endLine="11"/>
</PrimarySuffix>
</PrimaryExpression>
</ConditionalExpression>
Если у вас есть сложное выражение в тройном операторе, разница будет считаться еще более распространенной. Что касается кода, он уже имеет 9 ветвей (8 тернарных операторов и цикл), которые высоки даже без всего расчета nPath. Я бы реорганизовал его независимо.