74 个版本 (稳定)
3.1.2 | 2024 年 5 月 15 日 |
---|---|
3.1.0 | 2024 年 4 月 30 日 |
3.0.0 | 2024 年 3 月 15 日 |
2.6.1 | 2024 年 1 月 23 日 |
0.1.0-pre.3 | 2021 年 3 月 29 日 |
#334 in Rust 模式
1,188 个月下载量
78KB
1.5K SLoC
dylint_linting
该软件包提供了创建 Dylint 库的宏和创建可配置库的实用工具。
内容
dylint_library!
declare_late_lint!
,declare_early_lint!
,declare_pre_expansion_lint!
impl_late_lint!
,impl_early_lint!
,impl_pre_expansion_lint!
constituent
功能- 可配置库
dylint_library!
dylint_library!
宏展开为以下内容
#[allow(unused_extern_crates)]
extern crate rustc_driver;
#[no_mangle]
pub extern "C" fn dylint_version() -> *mut std::os::raw::c_char {
std::ffi::CString::new($crate::DYLINT_VERSION)
.unwrap()
.into_raw()
}
如果您的库使用 dylint_library!
宏和 dylint-link
工具,那么您只需实现 register_lints
函数即可。请参阅此存储库中的 示例。
declare_late_lint!
等。
如果您的库仅包含一个 lint,使用 declare_late_lint!
等可以使您的代码更简洁。这些宏中的每个都需要与 declare_lint!
相同的参数,并包装以下内容:
- 对
dylint_library!
的调用 register_lints
函数的实现- 对
declare_lint!
的调用 - 对
declare_lint_pass!
的调用
例如,以下代码
dylint_linting::dylint_library!();
extern crate rustc_lint;
extern crate rustc_session;
#[no_mangle]
pub fn register_lints(sess: &rustc_session::Session, lint_store: &mut rustc_lint::LintStore) {
dylint_linting::init_config(sess);
lint_store.register_lints(&[NAME]);
lint_store.register_late_pass(|_| Box::new(Name));
}
rustc_session::declare_lint!(vis NAME, Level, "description");
rustc_session::declare_lint_pass!(Name => [NAME]);
declare_late_lint!)
扩展为以下内容
declare_early_lint!
和 declare_pre_expansion_lint!
的定义方式类似。
impl_late_lint!
等。
impl_late_lint!
等. 与declare_late_lint!
等. 类似,除了- 每个调用
impl_lint_pass!
而不是declare_lint_pass!
;
这意味着 impl_late_lint!
的附加参数是这里的内容
lint_store.register_late_pass(|_| Box::new(...));
^^^
constituent
功能
启用包级别的 constituent
功能会改变上述宏的工作方式。具体来说,它会 排除
dylint_library!
的调用- 在
register_lints
声明之前使用#[no_mangle]
的用法
这些更改有助于将使用上述宏之一声明的 lint 包含到更大的库中。也就是说
- 在关闭功能的情况下,lint 可以作为库独立构建。
- 在开启功能的情况下,lint 可以作为更大库的一部分构建,与其他 lint 一起。
本存储库中的 通用 和 补充 lint 使用了这项技术。也就是说,每个通用 lint 都可以独立构建为一个库,或者作为 general
库 的一部分。类似的说法也适用于补充 lint 和 supplementary
库。constituent
功能是这个工作背后的机制。
可配置库
可以通过在目标工作空间的根目录中包含一个 dylint.toml
文件来配置库。此 crate 为读取和解析 dylint.toml
文件提供了以下功能
仅包含一个 lint 的可配置库通常具有以下形式的 lib.rs
文件
dylint_linting::impl_late_lint! {
...,
LintName::new()
}
// Lint configuration
#[derive(Default, serde::Deserialize)]
struct Config {
boolean: bool,
strings: Vec<String>,
}
// Keep a copy of the configuration in the `LintPass` structure.
struct LintName {
config: Config,
}
// Read the configuration from the `dylint.toml` file, or use the default configuration if
// none is present.
impl LintName {
pub fn new() -> Self {
Self {
config: dylint_linting::config_or_default(env!("CARGO_PKG_NAME")),
}
}
}
有关此形式 lib.rs
文件的具体示例,请参阅本存储库中的 non_local_effect_before_error_return
库。
包含多个 lint 的库必须实现 register_lints
函数,而不依赖于上述宏。如果库是可配置的,那么它的 register_lints
函数应包含对 dylint_linting::init_config
的调用,如下例所示
#[no_mangle]
pub fn register_lints(sess: &rustc_session::Session, lint_store: &mut rustc_lint::LintStore) {
// `init_config` or `try_init_config` must be called before `config_or_default`, `config`,
// or `config_toml` is called.
dylint_linting::init_config(sess);
lint_store.register_lints(&[FIRST_LINT_NAME, SECOND_LINT_NAME]);
lint_store.register_late_pass(|_| Box::new(LintPassName::new()));
}
有关 config_or_default
等. 的其他文档可以在 docs.rs 上找到。
依赖项
~1.3–2.2MB
~45K SLoC