in src/metrics/abc.rs [364:546]
fn compute(node: &Node, stats: &mut Stats) {
use Java::*;
match node.kind_id().into() {
STAREQ | SLASHEQ | PERCENTEQ | DASHEQ | PLUSEQ | LTLTEQ | GTGTEQ | AMPEQ | PIPEEQ
| CARETEQ | GTGTGTEQ | PLUSPLUS | DASHDASH => {
stats.assignments += 1.;
}
FieldDeclaration | LocalVariableDeclaration => {
stats.declaration.push(DeclKind::Var);
}
Final => {
if let Some(DeclKind::Var) = stats.declaration.last() {
stats.declaration.push(DeclKind::Const);
}
}
SEMI => {
if let Some(DeclKind::Const | DeclKind::Var) = stats.declaration.last() {
stats.declaration.clear();
}
}
EQ => {
// Excludes constant declarations
stats
.declaration
.last()
.map(|decl| {
if matches!(decl, DeclKind::Var) {
stats.assignments += 1.;
}
})
.unwrap_or_else(|| {
stats.assignments += 1.;
});
}
MethodInvocation | New => {
stats.branches += 1.;
}
GTEQ | LTEQ | EQEQ | BANGEQ | Else | Case | Default | QMARK | Try | Catch => {
stats.conditions += 1.;
}
GT | LT => {
// Excludes `<` and `>` used for generic types
if let Some(parent) = node.parent() {
if !matches!(parent.kind_id().into(), TypeArguments) {
stats.conditions += 1.;
}
}
}
// Counts unary conditions in elements separated by `&&` or `||` boolean operators
AMPAMP | PIPEPIPE => {
if let Some(parent) = node.parent() {
java_count_unary_conditions(&parent, &mut stats.conditions);
}
}
// Counts unary conditions among method arguments
ArgumentList => {
java_count_unary_conditions(node, &mut stats.conditions);
}
// Counts unary conditions inside assignments
VariableDeclarator | AssignmentExpression => {
// The child node of index 2 contains the right operand of an assignment operation
if let Some(right_operand) = node.child(2) {
if matches!(
right_operand.kind_id().into(),
ParenthesizedExpression | UnaryExpression
) {
java_inspect_container(&right_operand, &mut stats.conditions);
}
}
}
// Counts unary conditions inside if and while statements
IfStatement | WhileStatement => {
// The child node of index 1 contains the condition
if let Some(condition) = node.child(1) {
if matches!(condition.kind_id().into(), ParenthesizedExpression) {
java_inspect_container(&condition, &mut stats.conditions);
}
}
}
// Counts unary conditions do-while statements
DoStatement => {
// The child node of index 3 contains the condition
if let Some(condition) = node.child(3) {
if matches!(condition.kind_id().into(), ParenthesizedExpression) {
java_inspect_container(&condition, &mut stats.conditions);
}
}
}
// Counts unary conditions inside for statements
ForStatement => {
// The child node of index 3 contains the `condition` when
// the initialization expression is a variable declaration
// e.g. `for ( int i=0; `condition`; ... ) {}`
if let Some(condition) = node.child(3) {
match condition.kind_id().into() {
SEMI => {
// The child node of index 4 contains the `condition` when
// the initialization expression is not a variable declaration
// e.g. `for ( i=0; `condition`; ... ) {}`
if let Some(cond) = node.child(4) {
match cond.kind_id().into() {
MethodInvocation | Identifier | True | False | SEMI
| RPAREN => {
stats.conditions += 1.;
}
ParenthesizedExpression | UnaryExpression => {
java_inspect_container(&cond, &mut stats.conditions);
}
_ => {}
}
}
}
MethodInvocation | Identifier | True | False => {
stats.conditions += 1.;
}
ParenthesizedExpression | UnaryExpression => {
java_inspect_container(&condition, &mut stats.conditions);
}
_ => {}
}
}
}
// Counts unary conditions inside return statements
ReturnStatement => {
// The child node of index 1 contains the return value
if let Some(value) = node.child(1) {
if matches!(
value.kind_id().into(),
ParenthesizedExpression | UnaryExpression
) {
java_inspect_container(&value, &mut stats.conditions)
}
}
}
// Counts unary conditions inside implicit return statements in lambda expressions
LambdaExpression => {
// The child node of index 2 contains the return value
if let Some(value) = node.child(2) {
if matches!(
value.kind_id().into(),
ParenthesizedExpression | UnaryExpression
) {
java_inspect_container(&value, &mut stats.conditions)
}
}
}
// Counts unary conditions inside ternary expressions
TernaryExpression => {
// The child node of index 0 contains the condition
if let Some(condition) = node.child(0) {
match condition.kind_id().into() {
MethodInvocation | Identifier | True | False => {
stats.conditions += 1.;
}
ParenthesizedExpression | UnaryExpression => {
java_inspect_container(&condition, &mut stats.conditions);
}
_ => {}
}
}
// The child node of index 2 contains the first expression
if let Some(expression) = node.child(2) {
if matches!(
expression.kind_id().into(),
ParenthesizedExpression | UnaryExpression
) {
java_inspect_container(&expression, &mut stats.conditions);
}
}
// The child node of index 4 contains the second expression
if let Some(expression) = node.child(4) {
if matches!(
expression.kind_id().into(),
ParenthesizedExpression | UnaryExpression
) {
java_inspect_container(&expression, &mut stats.conditions);
}
}
}
_ => {}
}
}