3 个不稳定版本
0.2.0 | 2020 年 4 月 26 日 |
---|---|
0.1.1 | 2020 年 4 月 25 日 |
0.1.0 | 2020 年 4 月 20 日 |
0.0.0 |
|
#1371 在 开发工具
67 每月下载量
28KB
395 行
complexity
计算 Rust 代码的认知复杂度。
基于 G. Ann Campbell 的 认知复杂度。
入门指南
将 complexity
添加到您的 Cargo.toml
文件中。
[dependencies]
complexity = "0.2"
syn = "1"
您需要将 Complexity
特性引入作用域,可能还需要从 syn
中的一些内容。
use complexity::Complexity;
use syn::{Expr, parse_quote};
表达式和其他 syn
类型的复杂度计算非常简单,只需在那种类型的实例上调用 .complexity()
方法即可。
let expr: Expr = parse_quote! {
for element in iterable { // +1
if something { // +2 (nesting = 1)
do_something();
}
}
};
assert_eq!(expr.complexity(), 3);
示例
本库中认知复杂度的实现主要基于 G. Ann Campbell 的 认知复杂度。阅读它将有助于理解复杂度指数是如何计算的。
引入分支的循环和结构会增加复杂度,每个分支增加 1。一些语法结构引入了“嵌套”级别,除了常规增加外,还会增加一些表达式的复杂度。下面我们看看两个嵌套循环和一个 if 语句如何产生相当高的 7 复杂度。
use complexity::Complexity;
use syn::{ItemFn, parse_quote};
let func: ItemFn = parse_quote! {
fn sum_of_primes(max: u64) -> u64 {
let mut total = 0;
'outer: for i in 1..=max { // +1
for j in 2..i { // +2 (nesting = 1)
if i % j == 0 { // +3 (nesting = 2)
continue 'outer; // +1
}
}
total += i;
}
}
};
assert_eq!(func.complexity(), 7);
但某些结构是受奖励的。特别是 match
语句,无论有多少分支,它只会增加 1 的复杂度。(尽管它会增加嵌套级别。)下面我们看看尽管代码中有很多分支(这会为更传统的 圈复杂度 测量贡献很多),但复杂度相当低,只有 1。
use complexity::Complexity;
use syn::{ItemFn, parse_quote};
let func: ItemFn = parse_quote! {
fn get_words(number: u64) -> &str {
match number { // +1
1 => "one",
2 => "a couple",
3 => "a few",
_ => "lots",
}
}
};
assert_eq!(func.complexity(), 1);
下面提供了一个示例,用于计算并优雅地打印出整个 Rust 文件中每个函数和方法的认知复杂度。请参阅 examples/lint-files.rs。您可以在这样的 Rust 文件上运行它
cargo run --example lint-files -- src/
许可证
许可协议为以下之一:
- Apache License, Version 2.0 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可协议 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
依赖项
约 1.5MB
约 35K SLoC