Skip to content

Commit

Permalink
Implement Halstead for Java (#811)
Browse files Browse the repository at this point in the history
  • Loading branch information
dburriss authored May 29, 2022
1 parent b5496f8 commit 4987e90
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
39 changes: 39 additions & 0 deletions src/getter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,4 +524,43 @@ impl Getter for JavaCode {
_ => SpaceKind::Unknown,
}
}

fn get_op_type(node: &Node) -> HalsteadType {
use Java::*;
// Some guides that informed grammar choice for Halstead
// keywords, operators, literals: https://docs.oracle.com/javase/specs/jls/se18/html/jls-3.html#jls-3.12
// https://www.geeksforgeeks.org/software-engineering-halsteads-software-metrics/?msclkid=5e181114abef11ecbb03527e95a34828
let typ = node.object().kind_id();

match typ.into() {
// Operator: function calls
MethodInvocation
// Operator: control flow
| If | Else | Switch | Case | Try | Catch | Throw | Throws | Throws2 | For | While | Continue | Break | Do | Finally
// Operator: keywords
| New | Return | Default | Abstract | Assert | Instanceof | Extends | Final | Implements | Transient | Synchronized | Super | This | VoidType
// Operator: brackets and comma and terminators (separators)
| SEMI | COMMA | COLONCOLON | LBRACE | LBRACK | LPAREN | RBRACE | RBRACK | RPAREN | DOTDOTDOT | DOT
// Operator: operators
| EQ | LT | GT | BANG | TILDE | QMARK | COLON // no grammar for lambda operator ->
| EQEQ | LTEQ | GTEQ | BANGEQ | AMPAMP | PIPEPIPE | PLUSPLUS | DASHDASH
| PLUS | DASH | STAR | SLASH | AMP | PIPE | CARET | PERCENT| LTLT | GTGT | GTGTGT
| PLUSEQ | DASHEQ | STAREQ | SLASHEQ | AMPEQ | PIPEEQ | CARETEQ | PERCENTEQ | LTLTEQ | GTGTEQ | GTGTGTEQ
// type identifier
| TypeIdentifier | IntegralType | FloatingPointType | BooleanType
=> {
HalsteadType::Operator
},
// Operands: variables, constants, literals
Identifier | NullLiteral | ClassLiteral | StringLiteral | CharacterLiteral | HexIntegerLiteral | OctalIntegerLiteral
| BinaryIntegerLiteral | DecimalIntegerLiteral | HexFloatingPointLiteral | DecimalFloatingPointLiteral => {
HalsteadType::Operand
},
_ => {
HalsteadType::Unknown
},
}
}

get_operator!(Java);
}
30 changes: 29 additions & 1 deletion src/metrics/halstead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,9 +325,14 @@ impl Halstead for CppCode {
}
}

impl Halstead for JavaCode {
fn compute<'a>(node: &Node<'a>, code: &'a [u8], halstead_maps: &mut HalsteadMaps<'a>) {
compute_halstead::<Self>(node, code, halstead_maps);
}
}

impl Halstead for PreprocCode {}
impl Halstead for CcommentCode {}
impl Halstead for JavaCode {}

#[cfg(test)]
mod tests {
Expand Down Expand Up @@ -521,4 +526,27 @@ mod tests {
]
);
}

#[test]
fn java_operators_and_operands() {
check_metrics!(
"public class Main {
public static void main(String args[]) {
int a, b, c, avg;
a = 5; b = 5; c = 5;
avg = (a + b + c) / 3;
MessageFormat.format(\"{0}\", avg);
}
}",
"foo.java",
JavaParser,
halstead,
[
(u_operators, 16, usize), // { void ; ( String [ ] ) , int = + / format . }
(operators, 34, usize),
(u_operands, 12, usize), // Main main args a b c avg 5 3 MessageFormat format "{0}"
(operands, 22, usize)
]
);
}
}

0 comments on commit 4987e90

Please sign in to comment.