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